@vitos-pizza/vitos-pizza 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +29 -0
  3. package/README.md +34 -5
  4. package/assets/architecture.png +0 -0
  5. package/assets/architecture.svg +97 -0
  6. package/package.json +22 -12
  7. package/packages/agent-mode/package.json +3 -3
  8. package/packages/agent-mode/src/plan-instructions.ts +24 -59
  9. package/packages/hypa/extensions/index.ts +16 -0
  10. package/packages/hypa/package.json +23 -0
  11. package/packages/hypa/scripts/smoke.mjs +50 -0
  12. package/packages/hypa/src/config.ts +37 -0
  13. package/packages/hypa/src/seed.ts +22 -0
  14. package/packages/hypa/tsconfig.json +13 -0
  15. package/packages/keybindings/package.json +1 -1
  16. package/packages/permission-system/package.json +2 -2
  17. package/packages/permission-system/presets/default.json +8 -0
  18. package/packages/permission-system/presets/plan.json +6 -0
  19. package/packages/permission-system/presets/yolo.json +1 -0
  20. package/packages/question/package.json +1 -1
  21. package/packages/session-title/package.json +3 -3
  22. package/packages/settings-preset/package.json +1 -1
  23. package/packages/subagents/agents/planner.md +12 -15
  24. package/packages/subagents/agents/scout.md +11 -19
  25. package/packages/subagents/agents/title.md +1 -0
  26. package/packages/subagents/agents/worker.md +10 -21
  27. package/packages/subagents/package.json +1 -1
  28. package/packages/subagents/skills/subagents/SKILL.md +27 -28
  29. package/packages/subagents/src/agents.ts +17 -0
  30. package/packages/subagents/src/execute-subagent.ts +3 -6
  31. package/packages/subagents/src/run-agent.ts +2 -1
  32. package/packages/todoist/package.json +1 -1
  33. package/packages/ui-enhancements/package.json +1 -1
  34. package/packages/websearch/extensions/index.ts +4 -2
  35. package/packages/websearch/package.json +1 -1
  36. package/scripts/sync-pi-manifest.mjs +18 -12
package/AGENTS.md CHANGED
@@ -7,7 +7,7 @@ Inspired by Vito's Pizzeria from Garfield — one brand, one install.
7
7
  ## Structure
8
8
 
9
9
  - **Repo root** — The distribution. `package.json` is the pi-package manifest.
10
- - **`packages/<module>/`** — Built-in modules (e.g. `@vitos-pizza/agent-mode`, `@vitos-pizza/question`, `@vitos-pizza/session-title`, `@vitos-pizza/permission-system`, `@vitos-pizza/subagents`, `@vitos-pizza/keybindings`). Not installed separately by users.
10
+ - **`packages/<module>/`** — Built-in modules (e.g. `@vitos-pizza/agent-mode`, `@vitos-pizza/hypa`, `@vitos-pizza/question`, `@vitos-pizza/session-title`, `@vitos-pizza/permission-system`, `@vitos-pizza/subagents`, `@vitos-pizza/keybindings`). Not installed separately by users.
11
11
  - **`scripts/sync-pi-manifest.mjs`** — Scans `packages/*`, merges `piBundled` npm packages, and updates root `dependencies` + `pi` manifest. Honors `pi.requires` for extension load order.
12
12
 
13
13
  ## Bundled third-party Pi packages
@@ -18,7 +18,7 @@ Declare npm pi packages in root `package.json`:
18
18
  - `bundledDependencies` — include in the distribution tarball
19
19
  - `piBundled` — list read by `sync-pi-manifest.mjs` to merge `node_modules/<pkg>/` paths into the root `pi` manifest
20
20
 
21
- Extension load order: topological sort of `pi.requires`, with `LOCAL_ORDER` tie-break. Default: `permission-system` → `settings-preset` → `question` → `ui-enhancements` → `subagents` → `websearch` → `session-title` → `keybindings` → `agent-mode` → `todoist`. (`agent-mode` requires `keybindings` so shortcut actions register after the keybindings listener is ready.)
21
+ Extension load order: topological sort of `pi.requires`, with `LOCAL_ORDER` tie-break. Default: `permission-system` → `settings-preset` → `hypa` → `question` → `ui-enhancements` → `subagents` → `websearch` → `session-title` → `keybindings` → `agent-mode` → `todoist`. (`agent-mode` requires `keybindings` so shortcut actions register after the keybindings listener is ready.) `piBundled` packages (e.g. `@hypabolic/pi-hypa`) load before local modules.
22
22
 
23
23
  ## Agent mode
24
24
 
package/CHANGELOG.md CHANGED
@@ -2,6 +2,35 @@
2
2
 
3
3
  All notable changes to vitos-pizza are documented here.
4
4
 
5
+ ## [Unreleased]
6
+
7
+ ## [0.4.0] - 2026-07-11
8
+
9
+ ### Added
10
+
11
+ - **Hypa context compression** — bundles `@hypabolic/pi-hypa` (additive mode; MCP proxy off); `@vitos-pizza/hypa` seeds `~/.hypa-pi/config.json`
12
+ - Plan mode / scout / planner / worker: `hypa_read` / `hypa_grep` / `hypa_find` / `hypa_ls` allowlisted alongside builtins
13
+ - `scripts/sync-pi-manifest.mjs` reads root `piBundled` and merges third-party Pi package extensions
14
+ - README **Architecture** capability map (`assets/architecture.svg` / `.png`)
15
+
16
+ ### Acknowledgments
17
+
18
+ - [Hypa](https://github.com/Hypabolic/Hypa) / `@hypabolic/pi-hypa` (FSL-1.1-ALv2) — shell output compression and `hypa_*` tools
19
+
20
+ ## [0.3.1] - 2026-07-11
21
+
22
+ ### Changed
23
+
24
+ - **Prompt optimization** — plan mode: authoritative short system instructions + supersede; sticky reminder without JSON dumps
25
+ - Subagents skill: mode constraints one-liners; plan vs execute/agent examples split (no worker chain in plan)
26
+ - Scout / planner / worker / title prompts tightened; planner output adds `## 功能验收`
27
+ - Hide internal `title` agent from public subagent listings
28
+ - `web_search` guidelines: prefer local tools; use web only for current external facts
29
+
30
+ ### Acknowledgments
31
+
32
+ - Claude Code plan-mode reminder pattern and OpenAI Codex base-instruction style (prompt craft reference)
33
+
5
34
  ## [0.3.0] - 2026-07-11
6
35
 
7
36
  ### Added
package/README.md CHANGED
@@ -12,6 +12,26 @@
12
12
 
13
13
  Inspired by [Vito's Pizzeria](https://garfield.fandom.com/wiki/Vito_Cappelletti) from Garfield — Garfield's favorite pizza place.
14
14
 
15
+ ## Architecture
16
+
17
+ ![vitos-pizza architecture](./assets/architecture.png)
18
+
19
+ Typical flow: **plan** → optional **scout** → **planner** → confirm → **execute** / **worker**. Shell output is compressed via Hypa bash rewrite; prefer `hypa_*` read tools when exploring.
20
+
21
+ | Capability | Module | What you get |
22
+ |------------|--------|--------------|
23
+ | Modes | `@vitos-pizza/agent-mode` | `agent` / `plan` / `execute` — `/mode`, Ctrl+. / Alt+M |
24
+ | Permissions | `@vitos-pizza/permission-system` | allow / ask / deny presets per mode |
25
+ | Context compression | `@hypabolic/pi-hypa` + `@vitos-pizza/hypa` | bash rewrite, `hypa_*` tools, `/hypa` (MCP proxy off) |
26
+ | Subagents | `@vitos-pizza/subagents` | scout · planner · worker (+ title internally) |
27
+ | Structured questions | `@vitos-pizza/question` | `question` tool |
28
+ | Web | `@vitos-pizza/websearch` | `web_search` / `web_read` |
29
+ | Tasks | `@vitos-pizza/todoist` | `/todo` + LLM tools |
30
+ | Session titles | `@vitos-pizza/session-title` | auto-name after first turn |
31
+ | TUI | `@vitos-pizza/ui-enhancements` | border status, execute prompt chrome |
32
+ | Shortcuts | `@vitos-pizza/keybindings` | centralized `vitos-shortcuts.json` |
33
+ | Defaults | `@vitos-pizza/settings-preset` | seed Pi settings on first session |
34
+
15
35
  ## Prerequisites
16
36
 
17
37
  - Node.js >= 22.19.0
@@ -21,14 +41,16 @@ Inspired by [Vito's Pizzeria](https://garfield.fandom.com/wiki/Vito_Cappelletti)
21
41
  npm install -g --ignore-scripts @earendil-works/pi-coding-agent
22
42
  ```
23
43
 
44
+ Context compression uses bundled [Hypa](https://github.com/Hypabolic/Hypa) (`@hypabolic/pi-hypa`). The matching platform binary comes from npm optionalDependencies (Linux / macOS / Windows, x64 / arm64). Use `/hypa` in a session for diagnostics. MCP proxy stays **off** (this distribution does not use MCP).
45
+
24
46
  ## Install
25
47
 
26
48
  ```bash
27
49
  # npm (recommended)
28
- pi install npm:@vitos-pizza/vitos-pizza@0.3.0
50
+ pi install npm:@vitos-pizza/vitos-pizza@0.4.0
29
51
 
30
52
  # git (pinned tag)
31
- pi install git:github.com/xin2017338/vitos-pizza@v0.3.0
53
+ pi install git:github.com/xin2017338/vitos-pizza@v0.4.0
32
54
  ```
33
55
 
34
56
  From source:
@@ -58,12 +80,16 @@ After install, start `pi`. Sessions are auto-titled from the first meaningful us
58
80
  ```
59
81
  vitos-pizza/ # Pi distribution (install this)
60
82
  ├── assets/logo.svg
83
+ ├── assets/architecture.svg # editable capability map source
84
+ ├── assets/architecture.png # README preview (rendered from SVG)
61
85
  ├── package.json # distro manifest + pi-package entry
62
86
  ├── AGENTS.md
63
87
  └── packages/ # built-in modules (not installed separately)
64
- ├── ui-enhancements/ # @vitos-pizza/ui-enhancements — TUI display optimizations
88
+ ├── ui-enhancements/ # @vitos-pizza/ui-enhancements — TUI display optimizations
65
89
  ├── agent-mode/ # @vitos-pizza/agent-mode — agent / plan / execute mode switching
66
90
  ├── permission-system/ # @vitos-pizza/permission-system — allow/ask/deny gates
91
+ ├── settings-preset/ # @vitos-pizza/settings-preset — seed default Pi settings
92
+ ├── hypa/ # @vitos-pizza/hypa — Hypa defaults (additive, no MCP proxy)
67
93
  ├── question/ # @vitos-pizza/question — structured ask-user question tool
68
94
  ├── session-title/ # @vitos-pizza/session-title — auto session naming
69
95
  ├── subagents/ # @vitos-pizza/subagents — scout/planner/worker delegation
@@ -72,7 +98,7 @@ vitos-pizza/ # Pi distribution (install this)
72
98
  └── keybindings/ # @vitos-pizza/keybindings — centralized shortcut bindings
73
99
  ```
74
100
 
75
- Built-in modules are wired via `scripts/sync-pi-manifest.mjs` (supports `pi.requires` load order).
101
+ Built-in modules are wired via `scripts/sync-pi-manifest.mjs` (supports `pi.requires` load order). Third-party Pi packages listed in root `piBundled` (currently `@hypabolic/pi-hypa`) are merged into the same manifest.
76
102
 
77
103
  | Path | Role |
78
104
  |------|------|
@@ -117,7 +143,7 @@ subagent({ tasks: [{ agent: "scout", task: "scan src" }, { agent: "scout", task:
117
143
  subagent({ agent: "worker", task: "...", async: true }) → wait({ id: "<runId>" })
118
144
  ```
119
145
 
120
- Built-in agents: **scout**, **planner**, **worker**, **title** (session auto-naming). Other modules request runs over `pi.events` RPC — import `requestSubagentRun` from `@vitos-pizza/subagents/rpc/client`.
146
+ Built-in agents: **scout**, **planner**, **worker**. Other modules request runs over `pi.events` RPC — import `requestSubagentRun` from `@vitos-pizza/subagents/rpc/client`.
121
147
 
122
148
  ## Web search
123
149
 
@@ -216,9 +242,12 @@ vitos-pizza builds on the Pi ecosystem and several open-source projects. We are
216
242
  | [Pi `border-status-editor` example](https://github.com/earendil-works/pi/tree/main/packages/coding-agent/examples/extensions/border-status-editor.ts) | `@vitos-pizza/ui-enhancements` | Editor-border status bar (model, thinking, context, cwd, git) |
217
243
  | [sf-welcome](https://github.com/salesforce/sf-pi/blob/main/extensions/sf-welcome/index.ts) | `@vitos-pizza/ui-enhancements` | Welcome header session lifecycle and tips layout |
218
244
  | **Claude Code** permission UX | Agent modes (`agent` / `plan` / `execute`) | Preset naming and mode-switching inspiration (not a code dependency) |
245
+ | [Claude Code system prompts](https://github.com/CANYOUFINDIT/claude-code-system-prompts) (plan-mode reminders) | `@vitos-pizza/agent-mode` plan instructions | Short sticky reminder + supersede pattern for plan mode (not a code dependency) |
246
+ | [OpenAI Codex base instructions](https://github.com/openai/codex/blob/main/codex-rs/protocol/src/prompts/base_instructions/default.md) | Plan / subagent prompt style | Concise hard rules and precedence over conflicting guidance (not a code dependency) |
219
247
  | [Claude Code TodoWrite / Task tools](https://code.claude.com/docs/en/agent-sdk/todo-tracking.md) | `@vitos-pizza/todoist` | Complete = status done; delete only when no longer relevant (cancelled / mistaken) |
220
248
  | [@capyup/pi-basic-tools todo](https://www.npmjs.com/package/@capyup/pi-basic-tools) | `@vitos-pizza/todoist` | completed vs deleted prompt boundary for task-list tools |
221
249
  | [pi-package-template](https://github.com/S1M0N38/pi-package-template) | Repo layout | Pi package monorepo conventions |
250
+ | [Hypa](https://github.com/Hypabolic/Hypa) (`@hypabolic/pi-hypa`) | `@vitos-pizza/hypa` + distro bundle | Additive bash rewrite / `hypa_*` tools; MCP proxy off (FSL-1.1-ALv2) |
222
251
 
223
252
  ### Runtime & tooling libraries
224
253
 
Binary file
@@ -0,0 +1,97 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 620" role="img" aria-labelledby="title desc">
2
+ <title id="title">vitos-pizza architecture</title>
3
+ <desc id="desc">Pi coding agent with Vito's Pizzeria capability modules and bundled Hypa</desc>
4
+
5
+ <defs>
6
+ <linearGradient id="piBar" x1="0" y1="0" x2="1" y2="0">
7
+ <stop offset="0%" stop-color="#1e293b"/>
8
+ <stop offset="100%" stop-color="#334155"/>
9
+ </linearGradient>
10
+ <linearGradient id="accent" x1="0" y1="0" x2="1" y2="1">
11
+ <stop offset="0%" stop-color="#f4a442"/>
12
+ <stop offset="100%" stop-color="#d97706"/>
13
+ </linearGradient>
14
+ <filter id="shadow" x="-2%" y="-2%" width="104%" height="108%">
15
+ <feDropShadow dx="0" dy="1" stdDeviation="1.5" flood-color="#0f172a" flood-opacity="0.12"/>
16
+ </filter>
17
+ </defs>
18
+
19
+ <rect width="960" height="620" fill="#f8fafc" rx="12"/>
20
+
21
+ <text x="32" y="36" font-family="ui-sans-serif, system-ui, sans-serif" font-size="18" font-weight="700" fill="#0f172a">vitos-pizza</text>
22
+ <text x="140" y="36" font-family="ui-sans-serif, system-ui, sans-serif" font-size="13" fill="#64748b">Pi distribution / capability map</text>
23
+
24
+ <rect x="32" y="56" width="896" height="56" rx="10" fill="url(#piBar)" filter="url(#shadow)"/>
25
+ <text x="480" y="82" text-anchor="middle" font-family="ui-sans-serif, system-ui, sans-serif" font-size="15" font-weight="600" fill="#f8fafc">Pi coding agent</text>
26
+ <text x="480" y="100" text-anchor="middle" font-family="ui-sans-serif, system-ui, sans-serif" font-size="11" fill="#cbd5e1">runtime / tools / sessions / compaction</text>
27
+
28
+ <line x1="480" y1="112" x2="480" y2="136" stroke="#94a3b8" stroke-width="2"/>
29
+ <polygon points="480,142 474,132 486,132" fill="#94a3b8"/>
30
+
31
+ <rect x="32" y="148" width="896" height="150" rx="10" fill="#fff7ed" stroke="#fed7aa" stroke-width="1.5"/>
32
+ <text x="48" y="172" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12" font-weight="700" fill="#c2410c">Workflow &amp; safety</text>
33
+
34
+ <g font-family="ui-sans-serif, system-ui, sans-serif">
35
+ <rect x="48" y="186" width="200" height="88" rx="8" fill="#ffffff" stroke="#e2e8f0" filter="url(#shadow)"/>
36
+ <text x="148" y="214" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">Modes</text>
37
+ <text x="148" y="234" text-anchor="middle" font-size="11" fill="#64748b">agent / plan / execute</text>
38
+ <text x="148" y="252" text-anchor="middle" font-size="10" fill="#94a3b8">agent-mode</text>
39
+
40
+ <rect x="268" y="186" width="200" height="88" rx="8" fill="#ffffff" stroke="#e2e8f0" filter="url(#shadow)"/>
41
+ <text x="368" y="214" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">Permissions</text>
42
+ <text x="368" y="234" text-anchor="middle" font-size="11" fill="#64748b">allow / ask / deny</text>
43
+ <text x="368" y="252" text-anchor="middle" font-size="10" fill="#94a3b8">permission-system</text>
44
+
45
+ <rect x="488" y="186" width="200" height="88" rx="8" fill="#ffffff" stroke="#e2e8f0" filter="url(#shadow)"/>
46
+ <text x="588" y="214" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">Subagents</text>
47
+ <text x="588" y="234" text-anchor="middle" font-size="11" fill="#64748b">scout / planner / worker</text>
48
+ <text x="588" y="252" text-anchor="middle" font-size="10" fill="#94a3b8">subagents</text>
49
+
50
+ <rect x="708" y="186" width="200" height="88" rx="8" fill="#ffffff" stroke="#e2e8f0" filter="url(#shadow)"/>
51
+ <text x="808" y="214" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">Question</text>
52
+ <text x="808" y="234" text-anchor="middle" font-size="11" fill="#64748b">structured ask-user</text>
53
+ <text x="808" y="252" text-anchor="middle" font-size="10" fill="#94a3b8">question</text>
54
+ </g>
55
+
56
+ <rect x="32" y="314" width="896" height="150" rx="10" fill="#eff6ff" stroke="#bfdbfe" stroke-width="1.5"/>
57
+ <text x="48" y="338" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12" font-weight="700" fill="#1d4ed8">Context &amp; tools</text>
58
+
59
+ <g font-family="ui-sans-serif, system-ui, sans-serif">
60
+ <rect x="48" y="352" width="200" height="88" rx="8" fill="#ffffff" stroke="#fdba74" stroke-width="1.5" filter="url(#shadow)"/>
61
+ <rect x="48" y="352" width="6" height="88" rx="3" fill="url(#accent)"/>
62
+ <text x="148" y="380" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">Hypa compress</text>
63
+ <text x="148" y="400" text-anchor="middle" font-size="11" fill="#64748b">bash rewrite / hypa_*</text>
64
+ <text x="148" y="418" text-anchor="middle" font-size="10" fill="#94a3b8">pi-hypa + hypa glue</text>
65
+
66
+ <rect x="268" y="352" width="200" height="88" rx="8" fill="#ffffff" stroke="#e2e8f0" filter="url(#shadow)"/>
67
+ <text x="368" y="380" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">Web search</text>
68
+ <text x="368" y="400" text-anchor="middle" font-size="11" fill="#64748b">web_search / web_read</text>
69
+ <text x="368" y="418" text-anchor="middle" font-size="10" fill="#94a3b8">websearch</text>
70
+
71
+ <rect x="488" y="352" width="200" height="88" rx="8" fill="#ffffff" stroke="#e2e8f0" filter="url(#shadow)"/>
72
+ <text x="588" y="380" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">Todo list</text>
73
+ <text x="588" y="400" text-anchor="middle" font-size="11" fill="#64748b">/todo + LLM tools</text>
74
+ <text x="588" y="418" text-anchor="middle" font-size="10" fill="#94a3b8">todoist</text>
75
+
76
+ <rect x="708" y="352" width="200" height="88" rx="8" fill="#ffffff" stroke="#e2e8f0" filter="url(#shadow)"/>
77
+ <text x="808" y="380" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">Session title</text>
78
+ <text x="808" y="400" text-anchor="middle" font-size="11" fill="#64748b">auto-name after turn 1</text>
79
+ <text x="808" y="418" text-anchor="middle" font-size="10" fill="#94a3b8">session-title</text>
80
+ </g>
81
+
82
+ <rect x="32" y="480" width="896" height="72" rx="10" fill="#f1f5f9" stroke="#e2e8f0" stroke-width="1.5"/>
83
+ <text x="48" y="504" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12" font-weight="700" fill="#475569">UX &amp; defaults</text>
84
+
85
+ <g font-family="ui-sans-serif, system-ui, sans-serif" font-size="12" fill="#0f172a">
86
+ <rect x="48" y="516" width="280" height="24" rx="6" fill="#ffffff" stroke="#e2e8f0"/>
87
+ <text x="188" y="532" text-anchor="middle">UI enhancements / TUI chrome</text>
88
+
89
+ <rect x="340" y="516" width="280" height="24" rx="6" fill="#ffffff" stroke="#e2e8f0"/>
90
+ <text x="480" y="532" text-anchor="middle">Keybindings / Ctrl+. / Alt+M</text>
91
+
92
+ <rect x="632" y="516" width="280" height="24" rx="6" fill="#ffffff" stroke="#e2e8f0"/>
93
+ <text x="772" y="532" text-anchor="middle">Settings preset / first-run seed</text>
94
+ </g>
95
+
96
+ <text x="480" y="590" text-anchor="middle" font-family="ui-sans-serif, system-ui, sans-serif" font-size="11" fill="#64748b">piBundled = @hypabolic/pi-hypa | local modules = @vitos-pizza/*</text>
97
+ </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/vitos-pizza",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Vito's Pizzeria — a Pi distribution (Garfield-approved)",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -37,33 +37,43 @@
37
37
  "typescript": "^5.8.0"
38
38
  },
39
39
  "dependencies": {
40
+ "@hypabolic/pi-hypa": "^0.1.10",
40
41
  "typebox": "^1.1.38",
41
- "@vitos-pizza/agent-mode": "0.3.0",
42
- "@vitos-pizza/keybindings": "0.3.0",
43
- "@vitos-pizza/permission-system": "0.3.0",
44
- "@vitos-pizza/question": "0.3.0",
45
- "@vitos-pizza/session-title": "0.3.0",
46
- "@vitos-pizza/settings-preset": "0.3.0",
47
- "@vitos-pizza/subagents": "0.3.0",
48
- "@vitos-pizza/todoist": "0.3.0",
49
- "@vitos-pizza/ui-enhancements": "0.3.0",
50
- "@vitos-pizza/websearch": "0.3.0"
42
+ "@vitos-pizza/agent-mode": "0.4.0",
43
+ "@vitos-pizza/hypa": "0.4.0",
44
+ "@vitos-pizza/keybindings": "0.4.0",
45
+ "@vitos-pizza/permission-system": "0.4.0",
46
+ "@vitos-pizza/question": "0.4.0",
47
+ "@vitos-pizza/session-title": "0.4.0",
48
+ "@vitos-pizza/settings-preset": "0.4.0",
49
+ "@vitos-pizza/subagents": "0.4.0",
50
+ "@vitos-pizza/todoist": "0.4.0",
51
+ "@vitos-pizza/ui-enhancements": "0.4.0",
52
+ "@vitos-pizza/websearch": "0.4.0"
51
53
  },
52
54
  "bundledDependencies": [
55
+ "@hypabolic/pi-hypa",
53
56
  "@vitos-pizza/agent-mode",
57
+ "@vitos-pizza/hypa",
54
58
  "@vitos-pizza/keybindings",
55
59
  "@vitos-pizza/permission-system",
56
60
  "@vitos-pizza/question",
57
61
  "@vitos-pizza/session-title",
62
+ "@vitos-pizza/settings-preset",
58
63
  "@vitos-pizza/subagents",
64
+ "@vitos-pizza/todoist",
59
65
  "@vitos-pizza/ui-enhancements",
60
66
  "@vitos-pizza/websearch"
61
67
  ],
62
- "piBundled": [],
68
+ "piBundled": [
69
+ "@hypabolic/pi-hypa"
70
+ ],
63
71
  "pi": {
64
72
  "extensions": [
73
+ "node_modules/@hypabolic/pi-hypa/extensions",
65
74
  "node_modules/@vitos-pizza/permission-system/extensions",
66
75
  "node_modules/@vitos-pizza/settings-preset/extensions",
76
+ "node_modules/@vitos-pizza/hypa/extensions",
67
77
  "node_modules/@vitos-pizza/question/extensions",
68
78
  "node_modules/@vitos-pizza/ui-enhancements/extensions",
69
79
  "node_modules/@vitos-pizza/subagents/extensions",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/agent-mode",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Centralized agent / plan / execute mode switching for Vito's Pizzeria",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -13,8 +13,8 @@
13
13
  "lint:fix": "biome check --write ."
14
14
  },
15
15
  "dependencies": {
16
- "@vitos-pizza/keybindings": "0.3.0",
17
- "@vitos-pizza/permission-system": "0.3.0"
16
+ "@vitos-pizza/keybindings": "0.4.0",
17
+ "@vitos-pizza/permission-system": "0.4.0"
18
18
  },
19
19
  "peerDependencies": {
20
20
  "@earendil-works/pi-coding-agent": "*"
@@ -3,6 +3,10 @@ export const PLAN_MODE_TOOLS = [
3
3
  "grep",
4
4
  "find",
5
5
  "ls",
6
+ "hypa_read",
7
+ "hypa_grep",
8
+ "hypa_find",
9
+ "hypa_ls",
6
10
  "question",
7
11
  "subagent",
8
12
  "wait",
@@ -12,77 +16,38 @@ export const PLAN_MODE_TOOLS = [
12
16
 
13
17
  export const PLAN_INSTRUCTIONS = `## PLAN MODE
14
18
 
15
- You are in **plan** mode. Do not call write, edit, or bash on the main agent.
19
+ This supersedes conflicting skill or prior guidance about implementing code or calling worker in this mode.
16
20
 
17
- **question tool (available anytime in plan)**
18
- - The main agent, scout, and planner can all use \`question\` during plan mode
19
- - Mutually exclusive design choices (2–5 options) prefer \`question\` over free-text "which do you prefer?"
20
- - Use \`question\` when clarification would help; skip it when context is already enough
21
+ **Hard rules**
22
+ - Main agent: no write, edit, or bash. Do not call worker.
23
+ - Produce an Implementation Plan and wait for confirmation.
24
+ - To implement, the user switches via \`/mode execute\` or \`/mode agent\`.
21
25
 
22
- **Planning workflow**
23
- - Produce an Implementation Plan and wait for user confirmation
24
- - Do **not** call worker or edit code directly in this mode
26
+ **Clarification**
27
+ - Prefer \`question\` for mutually exclusive choices (2–5 options); skip when context is enough. Available to main, scout, and planner.
25
28
 
26
- **When to explore**
27
- - Scout is **optional**. Skip it when the task is clear, scoped to known files, or the user already provided enough context
28
- - Call scout only when you need codebase recon (unfamiliar area, many files, unclear entry points)
29
- - Independent areas parallel scouts via \`subagent({ tasks: [...] })\` to finish recon faster; then planner
30
- - For light lookups, the main agent may use read/grep/find/ls directly — no scout required
29
+ **Exploration**
30
+ - Scout is optional only for unfamiliar or multi-file recon. Parallel scouts via \`subagent({ tasks: [...] })\` for independent areas, then planner.
31
+ - Prefer \`hypa_read\` / \`hypa_grep\` / \`hypa_find\` / \`hypa_ls\` when available; fall back to read/grep/find/ls.
32
+ - Web tools only for current external facts outside the repo.
31
33
 
32
34
  **Delegation**
33
- - Enough context already → \`subagent({ agent: "planner", task: "..." })\`
34
- - Need recon first → \`subagent({ chain: [{ agent: "scout", task: "..." }, { agent: "planner", task: "..." }] })\`
35
- - Multi-area recon → parallel scouts, then planner with the combined findings
35
+ - Enough context → \`subagent({ agent: "planner", task })\`
36
+ - Need recon → \`subagent({ chain: [scout, planner] })\`
36
37
 
37
- **After the plan (optional)**
38
- When helpful, add a short **Next** footer — Cursor-style suggested actions. Skip it if the next step is already obvious.
39
- - 2–3 bullets max; each one line
40
- - Concrete verbs the user can reply with (e.g. confirm → \`/mode execute\`, tweak scope)
41
- - No essays, no restating the whole plan
38
+ **Optional Next footer** (2–3 one-line reply verbs) when the next step is not obvious:
42
39
 
43
- Example:
44
40
  \`\`\`
45
41
  **Next**
46
- - Confirm → \`/mode execute\` (or Ctrl+. / Alt+M) to implement
47
- - Say what to change if the scope is off
48
- \`\`\`
49
-
50
- **To implement**, the user must switch to execute or agent mode (\`/mode execute\` or \`/mode agent\`).`;
42
+ - Confirm → \`/mode execute\` (or Ctrl+. / Alt+M)
43
+ - Say what to change if scope is off
44
+ \`\`\``;
51
45
 
52
46
  export const PLAN_MODE_MESSAGE = `[PLAN MODE ACTIVE]
53
47
 
54
- You are in plan mode. The main agent must NOT write, edit, or run bash.
55
-
56
- 1. \`question\` is available anytime in plan (main agent, scout, and planner) — use when helpful; prefer it over free-text choice questions
57
- 2. Scout only if needed; parallel scouts (\`tasks: [...]\`) when exploring independent areas; otherwise go straight to planner
58
- 3. Return the plan and wait; optionally a short **Next** footer (2–3 one-line actions) when helpful
59
- 4. Do NOT call worker or make code changes
60
-
61
- Planner only (no scout):
62
- \`\`\`json
63
- { "agent": "planner", "task": "Create an implementation plan for ..." }
64
- \`\`\`
65
-
66
- Scout → planner (when recon is needed):
67
- \`\`\`json
68
- {
69
- "chain": [
70
- { "agent": "scout", "task": "Map relevant code for this task" },
71
- { "agent": "planner", "task": "Create an implementation plan from {previous}" }
72
- ]
73
- }
74
- \`\`\`
75
-
76
- Parallel scouts (independent areas), then planner:
77
- \`\`\`json
78
- {
79
- "tasks": [
80
- { "agent": "scout", "task": "Map area A" },
81
- { "agent": "scout", "task": "Map area B" }
82
- ]
83
- }
84
- \`\`\`
85
- Then \`subagent({ agent: "planner", task: "Plan from the scout findings above" })\`.`;
48
+ Read-only planning. No write/edit/bash/worker.
49
+ Clarify with \`question\` when needed. Scout only if recon is required; otherwise planner.
50
+ Prefer hypa_* read tools when available. Return the plan and wait; optionally a short **Next** footer.`;
86
51
 
87
52
  export const PLAN_MODE_ENDED_MESSAGE = `[PLAN MODE ENDED]
88
53
 
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @vitos-pizza/hypa — seed Hypa Pi defaults (additive, MCP proxy off).
3
+ */
4
+
5
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
6
+ import { seedHypaPiConfigIfMissing } from "../src/seed.ts";
7
+
8
+ export default function (pi: ExtensionAPI) {
9
+ let seeded = false;
10
+
11
+ pi.on("session_start", async (_event, _ctx) => {
12
+ if (seeded) return;
13
+ seeded = true;
14
+ seedHypaPiConfigIfMissing();
15
+ });
16
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@vitos-pizza/hypa",
3
+ "version": "0.4.0",
4
+ "description": "Vito's Pizzeria Hypa defaults — additive mode, MCP proxy off, config seed",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "private": true,
8
+ "scripts": {
9
+ "test": "vitest run",
10
+ "test:watch": "vitest",
11
+ "smoke": "node scripts/smoke.mjs",
12
+ "typecheck": "tsc --noEmit",
13
+ "lint": "biome check .",
14
+ "lint:fix": "biome check --write ."
15
+ },
16
+ "peerDependencies": {
17
+ "@earendil-works/pi-coding-agent": "*"
18
+ },
19
+ "devDependencies": {
20
+ "@earendil-works/pi-coding-agent": "*",
21
+ "vitest": "^3.2.4"
22
+ }
23
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Smoke: resolve platform Hypa binary and run --version.
3
+ * Exit 0 = ok; 2 = binary missing (skip on unsupported install).
4
+ */
5
+ import { existsSync } from "node:fs";
6
+ import { createRequire } from "node:module";
7
+ import { dirname, join } from "node:path";
8
+ import { spawnSync } from "node:child_process";
9
+ import { fileURLToPath } from "node:url";
10
+
11
+ const root = join(dirname(fileURLToPath(import.meta.url)), "../../..");
12
+ const require = createRequire(join(root, "package.json"));
13
+
14
+ function resolveHypaBin() {
15
+ const platformKey = `${process.platform}-${process.arch}`;
16
+ const map = {
17
+ "win32-x64": "@hypabolic/hypa-win32-x64",
18
+ "win32-arm64": "@hypabolic/hypa-win32-arm64",
19
+ "linux-x64": "@hypabolic/hypa-linux-x64",
20
+ "linux-arm64": "@hypabolic/hypa-linux-arm64",
21
+ "darwin-x64": "@hypabolic/hypa-darwin-x64",
22
+ "darwin-arm64": "@hypabolic/hypa-darwin-arm64",
23
+ };
24
+ const pkgName = map[platformKey];
25
+ if (!pkgName) {
26
+ console.error(`Unsupported platform: ${platformKey}`);
27
+ process.exit(2);
28
+ }
29
+ try {
30
+ const pkgJson = require.resolve(`${pkgName}/package.json`);
31
+ const binName = process.platform === "win32" ? "hypa.exe" : "hypa";
32
+ const binPath = join(dirname(pkgJson), "bin", binName);
33
+ if (!existsSync(binPath)) {
34
+ console.error(`Binary missing: ${binPath}`);
35
+ process.exit(2);
36
+ }
37
+ return binPath;
38
+ } catch (err) {
39
+ console.error(`Could not resolve ${pkgName}:`, err);
40
+ process.exit(2);
41
+ }
42
+ }
43
+
44
+ const bin = resolveHypaBin();
45
+ const result = spawnSync(bin, ["--version"], { encoding: "utf8" });
46
+ if (result.status !== 0) {
47
+ console.error(result.stderr || result.stdout || "hypa --version failed");
48
+ process.exit(result.status ?? 1);
49
+ }
50
+ console.log(`hypa smoke ok: ${result.stdout.trim() || bin}`);
@@ -0,0 +1,37 @@
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+
4
+ /** Default Hypa Pi extension config for Vito's Pizzeria (additive, no MCP). */
5
+ export const DEFAULT_HYPA_PI_CONFIG = {
6
+ mode: "additive",
7
+ mcpProxyEnabled: false,
8
+ } as const;
9
+
10
+ export type HypaPiConfig = {
11
+ mode: string;
12
+ mcpProxyEnabled: boolean;
13
+ [key: string]: unknown;
14
+ };
15
+
16
+ /**
17
+ * Resolve config path the same way @hypabolic/pi-hypa documents:
18
+ * HYPA_PI_CONFIG, or ~/.hypa-pi/config.json. Empty / "none" means skip seeding.
19
+ */
20
+ export function resolveHypaPiConfigPath(
21
+ env: NodeJS.ProcessEnv = process.env,
22
+ home: string = homedir(),
23
+ ): string | null {
24
+ const raw = env.HYPA_PI_CONFIG;
25
+ if (raw !== undefined) {
26
+ const trimmed = raw.trim();
27
+ if (trimmed === "" || trimmed.toLowerCase() === "none") {
28
+ return null;
29
+ }
30
+ return trimmed;
31
+ }
32
+ return join(home, ".hypa-pi", "config.json");
33
+ }
34
+
35
+ export function formatDefaultHypaPiConfig(): string {
36
+ return `${JSON.stringify(DEFAULT_HYPA_PI_CONFIG, null, "\t")}\n`;
37
+ }
@@ -0,0 +1,22 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ import {
4
+ formatDefaultHypaPiConfig,
5
+ resolveHypaPiConfigPath,
6
+ } from "./config.ts";
7
+
8
+ /**
9
+ * Seed ~/.hypa-pi/config.json when missing. Never overwrites an existing file.
10
+ * @returns true if a new file was written
11
+ */
12
+ export function seedHypaPiConfigIfMissing(
13
+ env: NodeJS.ProcessEnv = process.env,
14
+ ): boolean {
15
+ const path = resolveHypaPiConfigPath(env);
16
+ if (!path) return false;
17
+ if (existsSync(path)) return false;
18
+
19
+ mkdirSync(dirname(path), { recursive: true });
20
+ writeFileSync(path, formatDefaultHypaPiConfig(), "utf8");
21
+ return true;
22
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "allowImportingTsExtensions": true,
5
+ "types": ["node"]
6
+ },
7
+ "include": [
8
+ "extensions/**/*.ts",
9
+ "src/**/*.ts",
10
+ "tests/**/*.ts"
11
+ ],
12
+ "exclude": ["node_modules"]
13
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/keybindings",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Centralized keyboard shortcut registry for Vito's Pizzeria Pi distribution",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/permission-system",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Permission enforcement for Vito's Pizzeria Pi distribution",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -18,7 +18,7 @@
18
18
  "lint:fix": "biome check --write ."
19
19
  },
20
20
  "dependencies": {
21
- "@vitos-pizza/keybindings": "0.3.0",
21
+ "@vitos-pizza/keybindings": "0.4.0",
22
22
  "tree-sitter-bash": "^0.25.1",
23
23
  "web-tree-sitter": "^0.25.10",
24
24
  "zod": "^3.25.76"
@@ -5,6 +5,12 @@
5
5
  "grep": "allow",
6
6
  "find": "allow",
7
7
  "ls": "allow",
8
+ "hypa_read": "allow",
9
+ "hypa_grep": "allow",
10
+ "hypa_find": "allow",
11
+ "hypa_ls": "allow",
12
+ "hypa_shell": "ask",
13
+ "hypa_mcp_proxy": "deny",
8
14
  "web_search": "ask",
9
15
  "web_read": "ask",
10
16
  "path": {
@@ -28,6 +34,8 @@
28
34
  "npm test *": "allow",
29
35
  "npm run typecheck": "allow",
30
36
  "npm run lint": "allow",
37
+ "hypa *": "ask",
38
+ "hypa -c *": "ask",
31
39
  "rm -rf *": "deny",
32
40
  "sudo *": "ask"
33
41
  },
@@ -5,12 +5,18 @@
5
5
  "grep": "allow",
6
6
  "find": "allow",
7
7
  "ls": "allow",
8
+ "hypa_read": "allow",
9
+ "hypa_grep": "allow",
10
+ "hypa_find": "allow",
11
+ "hypa_ls": "allow",
8
12
  "question": "allow",
9
13
  "subagent": "allow",
10
14
  "wait": "allow",
11
15
  "web_search": "ask",
12
16
  "web_read": "ask",
13
17
  "bash": "deny",
18
+ "hypa_shell": "deny",
19
+ "hypa_mcp_proxy": "deny",
14
20
  "write": "deny",
15
21
  "edit": "deny",
16
22
  "skill": {
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "permission": {
3
3
  "*": "allow",
4
+ "hypa_mcp_proxy": "deny",
4
5
  "path": {
5
6
  "*": "allow",
6
7
  "*.env": "deny",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/question",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Structured ask-user question tool for Vito's Pizzeria Pi distribution",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/session-title",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Async session auto-naming for Vito's Pizzeria Pi distribution",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -11,7 +11,7 @@
11
11
  ]
12
12
  },
13
13
  "dependencies": {
14
- "@vitos-pizza/subagents": "0.3.0"
14
+ "@vitos-pizza/subagents": "0.4.0"
15
15
  },
16
16
  "scripts": {
17
17
  "test": "vitest run",
@@ -30,7 +30,7 @@
30
30
  "devDependencies": {
31
31
  "@earendil-works/pi-ai": "*",
32
32
  "@earendil-works/pi-coding-agent": "*",
33
- "@vitos-pizza/subagents": "0.3.0",
33
+ "@vitos-pizza/subagents": "0.4.0",
34
34
  "typebox": "*",
35
35
  "vitest": "^3.2.4"
36
36
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/settings-preset",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Default Pi settings for Vito's Pizzeria distribution — written on first session start",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,23 +1,19 @@
1
1
  ---
2
2
  name: planner
3
3
  description: Creates implementation plans from context and requirements
4
- tools: read, grep, find, ls, write, question, web_search, web_read
4
+ tools: read, grep, find, ls, hypa_read, hypa_grep, hypa_find, hypa_ls, write, question, web_search, web_read
5
5
  thinking: high
6
6
  systemPromptMode: replace
7
7
  ---
8
8
 
9
- You are a planning subagent.
9
+ You are planner: turn requirements and code context into a concrete implementation plan. Do not change application code. You may `write` only to persist the plan document.
10
10
 
11
- Your job is to turn requirements and code context into a concrete implementation plan. Do not make code changes. Read, analyze, and write the plan only.
12
-
13
- Working rules:
14
- - Read the provided context before planning.
15
- - Read any additional code you need in order to make the plan concrete.
16
- - Name exact files whenever you can.
17
- - Prefer small, ordered, actionable tasks over vague phases.
18
- - Call out risks, dependencies, and anything that needs explicit validation.
19
- - If the task is underspecified, use the `question` tool to ask the user for clarification before guessing.
20
- - Mutually exclusive design choices (2–5 options) → always use `question`; never ask "which do you prefer?" in free text.
11
+ Rules:
12
+ - Read provided context (and more code as needed) before planning.
13
+ - Prefer `hypa_read` / `hypa_grep` / `hypa_find` / `hypa_ls` when available; fall back to read/grep/find/ls.
14
+ - Name exact files; prefer small, ordered, actionable tasks; call out risks and dependencies.
15
+ - Underspecified or mutually exclusive choices use `question` before guessing.
16
+ - Web tools only for current external facts outside the repo.
21
17
 
22
18
  Output format:
23
19
 
@@ -39,8 +35,9 @@ Numbered steps, each small and actionable.
39
35
  Which tasks depend on others.
40
36
 
41
37
  ## Risks
42
- Anything likely to go wrong, need clarification, or need careful verification.
38
+ Anything likely to go wrong or need careful verification.
43
39
 
44
- Do **not** add a long "next steps" essay — the parent plan-mode agent may add a short **Next** footer when helpful.
40
+ ## 功能验收
41
+ 3–6 checkboxes of observable outcomes (yes/no verifiable).
45
42
 
46
- Keep the plan concrete. Another agent should be able to execute it without guessing what you meant.
43
+ Keep the plan concrete enough for another agent to execute without guessing. The parent may add a short **Next** footer — do not write a long next-steps essay.
@@ -1,28 +1,20 @@
1
1
  ---
2
2
  name: scout
3
3
  description: Fast codebase recon that returns compressed context for handoff
4
- tools: read, grep, find, ls, question, web_search, web_read
4
+ tools: read, grep, find, ls, hypa_read, hypa_grep, hypa_find, hypa_ls, question, web_search, web_read
5
5
  thinking: low
6
6
  systemPromptMode: replace
7
7
  ---
8
8
 
9
- You are a scouting subagent running inside pi.
9
+ You are scout: fast codebase recon for handoff. Do not guess. Prefer targeted search over whole-file reads.
10
10
 
11
- Use the provided tools directly. Move fast, but do not guess. Prefer targeted search and selective reading over reading whole files unless the task clearly needs broader coverage.
11
+ Return the minimum context another agent needs: entry points, key types/APIs, data flow, files likely to change, risks and open questions.
12
12
 
13
- Focus on the minimum context another agent needs in order to act:
14
- - relevant entry points
15
- - key types, interfaces, and functions
16
- - data flow and dependencies
17
- - files that are likely to need changes
18
- - constraints, risks, and open questions
19
-
20
- Working rules:
21
- - Use `grep`, `find`, `ls`, and `read` to map the area before diving deeper.
22
- - You have the `question` tool. Use it when clarification would materially improve recon (ambiguous scope, mutually exclusive choices). Skip it when context is already enough.
23
- - When you do ask, prefer `question` over free-text "which do you prefer?".
24
- - When you cite code, use exact file paths and line ranges.
25
- - When running solo, summarize what you found in the final response.
13
+ Rules:
14
+ - Prefer `hypa_read` / `hypa_grep` / `hypa_find` / `hypa_ls` when available; fall back to read/grep/find/ls.
15
+ - Cite exact file paths and line ranges.
16
+ - Use `question` only when ambiguity blocks recon; prefer structured options over free-text choices.
17
+ - Web tools only for current external facts outside the repo.
26
18
 
27
19
  Output format:
28
20
 
@@ -32,10 +24,10 @@ Output format:
32
24
  List exact files and line ranges.
33
25
 
34
26
  ## Key Code
35
- Include the critical types, interfaces, functions, and small code snippets that matter.
27
+ Critical types, interfaces, functions, and small snippets that matter.
36
28
 
37
29
  ## Architecture
38
- Explain how the pieces connect.
30
+ How the pieces connect.
39
31
 
40
32
  ## Start Here
41
- Name the first file another agent should open and why.
33
+ First file another agent should open and why.
@@ -9,5 +9,6 @@ You analyze the user's intent together with the assistant's last reply and produ
9
9
 
10
10
  Rules:
11
11
  - Output only the title text — no quotes, no explanation, no markdown.
12
+ - Match the language of the user's message.
12
13
  - If there is no clear task intent, output exactly `SKIP`.
13
14
  - Respect the maximum title length given in the task.
@@ -1,33 +1,22 @@
1
1
  ---
2
2
  name: worker
3
3
  description: Implementation agent for approved plans and focused tasks
4
- tools: read, grep, find, ls, bash, edit, write
4
+ tools: read, grep, find, ls, hypa_read, hypa_grep, hypa_find, hypa_ls, bash, edit, write
5
5
  thinking: high
6
6
  systemPromptMode: replace
7
7
  ---
8
8
 
9
- You are `worker`: the implementation subagent.
9
+ You are worker: the single writer thread. Execute the assigned task or approved plan with narrow, coherent edits. The main agent and user remain the decision authority.
10
10
 
11
- You are the single writer thread. Your job is to execute the assigned task or approved direction with narrow, coherent edits. The main agent and user remain the decision authority.
11
+ Rules:
12
+ - Read inherited context/plan first; validate against the actual code.
13
+ - Prefer `hypa_read` / `hypa_grep` / `hypa_find` / `hypa_ls` when available; fall back to read/grep/find/ls.
14
+ - Prefer the smallest correct change; follow existing patterns.
15
+ - No speculative scaffolding, placeholders, TODOs, or silent scope changes.
16
+ - Use `bash` for inspection, validation, and relevant tests (Hypa may rewrite bash for compressed output — keep using `bash`, not `hypa_shell`).
17
+ - If the task expects file edits and you made none, do not claim success.
12
18
 
13
- Use the provided tools directly. First understand the inherited context, supplied files, plan, and explicit task. Then implement carefully and minimally.
14
-
15
- Default responsibilities:
16
- - validate the task or approved direction against the actual code
17
- - implement the smallest correct change
18
- - follow existing patterns in the codebase
19
- - verify the result with appropriate checks when possible
20
- - report back clearly with changes, validation, risks, and next steps
21
-
22
- Working rules:
23
- - Prefer narrow, correct changes over broad rewrites.
24
- - Do not add speculative scaffolding or future-proofing unless explicitly required.
25
- - Do not leave placeholder code, TODOs, or silent scope changes.
26
- - Use `bash` for inspection, validation, and relevant tests.
27
- - If there is supplied context or a plan, read it first.
28
- - If your delegated task expects code or file edits and you have not made those edits, do not return a success summary.
29
-
30
- Your final response should follow this shape:
19
+ Final response shape:
31
20
 
32
21
  Implemented X.
33
22
  Changed files: Y.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/subagents",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Subagent delegation for Vito's Pizzeria Pi distribution",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -7,56 +7,41 @@ description: Delegate exploration, planning, and implementation to Vito's Pizzer
7
7
 
8
8
  Use the `subagent` tool to delegate work to focused child agents with isolated context.
9
9
 
10
- ## Agent modes
10
+ ## Modes
11
11
 
12
- Vito's Pizzeria uses three modes via `/mode` or `Ctrl+.` / `Alt+M`:
13
-
14
- | Mode | When to use |
15
- |------|-------------|
16
- | **agent** | Default balanced work |
17
- | **plan** | Read-only planning — planner (+ optional scout); `question` available anytime when helpful; optional short **Next** footer |
18
- | **execute** | Full implementation after plan is approved |
19
-
20
- In **plan** mode the main agent cannot write/edit/bash. Delegate with subagents. Scout is optional — use it only when codebase recon is needed; otherwise call planner directly. When recon spans independent areas, run multiple scouts in parallel (`tasks: [...]`) then planner. The main agent, scout, and planner can all use `question` during plan when clarification would help (not required if context is enough):
21
-
22
- ```
23
- [optional scout(s) →] planner → (user confirms) → switch to execute → worker
24
- ```
12
+ | Mode | Constraint |
13
+ |------|------------|
14
+ | **plan** | Read-only. Scout (optional) → planner. Never call worker. |
15
+ | **agent** / **execute** | May call worker after a plan is approved (or for focused implementation). |
25
16
 
26
17
  ## Built-in agents
27
18
 
28
19
  | Agent | Use when |
29
20
  |-------|----------|
30
- | `scout` | Fast codebase recon; returns compressed context; may use `question` when recon needs clarification |
21
+ | `scout` | Fast codebase recon; compressed context for handoff |
31
22
  | `planner` | Turn context + requirements into an implementation plan |
32
23
  | `worker` | Execute an approved plan with narrow, correct edits |
33
- | `title` | Generate short session titles (used by `@vitos-pizza/session-title`) |
34
-
35
- ## Typical workflow
36
24
 
37
- ```
38
- [optional scout →] planner → worker
39
- ```
25
+ ## Plan-mode examples
40
26
 
41
- ### Planner only (enough context)
27
+ ### Planner only
42
28
 
43
29
  ```json
44
30
  { "agent": "planner", "task": "Create an implementation plan for ..." }
45
31
  ```
46
32
 
47
- ### Chain with scout (when recon is needed)
33
+ ### Scout planner
48
34
 
49
35
  ```json
50
36
  {
51
37
  "chain": [
52
38
  { "agent": "scout", "task": "Map the auth module and key entry points" },
53
- { "agent": "planner", "task": "Create a plan based on {previous}" },
54
- { "agent": "worker", "task": "Implement the plan from {previous}" }
39
+ { "agent": "planner", "task": "Create a plan based on {previous}" }
55
40
  ]
56
41
  }
57
42
  ```
58
43
 
59
- ### Parallel
44
+ ### Parallel scouts
60
45
 
61
46
  ```json
62
47
  {
@@ -67,9 +52,23 @@ In **plan** mode the main agent cannot write/edit/bash. Delegate with subagents.
67
52
  }
68
53
  ```
69
54
 
70
- ### Async + wait
55
+ Then call planner with the combined findings.
56
+
57
+ ## After plan approval (agent / execute)
71
58
 
72
- Start work in the background, then block until it finishes:
59
+ ### Chain through worker
60
+
61
+ ```json
62
+ {
63
+ "chain": [
64
+ { "agent": "scout", "task": "Map relevant code" },
65
+ { "agent": "planner", "task": "Create a plan based on {previous}" },
66
+ { "agent": "worker", "task": "Implement the plan from {previous}" }
67
+ ]
68
+ }
69
+ ```
70
+
71
+ ### Async + wait
73
72
 
74
73
  ```json
75
74
  { "agent": "worker", "task": "...", "async": true }
@@ -36,6 +36,23 @@ const THINKING_LEVELS = new Set([
36
36
  "max",
37
37
  ]);
38
38
 
39
+ /** Internal agents (e.g. session naming) — callable by name, not listed to the main agent. */
40
+ const INTERNAL_AGENT_NAMES = new Set(["title"]);
41
+
42
+ export function isPublicAgent(name: string): boolean {
43
+ return !INTERNAL_AGENT_NAMES.has(name);
44
+ }
45
+
46
+ export function formatAvailableAgents(
47
+ agents: Array<{ name: string; source: string }>,
48
+ ): string {
49
+ const visible = agents.filter((agent) => isPublicAgent(agent.name));
50
+ return (
51
+ visible.map((agent) => `${agent.name} (${agent.source})`).join(", ") ||
52
+ "none"
53
+ );
54
+ }
55
+
39
56
  export function getBuiltinAgentsDir(): string {
40
57
  return path.join(
41
58
  path.dirname(fileURLToPath(import.meta.url)),
@@ -1,6 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import type { AgentToolResult } from "@earendil-works/pi-agent-core";
3
- import { discoverAgents } from "./agents.ts";
3
+ import { discoverAgents, formatAvailableAgents } from "./agents.ts";
4
4
  import { runSingleAgent } from "./run-agent.ts";
5
5
  import type {
6
6
  AgentScope,
@@ -67,9 +67,7 @@ export async function executeSubagent(
67
67
  const mode = resolveMode(input);
68
68
 
69
69
  if (countModes(input) !== 1 || !mode) {
70
- const available =
71
- agents.map((agent) => `${agent.name} (${agent.source})`).join(", ") ||
72
- "none";
70
+ const available = formatAvailableAgents(agents);
73
71
  return {
74
72
  content: [
75
73
  {
@@ -267,8 +265,7 @@ export async function executeSubagent(
267
265
  };
268
266
  }
269
267
 
270
- const available =
271
- agents.map((agent) => `${agent.name} (${agent.source})`).join(", ") || "none";
268
+ const available = formatAvailableAgents(agents);
272
269
  return {
273
270
  content: [
274
271
  {
@@ -7,6 +7,7 @@ import type { Message } from "@earendil-works/pi-ai";
7
7
  import { withFileMutationQueue } from "@earendil-works/pi-coding-agent";
8
8
  import {
9
9
  applyThinkingSuffix,
10
+ formatAvailableAgents,
10
11
  type AgentConfig,
11
12
  } from "./agents.ts";
12
13
  import {
@@ -77,7 +78,7 @@ export async function runSingleAgent(
77
78
 
78
79
  const agent = agents.find((entry) => entry.name === agentName);
79
80
  if (!agent) {
80
- const available = agents.map((entry) => `"${entry.name}"`).join(", ") || "none";
81
+ const available = formatAvailableAgents(agents);
81
82
  return {
82
83
  agent: agentName,
83
84
  agentSource: "unknown",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/todoist",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "In-memory task management with TUI widget and optional Todoist MCP sync for Vito's Pizzeria Pi distribution",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/ui-enhancements",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "TUI and UI enhancements for Vito's Pizzeria Pi distribution",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,9 +25,11 @@ export default function (pi: ExtensionAPI) {
25
25
  label: "Web Search",
26
26
  description:
27
27
  "Search the web using configured backends. Auto mode tries Exa MCP, Firecrawl, and optional keyed providers.",
28
- promptSnippet: "Search the web for up-to-date information",
28
+ promptSnippet:
29
+ "Search the web only when local context is insufficient for current external facts",
29
30
  promptGuidelines: [
30
- "Use web_search when you need current facts, documentation, or news from the web",
31
+ "Do not use web_search when the answer is already in the repo, conversation, or local tools (read/grep/find/ls)",
32
+ "Use web_search only when you need current external facts, docs, or news that local context cannot provide",
31
33
  "Auto mode tries enabled backends in order; Exa MCP works without API keys",
32
34
  "Configure Tavily or Brave in .pi/search.json for higher-quality results",
33
35
  ],
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/websearch",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Web search and URL reading for Vito's Pizzeria Pi distribution",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -8,9 +8,20 @@ const rootPkgPath = join(root, "package.json");
8
8
 
9
9
  const RESOURCE_TYPES = ["extensions", "skills", "prompts", "themes"];
10
10
 
11
- const BUNDLED_FIRST = [];
12
- const BUNDLED_LAST = [];
13
- const LOCAL_ORDER = ["permission-system", "settings-preset", "question", "ui-enhancements", "agent-mode", "subagents", "websearch", "session-title", "todoist", "keybindings"];
11
+ /** Local modules after permission-system, before agent-mode (plan setActiveTools). */
12
+ const LOCAL_ORDER = [
13
+ "permission-system",
14
+ "settings-preset",
15
+ "hypa",
16
+ "question",
17
+ "ui-enhancements",
18
+ "subagents",
19
+ "websearch",
20
+ "session-title",
21
+ "keybindings",
22
+ "agent-mode",
23
+ "todoist",
24
+ ];
14
25
 
15
26
  function loadJson(path) {
16
27
  return JSON.parse(readFileSync(path, "utf8"));
@@ -157,9 +168,9 @@ function sortPackagesByRequires(packages) {
157
168
 
158
169
  const packages = discoverPackages();
159
170
  const sortedPackages = sortPackagesByRequires(packages);
160
- const packageByDir = new Map(packages.map((p) => [p.dir, p]));
161
171
  const rootPkg = loadJson(rootPkgPath);
162
172
  const existingDeps = rootPkg.dependencies ?? {};
173
+ const piBundled = Array.isArray(rootPkg.piBundled) ? rootPkg.piBundled : [];
163
174
 
164
175
  const dependencies = {};
165
176
  for (const [name, spec] of Object.entries(existingDeps)) {
@@ -174,7 +185,7 @@ for (const { dir, pkg } of packages) {
174
185
 
175
186
  const piEntries = [];
176
187
 
177
- for (const npmName of BUNDLED_FIRST) {
188
+ for (const npmName of piBundled) {
178
189
  const pi = resolveBundledPaths(npmName);
179
190
  if (pi) piEntries.push({ pi });
180
191
  }
@@ -185,17 +196,12 @@ for (const entry of sortedPackages) {
185
196
  });
186
197
  }
187
198
 
188
- for (const npmName of BUNDLED_LAST) {
189
- const pi = resolveBundledPaths(npmName);
190
- if (pi) piEntries.push({ pi });
191
- }
192
-
193
199
  rootPkg.dependencies = dependencies;
200
+ rootPkg.piBundled = piBundled;
194
201
  rootPkg.pi = mergePiManifest(piEntries);
195
202
 
196
203
  writeFileSync(rootPkgPath, `${JSON.stringify(rootPkg, null, "\t")}\n`, "utf8");
197
204
 
198
- const bundled = [...BUNDLED_FIRST, ...BUNDLED_LAST].join(", ");
199
205
  console.log(
200
- `Synced vitos-pizza manifest: ${packages.length} local module(s) [${sortedPackages.map((p) => p.dir).join(", ")}], bundled: ${bundled || "(none)"}`,
206
+ `Synced vitos-pizza manifest: ${packages.length} local module(s) [${sortedPackages.map((p) => p.dir).join(", ")}], piBundled: ${piBundled.join(", ") || "(none)"}`,
201
207
  );