@gonrocca/zero-pi 0.1.70 → 0.1.71
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/README.md +3 -0
- package/extensions/autotune.ts +50 -14
- package/extensions/zero-activity-panel.ts +11 -9
- package/extensions/zero-models.ts +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -124,6 +124,7 @@ into `/forge` for you.
|
|
|
124
124
|
| **`zero-sdd` theme** | A dark, high-contrast pi theme tuned for SDD work. |
|
|
125
125
|
| **`zero-sunset` theme** | A warm sunset variant — gold/coral/magenta accents over warm-dark panels, with one cool tone kept for syntax legibility. Activate with `/theme zero-sunset`. |
|
|
126
126
|
| **`zero-omp-neon` theme** | A high-contrast OMP-inspired neon theme with separated colour roles: cyan links/paths, gold titles, mint code/success, violet borders, and navy tool cards. Activate with `/theme zero-omp-neon`. |
|
|
127
|
+
| **ZERO theme pack** | Extra visual variants: `zero-sith`, `zero-saiyan`, `zero-matrix`, and `zero-cyberpunk`. Switch quickly with `/zero-theme sith|saiyan|matrix|cyberpunk`. |
|
|
127
128
|
|
|
128
129
|
## ⌨️ Commands
|
|
129
130
|
|
|
@@ -137,6 +138,7 @@ into `/forge` for you.
|
|
|
137
138
|
| `/zero-validate <slug>` | Validate proposal/spec/design/tasks artifacts, including task schema and per-domain specs. |
|
|
138
139
|
| `/zero-status` | Show each `.sdd/` run's artifact, sync, latest-verdict, and GitHub-link status. |
|
|
139
140
|
| `/zero-hud [compact\|minimal\|full\|ascii\|off\|on\|preview]` | Preview or switch the segmented ZERO footer for this pi session. Default preset: `compact`. |
|
|
141
|
+
| `/zero-theme [neon\|sunset\|sdd\|sith\|saiyan\|matrix\|cyberpunk]` | Switch between packaged ZERO theme variants without remembering full `zero-*` names. |
|
|
140
142
|
| `/zero-cost [<slug>]` | Report tokens (in/out/cache), USD cost, duration, and tool-count per SDD phase for a run — reads native pi session metas and project-local `.pi-subagents/artifacts`; `<slug>` for a specific run, no argument for the most recent. |
|
|
141
143
|
| `/zero-checkpoint [<slug>] [--json]` | Save `diff.patch`, `status.txt`, `head.txt`, `meta.json`, and a review-before-running `restore.sh` under `.sdd/<slug>/checkpoints/<id>/`. |
|
|
142
144
|
| `/zero-branch <slug>` | Create/reuse the configured SDD Git branch and persist `branch`/`baseBranch`. |
|
|
@@ -154,6 +156,7 @@ zero-pi ships several visual extensions. They are related, but each one owns a d
|
|
|
154
156
|
| ------- | ---- | ---------------- | ------- |
|
|
155
157
|
| **ZERO HUD** | `extensions/zero-hud.ts` | Footer/status line at the bottom | Persistent model/tokens/cost/diff/context/branch telemetry. |
|
|
156
158
|
| **Activity panel** | `extensions/zero-activity-panel.ts` | Widget above the prompt while work is running | Live `/forge` phase progress plus recent tool cards. |
|
|
159
|
+
| **Tool cards** | `extensions/zero-pretty-tool-cards.ts` | Each tool execution/result in chat | ZERO-styled bordered cards with status glyphs, title metadata, and padded content. |
|
|
157
160
|
| **Prompt box** | `extensions/zero-pretty-input-box.ts` | The input/editor box | OMP-like rounded box with ZERO chips and key hints. |
|
|
158
161
|
| **Code fences** | `extensions/zero-pretty-code-fences.ts` | Markdown code blocks in chat | Bordered panels with language badges instead of raw ```txt / ```json lines. |
|
|
159
162
|
| **Working phrases** | `extensions/working-phrases.ts` | Tiny loading row (`Procesando… (esc)`) | Rotating ZERO/SDD/Star Wars/DBZ phrases and themed spinner. |
|
package/extensions/autotune.ts
CHANGED
|
@@ -429,24 +429,55 @@ export function aggregate(records: RunRecord[]): Map<string, PhaseModelStat> {
|
|
|
429
429
|
// Model tier ladder
|
|
430
430
|
// ---------------------------------------------------------------------------
|
|
431
431
|
|
|
432
|
-
/** Three
|
|
432
|
+
/** Three tiers per model family, ordered cheap < balanced < flagship. */
|
|
433
433
|
const TIER = { haiku: 0, sonnet: 1, opus: 2 } as const;
|
|
434
434
|
|
|
435
435
|
/** A model's tier index, or `null` for an unrecognized (untierable) model. */
|
|
436
436
|
export type Tier = (typeof TIER)[keyof typeof TIER];
|
|
437
437
|
|
|
438
|
-
/**
|
|
439
|
-
*
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
438
|
+
/** Model families the tier ladder understands. Step-ups never cross families:
|
|
439
|
+
* a Codex/GPT phase steps up to a bigger GPT model, never to a Claude one. */
|
|
440
|
+
export type ModelFamily = "claude" | "gpt";
|
|
441
|
+
|
|
442
|
+
/** A single hardcoded representative model id per (family, tier), used as the
|
|
443
|
+
* fallback step-up target when the user has no known model at the next tier.
|
|
444
|
+
* GPT tiers map OpenAI's GPT‑5.6 family (2026‑07‑09): Luna (cost‑efficient) <
|
|
445
|
+
* Terra (balanced) < Sol (flagship). */
|
|
446
|
+
const TIER_REPRESENTATIVE: Record<ModelFamily, Record<Tier, string>> = {
|
|
447
|
+
claude: {
|
|
448
|
+
[TIER.haiku]: "claude-haiku-4-5",
|
|
449
|
+
[TIER.sonnet]: "claude-sonnet-4-6",
|
|
450
|
+
[TIER.opus]: "claude-opus-4-8",
|
|
451
|
+
},
|
|
452
|
+
gpt: {
|
|
453
|
+
[TIER.haiku]: "gpt-5.6-luna",
|
|
454
|
+
[TIER.sonnet]: "gpt-5.6-terra",
|
|
455
|
+
[TIER.opus]: "gpt-5.6-sol",
|
|
456
|
+
},
|
|
444
457
|
};
|
|
445
458
|
|
|
459
|
+
/** Match a GPT‑5.6 variant name as its own dash/dot separated segment, so
|
|
460
|
+
* `gpt-5.6-sol` matches but an unrelated id like `solar-pro` does not. */
|
|
461
|
+
function gptVariant(id: string, variant: string): boolean {
|
|
462
|
+
return new RegExp(`(^|[-._])${variant}($|[-._])`).test(id);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Classify a model id into its family, or `null` when unrecognized.
|
|
467
|
+
* GPT/Codex ids are recognized by the `gpt` or `codex` marker.
|
|
468
|
+
*/
|
|
469
|
+
export function familyOf(modelId: string): ModelFamily | null {
|
|
470
|
+
if (typeof modelId !== "string") return null;
|
|
471
|
+
const id = modelId.toLowerCase();
|
|
472
|
+
if (id.includes("claude") || id.includes("haiku") || id.includes("sonnet") || id.includes("opus")) return "claude";
|
|
473
|
+
if (id.includes("gpt") || id.includes("codex")) return "gpt";
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
|
|
446
477
|
/**
|
|
447
478
|
* Classify a model id into a tier by substring match — deliberate so future
|
|
448
|
-
* point releases (`claude-sonnet-4-7`, etc.) classify with no
|
|
449
|
-
* Returns `null` for any id
|
|
479
|
+
* point releases (`claude-sonnet-4-7`, `gpt-5.7-luna`, etc.) classify with no
|
|
480
|
+
* code change. Returns `null` for any id without a recognizable tier marker.
|
|
450
481
|
*/
|
|
451
482
|
export function tierOf(modelId: string): Tier | null {
|
|
452
483
|
if (typeof modelId !== "string") return null;
|
|
@@ -454,6 +485,9 @@ export function tierOf(modelId: string): Tier | null {
|
|
|
454
485
|
if (id.includes("haiku")) return TIER.haiku;
|
|
455
486
|
if (id.includes("sonnet")) return TIER.sonnet;
|
|
456
487
|
if (id.includes("opus")) return TIER.opus;
|
|
488
|
+
if (gptVariant(id, "luna")) return TIER.haiku;
|
|
489
|
+
if (gptVariant(id, "terra")) return TIER.sonnet;
|
|
490
|
+
if (gptVariant(id, "sol")) return TIER.opus;
|
|
457
491
|
return null;
|
|
458
492
|
}
|
|
459
493
|
|
|
@@ -467,22 +501,24 @@ export function tierOf(modelId: string): Tier | null {
|
|
|
467
501
|
* hardcoded representative for that tier. Never returns an arbitrary id, and
|
|
468
502
|
* never steps more than one tier.
|
|
469
503
|
*
|
|
470
|
-
* Returns `null` when `model` is already at
|
|
471
|
-
* untierable (an unrecognized model id).
|
|
504
|
+
* Returns `null` when `model` is already at the top tier (no higher tier) or
|
|
505
|
+
* is untierable (an unrecognized model id). Candidates are restricted to the
|
|
506
|
+
* same model family, so a Codex phase never steps up onto a Claude model.
|
|
472
507
|
*/
|
|
473
508
|
export function stepUp(model: string, knownModels: readonly string[]): string | null {
|
|
474
509
|
const tier = tierOf(model);
|
|
475
|
-
|
|
510
|
+
const family = familyOf(model);
|
|
511
|
+
if (tier === null || family === null) return null;
|
|
476
512
|
if (tier === TIER.opus) return null;
|
|
477
513
|
|
|
478
514
|
const nextTier = (tier + 1) as Tier;
|
|
479
515
|
|
|
480
516
|
const candidates = knownModels
|
|
481
|
-
.filter((m) => typeof m === "string" && tierOf(m) === nextTier)
|
|
517
|
+
.filter((m) => typeof m === "string" && tierOf(m) === nextTier && familyOf(m) === family)
|
|
482
518
|
.sort();
|
|
483
519
|
if (candidates.length > 0) return candidates[0];
|
|
484
520
|
|
|
485
|
-
return TIER_REPRESENTATIVE[nextTier];
|
|
521
|
+
return TIER_REPRESENTATIVE[family][nextTier];
|
|
486
522
|
}
|
|
487
523
|
|
|
488
524
|
// ---------------------------------------------------------------------------
|
|
@@ -165,7 +165,7 @@ function toolGlyph(state: ToolState): string {
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
export function renderActivityPanel(state: ActivityState): string[] {
|
|
168
|
-
if (!state.sddActive
|
|
168
|
+
if (!state.sddActive) return [];
|
|
169
169
|
const rule = (n: number) => color.coral("─".repeat(n));
|
|
170
170
|
const border = rule(72);
|
|
171
171
|
const header = `${color.coral("╭─")} ${color.gold("ZERO activity")} ${rule(54)}${color.coral("╮")}`;
|
|
@@ -232,13 +232,15 @@ export default function register(pi?: PiAPI): void {
|
|
|
232
232
|
const e = event as { toolCallId?: string; toolName?: string; args?: unknown };
|
|
233
233
|
const phase = e.toolName === "subagent" ? phaseFromSubagentArgs(e.args) : undefined;
|
|
234
234
|
if (phase) markPhaseActive(state, phase);
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
235
|
+
if (state.sddActive || phase) {
|
|
236
|
+
upsertTool(state, {
|
|
237
|
+
id: e.toolCallId ?? `${Date.now()}`,
|
|
238
|
+
name: e.toolName ?? "tool",
|
|
239
|
+
label: toolLabel(e.toolName ?? "tool", e.args),
|
|
240
|
+
state: "running",
|
|
241
|
+
});
|
|
242
|
+
draw();
|
|
243
|
+
}
|
|
242
244
|
});
|
|
243
245
|
|
|
244
246
|
pi.on("tool_execution_end", (event, ctx) => {
|
|
@@ -248,7 +250,7 @@ export default function register(pi?: PiAPI): void {
|
|
|
248
250
|
const idx = state.tools.findIndex((tool) => tool.id === id);
|
|
249
251
|
if (idx >= 0) state.tools[idx].state = e.isError ? "error" : "ok";
|
|
250
252
|
if (e.toolName === "subagent") finishActivePhase(state, Boolean(e.isError));
|
|
251
|
-
draw();
|
|
253
|
+
if (state.sddActive) draw();
|
|
252
254
|
});
|
|
253
255
|
|
|
254
256
|
pi.on("agent_end", (_event, ctx) => {
|
|
@@ -104,13 +104,17 @@ export const DEFAULT_THINKING: Record<Phase, ThinkingLevel> = {
|
|
|
104
104
|
veredicto: "xhigh",
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
-
/** Model list used only when pi's model registry is unavailable.
|
|
107
|
+
/** Model list used only when pi's model registry is unavailable. Includes
|
|
108
|
+
* OpenAI's GPT‑5.6 family (Sol/Terra/Luna, GA 2026‑07‑09) available via Codex. */
|
|
108
109
|
const FALLBACK_MODELS = [
|
|
109
110
|
"claude-opus-4-8",
|
|
110
111
|
"claude-opus-4-7",
|
|
111
112
|
"claude-opus-4-6",
|
|
112
113
|
"claude-sonnet-4-6",
|
|
113
114
|
"claude-haiku-4-5",
|
|
115
|
+
"gpt-5.6-sol",
|
|
116
|
+
"gpt-5.6-terra",
|
|
117
|
+
"gpt-5.6-luna",
|
|
114
118
|
];
|
|
115
119
|
|
|
116
120
|
/** Absolute path of pi's `zero.json` marker. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gonrocca/zero-pi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.71",
|
|
4
4
|
"description": "zero-pi — an installable layer for pi (pi.dev): the zero spec-driven development workflow (clarify → explore → plan → analyze → build → veredicto) with automatic clarify/analyze gates, per-phase model autotune, and token-efficient batched builds. Adds capability to pi without modifying pi.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|