@gonrocca/zero-pi 0.1.21 → 0.1.22
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.
|
@@ -119,7 +119,12 @@ function colorForPiece(piece: string, row: number, rank: number, active: boolean
|
|
|
119
119
|
return lerpColor(base, COLORS.peak, heightWarmth * 0.18 + rankPulse);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
function paintMatrixLine(
|
|
122
|
+
function paintMatrixLine(
|
|
123
|
+
matrix: Matrix,
|
|
124
|
+
row: number,
|
|
125
|
+
visibleCells: number,
|
|
126
|
+
sparkles?: ReadonlySet<string>,
|
|
127
|
+
): string {
|
|
123
128
|
let out = "";
|
|
124
129
|
const line = matrix.rows[row] ?? "";
|
|
125
130
|
for (let col = 0; col < matrix.width; col++) {
|
|
@@ -128,16 +133,31 @@ function paintMatrixLine(matrix: Matrix, row: number, visibleCells: number): str
|
|
|
128
133
|
out += " ";
|
|
129
134
|
continue;
|
|
130
135
|
}
|
|
131
|
-
const
|
|
136
|
+
const key = `${row}:${col}`;
|
|
137
|
+
const rank = matrix.ranks.get(key) ?? Number.POSITIVE_INFINITY;
|
|
132
138
|
if (rank >= visibleCells) {
|
|
133
139
|
out += " ";
|
|
134
140
|
continue;
|
|
135
141
|
}
|
|
136
|
-
|
|
142
|
+
// A cell glints when it is the assembly's leading cell or when this
|
|
143
|
+
// sparkle frame picked it.
|
|
144
|
+
const glint = rank === visibleCells - 1 || (sparkles?.has(key) ?? false);
|
|
145
|
+
out += ansiFg(colorForPiece(piece, row, rank, glint), "[]");
|
|
137
146
|
}
|
|
138
147
|
return out;
|
|
139
148
|
}
|
|
140
149
|
|
|
150
|
+
/** Pick a handful of distinct settled cells to glint for one sparkle frame. */
|
|
151
|
+
function pickSparkles(matrix: Matrix, count: number, rand: () => number): Set<string> {
|
|
152
|
+
const keys = Array.from(matrix.ranks.keys());
|
|
153
|
+
const chosen = new Set<string>();
|
|
154
|
+
const target = Math.min(Math.max(0, count), keys.length);
|
|
155
|
+
for (let guard = 0; chosen.size < target && guard < target * 8; guard++) {
|
|
156
|
+
chosen.add(keys[Math.floor(rand() * keys.length)]);
|
|
157
|
+
}
|
|
158
|
+
return chosen;
|
|
159
|
+
}
|
|
160
|
+
|
|
141
161
|
interface OutStream {
|
|
142
162
|
write(chunk: string): unknown;
|
|
143
163
|
isTTY?: boolean;
|
|
@@ -178,6 +198,10 @@ export interface RenderOptions {
|
|
|
178
198
|
text?: string;
|
|
179
199
|
frames?: number;
|
|
180
200
|
frameMs?: number;
|
|
201
|
+
/** Number of post-settle sparkle frames (shimmer mode). `0` disables it. */
|
|
202
|
+
sparkleFrames?: number;
|
|
203
|
+
/** Delay between sparkle frames, in milliseconds. */
|
|
204
|
+
sparkleMs?: number;
|
|
181
205
|
stream?: OutStream;
|
|
182
206
|
}
|
|
183
207
|
|
|
@@ -201,6 +225,14 @@ export function renderBanner(options: RenderOptions = {}): void {
|
|
|
201
225
|
|
|
202
226
|
stream.write("\n" + Array.from({ length: ROWS }, () => "").join("\n") + "\n");
|
|
203
227
|
|
|
228
|
+
// Repaint the six rows in place; optionally with this frame's sparkle set.
|
|
229
|
+
const paintRows = (sparkles?: ReadonlySet<string>): void => {
|
|
230
|
+
stream.write(`\x1b[${ROWS}A\r`);
|
|
231
|
+
for (let r = 0; r < ROWS; r++) {
|
|
232
|
+
stream.write("\x1b[2K" + paintMatrixLine(matrix, r, matrix.totalCells, sparkles) + "\n");
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
|
|
204
236
|
if (mode === "shimmer") {
|
|
205
237
|
const frames = Math.max(2, options.frames ?? 42);
|
|
206
238
|
const frameMs = Math.max(1, options.frameMs ?? 18);
|
|
@@ -215,10 +247,21 @@ export function renderBanner(options: RenderOptions = {}): void {
|
|
|
215
247
|
}
|
|
216
248
|
}
|
|
217
249
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
250
|
+
// Settle on the completed wordmark.
|
|
251
|
+
paintRows();
|
|
252
|
+
|
|
253
|
+
// Sparkle pass — a few settled cells glint bright each frame, then a clean
|
|
254
|
+
// final settle. Shimmer only; `sparkleFrames: 0` disables it.
|
|
255
|
+
if (mode === "shimmer") {
|
|
256
|
+
const sparkleFrames = Math.max(0, options.sparkleFrames ?? 22);
|
|
257
|
+
const sparkleMs = Math.max(1, options.sparkleMs ?? 36);
|
|
258
|
+
for (let f = 0; f < sparkleFrames; f++) {
|
|
259
|
+
paintRows(pickSparkles(matrix, 3 + (f % 4), Math.random));
|
|
260
|
+
sleepSync(sparkleMs);
|
|
261
|
+
}
|
|
262
|
+
if (sparkleFrames > 0) paintRows();
|
|
221
263
|
}
|
|
264
|
+
|
|
222
265
|
stream.write("\n");
|
|
223
266
|
}
|
|
224
267
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gonrocca/zero-pi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.22",
|
|
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/orchestrator.md
CHANGED
|
@@ -166,6 +166,11 @@ your internal reasoning. Reference an artifact by its path; never paste its
|
|
|
166
166
|
contents. Summarize each sub-agent's result in one short message — synthesize,
|
|
167
167
|
do not relay.
|
|
168
168
|
|
|
169
|
+
**Formatting.** pi's chat shows a triple-backtick fenced code block with the
|
|
170
|
+
backticks rendered literally — never use one. Present commands, paths, and
|
|
171
|
+
snippets as plain lines indented two spaces, or inline with single backticks.
|
|
172
|
+
Keep the rest plain text; bold and single-backtick inline code render fine.
|
|
173
|
+
|
|
169
174
|
**Approval question.** In interactive mode, after the phase summary, ask a
|
|
170
175
|
single Spanish question — `¿Continuamos?` — never a bilingual one. Accept
|
|
171
176
|
continue, stop, or feedback.
|