@birdybeep/cli 0.8.2 → 0.8.3
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/dist/bin.cjs +196 -29
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-CZ4G735V.js → chunk-NSHPZ3RX.js} +197 -30
- package/dist/chunk-NSHPZ3RX.js.map +1 -0
- package/dist/index.cjs +196 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +1 -1
- package/package.json +7 -7
- package/dist/chunk-CZ4G735V.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -243,10 +243,164 @@ function surfaceRemedy(state, group) {
|
|
|
243
243
|
// src/framework.ts
|
|
244
244
|
var import_node_fs2 = require("fs");
|
|
245
245
|
var import_agent_core2 = require("@birdybeep/agent-core");
|
|
246
|
+
|
|
247
|
+
// src/presentation.ts
|
|
248
|
+
var BIRD = [
|
|
249
|
+
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
250
|
+
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
251
|
+
" \u2588\u2588\u2588\u2588\u2594\u2594\u2594\u2594\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
252
|
+
" \u2588\u2588\u2588\u2588\u2588\u2588 \u25AA \u2588\u2588\u2588\u2588\u2588\u2588",
|
|
253
|
+
"\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
254
|
+
"\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
255
|
+
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
256
|
+
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
257
|
+
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
258
|
+
" \u2588\u2588 \u2588\u2588",
|
|
259
|
+
" \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588"
|
|
260
|
+
].join("\n");
|
|
261
|
+
function presentation(output, env = process.env) {
|
|
262
|
+
const terminal = output.isTTY === true && env.TERM !== "dumb";
|
|
263
|
+
const color = terminal && !env.NO_COLOR;
|
|
264
|
+
const lime = (text) => {
|
|
265
|
+
if (!color) return text;
|
|
266
|
+
const code = /^(truecolor|24bit)$/.test(env.COLORTERM ?? "") ? "38;2;198;242;78" : (env.TERM ?? "").includes("256color") ? "38;5;191" : "92";
|
|
267
|
+
return `\x1B[${code}m${text}\x1B[0m`;
|
|
268
|
+
};
|
|
269
|
+
return {
|
|
270
|
+
lime,
|
|
271
|
+
banner: () => terminal ? `
|
|
272
|
+
${lime(BIRD)}
|
|
273
|
+
|
|
274
|
+
` : "",
|
|
275
|
+
help: (text) => text.split("\n").map((line, i) => i === 0 || line.endsWith(":") ? lime(line) : line).join("\n")
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// src/bird-animation.ts
|
|
280
|
+
function birdFrame(blink = false, lift = 0, pose = "rest") {
|
|
281
|
+
const rows = BIRD.split("\n");
|
|
282
|
+
if (pose === "inhale" || pose === "breathe") {
|
|
283
|
+
rows[8] = pose === "inhale" ? " \u2580\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2580" : " \u2580\u2580\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2580\u2580";
|
|
284
|
+
} else if (pose === "crouch" || pose === "land") {
|
|
285
|
+
rows.splice(7, 1);
|
|
286
|
+
rows.unshift("");
|
|
287
|
+
rows[7] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
288
|
+
rows[8] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
289
|
+
rows[9] = " \u2588\u2588 \u2588\u2588";
|
|
290
|
+
} else if (pose === "stretch") {
|
|
291
|
+
rows[4] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
292
|
+
rows[5] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
293
|
+
rows[6] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
294
|
+
rows[7] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
295
|
+
rows[9] = " \u2588\u2588 \u2588\u2588";
|
|
296
|
+
rows[10] = " \u2580\u2580 \u2580\u2580";
|
|
297
|
+
} else if (pose === "flight") {
|
|
298
|
+
rows[4] = "\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
299
|
+
rows[5] = "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2572\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
300
|
+
rows[6] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2572\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
301
|
+
rows[7] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
302
|
+
rows[9] = " \u2580\u2580 \u2580\u2580";
|
|
303
|
+
rows[10] = "";
|
|
304
|
+
}
|
|
305
|
+
if (blink)
|
|
306
|
+
rows[pose === "crouch" || pose === "land" ? 4 : 3] = rows[pose === "crouch" || pose === "land" ? 4 : 3].replace(" \u25AA ", " \u2501 ");
|
|
307
|
+
return [...Array(2 - lift).fill(""), ...rows, ...Array(lift).fill("")].join("\n");
|
|
308
|
+
}
|
|
309
|
+
var HOP = [
|
|
310
|
+
{ pose: "crouch", lift: 0, ms: 180 },
|
|
311
|
+
{ pose: "stretch", lift: 1, ms: 80 },
|
|
312
|
+
{ pose: "flight", lift: 2, ms: 130 },
|
|
313
|
+
{ pose: "flight", lift: 2, ms: 110 },
|
|
314
|
+
{ pose: "stretch", lift: 1, ms: 90 },
|
|
315
|
+
{ pose: "land", lift: 0, ms: 140 },
|
|
316
|
+
{ pose: "inhale", lift: 0, ms: 120 },
|
|
317
|
+
{ pose: "rest", lift: 0, ms: 180 }
|
|
318
|
+
];
|
|
319
|
+
function createBirdAnimation(output, env = process.env) {
|
|
320
|
+
const allowed = () => output.isTTY === true && env.TERM !== "dumb" && !env.CI && env.BIRDYBEEP_ANIMATION !== "0" && (output.columns ?? 80) >= 26 && (output.rows ?? 40) >= 16;
|
|
321
|
+
const style = presentation(output, env);
|
|
322
|
+
let activeStop;
|
|
323
|
+
const begin = () => {
|
|
324
|
+
activeStop?.();
|
|
325
|
+
if (!allowed()) return void 0;
|
|
326
|
+
let stopped = false;
|
|
327
|
+
let timer;
|
|
328
|
+
const paint = (frame, rewind = false) => {
|
|
329
|
+
output.write(
|
|
330
|
+
(rewind ? "\x1B[13A" : "") + frame.split("\n").map((line) => `\r\x1B[2K${style.lime(line)}
|
|
331
|
+
`).join("")
|
|
332
|
+
);
|
|
333
|
+
};
|
|
334
|
+
const finish = (clear) => {
|
|
335
|
+
if (stopped) return;
|
|
336
|
+
stopped = true;
|
|
337
|
+
if (timer) clearInterval(timer);
|
|
338
|
+
process.off("exit", stop);
|
|
339
|
+
process.stdout.off("resize", resize);
|
|
340
|
+
if (clear) output.write("\x1B[13A" + "\r\x1B[2K\n".repeat(13) + "\x1B[13A\r");
|
|
341
|
+
activeStop = void 0;
|
|
342
|
+
};
|
|
343
|
+
const stop = () => finish(true);
|
|
344
|
+
const resize = () => {
|
|
345
|
+
stopped = true;
|
|
346
|
+
if (timer) clearInterval(timer);
|
|
347
|
+
process.off("exit", stop);
|
|
348
|
+
process.stdout.off("resize", resize);
|
|
349
|
+
activeStop = void 0;
|
|
350
|
+
};
|
|
351
|
+
process.once("exit", stop);
|
|
352
|
+
process.stdout.once("resize", resize);
|
|
353
|
+
activeStop = stop;
|
|
354
|
+
paint(birdFrame());
|
|
355
|
+
return {
|
|
356
|
+
stop,
|
|
357
|
+
settle: () => finish(false),
|
|
358
|
+
draw: (frame) => {
|
|
359
|
+
if (!stopped) {
|
|
360
|
+
paint(frame, true);
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
repeat: (callback) => {
|
|
364
|
+
timer = setInterval(callback, 140);
|
|
365
|
+
timer.unref();
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
};
|
|
369
|
+
return {
|
|
370
|
+
wait: () => {
|
|
371
|
+
const canvas = begin();
|
|
372
|
+
if (!canvas) return () => {
|
|
373
|
+
};
|
|
374
|
+
let tick = 0;
|
|
375
|
+
canvas.repeat(() => {
|
|
376
|
+
tick += 1;
|
|
377
|
+
const phase = tick % 22;
|
|
378
|
+
const pose = phase >= 8 && phase <= 10 ? "breathe" : phase >= 6 && phase <= 12 ? "inhale" : "rest";
|
|
379
|
+
canvas.draw(birdFrame(phase === 18, 0, pose));
|
|
380
|
+
});
|
|
381
|
+
return canvas.stop;
|
|
382
|
+
},
|
|
383
|
+
celebrate: async () => {
|
|
384
|
+
const canvas = begin();
|
|
385
|
+
if (!canvas) return;
|
|
386
|
+
try {
|
|
387
|
+
for (const { pose, lift, ms } of HOP) {
|
|
388
|
+
canvas.draw(birdFrame(pose === "land", lift, pose));
|
|
389
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
390
|
+
}
|
|
391
|
+
} finally {
|
|
392
|
+
canvas.settle();
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// src/framework.ts
|
|
246
399
|
var EXIT = { OK: 0, ERROR: 1, USAGE: 2 };
|
|
247
|
-
function createIo(json, stdout, stderr) {
|
|
400
|
+
function createIo(json, stdout, stderr, animate = false) {
|
|
248
401
|
return {
|
|
249
402
|
json,
|
|
403
|
+
...!json && animate ? { bird: createBirdAnimation(stdout) } : {},
|
|
250
404
|
line: (text) => {
|
|
251
405
|
if (!json) stdout.write(`${text}
|
|
252
406
|
`);
|
|
@@ -382,7 +536,8 @@ function renderCommandHelp(path, command) {
|
|
|
382
536
|
}
|
|
383
537
|
async function dispatch(argv, deps) {
|
|
384
538
|
const { flags, rest } = parseGlobalFlags(argv);
|
|
385
|
-
const io = createIo(flags.json, deps.stdout, deps.stderr);
|
|
539
|
+
const io = createIo(flags.json, deps.stdout, deps.stderr, !flags.nonInteractive);
|
|
540
|
+
const style = presentation(deps.stdout);
|
|
386
541
|
if (deps.ensureConfig !== false) {
|
|
387
542
|
try {
|
|
388
543
|
(0, import_node_fs2.mkdirSync)((0, import_agent_core2.birdyBeepConfigDir)(), { recursive: true, mode: 448 });
|
|
@@ -410,7 +565,7 @@ async function dispatch(argv, deps) {
|
|
|
410
565
|
}
|
|
411
566
|
}
|
|
412
567
|
if (rest.length === 0 || flags.help && command === void 0) {
|
|
413
|
-
io.emit(renderRootHelp(deps.version, deps.commands), {
|
|
568
|
+
io.emit(style.banner() + style.help(renderRootHelp(deps.version, deps.commands)), {
|
|
414
569
|
version: deps.version,
|
|
415
570
|
commands: deps.commands.map((c) => ({
|
|
416
571
|
name: c.name,
|
|
@@ -426,7 +581,7 @@ async function dispatch(argv, deps) {
|
|
|
426
581
|
}
|
|
427
582
|
const path = pathParts.join(" ");
|
|
428
583
|
if (flags.help) {
|
|
429
|
-
io.emit(renderCommandHelp(path, command), {
|
|
584
|
+
io.emit(style.help(renderCommandHelp(path, command)), {
|
|
430
585
|
name: path,
|
|
431
586
|
summary: command.summary,
|
|
432
587
|
usage: command.usage,
|
|
@@ -448,6 +603,10 @@ async function dispatch(argv, deps) {
|
|
|
448
603
|
}
|
|
449
604
|
let code;
|
|
450
605
|
try {
|
|
606
|
+
if (!flags.nonInteractive && (path === "setup" || path === "pair")) {
|
|
607
|
+
const banner = style.banner();
|
|
608
|
+
if (banner) io.line(banner.trimEnd());
|
|
609
|
+
}
|
|
451
610
|
code = await command.run({ args, flags, io });
|
|
452
611
|
} catch (err) {
|
|
453
612
|
if (err instanceof MissingInputError) {
|
|
@@ -1238,7 +1397,7 @@ async function pairTokenPoll(apiUrl, deviceCode, fetchImpl, machineFingerprint,
|
|
|
1238
1397
|
}
|
|
1239
1398
|
|
|
1240
1399
|
// src/version.ts
|
|
1241
|
-
var CLI_VERSION = "0.8.
|
|
1400
|
+
var CLI_VERSION = "0.8.3".length > 0 ? "0.8.3" : "0.0.0";
|
|
1242
1401
|
|
|
1243
1402
|
// src/commands/setup.ts
|
|
1244
1403
|
var import_claude_code5 = require("@birdybeep/claude-code");
|
|
@@ -1791,32 +1950,39 @@ function createPairingCommand(verb, deps = {}) {
|
|
|
1791
1950
|
let lastBeat = startedAt;
|
|
1792
1951
|
let paired;
|
|
1793
1952
|
let terminal;
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
paired = poll;
|
|
1808
|
-
break;
|
|
1809
|
-
}
|
|
1810
|
-
if (poll.status === "error" && !poll.retryable) {
|
|
1811
|
-
terminal = poll;
|
|
1812
|
-
break;
|
|
1813
|
-
}
|
|
1814
|
-
if (!ctx.flags.json && nowMs - lastBeat >= HEARTBEAT_MS) {
|
|
1815
|
-
ctx.io.line(
|
|
1816
|
-
poll.status === "error" ? ` Backend unavailable (${poll.message}); retrying.` : " Waiting for approval in the BirdyBeep app."
|
|
1953
|
+
let stopBird = ctx.io.bird?.wait();
|
|
1954
|
+
try {
|
|
1955
|
+
for (; ; ) {
|
|
1956
|
+
const nowMs = clock();
|
|
1957
|
+
if (nowMs >= deadline) break;
|
|
1958
|
+
await sleep(intervalMs);
|
|
1959
|
+
const poll = await pairTokenPoll(
|
|
1960
|
+
apiUrl,
|
|
1961
|
+
start.device_code,
|
|
1962
|
+
fetchImpl,
|
|
1963
|
+
identity.fingerprintHash,
|
|
1964
|
+
codeVerifier
|
|
1965
|
+
// PKCE proof-of-possession (dgxd) — sent on every poll
|
|
1817
1966
|
);
|
|
1818
|
-
|
|
1967
|
+
if (poll.status === "paired") {
|
|
1968
|
+
paired = poll;
|
|
1969
|
+
break;
|
|
1970
|
+
}
|
|
1971
|
+
if (poll.status === "error" && !poll.retryable) {
|
|
1972
|
+
terminal = poll;
|
|
1973
|
+
break;
|
|
1974
|
+
}
|
|
1975
|
+
if (!ctx.flags.json && nowMs - lastBeat >= HEARTBEAT_MS) {
|
|
1976
|
+
stopBird?.();
|
|
1977
|
+
ctx.io.line(
|
|
1978
|
+
poll.status === "error" ? ` Backend unavailable (${poll.message}); retrying.` : " Waiting for approval in the BirdyBeep app."
|
|
1979
|
+
);
|
|
1980
|
+
lastBeat = nowMs;
|
|
1981
|
+
stopBird = ctx.io.bird?.wait();
|
|
1982
|
+
}
|
|
1819
1983
|
}
|
|
1984
|
+
} finally {
|
|
1985
|
+
stopBird?.();
|
|
1820
1986
|
}
|
|
1821
1987
|
if (terminal !== void 0) {
|
|
1822
1988
|
ctx.io.result({ paired: false, reason: terminal.code });
|
|
@@ -1864,6 +2030,7 @@ function createPairingCommand(verb, deps = {}) {
|
|
|
1864
2030
|
const humanSuffix = approvedBy !== void 0 ? ` to ${approvedBy}` : "";
|
|
1865
2031
|
const discardedSuffix = discarded > 0 ? ` Discarded ${discarded} event(s) queued before pairing. They will not produce notifications.` : "";
|
|
1866
2032
|
const nextStep = chain === void 0 ? " Run `birdybeep setup` to install coding-agent hooks." : "";
|
|
2033
|
+
await ctx.io.bird?.celebrate();
|
|
1867
2034
|
ctx.io.line(`\u2713 Paired${humanSuffix}.${nextStep}${discardedSuffix}`);
|
|
1868
2035
|
const report = chain !== void 0 ? await runSetupChain(ctx, setupDeps, pairFlags) : void 0;
|
|
1869
2036
|
ctx.io.result({
|