@birdybeep/cli 0.6.1 → 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-SAUSKJDH.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-SAUSKJDH.js.map +0 -1
package/dist/bin.cjs
CHANGED
|
@@ -48,6 +48,21 @@ async function gatherIntegrations(adapters) {
|
|
|
48
48
|
async function isPaired(tokenOptions = {}) {
|
|
49
49
|
return await (0, import_agent_core.getToken)(tokenOptions) !== null;
|
|
50
50
|
}
|
|
51
|
+
async function pairingReport(tokenOptions = {}) {
|
|
52
|
+
const lookup = await (0, import_agent_core.readToken)(tokenOptions);
|
|
53
|
+
if (lookup.state === "present") return { state: "paired" };
|
|
54
|
+
if (lookup.state === "absent") return { state: "unpaired" };
|
|
55
|
+
return { state: "unknown", reason: lookup.reason, store: lookup.store };
|
|
56
|
+
}
|
|
57
|
+
function describeTokenStoreUnavailable(report) {
|
|
58
|
+
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.`;
|
|
59
|
+
}
|
|
60
|
+
function tokenStoreRemedy(report) {
|
|
61
|
+
if (report.store === "file") {
|
|
62
|
+
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.";
|
|
63
|
+
}
|
|
64
|
+
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`.";
|
|
65
|
+
}
|
|
51
66
|
function localQueueDepth() {
|
|
52
67
|
return new import_agent_core.LocalEventQueue().size();
|
|
53
68
|
}
|
|
@@ -652,16 +667,36 @@ function createDoctorCommand(deps = {}) {
|
|
|
652
667
|
usage: "birdybeep doctor [--json]",
|
|
653
668
|
run: async (ctx) => {
|
|
654
669
|
const checks = [];
|
|
655
|
-
const apiUrl = resolveApiUrl();
|
|
656
|
-
const
|
|
670
|
+
const apiUrl = deps.baseUrl ?? resolveApiUrl();
|
|
671
|
+
const pairing = await pairingReport(deps.tokenOptions ?? {});
|
|
657
672
|
checks.push(
|
|
658
|
-
paired ? { name: "Machine token", ok: true } : {
|
|
673
|
+
pairing.state === "paired" ? { name: "Machine token", ok: true } : pairing.state === "unpaired" ? {
|
|
659
674
|
name: "Machine token",
|
|
660
675
|
ok: false,
|
|
661
676
|
detail: "No machine token found.",
|
|
662
677
|
remedy: "Run `birdybeep pair` to pair this machine."
|
|
678
|
+
} : {
|
|
679
|
+
name: "Machine token",
|
|
680
|
+
ok: false,
|
|
681
|
+
detail: describeTokenStoreUnavailable(pairing),
|
|
682
|
+
remedy: tokenStoreRemedy(pairing)
|
|
663
683
|
}
|
|
664
684
|
);
|
|
685
|
+
const reach = (0, import_agent_core4.describeReachability)(
|
|
686
|
+
await (0, import_agent_core4.fetchPushReachability)({
|
|
687
|
+
baseUrl: apiUrl,
|
|
688
|
+
...deps.tokenOptions ? { tokenOptions: deps.tokenOptions } : {},
|
|
689
|
+
...deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {}
|
|
690
|
+
})
|
|
691
|
+
);
|
|
692
|
+
if (reach !== null) {
|
|
693
|
+
checks.push({
|
|
694
|
+
name: "Push reachability",
|
|
695
|
+
ok: reach.ok,
|
|
696
|
+
detail: reach.detail,
|
|
697
|
+
...reach.remedy !== void 0 ? { remedy: reach.remedy } : {}
|
|
698
|
+
});
|
|
699
|
+
}
|
|
665
700
|
const unpaired = unpairedActivity();
|
|
666
701
|
if (unpaired !== null) {
|
|
667
702
|
checks.push({
|
|
@@ -733,6 +768,8 @@ function createDoctorCommand(deps = {}) {
|
|
|
733
768
|
ctx.io.result({
|
|
734
769
|
ok,
|
|
735
770
|
checks,
|
|
771
|
+
pairing,
|
|
772
|
+
// gcgp.23: paired | unpaired | unknown — never a bare boolean
|
|
736
773
|
surfaces: surfaceGroups,
|
|
737
774
|
queue: { depthBefore, delivered: drain.delivered, depthAfter, overflowDropped },
|
|
738
775
|
...unpaired !== null ? { unpairedActivity: unpaired } : {},
|
|
@@ -979,13 +1016,20 @@ function createHookCommand(deps = {}) {
|
|
|
979
1016
|
outcome: result.outcome,
|
|
980
1017
|
eventType: result.eventType,
|
|
981
1018
|
...result.send?.decision ? { decision: result.send.decision } : {},
|
|
982
|
-
...result.send?.status !== void 0 ? { status: result.send.status } : {}
|
|
1019
|
+
...result.send?.status !== void 0 ? { status: result.send.status } : {},
|
|
1020
|
+
...result.send?.tokenStoreUnavailable !== void 0 ? { tokenStore: "unavailable" } : {}
|
|
983
1021
|
});
|
|
984
1022
|
if (result.outcome === "unpaired") {
|
|
985
1023
|
ctx.io.errline(
|
|
986
1024
|
"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)."
|
|
987
1025
|
);
|
|
988
1026
|
}
|
|
1027
|
+
const unavailable = result.send?.tokenStoreUnavailable;
|
|
1028
|
+
if (unavailable !== void 0) {
|
|
1029
|
+
ctx.io.errline(
|
|
1030
|
+
`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.`
|
|
1031
|
+
);
|
|
1032
|
+
}
|
|
989
1033
|
return EXIT.OK;
|
|
990
1034
|
}
|
|
991
1035
|
};
|
|
@@ -1118,7 +1162,7 @@ async function pairTokenPoll(apiUrl, deviceCode, fetchImpl, machineFingerprint,
|
|
|
1118
1162
|
}
|
|
1119
1163
|
|
|
1120
1164
|
// src/version.ts
|
|
1121
|
-
var CLI_VERSION = "0.
|
|
1165
|
+
var CLI_VERSION = "0.7.0".length > 0 ? "0.7.0" : "0.0.0";
|
|
1122
1166
|
|
|
1123
1167
|
// src/commands/setup.ts
|
|
1124
1168
|
var import_claude_code5 = require("@birdybeep/claude-code");
|
|
@@ -1160,16 +1204,33 @@ function createTestCommand(deps = {}) {
|
|
|
1160
1204
|
usage: "birdybeep test [--json]",
|
|
1161
1205
|
run: async (ctx) => {
|
|
1162
1206
|
const event = buildTestEvent();
|
|
1163
|
-
const
|
|
1207
|
+
const baseUrl = deps.baseUrl ?? resolveApiUrl();
|
|
1208
|
+
const result = await makeSender(baseUrl).send(event);
|
|
1164
1209
|
if (ctx.flags.json) {
|
|
1165
1210
|
ctx.io.result({
|
|
1166
1211
|
outcome: result.outcome,
|
|
1167
1212
|
...result.status ? { status: result.status } : {},
|
|
1168
|
-
...result.decision ? { decision: result.decision } : {}
|
|
1213
|
+
...result.decision ? { decision: result.decision } : {},
|
|
1214
|
+
...result.tokenStoreUnavailable !== void 0 ? { tokenStore: "unavailable", tokenStoreReason: result.tokenStoreUnavailable.reason } : {}
|
|
1169
1215
|
});
|
|
1170
1216
|
} else if (result.outcome === "delivered") {
|
|
1171
1217
|
if (result.decision === "notified" || result.decision === void 0) {
|
|
1172
|
-
|
|
1218
|
+
const reach = await (0, import_agent_core8.fetchPushReachability)({
|
|
1219
|
+
baseUrl,
|
|
1220
|
+
...deps.tokenOptions ? { tokenOptions: deps.tokenOptions } : {},
|
|
1221
|
+
...deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {}
|
|
1222
|
+
});
|
|
1223
|
+
if (reach.state === "ok" && reach.data.active_device_count === 0) {
|
|
1224
|
+
ctx.io.line(
|
|
1225
|
+
"\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)."
|
|
1226
|
+
);
|
|
1227
|
+
} else if (reach.state === "ok") {
|
|
1228
|
+
ctx.io.line(
|
|
1229
|
+
`\u2713 Test event accepted and queued for ${String(reach.data.active_device_count)} registered device(s) \u2014 check your phone for a test Beep.`
|
|
1230
|
+
);
|
|
1231
|
+
} else {
|
|
1232
|
+
ctx.io.line("\u2713 Test event accepted by the backend \u2014 check your phone for a test Beep.");
|
|
1233
|
+
}
|
|
1173
1234
|
} else if (result.decision === "suppressed") {
|
|
1174
1235
|
ctx.io.line(
|
|
1175
1236
|
"\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`."
|
|
@@ -1187,6 +1248,10 @@ function createTestCommand(deps = {}) {
|
|
|
1187
1248
|
ctx.io.line(
|
|
1188
1249
|
"\u2717 NOT PAIRED \u2014 this machine has no BirdyBeep machine token, so nothing was sent (and nothing was queued). Run `birdybeep pair`."
|
|
1189
1250
|
);
|
|
1251
|
+
} else if (result.tokenStoreUnavailable !== void 0) {
|
|
1252
|
+
ctx.io.line(
|
|
1253
|
+
`\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.`
|
|
1254
|
+
);
|
|
1190
1255
|
} else if (result.outcome === "queued") {
|
|
1191
1256
|
ctx.io.line("\u2022 Offline \u2014 test event queued; it will deliver when you reconnect.");
|
|
1192
1257
|
} else {
|
|
@@ -1889,7 +1954,8 @@ function createStatusCommand(deps = {}) {
|
|
|
1889
1954
|
usage: "birdybeep status [--json]",
|
|
1890
1955
|
run: async (ctx) => {
|
|
1891
1956
|
const machine = machineIdentity();
|
|
1892
|
-
const
|
|
1957
|
+
const pairing = await pairingReport(deps.tokenOptions ?? {});
|
|
1958
|
+
const paired = pairing.state === "paired";
|
|
1893
1959
|
const integrations = await gatherIntegrations(adapters);
|
|
1894
1960
|
const surfaces = await gatherSurfaces(adapters, deps.surfaceOptions ?? {});
|
|
1895
1961
|
const depthBefore = localQueueDepth();
|
|
@@ -1901,6 +1967,8 @@ function createStatusCommand(deps = {}) {
|
|
|
1901
1967
|
const report = {
|
|
1902
1968
|
machine,
|
|
1903
1969
|
paired,
|
|
1970
|
+
pairing,
|
|
1971
|
+
// gcgp.23: paired | unpaired | unknown — `paired: false` cannot say which
|
|
1904
1972
|
integrations,
|
|
1905
1973
|
surfaces,
|
|
1906
1974
|
queue: { depthBefore, delivered: drain.delivered, depthAfter, overflowDropped },
|
|
@@ -1911,7 +1979,9 @@ function createStatusCommand(deps = {}) {
|
|
|
1911
1979
|
ctx.io.result(report);
|
|
1912
1980
|
} else {
|
|
1913
1981
|
ctx.io.line(`Machine: ${machine.label} (${machine.os})`);
|
|
1914
|
-
ctx.io.line(
|
|
1982
|
+
ctx.io.line(
|
|
1983
|
+
pairing.state === "paired" ? "Paired: yes" : pairing.state === "unpaired" ? "Paired: no \u2014 run `birdybeep pair`" : `Paired: unknown \u2014 ${describeTokenStoreUnavailable(pairing)}`
|
|
1984
|
+
);
|
|
1915
1985
|
ctx.io.line("Integrations:");
|
|
1916
1986
|
for (const i of integrations) {
|
|
1917
1987
|
ctx.io.line(` ${i.displayName}: ${i.status}`);
|