Skip to content

Commit 506d359

Browse files
committed
Release v1.27.0 — sanitized source snapshot (2026-07-29)
1 parent 08a03ce commit 506d359

263 files changed

Lines changed: 9568 additions & 381 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,172 @@
22

33
All notable changes to SuperBased Observer are documented here.
44

5+
## [1.27.0] — 2026-07-29
6+
7+
### Added
8+
9+
- **feat(adapter): three new adapters — Factory `droid`, Open Interpreter
10+
and Command Code (26 → 29).** All three were Phase-0 grounded against
11+
live installs on WSL *and* Windows before any parser was written, then
12+
put through one adversarial review over the combined diff (four
13+
confirmed findings, each fixed with a revert-proof regression test —
14+
see Fixed below). All three are **Tier-2 log capture**: none has a
15+
verified proxy lane and none exposes a hook mechanism, so every token
16+
figure they produce is the tool's own reported number read out of its
17+
local transcript, never a proxy-exact one.
18+
- **`droid`** (`internal/adapter/droid/`, `models.ToolDroid`) is
19+
Factory AI's terminal agent — the company is Factory AI, the product
20+
is droid, and Observer names adapters after the product. Two flat
21+
files per session and no SQLite anywhere: the JSONL transcript at
22+
`~/.factory/sessions/<dashed-cwd>/<uuid>.jsonl` plus a
23+
`<uuid>.settings.json` sidecar. There is **no per-message usage
24+
envelope anywhere in the corpus** (`"usage"` occurs zero times across
25+
the nine captured sessions), so tokens are SESSION-level cumulative
26+
only — the goose precedent. Only the self-only `tokenUsage` block is
27+
emitted, under the stable id `tokens:<session-id>`, so a later parse
28+
of a grown sidecar rewrites the same `(source_file, source_event_id)`
29+
row and the store's `ON CONFLICT … MAX(…)` upgrade keeps the counts
30+
monotonically non-decreasing; `inclusiveTokenUsage` and
31+
`lastCallTokenUsage` are deliberately NOT emitted (both would
32+
double-count — mission child sessions get their own transcript and
33+
sidecar), and `factoryCredits` has no `TokenBundle` counterpart at
34+
all. Tier `source='jsonl'`, `reliability='approximate'`. Project root
35+
comes from the inline `session_start.cwd`; `compaction_state` maps to
36+
`ActionContextCompacted` with its git-output snapshots dropped. The
37+
adapter never reads the `~/.factory` root — `auth.v2.*` and the
38+
top-level `settings.json` carry plaintext BYOK keys — and sidecar
39+
reads refuse symlinks (a new house idiom).
40+
- **Open Interpreter** is deliberately **not a new package.** The
41+
`interpreter` binary is the OpenAI Codex CLI Rust codebase recompiled
42+
under another product name, and the evidence is not circumstantial:
43+
every subcommand's `--help` is titled "Codex", the Rust module
44+
namespace is `codex_*`, the session file's `base_instructions` say
45+
"You are Codex", `CODEX_HOME` is renamed to `INTERPRETER_HOME`, and
46+
every `token_count` event's `rate_limits.limit_id` is still the
47+
literal string `"codex"`. So `codex.NewOpenInterpreter()` retags the
48+
existing codex parser at the §2.1 boundary seam (CLAUDE.md rule 3 —
49+
branch on capability, not source identity) with watch root
50+
`~/.openinterpreter/sessions`; because the on-disk shape is
51+
*identical* to codex's, root-based watcher dispatch is the only thing
52+
keeping the two apart. Tier 2 JSONL `token_count`, with gross input
53+
netted against `cached_input_tokens` exactly as codex's own path does.
54+
Its four SQLite stores are index/debug only and are not read.
55+
- **Command Code** (`internal/adapter/commandcode/`,
56+
`models.ToolCommandCode`) is the closed-source `command-code` npm CLI
57+
(v1.4.5 at capture) — one binary behind four bin aliases (`cmd`,
58+
`cmdc`, `command-code`, `commandcode`), not a two-product split.
59+
Claude-Code-shaped JSONL under `~/.commandcode/projects/`, with
60+
per-assistant-message usage inline. **`inputTokens` is GROSS** — it
61+
includes `cacheReadTokens` — so the adapter emits the netted figure,
62+
clamped at zero (mutation-proved), and carries the cached count
63+
separately. The provider's own `costUsd` is carried through as an
64+
estimated cost (the opencode / pi precedent) because Command Code
65+
resells ~48 mostly open-weight models through its own gateway, for
66+
which Observer has no pricing rows. `.checkpoints.jsonl`, meta,
67+
config and history files are excluded by `IsSessionFile`, and
68+
`auth.json` is never read.
69+
- **Registration.** `enabled_adapters` goes 26 → 29, with one
70+
`internal/integration` capability row each (droid and open-interpreter
71+
`probe_required`; command-code `after_bridge` — its API-URL knob
72+
points at its own closed gateway, not an Anthropic/OpenAI-shaped
73+
endpoint), guard conformance rows, cross-OS process-attribution
74+
basenames (the `cmd` / `cmdc` aliases are deliberately excluded — they
75+
collide with `cmd.exe`), `defaults.Adapters()`, and dashboard tool
76+
label + colour rows (CIE76-checked). `RegistryVersion` stays at 1 by
77+
the browserchat precedent: a bump revokes aggregate consent receipts,
78+
and adding tools is not a consent-shape change. As with every new
79+
adapter, a daemon built before this release has no compiled-in support
80+
— rebuild and restart before expecting rows.
81+
- **feat(launch): full terminal parity for the wave — 19 → 22 launchers.**
82+
`observer droid`, `observer open-interpreter` (alias `interpreter`) and
83+
`observer command-code` (alias `commandcode`) each open a real PTY from
84+
the dashboard or a shell. Every seed and resume contract was read out of
85+
the tool's own `--help` on 2026-07-29 rather than inferred: droid takes
86+
the distilled handover as a **trailing positional** and resumes with a
87+
JOINED `--resume=<uuid>` (its flag declares an optional value, so a
88+
space-separated form would swallow the next argument); Open Interpreter
89+
resumes through the `resume <uuid>` **subcommand**, codex's shape, which
90+
landed as a new positional `resumeTranslation` shape expressed as DATA
91+
rather than a new code path; Command Code resumes with `--session <id>`,
92+
chosen over its optional-value, name-resolving `-r`. All three launch
93+
**non-proxied** on purpose — no proxy lane has been probed for any of
94+
them, and `observer open-interpreter` deliberately does not copy
95+
`observer codex`'s `openai_base_url` injection. Attach, attach-by-default,
96+
Jump-in and the Session Cockpit come for free, because those dispatch on
97+
the launcher capability rather than the tool name (new-adapter checklist
98+
§3.6a). Totals after the pass, read out of the registry: **22 launcher
99+
verbs** (20 seeded + 2 doc-assisted), **22 attachable**, **21 of 22 with
100+
native resume** — openclaw is the sole holdout, picker-only — **22
101+
`Binary` rows**, and **21 with at least one grounded install hint**
102+
(`kimi-code` is the sole gap, no official channel grounded). Factory's
103+
Windows `irm` one-liner is deliberately NOT offered as an install hint:
104+
it is undocumented upstream.
105+
- **docs: the adapter-coverage parity matrix is re-derived from code.**
106+
`docs/plans/adapter-coverage-parity-plan-2026-06-26.md` §15 is now a
107+
34-row matrix — every cell read out of the `internal/integration`
108+
registry and the launcher wiring on 2026-07-29 and cross-checked against
109+
`observer adapters`, with `—` meaning the registry's honest zero ("no
110+
grounded capability"), never "probably". It also writes down the four
111+
adapter numbers that are routinely confused and are not a discrepancy:
112+
**29** CLI/IDE/desktop adapters, **34** registry rows (the 29 plus the
113+
five browser-rail `*-web` tool identities, which are one package),
114+
**35** `enabled_adapters` entries (the 34 plus `roo-code`, which has no
115+
package and no row), and `integration.Tools()` — not `EnabledAdapters` —
116+
as the canonical closed tool vocabulary. `docs/new-adapter-checklist.md`
117+
gains §3.6a, "what a new launcher gets for FREE".
118+
119+
### Fixed
120+
121+
- **fix(adapter): a tool result that lands in the NEXT parse tick is no
122+
longer dropped.** Found by adversarial review over the wave's combined
123+
diff, not by a test: when a poll ends between a `tool_use` record and
124+
its `tool_result`, the outcome arrives in a later parse and the action
125+
had already been written without it. Both new JSONL parsers now defer —
126+
an unanswered trailing `tool_use` rewinds `NewOffset` back to that
127+
record's start (never below `fromOffset`), bounded by a 1 MiB tail and a
128+
90-minute mtime grace so a genuinely abandoned session cannot pin the
129+
cursor forever. **Honest scope: this fixes the two new parsers only.**
130+
claudecode, qwencode, qoder, kimicode and grok carry the same latent
131+
defect, and the right fix there is one store seam (an `ON CONFLICT`
132+
outcome upgrade, or a `ParseResult` outcome-update channel) rather than
133+
five more copies of the deferral — that arc is deferred and recorded
134+
rather than quietly bundled here.
135+
- **fix(codex): duplicate token and system-prompt rows when identical
136+
snapshots straddle a poll boundary.** Surfaced while reviewing the
137+
Open Interpreter retag, but it is a **codex bug and the fix benefits
138+
codex itself**: `prefetchSessionContext` did not seed its dedup state
139+
from the already-parsed prefix, so a `token_count` snapshot whose totals
140+
were unchanged across a poll — and, separately, a re-seen system prompt
141+
— produced a second row. It now seeds both `seenModernTotal` and
142+
`seenSystemPrompts` by a state-only prefix replay: rescan-idempotent,
143+
with no change to the `SourceEventID` scheme, and it closes a
144+
pre-existing codex system-prompt duplicate class along the way.
145+
- **fix(dashboard): the messages-table sort survives a reload and follows
146+
you across sessions.** v1.26.0 made every header sortable but the choice
147+
was per-mount state, so any reload or session switch silently reverted to
148+
chronological. The selection now persists in `localStorage`, is validated
149+
on read (an unknown column or direction falls back to today's exact
150+
chronological default rather than erroring), and is *removed* rather than
151+
written when the sort IS the default — so a stored value never
152+
out-lives the preference that created it.
153+
- **fix(adapter): two smaller findings from the same review.** Command
154+
Code's meta-model fallback was reachable only at offset 0, so a session
155+
first parsed mid-file never recovered its model; it is now lazy and
156+
fires at any offset. And a racy `WithName` mutator was removed outright —
157+
the adapter name is construction-only, so a setter that could run
158+
concurrently with a parse had no reason to exist.
159+
160+
### Changed
161+
162+
- **test(terminal): the repaint-nudge geometry read is now pinned.**
163+
v1.26.0's reconnect repaint nudge shipped with the gap written into its
164+
own commit message: the geometry snapshot must be taken BEFORE the
165+
forwarded resize (after it, the manager's snapshot has already converged
166+
and every resize misreads as identical), but nothing pinned that order,
167+
because the package's fake `Snapshot()` never converged — so a refactor
168+
moving the read below the resize would have passed the whole suite while
169+
nudging on every resize. A converging fake closes it; mutation-proved.
170+
5171
## [1.26.0] — 2026-07-28
6172

7173
### Added

README.md

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SuperBased
22

33
> The exact tokens your AI provider billed you — cache splits,
4-
> reasoning tokens, long-context surcharges — reconciled across 26
4+
> reasoning tokens, long-context surcharges — reconciled across 29
55
> coding tools, entirely on your own machine. Nothing you build here
66
> ever leaves your machine unless you opt a node into it.
77
@@ -57,19 +57,20 @@ can't give you, in order of how much they matter:
5757
rollup server ships only hashed metadata by default; raw content
5858
ships only when **the node** opts in, never a remote admin toggle.
5959
Full details: [`PRIVACY.md`](PRIVACY.md).
60-
3. **One capture layer, every tool you actually use.** 26 adapters —
60+
3. **One capture layer, every tool you actually use.** 29 adapters —
6161
Claude Code, Codex, Cursor, Cline + Cline CLI, GitHub Copilot +
6262
Copilot CLI, Gemini CLI, OpenCode, Google Antigravity, Cowork,
6363
Hermes Agent, Kilo Code, Aider, Goose, Devin, Qoder, Crush, Grok,
64-
Kiro CLI, Kimi Code, Qwen Code, OpenClaw, Pi, and more — parsed
65-
into one normalized schema, queryable from a local dashboard, an
66-
MCP server (so the tools themselves can query it), and a CLI.
67-
(Five of the 26 are `*-web` adapters for ChatGPT/Claude.ai/Gemini/
68-
Copilot/Perplexity in the browser — those need the browser-capture
69-
extension, which today only installs unpacked; every tool listed
70-
above works out of the box.) Nineteen of those are also full CLI
71-
launchers you can run as real terminals — from the dashboard or
72-
your own shell, captured through the same pipeline — see
64+
Kiro CLI, Kimi Code, Qwen Code, OpenClaw, Pi, Factory Droid,
65+
Open Interpreter, Command Code, and more — parsed into one
66+
normalized schema, queryable from a local dashboard, an MCP server
67+
(so the tools themselves can query it), and a CLI. (Five *more*
68+
`*-web` adapters cover ChatGPT/Claude.ai/Gemini/Copilot/Perplexity
69+
in the browser — those need the browser-capture extension, which
70+
today only installs unpacked; every tool listed above works out of
71+
the box.) Twenty-two of those are also full CLI launchers you can
72+
run as real terminals — from the dashboard or your own shell,
73+
captured through the same pipeline — see
7374
[Terminals](#terminals--launch-join-and-track-your-ai-clis) below.
7475

7576
Raw token counting across tools is table stakes here — it's the
@@ -580,10 +581,11 @@ The dashboard doesn't just watch your AI tools after the fact — it
580581
can launch them, and any paired device can join a session that's
581582
already running.
582583

583-
- **Launch from the dashboard or any shell.** All 19 CLI launchers
584+
- **Launch from the dashboard or any shell.** All 22 CLI launchers
584585
(claude, codex, opencode, cursor, copilot-cli, kilo, cline-cli,
585586
hermes, gemini, openclaw, pi, antigravity, qwen, kiro, grok, kimi,
586-
devin, qoder, goose) launch as real PTY terminals from the
587+
devin, qoder, goose, droid, open-interpreter, command-code) launch
588+
as real PTY terminals from the
587589
dashboard ("Launch here") or via `observer <verb>`; Linux/macOS +
588590
native Windows (ConPTY, Win10 1809+). Guided one-click install when
589591
the tool binary isn't found.
@@ -624,9 +626,10 @@ already running.
624626
- **Workspace grid.** Up to 9 live terminal tiles at once, drag to
625627
resize, layouts persist server-side; read-only when viewed from a
626628
remote device.
627-
- **Restarts & continuity.** On a daemon restart, claude and codex
628-
auto-resume the same transcript (native resume); every other tool's
629-
attached session ends. Fork any tool's session forward with
629+
- **Restarts & continuity.** On a daemon restart, 21 of the 22
630+
launchers auto-resume the same transcript (native resume) —
631+
openclaw is the sole holdout, because its resume is picker-only.
632+
Fork any tool's session forward with
630633
`observer <verb> --continue-from <id>` — a new session id seeded
631634
with a distilled handover as the first prompt.
632635
- **Remote posture.** Remote access is opt-in, tailnet-only
@@ -843,7 +846,7 @@ your client through the proxy — the one-click button path in the
843846

844847
```
845848
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
846-
│ Claude Code │ │ Cursor │ │ Codex │ ... 26 adapters total
849+
│ Claude Code │ │ Cursor │ │ Codex │ ... 29 adapters total
847850
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
848851
│ JSONL │ hook events │ rollout files
849852
▼ ▼ ▼

browser-extension/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifest_version": 3,
33
"name": "SuperBased Observer — Browser Capture",
4-
"version": "1.26.0",
4+
"version": "1.27.0",
55
"description": "Opt-in, passive observability of your own AI chatbot web usage (ChatGPT, Claude, Perplexity, Gemini, Copilot). Captures per-turn metadata + estimated tokens locally; nothing leaves your machine except to your local observer daemon.",
66
"minimum_chrome_version": "111",
77
"permissions": [

0 commit comments

Comments
 (0)