@gonrocca/zero-pi 0.1.55 → 0.1.56
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 +1 -0
- package/extensions/zero-banner.ts +38 -20
- package/extensions/zero-statusline.ts +16 -15
- package/package.json +1 -1
- package/themes/zero-sunset.json +79 -0
package/README.md
CHANGED
|
@@ -86,6 +86,7 @@ into `/forge` for you.
|
|
|
86
86
|
| **Windows tree-kill** | Aborting a turn kills the whole process tree — no orphaned `claude`. |
|
|
87
87
|
| **Skill auto-learning** | Distills reusable skills from substantial tasks and surfaces them later. |
|
|
88
88
|
| **`zero-sdd` theme** | A dark, high-contrast pi theme tuned for SDD work. |
|
|
89
|
+
| **`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`. |
|
|
89
90
|
|
|
90
91
|
## ⌨️ Commands
|
|
91
92
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// zero-pi — static ZERO SDD startup banner.
|
|
2
2
|
//
|
|
3
3
|
// Renders the ZERO wordmark ONCE, at extension load, as an "ANSI Shadow" 3D
|
|
4
|
-
// block in
|
|
5
|
-
//
|
|
4
|
+
// block in a sunset gradient — gold at the lit top edge melting down through
|
|
5
|
+
// coral and magenta to a ceroclawd-violet base, with dark shadow strokes and
|
|
6
|
+
// a cast shadow for depth.
|
|
6
7
|
//
|
|
7
8
|
// It writes a single block to stdout before pi's UI takes over. There is
|
|
8
9
|
// deliberately NO setHeader and NO animation timer: an animated header that
|
|
@@ -29,14 +30,23 @@ const FONT: Record<string, string[]> = {
|
|
|
29
30
|
" ": [" ", " ", " ", " ", " ", " "],
|
|
30
31
|
};
|
|
31
32
|
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
// Sunset palette — a warm sky gradient (gold → peach → coral → rose → magenta
|
|
34
|
+
// → violet) for the letter faces, plus glow, shadow and darkness. The violet
|
|
35
|
+
// base keeps the ZERO wordmark ending on the ceroclawd brand colour.
|
|
36
|
+
const SKY: RGB[] = [
|
|
37
|
+
[255, 214, 130], // gold
|
|
38
|
+
[255, 168, 99], // peach
|
|
39
|
+
[255, 124, 92], // coral
|
|
40
|
+
[255, 92, 122], // rose
|
|
41
|
+
[214, 74, 140], // magenta
|
|
42
|
+
[142, 59, 158], // violet
|
|
43
|
+
];
|
|
44
|
+
const PEAK: RGB = [255, 244, 224];
|
|
45
|
+
const SHADOW: RGB = [46, 22, 54];
|
|
46
|
+
const INK: RGB = [22, 12, 30];
|
|
47
|
+
const CORAL: RGB = [255, 124, 92];
|
|
48
|
+
const PEACH: RGB = [255, 168, 99];
|
|
49
|
+
const MUTED: RGB = [150, 120, 130];
|
|
40
50
|
|
|
41
51
|
const ANSI_RE = /\x1b\[[0-9;]*m/g;
|
|
42
52
|
|
|
@@ -57,6 +67,14 @@ function mix(a: RGB, b: RGB, t: number): RGB {
|
|
|
57
67
|
];
|
|
58
68
|
}
|
|
59
69
|
|
|
70
|
+
/** Sample a multi-stop colour ramp at t∈[0,1] — the sunset sky, top to base. */
|
|
71
|
+
function ramp(stops: RGB[], t: number): RGB {
|
|
72
|
+
const k = Math.max(0, Math.min(1, t));
|
|
73
|
+
const seg = k * (stops.length - 1);
|
|
74
|
+
const i = Math.min(stops.length - 2, Math.floor(seg));
|
|
75
|
+
return mix(stops[i], stops[i + 1], seg - i);
|
|
76
|
+
}
|
|
77
|
+
|
|
60
78
|
/** Printable width of a string, ignoring ANSI colour escapes. */
|
|
61
79
|
export function visibleWidth(text: string): number {
|
|
62
80
|
return text.replace(ANSI_RE, "").length;
|
|
@@ -76,17 +94,17 @@ function matrixFor(text: string): { rows: string[]; width: number } {
|
|
|
76
94
|
return { rows, width: rows[0]?.length ?? 0 };
|
|
77
95
|
}
|
|
78
96
|
|
|
79
|
-
/** Front-face colour:
|
|
97
|
+
/** Front-face colour: sunset vertical gradient with a lit top edge. */
|
|
80
98
|
function faceColor(row: number, topEdge: boolean): RGB {
|
|
81
|
-
const vt = Math.pow(row / (ROWS - 1), 0.
|
|
82
|
-
const base =
|
|
83
|
-
return topEdge ? mix(base, PEAK, 0.
|
|
99
|
+
const vt = Math.pow(row / (ROWS - 1), 0.82);
|
|
100
|
+
const base = ramp(SKY, vt);
|
|
101
|
+
return topEdge ? mix(base, PEAK, 0.55) : base;
|
|
84
102
|
}
|
|
85
103
|
|
|
86
104
|
/** Extrusion side: a darker, shaded version of the face it belongs to. */
|
|
87
105
|
function sideColor(row: number): RGB {
|
|
88
|
-
const vt = Math.pow(row / (ROWS - 1), 0.
|
|
89
|
-
return mix(
|
|
106
|
+
const vt = Math.pow(row / (ROWS - 1), 0.82);
|
|
107
|
+
return mix(ramp(SKY, vt), SHADOW, 0.62);
|
|
90
108
|
}
|
|
91
109
|
|
|
92
110
|
function renderLogo(width: number): string[] {
|
|
@@ -114,13 +132,13 @@ function renderLogo(width: number): string[] {
|
|
|
114
132
|
return lines;
|
|
115
133
|
}
|
|
116
134
|
|
|
117
|
-
/** A thin
|
|
135
|
+
/** A thin sunset rule, brightest in the middle. */
|
|
118
136
|
function ornament(width: number): string {
|
|
119
137
|
const length = Math.min(46, Math.max(22, Math.floor(width * 0.5)));
|
|
120
138
|
let line = "";
|
|
121
139
|
for (let i = 0; i < length; i++) {
|
|
122
140
|
const t = i / Math.max(1, length - 1);
|
|
123
|
-
line += fg(mix(
|
|
141
|
+
line += fg(mix(CORAL, PEACH, Math.sin(t * Math.PI)), "─");
|
|
124
142
|
}
|
|
125
143
|
return center(line, width);
|
|
126
144
|
}
|
|
@@ -136,9 +154,9 @@ function ornament(width: number): string {
|
|
|
136
154
|
*/
|
|
137
155
|
export function bannerBlock(width: number): string[] {
|
|
138
156
|
if (width < 64) {
|
|
139
|
-
return [center(fg(
|
|
157
|
+
return [center(fg(PEACH, "ZERO SDD"), width), center(fg(MUTED, "pi.dev · spec-driven work"), width)];
|
|
140
158
|
}
|
|
141
|
-
const tag = fg(
|
|
159
|
+
const tag = fg(PEACH, "ZERO SDD") + fg(MUTED, " explore → plan → build → veredicto");
|
|
142
160
|
return [ornament(width), ...renderLogo(width), center(tag, width), ornament(width)];
|
|
143
161
|
}
|
|
144
162
|
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
//
|
|
5
5
|
// claude-opus-4-7 · tok ↑12.3K ↓4.1K · diff +50/-12 · ctx 45% · master · www.ceroclawd.com
|
|
6
6
|
//
|
|
7
|
-
// Themed: model
|
|
8
|
-
// by load, branch steel, brand
|
|
7
|
+
// Themed (sunset): model coral, tokens gold/peach, diff mint/rose, ctx
|
|
8
|
+
// mint→amber→rose by load, branch steel, brand orchid. Pure 24-bit ANSI.
|
|
9
9
|
//
|
|
10
10
|
// Refreshes on `session_start`, `model_select`, `message_update`
|
|
11
11
|
// (accumulates tokens), and `tool_execution_end` (re-reads git, since tools
|
|
@@ -17,17 +17,18 @@ import { promisify } from "node:util";
|
|
|
17
17
|
|
|
18
18
|
const execAsync = promisify(exec);
|
|
19
19
|
|
|
20
|
-
// ─── Color palette (matches the zero-
|
|
20
|
+
// ─── Color palette (matches the zero-sunset theme `vars`) ─────────────────────
|
|
21
21
|
|
|
22
22
|
type RGB = [number, number, number];
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
23
|
+
const CORAL: RGB = [255, 124, 92]; // model
|
|
24
|
+
const GOLD: RGB = [255, 214, 130]; // tokens in
|
|
25
|
+
const PEACH: RGB = [255, 168, 99]; // tokens out
|
|
26
|
+
const ORCHID: RGB = [176, 106, 179]; // brand
|
|
27
|
+
const MINT: RGB = [79, 221, 171]; // diff added / ctx ok (semantic)
|
|
28
|
+
const AMBER: RGB = [238, 190, 92]; // ctx mid (semantic)
|
|
29
|
+
const ROSE: RGB = [255, 106, 122]; // diff removed / ctx hot (semantic)
|
|
30
|
+
const STEEL: RGB = [176, 152, 142]; // branch (warm gray)
|
|
31
|
+
const DIM: RGB = [120, 104, 98]; // labels / separators (warm gray)
|
|
31
32
|
|
|
32
33
|
function fg([r, g, b]: RGB, text: string): string {
|
|
33
34
|
return `\x1b[38;2;${r};${g};${b}m${text}\x1b[0m`;
|
|
@@ -78,11 +79,11 @@ const SEP = fg(DIM, " · ");
|
|
|
78
79
|
export function composeStatusline(p: StatuslineParts): string {
|
|
79
80
|
const parts: string[] = [];
|
|
80
81
|
|
|
81
|
-
if (p.model) parts.push(fg(
|
|
82
|
+
if (p.model) parts.push(fg(CORAL, p.model));
|
|
82
83
|
|
|
83
84
|
if (p.tokensIn != null || p.tokensOut != null) {
|
|
84
|
-
const inS = fg(
|
|
85
|
-
const outS = fg(
|
|
85
|
+
const inS = fg(GOLD, `↑${formatTokenCount(p.tokensIn ?? 0)}`);
|
|
86
|
+
const outS = fg(PEACH, `↓${formatTokenCount(p.tokensOut ?? 0)}`);
|
|
86
87
|
parts.push(`${fg(DIM, "tok")} ${inS} ${outS}`);
|
|
87
88
|
}
|
|
88
89
|
|
|
@@ -98,7 +99,7 @@ export function composeStatusline(p: StatuslineParts): string {
|
|
|
98
99
|
|
|
99
100
|
if (p.branch) parts.push(fg(STEEL, p.branch));
|
|
100
101
|
|
|
101
|
-
if (p.brand) parts.push(fg(
|
|
102
|
+
if (p.brand) parts.push(fg(ORCHID, p.brand));
|
|
102
103
|
|
|
103
104
|
return parts.join(SEP);
|
|
104
105
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gonrocca/zero-pi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.56",
|
|
4
4
|
"description": "zero-pi — an installable layer for pi (pi.dev): the zero spec-driven development workflow (explore → plan → build → veredicto) with per-phase model autotune and token-efficient batched builds. Adds capability to pi without modifying pi.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
|
+
"name": "zero-sunset",
|
|
4
|
+
"vars": {
|
|
5
|
+
"gold": "#ffd682",
|
|
6
|
+
"peach": "#ffa863",
|
|
7
|
+
"coral": "#ff7c5c",
|
|
8
|
+
"rose": "#ff5c7a",
|
|
9
|
+
"magenta": "#d64a8c",
|
|
10
|
+
"orchid": "#b06ab3",
|
|
11
|
+
"sky": "#6db8e6",
|
|
12
|
+
"mint": "#5fd6a0",
|
|
13
|
+
"amber": "#eebe5c",
|
|
14
|
+
"steel": "#b0978f",
|
|
15
|
+
"dimSteel": "#7d6a64",
|
|
16
|
+
"panel": "#1c1117",
|
|
17
|
+
"selected": "#3a2230",
|
|
18
|
+
"okPanel": "#152318",
|
|
19
|
+
"errPanel": "#2e1518"
|
|
20
|
+
},
|
|
21
|
+
"colors": {
|
|
22
|
+
"accent": "coral",
|
|
23
|
+
"border": "orchid",
|
|
24
|
+
"borderAccent": "gold",
|
|
25
|
+
"borderMuted": "dimSteel",
|
|
26
|
+
"success": "mint",
|
|
27
|
+
"error": "rose",
|
|
28
|
+
"warning": "amber",
|
|
29
|
+
"muted": "steel",
|
|
30
|
+
"dim": "dimSteel",
|
|
31
|
+
"text": "",
|
|
32
|
+
"thinkingText": "steel",
|
|
33
|
+
"selectedBg": "selected",
|
|
34
|
+
"userMessageBg": "panel",
|
|
35
|
+
"userMessageText": "coral",
|
|
36
|
+
"customMessageBg": "panel",
|
|
37
|
+
"customMessageText": "",
|
|
38
|
+
"customMessageLabel": "gold",
|
|
39
|
+
"toolPendingBg": "panel",
|
|
40
|
+
"toolSuccessBg": "okPanel",
|
|
41
|
+
"toolErrorBg": "errPanel",
|
|
42
|
+
"toolTitle": "peach",
|
|
43
|
+
"toolOutput": "steel",
|
|
44
|
+
"mdHeading": "gold",
|
|
45
|
+
"mdLink": "peach",
|
|
46
|
+
"mdLinkUrl": "dimSteel",
|
|
47
|
+
"mdCode": "mint",
|
|
48
|
+
"mdCodeBlock": "mint",
|
|
49
|
+
"mdCodeBlockBorder": "orchid",
|
|
50
|
+
"mdQuote": "steel",
|
|
51
|
+
"mdQuoteBorder": "dimSteel",
|
|
52
|
+
"mdHr": "dimSteel",
|
|
53
|
+
"mdListBullet": "gold",
|
|
54
|
+
"toolDiffAdded": "mint",
|
|
55
|
+
"toolDiffRemoved": "rose",
|
|
56
|
+
"toolDiffContext": "steel",
|
|
57
|
+
"syntaxComment": "dimSteel",
|
|
58
|
+
"syntaxKeyword": "magenta",
|
|
59
|
+
"syntaxFunction": "peach",
|
|
60
|
+
"syntaxVariable": "gold",
|
|
61
|
+
"syntaxString": "mint",
|
|
62
|
+
"syntaxNumber": "rose",
|
|
63
|
+
"syntaxType": "sky",
|
|
64
|
+
"syntaxOperator": "coral",
|
|
65
|
+
"syntaxPunctuation": "steel",
|
|
66
|
+
"thinkingOff": "dimSteel",
|
|
67
|
+
"thinkingMinimal": "steel",
|
|
68
|
+
"thinkingLow": "sky",
|
|
69
|
+
"thinkingMedium": "peach",
|
|
70
|
+
"thinkingHigh": "coral",
|
|
71
|
+
"thinkingXhigh": "rose",
|
|
72
|
+
"bashMode": "gold"
|
|
73
|
+
},
|
|
74
|
+
"export": {
|
|
75
|
+
"pageBg": "#160e13",
|
|
76
|
+
"cardBg": "#1c1117",
|
|
77
|
+
"infoBg": "#241620"
|
|
78
|
+
}
|
|
79
|
+
}
|