|
2 | 2 |
|
3 | 3 | All notable changes to SuperBased Observer are documented here. |
4 | 4 |
|
| 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 | + |
5 | 171 | ## [1.26.0] — 2026-07-28 |
6 | 172 |
|
7 | 173 | ### Added |
|
0 commit comments