@superbased/observer 1.4.5 → 1.4.6
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 +718 -48
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -2,13 +2,50 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@superbased/observer)
|
|
4
4
|
[](https://www.apache.org/licenses/LICENSE-2.0)
|
|
5
|
+
[](https://github.com/marmutapp/superbased-observer)
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
**Capture, normalize, compress, and analyze every AI coding tool call you
|
|
8
|
+
run** — across Claude Code, Codex, Cursor, Cline / Roo Code, and GitHub
|
|
9
|
+
Copilot — in one local single-binary tool. No telemetry, no cloud, no
|
|
10
|
+
data leaves your machine.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
┌──────────────┐ ┌──────────────────────────────────┐
|
|
14
|
+
│ AI clients │ ─▶ │ observer proxy :8820 (local) │ ─▶ Anthropic / OpenAI
|
|
15
|
+
│ (Claude │ │ • intercepts every API call │
|
|
16
|
+
│ Code, │ │ • compresses conversations │
|
|
17
|
+
│ Cursor, │ │ • records api_turns + tokens │
|
|
18
|
+
│ Codex …) │ └──────────────┬───────────────────┘
|
|
19
|
+
│ │ ▼
|
|
20
|
+
│ │ ◀── observer mcp (stdio JSON-RPC) ◀── 12 cross-client tools
|
|
21
|
+
└──────┬───────┘
|
|
22
|
+
│ JSONL session logs
|
|
23
|
+
▼
|
|
24
|
+
┌──────────────────────────────────────────────────────────────┐
|
|
25
|
+
│ observer watch SQLite store :8081 dashboard │
|
|
26
|
+
│ • normalizes tool calls • cost over time │
|
|
27
|
+
│ • freshness, redundancy detection • compression savings │
|
|
28
|
+
│ • patterns, suggestions • discovery / waste │
|
|
29
|
+
└──────────────────────────────────────────────────────────────┘
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
# Table of contents
|
|
33
|
+
|
|
34
|
+
- [Install](#install)
|
|
35
|
+
- [Five-minute quickstart](#five-minute-quickstart)
|
|
36
|
+
- [Per-AI-client setup](#per-ai-client-setup)
|
|
37
|
+
- [Architecture in detail](#architecture-in-detail)
|
|
38
|
+
- [Dashboard tour](#dashboard-tour)
|
|
39
|
+
- [MCP tools reference](#mcp-tools-reference)
|
|
40
|
+
- [Compression mechanisms](#compression-mechanisms)
|
|
41
|
+
- [Cost and token math](#cost-and-token-math)
|
|
42
|
+
- [Terminology and glossary](#terminology-and-glossary)
|
|
43
|
+
- [CLI reference](#cli-reference)
|
|
44
|
+
- [Configuration](#configuration)
|
|
45
|
+
- [Troubleshooting](#troubleshooting)
|
|
46
|
+
- [Security and privacy](#security-and-privacy)
|
|
47
|
+
- [Source, contributing, license](#source-contributing-license)
|
|
9
48
|
|
|
10
|
-
Single binary. Local-only (no network calls from the observer
|
|
11
|
-
itself). Pure-Go, no CGO.
|
|
12
49
|
|
|
13
50
|
## Install
|
|
14
51
|
|
|
@@ -17,66 +54,699 @@ npm install -g @superbased/observer
|
|
|
17
54
|
observer --version
|
|
18
55
|
```
|
|
19
56
|
|
|
20
|
-
|
|
57
|
+
Pre-built binaries ship for:
|
|
21
58
|
|
|
22
59
|
| Platform | Architecture |
|
|
23
|
-
|
|
60
|
+
|-----------------------|--------------|
|
|
24
61
|
| Linux | x64, arm64 |
|
|
25
62
|
| macOS (Intel) | x64 |
|
|
26
63
|
| macOS (Apple Silicon) | arm64 |
|
|
27
64
|
| Windows | x64 |
|
|
28
65
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
66
|
+
The package uses the `optionalDependencies`-per-platform pattern (same
|
|
67
|
+
shape as `esbuild` / `swc` / `@biomejs/biome`) — only the binary
|
|
68
|
+
matching your machine downloads. No postinstall network calls, no
|
|
69
|
+
compile step.
|
|
32
70
|
|
|
33
|
-
|
|
71
|
+
If your platform isn't listed, build from source — instructions in
|
|
72
|
+
the [main repo](https://github.com/marmutapp/superbased-observer).
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
## Five-minute quickstart
|
|
34
76
|
|
|
35
77
|
```bash
|
|
36
|
-
# 1
|
|
78
|
+
# 1) Install + register hooks with whichever AI clients you use.
|
|
37
79
|
npm install -g @superbased/observer
|
|
38
|
-
observer init
|
|
80
|
+
observer init # interactive: pick clients
|
|
81
|
+
|
|
82
|
+
# 2) Start the long-running services (watcher + dashboard + proxy).
|
|
83
|
+
observer start & # all three in one process
|
|
84
|
+
# (or run them separately, see CLI ref)
|
|
85
|
+
|
|
86
|
+
# 3) Engage the proxy by pointing your AI client at the local URL.
|
|
87
|
+
# See "Per-AI-client setup" for the matching env var.
|
|
88
|
+
export ANTHROPIC_BASE_URL=http://127.0.0.1:8820 # Claude Code
|
|
89
|
+
export OPENAI_BASE_URL=http://127.0.0.1:8820/v1 # Codex / OpenAI
|
|
90
|
+
|
|
91
|
+
# 4) Open the dashboard.
|
|
92
|
+
open http://127.0.0.1:8081/ # macOS
|
|
93
|
+
xdg-open http://127.0.0.1:8081/ # Linux
|
|
94
|
+
start http://127.0.0.1:8081/ # Windows
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
After ten minutes of normal AI-coding usage, the dashboard will be
|
|
98
|
+
populated with cost over time, per-tool activity, compression
|
|
99
|
+
savings, and stale-reread waste signals.
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
## Per-AI-client setup
|
|
103
|
+
|
|
104
|
+
Different clients send to different upstreams. The local proxy on
|
|
105
|
+
`127.0.0.1:8820` handles all of them — routes by URL path. Set the
|
|
106
|
+
env var that matches your client(s); both can coexist on one machine.
|
|
107
|
+
|
|
108
|
+
| AI client | Env var |
|
|
109
|
+
|---------------------------------|-------------------------------------------------------|
|
|
110
|
+
| **Claude Code** | `ANTHROPIC_BASE_URL=http://127.0.0.1:8820` |
|
|
111
|
+
| **Cursor** (Anthropic mode) | `ANTHROPIC_BASE_URL=http://127.0.0.1:8820` |
|
|
112
|
+
| **Codex** | `OPENAI_BASE_URL=http://127.0.0.1:8820/v1` (note `/v1`) |
|
|
113
|
+
| **Cursor** (OpenAI mode) | `OPENAI_BASE_URL=http://127.0.0.1:8820/v1` |
|
|
114
|
+
| **Cline / Roo Code** | `ANTHROPIC_BASE_URL=...` or `OPENAI_BASE_URL=...` per provider |
|
|
115
|
+
| **GitHub Copilot** | not yet — JSONL adapter only (no proxy support) |
|
|
116
|
+
|
|
117
|
+
### Persistent setups
|
|
118
|
+
|
|
119
|
+
**Claude Code** (`~/.claude/settings.json`):
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"env": { "ANTHROPIC_BASE_URL": "http://127.0.0.1:8820" },
|
|
124
|
+
"hooks": { /* `observer init` writes these */ }
|
|
125
|
+
}
|
|
126
|
+
```
|
|
39
127
|
|
|
40
|
-
|
|
41
|
-
observer start &
|
|
128
|
+
**Codex** (`~/.codex/config.toml`):
|
|
42
129
|
|
|
43
|
-
|
|
44
|
-
|
|
130
|
+
```toml
|
|
131
|
+
[env]
|
|
132
|
+
OPENAI_BASE_URL = "http://127.0.0.1:8820/v1"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Shell rc** (`~/.bashrc` / `~/.zshrc`) — affects every program:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
45
138
|
export ANTHROPIC_BASE_URL=http://127.0.0.1:8820
|
|
46
|
-
# Codex / Cursor (OpenAI mode):
|
|
47
139
|
export OPENAI_BASE_URL=http://127.0.0.1:8820/v1
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
## Architecture in detail
|
|
144
|
+
|
|
145
|
+
Five components running side by side:
|
|
146
|
+
|
|
147
|
+
### 1. JSONL adapters (passive ingest)
|
|
148
|
+
|
|
149
|
+
Watch `~/.claude/projects/`, `~/.codex/sessions/`, etc. for new
|
|
150
|
+
session log lines. Normalize per-client tool names to a shared
|
|
151
|
+
taxonomy (`read_file`, `run_command`, `spawn_subagent`, …) and write
|
|
152
|
+
them into the actions table. **Always-on**, no setup required —
|
|
153
|
+
`observer init` registers the hooks once.
|
|
154
|
+
|
|
155
|
+
What this gets you: every tool call you've ever run, queryable.
|
|
156
|
+
|
|
157
|
+
### 2. API reverse proxy (active capture)
|
|
158
|
+
|
|
159
|
+
A localhost HTTP server (`127.0.0.1:8820`) you point your AI client
|
|
160
|
+
at via `ANTHROPIC_BASE_URL` / `OPENAI_BASE_URL`. Intercepts every
|
|
161
|
+
request before it hits Anthropic / OpenAI and:
|
|
162
|
+
|
|
163
|
+
- Records exact token usage from the upstream `usage` envelope (the
|
|
164
|
+
most accurate cost source — proxy beats JSONL parsing here).
|
|
165
|
+
- Runs the **conversation compression pipeline** to trim large
|
|
166
|
+
`tool_result` blocks and drop low-importance messages before
|
|
167
|
+
forwarding upstream.
|
|
168
|
+
- Captures the `cost_usd` the upstream reports (when present).
|
|
169
|
+
|
|
170
|
+
What this gets you: ground-truth cost numbers and conversation
|
|
171
|
+
compression savings you can measure.
|
|
172
|
+
|
|
173
|
+
### 3. SQLite store
|
|
174
|
+
|
|
175
|
+
A single file at `~/.observer/observer.db`. Tables include:
|
|
176
|
+
|
|
177
|
+
- `projects`, `sessions`, `actions` — the taxonomy
|
|
178
|
+
- `api_turns` — one row per proxy-intercepted upstream request
|
|
179
|
+
- `token_usage` — JSONL-derived token-row events (deduped via spec §A1)
|
|
180
|
+
- `file_state` — content hashes for freshness classification
|
|
181
|
+
- `compression_events` — per-event compression detail (post-migration 010)
|
|
182
|
+
- `project_patterns` — derived patterns from `observer patterns`
|
|
183
|
+
- `failure_context`, `action_excerpts` — diagnostic data
|
|
184
|
+
|
|
185
|
+
Pure-Go via `modernc.org/sqlite`, no CGO. WAL mode by default.
|
|
186
|
+
|
|
187
|
+
### 4. Local dashboard (`:8081`)
|
|
188
|
+
|
|
189
|
+
Eight tabs covering: Overview, Cost, Sessions, Actions, Tools,
|
|
190
|
+
Compression, Discovery, Patterns. See [Dashboard tour](#dashboard-tour).
|
|
191
|
+
|
|
192
|
+
Static HTML + Chart.js. No analytics, no external requests.
|
|
193
|
+
|
|
194
|
+
### 5. MCP server (stdio)
|
|
195
|
+
|
|
196
|
+
12 read-only tools the AI client itself can call mid-conversation —
|
|
197
|
+
`check_file_freshness`, `get_last_test_result`, `search_past_outputs`,
|
|
198
|
+
etc. Powers cross-client tool sharing: if Claude Code ran `go test`,
|
|
199
|
+
Cursor's MCP query for the latest test result will return Claude
|
|
200
|
+
Code's run. See [MCP tools reference](#mcp-tools-reference).
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
## Dashboard tour
|
|
204
|
+
|
|
205
|
+
Open `http://127.0.0.1:8081/` after `observer start`. Eight tabs.
|
|
206
|
+
|
|
207
|
+
### Overview tab
|
|
208
|
+
|
|
209
|
+
High-level snapshot of the selected window:
|
|
210
|
+
|
|
211
|
+
- **KPI tiles**: Sessions count, API turns (proxy-captured), Token
|
|
212
|
+
rows (JSONL-recovered), Failures (24h)
|
|
213
|
+
- **Cost over time** chart — daily token volume, split into the four
|
|
214
|
+
billable buckets (net input / cache read / cache write / output)
|
|
215
|
+
- **Actions over time** chart — total actions vs failures
|
|
216
|
+
- **Top models (by tokens)** chart — top-8 models stacked by net
|
|
217
|
+
input / cache read / output
|
|
218
|
+
- **Top tools (actions over time)** — per-AI-client stacked-area
|
|
219
|
+
showing when each client is active
|
|
220
|
+
|
|
221
|
+
### Cost tab
|
|
222
|
+
|
|
223
|
+
Per-model breakdown over the selected window. Tokens split into the
|
|
224
|
+
four billing buckets, with computed dollar cost and a reliability
|
|
225
|
+
flag (`high` = upstream-reported, `medium` = computed, `low` =
|
|
226
|
+
estimated, `unreliable` = no pricing entry). Daily stacked-bar chart
|
|
227
|
+
of token volume per day.
|
|
228
|
+
|
|
229
|
+
Hover any column header for tooltip; click for the full definition
|
|
230
|
+
in the help drawer.
|
|
231
|
+
|
|
232
|
+
### Sessions tab
|
|
233
|
+
|
|
234
|
+
One row per AI-coding session. Each session has a stable ID, a tool
|
|
235
|
+
(claude-code / cursor / codex / cline / copilot), a working-directory
|
|
236
|
+
project, action count, sub-agent action count (when the session
|
|
237
|
+
spawned sub-agents via the `Agent` tool), and — if `observer score`
|
|
238
|
+
has run — quality / errors / redundancy ratios.
|
|
239
|
+
|
|
240
|
+
Click a row to open the session-detail modal: action breakdown,
|
|
241
|
+
token buckets, cost, recent actions.
|
|
242
|
+
|
|
243
|
+
### Actions tab
|
|
244
|
+
|
|
245
|
+
The flat firehose: every recorded tool call, normalized across
|
|
246
|
+
adapters. Filter by action type (`read_file`, `write_file`,
|
|
247
|
+
`run_command`, `spawn_subagent`, `todo_update`, `mcp_call`, …).
|
|
248
|
+
Pagination caps at 50 rows per page; total count is shown next to
|
|
249
|
+
the heading.
|
|
250
|
+
|
|
251
|
+
### Tools tab
|
|
252
|
+
|
|
253
|
+
Per-AI-client (the *client* — claude-code / cursor / codex / etc., not
|
|
254
|
+
the per-tool name) aggregates plus three views:
|
|
255
|
+
|
|
256
|
+
- **KPI tiles**: Total actions, Distinct tools, Overall success rate,
|
|
257
|
+
Busiest tool
|
|
258
|
+
- **Activity over time** stacked-area showing per-tool action volume
|
|
259
|
+
per day
|
|
260
|
+
- **Action-type mix per tool** horizontal stacked bar — what each
|
|
261
|
+
tool actually does (read_file vs edit_file vs run_command vs
|
|
262
|
+
search_text vs spawn_subagent)
|
|
263
|
+
- The full per-tool aggregate table with first/last seen
|
|
264
|
+
|
|
265
|
+
### Compression tab
|
|
266
|
+
|
|
267
|
+
How many tokens and dollars the conversation-compression pipeline
|
|
268
|
+
saved by trimming requests before forwarding upstream:
|
|
269
|
+
|
|
270
|
+
- **KPI tiles**: Tokens saved (est.), Dollars saved (est.), Bytes
|
|
271
|
+
saved, Turns compressed
|
|
272
|
+
- **Savings per day** chart — daily tokens-saved (left axis) and
|
|
273
|
+
bytes-saved (right axis)
|
|
274
|
+
- **Savings by mechanism** stacked bar — segments per mechanism
|
|
275
|
+
(json / code / logs / text / diff / html / drop). **Toggle the
|
|
276
|
+
y-axis between tokens and bytes** with the chart-header switch.
|
|
277
|
+
- **Per-model breakdown table** — tokens saved ~, $ saved ~, bytes
|
|
278
|
+
saved, saved %, turns, tool-results compressed, dropped, markers
|
|
279
|
+
- **Recent compression events** — paginated per-event detail with
|
|
280
|
+
mechanism, original / compressed / saved bytes, message slot, importance
|
|
281
|
+
score (for drops), and a **Source** column showing whether the
|
|
282
|
+
event came from a main-thread or sub-agent runtime call
|
|
283
|
+
|
|
284
|
+
### Discovery tab
|
|
285
|
+
|
|
286
|
+
Wasted-effort signals:
|
|
287
|
+
|
|
288
|
+
- **Stale rereads** — files re-read after they changed inside the
|
|
289
|
+
same session. KPI tiles show count, ~Tokens wasted, ~$ wasted (at
|
|
290
|
+
your blended input rate), affected files. The **CROSS-THREAD**
|
|
291
|
+
column flags re-reads that crossed the parent ↔ sub-agent
|
|
292
|
+
boundary — these are the "pass content via Agent's prompt
|
|
293
|
+
parameter" candidates.
|
|
294
|
+
- **Repeated commands** — commands run multiple times with no
|
|
295
|
+
relevant inputs changed in between (e.g. you ran `go test` three
|
|
296
|
+
times without editing anything between runs).
|
|
297
|
+
- **Cross-tool overlap** — files touched by ≥2 AI clients in the
|
|
298
|
+
window (e.g. claude-code AND cursor both edited `auth.ts`). This
|
|
299
|
+
is the visible side of cross-platform tool-call sharing via the
|
|
300
|
+
MCP server.
|
|
301
|
+
|
|
302
|
+
### Patterns tab
|
|
303
|
+
|
|
304
|
+
Repeatable behaviours the observer noticed across your sessions —
|
|
305
|
+
"after running `go test`, you almost always run `go vet`", "when
|
|
306
|
+
working on `auth.ts`, you also touch `login.tsx`", etc. Each pattern
|
|
307
|
+
has a confidence score (decay-weighted: more observations + recent
|
|
308
|
+
observations push it higher) and an observation count.
|
|
309
|
+
|
|
310
|
+
`observer patterns` derives them; `observer suggest` writes the
|
|
311
|
+
high-confidence ones into `CLAUDE.md` / `AGENTS.md` / `.cursorrules`
|
|
312
|
+
so new sessions inherit your habits.
|
|
313
|
+
|
|
314
|
+
### Help drawer
|
|
315
|
+
|
|
316
|
+
Press `?` anywhere on the dashboard or click the **? Help** button in
|
|
317
|
+
the topbar. Every column header, KPI tile, chart label, and filter
|
|
318
|
+
control on every tab is annotated — hover any element to see a
|
|
319
|
+
one-liner tooltip; click to open the drawer at the matching glossary
|
|
320
|
+
entry.
|
|
321
|
+
|
|
322
|
+
The drawer has full descriptions, formulas, data sources, examples,
|
|
323
|
+
"why it matters", "what to do", and cross-links. Search at the top.
|
|
324
|
+
Deep-linkable via URL fragment — `#help/metric.stale_count` opens
|
|
325
|
+
the drawer at that entry.
|
|
326
|
+
|
|
327
|
+
Each compression mechanism (json / code / logs / text / diff / html
|
|
328
|
+
/ drop) has a "Full methodology · see more" expandable section
|
|
329
|
+
explaining the actual algorithm.
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
## MCP tools reference
|
|
333
|
+
|
|
334
|
+
Every AI client running through `observer init` gets these 12 tools
|
|
335
|
+
registered as an MCP server. They're **read-only** queries against
|
|
336
|
+
the unified database, so any agent can read any other agent's
|
|
337
|
+
recorded work — true cross-platform tool-call sharing.
|
|
338
|
+
|
|
339
|
+
| Tool | Purpose |
|
|
340
|
+
|-----------------------------------|---------|
|
|
341
|
+
| `check_file_freshness` | Has this file been read in the current session? Has it changed since? |
|
|
342
|
+
| `get_file_history` | Full read/edit history of a file across all sessions and clients |
|
|
343
|
+
| `get_session_summary` | Roll-up stats for a session: action count, success rate, cost, token buckets |
|
|
344
|
+
| `search_past_outputs` | Full-text search across recorded tool outputs (FTS5-indexed) |
|
|
345
|
+
| `get_last_test_result` | Most recent `go test` / `npm test` / `pytest` etc. output |
|
|
346
|
+
| `get_failure_context` | Recent failures: which command, which file, which session |
|
|
347
|
+
| `get_action_details` | One specific action's full record (target, args, output excerpt) |
|
|
348
|
+
| `check_command_freshness` | Has this command been run in the current session? With what result? |
|
|
349
|
+
| `get_session_recovery_context` | Recent activity for resuming a paused session |
|
|
350
|
+
| `get_project_patterns` | High-confidence patterns derived from this project's history |
|
|
351
|
+
| `get_cost_summary` | Daily / per-model / per-session cost rollups |
|
|
352
|
+
| `get_redundancy_report` | Stale rereads, repeated commands, cross-tool overlap for the project |
|
|
353
|
+
|
|
354
|
+
**Cross-tool sharing**: when `observer init` registers the MCP server
|
|
355
|
+
with Claude Code AND Cursor (and Codex…), all of them call the same
|
|
356
|
+
12 tools against the same database. Cursor's `get_last_test_result`
|
|
357
|
+
returns Claude Code's last test run; Codex's `check_file_freshness`
|
|
358
|
+
reflects edits made by Cursor.
|
|
359
|
+
|
|
48
360
|
|
|
49
|
-
|
|
50
|
-
|
|
361
|
+
## Compression mechanisms
|
|
362
|
+
|
|
363
|
+
The conversation-compression pipeline runs inside the proxy on every
|
|
364
|
+
upstream request. It tries to fit the request body within
|
|
365
|
+
`target_ratio × original_bytes` (default 0.85) without breaking the
|
|
366
|
+
conversation's referential integrity.
|
|
367
|
+
|
|
368
|
+
Two passes, in order:
|
|
369
|
+
|
|
370
|
+
### Pass 1 — per-content-type compression
|
|
371
|
+
|
|
372
|
+
Each `tool_result` block is sniffed for content type, then routed to
|
|
373
|
+
a content-aware compressor. Six compressors:
|
|
374
|
+
|
|
375
|
+
| Mechanism | What it does | When it fires |
|
|
376
|
+
|-----------|--------------|---------------|
|
|
377
|
+
| **json** | Replaces every scalar value with a type sentinel (`"<string>"`, `"<number>"`, …) preserving structure (keys, arrays, nesting). Arrays of length > 1 collapse to one element with `_len: N`. | API responses, structured logs, telemetry exports. JSON tool_results are usually the biggest savings target. |
|
|
378
|
+
| **code** | Heuristic skeleton: keeps top-of-file imports + signature lines (function / method / class / struct / interface / type), drops bodies. | Source code files. **Opt-in only** (excluded from default `compress_types`) because the model often needs to read full code. |
|
|
379
|
+
| **logs** | Two-pass: collapses adjacent identical lines to `<line> [×N]`, then head+tail-truncates to 200 lines if still long. | Log-shaped output — `go test ./...`, `npm run build`, polling/retry loops. Lossless on distinct lines; only the truncate pass is lossy. |
|
|
380
|
+
| **text** | Catch-all for content not classified as code/json/logs/diff/html. Head+tail truncation: keeps 40 + 40 lines on inputs over 80 lines. | Markdown bodies, README excerpts, narrative descriptions. |
|
|
381
|
+
| **diff** | Strips unified-diff context beyond ±1 line of each change. Keeps every header, every `+`/`-` line, drops the rest with elision markers. | `git diff`, patch tool outputs. Lossless on changes; lossy only on the cheap-to-rebuild context. |
|
|
382
|
+
| **html** | Three regex passes: strips `<script>`, `<style>`, and HTML comments. Tag attributes + visible text + structural elements survive. | `web_fetch` results pulling whole HTML pages — usually 80%+ scripts/styles. |
|
|
383
|
+
|
|
384
|
+
### Pass 2 — drop with marker
|
|
385
|
+
|
|
386
|
+
If Pass 1's compressed body is still over budget, the budget enforcer
|
|
387
|
+
ranks remaining messages by **importance score** (a deterministic
|
|
388
|
+
weighted sum) and drops the lowest-scored non-preserved ones until
|
|
389
|
+
the budget is met. Each dropped message is replaced by a single
|
|
390
|
+
marker block (a placeholder text) so the conversation flow stays
|
|
391
|
+
intact for the model.
|
|
392
|
+
|
|
393
|
+
**Importance score** = `0.4 × recency + 0.3 × reference + 0.15 × density + 0.15 × role`
|
|
394
|
+
|
|
395
|
+
- **Recency** = `(i+1) / n` — newest message scores 1.0, oldest scores 1/n
|
|
396
|
+
- **Reference** = `1.0` if any of the message's `tool_use_ids` is
|
|
397
|
+
cited by a later `tool_result`, OR any of its `referenced_ids` points
|
|
398
|
+
to a live tool_use; `0.0` otherwise. Tool-pair-live messages always
|
|
399
|
+
get full weight regardless of position.
|
|
400
|
+
- **Density** = fraction of non-whitespace runes (whitespace-padded
|
|
401
|
+
outputs get dropped first)
|
|
402
|
+
- **Role** = `system 1.0`, `user 0.9`, `assistant 0.7`, `tool 0.5`
|
|
403
|
+
(tool outputs are the most-compressible by policy)
|
|
404
|
+
|
|
405
|
+
**Preserved messages** (never droppable):
|
|
406
|
+
- The last `PreserveLastN` messages (default 4)
|
|
407
|
+
- Any `system` role message
|
|
408
|
+
- **Tool-pair-live messages**: any message whose `tool_use_id` is
|
|
409
|
+
referenced by a later tool_result (parent side), AND any
|
|
410
|
+
`tool_result` message whose `referenced_id` points to a live
|
|
411
|
+
tool_use (consumer side)
|
|
412
|
+
|
|
413
|
+
Tool-pair preservation is symmetric — dropping either side leaves an
|
|
414
|
+
orphan that Anthropic rejects with 400.
|
|
415
|
+
|
|
416
|
+
### Per-event detail
|
|
417
|
+
|
|
418
|
+
Every drop and every per-type compression is recorded as a row in
|
|
419
|
+
the `compression_events` table (post migration 010). The Compression
|
|
420
|
+
tab's "Recent compression events" view surfaces these with
|
|
421
|
+
mechanism, original / compressed / saved bytes, message slot, and
|
|
422
|
+
importance score (for drops).
|
|
423
|
+
|
|
424
|
+
### Tuning
|
|
425
|
+
|
|
426
|
+
`observer config` settings (in `~/.observer/config.toml`):
|
|
427
|
+
|
|
428
|
+
```toml
|
|
429
|
+
[compression.conversation]
|
|
430
|
+
enabled = true
|
|
431
|
+
target_ratio = 0.85
|
|
432
|
+
mode = "token" # or "cache" — restricts drops to tail half
|
|
433
|
+
preserve_last_n = 4
|
|
434
|
+
prefix_bytes = 8192
|
|
435
|
+
compress_types = ["json", "logs", "text"] # add "code", "diff", "html" to opt in
|
|
436
|
+
min_bytes_to_compress = 1024
|
|
437
|
+
|
|
438
|
+
[compression.conversation.weights]
|
|
439
|
+
recency = 0.4
|
|
440
|
+
reference = 0.3
|
|
441
|
+
density = 0.15
|
|
442
|
+
role = 0.15
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
High importance scores on dropped events (≥0.5) suggest the threshold
|
|
446
|
+
is too aggressive — raise `target_ratio` (e.g. 0.9 or 0.95).
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
## Cost and token math
|
|
450
|
+
|
|
451
|
+
Anthropic's usage envelope reports four token buckets per request,
|
|
452
|
+
each at a different rate:
|
|
453
|
+
|
|
454
|
+
| Bucket | What it is | Bills at |
|
|
455
|
+
|--------------------|------------------------------------------------------------------------------|-----------------------------|
|
|
456
|
+
| `net_input` | Fresh prompt tokens not served from cache | model's standard input rate |
|
|
457
|
+
| `cache_read` | Prompt tokens served from Anthropic's ephemeral cache | ~10% of input rate |
|
|
458
|
+
| `cache_creation` | Tokens written to ephemeral cache | 1.25× input (5m tier) or 2× input (1h tier) |
|
|
459
|
+
| `output` | What the model generated | typically 5× input rate |
|
|
460
|
+
|
|
461
|
+
`prompt_context = net_input + cache_read + cache_creation`
|
|
462
|
+
`total_tokens = prompt_context + output`
|
|
463
|
+
|
|
464
|
+
The cost engine (`internal/intelligence/cost`) computes USD via:
|
|
465
|
+
|
|
466
|
+
```
|
|
467
|
+
cost_usd = (net_input × p.input + cache_read × p.cache_read +
|
|
468
|
+
cache_creation_5m × p.cache_creation +
|
|
469
|
+
cache_creation_1h × p.cache_creation_1h +
|
|
470
|
+
output × p.output) ÷ 1,000,000
|
|
51
471
|
```
|
|
52
472
|
|
|
53
|
-
|
|
473
|
+
When the upstream API returns `cost_usd` in the response envelope
|
|
474
|
+
(proxy-sourced rows), that value is preferred over the computed one —
|
|
475
|
+
ground truth, reliability=high.
|
|
476
|
+
|
|
477
|
+
### Blended input rate
|
|
478
|
+
|
|
479
|
+
The Discovery tab's "~$ wasted" tile uses a **blended input rate**
|
|
480
|
+
computed from your last-30d api_turns mix: each model's input rate
|
|
481
|
+
weighted by the prompt-token volume it consumed. Example: if you
|
|
482
|
+
spent 70% of prompt tokens on opus-4-7 ($15/1M) and 30% on
|
|
483
|
+
haiku-4-5 ($1/1M), the blended rate is `0.7 × 15 + 0.3 × 1 = $10.80/1M`.
|
|
484
|
+
|
|
485
|
+
Falls back to $3/1M (claude-sonnet-4 input) on fresh installs with
|
|
486
|
+
no proxy data.
|
|
54
487
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
488
|
+
### JSONL dedup
|
|
489
|
+
|
|
490
|
+
When the proxy isn't engaged, observer falls back to parsing the AI
|
|
491
|
+
client's on-disk session log. Clients echo the same cumulative usage
|
|
492
|
+
on every content block of a multi-block response, so naive parsing
|
|
493
|
+
counts one API call 2-4×. Two layers of dedup catch this:
|
|
494
|
+
|
|
495
|
+
1. **Adapter-level**: dedupes on Anthropic `message.id` at write time
|
|
496
|
+
2. **Cost-engine-level**: dedupes on `(source_file, model, timestamp-bucketed-to-minute, tokens)` at read time
|
|
497
|
+
|
|
498
|
+
Migration 007 ran a one-time pass collapsing pre-fix duplicates.
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
## Terminology and glossary
|
|
502
|
+
|
|
503
|
+
Quick reference; the in-platform help drawer (press `?` on the
|
|
504
|
+
dashboard) has the full versions with cross-links.
|
|
505
|
+
|
|
506
|
+
- **Action** — one normalized tool call recorded by an adapter. Action
|
|
507
|
+
types are taxonomic and cross-client: `read_file`, `write_file`,
|
|
508
|
+
`edit_file`, `run_command`, `search_text`, `search_files`,
|
|
509
|
+
`web_search`, `web_fetch`, `mcp_call`, `spawn_subagent`,
|
|
510
|
+
`todo_update`, `ask_user`, `task_complete`, `user_prompt`,
|
|
511
|
+
`unknown`.
|
|
512
|
+
- **API turn** — one HTTP request captured by the local proxy. Records
|
|
513
|
+
one row in `api_turns` per request, with the upstream usage envelope
|
|
514
|
+
intact.
|
|
515
|
+
- **Cache 5m vs 1h tier** — Anthropic's prompt cache has two TTLs.
|
|
516
|
+
Default is 5 minutes; `cache_control: {type: ephemeral, ttl: 3600}`
|
|
517
|
+
extends to 1 hour at 2× the write cost. Reads bill the same rate
|
|
518
|
+
regardless of tier.
|
|
519
|
+
- **Compression event** — one individual compression decision (one
|
|
520
|
+
per-type compress, or one drop) recorded post migration 010.
|
|
58
521
|
- **Conversation compression** — pre-forward trimming of API request
|
|
59
|
-
bodies.
|
|
60
|
-
|
|
61
|
-
- **
|
|
62
|
-
|
|
63
|
-
`
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
522
|
+
bodies. Pass 1 = per-content-type compression, Pass 2 = drop with
|
|
523
|
+
marker. See [Compression mechanisms](#compression-mechanisms).
|
|
524
|
+
- **Cross-platform tool calling** — every AI client connected via
|
|
525
|
+
`observer init` can call the 12 MCP tools against the unified
|
|
526
|
+
database. So Cursor's `get_last_test_result` can return a `go test`
|
|
527
|
+
Claude Code ran an hour earlier.
|
|
528
|
+
- **Cross-thread reread** — the parent thread re-reads a file the
|
|
529
|
+
sub-agent already saw (or vice versa) within the same session. Fix:
|
|
530
|
+
pass content via the Agent tool's `prompt` parameter rather than
|
|
531
|
+
letting the child re-read.
|
|
532
|
+
- **Freshness state** — per-read tag from the freshness engine: `fresh`
|
|
533
|
+
(first read in this session, OR re-read with same content),
|
|
534
|
+
`stale` (re-read after change in same session), `missing` (file no
|
|
535
|
+
longer exists), `modified-elsewhere` (file changed by something
|
|
536
|
+
other than an observable AI action).
|
|
537
|
+
- **Mechanism** — one of `json`, `code`, `logs`, `text`, `diff`,
|
|
538
|
+
`html` (per-content-type compressor) or `drop` (low-importance
|
|
539
|
+
message replaced by a marker).
|
|
540
|
+
- **Pattern** — a derived behaviour: `command_pair` (X often
|
|
541
|
+
followed by Y), `cross_tool_file` (file touched by multiple
|
|
542
|
+
clients), `knowledge_snippet` (consistent topic-specific habit),
|
|
543
|
+
`failure_correlation` (X often precedes a failure of Y),
|
|
544
|
+
`session_summary`. Each has a decay-weighted confidence score 0-1.
|
|
545
|
+
- **Project** — working-directory root that owns sessions and
|
|
546
|
+
actions. Derived from cwd at session start; `/.git/worktrees/...`
|
|
547
|
+
paths fold back to the working-tree root.
|
|
548
|
+
- **Proxy vs JSONL** — proxy intercepts upstream HTTP calls (ground
|
|
549
|
+
truth, reliability=high). JSONL parses the AI client's on-disk
|
|
550
|
+
session log (works without configuring a base URL, but client
|
|
551
|
+
echoes cumulative usage on every block, requiring dedup —
|
|
552
|
+
reliability=unreliable for token counts on Claude Code).
|
|
553
|
+
- **Reliability** — cost-engine confidence: `high` (upstream-
|
|
554
|
+
reported), `medium` (computed from known pricing), `low` (some
|
|
555
|
+
buckets estimated), `unreliable` (no pricing entry).
|
|
556
|
+
- **Session** — one continuous AI-coding conversation in a single
|
|
557
|
+
tool, scoped to one working directory. Has a stable ID (Claude
|
|
558
|
+
Code's UUID, Codex's rollout ID, …).
|
|
559
|
+
- **Sidechain** — actions emitted inside a sub-agent runtime spawned
|
|
560
|
+
via the parent's `Agent` tool. Sub-agents share the parent's
|
|
561
|
+
session_id; the `is_sidechain` column distinguishes them. The
|
|
562
|
+
Discovery tab's CROSS-THREAD column counts stale rereads that
|
|
563
|
+
crossed this boundary.
|
|
564
|
+
- **Stale reread** — same-session re-read of a file whose content
|
|
565
|
+
changed between reads. Cross-session reads are excluded (a fresh
|
|
566
|
+
session has no memory of a prior session's read).
|
|
567
|
+
- **Tool** — in this dashboard, "tool" means the *AI client*
|
|
568
|
+
(claude-code, cursor, codex, cline, copilot), not the per-tool
|
|
569
|
+
name (`read_file`, `run_command`). The latter is "Tool name" on
|
|
570
|
+
the Actions tab.
|
|
571
|
+
- **Tool-pair integrity** — Anthropic requires every `tool_result`
|
|
572
|
+
block to have a corresponding `tool_use` block in a preceding
|
|
573
|
+
message. The compression pipeline preserves both sides of every
|
|
574
|
+
live pair to satisfy this constraint.
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
## CLI reference
|
|
578
|
+
|
|
579
|
+
Every command supports `--help` for the full surface.
|
|
580
|
+
|
|
581
|
+
| Subcommand | Purpose |
|
|
582
|
+
|------------------------------------|---------|
|
|
583
|
+
| `observer init` | Register hooks + MCP server with installed AI clients |
|
|
584
|
+
| `observer uninstall` | Reverse `observer init` |
|
|
585
|
+
| `observer start` | Run watcher + dashboard + proxy in one process (recommended) |
|
|
586
|
+
| `observer watch` | Long-running JSONL watcher only |
|
|
587
|
+
| `observer dashboard --addr ADDR` | HTTP dashboard only |
|
|
588
|
+
| `observer proxy start` | Reverse proxy only |
|
|
589
|
+
| `observer scan` | One-shot ingest of existing JSONL files (catch-up after install) |
|
|
590
|
+
| `observer status` | DB stats + recent activity |
|
|
591
|
+
| `observer doctor` | Diagnostic — checks paths, schemas, hook registration |
|
|
592
|
+
| `observer tail` | Live tail of incoming events |
|
|
593
|
+
| `observer cost` | Per-model cost summary CLI |
|
|
594
|
+
| `observer score` | Compute quality_score / error_rate / redundancy_ratio for sessions |
|
|
595
|
+
| `observer discover` | Stale rereads + repeated commands report (CLI version of the Discovery tab) |
|
|
596
|
+
| `observer patterns` | Derive patterns from session history |
|
|
597
|
+
| `observer learn` | Adapter for ingesting external JSONL exports |
|
|
598
|
+
| `observer suggest` | Write high-confidence patterns into CLAUDE.md / AGENTS.md / .cursorrules |
|
|
599
|
+
| `observer summarize` | Roll-up summary across sessions |
|
|
600
|
+
| `observer export` | Export DB to xlsx / json |
|
|
601
|
+
| `observer prune` | Manual retention pass (delete old data) |
|
|
602
|
+
| `observer backfill --is-sidechain` | Re-walk JSONL to populate is_sidechain on pre-migration rows |
|
|
603
|
+
| `observer metrics` | Prometheus-format metrics endpoint |
|
|
604
|
+
| `observer serve` | MCP server (stdio JSON-RPC) — usually invoked by `observer init` registration |
|
|
605
|
+
| `observer tail` | Live event stream |
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
## Configuration
|
|
609
|
+
|
|
610
|
+
`~/.observer/config.toml` — created with defaults on first run.
|
|
611
|
+
|
|
612
|
+
```toml
|
|
613
|
+
[paths]
|
|
614
|
+
db_path = "~/.observer/observer.db"
|
|
615
|
+
log_dir = "~/.observer/logs"
|
|
616
|
+
|
|
617
|
+
[proxy]
|
|
618
|
+
listen_addr = "127.0.0.1"
|
|
619
|
+
port = 8820
|
|
620
|
+
anthropic_upstream = "https://api.anthropic.com"
|
|
621
|
+
openai_upstream = "https://api.openai.com"
|
|
622
|
+
|
|
623
|
+
[dashboard]
|
|
624
|
+
listen_addr = "127.0.0.1"
|
|
625
|
+
port = 8081
|
|
626
|
+
|
|
627
|
+
[compression.conversation]
|
|
628
|
+
enabled = true
|
|
629
|
+
target_ratio = 0.85
|
|
630
|
+
mode = "token"
|
|
631
|
+
preserve_last_n = 4
|
|
632
|
+
prefix_bytes = 8192
|
|
633
|
+
compress_types = ["json", "logs", "text"]
|
|
634
|
+
min_bytes_to_compress = 1024
|
|
635
|
+
|
|
636
|
+
[compression.conversation.weights]
|
|
637
|
+
recency = 0.4
|
|
638
|
+
reference = 0.3
|
|
639
|
+
density = 0.15
|
|
640
|
+
role = 0.15
|
|
641
|
+
|
|
642
|
+
[compression.shell]
|
|
643
|
+
enabled = true
|
|
644
|
+
# per-command filters configured under [compression.shell.filters]
|
|
645
|
+
|
|
646
|
+
[retention]
|
|
647
|
+
prune_on_startup = true
|
|
648
|
+
max_actions = 5_000_000
|
|
649
|
+
max_age_days = 365
|
|
650
|
+
|
|
651
|
+
[pricing]
|
|
652
|
+
# Per-model overrides if the baked-in pricing is wrong for you.
|
|
653
|
+
# [pricing.models."claude-opus-4-7"]
|
|
654
|
+
# input = 15
|
|
655
|
+
# output = 75
|
|
656
|
+
# cache_read = 1.5
|
|
657
|
+
# cache_creation = 18.75
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
## Troubleshooting
|
|
662
|
+
|
|
663
|
+
### Empty dashboard / "No proxy traffic"
|
|
664
|
+
|
|
665
|
+
The JSONL adapter populates passively after `observer init`, but
|
|
666
|
+
ground-truth cost / compression numbers require the proxy. Set
|
|
667
|
+
`ANTHROPIC_BASE_URL=http://127.0.0.1:8820` (Claude Code) or
|
|
668
|
+
`OPENAI_BASE_URL=http://127.0.0.1:8820/v1` (Codex) in the shell
|
|
669
|
+
that launches your AI client.
|
|
670
|
+
|
|
671
|
+
Verify with `observer status | grep api_turns` — count should
|
|
672
|
+
climb during AI-client activity.
|
|
673
|
+
|
|
674
|
+
### `observer --version` says `dev`
|
|
675
|
+
|
|
676
|
+
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.
|
|
677
|
+
|
|
678
|
+
### `tool_result block must have a corresponding tool_use block`
|
|
679
|
+
|
|
680
|
+
Anthropic 400. Means the conversation-compression pipeline dropped
|
|
681
|
+
a `tool_use` while keeping its matching `tool_result`. Versions
|
|
682
|
+
prior to 1.3.2 had this bug; upgrade. If you're on 1.3.2+ and still
|
|
683
|
+
see it, file an issue with the conversation prefix.
|
|
684
|
+
|
|
685
|
+
### `tool use concurrency issues`
|
|
686
|
+
|
|
687
|
+
Anthropic 400 surfaced in Claude Code as this message. Means the
|
|
688
|
+
parallel-tool-use case (multiple `tool_use` blocks in one assistant
|
|
689
|
+
message) isn't paired correctly with the multi-block tool_result
|
|
690
|
+
that follows. Versions prior to 1.3.2 had this bug; upgrade.
|
|
691
|
+
|
|
692
|
+
### Cross-thread numbers are 0
|
|
693
|
+
|
|
694
|
+
Pre-migration data was ingested without the `is_sidechain` flag.
|
|
695
|
+
Run `observer backfill --is-sidechain` once to re-walk JSONL and
|
|
696
|
+
populate the flag on existing rows.
|
|
697
|
+
|
|
698
|
+
### Migration error: `duplicate column name`
|
|
699
|
+
|
|
700
|
+
Race condition between concurrent daemon startups, fixed in 1.4.1.
|
|
701
|
+
Upgrade. If you still see it, run daemons serially: `observer
|
|
702
|
+
watch`, wait, then `observer dashboard`, then `observer proxy
|
|
703
|
+
start` (or just use `observer start` which runs all three in one
|
|
704
|
+
process).
|
|
705
|
+
|
|
706
|
+
### Dashboard port already in use
|
|
707
|
+
|
|
708
|
+
```bash
|
|
709
|
+
observer dashboard --addr 127.0.0.1:8082 # pick a different port
|
|
710
|
+
# or
|
|
711
|
+
[dashboard]
|
|
712
|
+
port = 8082 # in config.toml
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
## Security and privacy
|
|
717
|
+
|
|
718
|
+
- **No telemetry**. The observer never makes outbound network calls
|
|
719
|
+
except: (a) the proxy forwarding to the upstream API on your
|
|
720
|
+
behalf, (b) optional codegraph-MCP integration if you've configured
|
|
721
|
+
it. Both are explicit.
|
|
722
|
+
- **Local-only HTTP**. The proxy and dashboard bind to
|
|
723
|
+
`127.0.0.1` by default. Don't bind to `0.0.0.0` unless you've
|
|
724
|
+
thought about it — there's no auth.
|
|
725
|
+
- **Secrets scrubbing**. Tool inputs and outputs are passed through
|
|
726
|
+
a configurable scrubber (`internal/scrub`) that redacts API keys,
|
|
727
|
+
bearer tokens, and other obvious secrets before persistence. Not a
|
|
728
|
+
guarantee — review the rules in `~/.observer/config.toml` for your
|
|
729
|
+
own secret formats.
|
|
730
|
+
- **Database**. `~/.observer/observer.db` is a SQLite file. Owns
|
|
731
|
+
the same security as your `~/.claude/` and `~/.codex/` session
|
|
732
|
+
logs (which already contain the same content). Encrypt the disk
|
|
733
|
+
if your threat model needs that.
|
|
734
|
+
- **Logs**. `~/.observer/logs/` carries operational logs (start /
|
|
735
|
+
stop, errors, retention). Not request bodies — those are in the
|
|
736
|
+
DB only.
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
## Source, contributing, license
|
|
740
|
+
|
|
741
|
+
- **Source**: https://github.com/marmutapp/superbased-observer
|
|
742
|
+
- **Specification**: `superbased-final-spec-v2.md` in the repo
|
|
743
|
+
- **Issues**: https://github.com/marmutapp/superbased-observer/issues
|
|
744
|
+
- **License**: [Apache 2.0](https://github.com/marmutapp/superbased-observer/blob/main/LICENSE)
|
|
745
|
+
- **Author**: Santosh Kathira <contact@marmut.app>
|
|
746
|
+
|
|
747
|
+
This npm package is a thin Node.js shim that resolves the right
|
|
748
|
+
pre-built binary at runtime and spawns it. Same shape as `esbuild` /
|
|
749
|
+
`swc` / `@biomejs/biome`. The Go source lives in the main repo;
|
|
750
|
+
binaries are cross-compiled per release tag via GitHub Actions and
|
|
751
|
+
published as `@superbased/observer-<platform>-<arch>` per-platform
|
|
752
|
+
packages.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superbased/observer",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.6",
|
|
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.4.
|
|
40
|
-
"@superbased/observer-linux-arm64": "1.4.
|
|
41
|
-
"@superbased/observer-darwin-x64": "1.4.
|
|
42
|
-
"@superbased/observer-darwin-arm64": "1.4.
|
|
43
|
-
"@superbased/observer-win32-x64": "1.4.
|
|
39
|
+
"@superbased/observer-linux-x64": "1.4.6",
|
|
40
|
+
"@superbased/observer-linux-arm64": "1.4.6",
|
|
41
|
+
"@superbased/observer-darwin-x64": "1.4.6",
|
|
42
|
+
"@superbased/observer-darwin-arm64": "1.4.6",
|
|
43
|
+
"@superbased/observer-win32-x64": "1.4.6"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"test": "node bin/observer.js --version"
|