istari AI
A VS Code companion extension for the istari CLI - a general
bridge between the editor and the CLI over a local socket. You can run the
workflows as guided commands (no CLI typing), approve or deny istari's gated
actions, watch its live thinking and report, and steer a running
session from VS Code instead of the terminal; more interactions can be added
over the same socket.
Guided commands
Run any workflow from the Command Palette (Ctrl/Cmd+Shift+P)
under the istari category - a short prompt sequence assembles the exact CLI
invocation for you, so you never hand-type a subcommand, flag spelling, or enum
value:
| Command |
Prompts |
| istari: Review Pull Request |
Remote PR (URL/number, prefilled from the clipboard) or local changes (scope, optional base); optional linked tickets, context, quality, and flags. |
| istari: Review Ticket |
One or more ticket ids/URLs (prefilled from the editor selection); optional context, quality, and flags. |
| istari: Check Environment |
Provider (all / jira / ado / github) and whether to probe. |
| istari: Initialize Config |
Full interactive wizard or example file only. |
Extra entry points:
- Source Control view → Review Local Changes reviews the current worktree in
one click, targeting the repo the SCM view points at (multi-root safe).
- Editor context menu → istari: Review Ticket appears when you have a
selection, prefilling it as the ticket id.
The quality picker maps to the CLI's refine model: Standard (the default
one round), Fast (--fast), or Refine 2-5 (--refine N). The review
commands use istari.defaultModel (below) for --model; env-check and init
never receive it.
Runs launch as a VS Code task wired to the same approval socket, so approvals
and @istari streaming work exactly as for a terminal run. Only one review runs
at a time (the approval socket is shared); a quick env-check or init can run
alongside it.
How it works
While this extension is active it exports ISTARI_AI_SOCKET into the window's
integrated terminals, so any istari run started here binds the socket
automatically - no --approval-socket flag needed (passing the flag still
works and wins). istari offers each gated permission prompt over that socket; the
extension shows a modal dialog with Approve, Always allow, and Deny
buttons, and your choice is sent straight back.
If VS Code is not connected (or you dismiss the dialog), istari falls back to its
normal terminal prompt - nothing stalls. Concurrent prompts are serialized, so
you always answer one at a time.
sequenceDiagram
participant istari
participant Socket as .istari/istari.sock
participant VS Code as VS Code extension
istari->>Socket: bind socket
VS Code->>Socket: connect
istari->>VS Code: permission_request
VS Code->>istari: {"decision":"approve"}
Note over VS Code: modal dialog
Usage
Build and install this extension (see Development below).
Open a terminal in this window and run istari normally - no flag needed:
istari ticket-review <jira-url>
(Terminals opened before the extension activated won't have the env var yet;
open a fresh one. The istari: Run istari in a terminal command also works.)
The status bar shows istari: connected once linked. Approval prompts appear
as modal dialogs.
Chat: watch, steer, and run
The @istari chat participant reuses VS Code's built-in chat - no separate UI:
@istari /watch - stream the running agent's thinking and report here.
@istari /reasoning - stream only the thinking (reasoning) progress.
@istari /report - stream only the report/output and the final result.
@istari /run <args> - start a run in a terminal (e.g. /run ticket-review <url>) and stream it here.
@istari <message> - steer the run: the message is queued and folded into
the agent's next pass (istari can't interrupt a pass mid-flight, so it applies
at the next draft/repair/refine/steer pass). Steering never changes permission
decisions.
Streaming into chat needs an open chat turn, so start with /run (or invoke
/watch while a run is active). Cancel the chat response to stop watching;
approvals still appear as modal dialogs.
CI / headless: omit the extension and use --yes (approve-all) or run without
a TTY; istari handles non-interactive approval on its own.
Windows: istari uses a named pipe instead of a Unix socket. Set
istari.socketPath to a pipe path (e.g. \\.\pipe\istari-ai); the extension
exports it the same way.
Settings
| Setting |
Default |
Description |
istari.socketPath |
.istari/istari.sock |
Socket path istari binds. Relative paths resolve to the workspace folder. |
istari.autoConnect |
true |
Connect automatically whenever the socket appears. |
istari.binaryPath |
istari |
Executable for the guided and terminal commands. Bare command → PATH; relative path → first workspace folder. |
istari.defaultModel |
"" (empty) |
Comma-separated --model list for the review commands only. Empty omits the flag (CLI default list applies). |
Commands
- istari: Review Pull Request / Review Ticket / Check Environment / Initialize
Config - guided workflows (see Guided commands).
- istari: Review Local Changes - one-click local review from the Source
Control view.
- istari: Run istari in a terminal - power-user escape hatch: type raw istari
args (tokenized and launched as a task; no shell).
- istari: Connect to the istari socket - connect now.
- istari: Disconnect from the istari socket - drop the connection.
Development
npm install
npm run compile # or: npm run watch
npm test # unit tests (arg assembly, tokenizer, CLI-manifest drift)
Press F5 in VS Code to launch an Extension Development Host.
The guided commands assemble argv from a small typed table
(src/commands.ts), whose enum/provider values are
drift-guarded against the CLI: cli-manifest.json is a committed snapshot of
istari __cli-manifest, and both a Rust test and
src/test/manifest.test.ts fail if a flag, enum, or
provider changes without regenerating it
(UPDATE_MANIFEST=1 cargo test manifest_matches_fixture).
Wire protocol
Line-delimited JSON, one object per line:
// istari -> extension
{ "type": "permission_request", "id": 1, "action": "run a shell command",
"command": "rm -rf build", "intention": "clean the build dir", "risk": "destructive" }
// istari -> extension (live run stream, rendered by @istari chat)
{ "type": "run_start" }
{ "type": "reasoning", "text": "…thinking tokens…" }
{ "type": "report", "text": "…agent message tokens…" }
{ "type": "status", "text": "calling tool 'grep'" }
{ "type": "result", "text": "…final rendered deliverable…" }
{ "type": "run_end" }
// extension -> istari (approval verdict)
{ "id": 1, "decision": "approve" } // or "deny" | "always"
// extension -> istari (steering, from @istari chat)
{ "type": "steer", "text": "also cover the error-handling path" }