@birdybeep/cli 0.8.1 → 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 +224 -31
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-J45QGUDO.js → chunk-NSHPZ3RX.js} +244 -35
- package/dist/chunk-NSHPZ3RX.js.map +1 -0
- package/dist/index.cjs +224 -31
- 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-J45QGUDO.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) {
|
|
@@ -837,6 +996,7 @@ var import_node_crypto = require("crypto");
|
|
|
837
996
|
var import_node_fs4 = require("fs");
|
|
838
997
|
var import_node_os2 = require("os");
|
|
839
998
|
var import_node_path2 = require("path");
|
|
999
|
+
var import_node_perf_hooks = require("perf_hooks");
|
|
840
1000
|
var import_agent_core5 = require("@birdybeep/agent-core");
|
|
841
1001
|
var import_claude_code4 = require("@birdybeep/claude-code");
|
|
842
1002
|
var import_codex3 = require("@birdybeep/codex");
|
|
@@ -857,6 +1017,21 @@ var HOOK_HARNESSES = [
|
|
|
857
1017
|
"copilot"
|
|
858
1018
|
];
|
|
859
1019
|
var STDIN_READ_TIMEOUT_MS = 3e3;
|
|
1020
|
+
var LEGACY_HOOK_RUNTIME_BUDGET_MS = 9e3;
|
|
1021
|
+
function hookRuntimeBudgetMs(configuredTimeoutSeconds) {
|
|
1022
|
+
if (configuredTimeoutSeconds === void 0 || !Number.isFinite(configuredTimeoutSeconds) || configuredTimeoutSeconds <= 0) {
|
|
1023
|
+
return LEGACY_HOOK_RUNTIME_BUDGET_MS;
|
|
1024
|
+
}
|
|
1025
|
+
const configuredBudgetMs = Math.max(1, Math.floor(configuredTimeoutSeconds * 1e3) - 1e3);
|
|
1026
|
+
return Math.min(LEGACY_HOOK_RUNTIME_BUDGET_MS, configuredBudgetMs);
|
|
1027
|
+
}
|
|
1028
|
+
function configuredHookTimeoutSeconds(harness) {
|
|
1029
|
+
if (harness === "claude") return (0, import_claude_code4.configuredClaudeHookTimeoutSeconds)();
|
|
1030
|
+
if (harness === "codex") return (0, import_codex3.configuredCodexHookTimeoutSeconds)();
|
|
1031
|
+
if (harness === "cursor") return (0, import_cursor4.configuredCursorHookTimeoutSeconds)();
|
|
1032
|
+
if (harness === "copilot") return (0, import_copilot3.configuredCopilotHookTimeoutSeconds)();
|
|
1033
|
+
return void 0;
|
|
1034
|
+
}
|
|
860
1035
|
function withTimeout(promise, ms, fallback) {
|
|
861
1036
|
return new Promise((resolve) => {
|
|
862
1037
|
let settled = false;
|
|
@@ -977,15 +1152,22 @@ function detachCodexNotifyWorker(payload) {
|
|
|
977
1152
|
}
|
|
978
1153
|
}
|
|
979
1154
|
function createHookCommand(deps = {}) {
|
|
980
|
-
const makeSender = deps.createSender ?? ((baseUrl) => (0, import_agent_core5.createSender)({
|
|
1155
|
+
const makeSender = deps.createSender ?? ((baseUrl, budgetMs) => (0, import_agent_core5.createSender)({
|
|
1156
|
+
baseUrl,
|
|
1157
|
+
timeoutMs: Math.min(import_agent_core5.DEFAULT_SEND_TIMEOUT_MS, budgetMs),
|
|
1158
|
+
totalBudgetMs: budgetMs
|
|
1159
|
+
}));
|
|
981
1160
|
const readStdin = deps.readStdin ?? readStdinDefault;
|
|
982
1161
|
const stdinTimeoutMs = deps.stdinTimeoutMs ?? STDIN_READ_TIMEOUT_MS;
|
|
1162
|
+
const now = deps.now ?? (() => import_node_perf_hooks.performance.now());
|
|
1163
|
+
const readConfiguredHookTimeoutSeconds = deps.configuredHookTimeoutSeconds ?? configuredHookTimeoutSeconds;
|
|
983
1164
|
const detachCodexNotify = deps.detachCodexNotify ?? detachCodexNotifyWorker;
|
|
984
1165
|
return {
|
|
985
1166
|
name: "hook",
|
|
986
1167
|
summary: "Internal: normalize + send an event fired by a harness hook",
|
|
987
1168
|
usage: "birdybeep hook <claude|codex|opencode|cursor|copilot> [copilot-event]",
|
|
988
1169
|
run: async (ctx) => {
|
|
1170
|
+
const hookStartedAt = now();
|
|
989
1171
|
const harness = ctx.args[0];
|
|
990
1172
|
if (!isHarnessName(harness)) {
|
|
991
1173
|
ctx.io.errline(`birdybeep hook: expected one of ${HOOK_HARNESSES.join("|")}`);
|
|
@@ -1051,7 +1233,10 @@ function createHookCommand(deps = {}) {
|
|
|
1051
1233
|
);
|
|
1052
1234
|
return EXIT.ERROR;
|
|
1053
1235
|
}
|
|
1054
|
-
const
|
|
1236
|
+
const runtimeBudgetMs = hookRuntimeBudgetMs(readConfiguredHookTimeoutSeconds(harness));
|
|
1237
|
+
const elapsedMs = Math.max(0, now() - hookStartedAt);
|
|
1238
|
+
const budgetMs = Math.max(1, Math.min(import_agent_core5.DEFAULT_TOTAL_BUDGET_MS, runtimeBudgetMs - elapsedMs));
|
|
1239
|
+
const sender = makeSender(resolveApiUrl(), budgetMs);
|
|
1055
1240
|
const result = await runHookCommand(harness, payload, sender, copilotEventName);
|
|
1056
1241
|
ctx.io.result({
|
|
1057
1242
|
harness: handler,
|
|
@@ -1212,7 +1397,7 @@ async function pairTokenPoll(apiUrl, deviceCode, fetchImpl, machineFingerprint,
|
|
|
1212
1397
|
}
|
|
1213
1398
|
|
|
1214
1399
|
// src/version.ts
|
|
1215
|
-
var CLI_VERSION = "0.8.
|
|
1400
|
+
var CLI_VERSION = "0.8.3".length > 0 ? "0.8.3" : "0.0.0";
|
|
1216
1401
|
|
|
1217
1402
|
// src/commands/setup.ts
|
|
1218
1403
|
var import_claude_code5 = require("@birdybeep/claude-code");
|
|
@@ -1765,32 +1950,39 @@ function createPairingCommand(verb, deps = {}) {
|
|
|
1765
1950
|
let lastBeat = startedAt;
|
|
1766
1951
|
let paired;
|
|
1767
1952
|
let terminal;
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
paired = poll;
|
|
1782
|
-
break;
|
|
1783
|
-
}
|
|
1784
|
-
if (poll.status === "error" && !poll.retryable) {
|
|
1785
|
-
terminal = poll;
|
|
1786
|
-
break;
|
|
1787
|
-
}
|
|
1788
|
-
if (!ctx.flags.json && nowMs - lastBeat >= HEARTBEAT_MS) {
|
|
1789
|
-
ctx.io.line(
|
|
1790
|
-
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
|
|
1791
1966
|
);
|
|
1792
|
-
|
|
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
|
+
}
|
|
1793
1983
|
}
|
|
1984
|
+
} finally {
|
|
1985
|
+
stopBird?.();
|
|
1794
1986
|
}
|
|
1795
1987
|
if (terminal !== void 0) {
|
|
1796
1988
|
ctx.io.result({ paired: false, reason: terminal.code });
|
|
@@ -1838,6 +2030,7 @@ function createPairingCommand(verb, deps = {}) {
|
|
|
1838
2030
|
const humanSuffix = approvedBy !== void 0 ? ` to ${approvedBy}` : "";
|
|
1839
2031
|
const discardedSuffix = discarded > 0 ? ` Discarded ${discarded} event(s) queued before pairing. They will not produce notifications.` : "";
|
|
1840
2032
|
const nextStep = chain === void 0 ? " Run `birdybeep setup` to install coding-agent hooks." : "";
|
|
2033
|
+
await ctx.io.bird?.celebrate();
|
|
1841
2034
|
ctx.io.line(`\u2713 Paired${humanSuffix}.${nextStep}${discardedSuffix}`);
|
|
1842
2035
|
const report = chain !== void 0 ? await runSetupChain(ctx, setupDeps, pairFlags) : void 0;
|
|
1843
2036
|
ctx.io.result({
|