@superbased/observer 1.8.0 → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -140,6 +140,8 @@ env var that matches your client(s); both can coexist on one machine.
140
140
  | **OpenClaw** ([openclaw.ai](https://openclaw.ai/)) | (no proxy yet) | JSONL + sqlite — `~/.openclaw/tasks/runs.sqlite` + `~/.openclaw/agents/<agent>/sessions/sessions.json` |
141
141
  | **Pi** ([pi.dev](https://pi.dev/)) | (no proxy yet) | JSONL — `~/.pi/agent/sessions/--<path>--/*.jsonl` (per upstream `docs/session-format.md` v3). Captures user / assistant / toolResult / `bashExecution` message roles; `usage.cost.total` → per-message USD; terminal `stopReason` (stop/length/error/aborted) → `task_complete` with `success=false` for failures (mid-turn `toolUse` is correctly skipped); `thinking` blocks surface as preceding reasoning. Tagged `Source=jsonl, Reliability=approximate`. |
142
142
  | **Google Antigravity** | (no proxy yet) | Encrypted protobuf — `~/.gemini/antigravity/conversations/*.pb` (Linux-native) and the matching Windows-side path on WSL2. Observer ships a per-OS Chromium-pattern `oscrypt` key fetcher (macOS Keychain / libsecret / DPAPI / WSL2-via-PowerShell helper) and a multi-cipher try-loop for local decryption. Sessions whose ciphers don't validate locally fall back to the language_server's `GetCascadeTrajectory` gRPC endpoint via a built-in helper (`antigravity-bridge.exe` on WSL2 / native gRPC elsewhere) — extracts model + per-turn token counts + Tier 0–6 ToolEvents (file views, artifact edits/writes, user prompts, assistant text, run_command terminal snapshots, structured plan steps, final summaries). State index + per-conversation title/workspace URI read from `state.vscdb` + `state.vscdb.backup`. Tagged `Source=jsonl, Reliability=approximate`. |
143
+ | **Kilo Code IDE extension (legacy)** | (no proxy yet) | JSON — `<vsCodeGlobalStorage>/kilocode.kilo-code/tasks/<taskId>/api_conversation_history.json`. The legacy Kilo extension is a Cline + Roo Code fork and shares the Cline parser; emitted rows are re-tagged `Tool="kilo-code"` so dashboard rollups don't blur Kilo activity into Cline. Tagged `Source=jsonl, Reliability=approximate`. |
144
+ | **Kilo Code CLI (current)** | Optional: `OPENAI_BASE_URL=http://127.0.0.1:8820/v1` (Kilo Gateway is OpenAI-compatible at the wire) | SQLite — `~/.local/share/kilo/kilo.db` on every OS (Kilo intentionally mirrors XDG; Windows does NOT use `%APPDATA%`). The new `@kilocode/cli` (npm) is a fork of sst/opencode and uses the same `message`/`part`/`todo` tables shape with Kilo additions (`project`, `workspace`, `event`, `session_message`, `account`, `permission`, `session_share`). Captures **token counts + model + cost** per assistant message from `message.data.tokens = {total, input, output, reasoning, cache: {read, write}}`. Tool name coverage inherits OpenCode's surface (`read` → `read_file`, `bash` → `run_command`, `websearch` → `web_search`, etc.). Tagged `Source=jsonl, Reliability=approximate`. |
143
145
  | **Gemini CLI** | (no proxy yet) | JSONL or single-object JSON — `~/.gemini/tmp/<hash>/chats/session-*.{json,jsonl}`. Dual-format dispatch: legacy single-object JSON (size-based cursor, cline-style) and proposed JSONL event records (byte-offset cursor, issue [#15292](https://github.com/google-gemini/gemini-cli/issues/15292)). Action mapping covers `read_file` / `write_file` / `edit_file` / `run_command` / `search_files` / `web_fetch` and arbitrary MCP tool calls. Project root falls back through tool-call `cwd` → `~/.gemini/history/<hash>/.git/config` worktree pointer → synthetic `[gemini-cli:<hash>]` key (promoted via ON CONFLICT DO UPDATE on `sessions.project_id` once a future scan supplies a real cwd). Tagged `Source=jsonl, Reliability=approximate`. |
144
146
 
145
147
  **JSONL-only** clients are captured passively by the watcher whenever
@@ -150,7 +152,7 @@ call shows up on Sessions / Actions / Discovery / Tools / Patterns and
150
152
  the JSONL-derived token counts feed the Cost tab. Reliability tagging
151
153
  is per-adapter: Claude Code emits `unreliable` (the JSONL stream uses
152
154
  streaming-time placeholder counts per spec §24); Codex / Cline / Pi /
153
- OpenCode / OpenClaw / Antigravity / Gemini CLI emit `approximate`
155
+ OpenCode / OpenClaw / Antigravity / Gemini CLI / Kilo Code / Kilo Code CLI emit `approximate`
154
156
  (provider-reported usage that hasn't been reconciled against an
155
157
  upstream invoice).
156
158
 
@@ -342,8 +344,9 @@ sessions that could have used Sonnet).
342
344
  </p>
343
345
 
344
346
  One row per AI-coding session. Each session has a stable ID, a tool
345
- (claude-code / cursor / codex / cline / copilot / opencode / openclaw /
346
- pi / antigravity / gemini-cli), a working-directory project, action
347
+ (claude-code / cursor / codex / cline / cline-cli / copilot / copilot-cli /
348
+ opencode / openclaw / pi / antigravity / gemini-cli / hermes /
349
+ kilo-code / kilo-code-cli), a working-directory project, action
347
350
  count, sub-agent action count (when the session spawned sub-agents via
348
351
  the `Agent` tool), per-session **Tokens** and **Cost** columns, and —
349
352
  if `observer score` has run — quality / errors / redundancy ratios. The `~` suffix on Cost flags rows whose pricing
@@ -817,8 +820,9 @@ dashboard) has the full versions with cross-links.
817
820
  changed between reads. Cross-session reads are excluded (a fresh
818
821
  session has no memory of a prior session's read).
819
822
  - **Tool** — in this dashboard, "tool" means the *AI client*
820
- (claude-code, cursor, codex, cline, copilot, opencode, openclaw,
821
- pi, antigravity, gemini-cli), not the per-tool name (`read_file`,
823
+ (claude-code, cursor, codex, cline, cline-cli, copilot, copilot-cli,
824
+ opencode, openclaw, pi, antigravity, gemini-cli, hermes, kilo-code,
825
+ kilo-code-cli), not the per-tool name (`read_file`,
822
826
  `run_command`). The latter is "Tool name" on the Actions tab.
823
827
  - **Tool-pair integrity** — Anthropic requires every `tool_result`
824
828
  block to have a corresponding `tool_use` block in a preceding
@@ -0,0 +1,299 @@
1
+ # @superbased/observer
2
+
3
+ [![npm](https://img.shields.io/npm/v/@superbased/observer.svg)](https://www.npmjs.com/package/@superbased/observer)
4
+ [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
5
+ [![Platforms: Linux • macOS • Windows](https://img.shields.io/badge/platforms-linux%20%7C%20macos%20%7C%20windows-blue.svg)](https://github.com/marmutapp/superbased-observer)
6
+
7
+ **Capture, normalize, compress, and analyze every AI coding tool call you
8
+ run** — across Claude Code, Codex, Cursor, Cline / Roo Code, GitHub
9
+ Copilot (VS Code), GitHub Copilot CLI, OpenCode, OpenClaw, Pi, Google
10
+ Antigravity, Gemini CLI, and Cowork — in one local single-binary tool.
11
+ No telemetry, no cloud, no data leaves your machine.
12
+
13
+ <p align="center">
14
+ <img src="https://github.com/marmutapp/superbased-observer/raw/main/docs/assets/infographics/one-local-path.png" alt="One local path for AI coding activity" width="780">
15
+ </p>
16
+
17
+ # Table of contents
18
+
19
+ - [Install](#install)
20
+ - [Five-minute quickstart](#five-minute-quickstart)
21
+ - [Per-AI-client setup](#per-ai-client-setup)
22
+ - [Architecture in detail](#architecture-in-detail)
23
+ - [Dashboard tour](#dashboard-tour)
24
+ - [MCP tools reference](#mcp-tools-reference)
25
+ - [Compression mechanisms](#compression-mechanisms)
26
+ - [Cost and token math](#cost-and-token-math)
27
+ - [Terminology and glossary](#terminology-and-glossary)
28
+ - [CLI reference](#cli-reference)
29
+ - [Configuration](#configuration)
30
+ - [Troubleshooting](#troubleshooting)
31
+ - [Security and privacy](#security-and-privacy)
32
+ - [Source, contributing, license](#source-contributing-license)
33
+
34
+
35
+ ## Install
36
+
37
+ **Use a global install** (`-g`) so the `observer` command is available
38
+ on your `$PATH` from any directory:
39
+
40
+ ```bash
41
+ npm install -g @superbased/observer
42
+ observer --version
43
+ ```
44
+
45
+ If you install locally (without `-g`) the binary lives at
46
+ `./node_modules/.bin/observer` and isn't on your `$PATH`. Run it
47
+ with `npx`:
48
+
49
+ ```bash
50
+ npm install @superbased/observer # local install
51
+ npx observer --version # ↑ what to use everywhere `observer` is shown below
52
+ ```
53
+
54
+ A note for shared / CI machines where `npm install -g` may need
55
+ `sudo`: see [Troubleshooting → EACCES](#npm-install--g-fails-with-eacces-permission-denied)
56
+ for user-writable-prefix and version-manager fixes.
57
+
58
+ > **Python users:** `pip install superbased-observer` ships the
59
+ > same binary; version numbers are kept in lock-step. See
60
+ > [the PyPI page](https://pypi.org/project/superbased-observer/).
61
+ > Don't install both globally — whichever directory comes first on
62
+ > `$PATH` wins, which gets confusing if their versions drift.
63
+
64
+ Pre-built binaries ship for:
65
+
66
+ | Platform | Architecture |
67
+ |-----------------------|--------------|
68
+ | Linux | x64, arm64 |
69
+ | macOS (Intel) | x64 |
70
+ | macOS (Apple Silicon) | arm64 |
71
+ | Windows | x64 |
72
+
73
+ The package uses the `optionalDependencies`-per-platform pattern (same
74
+ shape as `esbuild` / `swc` / `@biomejs/biome`) — only the binary
75
+ matching your machine downloads. No postinstall network calls, no
76
+ compile step.
77
+
78
+ If your platform isn't listed, build from source — instructions in
79
+ the [main repo](https://github.com/marmutapp/superbased-observer).
80
+
81
+
82
+ ## Five-minute quickstart
83
+
84
+ ```bash
85
+ # 1) Install. `observer init` is OPTIONAL — only run it if you want
86
+ # the MCP server registered with your AI clients (gives them
87
+ # on-demand tools like check_file_freshness / get_cost_summary
88
+ # at the cost of ~1,800 tokens of schema per turn).
89
+ npm install -g @superbased/observer
90
+ observer init # OPTIONAL — interactive: pick clients;
91
+ # writes MCP + codex proxy-route into AI client configs.
92
+ # Skip this step for an MCP-free install.
93
+
94
+ # 2) Start the long-running services (proxy + watcher + dashboard).
95
+ # Auto-registers HOOKS for every detected AI tool on first launch.
96
+ observer start &
97
+
98
+ # 3) Engage the proxy by pointing your AI client at the local URL.
99
+ # See "Per-AI-client setup" for the matching env var.
100
+ export ANTHROPIC_BASE_URL=http://127.0.0.1:8820 # Claude Code
101
+ export OPENAI_BASE_URL=http://127.0.0.1:8820/v1 # Codex / OpenAI
102
+
103
+ # 4) Open the dashboard.
104
+ open http://127.0.0.1:8081/ # macOS
105
+ xdg-open http://127.0.0.1:8081/ # Linux
106
+ start http://127.0.0.1:8081/ # Windows
107
+ ```
108
+
109
+ **What `start` does vs what `init` adds:**
110
+
111
+ | Step | Hooks | Proxy listening | Watcher | Dashboard | MCP in AI clients | Codex proxy route |
112
+ |---|---|---|---|---|---|---|
113
+ | `observer start` alone | auto-registers ✓ | ✓ | ✓ | ✓ | — | — |
114
+ | `observer init` + `observer start` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
115
+ | `observer init --skip-mcp` + `start` | ✓ | ✓ | ✓ | ✓ | — | ✓ |
116
+
117
+ MCP and codex routing are explicit-only because both write per-client
118
+ config files. Hooks self-heal on every `start`.
119
+
120
+ After ten minutes of normal AI-coding usage, the dashboard will be
121
+ populated with cost over time, per-tool activity, compression
122
+ savings, and stale-reread waste signals.
123
+
124
+
125
+ <!-- @@INCLUDE:docs/distribution/README-body.md@@ -->
126
+
127
+
128
+ ## Troubleshooting
129
+
130
+ ### `npm install -g` fails with `EACCES: permission denied`
131
+
132
+ Default npm puts globals under `/usr/local/lib/node_modules` which
133
+ Homebrew-managed Node owns as root on macOS. Three fixes; pick one:
134
+
135
+ ```bash
136
+ # 1) RECOMMENDED — point npm at a user-writable prefix.
137
+ mkdir -p ~/.npm-global
138
+ npm config set prefix '~/.npm-global'
139
+ echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.zshrc
140
+ source ~/.zshrc
141
+ npm install -g @superbased/observer
142
+
143
+ # 2) Use a Node version manager — fnm / nvm install Node into your
144
+ # home directory and dodge the permission issue entirely.
145
+ brew install fnm
146
+ fnm install --lts
147
+ npm install -g @superbased/observer
148
+
149
+ # 3) sudo (works but you'll fight permissions on every update).
150
+ sudo npm install -g @superbased/observer
151
+ ```
152
+
153
+ ### `observer: command not found` after install
154
+
155
+ The shim binary is at `~/.npm-global/bin/observer` (or wherever your
156
+ npm prefix points). Make sure that directory is on `$PATH`:
157
+
158
+ ```bash
159
+ echo $PATH | tr ':' '\n' | grep -E 'npm|node'
160
+ # add the prefix's bin/ to PATH if missing — see fix above
161
+ ```
162
+
163
+ If you installed only a platform package (e.g. `@superbased/observer-darwin-x64`)
164
+ without the main `@superbased/observer`, the shim doesn't get created
165
+ — there's no `bin` field. Install the main package; npm picks up the
166
+ right platform binary automatically via `optionalDependencies`.
167
+
168
+ ### `observer init` says "no tools selected and none auto-detected"
169
+
170
+ Auto-detection looks for the AI clients' default session-log dirs
171
+ (`~/.claude/projects/`, `~/.codex/sessions/`, `~/.cursor/`, etc.).
172
+ On a fresh machine where no client has run yet, those dirs don't
173
+ exist. Pass the flag explicitly:
174
+
175
+ ```bash
176
+ observer init --claude-code # or --codex / --cursor / --cline / --all
177
+ ```
178
+
179
+ This registers hooks regardless — the next time the client runs,
180
+ its dirs get created and the watcher picks them up.
181
+
182
+ ### Empty dashboard / "No proxy traffic"
183
+
184
+ The JSONL adapter populates passively after `observer init`, but
185
+ ground-truth cost / compression numbers require the proxy. Set
186
+ `ANTHROPIC_BASE_URL=http://127.0.0.1:8820` (Claude Code) or
187
+ `OPENAI_BASE_URL=http://127.0.0.1:8820/v1` (Codex) in the shell
188
+ that launches your AI client.
189
+
190
+ Verify with `observer status | grep api_turns` — count should
191
+ climb during AI-client activity.
192
+
193
+ ### `observer --version` says `dev`
194
+
195
+ You're on a non-released build. Reinstall with `npm install -g @superbased/observer` or rebuild with the workflow's `-X main.version=$VERSION` ldflag.
196
+
197
+ ### `tool_result block must have a corresponding tool_use block`
198
+
199
+ Anthropic 400. Means the conversation-compression pipeline dropped
200
+ a `tool_use` while keeping its matching `tool_result`. Versions
201
+ prior to 1.3.2 had this bug; upgrade. If you're on 1.3.2+ and still
202
+ see it, file an issue with the conversation prefix.
203
+
204
+ ### `tool use concurrency issues`
205
+
206
+ Anthropic 400 surfaced in Claude Code as this message. Means the
207
+ parallel-tool-use case (multiple `tool_use` blocks in one assistant
208
+ message) isn't paired correctly with the multi-block tool_result
209
+ that follows. Versions prior to 1.3.2 had this bug; upgrade.
210
+
211
+ ### Cross-thread numbers are 0
212
+
213
+ Pre-migration data was ingested without the `is_sidechain` flag.
214
+ Run `observer backfill --is-sidechain` once to re-walk JSONL and
215
+ populate the flag on existing rows.
216
+
217
+ ### Migration error: `duplicate column name`
218
+
219
+ Race condition between concurrent daemon startups, fixed in 1.4.1.
220
+ Upgrade. If you still see it, run daemons serially: `observer
221
+ watch`, wait, then `observer dashboard`, then `observer proxy
222
+ start` (or just use `observer start` which runs all three in one
223
+ process — proxy + watcher + dashboard).
224
+
225
+ ### `observer start` log says only `proxy + observer` — no `:8081`
226
+
227
+ You're on a pre-1.4.7 build. Earlier versions ran only proxy +
228
+ watcher under `observer start`; the dashboard had to be started
229
+ separately via `observer dashboard --addr 127.0.0.1:8081`. Upgrade
230
+ to 1.4.7+ — the dashboard goroutine is now part of `observer start`
231
+ and the log line confirms all three: `proxy <addr> + watcher +
232
+ dashboard http://127.0.0.1:8081`. Pass `--no-dashboard` to opt out.
233
+
234
+ ### "address already in use" on port 8820
235
+
236
+ Another `observer proxy start` or `observer start` is still running.
237
+ Find it with `pgrep -af 'observer (proxy|start)'` and `kill <pid>`.
238
+ On macOS:
239
+
240
+ ```bash
241
+ lsof -nP -iTCP:8820 -sTCP:LISTEN
242
+ kill <pid>
243
+ ```
244
+
245
+ ### Dashboard port already in use
246
+
247
+ ```bash
248
+ observer dashboard --addr 127.0.0.1:8082 # pick a different port
249
+ # or
250
+ [dashboard]
251
+ port = 8082 # in config.toml
252
+ ```
253
+
254
+
255
+ ## Security and privacy
256
+
257
+ **Local-only. No telemetry. No remote anything.** The watcher, hook
258
+ handler, dashboard, MCP server, and CLI never make an outbound network
259
+ call on observer's behalf. The only code paths that touch the network
260
+ are the optional API proxy (which forwards **your** requests unchanged
261
+ to the AI provider you already use) and a handful of explicit opt-in
262
+ features (message-summary LLM, codegraph MCP, Teams org-server).
263
+
264
+ The full privacy statement — what observer stores, what it reads,
265
+ what it never stores, the explicit list of outbound-network call sites
266
+ gated behind config, and how to verify "no telemetry" yourself with
267
+ `grep`, `strings`, and a network-namespaced shell — lives in
268
+ [`PRIVACY.md`](https://github.com/marmutapp/superbased-observer/blob/main/PRIVACY.md).
269
+
270
+ Operational shorthand:
271
+
272
+ - **Local-only HTTP.** The proxy and dashboard bind to `127.0.0.1`
273
+ by default. Don't bind to `0.0.0.0` unless you've thought about
274
+ it — there's no auth.
275
+ - **Secrets scrubbing.** Tool inputs and outputs pass through
276
+ `internal/scrub/` before persistence; review the regex set if your
277
+ secrets follow non-default formats.
278
+ - **Database.** `~/.observer/observer.db` is a SQLite file with the
279
+ same security posture as your `~/.claude/` and `~/.codex/` session
280
+ logs (which already hold the same content). Encrypt the disk if
281
+ your threat model needs that.
282
+ - **Full delete.** `rm -rf ~/.observer/` removes everything observer
283
+ ever stored — no traces elsewhere on your system.
284
+
285
+
286
+ ## Source, contributing, license
287
+
288
+ - **Source**: https://github.com/marmutapp/superbased-observer
289
+ - **Specification**: `superbased-final-spec-v2.md` in the repo
290
+ - **Issues**: https://github.com/marmutapp/superbased-observer/issues
291
+ - **License**: [Apache 2.0](https://github.com/marmutapp/superbased-observer/blob/main/LICENSE)
292
+ - **Author**: Santosh Kathira <contact@marmut.app>
293
+
294
+ This npm package is a thin Node.js shim that resolves the right
295
+ pre-built binary at runtime and spawns it. Same shape as `esbuild` /
296
+ `swc` / `@biomejs/biome`. The Go source lives in the main repo;
297
+ binaries are cross-compiled per release tag via GitHub Actions and
298
+ published as `@superbased/observer-<platform>-<arch>` per-platform
299
+ packages.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superbased/observer",
3
- "version": "1.8.0",
3
+ "version": "1.8.2",
4
4
  "description": "SuperBased Observer — capture, normalize, compress, and analyze AI coding tool activity across Claude Code, Codex, Cursor, Cline/Roo, and Copilot.",
5
5
  "keywords": [
6
6
  "ai",
@@ -36,11 +36,11 @@
36
36
  "LICENSE"
37
37
  ],
38
38
  "optionalDependencies": {
39
- "@superbased/observer-linux-x64": "1.8.0",
40
- "@superbased/observer-linux-arm64": "1.8.0",
41
- "@superbased/observer-darwin-x64": "1.8.0",
42
- "@superbased/observer-darwin-arm64": "1.8.0",
43
- "@superbased/observer-win32-x64": "1.8.0"
39
+ "@superbased/observer-linux-x64": "1.8.2",
40
+ "@superbased/observer-linux-arm64": "1.8.2",
41
+ "@superbased/observer-darwin-x64": "1.8.2",
42
+ "@superbased/observer-darwin-arm64": "1.8.2",
43
+ "@superbased/observer-win32-x64": "1.8.2"
44
44
  },
45
45
  "scripts": {
46
46
  "test": "node bin/observer.js --version"