@birdybeep/cli 0.6.0 → 0.7.0
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 +80 -10
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-BY5MNQE3.js → chunk-6RIMM4RO.js} +86 -12
- package/dist/chunk-6RIMM4RO.js.map +1 -0
- package/dist/index.cjs +80 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +7 -7
- package/dist/chunk-BY5MNQE3.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -67,6 +67,21 @@ async function gatherIntegrations(adapters) {
|
|
|
67
67
|
async function isPaired(tokenOptions = {}) {
|
|
68
68
|
return await (0, import_agent_core.getToken)(tokenOptions) !== null;
|
|
69
69
|
}
|
|
70
|
+
async function pairingReport(tokenOptions = {}) {
|
|
71
|
+
const lookup = await (0, import_agent_core.readToken)(tokenOptions);
|
|
72
|
+
if (lookup.state === "present") return { state: "paired" };
|
|
73
|
+
if (lookup.state === "absent") return { state: "unpaired" };
|
|
74
|
+
return { state: "unknown", reason: lookup.reason, store: lookup.store };
|
|
75
|
+
}
|
|
76
|
+
function describeTokenStoreUnavailable(report) {
|
|
77
|
+
return `Could not read the token store (${report.reason ?? "unknown error"}), so whether this machine is paired is unknown. Events fired now are QUEUED, not lost, and send once it is readable.`;
|
|
78
|
+
}
|
|
79
|
+
function tokenStoreRemedy(report) {
|
|
80
|
+
if (report.store === "file") {
|
|
81
|
+
return "Repair the token file \u2014 check that its directory and the file itself are readable and writable by you (`chmod 700` the directory, `chmod 600` the file), then run `birdybeep doctor` again to drain the queue.";
|
|
82
|
+
}
|
|
83
|
+
return "Unlock your login keychain (log in to the desktop session, or unlock the screen), then run `birdybeep doctor` again to drain the queue. If it stays unreadable, run `birdybeep pair`.";
|
|
84
|
+
}
|
|
70
85
|
function localQueueDepth() {
|
|
71
86
|
return new import_agent_core.LocalEventQueue().size();
|
|
72
87
|
}
|
|
@@ -676,16 +691,36 @@ function createDoctorCommand(deps = {}) {
|
|
|
676
691
|
usage: "birdybeep doctor [--json]",
|
|
677
692
|
run: async (ctx) => {
|
|
678
693
|
const checks = [];
|
|
679
|
-
const apiUrl = resolveApiUrl();
|
|
680
|
-
const
|
|
694
|
+
const apiUrl = deps.baseUrl ?? resolveApiUrl();
|
|
695
|
+
const pairing = await pairingReport(deps.tokenOptions ?? {});
|
|
681
696
|
checks.push(
|
|
682
|
-
paired ? { name: "Machine token", ok: true } : {
|
|
697
|
+
pairing.state === "paired" ? { name: "Machine token", ok: true } : pairing.state === "unpaired" ? {
|
|
683
698
|
name: "Machine token",
|
|
684
699
|
ok: false,
|
|
685
700
|
detail: "No machine token found.",
|
|
686
701
|
remedy: "Run `birdybeep pair` to pair this machine."
|
|
702
|
+
} : {
|
|
703
|
+
name: "Machine token",
|
|
704
|
+
ok: false,
|
|
705
|
+
detail: describeTokenStoreUnavailable(pairing),
|
|
706
|
+
remedy: tokenStoreRemedy(pairing)
|
|
687
707
|
}
|
|
688
708
|
);
|
|
709
|
+
const reach = (0, import_agent_core4.describeReachability)(
|
|
710
|
+
await (0, import_agent_core4.fetchPushReachability)({
|
|
711
|
+
baseUrl: apiUrl,
|
|
712
|
+
...deps.tokenOptions ? { tokenOptions: deps.tokenOptions } : {},
|
|
713
|
+
...deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {}
|
|
714
|
+
})
|
|
715
|
+
);
|
|
716
|
+
if (reach !== null) {
|
|
717
|
+
checks.push({
|
|
718
|
+
name: "Push reachability",
|
|
719
|
+
ok: reach.ok,
|
|
720
|
+
detail: reach.detail,
|
|
721
|
+
...reach.remedy !== void 0 ? { remedy: reach.remedy } : {}
|
|
722
|
+
});
|
|
723
|
+
}
|
|
689
724
|
const unpaired = unpairedActivity();
|
|
690
725
|
if (unpaired !== null) {
|
|
691
726
|
checks.push({
|
|
@@ -757,6 +792,8 @@ function createDoctorCommand(deps = {}) {
|
|
|
757
792
|
ctx.io.result({
|
|
758
793
|
ok,
|
|
759
794
|
checks,
|
|
795
|
+
pairing,
|
|
796
|
+
// gcgp.23: paired | unpaired | unknown — never a bare boolean
|
|
760
797
|
surfaces: surfaceGroups,
|
|
761
798
|
queue: { depthBefore, delivered: drain.delivered, depthAfter, overflowDropped },
|
|
762
799
|
...unpaired !== null ? { unpairedActivity: unpaired } : {},
|
|
@@ -1003,13 +1040,20 @@ function createHookCommand(deps = {}) {
|
|
|
1003
1040
|
outcome: result.outcome,
|
|
1004
1041
|
eventType: result.eventType,
|
|
1005
1042
|
...result.send?.decision ? { decision: result.send.decision } : {},
|
|
1006
|
-
...result.send?.status !== void 0 ? { status: result.send.status } : {}
|
|
1043
|
+
...result.send?.status !== void 0 ? { status: result.send.status } : {},
|
|
1044
|
+
...result.send?.tokenStoreUnavailable !== void 0 ? { tokenStore: "unavailable" } : {}
|
|
1007
1045
|
});
|
|
1008
1046
|
if (result.outcome === "unpaired") {
|
|
1009
1047
|
ctx.io.errline(
|
|
1010
1048
|
"birdybeep: this machine is not paired \u2014 the event was not sent and was not queued. Run `birdybeep pair` (or `birdybeep doctor` to see how many events this has cost)."
|
|
1011
1049
|
);
|
|
1012
1050
|
}
|
|
1051
|
+
const unavailable = result.send?.tokenStoreUnavailable;
|
|
1052
|
+
if (unavailable !== void 0) {
|
|
1053
|
+
ctx.io.errline(
|
|
1054
|
+
`birdybeep: could not read the machine token (${unavailable.reason}) \u2014 the event was QUEUED, not sent. It will deliver once the token store is readable (unlock your keychain); \`birdybeep doctor\` drains the queue.`
|
|
1055
|
+
);
|
|
1056
|
+
}
|
|
1013
1057
|
return EXIT.OK;
|
|
1014
1058
|
}
|
|
1015
1059
|
};
|
|
@@ -1142,7 +1186,7 @@ async function pairTokenPoll(apiUrl, deviceCode, fetchImpl, machineFingerprint,
|
|
|
1142
1186
|
}
|
|
1143
1187
|
|
|
1144
1188
|
// src/version.ts
|
|
1145
|
-
var CLI_VERSION = "0.
|
|
1189
|
+
var CLI_VERSION = "0.7.0".length > 0 ? "0.7.0" : "0.0.0";
|
|
1146
1190
|
|
|
1147
1191
|
// src/commands/setup.ts
|
|
1148
1192
|
var import_claude_code5 = require("@birdybeep/claude-code");
|
|
@@ -1184,16 +1228,33 @@ function createTestCommand(deps = {}) {
|
|
|
1184
1228
|
usage: "birdybeep test [--json]",
|
|
1185
1229
|
run: async (ctx) => {
|
|
1186
1230
|
const event = buildTestEvent();
|
|
1187
|
-
const
|
|
1231
|
+
const baseUrl = deps.baseUrl ?? resolveApiUrl();
|
|
1232
|
+
const result = await makeSender(baseUrl).send(event);
|
|
1188
1233
|
if (ctx.flags.json) {
|
|
1189
1234
|
ctx.io.result({
|
|
1190
1235
|
outcome: result.outcome,
|
|
1191
1236
|
...result.status ? { status: result.status } : {},
|
|
1192
|
-
...result.decision ? { decision: result.decision } : {}
|
|
1237
|
+
...result.decision ? { decision: result.decision } : {},
|
|
1238
|
+
...result.tokenStoreUnavailable !== void 0 ? { tokenStore: "unavailable", tokenStoreReason: result.tokenStoreUnavailable.reason } : {}
|
|
1193
1239
|
});
|
|
1194
1240
|
} else if (result.outcome === "delivered") {
|
|
1195
1241
|
if (result.decision === "notified" || result.decision === void 0) {
|
|
1196
|
-
|
|
1242
|
+
const reach = await (0, import_agent_core8.fetchPushReachability)({
|
|
1243
|
+
baseUrl,
|
|
1244
|
+
...deps.tokenOptions ? { tokenOptions: deps.tokenOptions } : {},
|
|
1245
|
+
...deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {}
|
|
1246
|
+
});
|
|
1247
|
+
if (reach.state === "ok" && reach.data.active_device_count === 0) {
|
|
1248
|
+
ctx.io.line(
|
|
1249
|
+
"\u26A0 The backend accepted the test event, but NO device on this account can receive it \u2014 nothing will arrive. Open the BirdyBeep app on your phone to register it (if it says the device limit is full, free a slot in Settings \u203A devices)."
|
|
1250
|
+
);
|
|
1251
|
+
} else if (reach.state === "ok") {
|
|
1252
|
+
ctx.io.line(
|
|
1253
|
+
`\u2713 Test event accepted and queued for ${String(reach.data.active_device_count)} registered device(s) \u2014 check your phone for a test Beep.`
|
|
1254
|
+
);
|
|
1255
|
+
} else {
|
|
1256
|
+
ctx.io.line("\u2713 Test event accepted by the backend \u2014 check your phone for a test Beep.");
|
|
1257
|
+
}
|
|
1197
1258
|
} else if (result.decision === "suppressed") {
|
|
1198
1259
|
ctx.io.line(
|
|
1199
1260
|
"\u26A0 The backend accepted the test event but suppressed the push \u2014 this machine or integration is probably muted. Check mutes in the app, or run `birdybeep doctor`."
|
|
@@ -1211,6 +1272,10 @@ function createTestCommand(deps = {}) {
|
|
|
1211
1272
|
ctx.io.line(
|
|
1212
1273
|
"\u2717 NOT PAIRED \u2014 this machine has no BirdyBeep machine token, so nothing was sent (and nothing was queued). Run `birdybeep pair`."
|
|
1213
1274
|
);
|
|
1275
|
+
} else if (result.tokenStoreUnavailable !== void 0) {
|
|
1276
|
+
ctx.io.line(
|
|
1277
|
+
`\u2022 Could not read the machine token (${result.tokenStoreUnavailable.reason}) \u2014 the test event was queued and delivers once the token store is readable. If your keychain is locked, unlock it and run \`birdybeep test\` again.`
|
|
1278
|
+
);
|
|
1214
1279
|
} else if (result.outcome === "queued") {
|
|
1215
1280
|
ctx.io.line("\u2022 Offline \u2014 test event queued; it will deliver when you reconnect.");
|
|
1216
1281
|
} else {
|
|
@@ -1913,7 +1978,8 @@ function createStatusCommand(deps = {}) {
|
|
|
1913
1978
|
usage: "birdybeep status [--json]",
|
|
1914
1979
|
run: async (ctx) => {
|
|
1915
1980
|
const machine = machineIdentity();
|
|
1916
|
-
const
|
|
1981
|
+
const pairing = await pairingReport(deps.tokenOptions ?? {});
|
|
1982
|
+
const paired = pairing.state === "paired";
|
|
1917
1983
|
const integrations = await gatherIntegrations(adapters);
|
|
1918
1984
|
const surfaces = await gatherSurfaces(adapters, deps.surfaceOptions ?? {});
|
|
1919
1985
|
const depthBefore = localQueueDepth();
|
|
@@ -1925,6 +1991,8 @@ function createStatusCommand(deps = {}) {
|
|
|
1925
1991
|
const report = {
|
|
1926
1992
|
machine,
|
|
1927
1993
|
paired,
|
|
1994
|
+
pairing,
|
|
1995
|
+
// gcgp.23: paired | unpaired | unknown — `paired: false` cannot say which
|
|
1928
1996
|
integrations,
|
|
1929
1997
|
surfaces,
|
|
1930
1998
|
queue: { depthBefore, delivered: drain.delivered, depthAfter, overflowDropped },
|
|
@@ -1935,7 +2003,9 @@ function createStatusCommand(deps = {}) {
|
|
|
1935
2003
|
ctx.io.result(report);
|
|
1936
2004
|
} else {
|
|
1937
2005
|
ctx.io.line(`Machine: ${machine.label} (${machine.os})`);
|
|
1938
|
-
ctx.io.line(
|
|
2006
|
+
ctx.io.line(
|
|
2007
|
+
pairing.state === "paired" ? "Paired: yes" : pairing.state === "unpaired" ? "Paired: no \u2014 run `birdybeep pair`" : `Paired: unknown \u2014 ${describeTokenStoreUnavailable(pairing)}`
|
|
2008
|
+
);
|
|
1939
2009
|
ctx.io.line("Integrations:");
|
|
1940
2010
|
for (const i of integrations) {
|
|
1941
2011
|
ctx.io.line(` ${i.displayName}: ${i.status}`);
|