← All tools

kriasoft/obserf

Popularity 75 Updated Development & Build

Local-first CLI that finds relevant conversations where your product can genuinely help, ranks the opportunities, and drafts responses.

githubauto-collected

Installation

A directly usable install command is not verified yet. Check the project documentation or releases.

Obserf

Obserf (obserf.com) finds public conversations and listings where mentioning a project could help someone, ranks them, and drafts what to say.

Maintaining a project leaves little time to promote it. Search turns up hundreds of loosely related pages; deciding which ones are active, relevant, and open to a maintainer's contribution takes longer than writing the replies. Obserf narrows that reading to a ranked inbox, with a reason for each finding.

An opportunity must be useful, permitted, and free, with a public way to participate: a comment, reply, or submission. Obserf searches Hacker News, Reddit, GitHub and Brave, filters duplicates and unsuitable candidates, and uses a model to assess the survivors. The model has no tools and cannot read a venue's rules or its pricing, so what reaches the inbox is not known to be forbidden and not known to cost money — a weaker claim than permitted and free, and the reason Obserf never posts. You read the thread, check the venue's rules and whatever a submission actually requires, edit the draft, and post it yourself.

This is a personal tool for one operator and a handful of projects. Obserf ships no projects and no data: your profiles, your database and your credentials live in a workspace you own, and this repository never sees them. There is no Obserf service to sign up for, no account, and nothing to sync: its state is one SQLite file on your machine, and your triage decisions and notes never leave it. The one server involved is obserf serve, which is yours, on your loopback interface.

The work itself is not local, though. Your queries go to the search providers you configure. Candidates that survive gating go to Claude, with whatever evidence was gathered about them and your project's profile text, to be assessed — and again when you ask for a draft, along with the thread's current text where Obserf can fetch it, and the stored excerpt where it cannot. Your credentials authenticate those requests to the providers they belong to and never enter a model prompt. Model calls go through Claude Code, whose network behaviour is its own — and if your environment configures model routing, obserf names the relevant variables on the process's first model call rather than letting your candidate text and project brief go somewhere else quietly.

The discovery, review and drafting loop is implemented end to end. What is not established is that it finds enough worth posting: there is no outcome tracking and no eval set yet, so treat the ranking as a reading order rather than a measured result. See the roadmap.

A ranked list looks like this — illustrative, not a recorded run:

 78 #42   Looking for a local way to tail and filter JSON logs
     example · question · 2 drafts · https://news.ycombinator.com/item?id=44444444
     The author is describing the exact problem the project solves and is asking
     for recommendations; HN tolerates a maintainer answering with disclosure.

Setup

You need Bun 1.4 or later and Claude Code installed and signed in with a subscription for assessment and drafting. Obserf uses the Claude Agent SDK with tools disabled; model calls require no Anthropic API key and consume the subscription quota shared with interactive Claude Code sessions. See ADR-008.

bunx @obserf/cli init ~/dev/marketing
cd ~/dev/marketing
bun install

init writes the files a workspace needs and stops there, so bun install is the whole install step; the database is created by the first command that needs it. To work against a checkout instead, run bun link in it and bun link @obserf/cli in the workspace — the profiles import @obserf/cli either way, so nothing else changes.

A workspace is a directory you own, marked by obserf.config.ts:

~/dev/marketing/
  obserf.config.ts      the marker; almost empty by design
  projects/*.ts         your profiles — author these, commit these
  package.json          declares the Obserf version this workspace was scaffolded for
  tsconfig.json         what typechecks the profiles
  .env.example          the variables; copy it to .env to set any
  .env                  credentials, read by Bun
  .obserf/obserf.db     everything Obserf learns
  .obserf/backups/

Obserf finds it by walking up from wherever you run a command, the way git does, so a command run from a subdirectory still uses the same database and the same profiles. Credentials are the exception: Bun loads .env from the process's working directory and Obserf does not parse one itself, so run scan, draft and serve — which drafts through the same code path — from the workspace root unless those variables are already in your environment. Keep the workspace in its own private git repository; init writes a .gitignore that keeps .env and .obserf/ out of it.

From then on, work from the workspace:

cd ~/dev/marketing
$EDITOR projects/example.ts
bun run obserf scan --dry-run