@pushary/agent-hooks 1.9.7 → 1.9.9
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/CHANGELOG.md +18 -0
- package/README.md +3 -3
- package/data/cursor-plugin/README.md +3 -7
- package/data/vscode-plugin/README.md +1 -1
- package/dist/bin/pushary-bell-hook.js +22 -24
- package/dist/bin/pushary-bell.js +13 -13
- package/dist/bin/pushary-claude.js +28 -30
- package/dist/bin/pushary-clean.js +113 -94
- package/dist/bin/pushary-codex-bridge.js +20 -20
- package/dist/bin/pushary-codex-hook.js +36 -38
- package/dist/bin/pushary-codex.js +13 -13
- package/dist/bin/pushary-connect.js +48 -22
- package/dist/bin/pushary-cowork.js +5 -5
- package/dist/bin/pushary-daemon.js +50 -40
- package/dist/bin/pushary-disconnect.js +188 -56
- package/dist/bin/pushary-doctor.js +105 -85
- package/dist/bin/pushary-elicitation-hook.js +25 -27
- package/dist/bin/pushary-gemini-bridge.js +13 -13
- package/dist/bin/pushary-gemini-hook.js +31 -33
- package/dist/bin/pushary-hook.js +36 -39
- package/dist/bin/pushary-login.js +12 -12
- package/dist/bin/pushary-logout.js +105 -42
- package/dist/bin/pushary-mcp.js +9 -9
- package/dist/bin/pushary-mode.js +28 -31
- package/dist/bin/pushary-notification-hook.js +29 -32
- package/dist/bin/pushary-opencode-hook.js +30 -32
- package/dist/bin/pushary-permission-denied-hook.js +30 -33
- package/dist/bin/pushary-permission-hook.js +33 -36
- package/dist/bin/pushary-post-hook.js +30 -33
- package/dist/bin/pushary-prompt-hook.js +29 -32
- package/dist/bin/pushary-session-end-hook.js +29 -32
- package/dist/bin/pushary-session-start-hook.js +33 -36
- package/dist/bin/pushary-setup.js +168 -160
- package/dist/bin/pushary-stats.js +5 -5
- package/dist/bin/pushary-status.js +65 -19
- package/dist/bin/pushary-stop-hook.js +29 -32
- package/dist/bin/pushary-stopfailure-hook.js +29 -32
- package/dist/bin/pushary-suggestions.js +19 -21
- package/dist/bin/pushary-transcript-register.js +18 -20
- package/dist/bin/pushary-transcripts.js +7 -7
- package/dist/bin/pushary-upgrade.js +50 -26
- package/dist/bin/pushary-wait.js +23 -19
- package/dist/bin/pushary.js +15 -14
- package/dist/{chunk-4FK6RZVJ.js → chunk-462EQA6K.js} +1 -1
- package/dist/{chunk-STQRUH3S.js → chunk-5DCDQ5VW.js} +59 -15
- package/dist/{chunk-JXISQ7DT.js → chunk-5N5L6DNN.js} +3 -3
- package/dist/{chunk-QR6VE5ME.js → chunk-5RGA636G.js} +79 -17
- package/dist/{chunk-L76HTPU6.js → chunk-6AYSKVLL.js} +3 -3
- package/dist/{chunk-NIBFSARF.js → chunk-6EBGOHDJ.js} +33 -13
- package/dist/{chunk-QQ4HBXZC.js → chunk-6W5M3MSE.js} +84 -673
- package/dist/{chunk-R3YW55MY.js → chunk-AI7RMFVV.js} +29 -26
- package/dist/{chunk-AUUXS44H.js → chunk-APP43AW7.js} +1 -1
- package/dist/{chunk-RQGODFQN.js → chunk-AZOKPWVI.js} +1 -1
- package/dist/{chunk-3GNUXXDZ.js → chunk-B5NMSP3V.js} +2 -2
- package/dist/{chunk-4D2AYNSE.js → chunk-BNSKVIAW.js} +2 -2
- package/dist/chunk-BYLKCZ2G.js +367 -0
- package/dist/{chunk-X5NXPCIC.js → chunk-BZLHTMT6.js} +89 -7
- package/dist/{chunk-BTQGAXZ3.js → chunk-COQ64C4F.js} +10 -10
- package/dist/{chunk-N4EUSDKX.js → chunk-DCCSULXK.js} +14 -14
- package/dist/{chunk-JWKBDSPF.js → chunk-DP3WX7FW.js} +2 -2
- package/dist/chunk-E5HOHIUV.js +52 -0
- package/dist/{chunk-GU3EJCVV.js → chunk-EA5NWDK7.js} +4 -0
- package/dist/chunk-EIAEUG7G.js +46 -0
- package/dist/{chunk-EB4XGVBG.js → chunk-EUW7JL2K.js} +0 -32
- package/dist/{chunk-T7Y5EADL.js → chunk-F7R3SZ4Q.js} +2 -2
- package/dist/{chunk-H37L7TT3.js → chunk-G7RIDXAT.js} +2 -2
- package/dist/{chunk-W2KI5KPD.js → chunk-H5T27W7M.js} +2 -2
- package/dist/chunk-HBWYMRR5.js +94 -0
- package/dist/{chunk-CBQACHKY.js → chunk-IIVZZMSO.js} +1 -1
- package/dist/{chunk-Z6HPS67T.js → chunk-IRHABAQT.js} +1 -1
- package/dist/{chunk-QTO6HEZD.js → chunk-K545B734.js} +2 -2
- package/dist/{chunk-KYO45G5L.js → chunk-KOWFRUIT.js} +1 -1
- package/dist/{chunk-QFEM7R6T.js → chunk-KQFTBQ66.js} +11 -11
- package/dist/chunk-LENBKYRB.js +50 -0
- package/dist/{chunk-JCWZ23MJ.js → chunk-M3STIAGU.js} +3 -3
- package/dist/{chunk-6DJTDHBI.js → chunk-MD4SVNT6.js} +1 -1
- package/dist/{chunk-7264S5HZ.js → chunk-MLGIVVSG.js} +1 -1
- package/dist/{chunk-H7MMU64M.js → chunk-NGKUXZID.js} +2 -2
- package/dist/{chunk-JWQZSYCK.js → chunk-NUVGDBZC.js} +1 -1
- package/dist/{chunk-AQ55ZSSS.js → chunk-OAYWO5NP.js} +1 -1
- package/dist/chunk-Q6C6ILUS.js +49 -0
- package/dist/{chunk-MBK7N46B.js → chunk-QIOIO7VN.js} +6 -6
- package/dist/{chunk-KFKL3FHS.js → chunk-QRXPWW3M.js} +4 -3
- package/dist/{chunk-7OIWWZAD.js → chunk-QTIUJZRX.js} +3 -3
- package/dist/{chunk-XWAYAO3V.js → chunk-R5RIVOPL.js} +2 -2
- package/dist/{chunk-ADSQDYYG.js → chunk-REU2VQPH.js} +54 -5
- package/dist/{chunk-GKI6LFAV.js → chunk-RQ32ADJP.js} +2 -2
- package/dist/{chunk-VXRXFU6Q.js → chunk-SZ4Q6ZVS.js} +14 -7
- package/dist/{chunk-KT5E2RLS.js → chunk-T6ZN4TEF.js} +1 -1
- package/dist/{chunk-UFVGSEWH.js → chunk-TO3PS646.js} +2 -2
- package/dist/chunk-UAP5DS6P.js +599 -0
- package/dist/{chunk-MZPXVH4A.js → chunk-UF6RBP5V.js} +204 -28
- package/dist/{chunk-AVNKVF7N.js → chunk-UPIZSCYD.js} +4 -4
- package/dist/{chunk-3PVDOCFI.js → chunk-VHPFNLRS.js} +5 -5
- package/dist/{chunk-HPRZJKRO.js → chunk-VIIHC42X.js} +1 -1
- package/dist/{chunk-D6S5EKXA.js → chunk-WRPYCIV2.js} +8 -12
- package/dist/{chunk-ZUTU43FT.js → chunk-Z23ZBYDW.js} +6 -4
- package/dist/{chunk-SBLPHUEB.js → chunk-ZGADIZDS.js} +8 -6
- package/dist/{global-upgrade-E2HUEB4B.js → global-upgrade-H272QOGD.js} +6 -6
- package/dist/{paths-QVTEGNZV.js → paths-HMVOTFUN.js} +2 -2
- package/dist/reapply-Q5NHDTVU.js +55 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +19 -20
- package/dist/{upgrade-lock-JCIDZMHF.js → upgrade-lock-L3GHFIRW.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-4YO4T5FV.js +0 -149
- package/dist/chunk-ANEAA37E.js +0 -197
- package/dist/chunk-MNWRUGMH.js +0 -86
- package/dist/chunk-RQSOEB4S.js +0 -44
- package/dist/chunk-SD3272LS.js +0 -143
- package/dist/reapply-5QVKM6LA.js +0 -38
|
@@ -1,14 +1,36 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./chunk-
|
|
2
|
+
compatibleConfigFile
|
|
3
|
+
} from "./chunk-UF6RBP5V.js";
|
|
4
|
+
import {
|
|
5
|
+
hookOwnerOf,
|
|
6
|
+
hookOwnerOfCommands,
|
|
7
|
+
liveBridgeProbe,
|
|
8
|
+
resolveBridgeStub
|
|
9
|
+
} from "./chunk-BYLKCZ2G.js";
|
|
10
|
+
import {
|
|
11
|
+
claudeSettings,
|
|
12
|
+
codexHooksJson,
|
|
13
|
+
cursorUserHooks,
|
|
14
|
+
geminiSettings,
|
|
15
|
+
guardedArgv,
|
|
16
|
+
pusharyDir,
|
|
17
|
+
vscodePluginDir
|
|
18
|
+
} from "./chunk-Z23ZBYDW.js";
|
|
19
|
+
import {
|
|
20
|
+
readJsonSafe
|
|
21
|
+
} from "./chunk-T7E75EKA.js";
|
|
4
22
|
import {
|
|
5
23
|
HOOK_BUDGETS,
|
|
6
|
-
|
|
7
|
-
|
|
24
|
+
HOOK_COMPATIBLE_PROFILES,
|
|
25
|
+
HOOK_LOCATOR_BINARY,
|
|
26
|
+
OPENCODE_APPROVAL_EVENT,
|
|
27
|
+
hookCompatibleProfile
|
|
28
|
+
} from "./chunk-5RGA636G.js";
|
|
8
29
|
|
|
9
30
|
// src/opencode-plugin.ts
|
|
10
31
|
var OPENCODE_PLUGIN_MARKER = "pushary-opencode-plugin w1";
|
|
11
32
|
var OPENCODE_PLUGIN_PLACEHOLDER = "__PUSHARY_COMMAND__";
|
|
33
|
+
var OPENCODE_APPROVAL_EVENTS_PLACEHOLDER = "__PUSHARY_APPROVAL_EVENTS__";
|
|
12
34
|
var OPENCODE_PLUGIN_FILE = "pushary.js";
|
|
13
35
|
var OPENCODE_PLUGIN_DIR = "plugins";
|
|
14
36
|
var OPENCODE_PLUGIN_SIBLING = "package.json";
|
|
@@ -262,7 +284,7 @@ export const PusharyPlugin = async ({ client, directory, worktree }) => {
|
|
|
262
284
|
try {
|
|
263
285
|
const type = event && event.type
|
|
264
286
|
const properties = event && event.properties
|
|
265
|
-
if (${
|
|
287
|
+
if (${OPENCODE_APPROVAL_EVENTS_PLACEHOLDER}.includes(type)) {
|
|
266
288
|
const asked = askedFrom(properties)
|
|
267
289
|
if (asked) void gate(asked)
|
|
268
290
|
return
|
|
@@ -295,12 +317,29 @@ var openCodePluginModule = () => ({
|
|
|
295
317
|
marker: OPENCODE_PLUGIN_MARKER,
|
|
296
318
|
source: openCodePluginSource(),
|
|
297
319
|
placeholder: OPENCODE_PLUGIN_PLACEHOLDER,
|
|
320
|
+
approvalEvents: {
|
|
321
|
+
placeholder: OPENCODE_APPROVAL_EVENTS_PLACEHOLDER,
|
|
322
|
+
events: OPENCODE_ASKED_EVENTS
|
|
323
|
+
},
|
|
298
324
|
sibling: {
|
|
299
325
|
path: OPENCODE_PLUGIN_SIBLING,
|
|
300
326
|
contents: OPENCODE_PLUGIN_SIBLING_CONTENTS
|
|
301
327
|
}
|
|
302
328
|
});
|
|
303
|
-
var renderOpenCodePlugin = (module, argv) => module.source.replace(module.placeholder, JSON.stringify(argv));
|
|
329
|
+
var renderOpenCodePlugin = (module, argv, holdsApprovals = true) => module.source.replace(module.placeholder, JSON.stringify(argv)).replace(module.approvalEvents.placeholder, JSON.stringify(holdsApprovals ? module.approvalEvents.events : []));
|
|
330
|
+
var COMMAND_LINE = /^const COMMAND = (.*)$/m;
|
|
331
|
+
var isArgv = (value) => Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
332
|
+
var openCodePluginArgv = (contents) => {
|
|
333
|
+
if (!isOpenCodePluginOurs(contents)) return null;
|
|
334
|
+
const line = contents.match(COMMAND_LINE)?.[1];
|
|
335
|
+
if (line === void 0) return null;
|
|
336
|
+
try {
|
|
337
|
+
const parsed = JSON.parse(line);
|
|
338
|
+
return isArgv(parsed) ? parsed : null;
|
|
339
|
+
} catch {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
};
|
|
304
343
|
var isOpenCodePluginOurs = (contents) => contents.includes(OPENCODE_PLUGIN_MARKER);
|
|
305
344
|
|
|
306
345
|
// src/opencode-config.ts
|
|
@@ -362,6 +401,46 @@ var removeOpenCodeMcpServer = (config) => {
|
|
|
362
401
|
return true;
|
|
363
402
|
};
|
|
364
403
|
|
|
404
|
+
// src/setup/agent-hook-owner.ts
|
|
405
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
406
|
+
import { join as join2 } from "path";
|
|
407
|
+
var COMPATIBLE_HOOK_FILES = Object.fromEntries(
|
|
408
|
+
HOOK_COMPATIBLE_PROFILES.map((profile) => [profile.agentType, () => compatibleConfigFile(profile)])
|
|
409
|
+
);
|
|
410
|
+
var HOOK_FILES = {
|
|
411
|
+
claude_code: claudeSettings,
|
|
412
|
+
codex: codexHooksJson,
|
|
413
|
+
gemini_cli: geminiSettings,
|
|
414
|
+
cursor: cursorUserHooks,
|
|
415
|
+
vscode: () => join2(vscodePluginDir(), "hooks", "hooks.json"),
|
|
416
|
+
...COMPATIBLE_HOOK_FILES
|
|
417
|
+
};
|
|
418
|
+
var agentHookFile = (agent) => HOOK_FILES[agent]?.() ?? null;
|
|
419
|
+
var readTextOrNull = (path) => {
|
|
420
|
+
try {
|
|
421
|
+
return readFileSync2(path, "utf-8");
|
|
422
|
+
} catch {
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
var openCodePluginOwner = (appAvailable) => {
|
|
427
|
+
const contents = readTextOrNull(openCodePluginFile());
|
|
428
|
+
return hookOwnerOfCommands(contents === null ? [] : openCodePluginArgv(contents) ?? [], appAvailable);
|
|
429
|
+
};
|
|
430
|
+
var agentHookOwner = (agent, appAvailable) => {
|
|
431
|
+
if (agent === "opencode") return openCodePluginOwner(appAvailable);
|
|
432
|
+
const file = agentHookFile(agent);
|
|
433
|
+
if (!file) return "none";
|
|
434
|
+
const document = readJsonSafe(file);
|
|
435
|
+
const profile = hookCompatibleProfile(agent);
|
|
436
|
+
return hookOwnerOf(
|
|
437
|
+
document.kind === "ok" ? document.value : null,
|
|
438
|
+
appAvailable,
|
|
439
|
+
profile ? profile.hooksKeyPath : void 0
|
|
440
|
+
);
|
|
441
|
+
};
|
|
442
|
+
var macAppBridgeAvailable = () => resolveBridgeStub(join2(pusharyDir(), "bin", HOOK_LOCATOR_BINARY), liveBridgeProbe()).kind === "bundle";
|
|
443
|
+
|
|
365
444
|
export {
|
|
366
445
|
OPENCODE_PLUGIN_PLACEHOLDER,
|
|
367
446
|
OPENCODE_PLUGIN_SIBLING,
|
|
@@ -379,5 +458,8 @@ export {
|
|
|
379
458
|
openCodeConfigFile,
|
|
380
459
|
openCodeInstructionsFile,
|
|
381
460
|
addOpenCodeMcpServer,
|
|
382
|
-
removeOpenCodeMcpServer
|
|
461
|
+
removeOpenCodeMcpServer,
|
|
462
|
+
agentHookFile,
|
|
463
|
+
agentHookOwner,
|
|
464
|
+
macAppBridgeAvailable
|
|
383
465
|
};
|
|
@@ -4,40 +4,40 @@ import {
|
|
|
4
4
|
savePin,
|
|
5
5
|
verifyRecipients
|
|
6
6
|
} from "./chunk-SGZJ5LYH.js";
|
|
7
|
-
import {
|
|
8
|
-
hookOwnerOf
|
|
9
|
-
} from "./chunk-SD3272LS.js";
|
|
10
7
|
import {
|
|
11
8
|
ensureDaemonRunning
|
|
12
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-SZ4Q6ZVS.js";
|
|
13
10
|
import {
|
|
14
11
|
buildTranscriptRecords,
|
|
15
12
|
decodePublicKey,
|
|
16
13
|
generateSessionKey,
|
|
17
14
|
wrapSessionKey
|
|
18
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-APP43AW7.js";
|
|
19
16
|
import {
|
|
20
17
|
fetchTranscriptRecipients,
|
|
21
18
|
uploadTranscriptRecords
|
|
22
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-462EQA6K.js";
|
|
23
20
|
import {
|
|
24
21
|
transcriptEnvironmentPreference,
|
|
25
22
|
transcriptsEnabled
|
|
26
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-VIIHC42X.js";
|
|
24
|
+
import {
|
|
25
|
+
hookOwnerOf
|
|
26
|
+
} from "./chunk-BYLKCZ2G.js";
|
|
27
27
|
import {
|
|
28
28
|
readTranscriptPreference
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-REU2VQPH.js";
|
|
30
30
|
import {
|
|
31
31
|
codexHome,
|
|
32
32
|
pusharyDir
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-Z23ZBYDW.js";
|
|
34
34
|
import {
|
|
35
35
|
writeJsonAtomic
|
|
36
36
|
} from "./chunk-T7E75EKA.js";
|
|
37
37
|
import {
|
|
38
38
|
getApiKey,
|
|
39
39
|
getBaseUrl
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-IRHABAQT.js";
|
|
41
41
|
|
|
42
42
|
// src/transcript-registration.ts
|
|
43
43
|
import { createHash } from "crypto";
|
|
@@ -14,19 +14,19 @@ import {
|
|
|
14
14
|
} from "./chunk-U4TMAANR.js";
|
|
15
15
|
import {
|
|
16
16
|
callMcpTool
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-6AYSKVLL.js";
|
|
18
18
|
import {
|
|
19
19
|
reportedInstallSource
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-BNSKVIAW.js";
|
|
21
21
|
import {
|
|
22
22
|
NPX_LATEST_COMMAND
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-5DCDQ5VW.js";
|
|
24
24
|
import {
|
|
25
25
|
NO_PAIRING_COMPUTER,
|
|
26
26
|
PAIR_TTL_SECONDS,
|
|
27
27
|
classifyConfirmResponse,
|
|
28
28
|
isAnswerSource
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-5RGA636G.js";
|
|
30
30
|
|
|
31
31
|
// src/reach.ts
|
|
32
32
|
var reachVerdict = (channels) => {
|
|
@@ -155,7 +155,7 @@ var describeVerifyOutcome = (outcome) => {
|
|
|
155
155
|
ok: false,
|
|
156
156
|
message: "Nothing to deliver to. Agents are configured; approvals will fall back to the terminal.",
|
|
157
157
|
next: [
|
|
158
|
-
"Run pushary
|
|
158
|
+
"Run pushary pair to pair your phone.",
|
|
159
159
|
"Then pushary doctor --roundtrip to test a synthetic question and answer."
|
|
160
160
|
]
|
|
161
161
|
};
|
|
@@ -165,7 +165,7 @@ var describeVerifyOutcome = (outcome) => {
|
|
|
165
165
|
message: `Delivered to ${plural2(outcome.recipients, "device")} on this site, none of them yours.`,
|
|
166
166
|
next: [
|
|
167
167
|
`Approvals for your agent would wake one of your ${plural2(outcome.otherMembers, "teammate")}.`,
|
|
168
|
-
"Run pushary
|
|
168
|
+
"Run pushary pair to pair your own phone."
|
|
169
169
|
]
|
|
170
170
|
};
|
|
171
171
|
case "unattributable":
|
|
@@ -174,7 +174,7 @@ var describeVerifyOutcome = (outcome) => {
|
|
|
174
174
|
message: `Delivered to ${plural2(outcome.recipients, "device")} on this site, and no way to tell whose.`,
|
|
175
175
|
next: [
|
|
176
176
|
"Browser subscriptions carry no owner, and this site has other members.",
|
|
177
|
-
"Install the Pushary app with pushary
|
|
177
|
+
"Install the Pushary app and pair it with pushary pair, or run pushary doctor --roundtrip to prove it reaches you."
|
|
178
178
|
]
|
|
179
179
|
};
|
|
180
180
|
case "error":
|
|
@@ -319,8 +319,8 @@ var describeRoundTripOutcome = (outcome) => {
|
|
|
319
319
|
ok: false,
|
|
320
320
|
message: "Nothing to ask. No phone or browser is connected to this site.",
|
|
321
321
|
next: [
|
|
322
|
-
"Run pushary
|
|
323
|
-
"Or pushary
|
|
322
|
+
"Run pushary pair to pair your phone.",
|
|
323
|
+
"Or pushary pair --app if you already have the Pushary app."
|
|
324
324
|
]
|
|
325
325
|
};
|
|
326
326
|
case "error":
|
|
@@ -538,14 +538,14 @@ var waitForDevice = async (apiKey, baseline) => {
|
|
|
538
538
|
consecutiveFailures = 0;
|
|
539
539
|
const channels = probe.status;
|
|
540
540
|
if (reachesYou(channels) || channels.webActive > baseline.webActive) {
|
|
541
|
-
stop(check, "Phone
|
|
541
|
+
stop(check, "Phone paired");
|
|
542
542
|
return { kind: "connected", channels };
|
|
543
543
|
}
|
|
544
544
|
await sleep(CONNECT_POLL_INTERVAL_MS);
|
|
545
545
|
}
|
|
546
546
|
stop(yellow("!"), "Didn't detect a connection yet");
|
|
547
547
|
console.log(` ${dim("Signed in on the app already? Open it and allow notifications.")}`);
|
|
548
|
-
console.log(` ${dim("Signing in alone does not
|
|
548
|
+
console.log(` ${dim("Signing in alone does not pair the phone. Then run")} ${cyan("pushary doctor")}${dim(".")}`);
|
|
549
549
|
return { kind: "timeout" };
|
|
550
550
|
} catch (err) {
|
|
551
551
|
stop(yellow("!"), `Couldn't check connection ${dim(`(${err instanceof Error ? err.message : "network error"})`)}`);
|
|
@@ -588,14 +588,14 @@ var connectDevice = async (apiKey, options = {}) => {
|
|
|
588
588
|
}
|
|
589
589
|
const site = await fetchSite(apiKey);
|
|
590
590
|
if (!site) {
|
|
591
|
-
console.log(` ${yellow("!")} Couldn't load your subscribe link.
|
|
591
|
+
console.log(` ${yellow("!")} Couldn't load your subscribe link. Pair your phone later at ${cyan("pushary.com/download")}.`);
|
|
592
592
|
return phoneFailure("no_subscribe_link");
|
|
593
593
|
}
|
|
594
594
|
console.log();
|
|
595
595
|
if (channels.site !== null && channels.site.otherMembers > 0 && channels.phoneReachable) {
|
|
596
596
|
printSiteOnlyWarning(channels);
|
|
597
597
|
} else {
|
|
598
|
-
console.log(` ${bold("
|
|
598
|
+
console.log(` ${bold("Pair your phone")}`);
|
|
599
599
|
if (channels.webDesktop > 0) {
|
|
600
600
|
console.log(` ${dim("A browser on this computer is subscribed, but no phone is connected yet.")}`);
|
|
601
601
|
}
|
|
@@ -727,7 +727,7 @@ var printConnectInstructions = async (apiKey) => {
|
|
|
727
727
|
}
|
|
728
728
|
const site = await fetchSite(apiKey);
|
|
729
729
|
const target = site?.subscribeUrl ?? "https://pushary.com/download";
|
|
730
|
-
console.log(` ${dim("
|
|
730
|
+
console.log(` ${dim("Pair your phone for push notifications at")} ${cyan(target)}`);
|
|
731
731
|
console.log(` ${dim("or get the Pushary app at")} ${cyan("https://pushary.com/download")}`);
|
|
732
732
|
return phoneFailure("no_device");
|
|
733
733
|
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
macAppBridgeAvailable
|
|
3
|
+
} from "./chunk-BZLHTMT6.js";
|
|
4
|
+
import {
|
|
5
|
+
keyPrefix
|
|
6
|
+
} from "./chunk-REU2VQPH.js";
|
|
7
|
+
import {
|
|
8
|
+
bridgeAgentKey
|
|
9
|
+
} from "./chunk-Z23ZBYDW.js";
|
|
10
|
+
import {
|
|
11
|
+
readJsonSafe
|
|
12
|
+
} from "./chunk-T7E75EKA.js";
|
|
13
|
+
import {
|
|
14
|
+
isValidApiKey
|
|
15
|
+
} from "./chunk-5RGA636G.js";
|
|
16
|
+
|
|
17
|
+
// src/shared-mcp-key.ts
|
|
18
|
+
var asRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
19
|
+
var pusharyKey = (value) => typeof value === "string" && isValidApiKey(value.trim()) ? value.trim() : null;
|
|
20
|
+
var bearerKey = (authorization) => typeof authorization === "string" && authorization.startsWith("Bearer ") ? pusharyKey(authorization.slice("Bearer ".length)) : null;
|
|
21
|
+
var mcpServerBearer = (mcpServers) => bearerKey(asRecord(asRecord(asRecord(mcpServers)?.pushary)?.headers)?.Authorization);
|
|
22
|
+
var appAgentKey = (bridgeAgentKey2) => pusharyKey(asRecord(bridgeAgentKey2)?.key);
|
|
23
|
+
var setupReceiptKey = (claudeMcpReceipt) => bearerKey(asRecord(asRecord(asRecord(claudeMcpReceipt)?.installedPushary)?.headers)?.Authorization);
|
|
24
|
+
var macAppKeepsMcpEntry = (entryKey, keys) => {
|
|
25
|
+
if (!entryKey) return true;
|
|
26
|
+
if (keys.appKey) return entryKey === keys.appKey;
|
|
27
|
+
return entryKey !== keys.setupKey;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// src/mac-app-key.ts
|
|
31
|
+
var NOT_CONNECTED = { kind: "not_connected" };
|
|
32
|
+
var CONNECTED_THROUGH_MAC_APP = "This computer is connected through the Pushary Mac app";
|
|
33
|
+
var PAIR_FROM_MAC_APP = "Pair a phone from the Pushary Mac app: Settings > Phone > Pair.";
|
|
34
|
+
var readMacAppAgentKey = () => {
|
|
35
|
+
const stored = readJsonSafe(bridgeAgentKey());
|
|
36
|
+
return stored.kind === "ok" ? appAgentKey(stored.value) : null;
|
|
37
|
+
};
|
|
38
|
+
var macAppConnectionOf = (appKey, appInstalled) => appKey !== null && appInstalled() ? { kind: "connected", keyPrefix: keyPrefix(appKey) } : NOT_CONNECTED;
|
|
39
|
+
var readMacAppConnection = () => macAppConnectionOf(readMacAppAgentKey(), macAppBridgeAvailable);
|
|
40
|
+
var readMacAppConnectionWhenKeyless = (cliKey) => cliKey ? NOT_CONNECTED : readMacAppConnection();
|
|
41
|
+
|
|
42
|
+
export {
|
|
43
|
+
pusharyKey,
|
|
44
|
+
mcpServerBearer,
|
|
45
|
+
setupReceiptKey,
|
|
46
|
+
macAppKeepsMcpEntry,
|
|
47
|
+
CONNECTED_THROUGH_MAC_APP,
|
|
48
|
+
PAIR_FROM_MAC_APP,
|
|
49
|
+
readMacAppAgentKey,
|
|
50
|
+
readMacAppConnection,
|
|
51
|
+
readMacAppConnectionWhenKeyless
|
|
52
|
+
};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/hooks-spec.ts
|
|
2
|
+
var CURSOR_GATE_SCRIPT = "pushary-gate.mjs";
|
|
3
|
+
|
|
1
4
|
// src/diagnostics/service-runtime.ts
|
|
2
5
|
var unescapeXml = (value) => value.replaceAll(""", '"').replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">").replaceAll("&", "&");
|
|
3
6
|
var unquoteSystemd = (value) => value.replaceAll('\\"', '"').replaceAll("\\\\", "\\").replaceAll("%%", "%");
|
|
@@ -37,6 +40,7 @@ var versionManagerOf = (execPath) => {
|
|
|
37
40
|
var describeVersionManagerPin = (execPath, manager) => `The background service is pinned to ${execPath}, which ${manager} manages. Switching Node versions strands it; run pushary daemon install afterwards.`;
|
|
38
41
|
|
|
39
42
|
export {
|
|
43
|
+
CURSOR_GATE_SCRIPT,
|
|
40
44
|
readServiceExecPath,
|
|
41
45
|
versionManagerOf,
|
|
42
46
|
describeVersionManagerPin
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {
|
|
2
|
+
pusharyDir
|
|
3
|
+
} from "./chunk-Z23ZBYDW.js";
|
|
4
|
+
import {
|
|
5
|
+
readJsonSafe,
|
|
6
|
+
writeFileAtomic
|
|
7
|
+
} from "./chunk-T7E75EKA.js";
|
|
8
|
+
import {
|
|
9
|
+
DECLINED_AGENTS_FILE,
|
|
10
|
+
HOOK_SOURCES,
|
|
11
|
+
normalizeAgentId,
|
|
12
|
+
parseDeclinedAgents,
|
|
13
|
+
serializeDeclinedAgents,
|
|
14
|
+
withDeclinedAgent,
|
|
15
|
+
withoutDeclinedAgent
|
|
16
|
+
} from "./chunk-5RGA636G.js";
|
|
17
|
+
|
|
18
|
+
// src/declined-agents-file.ts
|
|
19
|
+
import { join } from "path";
|
|
20
|
+
var DECLINED_AGENTS_MODE = 384;
|
|
21
|
+
var declinedAgentsFile = () => join(pusharyDir(), DECLINED_AGENTS_FILE);
|
|
22
|
+
var readDeclinedAgents = (file = declinedAgentsFile()) => {
|
|
23
|
+
const stored = readJsonSafe(file);
|
|
24
|
+
return stored.kind === "ok" ? parseDeclinedAgents(stored.value) : [];
|
|
25
|
+
};
|
|
26
|
+
var writeDeclinedAgents = (agents, file) => writeFileAtomic(file, serializeDeclinedAgents(agents), DECLINED_AGENTS_MODE, "utf-8");
|
|
27
|
+
var changeDeclinedAgents = (file, applies, next) => {
|
|
28
|
+
const current = readDeclinedAgents(file);
|
|
29
|
+
if (!applies(current)) return "unchanged";
|
|
30
|
+
try {
|
|
31
|
+
writeDeclinedAgents(next(current), file);
|
|
32
|
+
return "changed";
|
|
33
|
+
} catch {
|
|
34
|
+
return "unwritable";
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
var recordDeclinedAgent = (agent, file = declinedAgentsFile()) => changeDeclinedAgents(file, (current) => !current.includes(agent), (current) => withDeclinedAgent(current, agent));
|
|
38
|
+
var clearDeclinedAgent = (agent, file = declinedAgentsFile()) => changeDeclinedAgents(file, (current) => current.includes(agent), (current) => withoutDeclinedAgent(current, agent));
|
|
39
|
+
var declinedAgentForSetupChoice = (choice) => normalizeAgentId(choice, HOOK_SOURCES);
|
|
40
|
+
|
|
41
|
+
export {
|
|
42
|
+
declinedAgentsFile,
|
|
43
|
+
recordDeclinedAgent,
|
|
44
|
+
clearDeclinedAgent,
|
|
45
|
+
declinedAgentForSetupChoice
|
|
46
|
+
};
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
pusharyHookExecutable
|
|
3
|
-
} from "./chunk-4YO4T5FV.js";
|
|
4
|
-
import {
|
|
5
|
-
isProtectedByScope,
|
|
6
|
-
registerHookEntry
|
|
7
|
-
} from "./chunk-ZUTU43FT.js";
|
|
8
|
-
|
|
9
1
|
// src/skills-cli.ts
|
|
10
2
|
import { execSync } from "child_process";
|
|
11
3
|
var PUSHARY_SKILL_SOURCE = "Pushary/pushary-skill";
|
|
@@ -33,28 +25,6 @@ var installAgentSkill = async (request, effects) => {
|
|
|
33
25
|
return "packaged-copy";
|
|
34
26
|
};
|
|
35
27
|
|
|
36
|
-
// src/cursor-config.ts
|
|
37
|
-
var hookCommandOf = (entry) => {
|
|
38
|
-
const command = entry && typeof entry === "object" && !Array.isArray(entry) ? entry.command : void 0;
|
|
39
|
-
return typeof command === "string" ? command : "";
|
|
40
|
-
};
|
|
41
|
-
var isPusharyCursorEntry = (entry) => pusharyHookExecutable(hookCommandOf(entry)) !== null;
|
|
42
|
-
var registerCursorGate = (existing, entry) => registerHookEntry(existing, isPusharyCursorEntry, entry);
|
|
43
|
-
var withoutPusharyCursorHooks = (hooks, scope) => {
|
|
44
|
-
let removed = 0;
|
|
45
|
-
const kept = {};
|
|
46
|
-
for (const [event, entries] of Object.entries(hooks)) {
|
|
47
|
-
if (!Array.isArray(entries)) {
|
|
48
|
-
kept[event] = entries;
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
const others = entries.filter((entry) => !isPusharyCursorEntry(entry) || isProtectedByScope(hookCommandOf(entry), scope));
|
|
52
|
-
removed += entries.length - others.length;
|
|
53
|
-
if (others.length > 0 || entries.length === 0) kept[event] = others;
|
|
54
|
-
}
|
|
55
|
-
return { hooks: kept, removed };
|
|
56
|
-
};
|
|
57
|
-
|
|
58
28
|
// src/cli/dry-run.ts
|
|
59
29
|
import { execFileSync } from "child_process";
|
|
60
30
|
import { rmSync, writeFileSync } from "fs";
|
|
@@ -92,8 +62,6 @@ export {
|
|
|
92
62
|
PUSHARY_SKILL_NAME,
|
|
93
63
|
installSkillViaSkillsCli,
|
|
94
64
|
installAgentSkill,
|
|
95
|
-
registerCursorGate,
|
|
96
|
-
withoutPusharyCursorHooks,
|
|
97
65
|
createGuards,
|
|
98
66
|
describeSetupSideEffects
|
|
99
67
|
};
|
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
resolvePackageVersionFromBinary,
|
|
11
11
|
resolvePathBinary,
|
|
12
12
|
resolvePathBinaryAsync
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-Z23ZBYDW.js";
|
|
14
14
|
import {
|
|
15
15
|
MANAGED_PROVIDERS
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-5RGA636G.js";
|
|
17
17
|
|
|
18
18
|
// src/setup/codex-install.ts
|
|
19
19
|
var NATIVE_BINARY_MIN_BYTES = 20 * 1024 * 1024;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
readConfigFileKey
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-REU2VQPH.js";
|
|
4
4
|
|
|
5
5
|
// src/bell/fleet.ts
|
|
6
6
|
import { closeSync, constants, futimesSync, lstatSync, mkdirSync, openSync, readdirSync, unlinkSync } from "fs";
|
|
@@ -141,7 +141,7 @@ var writeLastShown = (at) => {
|
|
|
141
141
|
}
|
|
142
142
|
};
|
|
143
143
|
var upgradeLine = (context) => ` ${context.liveAgents} agents running. A bell can't tell you which one needs you, and it can't reach your pocket.
|
|
144
|
-
pushary
|
|
144
|
+
pushary pair`;
|
|
145
145
|
var upgradeNotice = (context, deps = {}) => {
|
|
146
146
|
const env = deps.env ?? process.env;
|
|
147
147
|
if (env.PUSHARY_BELL_QUIET === "1" || env.PUSHARY_BELL_QUIET === "true") return null;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SIGNED_OUT_ON_MAC_MESSAGE,
|
|
3
|
+
describeSignedOutKey,
|
|
4
|
+
readSignedOutDiagnosis
|
|
5
|
+
} from "./chunk-Q6C6ILUS.js";
|
|
6
|
+
import {
|
|
7
|
+
createIo
|
|
8
|
+
} from "./chunk-U4TMAANR.js";
|
|
9
|
+
import {
|
|
10
|
+
readKeySource
|
|
11
|
+
} from "./chunk-REU2VQPH.js";
|
|
12
|
+
import {
|
|
13
|
+
absoluteUrl,
|
|
14
|
+
checkApiKey,
|
|
15
|
+
describeKeyCheck,
|
|
16
|
+
keyCheckFromResponse
|
|
17
|
+
} from "./chunk-QRXPWW3M.js";
|
|
18
|
+
import {
|
|
19
|
+
EXIT
|
|
20
|
+
} from "./chunk-KZERVKTD.js";
|
|
21
|
+
import {
|
|
22
|
+
getBaseUrl
|
|
23
|
+
} from "./chunk-IRHABAQT.js";
|
|
24
|
+
|
|
25
|
+
// src/cli/report-key.ts
|
|
26
|
+
var { dim, yellow } = createIo();
|
|
27
|
+
var printReport = (report) => {
|
|
28
|
+
console.log(` ${yellow("!")} ${report.message}`);
|
|
29
|
+
for (const line of report.next) console.log(` ${dim(line)}`);
|
|
30
|
+
};
|
|
31
|
+
var signedOutKeyReport = (check) => {
|
|
32
|
+
if (check.kind !== "rejected") return null;
|
|
33
|
+
const diagnosis = readSignedOutDiagnosis(readKeySource().key, "rejected");
|
|
34
|
+
if (diagnosis.kind !== "signed_out_on_mac") return null;
|
|
35
|
+
return { message: SIGNED_OUT_ON_MAC_MESSAGE, next: describeSignedOutKey(diagnosis), exitCode: EXIT.UNAUTHENTICATED, fatal: true };
|
|
36
|
+
};
|
|
37
|
+
var printKeyCheck = (check, baseUrl) => {
|
|
38
|
+
const report = signedOutKeyReport(check) ?? describeKeyCheck(check, baseUrl);
|
|
39
|
+
printReport(report);
|
|
40
|
+
return report;
|
|
41
|
+
};
|
|
42
|
+
var exitIfKeyFailure = async (response, baseUrl) => {
|
|
43
|
+
const check = await keyCheckFromResponse(response, baseUrl);
|
|
44
|
+
if (!check) return;
|
|
45
|
+
const report = printKeyCheck(check, baseUrl);
|
|
46
|
+
process.exit(report.exitCode);
|
|
47
|
+
};
|
|
48
|
+
var responseDetail = async (response) => {
|
|
49
|
+
try {
|
|
50
|
+
const body = await response.json();
|
|
51
|
+
const text = [body.error, body.message].find((part) => typeof part === "string" && part);
|
|
52
|
+
if (typeof text === "string") return text;
|
|
53
|
+
} catch {
|
|
54
|
+
}
|
|
55
|
+
return response.statusText || `HTTP ${response.status}`;
|
|
56
|
+
};
|
|
57
|
+
var exitOnFailedResponse = async (response, baseUrl) => {
|
|
58
|
+
await exitIfKeyFailure(response, baseUrl);
|
|
59
|
+
console.log(` ${yellow("!")} Failed: ${await responseDetail(response)}`);
|
|
60
|
+
process.exit(EXIT.FAILED);
|
|
61
|
+
};
|
|
62
|
+
var REFUSED_SETTINGS_ACTION = {
|
|
63
|
+
mode: "change the approval mode",
|
|
64
|
+
wait: "change how long approvals wait for you",
|
|
65
|
+
suggestions: "read or accept rule suggestions"
|
|
66
|
+
};
|
|
67
|
+
var APPROVAL_SETTINGS_PATH = "/dashboard/agent/settings";
|
|
68
|
+
var AGENT_KEY_SCOPE = "agent";
|
|
69
|
+
var isAgentKeyRefusal = (status, check) => status === 401 && check.kind === "ok" && check.identity.keyScope === AGENT_KEY_SCOPE;
|
|
70
|
+
var describeAgentKeyRefusal = (request, baseUrl = getBaseUrl()) => ({
|
|
71
|
+
message: `This computer's key cannot ${REFUSED_SETTINGS_ACTION[request]}. Keys from pushary login, phone pairing and the Mac app run approvals and notifications, not account settings.`,
|
|
72
|
+
next: [
|
|
73
|
+
`Change it from the Pushary app, your phone, or the dashboard: ${absoluteUrl(baseUrl, APPROVAL_SETTINGS_PATH)}`,
|
|
74
|
+
"The key itself is valid. Nothing on this computer needs fixing."
|
|
75
|
+
],
|
|
76
|
+
exitCode: EXIT.USAGE,
|
|
77
|
+
fatal: true
|
|
78
|
+
});
|
|
79
|
+
var exitOnFailedSettingsRequest = async (response, settings) => {
|
|
80
|
+
if (response.status === 401) {
|
|
81
|
+
const check = await checkApiKey(settings.apiKey, { baseUrl: settings.baseUrl });
|
|
82
|
+
if (isAgentKeyRefusal(response.status, check)) {
|
|
83
|
+
const report = describeAgentKeyRefusal(settings.request, settings.baseUrl);
|
|
84
|
+
printReport(report);
|
|
85
|
+
process.exit(report.exitCode);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return exitOnFailedResponse(response, settings.baseUrl);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export {
|
|
92
|
+
printKeyCheck,
|
|
93
|
+
exitOnFailedSettingsRequest
|
|
94
|
+
};
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-POFBE6ZY.js";
|
|
4
4
|
import {
|
|
5
5
|
autoUpdateState
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-Z23ZBYDW.js";
|
|
7
7
|
import {
|
|
8
8
|
readJsonSafe,
|
|
9
9
|
writeJsonAtomic
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
cliPackagePathSegments,
|
|
15
15
|
globalUpgradeEntry,
|
|
16
16
|
ownPackageRoot
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-5RGA636G.js";
|
|
18
18
|
|
|
19
19
|
// src/auto-update.ts
|
|
20
20
|
import { spawn } from "child_process";
|