Skip to content

Releases: superbasedapp/observer

v1.27.0

Choose a tag to compare

@marmutapp marmutapp released this 29 Jul 12:56

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>.jsonl plus a
      <uuid>.settings.json sidecar. 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-only tokenUsage block is
      emitted, under the stable id tokens:<session-id>, so a later parse
      of a grown sidecar rewrites the same (source_file, source_event_id)
      row and the store's ON CONFLICT … MAX(…) upgrade keeps the counts
      monotonically non-decreasing; inclusiveTokenUsage and
      lastCallTokenUsage are deliberately NOT emitted (both would
      double-count — mission child sessions get their own transcript and
      sidecar), and factoryCredits has no TokenBundle counterpart at
      all. Tier source='jsonl', reliability='approximate'. Project root
      comes from the inline session_start.cwd; compaction_state maps to
      ActionContextCompacted with its git-output snapshots dropped. The
      adapter never reads the ~/.factory root — auth.v2.* and the
      top-level settings.json carry plaintext BYOK keys — and sidecar
      reads refuse symlinks (a new house idiom).
    • Open Interpreter is deliberately not a new package. The
      interpreter binary is the OpenAI Codex CLI Rust codebase recompiled
      under another product name, and the evidence is not circumstantial:
      every subcommand's --help is titled "Codex", the Rust module
      namespace is codex_*, the session file's base_instructions say
      "You are Codex", CODEX_HOME is renamed to INTERPRETER_HOME, and
      every token_count event's rate_limits.limit_id is still the
      literal string "codex". So codex.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 JSONL token_count, with gross input
      netted against cached_input_tokens exactly 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-source command-code npm 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. inputTokens is GROSS — it
      includes cacheReadTokens — so the adapter emits the netted figure,
      clamped at zero (mutation-proved), and carries the cached count
      separately. The provider's own costUsd is 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 by IsSessionFile, and
      auth.json is never read.
    • Registration. enabled_adapters goes 26 → 29, with one
      internal/integration capability row each (droid and open-interpreter
      probe_required; command-code after_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 (the cmd / cmdc aliases are deliberately excluded — they
      collide with cmd.exe), defaults.Adapters(), and dashboard tool
      label + colour rows (CIE76-checked). RegistryVersion stays 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 (alias interpreter) and
    observer command-code (alias commandcode) each open a real PTY from
    the dashboard or a shell. Every seed and resume contract was read out of
    the tool's own --help on 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 the resume <uuid> subcommand, codex's shape, which
    landed as a new positional resumeTranslation shape 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, and observer open-interpreter deliberately does not copy
    observer codex's openai_base_url injection. 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
    Binary rows
    , and 21 with at least one grounded install hint
    (kimi-code is the sole gap, no official channel grounded). Factory's
    Windows irm one-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 the internal/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 *-web tool identities, which are one package),
    35 enabled_adapters entries (the 34 plus roo-code, which has no
    package and no row), and integration.Tools() — not EnabledAdapters
    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 a tool_use record and
    its tool_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 trailing tool_use rewinds NewOffset back to that
    record's start (never below fromOffset), 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 (an ON CONFLICT
    outcome upgrade, or a ParseResult outcome-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
    : prefetchSessionContext did not seed its dedup state
    from the already-parsed prefix, so a token_count snapshot whose totals
    were unchanged across a poll — and, separately, a re-seen system prompt
    — produced a second row. It now seeds both seenModernTotal and
    seenSystemPrompts by a state-only prefix replay: rescan-idempotent,
    with no change to the SourceEventID scheme, 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 in localStorage, 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-fil...
Read more

v1.26.0

Choose a tag to compare

@marmutapp marmutapp released this 28 Jul 09:38

Added

  • feat(processobs/etw): Windows per-process network accounting over ETW
    (W1–W4).
    Closes the cross-OS gap where only Linux (eBPF) could measure
    per-process network bytes. W1 is a pure-Go, CGO-free, dependency-free
    decode-only consumer of Microsoft-Windows-Kernel-Network — the manifest
    provider chosen over the legacy NT Kernel Logger for no singleton-session
    contention, fixed-width payloads (connid is win:UInt32, where the
    legacy MOF declares it Pointer-qualified so the width tracks pointer size)
    and keyword filtering. Bytes are attributed to the PAYLOAD pid, never
    EVENT_HEADER.ProcessId, which for kernel network events is routinely 4
    (System) or 0 (Idle) because completion runs in a DPC or worker thread.
    TCP only, enforced structurally: TCP and UDP decode into unrelated types
    with no shared parent, so a UDP count cannot reach a TCP total by
    accident. The ABI is pinned by 26 two-sided compile-time assertions rather
    than tests — CI has no Windows runner and GOOS=windows go build does not
    compile _test.go files, so a size test would never execute anywhere.
    W2 adds the per-pid cumulative accumulator that reconciles ETW's
    PER-EVENT byte reports with the cumulative contract every consumer
    differentiates (16384 live entries with LRU eviction, mirroring the Linux
    netMapMaxEntries, plus a 1024-entry retired cache so an exit event still
    carries final totals), and settles the W1 open question: Linux's
    tcp_cleanup_rbuf(copied) maps to ETW event 11 alone, not 11+18 — summing
    both would double-count already-pended data.
  • feat(processobs,cmd,config): the elevated Windows capturer dials the
    daemon (ETW W3/W4).
    The transport direction from the 2026-06-17 spike
    was inverted by measurement: on a NAT-mode host, WSL→Windows 127.0.0.1 is
    REFUSED (it is WSL's own loopback) and WSL→gateway times out (Defender
    drops inbound on the WSL vNIC), while Windows→WSL loopback works via
    localhostForwarding. So the capturer dials a loopback listener the WSL
    daemon owns — no firewall rule, no host-IP discovery, no
    NAT-vs-mirrored probe. Auth is mandatory with no bypass: 256 bits of
    crypto/rand persisted 0600 beside the DB, constant-time compared, never
    logged, read from --token-file or OBSERVER_PROCESS_BRIDGE_TOKEN
    there is deliberately NO --token flag, because argv is world-readable
    and this tool captures argv. New [observer.process.etw] config block.
    Backend selection is additive: etw selects the same baseline auto
    would and ADDS the listener, so an elevated feed that never arrives can
    never trade away working zero-privilege capture. Two real bugs were found
    building it — an infinite hot loop (a read error and bufio.ErrTooLong
    are permanent and bufio.Scanner returns them forever, latent on a pipe
    where EOF ends a stream, immediately fatal on a socket where a reset does)
    and a 30s reconnect stall, now ~1s via a hangup watcher. W4 adds
    capturer-link health (a TransportStatsSource + TransportUnavailableSource
    capability PAIR resolved into none/unavailable/configured, with the
    (TransportStats, bool) signature load-bearing so a Composite carrying no
    transport child cannot be forced to claim "a transport exists, with zero
    connections"), a detect-and-emit setup surface (observer init DETECTS an
    existing task via /Query, which works unprivileged, and emits a
    fully-resolved command for the operator's own elevated run — it never
    prints "registered", because from WSL's medium-integrity interop token
    /Create is refused for /RL HIGHEST and for /SC ONLOGON while a plain
    /SC ONCE succeeds, so it is elevation that is blocked, not task
    creation), and --token-file re-read per reconnect attempt so a
    logon-triggered task firing before WSL is up no longer dies permanently.
    AuthFailures counts every handshake refusal and so can never name a
    cause — proven live, a wire-version mismatch and port-scanner garbage both
    rendered as "shared-token mismatch" — so the daemon's verbatim reason now
    travels separately, clamped to 240 bytes, with the metric label carrying a
    bounded CLASS rather than the remote string.
  • feat(processobs,dashboard): dashboard-driven ETW capturer setup (E1–E7).
    The W4 arc had concluded observer init can only DETECT and emit a
    command; the measurement behind that still stands (schtasks /Create IS
    Access-denied from WSL's medium-integrity token) but the inference —
    "elevation cannot be self-granted" — was too strong. Elevation cannot be
    taken silently; it can be brokered through UAC consent. Measured on this
    host: Start-Process -Verb RunAs from WSL reaches High Mandatory Level,
    /Create /SC ONLOGON /RL HIGHEST succeeds, and the single-quoted /TR
    form stores correctly — the first end-to-end confirmation of the quoting
    rule W4 derived (the backslash-escaped form parses in cmd.exe but FAILS in
    PowerShell; the unquoted form stores unquoted and would launch
    C:\Program). New GET /api/process/etw/status (capability V, first-class
    states rather than errors), POST /api/process/etw/register (capability L
    • confirm token, with the argv built ENTIRELY server-side — there is no
      request struct at all), and an ETW capturer card under Settings → Process
      capture. Independent review of E1–E6 raised eight findings, each reproduced
      with a failing test before any fix; two were real and sharp — an apostrophe
      in a Windows path (C:\Users\O'Brien\…) closed the /TR quote early so
      schtasks stored a program that was a PREFIX of the real path, and
      normalize() floored a negative counter to zero, turning "this report is
      nonsense" into "the decoder ran and refused nothing".
  • feat(processobs,diag,metrics): decode-classification counters, so
    "nothing captured" can no longer read as "healthy".
    Classify() routes
    every unknown event id to ClassIgnored, so a renumbered provider would
    report dropped:0 / unsupported:0 and zero bytes — passing validation
    while measuring nothing. New NetworkIgnored + NetworkDecoded counters
    and NothingClassified(); Ignored is deliberately NOT in Any(),
    because a healthy busy capture has a huge Ignored and folding it in would
    fire a fault on every working host. Separately, Health.NetworkAccountingMode
    / Reason were computed and read by nothing, so an operator whose probes
    failed to attach got silence and could not tell "measured, no traffic"
    from "never measured". The daemon now publishes a small node-local JSON
    record beside the DB (per-PID + liveness-filtered, the pattern
    diag.LockInfo already uses; a record whose writer pid is gone is dropped
    rather than called stale), refreshed every 30s because the backend only
    decides the accounting outcome inside Start. Both observer doctor and
    the /metrics exporter read it and report it AS A REPORT ("pid N said X,
    T ago"), never as live truth; with no daemon reporting, the
    observer_process_* families are ABSENT rather than zeroed, since a
    fabricated backend_up 0 is indistinguishable from a genuinely down
    backend, and the network mode is an enum series per mode so a mode flip
    cannot leave a stale series at 1.
    • Honesty caveat, restated on every surface: nothing under
      internal/processobs/etw/ has ever executed. There is no Windows CI
      runner and WSL cannot elevate, so the Windows runtime path is compiled,
      vetted and lint-clean under both GOOS — not run. The six-step elevated
      validation is now enumerated (it had been cited in three documents and
      written down in none) in docs/process-observability.md §5.5 and is
      still owed. An idle host also produces the same counter shape as a
      renumbered provider; no threshold was invented in either direction, so
      the signal is worded as a suspicion.
  • feat(processobs): eBPF per-process network bytes + a high-frequency
    metric ring.
    The Linux backend attached only
    sched_process_exec/exit and hard-coded NetworkBytesIn/Out to zero;
    it now attaches fexit/tcp_sendmsg (return value = bytes actually
    queued, so partial sends are honest) and fentry/tcp_cleanup_rbuf.
    tcp_recvmsg was rejected deliberately — its arity changed between 5.x
    and 6.x and an fexit program must know the argument count to locate the
    return slot. Same pure-Go cilium/ebpf loader and hand-written asm as the
    existing lifecycle programs: no clang, no bpf2go, no CO-RE, no CGO.
    Alongside it, sampling and persistence are split into separate cadences —
    sample_interval_ms (2000) into memory, persist_interval_ms (15000)
    with a ring capped at persist_max_samples (60) — which is 7.5× finer
    sampling AND 7.5× fewer row rewrites, with the stored column the same size
    as before and independent of the sample rate. MetricSample gains
    net_rx/net_tx/net_measured as additive JSON on the existing ring, so
    no migration; old rings decode with the fields absent, which reads as
    unmeasured. TCP payload bytes only — no UDP, so QUIC/HTTP-3 is invisible —
    stated in the field docs, the config and the operator docs. NOT VERIFIED:
    the eBPF happy path; the authoring host runs
    kernel.unprivileged_bpf_disabled=2, so the programs have never been
    through the kernel verifier. The degradation path is verified.
  • feat(dashboard): live CPU/RSS/disk charts on the Session Cockpit. The
    cockpit's System section rendered three 48×14px sparklines with no axes,
    units, tooltip or time base, and three defects underneath: only ONE
    process was charted (measured on a real session — 458 processes, 455 with
    samples, 33 with the ≥2 samples a rate needs, exactly one drawn);
    cpu_ms, rb and wb are cumulative monotonic counters plotted RAW, and
    no differentiation code existed anywhere in the repo. New
    GET /api/session/<id>/metrics?bucket= aggregates the process subtree onto
    an epoch-anchored common grid, differen...
Read more

v1.25.0

Choose a tag to compare

@marmutapp marmutapp released this 24 Jul 13:21

Added

  • feat(terminal): dashboard-launched terminals joinable by default.
    /api/attach/sessions widened to every live daemon-owned run kind
    (fresh/handoff/attach/resume) — a terminal launched from the dashboard is
    now itself a Jump-in candidate, not just an --attach session. A handoff
    terminal's row keys by the FORKED session (not the source it continued
    from), so it's joined from the fork's session detail once correlation links
    it. JumpInButton's copy and newest-row selection (picking the most
    recently created live row when more than one matches a session) were
    updated to match the wider row set.
  • feat(attach): attach-by-default for all 19 CLI launchers. Every
    observer <verb> launcher (claude, codex, opencode, cursor, copilot-cli,
    kilo, cline-cli, hermes, gemini, openclaw, pi, antigravity-cli, qwen, kiro,
    grok, kimi, devin, qoder, goose) now attaches by default the same way
    claude/codex have — a shared launcher gate plus 19 new integration-registry
    Attach rows (tool key → launcher verb). Auto-resume-on-daemon-restart stays
    gated to the two tools with a verified native resume (claude, codex) — every
    other launcher gets an honest degraded-mortality notice instead (a daemon
    restart ends the session outright; observer <verb> --continue-from <session-id> is the manual fork fallback). Proxy env forwarding and
    [terminal.attach].route_proxy / --no-proxy remain claude/codex-scoped —
    every other tool's daemon-spawned inner launcher handles its own
    base-URL routing itself. Note the attached child inherits the DAEMON's
    environment, not the launching shell's — a credential exported only in the
    launching shell won't reach it (config-file/OAuth auth unaffected; export
    it where observer start runs, or use --no-attach). JumpInButton's verb map extended to cover
    all 19 tools.

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.25.0-linux-x64.tar.gz
Linux arm64 observer-v1.25.0-linux-arm64.tar.gz
macOS x86_64 (Intel) observer-v1.25.0-darwin-x64.tar.gz
macOS arm64 (Apple Silicon) observer-v1.25.0-darwin-arm64.tar.gz
Windows x86_64 observer-v1.25.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.25.0

Org server (Docker)

The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.25.0-* archives (attached below).

docker pull ghcr.io/superbasedapp/observer-org:v1.25.0

The image is keyless-signed with cosign. Verify it:

cosign verify ghcr.io/superbasedapp/observer-org:v1.25.0 \
  --certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

Supply 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

v1.24.1

Choose a tag to compare

@marmutapp marmutapp released this 24 Jul 07:06

Added

  • feat(terminal): generic terminal→session correlation sweep. Closes the
    Session Cockpit gap where only claude-code (out-of-band, 0.95 confidence)
    and codex (rollout discovery, 0.75) could link a dashboard-launched
    terminal to its observer session — every other launcher stayed
    uncorrelated. A 10s daemon-side, tool-agnostic discovery pass
    (termsvc.Correlate) now links any LIVE uncorrelated run to a UNIQUE
    candidate session (matched on tool + project root + a launch-time window
    of [−5s, +30m]) at SourceDiscovered 0.75 confidence — unique-or-abstain
    with a 2-tick dwell before committing a link, and tick-wide abstention on
    any unsound tick (hit caps, transient failures) rather than a partial or
    best-guess link. Both sides are revalidated immediately before a link
    commits; store queries use julianday-precise window arithmetic;
    dashboard-handoff runs are resolved via the source session's own project
    root; a new integration reverse map (launcher-verb → tool) normalizes the
    match. Open Session Cockpit panels self-heal through the existing 15s
    link poll — no frontend change needed.
  • feat(dashboard): themed tooltips. Finished the migration to the
    existing floating-ui Tooltip primitive across the sidebar collapsed
    rail, terminal toolbars (⊙ Session/Files/Git, focus/grid/minimize/close,
    size-mode, standing-secret), the Launch Dock, and the New Terminal
    dialog — aria-labels preserved or added throughout, and the Playwright
    specs flipped from title to aria-label assertions in lockstep. Native
    <option> titles are deliberately kept as-is, and the terminal-resize
    modal hint deliberately stays a native title (a persistent tooltip
    hovering a live terminal is worse than a native one).
  • feat(dashboard): Tailscale setup flow. The Configuration card's "Pair
    a device" action now gates on tailnet reachability: disabled with the
    exact missing step plus a "Go to Tailscale setup" scroll-link when the
    tailnet is known-unreachable, and enabled-with-caution when serve status
    can't be detected on older Tailscale CLIs. Device-side guidance was added
    to the serve-active step and the QR reveal ("install Tailscale on your
    phone/device and sign into the same tailnet", with iOS/Android/download
    links). The HTTPS-consent (enable_url) path now states plainly that
    approval alone does not start serving, and offers a Retry serve action.
    docs/remote-access.md updated to match.

Notes

  • Adversarial review: two codex GPT-5.6 passes (all findings fixed) plus an
    independent Claude Opus pass (verdict SHIP; its remaining findings —
    bounding the forward correlation window at 30 minutes, reconciling the
    remote-language e2e case, reverting the resize-hint tooltip, and a
    watcher-lag accessibility fix — were all applied). codex usage stayed
    capped through this work (resets 2026-07-28); the Opus substitution was
    operator-approved.

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.24.1-linux-x64.tar.gz
Linux arm64 observer-v1.24.1-linux-arm64.tar.gz
macOS x86_64 (Intel) observer-v1.24.1-darwin-x64.tar.gz
macOS arm64 (Apple Silicon) observer-v1.24.1-darwin-arm64.tar.gz
Windows x86_64 observer-v1.24.1-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.24.1

Org server (Docker)

The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.24.1-* archives (attached below).

docker pull ghcr.io/superbasedapp/observer-org:v1.24.1

The image is keyless-signed with cosign. Verify it:

cosign verify ghcr.io/superbasedapp/observer-org:v1.24.1 \
  --certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

Supply 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

v1.24.0

Choose a tag to compare

@marmutapp marmutapp released this 24 Jul 00:09

Added

  • Session Cockpit: a live per-terminal floating panel. Every embedded
    dashboard terminal running an AI tool gains a "⊙ Session" button that
    opens a compact, draggable cockpit next to the terminal — the glanceable
    companion to the session-detail page, not a clone of it. It shows, live:
    a now strip (last activity, tokens/sec with an honest measured/estimated
    basis badge, live process count), total cost with the AI/tool split and
    the next-message cost band, context fill against the model budget, token
    buckets, the 5h/7d rate-limit gauge (proxy-routed sessions), prompt-cache
    expiry countdown chips, system telemetry (CPU/memory/disk sparklines and
    the spawned-process tree from process observation, plus proxied API
    traffic with byte totals when body capture measures them), and the last
    five turns deep-linking into the session-detail page.

  • Terminal→session live linkage. New GET /api/terminal/session/<token>
    resolves a running terminal to its correlated observer session (id +
    correlation confidence, refusal-ordered so remote callers can never probe
    token existence); the cockpit keeps polling so a later authoritative
    correlation re-points the panel, and links below the out-of-band tier
    carry an explicit "≈ linked" badge.

  • One-click process-capture enable. When process observation is off, the
    cockpit's System section explains what's missing and offers an atomic
    server-side enable (POST /api/process/enable-capture): non-runnable
    backend selections switch to automatic with the previous value named in
    the notice, hosts with no runnable capture backend get an honest
    "unavailable on this machine" instead of a false success, and capture
    honestly starts only after the daemon restarts.

  • ?tail=N on the session messages API — returns the true last N rows
    of the full timeline for fast pollers (explicitly rejected when combined
    with pagination parameters).

  • ?summary=1 on the session network API — a server-side aggregate
    separating proxied API calls (with request/response byte sums from body
    metadata) from OS-observed process connections.

  • Tool-binary resolution with classified verdicts. Every embedded-
    terminal launcher now resolves its tool binary through a shared ladder —
    process PATH, then a memoized login-shell PATH capture, then native
    install-location probing, then (WSL only) a foreign-Windows-home check —
    and classifies the result as ok, ok_off_path, shadowed,
    foreign_only, or not_found. Fixes the class of bug where a
    Windows-installed npm shim shadowed (or stood in for) a native binary on
    WSL, and the launcher's stale process PATH meant a fresh native install
    wasn't picked up without restarting the daemon.

  • Guided one-click install. When a tool isn't natively resolvable, the
    New Terminal dialog shows the verified official install command and an
    "Install in terminal" button that runs it in a visible PTY. Gated by the
    new [terminal.launch].allow_install config key (default on).

  • observer doctor and observer adapters surface binary-resolution
    health
    , including a foreign_only bucket (tool installed on Windows
    only, not launchable from a WSL daemon) and a best-effort Windows
    proxy-route reachability check.

  • observer init writes Windows-side proxy routes. When the daemon
    runs in WSL, init can now also point a Windows-installed claude-code or
    codex at the daemon's proxy (localhost:8820, relying on WSL2's
    localhostForwarding), so accurate token capture works even when the AI
    tool itself is installed on the Windows side.

  • [launch.tools.<tool>].path config override to pin a specific binary
    path per tool, bypassing the resolution ladder.

  • Custom terminal project paths typed in Windows form (C:\Users\…) are
    now translated to their WSL mount equivalent before validation.

Fixed

  • Concurrent dashboard config saves can no longer lose updates. All
    in-process config read-modify-write paths — section saves, pricing,
    backup restore, remote-manage toggles, terminal limits/policy,
    experiments, and the admission-policy persister — now serialize on one
    shared lock in the config package (cross-process CLI writes remain
    outside a mutex's reach and are documented as such).
  • The attach-replay bound test no longer flakes on slow runners (the
    precondition now waits for the pump to drain the full produced stream).

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.24.0-linux-x64.tar.gz
Linux arm64 observer-v1.24.0-linux-arm64.tar.gz
macOS x86_64 (Intel) observer-v1.24.0-darwin-x64.tar.gz
macOS arm64 (Apple Silicon) observer-v1.24.0-darwin-arm64.tar.gz
Windows x86_64 observer-v1.24.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.24.0

Org server (Docker)

The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.24.0-* archives (attached below).

docker pull ghcr.io/superbasedapp/observer-org:v1.24.0

The image is keyless-signed with cosign. Verify it:

cosign verify ghcr.io/superbasedapp/observer-org:v1.24.0 \
  --certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

Supply 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

v1.23.0

Choose a tag to compare

@marmutapp marmutapp released this 23 Jul 12:08

Added

  • superbased CLI alias. The binary now also runs as superbased,
    selected from argv[0]observer is unchanged and stays canonical
    (no deprecation yet). npm and PyPI ship superbased alongside observer
    as console entry points, and release tarballs/zips include a superbased
    alias next to the observer binary.
  • First-run guided dashboard tour. A spotlight-and-coach-mark
    walkthrough (Overview → Live → Sessions → Cost → Cache → Terminals →
    Security → Settings → global filter/help) auto-starts once on new
    installs and is replayable any time from the Help drawer or the command
    palette.
  • Per-terminal Files/Git project explorer. Every dashboard terminal
    (floating window or grid tile) gets Files/Git panel buttons: a read-only
    file tree + viewer and a git view (branch, ahead/behind, changes,
    100-commit history). Panels are floating, draggable, multi-panel windows
    — one per terminal, open simultaneously — with a right-click context
    menu to copy the selected path (relative or absolute) and, on a live
    write-capable terminal, paste it straight into that terminal.
  • Authenticated remote terminal takeover. A fully-authorized remote
    dashboard can now take over control of a terminal from a local/native
    writer or from another remote seat, completing the native → local →
    remote handoff. Default-on; see the config change below.
  • Playwright e2e regression suites covering the guided tour, terminal
    key/paste handling, and the new project panels.
  • VS Code extension lint gate. npm run lint (eslint) is now runnable
    in the extension's dev workflow; dev-only, not part of the packaged
    extension.
  • Pricing: the 2026 model-release wave. ~35 new cost-engine rows for
    Claude Mythos 5 (Fable-5-equivalent pricing); the Qwen 3.5 family
    (plus/flash/omni-plus/omni-flash) plus 3.7-Plus and a 3.8-Max-Preview
    placeholder row (no published rate yet — anchored to 3.7-Max's exact
    price pending an official card); GLM-5.2; MiniMax M3; Tencent Hy3;
    StepFun Step-3.5-Flash; ERNIE 5.1; ByteDance Seed 2.0 (provisional,
    Volcengine has no official card yet); Meta Muse Spark 1.1; Cohere North
    Mini Code (genuinely free); Sakana Fugu Ultra; Thinking Machines
    Inkling; Jamba Mini 2; Gemini Omni Flash; and Sarvam (free). A
    researched-but-not-priced ledger is kept in code comments for models
    with no public rate card (Cohere Command A+, the original pre-1.1 Muse
    Spark, Phi-4-reasoning-vision-15B, Falcon H1R 7B) so they aren't
    re-researched needlessly.
  • Website repositioned around the AI-agent control-plane story.
    superbased.app now leads with seeing agents' actions and provider-
    reported token usage across 26 tools, then controlling the supported
    sessions (dashboard terminals, paired-device session attach/takeover,
    model routing, egress guardrails); four decorative Canvas animations
    from the marketing library embed on the homepage
    (prefers-reduced-motion-aware, pause when hidden/offscreen).
    "Observer Quest" renamed "SuperBased Quest". 12 README + 3 website
    dashboard screenshots refreshed against the current UI.

Changed

  • [remote].allow_terminal_view now defaults to true. A paired,
    authenticated remote device can view (read-only) attach/resume terminal
    output by default; set it to false to restore the prior deny-by-default
    posture.
  • New [remote].allow_remote_terminal_takeover, defaults to true.
    Pairs with the takeover feature above; set it to false to keep refusing
    a remote takeover of an existing writer.
  • [terminal].idle_timeout now defaults to "0". Idle embedded
    terminals are no longer reaped after 30 minutes of no PTY I/O (a quiet
    agent sitting at its prompt was being killed mid-session); set it back to
    "30m" to restore the old cleanup behavior.
  • Product renamed "SuperBased Observer" → "SuperBased" in prose and UI
    only. Every technical identifier — the observer CLI, package names, the
    [observer] config section, ~/.observer, the observer.db filename —
    is unchanged. VS Code extension display strings (command titles, activity
    bar, output channel, notifications) were renamed the same way; the
    Marketplace listing name updates at the next publish.

Fixed

  • observer run no longer mangles multi-line commands or shell builtins
    (cd, export, …) when wrapping them for hooks, and the wrapped command
    now skips the daemon's integrity check on that path — about 750× faster
    to start (measured 0.16s vs. over 120s against a large database).
  • STT/dictation paste into the embedded terminal: xterm.js was silently
    canceling plain Ctrl+V, so dictation tools' fallback paste landed a stale
    clipboard instead of the transcription; plain Ctrl+V now reaches the
    browser's native paste handling.
  • Terminal-dock drag gestures: an interrupted drag (pointer cancel or lost
    pointer capture) can no longer leave the gesture armed for a later stray
    pointer move to resume from a stale origin.

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.23.0-linux-x64.tar.gz
Linux arm64 observer-v1.23.0-linux-arm64.tar.gz
macOS x86_64 (Intel) observer-v1.23.0-darwin-x64.tar.gz
macOS arm64 (Apple Silicon) observer-v1.23.0-darwin-arm64.tar.gz
Windows x86_64 observer-v1.23.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.23.0

Org server (Docker)

The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.23.0-* archives (attached below).

docker pull ghcr.io/superbasedapp/observer-org:v1.23.0

The image is keyless-signed with cosign. Verify it:

cosign verify ghcr.io/superbasedapp/observer-org:v1.23.0 \
  --certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

Supply 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

v1.22.0

Choose a tag to compare

@marmutapp marmutapp released this 21 Jul 07:55

Added

  • Take control back at your native terminal. The missing leg of the
    session-control triangle: after a dashboard Jump-in, just start typing in
    the terminal that launched the session (observer claude/codex) — the
    daemon returns the writer lease, delivers that keystroke, prints a
    one-line notice, and re-pushes your terminal's geometry so a TUI the
    dashboard left at foreign dimensions heals in the same gesture. Machine
    bytes never reclaim (terminal emulators auto-answer TUI queries on stdin);
    arrow keys or a bare ESC alone won't either, by design. Config:
    [terminal.attach].reclaim_on_input (default on). The dashboard seat goes
    honestly read-only — "control returned to the native terminal — click to
    take back".
  • Original-size restore for broken TUIs. The daemon now tracks each
    session's launch-time and current PTY dimensions; every dashboard terminal
    gets a fit / original-size toggle that pins the launch geometry (auto-refit
    suppressed) to recover a TUI corrupted by resizes, and a seat re-asserts
    its own geometry whenever it regains control.
  • Keyboard shortcuts reach the dashboard terminal. Ctrl+A/E/K/. and
    friends now go to the TUI instead of the page while the terminal is
    focused; Ctrl+Alt push-to-talk chords pass through untouched;
    copy-with-selection stays native. Browser-reserved keys (Ctrl+W/T/N)
    honestly can't be intercepted in a normal tab — the new fullscreen
    focus mode (Keyboard Lock, Chromium) is where they reach the TUI.
  • Watch a bare session read-only. Sessions started outside observer
    (plain claude, codex, …) that are actively producing events now show a
    "live · watch" badge: a read-only, auto-following view of the conversation
    (4s refresh, stick-to-bottom) in the session panel. "Jump in" stays
    honestly disabled — a bare launch's terminal belongs to the shell that
    started it — with "Watch instead (read-only)" offered in its place.
  • Collapsible sidebar. The dashboard's left nav collapses to a compact
    icon rail on desktop (persisted, tooltips); the mobile drawer is unchanged.

Fixed

  • Post-v1.21.0 CI red: six golangci-lint findings in the release's new code
    (behavior-preserving refactors) and the missed website version sweep.

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.22.0-linux-x64.tar.gz
Linux arm64 observer-v1.22.0-linux-arm64.tar.gz
macOS x86_64 (Intel) observer-v1.22.0-darwin-x64.tar.gz
macOS arm64 (Apple Silicon) observer-v1.22.0-darwin-arm64.tar.gz
Windows x86_64 observer-v1.22.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.22.0

Org server (Docker)

The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.22.0-* archives (attached below).

docker pull ghcr.io/marmutapp/observer-org:v1.22.0

The image is keyless-signed with cosign. Verify it:

cosign verify ghcr.io/marmutapp/observer-org:v1.22.0 \
  --certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

Supply 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

v1.21.0

Choose a tag to compare

@marmutapp marmutapp released this 20 Jul 23:10

Added

  • Browser-chat capture (opt-in MV3 extension). Full-detail capture of
    ChatGPT, Claude.ai, Perplexity, Gemini, and consumer Copilot web sessions
    from Chrome (WSL + Windows) via a native-messaging bridge into the new
    browserchat adapter — prompts, responses, models, and estimated tokens,
    with best-effort redaction and health telemetry (observer browser health).
    Load-unpacked only for now. See docs/browser-extension.md.
  • Session attach: join and drive live sessions from the dashboard.
    Observer-launched claude/codex sessions are daemon-owned PTYs the
    dashboard can now join ("live · joinable" badge → Jump in), while your
    native terminal stays fully interactive. Closed sessions gain one-click
    native Resume (observer claude --resume <id> composed server-side)
    from the session panel. Remote (paired-device) viewing of attach/resume
    terminals stays deny-by-default behind the new [remote].allow_terminal_view
    read opt-in.
  • Resilient default-on attach. Interactive observer claude/observer codex
    launches attach by default when the daemon is reachable
    ([terminal.attach].default_on, Settings-togglable; --no-attach opts out
    per launch). Graceful daemon restarts stamp a durable end_reason
    (migration 072) and the attach client offers prompt-with-timeout
    auto-resume onto the same transcript; every skipped default-attach prints
    an honest one-line reason.
  • Terminal Workspace dock grid. The Terminals page is now a workspace:
    an auto-compacting responsive grid of live terminals — drag tiles by their
    header, resize from edges, add running sessions from the tray, "⊞ Add to
    grid" directly on any floating terminal window, "⬈ Open as window" to
    undock a tile back into a user-resizable, size-persisted floating
    window
    . Layouts persist server-side (node-local workspace_layouts,
    migration 073) and render read-only on paired remote devices. Honest close
    semantics: "Remove from grid" keeps the session running; "Stop & close"
    actually ends the process. [terminal].max_concurrent default raised to 9.
    Existing policy/status/history content lives under a Settings tab.
  • Standing-access hardening toggle. Opt-in
    [remote].revoke_standing_on_takeover: a desktop takeover of a remote
    writer that held control through the standing secret also revokes the
    standing secret itself (identical teardown to the explicit revoke). Default
    stays seamless — takeover revokes only the live lease.

Fixed

  • Daemon-down no longer breaks claude launches. observer init bakes the
    proxy route into claude's own settings.json, which outranks the process
    environment — so a "bare" fallback launch used to route API calls into a
    dead proxy. The launchers now resolve the effective route across every
    settings scope claude honors (managed/CLI/local/project/user, including
    inline-JSON --settings and --continue-from working directories) and
    neutralize observer routes with a one-shot CLI-scope --settings override
    (signal-safe temp file); un-overridable cases (managed scope, your own
    --settings, codex's config-file route) refuse with copy naming the exact
    fix. Third-party gateway routes are always honored, never clobbered.
  • "Stop & close" now actually stops the process. Since detach-replay, a
    websocket close only detached the embedded terminal; every stop control now
    issues the explicit server-side reap.
  • Mobile layout no longer breaks on long project paths. One shared
    tail-preserving truncation primitive (ellipsis at the head, leaf visible,
    full path on hover) across all pages, plus explicit horizontal-scroll
    containment on the Overview table.
  • Terminal runs killed by a daemon shutdown no longer show as running forever
    in the run history; floating-terminal resize no longer minimizes the window
    on release.

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.21.0-linux-x64.tar.gz
Linux arm64 observer-v1.21.0-linux-arm64.tar.gz
macOS x86_64 (Intel) observer-v1.21.0-darwin-x64.tar.gz
macOS arm64 (Apple Silicon) observer-v1.21.0-darwin-arm64.tar.gz
Windows x86_64 observer-v1.21.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.21.0

Org server (Docker)

The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.21.0-* archives (attached below).

docker pull ghcr.io/marmutapp/observer-org:v1.21.0

The image is keyless-signed with cosign. Verify it:

cosign verify ghcr.io/marmutapp/observer-org:v1.21.0 \
  --certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

Supply 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

v1.20.0

Choose a tag to compare

@marmutapp marmutapp released this 17 Jul 09:09

Added

  • Remote dashboard + terminal control (Phase 4, explicit opt-in). Drive a
    node from another device over your tailnet: multi-device pairing, a draggable
    launch dock, in-dashboard terminals, and a mobile-friendly dashboard layout.
    Remote execute (launching AI tools / running terminal commands from the
    dashboard) is gated behind an explicit standing grant
    ([remote].allow_standing_terminal_control, default off) with per-session
    terminal leases, fanout bounds, revoked-lease handling, an execute-tier CSP,
    and a full audit lifecycle. Tailnet-only; nothing is exposed to the public
    internet. See docs/remote-access.md.
  • Process-network body capture + attribution wave. For observed processes
    routed through the proxy, capture proxied/plaintext request/response bodies
    into the new process_network_bodies store (agent migration 067) — never a
    claim of TLS visibility. Broader process observation and attribution: five
    adapters seed the pid bridge directly, a background attribution sweep and
    per-wave basenames tighten which session a process belongs to, and the
    dashboard gains process + raw-events surfaces. See
    docs/process-observability.md.
  • GPT-5.6 / OpenAI cache-write token capture. The proxy now parses
    input_tokens_details.cache_write_tokens from OpenAI/Responses usage (both
    the provider and streaming paths), nets cache-write against gross input
    correctly, and feeds the cachetrack engine so implicit-write events are
    observed instead of silently dropped. Wire field + expiry semantics
    documented in docs/general_info/openai_cache_expiry.md and
    docs/cache-tracking.md.
  • Dashboard time-window dropdown. A new date-range control adds 1h / 12h /
    1d
    windows plus explicit custom ranges alongside the existing options,
    resolving since/until with hours taking precedence over days. The range
    params thread through every dashboard page.
  • Benchmark integrity: retry-as-attempt + ephemeral runs. Each retry is now
    recorded as its own attempt (agent migration 068) so benchmark integrity
    reflects real attempt counts instead of collapsing retries. New ephemeral
    runs execute without persisting into the main corpus.
  • Compression: no-drop capability + honest lossy-eviction display. A new
    disable_drops capability lets the codex-safe recipe compress without lossy
    content eviction. All lossy eviction now routes through one classifier owner,
    and evicted bytes are subtracted from reported compression savings so
    "saved" reflects genuine, retrievable compression only — evicted content is
    surfaced additively (still recoverable via search_past_outputs markers,
    never counted as a saving).
  • M365 Copilot org analytics + browser-extension capture fixes. New
    observer-org m365 command and M365 Copilot analytics surface (Graph auth +
    surface_graph) on the org server — server-side only, never on the agent
    wire. Browser-extension capture (native-messaging host + service worker + the
    loopback ingest receiver) is fixed, with per-browser/per-OS host manifest
    writers including Windows registry hostfiles.
  • [dashboard].addr config knob (#8). The dashboard bind address is now
    configurable via [dashboard].addr (and the OBSERVER_DASHBOARD_ADDR
    environment override).
  • Kimi K3 model pricing added to the cost engine and the settings surface.

Changed

  • Codex fork/subagent token de-duplication + session lineage. Replayed
    fork/subagent turns are now skipped so a forked Codex session no longer
    double-counts tokens already attributed to its parent. New parent/child
    session-lineage tracking (agent migration 069, surfaced in the session-detail
    panel) makes the relationship explicit, and the new --codex-fork-dedup
    backfill pass reconciles historical fork double-counting.

Fixed

  • VS Code extension activation stall (#5). Fixed extension activation and
    observer-binary resolution; a new preferPathBinary setting lets the
    extension use a PATH-resolved observer instead of its bundled copy.
  • Codex 16 MiB record limit (#7). The Codex JSONL scanner's 16 MiB record
    cap is replaced with a shared readRecord (64 MiB bound + per-record skip) so
    an oversized record no longer aborts a whole session parse.
  • Prune now reclaims disk space. observer prune actually reclaims disk
    instead of only shedding rows, and startup latency previously spent in
    on-open integrity work is cut.

Upgrade notes

  • Agent DB migrates to schema 69 (migrations 061–069); the org server stays at
    schema 21 — both automatic.
  • Restart the daemon via the safe order (route off → stop → relaunch → route
    on; scripts/restart-daemon.sh) so the new binary and migrations load.
  • Remote execute + standing terminal control stay fully inert until you set
    [remote].allow_standing_terminal_control = true; pairing and remote viewing
    are tailnet-only.
  • Run observer backfill --codex-fork-dedup (or observer backfill --all) to
    reconcile historical Codex fork double-counting.

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.20.0-linux-x64.tar.gz
Linux arm64 observer-v1.20.0-linux-arm64.tar.gz
macOS x86_64 (Intel) observer-v1.20.0-darwin-x64.tar.gz
macOS arm64 (Apple Silicon) observer-v1.20.0-darwin-arm64.tar.gz
Windows x86_64 observer-v1.20.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.20.0

Org server (Docker)

The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.20.0-* archives (attached below).

docker pull ghcr.io/marmutapp/observer-org:v1.20.0

The image is keyless-signed with cosign. Verify it:

cosign verify ghcr.io/marmutapp/observer-org:v1.20.0 \
  --certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

Supply 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

v1.19.0

Choose a tag to compare

@marmutapp marmutapp released this 11 Jul 10:04

Added

  • Email notifications. New [email] config block (stdlib SMTP:
    STARTTLS/implicit-TLS, AUTH PLAIN/LOGIN; default off, fail-soft —
    a delivery failure never affects evaluation). Rides the existing alert
    evaluators: org budget alerts, org obs-alert rules, and node-side
    [observability.alerts]. See docs/email-notifications.md.
  • Scheduled cost digests. Weekly/monthly digest emails on both the node
    ([digest]) and the org server: period spend, per-model/per-project (org:
    per-developer) breakdowns, movers vs prior period. Restart-safe send-once
    de-dup via the new digest_state table (agent migration 060, server
    migration 021). Test on demand with observer digest send --dry-run /
    observer-org digest send --dry-run.
  • Shareable cost card. observer report share [--period week|month] [--markdown] renders a 1200×630 SVG social card + markdown summary of your
    observed spend (period total, cache-read share, model/tool leaderboards).
    Aggregates only — project names/paths never appear (pinned by test). No
    network.
  • Admin dashboard (web2) onboarding & navigation. First-run checklist for
    a fresh org server, command-palette data search (teams / projects /
    people / recent sessions), teaching empty states across pages, breadcrumbs
    on detail routes, and sidebar count badges.
  • Plane-A general-observability upgrades. web2 Admission center
    (/trajectories/admission, read-only policy viewer) + T6 admission
    org-wire tier
    ([org_client.share.obs].admission, default off; server
    migration 019) with audited deep reads; T7 per-item eval tier
    (.eval_items, server migration 020) with per-item EvalRun detail and
    run-vs-run compare; per-end-user spend page; node-side alert
    evaluation for share-off deployments
    ([observability.alerts], default
    off); LLM-judge robustness (map-reduce chunking, per-criterion prompts,
    hardened client) + observer obs admission verify; SDKs attach
    prompt/response content by default (OBSERVER_CAPTURE_CONTENT=0 to
    disable) and target the correct node port :8081; POST /policy?persist=1
    write-through.
  • M365 Copilot org-tier connector (server-side native-console poller,
    server migration 018; never on the agent wire).
  • Browser-chatbot capture extension (preview). Opt-in MV3 extension
    capturing ChatGPT / Claude.ai / Perplexity / Gemini / consumer-Copilot web
    chats via a native-messaging bridge (observer browser hook). Load-unpacked
    only for now — not yet published to the Chrome Web Store; all token
    counts are estimates.
  • Website. Text-first, fully indexable homepage (the Observer Quest
    arcade lives on at /arcade); product deck at /deck with a downloadable
    PDF; 28 per-tool "track costs" pages generated from the adapter
    registry; 6 comparison pages; 21-term glossary; a public two-planes
    explainer; llms.txt + JSON-LD + an explicit GEO robots posture
    (retrieval crawlers allowed, training crawlers opted out).

Changed

  • READMEs and store listings overhauled around the durable story:
    proxy-accurate billed-token attribution, local-first privacy, free node →
    team layer. One true adapter count (26) everywhere; npm/PyPI/VS Code
    listing descriptions rewritten; MCP tool census corrected to 25 (21
    always-on + 4 conditional) and docs/mcp-tools.md fully rewritten.
  • Org-server retention is now enforced. server.data_retention_days
    (default 730) actively prunes: upgraded org servers begin deleting
    rows older than the configured window
    (identity/config/audit/guard-chain
    tables are never pruned). Set the knob before upgrading if you need longer
    retention.
  • Guard alerting (desktop toasts, Slack/Discord/PagerDuty webhooks) and
    process observability are now documented on the main surfaces.

Fixed

  • VS Code walkthrough listed a nonexistent "Continue" adapter; stale
    "seventeen tools" counts across README/website/listings; dead help entries
    in the node dashboard; org migrate-test schema assertion; a date-dependent
    test (TestAggregateForOrg) that failed once its hardcoded day aged out.

Upgrade notes

  • Agent DB migrates to schema 60; org server to 21 — both automatic.
  • Restart the daemon via the safe order (route off → stop → relaunch →
    route on; scripts/restart-daemon.sh) so the new binary and migrations
    load.
  • Email/digests stay inert until you set [email].enabled = true plus the
    per-consumer opt-ins.

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.19.0-linux-x64.tar.gz
Linux arm64 observer-v1.19.0-linux-arm64.tar.gz
macOS x86_64 (Intel) observer-v1.19.0-darwin-x64.tar.gz
macOS arm64 (Apple Silicon) observer-v1.19.0-darwin-arm64.tar.gz
Windows x86_64 observer-v1.19.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.19.0

Org server (Docker)

The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.19.0-* archives (attached below).

docker pull ghcr.io/marmutapp/observer-org:v1.19.0

The image is keyless-signed with cosign. Verify it:

cosign verify ghcr.io/marmutapp/observer-org:v1.19.0 \
  --certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

Supply 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