@gonrocca/zero-pi 0.1.20 → 0.1.21

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.
@@ -157,7 +157,7 @@ function evaluateAndTune(ctx: PiSessionContext): void {
157
157
  if (data === null) {
158
158
  // Absent or unparseable `zero.json` — no profile to safely tune. Skip with
159
159
  // a single non-blocking warning; never synthesize a `models` map (AC 6.4).
160
- notify("zero autotune: ~/.pi/zero.json missing or unreadableskipping", "warning");
160
+ notify("zero autotune: ~/.pi/zero.json falta o no se puede leer se omite", "warning");
161
161
  return;
162
162
  }
163
163
 
@@ -213,7 +213,7 @@ function evaluateAndTune(ctx: PiSessionContext): void {
213
213
  );
214
214
  for (const adj of pending) {
215
215
  notify(
216
- `zero autotune suggests: ${adj.phase} → ${adj.to} — run /zero-models to apply`,
216
+ `zero autotune sugiere: ${adj.phase} → ${adj.to} — corré /zero-models para aplicar`,
217
217
  "info",
218
218
  );
219
219
  }
@@ -526,7 +526,7 @@ export function decideAdjustments(
526
526
  if (to === null) continue; // already at top tier, or untierable
527
527
 
528
528
  const blame = phase === "build" ? "corregir" : "replantear";
529
- const reason = `avg ${measure.toFixed(1)} ${blame}/run over ${stat.v2Samples} v2 runs`;
529
+ const reason = `prom ${measure.toFixed(1)} ${blame}/run en ${stat.v2Samples} runs v2`;
530
530
 
531
531
  adjustments.push({ phase, from: currentModel, to, reason });
532
532
  }
@@ -368,21 +368,21 @@ export default function register(pi?: PiAPI): void {
368
368
 
369
369
  try {
370
370
  const path = writeFromContext(ctx, reason);
371
- if (path) notify(ctx, `zero resume written: ${path}`, "info");
371
+ if (path) notify(ctx, `zero: resumen guardado en ${path}`, "info");
372
372
  } catch (err) {
373
- notify(ctx, `zero resume failed: ${err instanceof Error ? err.message : String(err)}`, "warning");
373
+ notify(ctx, `zero: falló el resumen — ${err instanceof Error ? err.message : String(err)}`, "warning");
374
374
  }
375
375
  });
376
376
  }
377
377
 
378
378
  if (typeof pi.registerCommand === "function") {
379
379
  pi.registerCommand("zero-resume", {
380
- description: "Write .pi/zero-resume.md with restore command and conversation tail",
380
+ description: "Escribe .pi/zero-resume.md con el comando de restauración y el final de la conversación",
381
381
  handler: async (_args, ctx) => {
382
382
  try {
383
383
  const path = writeFromContext(ctx, "manual");
384
384
  if (!path) {
385
- notify(ctx, "zero-resume: no persisted session context found", "warning");
385
+ notify(ctx, "zero-resume: no hay contexto de sesión persistido", "warning");
386
386
  return;
387
387
  }
388
388
  const command = sessionFile(ctx)
@@ -390,7 +390,7 @@ export default function register(pi?: PiAPI): void {
390
390
  : sessionId(ctx)
391
391
  ? `pi --session ${sessionId(ctx)}`
392
392
  : "pi --resume";
393
- notify(ctx, `zero-resume: wrote ${path}\nrestore: ${command}`, "info");
393
+ notify(ctx, `zero-resume: escrito ${path}\nrestaurar: ${command}`, "info");
394
394
  } catch (err) {
395
395
  notify(ctx, `zero-resume: ${err instanceof Error ? err.message : String(err)}`, "error");
396
396
  }
@@ -121,12 +121,12 @@ function renderSyncReport(slug: string, date: string, summary: MergeSummary): st
121
121
  /** Render the human-facing one-shot report of a `MergeSummary`. */
122
122
  function describeSummary(summary: MergeSummary): string {
123
123
  const lines: string[] = [];
124
- if (summary.added.length > 0) lines.push(` added: ${summary.added.join(", ")}`);
124
+ if (summary.added.length > 0) lines.push(` agregados: ${summary.added.join(", ")}`);
125
125
  if (summary.modified.length > 0) {
126
- lines.push(` modified: ${summary.modified.join(", ")} (replaces existing spec text)`);
126
+ lines.push(` modificados: ${summary.modified.join(", ")} (reemplaza el texto de spec existente)`);
127
127
  }
128
128
  if (summary.removed.length > 0) {
129
- lines.push(` removed: ${summary.removed.join(", ")} (deletes from the store)`);
129
+ lines.push(` eliminados: ${summary.removed.join(", ")} (borra del store)`);
130
130
  }
131
131
  return lines.join("\n");
132
132
  }
@@ -168,8 +168,8 @@ function runSync(args: string, ctx: PiCommandContext): void {
168
168
  const slug = resolveSlug(args);
169
169
  if (slug === null) {
170
170
  notify(
171
- "zero-sync: no run slug given and no single sync candidate found — " +
172
- "run /zero-sync <slug> (the slug of the run's .sdd/<slug>/ directory)",
171
+ "zero-sync: no se dio slug de run y no hay un único candidato — " +
172
+ "corré /zero-sync <slug> (el slug del directorio .sdd/<slug>/ del run)",
173
173
  "warning",
174
174
  );
175
175
  return;
@@ -181,7 +181,7 @@ function runSync(args: string, ctx: PiCommandContext): void {
181
181
  // A legacy run produced no delta `spec.md` — nothing to sync. This is not
182
182
  // an error: legacy runs finish in legacy mode (additive design).
183
183
  notify(
184
- `zero-sync: ${deltaPath} not foundthis run produced no delta spec.md, nothing to sync`,
184
+ `zero-sync: ${deltaPath} no existeeste run no produjo un spec.md delta, nada para sincronizar`,
185
185
  "warning",
186
186
  );
187
187
  return;
@@ -190,7 +190,7 @@ function runSync(args: string, ctx: PiCommandContext): void {
190
190
  // An empty delta (no blocks in any section) is valid — report and stop
191
191
  // before touching the store.
192
192
  if (isEmptyDelta(parseDelta(deltaText))) {
193
- notify(`zero-sync: empty delta in ${deltaPath} — nothing to sync, store left untouched`, "info");
193
+ notify(`zero-sync: delta vacío en ${deltaPath} — nada para sincronizar, store sin cambios`, "info");
194
194
  return;
195
195
  }
196
196
 
@@ -204,7 +204,7 @@ function runSync(args: string, ctx: PiCommandContext): void {
204
204
  // the store is flagged out of sync for a manual fix.
205
205
  const detail = result.errors.map((e) => ` - [${e.kind}] ${e.message}`).join("\n");
206
206
  notify(
207
- `zero-sync: store NOT updatedthe delta has guardrail errors:\n${detail}`,
207
+ `zero-sync: store NO actualizadoel delta tiene errores de guardrail:\n${detail}`,
208
208
  "error",
209
209
  );
210
210
  return;
@@ -219,7 +219,7 @@ function runSync(args: string, ctx: PiCommandContext): void {
219
219
  renameSync(tmp, STORE_FILE);
220
220
  } catch (err) {
221
221
  notify(
222
- `zero-sync: failed to write the store at ${STORE_FILE}: ${
222
+ `zero-sync: no se pudo escribir el store en ${STORE_FILE}: ${
223
223
  err instanceof Error ? err.message : String(err)
224
224
  }`,
225
225
  "error",
@@ -240,16 +240,16 @@ function runSync(args: string, ctx: PiCommandContext): void {
240
240
  if (existsSync(src)) copyFileSync(src, join(archiveDir, name));
241
241
  }
242
242
  writeFileSync(join(archiveDir, "sync.md"), renderSyncReport(slug, date, result.summary), "utf8");
243
- archiveNote = `archived to ${archiveDir}`;
243
+ archiveNote = `archivado en ${archiveDir}`;
244
244
  } catch (err) {
245
- archiveNote = `WARNING: store updated but archive step failed: ${
245
+ archiveNote = `ATENCIÓN: store actualizado pero falló el archivado: ${
246
246
  err instanceof Error ? err.message : String(err)
247
247
  }`;
248
248
  }
249
249
 
250
250
  const detail = describeSummary(result.summary);
251
251
  notify(
252
- `zero-sync: canonical store updated (${STORE_FILE})\n${detail}\n${archiveNote}`,
252
+ `zero-sync: store canónico actualizado (${STORE_FILE})\n${detail}\n${archiveNote}`,
253
253
  "info",
254
254
  );
255
255
  }
@@ -266,7 +266,7 @@ export default function register(pi?: PiExtensionAPI): void {
266
266
 
267
267
  pi.registerCommand("zero-sync", {
268
268
  description:
269
- "Fold a /forge run's delta spec.md into the canonical .sdd/specs/ store — /zero-sync <slug>",
269
+ "Integra el spec.md delta de un run /forge al store canónico .sdd/specs/ — /zero-sync <slug>",
270
270
  handler: (args: string, ctx: PiCommandContext): void => {
271
271
  try {
272
272
  if (!ctx || !ctx.ui || typeof ctx.ui.notify !== "function") return;
@@ -257,7 +257,7 @@ export default function register(pi?: PiExtensionAPI): void {
257
257
 
258
258
  pi.registerCommand("zero-models", {
259
259
  description:
260
- "Show or set the per-phase SDD models — /zero-models [<phase>=[<provider>/]<model>]",
260
+ "Muestra o cambia los modelos SDD por fase — /zero-models [<fase>=[<provider>/]<modelo>]",
261
261
  handler: async (args: string, ctx: PiCommandContext): Promise<void> => {
262
262
  try {
263
263
  const data = readZeroJson();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gonrocca/zero-pi",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "zero-pi — an installable layer for pi (pi.dev): the zero spec-driven development workflow, skill auto-learning, and an animated ZERO startup banner. Adds capability to pi without modifying pi.",
5
5
  "type": "module",
6
6
  "keywords": [
package/prompts/forge.md CHANGED
@@ -14,10 +14,11 @@ claim success unless veredicto returned `pasa`.
14
14
  If the request begins with `--continue [slug]`, resume that unfinished run from
15
15
  its `.sdd/<slug>/` artifacts instead of starting fresh.
16
16
 
17
- **Work quietly.** Emit one short status line per phase (`explore → …`, the
18
- verdict, the round count) no step-by-step narration, no reasoning out loud,
19
- and do not echo tool output or agent listings back into the chat. The four
17
+ **Output and language.** Follow the orchestrator's `## Language Boundary` and
18
+ `## Output Contract`: user-facing chat in Spanish (natural Rioplatense voseo),
19
+ the bounded per-phase summary, no raw tool output, no agent listings, no
20
+ step-by-step narration — progress and the final verdict, never a log. The four
20
21
  `zero-*` sub-agents already exist; delegate to them directly without running a
21
- `subagent` listing. The user wants progress and the final verdict, not a log.
22
+ `subagent` listing.
22
23
 
23
24
  Feature request: $ARGUMENTS
@@ -112,30 +112,84 @@ start of a run and delegate each phase's sub-agent to its configured
112
112
  provider + model. When the file is absent, a phase is missing, or its provider
113
113
  entry is empty, fall back to the session's default model.
114
114
 
115
+ ## Language Boundary
116
+
117
+ A zero SDD run has two language surfaces — keep them apart.
118
+
119
+ - **User-facing chat — Spanish.** Every message you print to the user is in
120
+ Spanish, in natural Rioplatense voseo: phase status lines, phase summaries,
121
+ the execution-mode question, the approval question, and the final verdict.
122
+ This holds in interactive and automatic mode alike.
123
+ - **Sub-agent briefs — English.** Write the briefs you hand to the `zero-*`
124
+ sub-agents in English, and expect their result envelopes back in English.
125
+ English keeps token use down and gives the executors one consistent
126
+ operating language. You translate and synthesize into Spanish for the user;
127
+ the sub-agents never address the user directly.
128
+ - **Fixed identifiers — verbatim.** Never translate identifiers. Keep verdict
129
+ values (`pasa`, `corregir`, `replantear`, `cap-reached`), feature slugs,
130
+ file and directory paths, model ids, and command names (`/forge`,
131
+ `/zero-sync`) exactly as they are, even inside Spanish text.
132
+
133
+ ## Output Contract
134
+
135
+ What you print to the user is bounded. A zero SDD run reads as a short, calm
136
+ progress stream — not a log.
137
+
138
+ **Phase start.** When a phase begins, emit one short Spanish line with: the
139
+ phase name, the model and provider it runs on — read from `~/.pi/zero.json` as
140
+ `<modelo> (<provider>)`, or the session's default model when the file has no
141
+ entry for that phase — and a brief gloss of what the phase does. Inside the
142
+ build/veredicto loop, also include the round number. One line per phase:
143
+
144
+ - `Fase explore · <modelo> (<provider>) — exploro el código y junto hallazgos`
145
+ - `Fase plan · <modelo> (<provider>) — escribo requisitos, diseño y tareas`
146
+ - `Fase build · ronda <n> · <modelo> (<provider>) — implemento las tareas y corro los tests`
147
+ - `Fase veredicto · ronda <n> · <modelo> (<provider>) — reviso la build y doy el veredicto`
148
+
149
+ **Phase summary.** When a phase finishes, emit a bounded summary — never
150
+ free-form prose:
151
+
152
+ - `Estado:` one line — the phase and its outcome (for veredicto, the verdict).
153
+ - `Resumen:` at most two lines of what the phase produced, user-relevant only.
154
+ - `Artefactos:` the `.sdd/<slug>/` path(s) the phase wrote — the path, never
155
+ the file contents.
156
+ - `Siguiente:` the next phase, or that the run is ending.
157
+
158
+ When summarising the plan phase, also report the run's total changed-lines
159
+ forecast from the `## Review Workload` section of `tasks.md`, naming each
160
+ over-budget exception with its reason — or stating that every task is within
161
+ the per-task budget.
162
+
163
+ **Never noise.** Do not echo raw tool output, file dumps, full sub-agent result
164
+ envelopes, or a sub-agent discovery/listing into the chat, and do not narrate
165
+ your internal reasoning. Reference an artifact by its path; never paste its
166
+ contents. Summarize each sub-agent's result in one short message — synthesize,
167
+ do not relay.
168
+
169
+ **Approval question.** In interactive mode, after the phase summary, ask a
170
+ single Spanish question — `¿Continuamos?` — never a bilingual one. Accept
171
+ continue, stop, or feedback.
172
+
173
+ **Run end.** When the run ends, state the final verdict and say plainly whether
174
+ the result is **verificado** (a `pasa` verdict) or **no verificado** (the
175
+ iteration cap reached without `pasa`). Never claim success without a `pasa`.
176
+
177
+ **Always visible.** Trimming noise must never make the run look frozen: the
178
+ phase name is always stated at phase start, and the round number is always
179
+ stated inside the build/veredicto loop. A phase that runs long keeps showing
180
+ progress through the working indicator — never go silent for a long stretch.
181
+
115
182
  ## Execution mode
116
183
 
117
- At the start of a run, ask the user which mode they want:
184
+ At the start of a run, ask the user — in Spanish — which mode they want:
118
185
 
119
- - **interactive** (default): after each phase, show a concise summary of what
120
- the phase produced and what the next phase will do, then ask
121
- "¿Continuamos? / Continue?" before proceeding. Accept continue, stop, or
122
- feedback to adjust.
123
- - **automatic**: run all phases back to back without pausing; show the final
124
- result only.
186
+ - **interactive** (default): pause after each phase. Emit the phase summary
187
+ defined in the Output Contract, then ask `¿Continuamos?` before proceeding.
188
+ - **automatic**: run all phases back to back without pausing; show only the
189
+ final result.
125
190
 
126
191
  Cache the mode for the run.
127
192
 
128
- When summarising the plan phase, report the run's total changed-lines forecast
129
- from the `## Review Workload` section of `tasks.md`, name each over-budget
130
- exception with its reason, and — when there are no exceptions — state that all
131
- tasks are within the per-task budget.
132
-
133
- ## Visibility
134
-
135
- While a phase runs, keep the user informed of progress — never run silently for
136
- a long stretch. The user must always be able to tell which phase and round the
137
- run is in.
138
-
139
193
  ## Run memory
140
194
 
141
195
  zero runs improve each other. The pipeline reads from and writes to Cortex —
@@ -19,4 +19,9 @@ change within the plan's scope — do not expand it on your own initiative.
19
19
  Run the test suite and make it pass before reporting the phase complete. Report
20
20
  what you changed so the veredicto phase has something concrete to review.
21
21
 
22
- **Work quietly.** Report only your phase's outcome — concise findings, plan, result, or verdict. No step-by-step narration, no reasoning out loud, no echoing tool output.
22
+ **Return contract.** Return a concise result envelope to the orchestrator: your
23
+ phase's outcome (findings, plan, build result, or verdict with its concrete
24
+ reasoning) and the `.sdd/<slug>/` artifact path(s) you touched. No step-by-step
25
+ narration, no reasoning out loud, no echoed tool output, and no `subagent`
26
+ discovery or listing step. Write the envelope in English — the orchestrator
27
+ translates and synthesizes for the user; you never address the user directly.
@@ -21,4 +21,9 @@ If the orchestrator includes prior-run memory in your brief, use it: past runs
21
21
  record what already broke in this code and which plans were sent back. Fold the
22
22
  relevant points into the findings under a "Prior runs" heading.
23
23
 
24
- **Work quietly.** Report only your phase's outcome — concise findings, plan, result, or verdict. No step-by-step narration, no reasoning out loud, no echoing tool output.
24
+ **Return contract.** Return a concise result envelope to the orchestrator: your
25
+ phase's outcome (findings, plan, build result, or verdict with its concrete
26
+ reasoning) and the `.sdd/<slug>/` artifact path(s) you touched. No step-by-step
27
+ narration, no reasoning out loud, no echoed tool output, and no `subagent`
28
+ discovery or listing step. Write the envelope in English — the orchestrator
29
+ translates and synthesizes for the user; you never address the user directly.
@@ -81,4 +81,9 @@ means the same number on every run.
81
81
  per-task estimates, and the over-budget exceptions list — state "none" when
82
82
  there are no exceptions.
83
83
 
84
- **Work quietly.** Report only your phase's outcome — concise findings, plan, result, or verdict. No step-by-step narration, no reasoning out loud, no echoing tool output.
84
+ **Return contract.** Return a concise result envelope to the orchestrator: your
85
+ phase's outcome (findings, plan, build result, or verdict with its concrete
86
+ reasoning) and the `.sdd/<slug>/` artifact path(s) you touched. No step-by-step
87
+ narration, no reasoning out loud, no echoed tool output, and no `subagent`
88
+ discovery or listing step. Write the envelope in English — the orchestrator
89
+ translates and synthesizes for the user; you never address the user directly.
@@ -29,4 +29,9 @@ State the verdict's reasoning concretely — the specific defects for `corregir`
29
29
  the specific plan flaw for `replantear`. The orchestrator persists that
30
30
  reasoning to the run's memory trace, so future runs depend on it being precise.
31
31
 
32
- **Work quietly.** Report only your phase's outcome — concise findings, plan, result, or verdict. No step-by-step narration, no reasoning out loud, no echoing tool output.
32
+ **Return contract.** Return a concise result envelope to the orchestrator: your
33
+ phase's outcome (findings, plan, build result, or verdict with its concrete
34
+ reasoning) and the `.sdd/<slug>/` artifact path(s) you touched. No step-by-step
35
+ narration, no reasoning out loud, no echoed tool output, and no `subagent`
36
+ discovery or listing step. Write the envelope in English — the orchestrator
37
+ translates and synthesizes for the user; you never address the user directly.
@@ -35,7 +35,8 @@ the feature request. Pass that described work **verbatim** — do not rephrase,
35
35
  summarize, translate, or interpret it. The existing `/forge` workflow does the
36
36
  rest: an ordinary SDD run with all four phases (explore, plan, build,
37
37
  veredicto), the round cap, and the veredicto verdict, exactly as an explicit
38
- `/forge` invocation behaves.
38
+ `/forge` invocation behaves — including its Spanish, low-noise output, governed
39
+ by the orchestrator's `## Language Boundary` and `## Output Contract`.
39
40
 
40
41
  ## When NOT to route — be conservative
41
42