feat(vscode): scaffold VS Code extension for issue #35#145
Conversation
Set up extensions/vscode/ as a thin client over the atlas-proxy HTTP API: extension manifest with settings (proxy URL, service token, permission mode, status bar) and command stubs, TypeScript + esbuild build, eslint, vitest test harness, and the src layout for the client/session/ui modules landing in follow-up commits. No functional behavior yet.
Implement the typed client layer over the atlas-proxy public API: - src/client/types.ts: request/event/error shapes from docs/API.md, matching the proxy's Go struct field tags - src/client/sse.ts: pure SSE frame parser mirroring tui/chat.go (comment skipping, [DONE] sentinel, malformed-frame tolerance, chunk-split and multibyte-safe buffering) - src/client/atlasClient.ts: /v1/agent streaming, /cancel (best-effort), /v1/permission (404-as-resolved), /ready, /version; bearer auth; stable error-envelope mapping via AtlasApiError - test/: vitest suites (27 tests) plus a mockProxy fixture — a real http.Server streaming canned SSE, including a permission pause-and-resume flow driven through the client tsconfig gains skipLibCheck: vitest's bundled declarations reference DOM WebSocket types absent from lib ES2022.
|
Commit 2 landed: client core ( Typed transport layer over the proxy's public API — no UI yet, that's commits 3–4.
Zero runtime deps (Node 18 |
…ement
Add a webview chat view backed by a vscode-free TurnManager that mirrors
the TUI's protocol conventions: per-turn 24-char hex session ids, rolling
history capped at 40 entries with assistant text re-wrapped in the
{"type":"text"} envelope, session_allowed_tools re-sent on every turn,
and cancel wired to stream abort plus best-effort POST /cancel.
The webview is a dumb renderer: all state lives in the extension host,
which replays the transcript into any re-created view. Rendering is
textContent-only under a nonce'd CSP. The service token is read from
SecretStorage (atlas.setToken command) with the plaintext setting as a
dev override; 401s surface a "Set Token" action.
permission_request is interim auto-deny (with a visible note) so turns
never sit on the server-side permission timeout; the approve/deny UI
lands in the next commit.
Covered by 12 TurnManager unit tests (39 total).
|
Commit 3 landed: minimal chat ( First interactive slice — a sidebar chat that streams real turns from the proxy. Protocol brain and rendering are split so the protocol part stays testable without VS Code.
One deliberate interim: |
…native prompts - src/session/permissionFlow.ts: vscode-free permission state machine — first-answer-wins settling, session allowlist auto-allow (scope "once", matching TUI), remote permission_denied dismissal by tool name, turn-end cleanup, advisory POSTs with swallowed errors - src/ui/chatView.ts: wire PermissionFlow into event dispatch (replaces interim auto-deny), dual-surface prompts (inline webview card + native notification), transcript-replay-safe prompt/resolution messages - media/chat.js + chat.css: permission cards with Allow Once / Allow for Session / Deny actions and resolved-state rendering - test/permissionFlow.test.ts: 11 tests covering auto-allow, scopes, race arbitration, remote denial, turn end, POST failure paths
|
Commit 4 — interactive permission flow ( Implements the
"View Diff" on permission cards lands in the next commit (diff rendering), which needs the diff provider. |
Predict edits client-side and surface them via native vscode.diff and a read-only atlas-diff: virtual doc, for both permission review and applied changes.
|
Commit 5 — diff rendering for write_file / edit_file / ast_edit ( Client-side edit prediction surfaced through native
This wires up the "View Diff" button deferred from commit 4. |
…ress, CI Poll /ready for a status bar item (pauses while streaming), warn on workspace/proxy mount mismatch, map all 12 proxy error codes to friendly messages, show a live progress line, and add a paths-filtered CI workflow for the extension.
|
Commit 6 — status bar, mismatch detection, error mapping, progress line, CI (final polish)
This completes the v1 scope agreed earlier in the thread. |
feat: VS Code extension — thin client over atlas-proxy (#35)
Relates to #35 (VS Code part; JetBrains deferred). Scaffold-only in this PR — later commits (2–6 in plan below) complete the feature before this can close the issue.
What this is
A VS Code extension under
extensions/vscode/that wraps the atlas-proxy agent loop as a thin SSE client — no agent logic in the extension. Built againstdocs/API.md, with the TUI as the reference client (session_id conventions,session_allowed_toolsre-sent per turn, cancel = abort + best-effortPOST /cancel).Scope (per maintainer review)
POST /v1/agent(SSE) +POST /cancel+POST /v1/permission. Permission approve/deny UI is in scope as required (auto-answer for session-allowed tools, native notification + chat card otherwise; 404 on decision POST treated as already-resolved).write_file,edit_file, andast_edit— computed client-side at permission time (ast_editresult carries no new content, so best-effort splice + snapshot-vs-disk post-view for the exact applied change).ATLAS: Set Service Token, plaintext setting as dev override), permission mode (default/accept-edits/yolo). No model preference setting.Also per review: no file sync (VS Code watcher picks up bind-mounted writes); instead a passive heuristic detects workspace ≠ proxy mounted dir and warns once.
/readypolling drives an optional status-bar badge.Plan (commits land on this branch)
atlasClient(agent/cancel/permission/ready), API types, unit tests + mock proxy fixturepaths: extensions/vscode/**)Out of scope
JetBrains extension, model preference setting, file sync, cross-reload chat persistence.
Follow-up suggestion
No endpoint exposes the proxy's mounted working dir, so the workspace-mismatch check is heuristic (post-edit
fs.stat). A tinyGET /workspacereturning the mounted path would make it exact — happy to file separately if wanted.Testing
npm run compile(tsc + eslint + esbuild) clean;npm test(vitest) passesatlas up) planned per commit: chat turn, edit permission + diff, allow-for-session across turns, mid-turn cancel, 401 path, status-bar states