v1.27.0
Added
- feat(adapter): three new adapters — Factory
droid, Open Interpreter
and Command Code (26 → 29). All three were Phase-0 grounded against
live installs on WSL and Windows before any parser was written, then
put through one adversarial review over the combined diff (four
confirmed findings, each fixed with a revert-proof regression test —
see Fixed below). All three are Tier-2 log capture: none has a
verified proxy lane and none exposes a hook mechanism, so every token
figure they produce is the tool's own reported number read out of its
local transcript, never a proxy-exact one.droid(internal/adapter/droid/,models.ToolDroid) is
Factory AI's terminal agent — the company is Factory AI, the product
is droid, and Observer names adapters after the product. Two flat
files per session and no SQLite anywhere: the JSONL transcript at
~/.factory/sessions/<dashed-cwd>/<uuid>.jsonlplus a
<uuid>.settings.jsonsidecar. There is no per-message usage
envelope anywhere in the corpus ("usage"occurs zero times across
the nine captured sessions), so tokens are SESSION-level cumulative
only — the goose precedent. Only the self-onlytokenUsageblock is
emitted, under the stable idtokens:<session-id>, so a later parse
of a grown sidecar rewrites the same(source_file, source_event_id)
row and the store'sON CONFLICT … MAX(…)upgrade keeps the counts
monotonically non-decreasing;inclusiveTokenUsageand
lastCallTokenUsageare deliberately NOT emitted (both would
double-count — mission child sessions get their own transcript and
sidecar), andfactoryCreditshas noTokenBundlecounterpart at
all. Tiersource='jsonl',reliability='approximate'. Project root
comes from the inlinesession_start.cwd;compaction_statemaps to
ActionContextCompactedwith its git-output snapshots dropped. The
adapter never reads the~/.factoryroot —auth.v2.*and the
top-levelsettings.jsoncarry plaintext BYOK keys — and sidecar
reads refuse symlinks (a new house idiom).- Open Interpreter is deliberately not a new package. The
interpreterbinary is the OpenAI Codex CLI Rust codebase recompiled
under another product name, and the evidence is not circumstantial:
every subcommand's--helpis titled "Codex", the Rust module
namespace iscodex_*, the session file'sbase_instructionssay
"You are Codex",CODEX_HOMEis renamed toINTERPRETER_HOME, and
everytoken_countevent'srate_limits.limit_idis still the
literal string"codex". Socodex.NewOpenInterpreter()retags the
existing codex parser at the §2.1 boundary seam (CLAUDE.md rule 3 —
branch on capability, not source identity) with watch root
~/.openinterpreter/sessions; because the on-disk shape is
identical to codex's, root-based watcher dispatch is the only thing
keeping the two apart. Tier 2 JSONLtoken_count, with gross input
netted againstcached_input_tokensexactly as codex's own path does.
Its four SQLite stores are index/debug only and are not read. - Command Code (
internal/adapter/commandcode/,
models.ToolCommandCode) is the closed-sourcecommand-codenpm CLI
(v1.4.5 at capture) — one binary behind four bin aliases (cmd,
cmdc,command-code,commandcode), not a two-product split.
Claude-Code-shaped JSONL under~/.commandcode/projects/, with
per-assistant-message usage inline.inputTokensis GROSS — it
includescacheReadTokens— so the adapter emits the netted figure,
clamped at zero (mutation-proved), and carries the cached count
separately. The provider's owncostUsdis carried through as an
estimated cost (the opencode / pi precedent) because Command Code
resells ~48 mostly open-weight models through its own gateway, for
which Observer has no pricing rows..checkpoints.jsonl, meta,
config and history files are excluded byIsSessionFile, and
auth.jsonis never read. - Registration.
enabled_adaptersgoes 26 → 29, with one
internal/integrationcapability row each (droid and open-interpreter
probe_required; command-codeafter_bridge— its API-URL knob
points at its own closed gateway, not an Anthropic/OpenAI-shaped
endpoint), guard conformance rows, cross-OS process-attribution
basenames (thecmd/cmdcaliases are deliberately excluded — they
collide withcmd.exe),defaults.Adapters(), and dashboard tool
label + colour rows (CIE76-checked).RegistryVersionstays at 1 by
the browserchat precedent: a bump revokes aggregate consent receipts,
and adding tools is not a consent-shape change. As with every new
adapter, a daemon built before this release has no compiled-in support
— rebuild and restart before expecting rows.
- feat(launch): full terminal parity for the wave — 19 → 22 launchers.
observer droid,observer open-interpreter(aliasinterpreter) and
observer command-code(aliascommandcode) each open a real PTY from
the dashboard or a shell. Every seed and resume contract was read out of
the tool's own--helpon 2026-07-29 rather than inferred: droid takes
the distilled handover as a trailing positional and resumes with a
JOINED--resume=<uuid>(its flag declares an optional value, so a
space-separated form would swallow the next argument); Open Interpreter
resumes through theresume <uuid>subcommand, codex's shape, which
landed as a new positionalresumeTranslationshape expressed as DATA
rather than a new code path; Command Code resumes with--session <id>,
chosen over its optional-value, name-resolving-r. All three launch
non-proxied on purpose — no proxy lane has been probed for any of
them, andobserver open-interpreterdeliberately does not copy
observer codex'sopenai_base_urlinjection. Attach, attach-by-default,
Jump-in and the Session Cockpit come for free, because those dispatch on
the launcher capability rather than the tool name (new-adapter checklist
§3.6a). Totals after the pass, read out of the registry: 22 launcher
verbs (20 seeded + 2 doc-assisted), 22 attachable, 21 of 22 with
native resume — openclaw is the sole holdout, picker-only — 22
Binaryrows, and 21 with at least one grounded install hint
(kimi-codeis the sole gap, no official channel grounded). Factory's
Windowsirmone-liner is deliberately NOT offered as an install hint:
it is undocumented upstream. - docs: the adapter-coverage parity matrix is re-derived from code.
docs/plans/adapter-coverage-parity-plan-2026-06-26.md§15 is now a
34-row matrix — every cell read out of theinternal/integration
registry and the launcher wiring on 2026-07-29 and cross-checked against
observer adapters, with—meaning the registry's honest zero ("no
grounded capability"), never "probably". It also writes down the four
adapter numbers that are routinely confused and are not a discrepancy:
29 CLI/IDE/desktop adapters, 34 registry rows (the 29 plus the
five browser-rail*-webtool identities, which are one package),
35enabled_adaptersentries (the 34 plusroo-code, which has no
package and no row), andintegration.Tools()— notEnabledAdapters—
as the canonical closed tool vocabulary.docs/new-adapter-checklist.md
gains §3.6a, "what a new launcher gets for FREE".
Fixed
- fix(adapter): a tool result that lands in the NEXT parse tick is no
longer dropped. Found by adversarial review over the wave's combined
diff, not by a test: when a poll ends between atool_userecord and
itstool_result, the outcome arrives in a later parse and the action
had already been written without it. Both new JSONL parsers now defer —
an unanswered trailingtool_userewindsNewOffsetback to that
record's start (never belowfromOffset), bounded by a 1 MiB tail and a
90-minute mtime grace so a genuinely abandoned session cannot pin the
cursor forever. Honest scope: this fixes the two new parsers only.
claudecode, qwencode, qoder, kimicode and grok carry the same latent
defect, and the right fix there is one store seam (anON CONFLICT
outcome upgrade, or aParseResultoutcome-update channel) rather than
five more copies of the deferral — that arc is deferred and recorded
rather than quietly bundled here. - fix(codex): duplicate token and system-prompt rows when identical
snapshots straddle a poll boundary. Surfaced while reviewing the
Open Interpreter retag, but it is a codex bug and the fix benefits
codex itself:prefetchSessionContextdid not seed its dedup state
from the already-parsed prefix, so atoken_countsnapshot whose totals
were unchanged across a poll — and, separately, a re-seen system prompt
— produced a second row. It now seeds bothseenModernTotaland
seenSystemPromptsby a state-only prefix replay: rescan-idempotent,
with no change to theSourceEventIDscheme, and it closes a
pre-existing codex system-prompt duplicate class along the way. - fix(dashboard): the messages-table sort survives a reload and follows
you across sessions. v1.26.0 made every header sortable but the choice
was per-mount state, so any reload or session switch silently reverted to
chronological. The selection now persists inlocalStorage, is validated
on read (an unknown column or direction falls back to today's exact
chronological default rather than erroring), and is removed rather than
written when the sort IS the default — so a stored value never
out-lives the preference that created it. - fix(adapter): two smaller findings from the same review. Command
Code's meta-model fallback was reachable only at offset 0, so a session
first parsed mid-file never recovered its model; it is now lazy and
fires at any offset. And a racyWithNamemutator was removed outright —
the adapter name is construction-only, so a setter that could run
concurrently with a parse had no reason to exist.
Changed
- test(terminal): the repaint-nudge geometry read is now pinned.
v1.26.0's reconnect repaint nudge shipped with the gap written into its
own commit message: the geometry snapshot must be taken BEFORE the
forwarded resize (after it, the manager's snapshot has already converged
and every resize misreads as identical), but nothing pinned that order,
because the package's fakeSnapshot()never converged — so a refactor
moving the read below the resize would have passed the whole suite while
nudging on every resize. A converging fake closes it; mutation-proved.
Downloads
Pre-built binaries for each supported platform are attached below. Linux variants bundle antigravity-bridge.exe next to the observer binary for WSL2 users of the Antigravity adapter.
| Platform | Asset |
|---|---|
| Linux x86_64 | observer-v1.27.0-linux-x64.tar.gz |
| Linux arm64 | observer-v1.27.0-linux-arm64.tar.gz |
| macOS x86_64 (Intel) | observer-v1.27.0-darwin-x64.tar.gz |
| macOS arm64 (Apple Silicon) | observer-v1.27.0-darwin-arm64.tar.gz |
| Windows x86_64 | observer-v1.27.0-win32-x64.zip |
Verify with sha256sum -c SHA256SUMS (or shasum -a 256 -c SHA256SUMS on macOS) from the directory containing the downloads.
Also available via npm: npm install -g @superbased/observer@1.27.0
Org server (Docker)
The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.27.0-* archives (attached below).
docker pull ghcr.io/superbasedapp/observer-org:v1.27.0The image is keyless-signed with cosign. Verify it:
cosign verify ghcr.io/superbasedapp/observer-org:v1.27.0 \
--certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comSupply chain
CycloneDX SBOMs are attached: observer.cdx.json and observer-org.cdx.json.
SLSA Level 3 build provenance for the binaries is attached below as a *.intoto.jsonl attestation. The build runs on the private origin repo, so pass that as the source when verifying an extracted binary with slsa-verifier v2.7.0 or newer (older versions fail with unexpected tlog entry type: expected intoto:0.0.2, got dsse:0.0.1):
slsa-verifier verify-artifact ./observer \
--provenance-path *.intoto.jsonl \
--source-uri github.com/marmutapp/superbased-observer-private