@gonrocca/zero-pi 0.1.12 → 0.1.13

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.
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Gonzalo Rocca
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Gonzalo Rocca
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,258 +1,296 @@
1
- ```
2
- ███████╗ ███████╗ ██████╗ ██████╗ ██████╗ ██╗
3
- ╚══███╔╝ ██╔════╝ ██╔══██╗ ██╔═══██╗ ██╔══██╗ ██║
4
- ███╔╝ █████╗ ██████╔╝ ██║ ██║ █████╗ ██████╔╝ ██║
5
- ███╔╝ ██╔══╝ ██╔══██╗ ██║ ██║ ╚════╝ ██╔═══╝ ██║
6
- ███████╗ ███████╗ ██║ ██║ ╚██████╔╝ ██║ ██║
7
- ╚══════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
8
- ```
9
-
10
- # @gonrocca/zero-pi
11
-
12
- An installable layer for **[pi](https://pi.dev)** — it adds the zero
13
- spec-driven development workflow, skill auto-learning, and an animated `ZERO`
14
- startup banner **without modifying pi itself**.
15
-
16
- Same idea as `gentle-pi`: pi stays untouched; zero-pi is a package pi loads.
17
-
18
- ## Install
19
-
20
- ```bash
21
- pi install npm:@gonrocca/zero-pi
22
- ```
23
-
24
- That registers zero-pi in `~/.pi/agent/settings.json` and makes its prompts,
25
- skills, and the startup-banner extension available in every pi session.
26
-
27
- To remove it:
28
-
29
- ```bash
30
- pi remove npm:@gonrocca/zero-pi
31
- ```
32
-
33
- ## What it adds
34
-
35
- ### SDD workflow (`prompts/`)
36
-
37
- A spec-driven development pipeline driven through four phases, in order:
38
-
39
- 1. **explore** — investigate the codebase read-only; produce findings.
40
- 2. **plan** — write requirements, design, and an ordered task list.
41
- 3. **build** — implement the plan.
42
- 4. **veredicto** — review the build adversarially and record a verdict
43
- (`pasa`, `corregir`, or `replantear`).
44
-
45
- Run it with the `/forge <feature>` prompt. The orchestrator drives phase order
46
- and enforces a hard build/veredicto iteration cap. Each phase has its own prompt
47
- under `prompts/phases/` so it can be delegated to a dedicated sub-agent.
48
-
49
- Besides the explicit `/forge` command, an SDD run can also be started from
50
- natural language: describe the work and signal SDD intent — e.g. "hacelo con
51
- sdd" or "usá el pipeline" — and the `sdd-routing` skill routes the request into
52
- `/forge` for you. It triggers only on a clear signal phrase and stays out of the
53
- way for ordinary requests; `/forge` remains the primary, explicit entry point.
54
-
55
- **Review Workload Forecast** — the plan phase keeps tasks reviewable. Every
56
- planned task carries a `review: ~N changed lines` estimate, and `tasks.md` gains
57
- a `## Review Workload` section with the per-task estimates and a bold run total.
58
- Tasks are sized against a fixed budget of **400 changed lines per task** — an
59
- internal, non-configurable default (borrowed from gentle-ai), so "small task"
60
- means the same number on every run. A task whose estimate exceeds the budget is
61
- split into smaller, individually verifiable tasks; one that genuinely cannot be
62
- split stays whole and is recorded as an over-budget exception with a reason. The
63
- orchestrator's plan-phase summary reports the run total and any exceptions.
64
-
65
- ### Per-phase models (`/zero-models`)
66
-
67
- `/zero-models` is a real pi command — a code handler, not an LLM prompt — for
68
- the SDD models. Run it with no argument to pick a phase and a model
69
- interactively, or set one directly:
70
-
71
- ```
72
- /zero-models # interactive picker
73
- /zero-models build=claude-opus-4-7 # set one phase
74
- ```
75
-
76
- It reads and writes `~/.pi/zero.json`; the orchestrator picks the change up on
77
- the next `/forge` run.
78
-
79
- Per-phase model assignments are read from `~/.pi/zero.json`, which the `zero`
80
- CLI writes when it installs this layer.
81
-
82
- **Run memory** — every SDD run reads from and writes to Cortex (the memory MCP
83
- server). Before exploring, the orchestrator recalls prior `zero-run/*` traces
84
- for the feature; when the run ends it saves a run-trace — the final verdict, the
85
- correction rounds, and the gotchas under `topic_key: zero-run/<slug>`. The
86
- next run on related work starts from what the last one learned. With `--no-mcp`
87
- the loop degrades silently.
88
-
89
- ### Canonical specs & `/zero-sync`
90
-
91
- zero keeps a **canonical, project-wide spec store** that accumulates accepted
92
- requirements across runs, so each `/forge` run builds on the last instead of
93
- starting from a blank spec.
94
-
95
- **The canonical store — `.sdd/specs/requirements.md`.** A single flat markdown
96
- file: a `# ` title followed by `### REQ: <stable-unique-name>` requirement
97
- blocks. It is the project's source of truth. The `plan` phase reads it as the
98
- baseline; a fresh project has no store yet, and that absence simply means an
99
- empty store.
100
-
101
- **The granular plan artifacts.** Every run's `plan` phase writes four files
102
- into `.sdd/<slug>/`:
103
-
104
- - `proposal.md` — the change intent: scope and rationale, in prose.
105
- - `spec.md` — the **delta** against the canonical store, never a full spec. Up
106
- to three `H2` sections `## ADDED`, `## MODIFIED`, `## REMOVED` — each
107
- holding `### REQ:` blocks. `## MODIFIED` carries the complete updated text of
108
- an existing block (not a diff); `## REMOVED` needs only the name line.
109
- - `design.md` — how it is built.
110
- - `tasks.md` — the ordered task list with its `## Review Workload` section.
111
-
112
- **`/zero-sync` folding the delta into the store.** `/zero-sync <slug>` is a
113
- real pi command a deterministic, unit-tested merge, not an LLM prompt — that
114
- reads the store and the run's delta `spec.md`, applies the ADDED/MODIFIED/REMOVED
115
- changes, and writes the store atomically. Guardrails reject a bad delta before
116
- anything is written: a duplicate name, an ADDED collision with an existing
117
- block, a MODIFIED or REMOVED of a missing block, or malformed input. On a
118
- guardrail failure it writes nothing and reports the offending requirement; the
119
- store is never left half-merged. After a `pasa` verdict the SDD orchestrator
120
- invokes `/zero-sync <slug>` automatically a `corregir`, `replantear`, or
121
- cap-reached run never syncs.
122
-
123
- **The archive `.sdd/archive/`.** Each successful sync appends a dated,
124
- slug-named entry `.sdd/archive/<YYYY-MM-DD>-<slug>/` containing a copy of the
125
- run's `proposal.md` and `spec.md` plus a `sync.md` report listing every added,
126
- modified, and removed requirement. The archive is append-only — a new entry
127
- never rewrites a prior one — so it is a full audit trail of how the canonical
128
- store evolved.
129
-
130
- ### Adaptive model profiles
131
-
132
- zero learns which model fits each SDD phase from your own run history and can
133
- re-tune `~/.pi/zero.json` for you.
134
-
135
- **The metrics log — `~/.pi/zero-runs.jsonl`.** Every completed SDD run appends
136
- one JSON line to this file: the feature slug, the per-phase models the run used,
137
- the final verdict, the build/veredicto round count, and the ordered per-round
138
- verdict sequence. It is append-only and never rewritten. This local log is the
139
- only thing zero learns from — a run abandoned before it reaches a verdict adds
140
- no line.
141
-
142
- **Phase attribution (v2).** The per-round verdict sequence makes blame precise:
143
- a `corregir` round re-runs and so blames the `build` phase, and a
144
- `replantear` round blames the `plan` phase. Autotune aggregates that sequence
145
- per phase and upgrades **only the phase at fault**, one tier at a time — a
146
- `build` problem no longer drags `plan` up with it. The `explore` and `veredicto`
147
- phases are never tuned.
148
-
149
- **Autotune modes.** At each pi session start zero aggregates the log and, once a
150
- phase has accumulated enough run data to cross a confidence threshold, decides
151
- whether that phase's model should change. Until a phase has accumulated enough
152
- v2 runs of its own, autotune deliberately stays quiet — a one-time, silent
153
- cold-start after upgrading, not a regression. The `autotune` mode in
154
- `~/.pi/zero.json` controls what happens next:
155
-
156
- | Mode | Behaviour |
157
- | ---- | --------- |
158
- | `auto` _(default)_ | zero applies the adjustment to `~/.pi/zero.json` and notifies you exactly what changed. |
159
- | `ask` | zero records the recommendation but changes nothing — you apply it from `/zero-models`. |
160
- | `off` | zero still records run metrics, but never changes or recommends anything. |
161
-
162
- A change always takes effect on the *next* `/forge` run, and every applied
163
- change is announced autotune is never silent.
164
-
165
- **Setting the mode.** Set it directly, or pick it from the interactive
166
- `/zero-models` menu (which shows the current mode as its own entry):
167
-
168
- ```
169
- /zero-models autotune=ask # auto | ask | off
170
- ```
171
-
172
- **Applying a pending suggestion.** In `ask` mode, when a recommendation is
173
- waiting, running `/zero-models` shows a leading `★ aplicar sugerencia` entry;
174
- selecting it applies the change and clears the pending suggestion. Note that a
175
- pending suggestion is *refreshed* — an unactioned suggestion is overwritten by
176
- the next `ask`-mode session with fresher data, so `/zero-models` always reflects
177
- the most recent recommendation.
178
-
179
- ### Skill auto-learning (`skills/`)
180
-
181
- `skill-loop.md` gives the agent a closed learning loop so solutions are reused
182
- instead of re-derived.
183
-
184
- ### ZERO terminal theme (`themes/zero-sdd.json`)
185
-
186
- `zero-pi` ships a Pi theme named `zero-sdd`: a dark, high-contrast terminal
187
- palette with cyan, amber, mint, rose, and violet accents tuned for SDD work.
188
- Select it from `/settings`, or set `"theme": "zero-sdd"` in Pi settings.
189
-
190
- ### Startup banner (`extensions/startup-banner.ts`)
191
-
192
- Renders the `ZERO` wordmark as ASCII-safe Tetris cells. In the default animated
193
- mode, the cells assemble from the bottom up when a pi session starts, then
194
- settle into the completed ZERO banner. Pure ANSI 24-bit colour, no runtime
195
- dependencies.
196
-
197
- The render runs synchronously before pi draws its UI, so the animation never
198
- fights pi's renderer.
199
-
200
- ### Working-phrase ticker (`extensions/working-phrases.ts`)
201
-
202
- Pi shows a single static `Working...` line while the agent is busy. This
203
- extension replaces it with a context-aware, rotating phrase:
204
-
205
- - **While a tool runs** — a tool-specific line: `Leyendo archivos…`,
206
- `Ejecutando comandos…`, `Buscando en el código…`. MCP tools are named by
207
- server (`Consultando un MCP…`).
208
- - **While a zero sub-agent runs** — the SDD phase it owns:
209
- `Explorando el código…`, `Planeando la solución…`,
210
- `Construyendo la implementación…`, `Revisando el veredicto…`.
211
- - **While the model thinks** a rotation of playful verbs (`Maquinando…`,
212
- `Rumiando…`, `Cocinando…`). Once a `/forge` run is detected the rotation
213
- biases toward SDD vocabulary.
214
-
215
- It also installs a theme-tinted braille spinner that gently breathes through
216
- the palette's `dim`/`muted`/`accent` colours. The extension uses only pi's
217
- public extension API, and every handler is defensive the indicator can never
218
- break a session.
219
-
220
- Control it with the `ZERO_BANNER` environment variable:
221
-
222
- | `ZERO_BANNER` | Effect |
223
- | ------------- | ------ |
224
- | _(unset)_ / `shimmer` | Animated Tetris assembly, then settle (default) |
225
- | `static` | Completed Tetris banner only, no animation |
226
- | `off` | Render nothing |
227
-
228
- Colour is skipped automatically when `NO_COLOR` is set or the output is not a
229
- TTY.
230
-
231
- ### Provider guard (`extensions/provider-guard.ts`)
232
-
233
- zero-pi watches model switches and steps in when you move to a metered
234
- provider. When you switch to a model on the `anthropic` provider — which bills
235
- per token and draws down your metered extra-usage pool — the guard offers to
236
- redirect you to the equivalent model on `pi-claude-cli`, the provider backed by
237
- your subscription's limits.
238
-
239
- The redirect is offered through a confirmation dialog, and that dialog is your
240
- escape hatch: say "yes" and the guard switches you to the subscription-backed
241
- equivalent; say "no" (or cancel) and you stay on the metered `anthropic`
242
- provider with no further nagging. When there is no equivalent model on
243
- `pi-claude-cli`, and when a model is restored on session start rather than
244
- switched deliberately, the guard skips the modal and just shows a one-line
245
- warning. Switching to a subscription provider is a complete no-op no dialog,
246
- no notification, no noise.
247
-
248
- ## Relationship to `zero`
249
-
250
- `zero-pi` is the pi-specific layer of the **[zero](https://github.com/gonzalonicolasr/zero)**
251
- integrator. The `zero` CLI installs this layer onto pi (bootstrapping pi.dev
252
- itself when it is missing) and writes the per-phase model configuration. You
253
- can also install `zero-pi` directly with `pi install npm:@gonrocca/zero-pi` if
254
- you only want the pi layer.
255
-
256
- ## License
257
-
258
- MIT © Gonzalo Rocca
1
+ ```
2
+ ███████╗ ███████╗ ██████╗ ██████╗ ██████╗ ██╗
3
+ ╚══███╔╝ ██╔════╝ ██╔══██╗ ██╔═══██╗ ██╔══██╗ ██║
4
+ ███╔╝ █████╗ ██████╔╝ ██║ ██║ █████╗ ██████╔╝ ██║
5
+ ███╔╝ ██╔══╝ ██╔══██╗ ██║ ██║ ╚════╝ ██╔═══╝ ██║
6
+ ███████╗ ███████╗ ██║ ██║ ╚██████╔╝ ██║ ██║
7
+ ╚══════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
8
+ ```
9
+
10
+ # @gonrocca/zero-pi
11
+
12
+ An installable layer for **[pi](https://pi.dev)** — it adds the zero
13
+ spec-driven development workflow, skill auto-learning, and an animated `ZERO`
14
+ startup banner **without modifying pi itself**.
15
+
16
+ Same idea as `gentle-pi`: pi stays untouched; zero-pi is a package pi loads.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pi install npm:@gonrocca/zero-pi
22
+ ```
23
+
24
+ That registers zero-pi in `~/.pi/agent/settings.json` and makes its prompts,
25
+ skills, and the startup-banner extension available in every pi session.
26
+
27
+ To remove it:
28
+
29
+ ```bash
30
+ pi remove npm:@gonrocca/zero-pi
31
+ ```
32
+
33
+ ## What it adds
34
+
35
+ ### SDD workflow (`prompts/`)
36
+
37
+ A spec-driven development pipeline driven through four phases, in order:
38
+
39
+ 1. **explore** — investigate the codebase read-only; produce findings.
40
+ 2. **plan** — write requirements, design, and an ordered task list.
41
+ 3. **build** — implement the plan.
42
+ 4. **veredicto** — review the build adversarially and record a verdict
43
+ (`pasa`, `corregir`, or `replantear`).
44
+
45
+ Run it with the `/forge <feature>` prompt. The orchestrator drives phase order
46
+ and enforces a hard build/veredicto iteration cap. Each phase has its own prompt
47
+ under `prompts/phases/` so it can be delegated to a dedicated sub-agent.
48
+
49
+ Besides the explicit `/forge` command, an SDD run can also be started from
50
+ natural language: describe the work and signal SDD intent — e.g. "hacelo con
51
+ sdd" or "usá el pipeline" — and the `sdd-routing` skill routes the request into
52
+ `/forge` for you. It triggers only on a clear signal phrase and stays out of the
53
+ way for ordinary requests; `/forge` remains the primary, explicit entry point.
54
+
55
+ **Review Workload Forecast** — the plan phase keeps tasks reviewable. Every
56
+ planned task carries a `review: ~N changed lines` estimate, and `tasks.md` gains
57
+ a `## Review Workload` section with the per-task estimates and a bold run total.
58
+ Tasks are sized against a fixed budget of **400 changed lines per task** — an
59
+ internal, non-configurable default (borrowed from gentle-ai), so "small task"
60
+ means the same number on every run. A task whose estimate exceeds the budget is
61
+ split into smaller, individually verifiable tasks; one that genuinely cannot be
62
+ split stays whole and is recorded as an over-budget exception with a reason. The
63
+ orchestrator's plan-phase summary reports the run total and any exceptions.
64
+
65
+ ### Per-phase models (`/zero-models`)
66
+
67
+ `/zero-models` is a real pi command — a code handler, not an LLM prompt — for
68
+ the SDD models. Run it with no argument for the interactive picker, or set one
69
+ directly:
70
+
71
+ ```
72
+ /zero-models # interactive picker
73
+ /zero-models build=claude-opus-4-7 # set one phase
74
+ /zero-models build=codex/gpt-5-codex # set one phase with an explicit provider
75
+ ```
76
+
77
+ The interactive picker is **provider-aware**: it reads pi's model registry, so
78
+ the flow is **phase → provider → model** and every provider you have configured
79
+ (anthropic, codex, opencode, …) and its models are offered not a hardcoded
80
+ list. An `— otro provider —` / `— otro modelo —` entry still lets you type
81
+ anything by hand.
82
+
83
+ It reads and writes `~/.pi/zero.json` `models` (the per-phase model id) plus a
84
+ parallel `providers` map. The orchestrator picks the change up on the next
85
+ `/forge` run. The `zero` CLI also writes this file when it installs the layer.
86
+
87
+ **Run memory** — every SDD run reads from and writes to Cortex (the memory MCP
88
+ server). Before exploring, the orchestrator recalls prior `zero-run/*` traces
89
+ for the feature; when the run ends it saves a run-trace — the final verdict, the
90
+ correction rounds, and the gotchas — under `topic_key: zero-run/<slug>`. The
91
+ next run on related work starts from what the last one learned. With `--no-mcp`
92
+ the loop degrades silently.
93
+
94
+ ### Canonical specs & `/zero-sync`
95
+
96
+ zero keeps a **canonical, project-wide spec store** that accumulates accepted
97
+ requirements across runs, so each `/forge` run builds on the last instead of
98
+ starting from a blank spec.
99
+
100
+ **The canonical store — `.sdd/specs/requirements.md`.** A single flat markdown
101
+ file: a `# ` title followed by `### REQ: <stable-unique-name>` requirement
102
+ blocks. It is the project's source of truth. The `plan` phase reads it as the
103
+ baseline; a fresh project has no store yet, and that absence simply means an
104
+ empty store.
105
+
106
+ **The granular plan artifacts.** Every run's `plan` phase writes four files
107
+ into `.sdd/<slug>/`:
108
+
109
+ - `proposal.md` — the change intent: scope and rationale, in prose.
110
+ - `spec.md` — the **delta** against the canonical store, never a full spec. Up
111
+ to three `H2` sections — `## ADDED`, `## MODIFIED`, `## REMOVED` — each
112
+ holding `### REQ:` blocks. `## MODIFIED` carries the complete updated text of
113
+ an existing block (not a diff); `## REMOVED` needs only the name line.
114
+ - `design.md` how it is built.
115
+ - `tasks.md` the ordered task list with its `## Review Workload` section.
116
+
117
+ **`/zero-sync` folding the delta into the store.** `/zero-sync <slug>` is a
118
+ real pi command a deterministic, unit-tested merge, not an LLM prompt — that
119
+ reads the store and the run's delta `spec.md`, applies the ADDED/MODIFIED/REMOVED
120
+ changes, and writes the store atomically. Guardrails reject a bad delta before
121
+ anything is written: a duplicate name, an ADDED collision with an existing
122
+ block, a MODIFIED or REMOVED of a missing block, or malformed input. On a
123
+ guardrail failure it writes nothing and reports the offending requirement; the
124
+ store is never left half-merged. After a `pasa` verdict the SDD orchestrator
125
+ invokes `/zero-sync <slug>` automatically a `corregir`, `replantear`, or
126
+ cap-reached run never syncs.
127
+
128
+ **The archive — `.sdd/archive/`.** Each successful sync appends a dated,
129
+ slug-named entry `.sdd/archive/<YYYY-MM-DD>-<slug>/` containing a copy of the
130
+ run's `proposal.md` and `spec.md` plus a `sync.md` report listing every added,
131
+ modified, and removed requirement. The archive is append-only — a new entry
132
+ never rewrites a prior one so it is a full audit trail of how the canonical
133
+ store evolved.
134
+
135
+ ### Adaptive model profiles
136
+
137
+ zero learns which model fits each SDD phase from your own run history and can
138
+ re-tune `~/.pi/zero.json` for you.
139
+
140
+ **The metrics log — `~/.pi/zero-runs.jsonl`.** Every completed SDD run appends
141
+ one JSON line to this file: the feature slug, the per-phase models the run used,
142
+ the final verdict, the build/veredicto round count, and the ordered per-round
143
+ verdict sequence. It is append-only and never rewritten. This local log is the
144
+ only thing zero learns from a run abandoned before it reaches a verdict adds
145
+ no line.
146
+
147
+ **Phase attribution (v2).** The per-round verdict sequence makes blame precise:
148
+ a `corregir` round re-runs — and so blames — the `build` phase, and a
149
+ `replantear` round blames the `plan` phase. Autotune aggregates that sequence
150
+ per phase and upgrades **only the phase at fault**, one tier at a time a
151
+ `build` problem no longer drags `plan` up with it. The `explore` and `veredicto`
152
+ phases are never tuned.
153
+
154
+ **Autotune modes.** At each pi session start zero aggregates the log and, once a
155
+ phase has accumulated enough run data to cross a confidence threshold, decides
156
+ whether that phase's model should change. Until a phase has accumulated enough
157
+ v2 runs of its own, autotune deliberately stays quiet — a one-time, silent
158
+ cold-start after upgrading, not a regression. The `autotune` mode in
159
+ `~/.pi/zero.json` controls what happens next:
160
+
161
+ | Mode | Behaviour |
162
+ | ---- | --------- |
163
+ | `auto` _(default)_ | zero applies the adjustment to `~/.pi/zero.json` and notifies you exactly what changed. |
164
+ | `ask` | zero records the recommendation but changes nothing — you apply it from `/zero-models`. |
165
+ | `off` | zero still records run metrics, but never changes or recommends anything. |
166
+
167
+ A change always takes effect on the *next* `/forge` run, and every applied
168
+ change is announced — autotune is never silent.
169
+
170
+ **Setting the mode.** Set it directly, or pick it from the interactive
171
+ `/zero-models` menu (which shows the current mode as its own entry):
172
+
173
+ ```
174
+ /zero-models autotune=ask # auto | ask | off
175
+ ```
176
+
177
+ **Applying a pending suggestion.** In `ask` mode, when a recommendation is
178
+ waiting, running `/zero-models` shows a leading `★ aplicar sugerencia` entry;
179
+ selecting it applies the change and clears the pending suggestion. Note that a
180
+ pending suggestion is *refreshed* — an unactioned suggestion is overwritten by
181
+ the next `ask`-mode session with fresher data, so `/zero-models` always reflects
182
+ the most recent recommendation.
183
+
184
+ ### Skill auto-learning (`skills/`)
185
+
186
+ `skill-loop.md` gives the agent a closed learning loop so solutions are reused
187
+ instead of re-derived.
188
+
189
+ ### ZERO terminal theme (`themes/zero-sdd.json`)
190
+
191
+ `zero-pi` ships a Pi theme named `zero-sdd`: a dark, high-contrast terminal
192
+ palette with cyan, amber, mint, rose, and violet accents tuned for SDD work.
193
+ Select it from `/settings`, or set `"theme": "zero-sdd"` in Pi settings.
194
+
195
+ ### Startup banner (`extensions/startup-banner.ts`)
196
+
197
+ Renders the `ZERO` wordmark as ASCII-safe Tetris cells. In the default animated
198
+ mode, the cells assemble from the bottom up when a pi session starts, then
199
+ settle into the completed ZERO banner. Pure ANSI 24-bit colour, no runtime
200
+ dependencies.
201
+
202
+ The render runs synchronously before pi draws its UI, so the animation never
203
+ fights pi's renderer.
204
+
205
+ ### Working-phrase ticker (`extensions/working-phrases.ts`)
206
+
207
+ Pi shows a single static `Working...` line while the agent is busy. This
208
+ extension replaces it with a context-aware, rotating phrase:
209
+
210
+ - **While a tool runs** — a tool-specific line: `Leyendo archivos…`,
211
+ `Ejecutando comandos…`, `Buscando en el código…`. MCP tools are named by
212
+ server (`Consultando un MCP…`).
213
+ - **While a zero sub-agent runs** — the SDD phase it owns:
214
+ `Explorando el código…`, `Planeando la solución…`,
215
+ `Construyendo la implementación…`, `Revisando el veredicto…`.
216
+ - **While the model thinks** a rotation of playful verbs (`Maquinando…`,
217
+ `Rumiando…`, `Cocinando…`). Once a `/forge` run is detected the rotation
218
+ biases toward SDD vocabulary.
219
+
220
+ It also installs a theme-tinted braille spinner that gently breathes through
221
+ the palette's `dim`/`muted`/`accent` colours. The extension uses only pi's
222
+ public extension API, and every handler is defensive — the indicator can never
223
+ break a session.
224
+
225
+ Control it with the `ZERO_BANNER` environment variable:
226
+
227
+ | `ZERO_BANNER` | Effect |
228
+ | ------------- | ------ |
229
+ | _(unset)_ / `shimmer` | Animated Tetris assembly, then settle (default) |
230
+ | `static` | Completed Tetris banner only, no animation |
231
+ | `off` | Render nothing |
232
+
233
+ Colour is skipped automatically when `NO_COLOR` is set or the output is not a
234
+ TTY.
235
+
236
+ ### Provider guard (`extensions/provider-guard.ts`)
237
+
238
+ zero-pi watches model switches and steps in when you move to a metered
239
+ provider. When you switch to a model on the `anthropic` provider which bills
240
+ per token and draws down your metered extra-usage pool the guard offers to
241
+ redirect you to the equivalent model on `pi-claude-cli`, the provider backed by
242
+ your subscription's limits.
243
+
244
+ The redirect is offered through a confirmation dialog, and that dialog is your
245
+ escape hatch: say "yes" and the guard switches you to the subscription-backed
246
+ equivalent; say "no" (or cancel) and you stay on the metered `anthropic`
247
+ provider with no further nagging. When there is no equivalent model on
248
+ `pi-claude-cli`, and when a model is restored on session start rather than
249
+ switched deliberately, the guard skips the modal and just shows a one-line
250
+ warning. Switching to a subscription provider is a complete no-op no dialog,
251
+ no notification, no noise.
252
+
253
+ ### Conversation resume (`extensions/conversation-resume.ts`)
254
+
255
+ When pi exits normally, zero-pi writes a local handoff note:
256
+
257
+ ```
258
+ .pi/zero-resume.md
259
+ ```
260
+
261
+ The note includes the exact restore command for the persisted pi session:
262
+
263
+ ```bash
264
+ pi --session '<session-file>'
265
+ ```
266
+
267
+ When a session id is available it also writes the shorter form:
268
+
269
+ ```bash
270
+ pi --session <session-id>
271
+ ```
272
+
273
+ `pi --resume` is listed too for the interactive session picker. The file also
274
+ keeps a concise conversation tail, enough to remember the last user intent and
275
+ assistant progress without replacing pi's real session history.
276
+
277
+ Generate it manually at any time:
278
+
279
+ ```text
280
+ /zero-resume
281
+ ```
282
+
283
+ The resume lives under `.pi/`, and zero-pi creates `.pi/.gitignore` so local
284
+ conversation context is not accidentally committed.
285
+
286
+ ## Relationship to `zero`
287
+
288
+ `zero-pi` is the pi-specific layer of the **[zero](https://github.com/gonzalonicolasr/zero)**
289
+ integrator. The `zero` CLI installs this layer onto pi (bootstrapping pi.dev
290
+ itself when it is missing) and writes the per-phase model configuration. You
291
+ can also install `zero-pi` directly with `pi install npm:@gonrocca/zero-pi` if
292
+ you only want the pi layer.
293
+
294
+ ## License
295
+
296
+ MIT © Gonzalo Rocca