diff --git a/desktop/package-lock.json b/desktop/package-lock.json index 3ea3f463a..a15ce2d15 100644 --- a/desktop/package-lock.json +++ b/desktop/package-lock.json @@ -1,12 +1,12 @@ { "name": "termipod-desktop", - "version": "2026.727.938", + "version": "2026.730.1242", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "termipod-desktop", - "version": "2026.727.938", + "version": "2026.730.1242", "dependencies": { "@codemirror/commands": "^6.10.4", "@codemirror/lang-markdown": "^6.5.0", diff --git a/desktop/package.json b/desktop/package.json index 083b83710..29ca2573c 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -1,7 +1,7 @@ { "name": "termipod-desktop", "private": true, - "version": "2026.727.938", + "version": "2026.730.1242", "type": "module", "description": "TermiPod desktop control plane — the unified web-tech client shell (WS2 of docs/plans/desktop-control-plane.md). Browser-target build; the Electron shell (desktop/electron) packages it (ADR-055).", "scripts": { diff --git a/docs/changelog-desktop.md b/docs/changelog-desktop.md index 708e9f0a2..4cf550b05 100644 --- a/docs/changelog-desktop.md +++ b/docs/changelog-desktop.md @@ -1,9 +1,9 @@ # Desktop Changelog > **Type:** reference -> **Status:** Current (2026-07-27) +> **Status:** Current (2026-07-30) > **Audience:** contributors, operators -> **Last verified vs code:** desktop 2026.727.938 / electron-v2026.727.938-alpha +> **Last verified vs code:** desktop 2026.730.1242 / electron-v2026.730.1242-alpha **TL;DR.** Append-only record of what shipped in each **desktop workbench** release. One section per version, newest first. Format follows @@ -39,6 +39,74 @@ This complements: --- +## 2026.730.1242 — 2026-07-30 + +**J8 Replay lands end to end, architecture diagrams go hybrid-aware, agents can +drive a browser, and the shell splits in two.** `electron-v2026.730.1242-alpha` +(unsigned alpha channel). The largest desktop cut so far — 52 commits since +2026.727.938 — because five plans reached their shipping wedges at once. + +### Added +- **J8 Replay — the whole job.** A dataset library rail with a folded digest + card and a paged episodes table (#448); **Open in Replay** from an Inspect + `meta/info.json` row (#454); the **episode player** — channel plots against a + shared cursor (#459) and a multi-camera video grid over a range-serving media + scheme (#462); a **URDF reader with forward kinematics** plus a robot manifest + (#465) driving a **3D pose panel** off the episode cursor (#466); the **Rerun + companion** with a launch policy and manager (#469), an **Export to Rerun** + action (J8 W4b-1), and a remote export fetched over the director's own SSH + session (J8 W4b-2); and a run's episodes one step from the player (#468). + Remote roots read video over SFTP through the SSH-forward wedge. +- **Architecture graph, hybrid-aware.** The arch card classifies hybrid + linear-attention models (#430) and sizes their KV cache honestly with a + KV-cache-per-token class (#431); the schematic lays out heterogeneous stacks + (#432) and renders them as a pattern strip with nested groups (#434); panels + zoom, carry an annotation layer, and export to SVG/PNG (#435); and an + architecture can be **compared against another model's config** over a pure + `diffArchCards` (#433, #436). +- **Agent browser bridge (W1–W3).** MCP-driven webtabs an agent can read + (#471), then act in — action tools behind a per-spawn opt-in with an audit + trail (#472) — and finally drive remotely, hub-relayed, with approval cards + (#474). +- **Split pane (S1–S3).** One pinned secondary surface beside the primary, + opened by Alt-clicking the activity rail or `Mod+\`, swapped with + `Mod+Shift+\`, resized by a draggable divider. The focus snapshot describes + both panes, so an agent asked about "this" resolves against the pane the user + is actually in. +- **UI context + pointing (D1–D2).** A `ui_get_focus` MCP tool — off by + default — lets an agent on this host ask what the director is looking at + (#476), and an annotation overlay lets the director point at it in return + (#477). +- **Env profiles + sealed secrets on the desktop.** A picker in the spawn sheet + (#400) and a management UI in Settings (#401); env-profile secrets are sealed + to the target host at spawn behind a host-key trust dialog (#412), with a + re-trust flow when a host's key changes. +- **Session teleport.** Move a paused session to another host from the desktop + (#423), with secret-bearing sessions re-sealed to the target rather than + refused (#425). +- **SSH parity with mobile.** Jump hosts (`ProxyJump`) and SOCKS5 proxies for + connections, parsed from and written back to `ssh_config` on import/export. +- **App-level assistant dock** with a status-bar chip, rebindable shortcuts, a + full ⌘K palette, an author filter, and "compare from roots/repos" (#411, + #464); Insight boards for projects and hosts. +- **Issues drawer on the run report** (#438), and an environment chip on the + episode player header plus an `env_ref` row on the run detail (#478). + +### Fixed +- **The vault detail pane carried the previous item's secret across a + selection change** — a real disclosure risk: switching entries could show one + item's secret under another's name. +- **Terminal right-click owns its context menu**, with honest paste behaviour + and OSC 52 support, instead of the shell's menu winning. +- **kimi-code config rows that don't exist are dropped** and the plugins path is + corrected; the Inspect schema pane falls back rather than blanking, and the + archgraph menu moved onto the shared primitive (#390 review). +- **`ui_get_focus`'s description names the split fields** — it still called + `surface` "the active surface" after S3 made it the primary pane, which would + have sent an agent's "this/here" to the wrong half. +- **The Tauri keychain migration read is skipped under `TERMIPOD_E2E`** (#473), + so the e2e suite stops touching a real keychain. + ## 2026.727.938 — 2026-07-27 **Inspect VLA/policy configs, roots context menus, Windows kimi-web fix.** diff --git a/docs/changelog.md b/docs/changelog.md index 46aadf2c1..f8290b391 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,9 +1,9 @@ # Changelog > **Type:** reference -> **Status:** Current (2026-07-27) +> **Status:** Current (2026-07-30) > **Audience:** contributors, operators -> **Last verified vs code:** 2026.727.206-alpha +> **Last verified vs code:** 2026.730.1231-alpha **TL;DR.** Append-only record of what shipped in each tagged release. One section per version, newest first. Format follows @@ -39,6 +39,132 @@ binding). Seed entries prior to that are in --- +## 2026.730.1231-alpha — 2026-07-30 + +**Env profiles, sealed secrets and session teleport reach the phone.** An +agent can now be spawned into a prepared environment from mobile — picked in +the spawn sheet, managed on its own screen — with secret values sealed +client-side to the target host's key so the hub only ever stores ciphertext +it cannot read (ADR-056). A paused session can be moved to another host and +resumed there (ADR-057). The run report gained an Issues sheet, and the +transcript's streaming path stopped re-parsing the whole message on every +chunk. + +**All three lanes are cut at this version** — `mobile-v2026.730.1231-alpha`, +`hub-v2026.730.1231-alpha`, `host-v2026.730.1231-alpha`. Hub and host were last +tagged at **2026.724.335**, so they ship everything since: 51 commits, +including the `host.update` fixes the 2026.727.206 section described as waiting +on a redeploy. **Operators must redeploy the hub and host-runner binaries** for +any server-side entry below to take effect. The desktop workbench cuts +separately at `2026.730.1242` +([`changelog-desktop.md`](changelog-desktop.md)). + +### Added +- **Env profiles on mobile.** The spawn sheet gains an env-profile picker, and + a dedicated management screen creates/edits/deletes profiles — setup script, + plain env vars, secret refs, network policy — so an agent starts in a + prepared shell instead of a bare one. (#402, #403) +- **Client-side env-secret sealing.** Secret refs resolve from the + zero-knowledge vault on the device and travel as envelopes sealed to the + target host's public key; the hub stores ciphertext it can never read + (ADR-056 D-3). The Rust and Dart implementations are KAT-locked against the + Go one, so all three agree byte-for-byte or the tests fail. (#409) +- **Host-key fingerprint short code.** A host's env-seal key shows a short + verification code, so a human can confirm they are sealing to the machine + they think they are before a secret leaves the device (ADR-056 D-2). (#410) +- **Teleport a paused session to another host.** A paused session can be moved + to a different machine and resumed there, carrying its conversational state + through the handoff bundle (ADR-057, T2c). (#428) +- **Issues sheet on the run report.** The report surfaces the run's recorded + issues in a sheet rather than leaving them to the raw transcript. (#439) +- **Env profiles, hub + host side (ADR-056).** The `env_profiles` entity with + REST CRUD (#396), env vars materialized into a spawn's spec (#397), a + `setup_script` run in the workdir before the agent (#398), and project-level + inherit plus the MCP schema for attaching one (#399). Secrets travel as + envelopes: an X25519 sealed-box crypto core with AAD binding (#404), an + X25519 host identity published through host capabilities (#405), an + `env_secret_envelope` column with presence-enforcement 422s (#406), and + host-side unseal + injection into the child's **real process environment** + for M4/exec (#407) and for M1/M2 persistent stdio (#408) — never the command + string, the spawn spec, a temp file, or a log (ADR-056 D-5). +- **Session teleport, hub + host side (ADR-057).** A chunked-manifest bundle + transport (#416), git-worktree handoff (#417), engine-state snapshot/restore + for claude-code (#418) and kimi-code-ts (T2b), `session_handoff_pack/unpack` + command kinds (#419), heterogeneous-host path portability (#420), the + teleport endpoint with pause-first orchestration (#421), secrets re-sealed to + the target host (#424), and a non-worktree path over a capped directory tar + (#426, #427). +- **Datasets as a hub entity (J8 Replay, ADR-060).** A `datasetmeta` reader for + both LeRobot generations (#446), the `datasets` entity + REST CRUD + host + read verbs (#447), a per-episode feature-series reader (#457) and its + endpoint (#458), per-episode video paths resolved uniformly across + generations (#461), and a run→dataset provenance link (#467). Episodes are + never materialized hub-side — the table is proxied from the host, windowed + and capped. +- **Detached host jobs (ADR-058).** A host-job executor (J8 W4b A1) and its + first kind, `dataset_export_rrd` (A2) — a long computation runs on the host + and is polled, so no request is held open for it. +- **Blob lifetime (ADR-061).** A blob declares its class and is deleted only by + expiry, never by a sweep guessing at reachability. +- **Environment handles on runs (environments plan E0).** `runs.env_ref` + carries the opaque `family:env_id@version` provenance handle (migration + 0072), settable at create and patchable, alongside the same field on + datasets. Deliberately unvalidated and never inferred from the linked + dataset. (#478) +- **Structural session-integrity issues fold into the digest** (transcript P5 + A1), which is what the mobile and desktop Issues surfaces read. (#437) + +### Changed +- **Streaming transcript costs the current block, not the whole message.** + Rendering a partial no longer re-parses and re-lays-out all accumulated text + on every chunk: highlight/math work left the per-chunk path (#440), and + settled blocks are cached as built widget instances split at safe block + boundaries (#442). Splitting refuses anywhere independent parsing could + change meaning — inside a fence, a list, a block quote, an indented code + block, or any document carrying a link reference definition — and a + completed message is still rendered as one body, so its layout is identical + to before by construction. +- **`flutter_markdown` → `flutter_markdown_plus`.** The Flutter team + discontinued `flutter_markdown` (2025-05-30); this moves to the maintained + continuation, API-identical for everything used here (13 files, no call site + changed). Two renderer behaviours the plan wanted checked on device shipped + as regression tests instead — a link label renders once, and inline `code` + falls through to the stylesheet rather than the highlighter. (#443) + +### Fixed +- **Env-profile attachment fails closed.** Review of the E1/E2 wedges: an + unusable workdir or an unsatisfiable network mode now refuses the spawn + rather than starting an agent in a half-prepared environment, and the + steward sheet's picker matches the ordinary spawn sheet's behaviour. +- **Pinned host env-keys survive a vault round-trip on mobile.** Editing a + vault entry no longer drops the pinned host keys attached to it, which would + have silently un-sealed a profile's secrets on the next spawn (ADR-056 + E3b-2b). (#413) +- **Plain env vars no longer shadow a same-key env secret** on the host — the + hub-visible value would have won over the sealed one, silently handing an + agent the wrong credential (E3 review). +- **Teleport refuses a secret-bearing session** until it can re-seal it, and a + same-host resume replays the existing envelope rather than minting a new one. +- **A queued host job heartbeats**, so the stale-job sweep can no longer fail a + healthy backlog that simply had not started yet. +- **A backup survives a blob vanishing mid-walk** (ADR-061 D-8) — the sweeper + can delete an expired blob while the walk is in flight, and that is not a + backup failure. +- **The session read-repair write runs on the writer pool** (#453), not the + reader pool, which is the only pool allowed to write. +- **The `team` URL parameter is guarded against path traversal** in the template + and journal paths (#422). +- **Kimi's session-index dedupe matches its own lines again** — it never did, so + the index could grow duplicates. +- **ACP `session/new` carries the real workdir**, and an M1 cosmetic pane no + longer leaks (#377). +- **Claude `task_progress` floods and kimi subagent `turn.result` leakage** are + filtered out of the transcript (#375). +- **`host.update` acks after resolve and downloads in the background** (#380), + with the progress watchdog measuring silence rather than total elapsed (#382). + Both shipped to mobile at 2026.727.206; the server halves take effect with + this redeploy. + ## 2026.727.206-alpha — 2026-07-27 **Fleet updates work from mobile again, with live progress.** The diff --git a/hub/internal/buildinfo/buildinfo.go b/hub/internal/buildinfo/buildinfo.go index 9182d9a70..999c43b9f 100644 --- a/hub/internal/buildinfo/buildinfo.go +++ b/hub/internal/buildinfo/buildinfo.go @@ -13,7 +13,7 @@ import ( // mobile and hub use the same x.y.z-alpha numbering. Use // `make bump VERSION=...` from the repo root to update both files // atomically. -const Version = "2026.727.206-alpha" +const Version = "2026.730.1231-alpha" var ( Commit string diff --git a/pubspec.yaml b/pubspec.yaml index 90fd76b8b..720861ae5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -19,7 +19,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # Date-based CalVer YYYY.MMDD.HHMM (UTC build time); the +N build number is # "minutes since 2020-01-01 UTC" (monotonic int32 versionCode — CI recomputes it # from the tag). See docs/changelog.md header for the scheme. -version: 2026.727.206-alpha+3454686 +version: 2026.730.1231-alpha+3459631 environment: sdk: ^3.10.7