Skip to content

Commit 91c0d49

Browse files
committed
Release v1.23.0 — sanitized source snapshot (2026-07-23)
1 parent d51536c commit 91c0d49

382 files changed

Lines changed: 13494 additions & 2249 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.

.github/workflows/ghcr-mirror.yml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# One-time / on-demand backfill: mirror observer-org container images from the
2+
# old marmutapp namespace to the new superbasedapp namespace after the GitHub
3+
# org transfer. The release pipeline (npm-release.yml) already publishes NEW
4+
# tags to ghcr.io/superbasedapp/observer-org; this workflow copies PRE-TRANSFER
5+
# tags so `docker pull ghcr.io/superbasedapp/observer-org:<old-tag>` resolves.
6+
#
7+
# Manual only (workflow_dispatch). Requires the GHCR_PUSH_TOKEN secret: a
8+
# classic PAT with read:packages (source, marmutapp) + write:packages
9+
# (destination, superbasedapp). Uses `crane copy` (registry-to-registry, no
10+
# local pull). No-ops with a notice when the secret is absent.
11+
name: GHCR mirror (observer-org backfill)
12+
13+
on:
14+
workflow_dispatch:
15+
inputs:
16+
tags:
17+
description: "Comma-separated tags to mirror (e.g. v1.22.0,v1.21.0)"
18+
required: true
19+
type: string
20+
21+
permissions:
22+
contents: read
23+
packages: write
24+
25+
jobs:
26+
mirror:
27+
name: Mirror tags marmutapp -> superbasedapp
28+
runs-on: ubuntu-latest
29+
steps:
30+
- name: Check GHCR_PUSH_TOKEN presence (skip job if unset)
31+
id: gate
32+
env:
33+
GHCR_PW: ${{ secrets.GHCR_PUSH_TOKEN }}
34+
run: |
35+
if [ -z "${GHCR_PW:-}" ]; then
36+
echo "::notice::GHCR_PUSH_TOKEN not set — nothing to mirror (secret setup pending)."
37+
echo "present=false" >> "$GITHUB_OUTPUT"
38+
else
39+
echo "present=true" >> "$GITHUB_OUTPUT"
40+
fi
41+
42+
- name: Install crane
43+
if: steps.gate.outputs.present == 'true'
44+
uses: imjasonh/setup-crane@v0.4
45+
46+
- name: Log in to ghcr.io
47+
if: steps.gate.outputs.present == 'true'
48+
env:
49+
GHCR_PW: ${{ secrets.GHCR_PUSH_TOKEN }}
50+
run: echo "$GHCR_PW" | crane auth login ghcr.io -u ${{ github.actor }} --password-stdin
51+
52+
- name: Copy tags
53+
if: steps.gate.outputs.present == 'true'
54+
env:
55+
TAGS: ${{ inputs.tags }}
56+
run: |
57+
SRC=ghcr.io/marmutapp/observer-org
58+
DST=ghcr.io/superbasedapp/observer-org
59+
IFS=',' read -ra LIST <<< "$TAGS"
60+
for t in "${LIST[@]}"; do
61+
tag="$(echo "$t" | xargs)" # trim whitespace
62+
[ -z "$tag" ] && continue
63+
echo "::group::mirror $tag"
64+
crane copy "$SRC:$tag" "$DST:$tag"
65+
echo "::endgroup::"
66+
done

.github/workflows/npm-release.yml

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -352,11 +352,19 @@ jobs:
352352

353353
# ----------------------------------------------------------------
354354
# Docker image (Teams M5). Build the observer-org server image from
355-
# Dockerfile.observer-org, push it to ghcr.io under the marmutapp
356-
# org using the private repo's GITHUB_TOKEN, then keyless-sign it
357-
# with cosign BY DIGEST (immutable reference; signing a mutable tag
358-
# is a TOCTOU footgun). The image digest is exposed as a job output
359-
# so downstream steps / docs can reference the exact pushed image.
355+
# Dockerfile.observer-org, push it to ghcr.io under the superbasedapp
356+
# org, then keyless-sign it with cosign BY DIGEST (immutable
357+
# reference; signing a mutable tag is a TOCTOU footgun). The image
358+
# digest is exposed as a job output so downstream steps / docs can
359+
# reference the exact pushed image.
360+
#
361+
# Auth: the repo's own GITHUB_TOKEN can only publish into THIS
362+
# repo's owner namespace (marmutapp), so cross-org publish uses the
363+
# GHCR_PUSH_TOKEN secret (a classic PAT with write:packages; GHCR is not
364+
# covered by fine-grained PATs), held on the private repo like every
365+
# other release secret. Absent secret => the job no-ops gracefully
366+
# (VSCE_PAT pattern). One-time backfill of pre-transfer tags is the
367+
# manual ghcr-mirror.yml workflow.
360368
# ----------------------------------------------------------------
361369
docker_image:
362370
name: Docker image (observer-org)
@@ -371,34 +379,51 @@ jobs:
371379
steps:
372380
- uses: actions/checkout@v5
373381

382+
- name: Check GHCR_PUSH_TOKEN presence (skip job if unset)
383+
id: ghcr_gate
384+
env:
385+
GHCR_PUSH_TOKEN: ${{ secrets.GHCR_PUSH_TOKEN }}
386+
run: |
387+
if [ -z "${GHCR_PUSH_TOKEN:-}" ]; then
388+
echo "::notice::GHCR_PUSH_TOKEN not set; skipping observer-org image publish (org-transfer secret setup pending)."
389+
echo "present=false" >> "$GITHUB_OUTPUT"
390+
else
391+
echo "present=true" >> "$GITHUB_OUTPUT"
392+
fi
393+
374394
- name: Set up Buildx
395+
if: steps.ghcr_gate.outputs.present == 'true'
375396
uses: docker/setup-buildx-action@v3
376397

377398
- name: Log in to ghcr.io
399+
if: steps.ghcr_gate.outputs.present == 'true'
378400
uses: docker/login-action@v3
379401
with:
380402
registry: ghcr.io
381403
username: ${{ github.actor }}
382-
password: ${{ secrets.GITHUB_TOKEN }}
404+
password: ${{ secrets.GHCR_PUSH_TOKEN }}
383405

384406
- name: Build and push
407+
if: steps.ghcr_gate.outputs.present == 'true'
385408
id: push
386409
uses: docker/build-push-action@v6
387410
with:
388411
context: .
389412
file: Dockerfile.observer-org
390413
push: true
391-
tags: ghcr.io/marmutapp/observer-org:${{ github.ref_name }}
414+
tags: ghcr.io/superbasedapp/observer-org:${{ github.ref_name }}
392415

393416
- name: Install cosign
417+
if: steps.ghcr_gate.outputs.present == 'true'
394418
uses: sigstore/cosign-installer@v3
395419

396420
- name: Sign image by digest (keyless)
421+
if: steps.ghcr_gate.outputs.present == 'true'
397422
# Keyless OIDC signing — no long-lived keys; the signature is
398423
# bound to this workflow's identity. Verifiable later with
399424
# `cosign verify ... --certificate-identity-regexp ...`.
400425
run: |
401-
cosign sign --yes "ghcr.io/marmutapp/observer-org@${{ steps.push.outputs.digest }}"
426+
cosign sign --yes "ghcr.io/superbasedapp/observer-org@${{ steps.push.outputs.digest }}"
402427
403428
# ----------------------------------------------------------------
404429
# Hashes (Teams M5). Compute the base64-encoded sha256sum subject
@@ -1125,10 +1150,19 @@ jobs:
11251150
# Linux + Darwin: tar.gz preserves the executable bit
11261151
# (chmod +x set in the build job rides along). Windows:
11271152
# zip is the conventional Windows artifact format.
1153+
#
1154+
# Dual-name compatibility (2026-07-23): ship a `superbased` alias
1155+
# beside `observer` so direct-download users get both command names
1156+
# (npm/PyPI installs get both via their bin/scripts maps). A relative
1157+
# symlink rides inside the tar for POSIX; Windows zip gets a copy
1158+
# (zip symlink support is unreliable across extractors).
11281159
for target in linux-x64 linux-arm64 darwin-x64 darwin-arm64; do
1160+
ln -sf observer "artifacts/observer-${target}/superbased"
11291161
tar -czf "release-assets/observer-${VERSION}-${target}.tar.gz" \
11301162
-C "artifacts/observer-${target}" .
11311163
done
1164+
cp "artifacts/observer-win32-x64/observer.exe" \
1165+
"artifacts/observer-win32-x64/superbased.exe"
11321166
(cd "artifacts/observer-win32-x64" && \
11331167
zip -r "$GITHUB_WORKSPACE/release-assets/observer-${VERSION}-win32-x64.zip" .)
11341168
@@ -1224,13 +1258,13 @@ jobs:
12241258
echo "The self-hosted org server ships as a Docker image and as per-platform \`observer-org-${GITHUB_REF_NAME}-*\` archives (attached below)."
12251259
echo ""
12261260
echo '```bash'
1227-
echo "docker pull ghcr.io/marmutapp/observer-org:${GITHUB_REF_NAME}"
1261+
echo "docker pull ghcr.io/superbasedapp/observer-org:${GITHUB_REF_NAME}"
12281262
echo '```'
12291263
echo ""
12301264
echo "The image is keyless-signed with cosign. Verify it:"
12311265
echo ""
12321266
echo '```bash'
1233-
echo "cosign verify ghcr.io/marmutapp/observer-org:${GITHUB_REF_NAME} \\"
1267+
echo "cosign verify ghcr.io/superbasedapp/observer-org:${GITHUB_REF_NAME} \\"
12341268
echo " --certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \\"
12351269
echo " --certificate-oidc-issuer https://token.actions.githubusercontent.com"
12361270
echo '```'

CHANGELOG.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,93 @@ All notable changes to SuperBased Observer are documented here.
44

55
## [Unreleased]
66

7+
## [1.23.0] — 2026-07-23
8+
9+
### Added
10+
11+
- **`superbased` CLI alias.** The binary now also runs as `superbased`,
12+
selected from `argv[0]` — `observer` is unchanged and stays canonical
13+
(no deprecation yet). npm and PyPI ship `superbased` alongside `observer`
14+
as console entry points, and release tarballs/zips include a `superbased`
15+
alias next to the `observer` binary.
16+
- **First-run guided dashboard tour.** A spotlight-and-coach-mark
17+
walkthrough (Overview → Live → Sessions → Cost → Cache → Terminals →
18+
Security → Settings → global filter/help) auto-starts once on new
19+
installs and is replayable any time from the Help drawer or the command
20+
palette.
21+
- **Per-terminal Files/Git project explorer.** Every dashboard terminal
22+
(floating window or grid tile) gets Files/Git panel buttons: a read-only
23+
file tree + viewer and a git view (branch, ahead/behind, changes,
24+
100-commit history). Panels are floating, draggable, multi-panel windows
25+
— one per terminal, open simultaneously — with a right-click context
26+
menu to copy the selected path (relative or absolute) and, on a live
27+
write-capable terminal, paste it straight into that terminal.
28+
- **Authenticated remote terminal takeover.** A fully-authorized remote
29+
dashboard can now take over control of a terminal from a local/native
30+
writer or from another remote seat, completing the native → local →
31+
remote handoff. Default-on; see the config change below.
32+
- **Playwright e2e regression suites** covering the guided tour, terminal
33+
key/paste handling, and the new project panels.
34+
- **VS Code extension lint gate.** `npm run lint` (eslint) is now runnable
35+
in the extension's dev workflow; dev-only, not part of the packaged
36+
extension.
37+
- **Pricing: the 2026 model-release wave.** ~35 new cost-engine rows for
38+
Claude Mythos 5 (Fable-5-equivalent pricing); the Qwen 3.5 family
39+
(plus/flash/omni-plus/omni-flash) plus 3.7-Plus and a 3.8-Max-Preview
40+
placeholder row (no published rate yet — anchored to 3.7-Max's exact
41+
price pending an official card); GLM-5.2; MiniMax M3; Tencent Hy3;
42+
StepFun Step-3.5-Flash; ERNIE 5.1; ByteDance Seed 2.0 (provisional,
43+
Volcengine has no official card yet); Meta Muse Spark 1.1; Cohere North
44+
Mini Code (genuinely free); Sakana Fugu Ultra; Thinking Machines
45+
Inkling; Jamba Mini 2; Gemini Omni Flash; and Sarvam (free). A
46+
researched-but-not-priced ledger is kept in code comments for models
47+
with no public rate card (Cohere Command A+, the original pre-1.1 Muse
48+
Spark, Phi-4-reasoning-vision-15B, Falcon H1R 7B) so they aren't
49+
re-researched needlessly.
50+
- **Website repositioned around the AI-agent control-plane story.**
51+
superbased.app now leads with seeing agents' actions and provider-
52+
reported token usage across 26 tools, then controlling the supported
53+
sessions (dashboard terminals, paired-device session attach/takeover,
54+
model routing, egress guardrails); four decorative Canvas animations
55+
from the marketing library embed on the homepage
56+
(`prefers-reduced-motion`-aware, pause when hidden/offscreen).
57+
"Observer Quest" renamed "SuperBased Quest". 12 README + 3 website
58+
dashboard screenshots refreshed against the current UI.
59+
60+
### Changed
61+
62+
- **`[remote].allow_terminal_view` now defaults to `true`.** A paired,
63+
authenticated remote device can view (read-only) attach/resume terminal
64+
output by default; set it to `false` to restore the prior deny-by-default
65+
posture.
66+
- **New `[remote].allow_remote_terminal_takeover`, defaults to `true`.**
67+
Pairs with the takeover feature above; set it to `false` to keep refusing
68+
a remote takeover of an existing writer.
69+
- **`[terminal].idle_timeout` now defaults to `"0"`.** Idle embedded
70+
terminals are no longer reaped after 30 minutes of no PTY I/O (a quiet
71+
agent sitting at its prompt was being killed mid-session); set it back to
72+
`"30m"` to restore the old cleanup behavior.
73+
- **Product renamed "SuperBased Observer" → "SuperBased"** in prose and UI
74+
only. Every technical identifier — the `observer` CLI, package names, the
75+
`[observer]` config section, `~/.observer`, the `observer.db` filename —
76+
is unchanged. VS Code extension display strings (command titles, activity
77+
bar, output channel, notifications) were renamed the same way; the
78+
Marketplace listing name updates at the next publish.
79+
80+
### Fixed
81+
82+
- `observer run` no longer mangles multi-line commands or shell builtins
83+
(`cd`, `export`, …) when wrapping them for hooks, and the wrapped command
84+
now skips the daemon's integrity check on that path — about 750× faster
85+
to start (measured 0.16s vs. over 120s against a large database).
86+
- STT/dictation paste into the embedded terminal: xterm.js was silently
87+
canceling plain Ctrl+V, so dictation tools' fallback paste landed a stale
88+
clipboard instead of the transcription; plain Ctrl+V now reaches the
89+
browser's native paste handling.
90+
- Terminal-dock drag gestures: an interrupted drag (pointer cancel or lost
91+
pointer capture) can no longer leave the gesture armed for a later stray
92+
pointer move to resume from a stale origin.
93+
794
## [1.22.0] — 2026-07-21
895

996
### Added

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SuperBased Observer
1+
# SuperBased
22

33
> The exact tokens your AI provider billed you — cache splits,
44
> reasoning tokens, long-context surcharges — reconciled across 26
@@ -47,7 +47,7 @@ can't give you, in order of how much they matter:
4747
tokens, long-context repricing — the same math your invoice uses,
4848
not a JSONL-derived estimate. It's accurate enough that it caught
4949
its **own** bug: a Codex reasoning-token double-billing regression
50-
Observer found and back-corrected months of history for
50+
SuperBased found and back-corrected months of history for
5151
(migration 058, shipped v1.18.0) — the kind of self-audit a vendor
5252
console has no incentive to run against itself.
5353
2. **Local-first, by construction.** The watcher, proxy, dashboard,
@@ -78,7 +78,7 @@ machine, with an optional team rollup server for org-wide spend.
7878
**Plane A** is general LLM-app observability — admin-server-first:
7979
OTLP trace/span capture, evals, and an LLM-as-judge input-admission
8080
guardrail for an application *you* host, whose end users route
81-
through Observer. Most solo developers only ever touch Plane B; teams
81+
through SuperBased. Most solo developers only ever touch Plane B; teams
8282
add Plane A when they're also running an LLM-powered product. Full
8383
explainer: [superbased.app/docs/getting-started/two-planes](https://superbased.app/docs/getting-started/two-planes)
8484
(or [docs/deployment-models.md](docs/deployment-models.md) if you're reading this in the repo).
@@ -509,7 +509,7 @@ while you work.
509509

510510
*General observability — [Plane A](https://superbased.app/docs/getting-started/two-planes). Distinct
511511
from the coding-agent usage above: this observes an LLM **application**
512-
you run at the admin level, whose **end-users** route through Observer.*
512+
you run at the admin level, whose **end-users** route through SuperBased.*
513513

514514
<p align="center">
515515
<img src="docs/assets/screenshots/13-trajectories.png" alt="Trajectories — OTLP trace and span capture (general-observability plane)" width="900">
@@ -842,7 +842,7 @@ bearers for agents; no prompts, command bodies, full assistant responses, or
842842
file contents ever leave the machine — even in the opt-in full-content mode,
843843
only the small set of fields the agent already stores in metadata-only mode
844844
gets expanded. The server ships as a signed Docker image
845-
(`ghcr.io/marmutapp/observer-org`) and a Helm chart (`charts/observer-org/`).
845+
(`ghcr.io/superbasedapp/observer-org`) and a Helm chart (`charts/observer-org/`).
846846

847847
Local-in-5-minutes: `observer-org quickstart` brings up a dev compose stack,
848848
provisions an admin, mints an enrolment token, and prints a ready-to-share

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.22.0",
4+
"version": "1.23.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": [

charts/observer-org/values.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
replicaCount: 1
88

99
image:
10-
repository: ghcr.io/marmutapp/observer-org
10+
repository: ghcr.io/superbasedapp/observer-org
1111
pullPolicy: IfNotPresent
1212
# Defaults to the chart's appVersion when empty. Override per release,
1313
# e.g. tag: v1.7.0.

cmd/observer/attach_host.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,6 +1127,15 @@ func (s *attachSession) ReclaimWriter() error {
11271127
return nil
11281128
}
11291129

1130+
// ReclaimAvailable satisfies attachsock.ReclaimAvailabler: a real keystroke can
1131+
// reclaim the writer only when a reacquire hook is wired
1132+
// ([terminal.attach].reclaim_on_input on). Lets the server word the takeover
1133+
// notice honestly — offering "press a key to take control back" only when that
1134+
// gesture will actually reclaim.
1135+
func (s *attachSession) ReclaimAvailable() bool {
1136+
return s.reacquire != nil
1137+
}
1138+
11301139
// CorrelatedSessions satisfies attachsock.CorrelationSource. It returns the
11311140
// per-run correlation channel (nil when the hub is disabled — the server's
11321141
// relay treats a nil channel as "no correlations", so no frame is ever sent).

cmd/observer/attach_standalone.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,13 @@ func buildTerminalStack(cfg config.Config, database *sql.DB, logger *slog.Logger
153153
return svc.RunIDForHandle(handle)
154154
}, logger)
155155

156-
opts := termsession.Options{Logger: logger}
156+
opts := termsession.Options{
157+
Logger: logger,
158+
// Startup seed closes the construction-before-controller-wiring window.
159+
// wireRemoteExecuteTier replaces this with the live controller reader
160+
// before either dashboard listener starts serving.
161+
AllowRemoteTakeover: func() bool { return cfg.Remote.AllowRemoteTerminalTakeover },
162+
}
157163
applyTerminalBounds(&opts, cfg.Terminal, logger)
158164
// Remote writer-lease lifetimes (§4.α.2c) come from [remote]; 0 falls back
159165
// to the termsession defaults (5m idle / 30m hard cap).

0 commit comments

Comments
 (0)