@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/bin.js
CHANGED
|
@@ -1,10 +1,164 @@
|
|
|
1
1
|
// src/framework.ts
|
|
2
2
|
import { mkdirSync } from "fs";
|
|
3
3
|
import { birdyBeepConfigDir } from "@birdybeep/agent-core";
|
|
4
|
+
|
|
5
|
+
// src/presentation.ts
|
|
6
|
+
var BIRD = [
|
|
7
|
+
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
8
|
+
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
9
|
+
" \u2588\u2588\u2588\u2588\u2594\u2594\u2594\u2594\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
10
|
+
" \u2588\u2588\u2588\u2588\u2588\u2588 \u25AA \u2588\u2588\u2588\u2588\u2588\u2588",
|
|
11
|
+
"\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
12
|
+
"\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
13
|
+
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
14
|
+
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
15
|
+
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
16
|
+
" \u2588\u2588 \u2588\u2588",
|
|
17
|
+
" \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588"
|
|
18
|
+
].join("\n");
|
|
19
|
+
function presentation(output, env = process.env) {
|
|
20
|
+
const terminal = output.isTTY === true && env.TERM !== "dumb";
|
|
21
|
+
const color = terminal && !env.NO_COLOR;
|
|
22
|
+
const lime = (text) => {
|
|
23
|
+
if (!color) return text;
|
|
24
|
+
const code = /^(truecolor|24bit)$/.test(env.COLORTERM ?? "") ? "38;2;198;242;78" : (env.TERM ?? "").includes("256color") ? "38;5;191" : "92";
|
|
25
|
+
return `\x1B[${code}m${text}\x1B[0m`;
|
|
26
|
+
};
|
|
27
|
+
return {
|
|
28
|
+
lime,
|
|
29
|
+
banner: () => terminal ? `
|
|
30
|
+
${lime(BIRD)}
|
|
31
|
+
|
|
32
|
+
` : "",
|
|
33
|
+
help: (text) => text.split("\n").map((line, i) => i === 0 || line.endsWith(":") ? lime(line) : line).join("\n")
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/bird-animation.ts
|
|
38
|
+
function birdFrame(blink = false, lift = 0, pose = "rest") {
|
|
39
|
+
const rows = BIRD.split("\n");
|
|
40
|
+
if (pose === "inhale" || pose === "breathe") {
|
|
41
|
+
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";
|
|
42
|
+
} else if (pose === "crouch" || pose === "land") {
|
|
43
|
+
rows.splice(7, 1);
|
|
44
|
+
rows.unshift("");
|
|
45
|
+
rows[7] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
46
|
+
rows[8] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
47
|
+
rows[9] = " \u2588\u2588 \u2588\u2588";
|
|
48
|
+
} else if (pose === "stretch") {
|
|
49
|
+
rows[4] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
50
|
+
rows[5] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
51
|
+
rows[6] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
52
|
+
rows[7] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
53
|
+
rows[9] = " \u2588\u2588 \u2588\u2588";
|
|
54
|
+
rows[10] = " \u2580\u2580 \u2580\u2580";
|
|
55
|
+
} else if (pose === "flight") {
|
|
56
|
+
rows[4] = "\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
57
|
+
rows[5] = "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2572\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
58
|
+
rows[6] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2572\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
59
|
+
rows[7] = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
|
|
60
|
+
rows[9] = " \u2580\u2580 \u2580\u2580";
|
|
61
|
+
rows[10] = "";
|
|
62
|
+
}
|
|
63
|
+
if (blink)
|
|
64
|
+
rows[pose === "crouch" || pose === "land" ? 4 : 3] = rows[pose === "crouch" || pose === "land" ? 4 : 3].replace(" \u25AA ", " \u2501 ");
|
|
65
|
+
return [...Array(2 - lift).fill(""), ...rows, ...Array(lift).fill("")].join("\n");
|
|
66
|
+
}
|
|
67
|
+
var HOP = [
|
|
68
|
+
{ pose: "crouch", lift: 0, ms: 180 },
|
|
69
|
+
{ pose: "stretch", lift: 1, ms: 80 },
|
|
70
|
+
{ pose: "flight", lift: 2, ms: 130 },
|
|
71
|
+
{ pose: "flight", lift: 2, ms: 110 },
|
|
72
|
+
{ pose: "stretch", lift: 1, ms: 90 },
|
|
73
|
+
{ pose: "land", lift: 0, ms: 140 },
|
|
74
|
+
{ pose: "inhale", lift: 0, ms: 120 },
|
|
75
|
+
{ pose: "rest", lift: 0, ms: 180 }
|
|
76
|
+
];
|
|
77
|
+
function createBirdAnimation(output, env = process.env) {
|
|
78
|
+
const allowed = () => output.isTTY === true && env.TERM !== "dumb" && !env.CI && env.BIRDYBEEP_ANIMATION !== "0" && (output.columns ?? 80) >= 26 && (output.rows ?? 40) >= 16;
|
|
79
|
+
const style = presentation(output, env);
|
|
80
|
+
let activeStop;
|
|
81
|
+
const begin = () => {
|
|
82
|
+
activeStop?.();
|
|
83
|
+
if (!allowed()) return void 0;
|
|
84
|
+
let stopped = false;
|
|
85
|
+
let timer;
|
|
86
|
+
const paint = (frame, rewind = false) => {
|
|
87
|
+
output.write(
|
|
88
|
+
(rewind ? "\x1B[13A" : "") + frame.split("\n").map((line) => `\r\x1B[2K${style.lime(line)}
|
|
89
|
+
`).join("")
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
const finish = (clear) => {
|
|
93
|
+
if (stopped) return;
|
|
94
|
+
stopped = true;
|
|
95
|
+
if (timer) clearInterval(timer);
|
|
96
|
+
process.off("exit", stop);
|
|
97
|
+
process.stdout.off("resize", resize);
|
|
98
|
+
if (clear) output.write("\x1B[13A" + "\r\x1B[2K\n".repeat(13) + "\x1B[13A\r");
|
|
99
|
+
activeStop = void 0;
|
|
100
|
+
};
|
|
101
|
+
const stop = () => finish(true);
|
|
102
|
+
const resize = () => {
|
|
103
|
+
stopped = true;
|
|
104
|
+
if (timer) clearInterval(timer);
|
|
105
|
+
process.off("exit", stop);
|
|
106
|
+
process.stdout.off("resize", resize);
|
|
107
|
+
activeStop = void 0;
|
|
108
|
+
};
|
|
109
|
+
process.once("exit", stop);
|
|
110
|
+
process.stdout.once("resize", resize);
|
|
111
|
+
activeStop = stop;
|
|
112
|
+
paint(birdFrame());
|
|
113
|
+
return {
|
|
114
|
+
stop,
|
|
115
|
+
settle: () => finish(false),
|
|
116
|
+
draw: (frame) => {
|
|
117
|
+
if (!stopped) {
|
|
118
|
+
paint(frame, true);
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
repeat: (callback) => {
|
|
122
|
+
timer = setInterval(callback, 140);
|
|
123
|
+
timer.unref();
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
return {
|
|
128
|
+
wait: () => {
|
|
129
|
+
const canvas = begin();
|
|
130
|
+
if (!canvas) return () => {
|
|
131
|
+
};
|
|
132
|
+
let tick = 0;
|
|
133
|
+
canvas.repeat(() => {
|
|
134
|
+
tick += 1;
|
|
135
|
+
const phase = tick % 22;
|
|
136
|
+
const pose = phase >= 8 && phase <= 10 ? "breathe" : phase >= 6 && phase <= 12 ? "inhale" : "rest";
|
|
137
|
+
canvas.draw(birdFrame(phase === 18, 0, pose));
|
|
138
|
+
});
|
|
139
|
+
return canvas.stop;
|
|
140
|
+
},
|
|
141
|
+
celebrate: async () => {
|
|
142
|
+
const canvas = begin();
|
|
143
|
+
if (!canvas) return;
|
|
144
|
+
try {
|
|
145
|
+
for (const { pose, lift, ms } of HOP) {
|
|
146
|
+
canvas.draw(birdFrame(pose === "land", lift, pose));
|
|
147
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
148
|
+
}
|
|
149
|
+
} finally {
|
|
150
|
+
canvas.settle();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// src/framework.ts
|
|
4
157
|
var EXIT = { OK: 0, ERROR: 1, USAGE: 2 };
|
|
5
|
-
function createIo(json, stdout, stderr) {
|
|
158
|
+
function createIo(json, stdout, stderr, animate = false) {
|
|
6
159
|
return {
|
|
7
160
|
json,
|
|
161
|
+
...!json && animate ? { bird: createBirdAnimation(stdout) } : {},
|
|
8
162
|
line: (text) => {
|
|
9
163
|
if (!json) stdout.write(`${text}
|
|
10
164
|
`);
|
|
@@ -140,7 +294,8 @@ function renderCommandHelp(path, command) {
|
|
|
140
294
|
}
|
|
141
295
|
async function dispatch(argv, deps) {
|
|
142
296
|
const { flags, rest } = parseGlobalFlags(argv);
|
|
143
|
-
const io = createIo(flags.json, deps.stdout, deps.stderr);
|
|
297
|
+
const io = createIo(flags.json, deps.stdout, deps.stderr, !flags.nonInteractive);
|
|
298
|
+
const style = presentation(deps.stdout);
|
|
144
299
|
if (deps.ensureConfig !== false) {
|
|
145
300
|
try {
|
|
146
301
|
mkdirSync(birdyBeepConfigDir(), { recursive: true, mode: 448 });
|
|
@@ -168,7 +323,7 @@ async function dispatch(argv, deps) {
|
|
|
168
323
|
}
|
|
169
324
|
}
|
|
170
325
|
if (rest.length === 0 || flags.help && command === void 0) {
|
|
171
|
-
io.emit(renderRootHelp(deps.version, deps.commands), {
|
|
326
|
+
io.emit(style.banner() + style.help(renderRootHelp(deps.version, deps.commands)), {
|
|
172
327
|
version: deps.version,
|
|
173
328
|
commands: deps.commands.map((c) => ({
|
|
174
329
|
name: c.name,
|
|
@@ -184,7 +339,7 @@ async function dispatch(argv, deps) {
|
|
|
184
339
|
}
|
|
185
340
|
const path = pathParts.join(" ");
|
|
186
341
|
if (flags.help) {
|
|
187
|
-
io.emit(renderCommandHelp(path, command), {
|
|
342
|
+
io.emit(style.help(renderCommandHelp(path, command)), {
|
|
188
343
|
name: path,
|
|
189
344
|
summary: command.summary,
|
|
190
345
|
usage: command.usage,
|
|
@@ -206,6 +361,10 @@ async function dispatch(argv, deps) {
|
|
|
206
361
|
}
|
|
207
362
|
let code;
|
|
208
363
|
try {
|
|
364
|
+
if (!flags.nonInteractive && (path === "setup" || path === "pair")) {
|
|
365
|
+
const banner = style.banner();
|
|
366
|
+
if (banner) io.line(banner.trimEnd());
|
|
367
|
+
}
|
|
209
368
|
code = await command.run({ args, flags, io });
|
|
210
369
|
} catch (err) {
|
|
211
370
|
if (err instanceof MissingInputError) {
|
|
@@ -227,7 +386,7 @@ async function dispatch(argv, deps) {
|
|
|
227
386
|
}
|
|
228
387
|
|
|
229
388
|
// src/version.ts
|
|
230
|
-
var CLI_VERSION = "0.8.
|
|
389
|
+
var CLI_VERSION = "0.8.3".length > 0 ? "0.8.3" : "0.0.0";
|
|
231
390
|
|
|
232
391
|
// src/commands/agent.ts
|
|
233
392
|
import { claudeCodeAdapter } from "@birdybeep/claude-code";
|
|
@@ -1812,32 +1971,39 @@ function createPairingCommand(verb, deps = {}) {
|
|
|
1812
1971
|
let lastBeat = startedAt;
|
|
1813
1972
|
let paired;
|
|
1814
1973
|
let terminal;
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
paired = poll;
|
|
1829
|
-
break;
|
|
1830
|
-
}
|
|
1831
|
-
if (poll.status === "error" && !poll.retryable) {
|
|
1832
|
-
terminal = poll;
|
|
1833
|
-
break;
|
|
1834
|
-
}
|
|
1835
|
-
if (!ctx.flags.json && nowMs - lastBeat >= HEARTBEAT_MS) {
|
|
1836
|
-
ctx.io.line(
|
|
1837
|
-
poll.status === "error" ? ` Backend unavailable (${poll.message}); retrying.` : " Waiting for approval in the BirdyBeep app."
|
|
1974
|
+
let stopBird = ctx.io.bird?.wait();
|
|
1975
|
+
try {
|
|
1976
|
+
for (; ; ) {
|
|
1977
|
+
const nowMs = clock();
|
|
1978
|
+
if (nowMs >= deadline) break;
|
|
1979
|
+
await sleep(intervalMs);
|
|
1980
|
+
const poll = await pairTokenPoll(
|
|
1981
|
+
apiUrl,
|
|
1982
|
+
start.device_code,
|
|
1983
|
+
fetchImpl,
|
|
1984
|
+
identity.fingerprintHash,
|
|
1985
|
+
codeVerifier
|
|
1986
|
+
// PKCE proof-of-possession (dgxd) — sent on every poll
|
|
1838
1987
|
);
|
|
1839
|
-
|
|
1988
|
+
if (poll.status === "paired") {
|
|
1989
|
+
paired = poll;
|
|
1990
|
+
break;
|
|
1991
|
+
}
|
|
1992
|
+
if (poll.status === "error" && !poll.retryable) {
|
|
1993
|
+
terminal = poll;
|
|
1994
|
+
break;
|
|
1995
|
+
}
|
|
1996
|
+
if (!ctx.flags.json && nowMs - lastBeat >= HEARTBEAT_MS) {
|
|
1997
|
+
stopBird?.();
|
|
1998
|
+
ctx.io.line(
|
|
1999
|
+
poll.status === "error" ? ` Backend unavailable (${poll.message}); retrying.` : " Waiting for approval in the BirdyBeep app."
|
|
2000
|
+
);
|
|
2001
|
+
lastBeat = nowMs;
|
|
2002
|
+
stopBird = ctx.io.bird?.wait();
|
|
2003
|
+
}
|
|
1840
2004
|
}
|
|
2005
|
+
} finally {
|
|
2006
|
+
stopBird?.();
|
|
1841
2007
|
}
|
|
1842
2008
|
if (terminal !== void 0) {
|
|
1843
2009
|
ctx.io.result({ paired: false, reason: terminal.code });
|
|
@@ -1885,6 +2051,7 @@ function createPairingCommand(verb, deps = {}) {
|
|
|
1885
2051
|
const humanSuffix = approvedBy !== void 0 ? ` to ${approvedBy}` : "";
|
|
1886
2052
|
const discardedSuffix = discarded > 0 ? ` Discarded ${discarded} event(s) queued before pairing. They will not produce notifications.` : "";
|
|
1887
2053
|
const nextStep = chain === void 0 ? " Run `birdybeep setup` to install coding-agent hooks." : "";
|
|
2054
|
+
await ctx.io.bird?.celebrate();
|
|
1888
2055
|
ctx.io.line(`\u2713 Paired${humanSuffix}.${nextStep}${discardedSuffix}`);
|
|
1889
2056
|
const report = chain !== void 0 ? await runSetupChain(ctx, setupDeps, pairFlags) : void 0;
|
|
1890
2057
|
ctx.io.result({
|
|
@@ -2304,4 +2471,4 @@ export {
|
|
|
2304
2471
|
buildCommands,
|
|
2305
2472
|
runCli
|
|
2306
2473
|
};
|
|
2307
|
-
//# sourceMappingURL=chunk-
|
|
2474
|
+
//# sourceMappingURL=chunk-NSHPZ3RX.js.map
|