pi-muselinn-harness
Kimi Code-style agent orchestration harness for Pi coding agent — Swarm (concurrent subagents + braille TUI), Goal (lifecycle + budget + queue), Plan (plan mode + tool restrictions), Permission (18-level policy chain: auto/yolo/manual), Task (background +
Package details
Install pi-muselinn-harness from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-muselinn-harness- Package
pi-muselinn-harness- Version
0.9.23- Published
- Nov 3, 2026
- Downloads
- 242/mo · 94/wk
- Author
- muselinn
- License
- MIT
- Types
- extension
- Size
- 767.8 KB
- Dependencies
- 0 dependencies · 4 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-muselinn-harness: parallel agents and execution controls for pi
Add concurrent subagents, goal budgets, plan review, and tool permissions to the Pi coding agent in one install.
Running a coding agent on a larger task means juggling parallel investigations, keeping their output from filling the main context, and checking tools before they change files. This harness dispatches work into separate subagent sessions and brings results back, tracks goals with budgets and a queue, and puts plan review and permission checks around execution.
What you can see in 30 seconds
(demo GIF pending) — planned file: docs/demo/swarm.gif; recording guide.
Demo caption: Two explore subagents inspect entry points and tests in parallel while the swarm panel tracks their progress, then return a combined summary.
Install into an existing pi setup:
pi install npm:pi-muselinn-harnessStart a fresh interactive session in a project directory (
pi). Enter these slash commands one at a time; the editor changes immediately, without a model call:/tui style compact /tui style boxed /swarm onTry parallel work. With a model configured in pi, send this as a normal prompt:
Use agent_swarm with two explore subagents and max_concurrency=2: one summarizes this project’s entry points, the other summarizes its tests. Do not edit files. Return a short combined summary.
You should see the editor switch styles and a swarm status label; when the model calls agent_swarm, the live panel shows two tasks progressing toward a combined summary. Model latency and approvals can take longer than 30 seconds; switching styles needs neither.
Capabilities at a glance
| Capability | What it does |
|---|---|
| Swarm | Runs isolated subagents concurrently with a concurrency cap and live progress. |
| Goals | Tracks an objective, budgets, completion criteria, and a priority queue. |
| Plan mode | Reviews a plan before execution; restricts write/edit to the plan file while bash follows permission rules. |
| Permissions | Checks tool calls through an 18-level policy chain, including destructive-command and sensitive-file guards. |
| Pause & steer | Pauses main/swarm agents at tool boundaries and sends instructions to running subagents. |
| Background & cron | Runs background agents and schedules prompts with persistent task records. |
| Ask & todo | Collects structured answers and displays phased task plans with reminders. |
| Hooks | Runs lifecycle commands on 16 events, with blocking at supported gates. |
| Skills & plugins | Discovers skills across project/user scopes and loads declarative resource bundles. |
| TUI | Adds a Kimi Code-style boxed editor, live task browser, and switchable styles. |
| Context & web | Spills oversized tool output to disk and fetches readable URL content. |
Installation details
Compatible with pi 0.81.x–0.83.x on macOS, Ubuntu, and Windows · Node 24/26 · CI matrix: macOS + Ubuntu + Windows.
Alternatively, install from Git:
pi install git:github.com/MuseLinn/pi-muselinn-harness
Everything works out of the box — no companion extensions required. Tools are model-callable; slash commands support Tab completion. See Commands for controls and Features for configuration details.

Upgrading from ≤ 0.7.4? Remove the old companion extensions — they conflict with the built-in tools (pi refuses to start on duplicate tool names):
pi remove npm:@juicesharp/rpiv-ask-user-question pi remove npm:rpiv-todo
Features
Swarm
- In-process subagents —
createAgentSession()execution,coder/explore/plantypes - Real concurrency control —
runProgressive()worker pool with truemax_concurrencycap + exponential backoff retries - 30-minute timeout — per-subagent
AbortSignal.timeout(aligned with Kimi Code) - run_in_background — whole swarm goes to a background task, early task-ID return, report written to
output_path - Smart model routing — task-aware selection from
ctx.modelRegistry - Braille progress bars — driven by real tool-call progress, 250 ms frames with a state-fingerprint gate (unchanged frames cost nothing)
- Harness-branded spinner — single-width braille rotation by default (
PI_MUSELINN_SPINNER=braille|pulse|bounce|moon, incl. Kimi moon-phase compat) - Adaptive layout — pi-tui Component protocol, status bar width adapts to the terminal (10–60)
- Three-pane task browser — status glyphs (○ pending / ◐ running / ✓ done / ✗ failed / ▲ aborted), strikethrough on done rows, overflow collapse (
+N more, running kept first), named keybindings,ctrl+shift+t - Cancel / resume — UserCancellationError + AbortSignal chain, two-step
/cancel
Pause & steer (freeze, inspect, redirect)
/pausefull-screen freeze — the main agent and every swarm subagent park at their next safe boundary (tool-call gate): in-flight calls run to completion, nothing is aborted, and a later release continues exactly where each loop parked. A full-screen overlay — theme-colored pause glyph, live hold timer — covers the terminal; esc/enter/space/ctrl+c releases, leaving a status line in the session transcript (已恢复(暂停 13s)— 代理继续运行). When the pause lands mid-tool, the overlay tags it<tool_call>.- Transcript recording — every subagent's conversation is written to
<sessionDir>/agents/<taskId>/wire.jsonl(user / assistant → tool-call lines, timestamps, stop reasons, usage; tool arguments deliberately omitted). Presscin the task browser (/tasks/ctrl+shift+t) for a conversation view, or Read the file directly. /steer <taskId> <message>— injects a message into a running subagent (swarm session or background task; Tab-completed task ids). The agent loop delivers it once the current tool call completes — no cancel/restart needed.- Safe boundaries — cancelling a single parked run (AbortSignal) unwinds
only that wait, never the gate; background tasks (
run_background) are not frozen (their tool calls bypass the harness gate) but do get transcripts and steering. - Theme-colored overlay — icon/headline/body/hints render with the active
theme's
accent/text/muted/dim; the terminal background is the backdrop. Block glyphs (█ / ⏸) are measured single-width, so the pause symbol centers exactly with the text below.
Goal
- Lifecycle — active / paused / blocked / complete / usage_limited / budget_limited
- Active Guard —
create_goalrefuses to silently overwrite an active goal (replace=trueor/goal replace) - Blocked 3-turn threshold — three consecutive blocks for the same reason before really blocking
- Completion-criterion gate — a declared criterion must be verified before completing (
verified=truein the sameupdate_goalcall; documented in the tool description) - Triple budget checks — tokenBudget + turnBudget + wallClockBudgetMs (
turns/tokens/ms/s/minutes/hours) - Goal Queue — FIFO + high/normal priority + auto-switch + prioritize/drop/skip
- Persistence — appendEntry + session_start restore; counters merge monotonically (max per goalId), so a stale entry can never pull turns/tokens backwards;
clear()writes a tombstone entry so completed goals stay completed - Context injection —
<untrusted_objective>tag into the system prompt - Recovery — compaction preservation + context-overflow detection + 429 detection
Plan
- Plan mode — the LLM explores, writes a plan, and only executes after approval
- Kimi Code permission model — bash is NOT blocked in plan mode; it follows the normal permission mode (auto/yolo/manual). Only Write/Edit (outside plan file), TaskStop, CronCreate, CronDelete are blocked
- Plan file path matching — exact path,
local://scheme basename, and resolved absolute path undersessionDir/plans/— all three accepted - ExitPlanMode reads the plan file — presentation matches what was actually written to disk
- Revise keeps your plan — a revised or cancelled review re-enters plan mode with the same plan object (id/path/content), never a trap, never lost work; review timeout 600 s
- Restore validation — a stale persisted active-plan entry with no content and no file on disk deactivates plan mode instead of trapping the session
- Context injection — the plan is injected into the system prompt
Permission
- 18-level policy chain —
auto/yolo/manual; safety policies (destructive, sensitive files) short-circuit before modes - Destructive detection —
rm -rf/git push --force/drop table/git reset --hardregex recognition, always asks, never short-circuited by session approvals - Sensitive-file guard —
.env/id_rsa/*.keyread/write interception, even in auto mode - Session approval fingerprints — approvals remembered per sessionId + input fingerprint, never degrading into "permanent allow"
- Approval panel — numbered dialog with per-tool action titles ("Run this command?" / "Apply these edits?"), digit-key direct select, four outcomes: Allow once / Always allow (session) / Deny / Deny with reason (reason relayed to the model). In RPC hosts (obsidian-pi etc.) the same choices render over the extension UI protocol (
select/input/confirm) instead of the TUI dialog — no more silent denials - Subagent gating — swarm worker tool calls run through the same policy chain (shared in-process manager):
/modeswitches propagate to in-flight subagents by construction,askverdicts degrade to blocks (never silent approval) - AGENTS.md hierarchy — project (nearest
AGENTS.mdor.kimi-code/AGENTS.md) → global$KIMI_CODE_HOME/AGENTS.md→ cross-tool~/.agents/AGENTS.md, aggregated;destructive-ask-alwayscan upgrade ask to deny - Config cache — permission config cached by file mtime, edits take effect immediately
- Persistent startup mode — optional
"defaultMode": "auto" | "yolo" | "manual"in~/.pi/agent/permissions.json(global) or.pi/permissions.json(project; global wins on conflict) replaces the hardcodedmanualstartup mode, so new sessions start in your preferred mode without an interactive/modecall. A session with a recorded/modehistory still restores the last used mode;defaultModeis the starting point for fresh sessions.
Task (background + cron)
- run_background — subagent in the background, immediate task ID;
output_pathpages full output via Read - 30-minute timeout — background tasks auto-fail (
stopReason=timeout_30min) - task_list / task_output / task_stop —
active_onlyfilter,block+timeoutwaiting,offset/limitpaging - 50-task cap + 7-day stale cleanup + orphaned tasks degrade to
process_restarton restart - Incremental persistence — single-task changes append a single entry; restore stays compatible with old snapshots
- Cron — 5-field cron (local timezone) + deterministic jitter (10% of period, ≤15 min) + recurring/one-shot + 50 cap + 7-day stale auto-delete
Hooks
- Kimi Code-aligned
[[hooks]]engine — reads$KIMI_CODE_HOME/config.toml(default~/.kimi-code/config.toml) + project.kimi-code/config.toml; event/matcher/command/timeout fields - Full event coverage — UserPromptSubmit / PreToolUse / Stop (blockable) + PostToolUse / PostToolUseFailure / PermissionRequest / PermissionResult / SessionStart / SessionEnd / SubagentStart / SubagentStop / StopFailure / Interrupt / PreCompact / PostCompact / Notification
- Exit-code semantics —
0allow (stdout appended as context),2block (stderr as reason), anything else / timeout / crash fails open; stdout JSONpermissionDecision: denysupported - Built-in TOML mini-parser — zero dependencies; invalid rules warn and skip without breaking the extension; mtime-cached hot reload
- Safety net — Stop auto-disables after 3 consecutive blocks (anti-loop); every trigger mirrored to
pi.eventsfor other extensions
Skills
- Seven-scope pi-native scanning — project
.pi/skills,.kimi-code/skills(Kimi compat),.agents/skills→ user~/.pi/agent/skills,~/.pi/skills,$KIMI_CODE_HOME/skills,~/.agents/skills; pi-native dirs win, Kimi dirs as compat layer, dedupe by name - Directory + flat forms —
SKILL.mdsubdirs (with auxiliary files) and single.mdfiles; full frontmatter fields (name/description/type/whenToUse/disableModelInvocation/arguments, kebab/snake variants) - Available to subagents — swarm and background subagent sessions receive skills via resourceLoader; the main session is injected via
resources_discover(collision-free: only files from dirs pi does not scan natively, minus names pi already provides) - Zero-dependency frontmatter parser + mtime directory-tree cache
TUI
Closed-box editor — Kimi Code's
wrapWithSideBordersported: pi-tui's horizontal-only borders post-processed into a╭╮│╰╯closed box; spinner + working state (Thinking/Streaming/Running tools) embedded in the top border; three stylesplain | boxed | compact(pi-spark-style info border = compact), default boxed; model name opt-in via"modelInBorder": trueThe first content line carries a prompt chevron (
│❯ text │), padding is clamped to ≥2 so the bars never touch the text or cursor./tuicommand — hot-switch styles without restarting (pi preserves text/focus/keybindings when swapping editors);/tui timingshows render timing; config persisted to~/.pi/agent/muselinn-tui.json(project.pi/override)Plan badge —
plantext badge on the top border while plan mode is active (no border recoloring — zero conflict with pi's thinking-level colors)Timing probe —
PI_MUSELINN_HARNESS_TUI_TIMING=1records editorrender()P50/P99; spinner only ticks at 250 ms while the agent worksShimmer working message (OMP-style) — the working label in the editor border gets a wall-clock driven light-band sweep (
classiccosine band orkittK.I.T.T. scanner); the crest paints accent+bold so dim text stays legible mid-animation.low: dim / mid: muted / high: accentby default;/tui shimmer <classic|kitt|disabled>switches live, config persistedStable animation frame-rate — the keep-alive timer uses a fixed 200ms quiet gate (≈10fps ceiling) so the animation cadence never changes; natural streaming renders ride pi's own frames at zero extra cost, and a stalled agent loop costs at most ~10 full-tree renders per second even on very large sessions. (Adaptive thresholds based on measured render latency were tried and rejected: latency noise made the frame rate stutter.)
Ask (interactive questions)
ask_user_questiontool — the agent asks 1-4 structured questions in one tabbed dialog: per-question header tabs (1/3 · header, ←/→/Tab to switch), numbered options with description sub-lines,multi_selectcheckboxes (Space toggles, Enter confirms), and an automatic free-text Other option on every question; digit keys 1-9 jump straight to an option, arrows/jk navigate, Esc cancels- Robust by default — long option lists scroll inside a bounded window, duplicate answers are deduplicated, and questions can be posed from background tasks without wedging the UI
- Previews, notes, chat row — options can carry Markdown previews (side-by-side pane on wide terminals, stacked below on narrow ones); attach a per-option note with
n; a Chat about this row ends the dialog with achatresult so the user can discuss the question instead of answering it - Shared dialog component — the same component backs permission approval (single-select, no Other); in print mode the tool returns the questions as text instead of blocking, and in RPC mode permission approvals fall back to
select/confirm/input - Answer reporting — per-question answers (multi-select as an array); skipped questions and Esc-cancelled dialogs are reported distinctly
- Auto-mode safe — auto mode denies
ask_user_questionby policy (no unattended hangs)
Todo
- Inline panel — above-editor widget with roman-numeral phase tree (
Ⅰ. Scanner · 2/4),/todo toggleexpand/collapse; finished tasks auto-clear afterPI_MUSELINN_TODO_CLEAR_DELAYseconds (default 60,0= instant,-1= manual) so completed plans fade out of the HUD instead of lingering /todocommand — full oh-my-pi phase model:init,start,done,drop,rm,append,export,import,copy,edit,add_notes,update_details, bare/todoprints Markdowntodo_listtool — model-driven task management with same ops- Reminder system — incomplete todos injected as
<system-reminder>when agent stops (max 3 reminders, debounced) - Subagent matching — pending tasks matching swarm subagent descriptions get highlighted with
◔spinner - Markdown round-trip —
/todo export/importfor persistence and sharing between sessions - Notes — per-task notes via
add_notes/update_details - Phase counts — widget header shows
N active · M pending · K done - Session persistence — survives hot-reload and session restart
Web fetch
fetch_urltool — no-auth URL fetch (20s timeout, 5MB stream cap, redirect follow); HTML → readable text (dependency-free extractor), JSON → pretty-print, everything else raw; 20k char cap withmax_charstuning- Full web access via pi-web-access — recommended companion for
web_search/fetch_content(multi-provider search, GitHub repo cloning, PDF / YouTube / local-video understanding). Itsweb_searchandfetch_contenttools sit in the permission system's read-only allowlist — auto-approved in every mode, including plan mode, so no approval prompts interrupt the flow. Install:pi install npm:pi-web-access
Plugins (declarative bundles)
muselinn.plugin.json— six declarative capabilities:skills(skill dirs merged into discovery),sessionStart(context injected on the session's first turn),hooks(merged into the[[hooks]]engine),commands(.md files become slash commands), plusmcpServers/interfacerecorded with skipped-diagnostics- Discovery — project
.pi/plugins/*/then user~/.pi/agent/plugins/*/, first-wins name dedupe;/pluginslists capabilities and diagnostics
Output truncation
- Oversized tool results spill to disk — results over the spill threshold are written to
<sessionDir>/tool-results/and replaced in context with a sanitized head+tail preview carrying theoutput_pathand read-paging instructions (KimitoolResultTruncationpattern) - Window-aware threshold — the threshold scales with the active model's context window (
max(40k, window × 4 chars/token), capped at 800k chars ≈ 200k tokens), so 1M-context models keep far more output in-context;PI_TRUNCATION_THRESHOLDoverrides it explicitly
Commands
| Command | Description |
|---|---|
/swarm on|off |
Toggle swarm mode |
/pause |
Freeze all agents at the next safe boundary (esc/enter/space/ctrl+c resumes) |
/steer <taskId> <message> |
Send a message to a running subagent |
/cancel |
Cancel current work (two-step confirm) |
/swarm-resume |
Resume an interrupted swarm |
/tasks |
Task browser (ctrl+shift+t) |
/goal <objective> |
Set a goal |
/todo |
Task plan with phase model; shortcuts: start done drop export import copy edit toggle |
/todo toggle |
Expand/collapse the todo panel (replaces former alt+t) |
/plugins |
List loaded plugins and their capabilities |
/swarm-status |
Show goal status and budget guidance; use /swarm status for the swarm toggle/recovery status |
/plan |
Toggle plan mode (on, off, clear also supported) |
/mode auto|yolo|manual |
Switch permission mode |
/tui style plain|boxed|compact |
Switch editor style |
/goal/swarm/plan/mode/tuiall support Tab completion.
Tools
| Tool | Description |
|---|---|
agent_swarm |
Batch parallel subagents (max_concurrency / run_in_background / output_path / model_map) |
agent |
Single subagent |
create_goal / get_goal / update_goal / set_goal_budget |
Goal management |
enter_plan_mode / exit_plan_mode |
Plan mode |
ask_user_question |
Tabbed structured questions (multi-select, Other free text) |
todo_list |
Model-driven task plan with inline panel |
fetch_url |
No-auth URL fetch with content-aware extraction |
run_background / task_list / task_output / task_stop |
Background tasks |
cron_create / cron_list / cron_delete |
Cron jobs |
Kimi Code alignment
Against the Kimi Code CLI docs — Agents & Subagents:
| Capability | Status | Notes |
|---|---|---|
| Three built-in subagent types (coder/explore/plan) | ✅ | coder=read/write+bash; explore=read-only; plan=read-only, no shell |
| Context isolation | ✅ | Independent sessions; only final results flow back |
| Parallel dispatch + max_concurrency | ✅ | Real worker-pool cap + progressive launch |
| 30-minute timeout | ✅ | Per-subagent AbortSignal.timeout |
| Background execution (run_in_background) | ✅ | Early task-ID return, blockable task_output, report to output_path |
| Resume an existing subagent | ⚠️ | Conservative semantics: same-id re-run; resume validated (saved state + nothing in flight + remaining items); true session resume pending pi-coding-agent API |
| Nested subagents (coder spawning more) | ❌ | Deliberately closed — no recursive dispatch; subagent toolset excludes agent/agent_swarm |
| Permission inheritance | ✅ | Worker tool calls pass through the shared policy chain; /mode propagates by construction; asks degrade to blocks |
| Instruction-file hierarchy | ✅ | Project AGENTS.md / .kimi-code/AGENTS.md → $KIMI_CODE_HOME/AGENTS.md → ~/.agents/AGENTS.md |
| wire.jsonl session persistence | ⚠️ | Per-subagent transcripts (agents/<id>/wire.jsonl, user/assistant/tool-call, no tool args) + conversation viewer; full session resume pending pi-coding-agent API |
Hooks ([[hooks]] lifecycle) |
✅ | All 16 events, exit-code/stdout-JSON block semantics, fail-open |
| Agent Skills (four scopes) | ✅+ | Kimi's four covered and extended to seven pi-native scopes; directory + flat forms; subagent + main-session channels |
Architecture
Core/adapter split: packages/core/ is pure logic with zero pi imports;
the repo root holds the pi adapter (entry, pi-tui components, tool registration).
pi-muselinn-harness/
├── index.ts entry (agent_swarm/agent tools, background runner, module wiring)
├── state.ts shared state
├── packages/core/ @muselinn/core — pure logic, no host imports
│ ├── ports.ts host contracts (PersistencePort, ScopeDirs)
│ ├── text-utils.ts visibleWidth & friends
│ ├── shell-output.ts control-sequence sanitizer
│ ├── truncation/ oversized tool-result spill (pure)
│ ├── webfetch/ HTML→text / JSON extraction (pure)
│ ├── completions.ts slash-command argument completions
│ ├── ask/ question spec + formatting (pure)
│ ├── todo/ todo model + Kimi folding strategy (pure)
│ ├── plugin/ muselinn.plugin.json manifest parse/discovery
│ ├── goal/ Goal module (state machine, budgets, queue, persistence)
│ ├── plan/ Plan module (tool whitelist, path guard, injection)
│ ├── permission/ Permission module (18-level chain, approval contract)
│ ├── pause/ pause gate + full-screen overlay layout (pure, theme-injectable)
│ ├── hooks/ Hooks module (TOML mini-parser, executor, 16 events)
│ ├── skills/ Skills module (frontmatter, seven-scope scanner)
│ ├── swarm/ pure swarm half
│ │ ├── types.ts state/constants (+ goal re-export)
│ │ ├── helpers.ts braille bars / layout / spinner (memoized)
│ │ ├── estimator.ts progress estimation (geometric mean)
│ │ ├── widget-lines.ts braille grid line builders (pure)
│ │ ├── wrap-tools.ts permission gate wrapper (pure)
│ │ ├── resume-guard.ts resume ownership/idle validation (pure)
│ │ ├── report.ts swarm report formatting
│ │ └── task-list-utils.ts collapse + key routing
│ ├── task/ cron + task persistence state (pure)
│ └── tui/ box/config/parse/switch/timing (pure chrome parts)
├── swarm/ adapter: subagent execution, /swarm commands,
│ SwarmWidgetComponent, three-pane task browser
├── pause/ adapter: /pause overlay component, /steer command
├── task/ adapter: background task manager (session spawn)
├── tui/ adapter: MuselinnEditor + event wiring
├── ask/ adapter: question dialog + ask_user_question tool
├── todo/ adapter: todo_list tool + inline panel widget
├── webfetch/ adapter: fetch_url tool
├── plugin/ adapter: plugin loader + /plugins command
└── tests/ node-level unit tests (below)
Tests
Pure node-level unit tests, no model quota needed (29 suites, 830+ assertions):
npm test # all suites (node tests/run-all.mjs)
npm run typecheck # full-package tsc (strict, es2024)
or individually:
node tests/musepi-config.test.mjs # MusePi config compat — 9
node tests/permission.test.mjs # Permission policy chain + subagent gate — 26
node tests/goal.test.mjs # Goal state machine + monotonic restore — 32
node tests/plan.test.mjs # Plan mode round-trip + restore validation — 42
node tests/task.test.mjs # Task restore/list/output/block + loader runtime — 16
node tests/cron.test.mjs # Cron subsystem — 16
node tests/hooks.test.mjs # Hooks engine — 43
node tests/skills.test.mjs # Skills scan/parse/scopes/discover — 38
node tests/tui.test.mjs # TUI collapse/keys/completions/spinner — 63
node tests/tui-box.test.mjs # TUI box/config/probe/switch — 63
node tests/tui-adapter.test.mjs # TUI adapter working-state render path — 4
node tests/agent-file.test.mjs # agent file discovery/parse — 11
node tests/agent-lifecycle.test.mjs # agent lifecycle events — 6
node tests/ask.test.mjs # ask spec/dialog/answers/approval titles — 123
node tests/ask-concurrency.test.mjs # Concurrent question-dialog handling
node tests/tool-policy.test.mjs # tool policy gate — 13
node tests/pause-gate.test.mjs # pause gate + full-screen render — 55
node tests/transcript.test.mjs # transcript wire.jsonl recording — 26
node tests/steering.test.mjs # steering queue drain — 8
node tests/todo.test.mjs # todo model + folding strategy — 99
node tests/shell-output.test.mjs # output sanitizer — 21
node tests/shimmer.test.mjs # shimmer sweep engine — 10
node tests/truncation.test.mjs # tool-result spill + window-aware threshold — 21
node tests/approval-rpc.test.mjs # RPC approval fallback (select/confirm) — 21
node tests/resume-guard.test.mjs # swarm resume validation — 6
node tests/webfetch.test.mjs # web extraction — 12
node tests/plugin.test.mjs # plugin manifest/discovery — 17
node tests/renderer.test.mjs # incremental renderer buffer/tree — 16
node tests/stream-rules.test.mjs # stream entry rules — 14
The suites run on Node 22/24/26 (22.6–22.17 via
--experimental-strip-types, older legs via tests/ts-esm-loader.mjs; 22.18+
strips types natively). CI runs the full matrix — macOS + ubuntu + windows ×
node 24/26 — on every push and PR.
Roadmap
- i18n — bilingual harness UI text and notifications (docs are already split en/zh-CN; the project page has an EN/中 toggle)
- Math renderer graduation — merge
feature/math-rendereronce compaction-path context safety is confirmed - Clustered diff preview — kimi-style ±3-line clustered diffs in edit/write approval messages (deferred from the P1 batch)
- True fullscreen — the pause overlay already covers the whole terminal (shipped in 0.9.19); container-swap fullscreen for the task browser (kimi tasks-browser pattern) is still open — no alt-screen, preserving terminal scrollback
Dependencies
- Pi >= 0.80.0
@earendil-works/pi-coding-agent,@earendil-works/pi-ai,@earendil-works/pi-tui(peers)typebox
For full protection against overlapping background and foreground question
dialogs, this extension requires pi >= 1.4.0. On pi versions below 1.4.0,
ask_user_question declares executionMode: "sequential" to prevent foreground
calls in the same tool batch from overwriting each other's dialogs. This
scheduling guarantee does not cover background: true: those calls return
before their dialogs settle, so background dialogs can still overlap other
questions on older pi versions.
Experimental branches
feature/math-renderer— renders$$...$$display math in assistant messages via txm (cell-based 2D typesetting, works in Windows Terminal; no image protocol). Context-safe: the original Markdown is restored before every LLM call. Enable with/tui math onaftercargo install txm.
Acknowledgments
Design and implementation inspired by these open-source projects:
Kimi Code (Moonshot AI)
- Agent Swarm concurrency architecture (max_concurrency worker pool, 30-min timeout, run_in_background)
- Goal system design (GoalActor tracking, Budget Report, blocked 3-turn threshold, context injection)
- Plan-mode lifecycle (enter/exit/approve/reject, ExitPlanMode disk read)
- Permission policy chain (auto/yolo/manual, destructive-always-ask, AGENTS.md priority)
- Cron scheduling (5-field + jitter + 7-day stale + 50 cap)
- TUI component design (braille progress bars, three-pane task browser,
wrapWithSideBordersclosed-box editor) - Cancel/resume mechanism (AbortSignal chain, UserCancellationError)
pi-spark (zlliang)
- Editor top-border info slots (spinner + working state + model embedded in the border)
- Component-replacement TUI customization path (
setEditorComponent/setFooter/setWidget)
@narumitw/pi-goal (narumitw)
- Goal Queue FIFO + auto-switch mechanism
- usage_limited / budget_limited state design
- Wrap-up instruction injection (post-budget behavior)
- Stale Tool Blocking design
- Compaction retention policy
pi-codex-goal (fitchmultz)
- Goal persistence (appendEntry + session_start restore)
- Goal state transitions
- Budget checking
- Recovery Machine concept (simplified)
Note: this extension is mostly an independent implementation. Exception: packages/core/tui/box.ts's wrapWithSideBorders is ported from Kimi Code (MIT), with attribution kept in comments and used under the MIT license.
Changelog
See CHANGELOG.md for the full version history.