Pi Code Chat
A chat surface for the pi coding agent — shipped as a
VS Code extension, with a desktop app in development. Both surfaces run on one host-agnostic
core and one Vue renderer.

Desktop is in development. apps/desktop is an early Electron shell: the chat window, the
project rail and the settings page run, but there is no file viewer and no diff panel yet, among
other gaps. The VS Code extension is the supported surface today.
Features
Chat panel and sidebar — one session controller in two shapes: an editor-tab webview, or a
single activity-bar view. pi-code-chat.ui picks the default; both drive the same pi process.
Built in VS Code's own visual language — colours, radii and spacing are taken from the active
theme and from the host's own size tokens, not from a palette of our own: bubbles ride
chat.requestBackground, secondary text is the theme foreground at 70%, corners are the editor's
corners. Light, dark and high-contrast themes all follow.
Streaming transcript — thinking, tool calls and the answer are one turn: the work folds away,
the answer stays in the clear, each tool row carries its own duration, its diff or output, and a
failed run shows the provider's error in the panel's language. Mermaid diagrams and KaTeX math
render inline.
Live editor bridge — the agent calls the editor as tools: active editor and selection,
diagnostics, document and workspace symbols, definitions, references, hovers, code actions and
formatting. Results are truncated at 50 KB / 2000 lines so a query cannot flood the context.
Bundled pi extensions — loaded into every session with -e, nothing to install, by both apps:
the desktop shell loads the same set minus the editor bridge (it has no editor to talk to, so
loading it would only fail inside pi):
| extension |
what it adds |
pi-vscode-bridge.js |
the vscode_* tools above, plus the TUI status row |
questionnaire.ts |
interactive multi-question forms, rendered as a card |
rewind-code.ts |
per-message file snapshots and the rewind card |
todo.ts |
the task list the model keeps, shown as a 任务 N/M capsule |
Permissions stay yours — the panel ships no gate of its own: it detects the permission engine
you installed in pi (@gotgenes/pi-permission-system) and turns its asks into an approval card in
the chat, where pi-code-chat.permission.mode decides whether to ask or answer automatically
(a rule that denies refuses either way). The composer says so when no engine is installed, and
docs/examples/permission/ carries a ready-to-copy policy —
"block only what is dangerous" — with the reasoning behind every rule. It is a decision layer, not
isolation: pi ships no built-in sandbox, so for untrusted or unattended work run pi inside a
container or a VM (pi's own security docs cover the patterns).
Rewind — every edit/write is snapshotted (sha256, on disk, no git dependency). The panel
shows what has changed since the last accept; a file can be accepted, reverted, or opened as a
diff against its snapshot in the editor's own diff view.
Turn artefacts — the end of a turn carries what the turn did: its changed files (click a row
to open the file, expand it for that file's diff), the model's todo list, the rewind card, usage
and context counters, and a chime when a run finishes.
Sessions and queue — sessions are listed, switched, renamed, forked and deleted from the
panel. A message sent while a run is going either queues behind it or steers into it
(chatRunningSendBehavior), with an optimistic bubble that is reconciled when pi echoes it back.
Models — pick a model per session (remembered per workspace), set the thinking level, mark
favourites, and see what the run reported.
Optional pi ecosystem packages — two capabilities are delegated to the ecosystem, with
install-state banners in the settings panel: pi-subagents
for the subagent tool, and pi-mcp-adapter for
MCP servers.
AI commit messages — generated from the staged diff, from the SCM title bar, in 14 languages
(pi-code-chat.commitModel, .commitLanguage, .commitMessagePrompt).
Send code to the chat — Add Selection / Add File from the editor and explorer context menus;
the selection arrives as a fenced block with its path and line range.
Localized — en and zh-cn, following the VS Code display language by default.
Chat display — font size, background image with frosted glass, Mermaid theme, whether tool
calls and thinking start expanded, the send shortcut, and a reading anchor that holds your place.
Requirements
VS Code 1.100.0 or newer
the pi CLI, on your PATH or named by pi-code-chat.path:
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
at least one provider configured for pi (API key or OAuth — see pi's own documentation)
Install
code --install-extension j62268781-alt.pi-code-chat
From source instead: pnpm install && pnpm run package writes
apps/vscode/pi-code-chat-<version>.vsix.
Repository layout
apps/vscode/ the VS Code extension (published as j62268781-alt.pi-code-chat)
apps/desktop/ the desktop app (Electron, in development)
assets/ static assets both apps ship: the icons, the completion sound
packages/core/ host-agnostic: the pi RPC client, the chat session, settings/model/bridge
config, the postMessage protocol — imports no editor API
packages/pi-extensions/
the pi extensions both apps load, injected with `-e` into every session
packages/ui/ the Vue 3 renderer (one Vite project, three builds: chat, settings, workspace)
docs/ design references
The things both apps load live outside both of them: the pi extensions are a package
(packages/pi-extensions/), the static assets sit at the root
(assets/) — neither app owns them, and only the editor bridge is VS Code's own (a host
without an editor must not load it, which is why packages/core's spawn settings take the list from
the host). A .vsix can only carry files inside the packaged folder, so apps/vscode's build copies
both into itself (pnpm run sync-assets); the desktop app reads them where they are.
packages/core is what keeps the surfaces one product: the session, the protocol and the config
layer live there once, and each host answers a small HostServices interface (revealFile,
pickPaths, showRewindDiff, …) in its own terms — VS Code with editor APIs, Electron with IPC.
The boundary is enforced by a test — packages/core/test/host-boundary.test.ts fails on any runtime
editor import in the core.
The extension's internals — how the webviews are built and loaded, how the chat talks to pi, how to
run and test it — are documented in apps/vscode/README.md.
Development
Requires Node 20+ and pnpm 10.
pnpm install
pnpm run build # renderer, then the extension host
pnpm run dev # watch the extension host only
pnpm run dev:webview # Vite dev server for the chat renderer
pnpm run typecheck # every package
pnpm run lint # oxlint + oxfmt --check
pnpm run test:unit # vitest, every package
pnpm run test # lint + typecheck + unit tests
pnpm run package # produce the .vsix
Credits
Pi Code Chat started from pi-agent-studio by
Johnny Zhao — the extension host's early shape, the bundled pi extensions, the editor bridge and
the chat protocol originate there, and the snapshot this repository began from is that project's
v1.3.9. (The upstream line continues at
JohnnyZ93/pi-agent-studio, itself a fork of
pithings/pi-vscode.)
Since then the repository has been restructured into this monorepo — the renderer rewritten in Vue 3,
the core split out from the editor — and it uses no upstream code today. Thank you, Johnny Zhao;
and thanks to the upstream contributors whose work came along the way
(koalajoe23, bsedat).
License
MIT — the copyright lines name both the upstream project this one started from and this
one.
| |