AWT Chat — VS Code Extension
A production-grade chat panel for the AWT
multi-agent coding runtime. Sidebar webview + status bar + slash-command
palette, integrated with VS Code's editor + Quick Pick + clipboard APIs.
Status: stable. Streaming chat, multi-turn memory, interactive
approval modal, sub-agent dispatch, cost tracking, transcript
import/export. See docs/AWT-CLI-CONTRACT.md
for the exact awt CLI flags the extension drives.
Features
- Streaming chat — NDJSON event stream from
awt --ndjson-events
rendered live (text, tool start/result, thinking deltas, mode changes)
- Multi-turn memory — prior turns prepended to each
awt -p invocation
(cap via awt.multiTurnMemoryMaxTurns)
- Workspace context auto-injection (R.4) —
.awt/AWT.md, AGENTS.md,
CLAUDE.md, top of README.md, framework hint and per-workspace
scratchpad are read once per session and inlined into the system prompt
- Per-workspace scratchpad (R.14) —
/scratch <note> appends to
.awt/scratch.md; injected automatically into the next session's
prompt so cross-turn intent survives a restart
- Framework auto-detect (R.13) —
package.json / Cargo.toml / etc.
scanned at boot; the detected framework appears in the status bar and
becomes a hint to the dispatch_specialist tool
- Interactive approval —
bus.awt.approval.requested events surface a
VS Code modal with human-friendly summary + path-scope warning for
out-of-cwd or OS system paths (P.2); user's choice is written back via
awt --stdin-commands
- Composer chips — permission mode picker (Codex-style dropdown), model
picker (live from
awt --list-models, P.1), effort level, "+ open file"
toggle, "📎 Attach…" media browser, voice input
- Slash commands —
/clear, /model, /mode, /effort, /system,
/agent, /save, /recall, /templates, /mcp, /stop, /settings,
/output, /help, /scratch, /show-scratch, /awt-md with / popup
@file mention — fuzzy file search popup tied to VS Code's index;
📁 Browse files… row opens a native OS picker (P.3 follow-up)
- Drag-drop media (P.3) — drop images/audio/video/PDFs onto the
composer; resolved to
@<path> tokens. Outside-workspace files are
copied into a workspace pastes dir + injected; images go to the LLM as
image_url content blocks
- Inline diff — file_edit results render as unified diff with green/red
bars; file_write shows "NEW FILE" chip + collapsible content. Every edit
offers:
- 🪞 Native diff — pops VS Code's real diff editor (split view,
gutter glyphs, jump-to-change keybindings)
- ↩ Undo — re-substitutes new_string → old_string on disk (Q.2)
- ✗ Reject — reverts the edit AND pre-fills the composer with a
re-prompt template so you can describe what you actually wanted (U.1)
- Sub-agent dispatch (N.1–3) —
dispatch_specialist tool routes to
any of 200+ YAML-defined specialists in ~/.awt/agents.d/; manifests are
hot-reloaded by the binary (U.2) so a freshly-dropped YAML is dispatchable
without restart
- Code actions (Q.1) — Quick Fix → "Fix with AWT" on red diagnostics;
passes absolute path + diagnostic message + recommended specialist hint
- Inline completion (R.9) — opt-in FIM-style ghost text via the
awt.inlineCompletionEnabled setting; 60s cache, 8s timeout
- Sidebar tree views (R.1) — Active Agents · Bg Shells · Approvals ·
MCP Servers (hidden by default; enable via
awt.showTrees)
- Auto-collapsing pager — long tool output truncated to 2 lines + toggle
- Status bar item —
model · framework · ↑in ↓out · $cost always visible
- Editor integration — right-click → "Send Selection to AWT"
(
Cmd+Alt+A) with action palette (explain / refactor / test / docstring,
R.7), CodeLens "Ask AWT" on functions across 8 languages
- Test runner integration (R.5) — failing test surfaces a "Fix with AWT"
CodeLens that re-runs after the patch
- Commit message generation (R.6) —
awt.generateCommitMessage command
- SCM input capture; uses
git diff --cached as the prompt
- Cost tracking — built-in price table for Claude/GPT/Llama families,
user-overridable per model; budget warning at configurable threshold
- Transcript persistence — auto-save to workspace state + export/import
to JSON/Markdown
- Paste image support —
Cmd+V an image into the composer → saved to
.awt/pastes/ and inserted as @<path>
- Auto-retry on transient failures (capped, configurable)
- Reverse history search —
Ctrl+R or ↑ on empty input
Setup
The extension ships the awt backend binary for every platform
(macOS, Linux, Windows — x64 and arm64) inside the .vsix, so there is
nothing to build or configure:
- Install the extension.
- Open the AWT chat panel (activity-bar icon, or
Ctrl/Cmd+Shift+A).
- Configure a provider — run AWT: Configure Provider from the Command
Palette (URL + token), or set
awt.providerUrl / awt.providerToken
in Settings. That's it.
Power users can point at their own build with the awt.binaryPath
setting; leave it empty to use the bundled backend.
Run / debug (contributors)
To hack on the extension itself, from a clone of this repo:
npm install # dev deps
npm run build # bundle src → out/extension.js (also runs on F5)
Then in VS Code press F5 (Run → Start Debugging) to launch an Extension
Development Host with the extension loaded; open any folder to use as the
cwd for awt. To rebuild the bundled backend binaries from a sibling
awt checkout, run AWT_REPO=/path/to/awt ALL=1 scripts/bundle-binaries.sh.
Settings
| Setting |
Default |
Notes |
awt.binaryPath |
awt |
Absolute path or awt if on PATH |
awt.model |
"" |
Forwarded as --model |
awt.effort |
"" |
low / medium / high / max → --effort |
awt.systemPrompt |
"" |
Forwarded as --system |
awt.maxTurns |
0 |
0 = awt default |
awt.extraArgs |
[] |
Appended verbatim, e.g. ["--verbose"] |
awt.workingDirectory |
"" |
Empty = first workspace folder |
awt.timeoutMs |
600000 |
Hard kill after this many ms |
Commands
| Command |
Title |
Default keybinding |
awt.toggle |
Toggle Panel — open if hidden, close if visible |
Cmd/Ctrl+Shift+A |
awt.sendSelection |
Send Selection to Chat |
Cmd/Ctrl+Alt+A |
awt.quickPick |
Slash Command Palette |
Cmd/Ctrl+Alt+P |
awt.newChat |
New Chat |
— |
awt.clearChat |
Clear Chat |
— |
awt.stop |
Stop Current Request |
— |
awt.openSettings |
Open Settings |
— |
awt.showOutput |
Show Output Log |
— |
Where the panel lives
By default the AWT view opens in the primary side bar (left) under
its own "AWT Chat" activity bar entry. If you'd rather have it behave
like Claude Code — pinned to the right side, toggleable on demand —
you can move it once and VS Code remembers the position:
- Right-click the AWT icon in the activity bar → Move View →
Secondary Side Bar (or Panel for bottom-dock).
- Use
Cmd/Ctrl+Shift+A (or the $(comment-discussion) icon in the
editor title bar) to toggle visibility from anywhere.
The toggle is smart: it closes whichever container holds the view
(primary side bar / secondary side bar / bottom panel) and re-opens
it from the same spot on the next keypress.
Packaging
npm install
npm run build
npm run package # produces awt-vscode-0.0.1.vsix
code --install-extension awt-vscode-0.0.1.vsix
Editor compatibility
The extension uses only stable VS Code APIs (no proposed APIs, no
extension dependencies) so any fork with a current extension host runs
the same .vsix:
| Editor |
Install command |
| VS Code 1.85+ |
code --install-extension awt-vscode-0.0.1.vsix |
| Cursor 0.40+ |
cursor --install-extension awt-vscode-0.0.1.vsix |
| VSCodium 1.85+ |
codium --install-extension awt-vscode-0.0.1.vsix |
Full verification matrix and Cursor-specific notes:
docs/IDE-COMPAT.md.
Layout
awt-vscode/
├── package.json ← extension manifest
├── esbuild.config.js ← bundler (single CJS file out/extension.js)
├── tsconfig.json
├── src/
│ ├── extension.ts ← activate(), registers commands + provider
│ ├── chatProvider.ts ← WebviewViewProvider; owns turn state
│ ├── awtClient.ts ← spawns awt, parses NDJSON, streams events
│ ├── messageTypes.ts ← shared wire types (host ↔ webview)
│ └── logger.ts ← OutputChannel wrapper
├── media/
│ ├── chat.html ← webview shell (CSP + nonce templated)
│ ├── chat.css ← VS Code-theme aware
│ ├── chat.js ← composer + message rendering (tiny markdown)
│ └── icon.svg ← activity bar icon
└── docs/
└── AWT-CLI-CONTRACT.md ← what awt CLI is expected to expose
Privacy & telemetry
The extension makes no network calls of its own. It spawns
awt --ndjson-events ... as a subprocess and pipes events to the
webview. Network traffic from awt itself goes only to whatever LLM
provider you configured (Anthropic, OpenAI, OpenAI-compatible, Bedrock,
local llama.cpp, …) — there is no AWT-operated analytics or update
endpoint. See the binary's
docs/TELEMETRY.md
for the full inventory.
Transcripts persist in VS Code's workspaceState (under
workspaceStorage/<id>/) and are never transmitted by the extension.
Caveats
- Multi-turn memory is replayed, not server-held. Each send re-attaches
prior turns as context (capped by
awt.multiTurnMemoryMaxTurns). When awt
grows a chat-serve mode this switches to a long-lived session handle — see
the CLI contract doc for the migration path.
- Tiny markdown renderer. Code fences + inline code + bold/italic only — no
XSS sink, no external deps. Upgrade later if you want full GFM.
- No streaming for non-JSON output. If awt emits plain text (no
--json
honored), it falls through to raw text rendering — still works, just no tool
events.