Issues #5–#11: provider-agnostic auth, expert tools, multi-ref provenance, session naming (v0.2.2) - #12
Merged
Merged
Conversation
#7, #11) #11: vision-expert subagents (task/task_batch) now run a bounded agentic loop instead of a single completion. They can call `view_region` (zoom into a normalized bbox at full resolution) and `view_page` (load another page from the source) to pull in detail on demand, rather than depending on the orchestrator to guess the right crop up front. The loop is capped at 8 tool calls; the full exchange (tool calls + results) is kept in the session and persisted as `steps`, with tool-result images re-cropped from disk on restore (no base64 bloat). Tools are only offered to models that can consume images, and the loop honors the caller's abort signal (threaded through task/task_batch). #7: removes the hardcoded `google/gemini-3-flash-preview` default. When no model is specified, experts fall back to the orchestrator's current model (whatever the user has selected/authed in pi) — no provider is baked in. Model recommendations move to the docs. Prompts/tool descriptions are de-Geminified and document the new self-zoom tools. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
On agent_end the pi-package summarises the session's USER prompts (only — never assistant replies, tool results, or page images) into a short title using the cheapest model pi has auth for, and caches it in a `.chronos/session-names.json` sidecar keyed by session id. The title is refined over the first few prompts then locked, with an in-process in-flight guard and atomic (temp+rename) writes. Best-effort and provider-agnostic: it falls back silently to the existing first-message truncation if no model is configured, the user is offline, or the call fails — naming never blocks the history list. The host overlays this name only when the user hasn't set one explicitly (precedence: user name > generated > first-message truncation). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…mes (#9, #8) #9: the "N messages" label in the history drawer now counts only USER prompts, not assistant/tool messages (which an agent that fans out many expert turns per prompt inflates meaninglessly). The cheap prefix scan still pre-filters by the `"role":"user"` substring, but now confirms the parsed role so a tool/assistant line that merely embeds that text isn't miscounted. #8 (host side): the session scan overlays the pi-package's auto-generated name (.chronos/session-names.json) as the display-name fallback, read fresh per listing so a late-written name isn't masked by the per-file mtime cache. Also extends the webview protocol (ChronosSessionInfo gains sessionId/userName; new loginRequired / viewer/clearSource / login messages used by #5/#6/#10). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…sion reset (#6, #5, #10) These three land together because they co-edit the panel, app, data-viewer, and styles. #6 — first-class login: pi's /login is TUI-only and unusable over RPC, so when no models are available the panel shows a discoverable CTA (header "Log in" button + empty-state banner). It opens a provider picker + API-key input, writes <PROVIDER>_API_KEY to .chronos/.env, and restarts the agent. Provider-agnostic; also exposed as the "Chronos: Connect AI Provider" command. Init Workspace no longer prompts for a Gemini key (#7), and the .env reader accepts mixed-case custom variable names. #5 — multi-reference provenance: a data row may cite several (page, bbox, source) locations via list-valued chronos_page/chronos_bbox/chronos_source; the viewer renders one citation chip per reference. Scalars still work (treated as a single reference) and a length-1 list broadcasts. Lists align by index, and an invalid page in the middle of a list no longer shifts the alignment of the others. #10 — new-session reset: on a fresh session the host clears the viewer + source dropdown (viewer/clearSource) so the displayed state matches the (unbound) selection, re-arming the Data-tab refresh guard and dropping a late preview that resolves after the clear. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…ulti-reference rows (#5, #6, #7, #11) - #7/#6: drop "Gemini API key required" framing across README, the extension README, and DOCS; document the native "Log in" flow and the standard per-provider env vars. Model choice is the user's; recommendations (cheap model for routine pages, stronger for hard ones) now live in the docs, not in code. - #11: document the expert self-zoom tools (view_region / view_page) and the bounded tool loop. - #5: document list-valued provenance keys (multiple references per row) with examples and the index-alignment / broadcast rules. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…in (#6) Extends the panel login beyond API keys: the "Log in" picker now offers "Anthropic — Claude Pro/Max (subscription)", which runs the OAuth flow directly from the host (pi's own /login is TUI-only and unreachable over RPC). A self-contained anthropic-oauth.ts module (no pi runtime dependency — constants copied verbatim from pi-ai, same as rpc-types.ts) does PKCE + authorize URL + the localhost callback server + token exchange. The flow opens the browser, auto-captures the redirect on localhost:53692 (with a paste-the-code fallback if the browser is remote or the port is busy), exchanges the code for tokens, and writes the credential to ~/.pi/agent/auth.json in pi's exact shape ({anthropic:{type:"oauth",...}}) — so the running pi reads and refreshes it. Then it restarts the agent and models populate. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Experts now run a tool loop (view_region/view_page), but that activity was invisible — the drawer only showed prompt/response. Now each runExpertTurn returns a compact `toolUses` summary (tool + page + bbox + isError), the task/task_batch result carries it in `details`, and the expert drawer renders each as an "examined" step. Region/page steps are clickable viewer links (reusing the data-page/data-bbox view-link path), so the historian can jump to exactly what the expert pulled in — full oversight of what the task did. Works live and on resumed sessions (details survive history). Guarded by a new UI test asserting the drawer renders the tool-use links. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…#11) Expert subagents now have a real capability model: - Read-only by default: view_region, view_page, read_file, list_dir, grep — the file tools are scoped to the workspace root (path-escape rejected). - The orchestrator can elevate a single task/task_batch call with grant: ["bash"|"write"|"edit"], adding bash / write_file / edit_file. This is OFF by default for oversight and safety, and requesting it triggers a user confirmation before any expert runs (once per task, once per batch cohort); denial aborts the call. executeExpertTool also refuses any elevated tool whose capability wasn't granted (defense in depth). Tool definitions are now built per-turn from (vision capability + granted caps), each call is captured with a short detail (command/path/term) and surfaced in the expert drawer: page steps stay clickable viewer links, file/search/command steps show as chips, and bash/write/edit are visually flagged so elevated actions are easy to audit. Prompts/docs explain that experts are read-only by default and that grants need user consent. Verified: agent-side integration test (15 cases incl. capability denial, path sandboxing, bash exec, write/edit) + the UI suite asserting the drawer renders links, chips, and the flagged elevated action. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Split machine-level dependency install out of "Init Workspace" into its own
chronos.setup command, and add a Getting Started walkthrough so onboarding is
discoverable and each step's scope is distinct.
- chronos.setup ("Install Dependencies") wraps ensureBootstrap; chronos.init no
longer installs deps (it only scaffolds the workspace); startSession keeps its
lazy gate.
- Install runs as an awaited VS Code task (runSetupTask) instead of a
fire-and-forget terminal, so the flow auto-continues instead of telling the
user to re-run the command.
- Getting Started walkthrough (4 steps) with context-key-driven completion;
auto-opens once on first run when pi is missing. Activation moved to
onStartupFinished; HttpServer now binds lazily so startup has no side effects.
- Unify pi-binary detection with the launcher: extract resolvePiBin + hasPi into
pi-env.ts so "is pi present?" matches "how pi is launched" (fixes false
negatives when pi isn't on GUI VS Code's PATH).
- Dev overrides: chronos.piPackageSource (install the pi-package from a local
path or branch) and chronos.piNpmPackage; default pi CLI package is the
maintained @earendil-works/pi-coding-agent.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@mariozechner/pi-{coding-agent,ai} are deprecated (frozen at 0.73.x); the
maintained packages are @earendil-works/pi-{coding-agent,ai} (same author, a
scope rename). Move the pi-package's build off the deprecated scope.
- Rename both peer deps and all 17 import specifiers across tools/ and utils/;
reinstall (lockfile updated).
- Reconcile event handlers with the 0.79 API: session_switch folded into
session_start (now carries `reason`); the session_directory hook is removed
(pi >=0.7x dropped it -- PI_CODING_AGENT_SESSION_DIR replaces it). Both hooks
were already non-firing on the 0.79 runtime.
- Update CLAUDE.md and README to match.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Generate session titles with a small, current model chosen for the orchestrator's provider instead of the registry's blind "cheapest", which ranks decommissioned models first and 404s at call time. helperModelCandidates() returns ordered specs best-first: the orchestrator provider's small tier (haiku/flash/nano), then any auth'd small-tier model from any provider, then the cheapest, then the orchestrator's own model; generateSessionTitle tries each until one succeeds. Hardening from the pre-release review: - rank rolling "*-latest" aliases first (they have no version digit but are always the currently-served model); - when no orchestrator is known, still prefer an auth'd small-tier model over the possibly-retired global cheapest; - defensive cost accessor so a cost-less custom-provider model can't throw the comparator out of the (try/catch-free) candidate builder; - correct the saveSessionName JSDoc, which overstated cross-process write safety (atomic publish only; same-workspace races self-heal on next agent_end). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Pre-release review fixes to the vision-expert tool loop: - read_file/list_dir/grep are always-on (no human gate) but resolveInWorkspace only blocked path escapes, so a default read-only expert could read .chronos/.env (provider API keys) and echo them into the transcript. Apply walkFiles' policy (dot-dirs + SKIP_DIRS off-limits) to every path-based tool, and filter those entries out of list_dir. - A cancel that lands while complete() is in flight resolves with an "aborted" response rather than throwing; it was committed to the session, persisted, and returned ok:true — so callers wrote "(empty response)" to output files and the turn was dropped on restore. Treat aborted like a failed turn before pushing/persisting. - Clamp the expert's view_region bbox into bounds in bboxToPixels: the self-zoom bbox isn't schema-validated at call time, so an out-of-range value produced a negative/out-of-bounds extract that made sharp throw. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…#5) Drag a column header's right-edge handle to resize; double-click to auto-fit (canvas text measure). The first interaction seeds every column's rendered width and flips the table to fixed layout, so untouched columns hold and the table can grow past the viewport with horizontal scroll. Includes pre-release review fixes: - Use pointer capture on drag handles (column resize + preview splitter) so a pointerup released outside the webview still tears down the move listener; without it the listener leaked and the column stuck to the cursor with no recovery short of reload. - Prune colWidths to the live column set on in-place reload (Refresh), so a schema change doesn't leave orphan width keys or silently revert to auto layout on a renamed column. - Multi-reference provenance (#5): a malformed flat numeric bbox (length != 4) now collapses to a single null instead of inflating the chip count, and a lone bbox is no longer broadcast across distinct pages (only across regions of one page), which had mis-cropped the other pages. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…e dev settings Auto-open the panel and start a session when a Chronos workspace (a folder with .chronos/) is opened. Opt out with chronos.autoStartSession. Gated and hardened so the launch is never a surprise: - Fire only when the bootstrap is already reconciled (deps present AND at the ref this extension wants), not merely deps-present. Otherwise an extension upgrade (stale stored ref) would auto-fire an unsolicited `pi install` terminal on every startup, re-firing on each launch if the install failed. A stale / un-set-up workspace falls back to the manual command / walkthrough. - Serialise chronos.startSession with an in-flight guard so auto-start racing a walkthrough/manual click can't construct two panels + pi subprocesses before ChronosPanel.current is assigned. Mark chronos.piPath / piPackageSource / piNpmPackage as "scope": "machine" so a malicious workspace .vscode/settings.json can't supply values that get interpolated into the setup ShellExecution (the install path is reachable without a modal for an already-installed returning user). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…ion label Pre-release review fixes around the new login flow and UI: - Write .chronos/.env and ~/.pi/agent/auth.json owner-only (0o600) and chmod after writing (writeFileSync's mode only applies on creation), and create the agent dir 0o700 — mirroring pi's auth-storage hardening. These hold billing-bearing API keys / long-lived OAuth tokens. - Use pointer capture on the main app splitter (same leak class as the data-viewer handles). - Generalise the login button/banner copy: it claimed "saves an API key to .chronos/.env", wrong for the Anthropic subscription OAuth path (which writes auth.json, no API key). - Skip the synthetic "Source selected: …" follow-up when picking a session's first-message label, so it never surfaces as the history label (the agent-side namer already skips it). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Bump both packages to 0.2.2 for the release. Also resync the chronos-vscode lockfile, whose own version had drifted to 0.2.0. Note: ensureBootstrap pins the pi-package install to the `v<version>` git tag, so cutting the release requires a `v0.2.2` tag on the repo. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The UI test injects its mock pi via a workspace-scoped chronos.piPath in the fixture's .vscode/settings.json (test/run-ui-test.mjs); machine scope made VS Code ignore that workspace value, so the extension fell back to "pi" on PATH and the agent failed to spawn (ENOENT). piPath wasn't one of the shell- interpolation vectors the review flagged — only piPackageSource / piNpmPackage are (those stay machine-scoped). Restore piPath to its prior window scope. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves the #5–#11 milestone and prepares the 0.2.2 release. Each issue was re-verified resolved by an adversarial review pass, and the confirmed findings from that pass are folded in.
Features
/loginin chat.Pre-release hardening (from the adversarial review)
.chronos/.env(provider keys) via read_file/list_dir/grep.pi install); in-flight start guard..env,auth.json) written0o600; dev settings markedscope: machine.Release
ensureBootstrappins the pi-package to thev<version>tag, so av0.2.2tag is required after merge.Build green: chronos tsc · host tsc · webview tsc · esbuild · RPC contract canary.
Closes #5
Closes #6
Closes #7
Closes #8
Closes #9
Closes #10
Closes #11
🤖 Generated with Claude Code