@pushary/agent-hooks 0.89.13 → 0.90.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/CHANGELOG.md +60 -0
- package/data/SKILL.md +1 -1
- package/data/cursor-plugin/skills/pushary/SKILL.md +1 -1
- package/data/vscode-plugin/skills/pushary/SKILL.md +1 -1
- package/dist/bin/pushary-bell-hook.js +4 -4
- package/dist/bin/pushary-bell.js +8 -8
- package/dist/bin/pushary-claude.js +72 -21
- package/dist/bin/pushary-clean.js +16 -42
- package/dist/bin/pushary-codex-bridge.js +37 -12
- package/dist/bin/pushary-codex-hook.js +45 -12
- package/dist/bin/pushary-codex.js +7 -7
- package/dist/bin/pushary-connect.js +11 -10
- package/dist/bin/pushary-daemon.js +186 -62
- package/dist/bin/pushary-disconnect.js +8 -8
- package/dist/bin/pushary-doctor.js +108 -25
- package/dist/bin/pushary-elicitation-hook.js +4 -4
- package/dist/bin/pushary-gemini-bridge.js +33 -11
- package/dist/bin/pushary-gemini-hook.js +21 -10
- package/dist/bin/pushary-hook.js +13 -13
- package/dist/bin/pushary-login.js +18 -7
- package/dist/bin/pushary-logout.js +6 -6
- package/dist/bin/pushary-mode.js +28 -21
- package/dist/bin/pushary-notification-hook.js +7 -7
- package/dist/bin/pushary-opencode-hook.js +8 -8
- package/dist/bin/pushary-permission-denied-hook.js +11 -11
- package/dist/bin/pushary-permission-hook.js +11 -11
- package/dist/bin/pushary-post-hook.js +14 -8
- package/dist/bin/pushary-prompt-hook.js +7 -7
- package/dist/bin/pushary-session-end-hook.js +7 -7
- package/dist/bin/pushary-session-start-hook.js +7 -7
- package/dist/bin/pushary-setup.js +168 -45
- package/dist/bin/pushary-stats.js +4 -4
- package/dist/bin/pushary-status.js +11 -10
- package/dist/bin/pushary-stop-hook.js +14 -8
- package/dist/bin/pushary-stopfailure-hook.js +7 -7
- package/dist/bin/pushary-suggestions.js +2 -2
- package/dist/bin/pushary-transcripts.js +6 -6
- package/dist/bin/pushary-upgrade.js +15 -15
- package/dist/bin/pushary-wait.js +5 -5
- package/dist/bin/pushary.js +1 -1
- package/dist/{chunk-B2HND22S.js → chunk-2LAHXHBR.js} +1 -1
- package/dist/{chunk-GMJDQDXU.js → chunk-43GMYSS4.js} +1 -0
- package/dist/{chunk-JTBDBKHU.js → chunk-54ELC7D7.js} +1 -1
- package/dist/{chunk-C56VHSXU.js → chunk-5NAZ7SFS.js} +1 -1
- package/dist/{chunk-4IPSMEGT.js → chunk-7FE2KABY.js} +12 -2
- package/dist/{chunk-RAEPAUNJ.js → chunk-7TPQEWUZ.js} +1 -1
- package/dist/{chunk-ZO43JTT3.js → chunk-AJYV3VGU.js} +1 -1
- package/dist/{chunk-QFJZHVVL.js → chunk-AZPIQG4G.js} +35 -1
- package/dist/{chunk-5MNTWAAJ.js → chunk-B7UZHEBL.js} +29 -22
- package/dist/{chunk-MNTZKFZI.js → chunk-BQBEH6TV.js} +5 -5
- package/dist/{chunk-WHDSJ6PD.js → chunk-BVBEURWJ.js} +1 -1
- package/dist/{chunk-ZWEKONU6.js → chunk-CELX75MW.js} +1 -1
- package/dist/{chunk-ZP3SNUP7.js → chunk-CNPAT3HL.js} +3 -2
- package/dist/{chunk-YXT55PYF.js → chunk-DYP6SMOR.js} +1 -1
- package/dist/chunk-DZDI62LY.js +145 -0
- package/dist/{chunk-VF3RTVWY.js → chunk-EZIEXHYM.js} +15 -7
- package/dist/{chunk-7JZCADBR.js → chunk-F2ICEWZL.js} +101 -19
- package/dist/{chunk-VASZ6TWW.js → chunk-FQL5E6NG.js} +2 -2
- package/dist/{chunk-JHJHCMAF.js → chunk-FXEVRLHC.js} +20 -2
- package/dist/{chunk-JVLB5CAJ.js → chunk-GL3FFM7A.js} +7 -4
- package/dist/{chunk-5YEF55AX.js → chunk-H2QZRQR2.js} +1 -1
- package/dist/{chunk-S4BLNILH.js → chunk-I463AEG3.js} +1 -1
- package/dist/{chunk-ANMHIZZY.js → chunk-JW4KO5AF.js} +1 -1
- package/dist/{chunk-3YGGEDJK.js → chunk-KUZWXPUS.js} +3 -2
- package/dist/{chunk-N4QJ3CLX.js → chunk-L4E2BIJ2.js} +80 -7
- package/dist/{chunk-NBDU3R3G.js → chunk-OSALSIUF.js} +1 -1
- package/dist/{chunk-KNLKHJZR.js → chunk-PYA4FLKI.js} +32 -21
- package/dist/chunk-QCGNGEGE.js +15 -0
- package/dist/chunk-S6LYP7QA.js +127 -0
- package/dist/{chunk-OX35BSPV.js → chunk-TDZFPMSZ.js} +70 -11
- package/dist/{chunk-M3UABYRT.js → chunk-UZNKVRLE.js} +1 -1
- package/dist/{chunk-FOGW6O2Y.js → chunk-VHWCVD42.js} +1 -1
- package/dist/{chunk-QINYXLA5.js → chunk-VNMKIJZB.js} +15 -2
- package/dist/{chunk-CBGGUEKE.js → chunk-Y6BWPERV.js} +90 -7
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.js +11 -11
- package/package.json +1 -1
- package/dist/chunk-MSTHT2M7.js +0 -72
|
@@ -6,10 +6,14 @@ import {
|
|
|
6
6
|
var HOOK_SHELL = "/bin/sh -c";
|
|
7
7
|
var LOCATE = 'B=$(command -v "$0") || exit 0; [ -f "$B" ] || exit 0; [ -x "$B" ] || exit 0';
|
|
8
8
|
var NODE_PRESENT = "command -v node >/dev/null 2>&1 || exit 0";
|
|
9
|
+
var CURSOR_NO_OPINION = { permission: "ask" };
|
|
10
|
+
var shellDoubleQuoted = (text) => `"${text.replace(/(["\\$`])/g, "\\$1")}"`;
|
|
11
|
+
var CURSOR_MISS = `{ printf %s ${shellDoubleQuoted(JSON.stringify(CURSOR_NO_OPINION))}; exit 0; }`;
|
|
9
12
|
var HOOK_GUARD_SCRIPTS = {
|
|
10
13
|
native_binary: `${LOCATE}; exec "$B" "$@"`,
|
|
11
14
|
node_binary: `${LOCATE}; ${NODE_PRESENT}; exec "$B" "$@"`,
|
|
12
|
-
node_script: `[ -f "$0" ] || exit 0; ${NODE_PRESENT}; exec node "$0" "$@"
|
|
15
|
+
node_script: `[ -f "$0" ] || exit 0; ${NODE_PRESENT}; exec node "$0" "$@"`,
|
|
16
|
+
cursor_gate_script: `[ -f "$0" ] || ${CURSOR_MISS}; command -v node >/dev/null 2>&1 || ${CURSOR_MISS}; exec node "$0" "$@"`
|
|
13
17
|
};
|
|
14
18
|
var BINARY_GUARDS = {
|
|
15
19
|
native: "native_binary",
|
|
@@ -19,21 +23,25 @@ var guardKindOf = (target) => {
|
|
|
19
23
|
switch (target.kind) {
|
|
20
24
|
case "node":
|
|
21
25
|
return "node_script";
|
|
26
|
+
case "cursor_gate":
|
|
27
|
+
return "cursor_gate_script";
|
|
22
28
|
case "binary":
|
|
23
29
|
return BINARY_GUARDS[target.runtime];
|
|
24
30
|
}
|
|
25
31
|
};
|
|
32
|
+
var targetPath = (target) => target.kind === "binary" ? target.path : target.script;
|
|
33
|
+
var runsThroughNode = (target) => target.kind !== "binary";
|
|
26
34
|
var guardHookCommand = (target, platform = process.platform) => {
|
|
27
|
-
const path = quoteIfNeeded(target
|
|
28
|
-
if (platform === "win32") return target
|
|
35
|
+
const path = quoteIfNeeded(targetPath(target));
|
|
36
|
+
if (platform === "win32") return runsThroughNode(target) ? `node ${path}` : path;
|
|
29
37
|
return `${HOOK_SHELL} '${HOOK_GUARD_SCRIPTS[guardKindOf(target)]}' ${path}`;
|
|
30
38
|
};
|
|
31
39
|
var guardBinary = (path, platform) => guardHookCommand({ kind: "binary", path, runtime: "node" }, platform);
|
|
32
|
-
var
|
|
40
|
+
var guardCursorGate = (script, platform) => guardHookCommand({ kind: "cursor_gate", script }, platform);
|
|
33
41
|
var guardedArgv = (target, args = [], platform = process.platform) => {
|
|
34
|
-
const path = target
|
|
42
|
+
const path = targetPath(target);
|
|
35
43
|
if (platform === "win32") {
|
|
36
|
-
return target
|
|
44
|
+
return runsThroughNode(target) ? ["node", path, ...args] : [path, ...args];
|
|
37
45
|
}
|
|
38
46
|
const [shell, ...shellArgs] = HOOK_SHELL.split(/\s+/);
|
|
39
47
|
return [shell, ...shellArgs, HOOK_GUARD_SCRIPTS[guardKindOf(target)], path, ...args];
|
|
@@ -41,6 +49,6 @@ var guardedArgv = (target, args = [], platform = process.platform) => {
|
|
|
41
49
|
|
|
42
50
|
export {
|
|
43
51
|
guardBinary,
|
|
44
|
-
|
|
52
|
+
guardCursorGate,
|
|
45
53
|
guardedArgv
|
|
46
54
|
};
|
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
} from "./chunk-L4ZCFMWW.js";
|
|
8
8
|
import {
|
|
9
9
|
getMachineId
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-54ELC7D7.js";
|
|
11
11
|
import {
|
|
12
12
|
pusharyDir
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-KUZWXPUS.js";
|
|
14
14
|
import {
|
|
15
15
|
getPackageVersion
|
|
16
16
|
} from "./chunk-DINDL2CF.js";
|
|
@@ -383,18 +383,32 @@ var manageDaemonService = (action, options = {}) => {
|
|
|
383
383
|
}
|
|
384
384
|
return applyDaemonService(action, definition, { run: options.run });
|
|
385
385
|
};
|
|
386
|
+
var nominalDaemonService = (options) => buildDaemonService({
|
|
387
|
+
platform: options.platform ?? process.platform,
|
|
388
|
+
homeDir: options.homeDir ?? homedir(),
|
|
389
|
+
stateDir: options.stateDir ?? pusharyDir(),
|
|
390
|
+
execPath: options.execPath ?? process.execPath,
|
|
391
|
+
daemonEntry: options.daemonEntry ?? process.execPath,
|
|
392
|
+
pathEnv: options.pathEnv ?? process.env.PATH ?? "",
|
|
393
|
+
uid: options.uid ?? process.getuid?.()
|
|
394
|
+
});
|
|
386
395
|
var hasDaemonServiceDefinition = (options = {}) => {
|
|
387
|
-
const definition =
|
|
388
|
-
platform: options.platform ?? process.platform,
|
|
389
|
-
homeDir: options.homeDir ?? homedir(),
|
|
390
|
-
stateDir: options.stateDir ?? pusharyDir(),
|
|
391
|
-
execPath: options.execPath ?? process.execPath,
|
|
392
|
-
daemonEntry: options.daemonEntry ?? process.execPath,
|
|
393
|
-
pathEnv: options.pathEnv ?? process.env.PATH ?? "",
|
|
394
|
-
uid: options.uid ?? process.getuid?.()
|
|
395
|
-
});
|
|
396
|
+
const definition = nominalDaemonService(options);
|
|
396
397
|
return definition !== null && existsSync(definition.definitionPath);
|
|
397
398
|
};
|
|
399
|
+
var daemonServiceDefinitionPath = (options = {}) => nominalDaemonService(options)?.definitionPath ?? null;
|
|
400
|
+
var readInstalledDaemonService = (options = {}) => {
|
|
401
|
+
const definition = nominalDaemonService(options);
|
|
402
|
+
if (!definition) return null;
|
|
403
|
+
try {
|
|
404
|
+
return {
|
|
405
|
+
path: definition.definitionPath,
|
|
406
|
+
contents: readFileSync(definition.definitionPath, definition.encoding ?? "utf-8")
|
|
407
|
+
};
|
|
408
|
+
} catch {
|
|
409
|
+
return null;
|
|
410
|
+
}
|
|
411
|
+
};
|
|
398
412
|
var spawnDetachedDaemon = (plan, options = {}) => {
|
|
399
413
|
const spawnImpl = options.spawnImpl ?? spawnClaude;
|
|
400
414
|
const child = spawnImpl(plan.command, plan.args, {
|
|
@@ -418,13 +432,19 @@ var processIsAlive = (pid) => {
|
|
|
418
432
|
};
|
|
419
433
|
var isString = (value) => typeof value === "string" && value.length > 0;
|
|
420
434
|
var isTimestamp = (value) => isString(value) && Number.isFinite(Date.parse(value));
|
|
435
|
+
var daemonConfigurationId = (apiKey) => createHash("sha256").update(apiKey).digest("hex").slice(0, 16);
|
|
421
436
|
var currentConfigurationId = () => {
|
|
422
437
|
try {
|
|
423
|
-
return
|
|
438
|
+
return daemonConfigurationId(getApiKey());
|
|
424
439
|
} catch {
|
|
425
440
|
return null;
|
|
426
441
|
}
|
|
427
442
|
};
|
|
443
|
+
var parseDaemonLastError = (value) => {
|
|
444
|
+
if (typeof value !== "object" || value === null) return null;
|
|
445
|
+
const error = value;
|
|
446
|
+
return isString(error.message) && isTimestamp(error.at) ? { message: error.message, at: error.at } : null;
|
|
447
|
+
};
|
|
428
448
|
var parseDaemonState = (value) => {
|
|
429
449
|
if (typeof value !== "object" || value === null) return null;
|
|
430
450
|
const state = value;
|
|
@@ -438,7 +458,8 @@ var parseDaemonState = (value) => {
|
|
|
438
458
|
startedAt: state.startedAt,
|
|
439
459
|
updatedAt: state.updatedAt,
|
|
440
460
|
lastSuccessfulHeartbeatAt: state.lastSuccessfulHeartbeatAt,
|
|
441
|
-
lastSuccessfulControlAt: state.lastSuccessfulControlAt ?? null
|
|
461
|
+
lastSuccessfulControlAt: state.lastSuccessfulControlAt ?? null,
|
|
462
|
+
lastError: parseDaemonLastError(state.lastError)
|
|
442
463
|
};
|
|
443
464
|
};
|
|
444
465
|
var parseLockOwner = (value) => {
|
|
@@ -461,16 +482,17 @@ var readDaemonStatus = (options = {}) => {
|
|
|
461
482
|
startedAt: null,
|
|
462
483
|
updatedAt: null,
|
|
463
484
|
lastSuccessfulHeartbeatAt: null,
|
|
464
|
-
lastSuccessfulControlAt: null
|
|
485
|
+
lastSuccessfulControlAt: null,
|
|
486
|
+
lastError: null
|
|
465
487
|
};
|
|
466
488
|
}
|
|
467
489
|
const value = state.kind === "ok" ? parseDaemonState(state.value) : null;
|
|
468
490
|
if (value) {
|
|
469
491
|
const alive = (options.isProcessAlive ?? processIsAlive)(value.pid);
|
|
470
492
|
const fresh = (options.now ?? Date.now)() - Date.parse(value.updatedAt) <= LOCAL_LEASE_TIMEOUT_MS;
|
|
471
|
-
const
|
|
493
|
+
const expectedConfigurationId2 = options.configurationId === void 0 ? currentConfigurationId() : options.configurationId;
|
|
472
494
|
return {
|
|
473
|
-
kind: !alive || !fresh ? "unresponsive" : value.version !== installedVersion ? "version-mismatch" :
|
|
495
|
+
kind: !alive || !fresh ? "unresponsive" : value.version !== installedVersion ? "version-mismatch" : expectedConfigurationId2 !== null && value.configurationId !== null && value.configurationId !== expectedConfigurationId2 ? "configuration-mismatch" : "running",
|
|
474
496
|
installedVersion,
|
|
475
497
|
machineId: value.machineId,
|
|
476
498
|
pid: value.pid,
|
|
@@ -479,7 +501,8 @@ var readDaemonStatus = (options = {}) => {
|
|
|
479
501
|
startedAt: value.startedAt,
|
|
480
502
|
updatedAt: value.updatedAt,
|
|
481
503
|
lastSuccessfulHeartbeatAt: value.lastSuccessfulHeartbeatAt,
|
|
482
|
-
lastSuccessfulControlAt: value.lastSuccessfulControlAt
|
|
504
|
+
lastSuccessfulControlAt: value.lastSuccessfulControlAt,
|
|
505
|
+
lastError: value.lastError
|
|
483
506
|
};
|
|
484
507
|
}
|
|
485
508
|
return {
|
|
@@ -492,7 +515,8 @@ var readDaemonStatus = (options = {}) => {
|
|
|
492
515
|
startedAt: null,
|
|
493
516
|
updatedAt: null,
|
|
494
517
|
lastSuccessfulHeartbeatAt: null,
|
|
495
|
-
lastSuccessfulControlAt: null
|
|
518
|
+
lastSuccessfulControlAt: null,
|
|
519
|
+
lastError: null
|
|
496
520
|
};
|
|
497
521
|
};
|
|
498
522
|
var safeUnlink = (path) => {
|
|
@@ -561,7 +585,8 @@ var acquireDaemonLease = (options = {}) => {
|
|
|
561
585
|
startedAt,
|
|
562
586
|
updatedAt: startedAt,
|
|
563
587
|
lastSuccessfulHeartbeatAt: null,
|
|
564
|
-
lastSuccessfulControlAt: null
|
|
588
|
+
lastSuccessfulControlAt: null,
|
|
589
|
+
lastError: null
|
|
565
590
|
};
|
|
566
591
|
try {
|
|
567
592
|
writeJsonAtomic(statePath(dir), state, 384);
|
|
@@ -605,6 +630,14 @@ var acquireDaemonLease = (options = {}) => {
|
|
|
605
630
|
lastSuccessfulControlAt: timestamp
|
|
606
631
|
});
|
|
607
632
|
},
|
|
633
|
+
recordError: (message, at = now()) => {
|
|
634
|
+
const timestamp = new Date(at).toISOString();
|
|
635
|
+
updateState({
|
|
636
|
+
...currentState,
|
|
637
|
+
updatedAt: timestamp,
|
|
638
|
+
lastError: { message: message.slice(0, 240), at: timestamp }
|
|
639
|
+
});
|
|
640
|
+
},
|
|
608
641
|
shouldYield: () => {
|
|
609
642
|
if (!isOwner()) return true;
|
|
610
643
|
const target = readJsonSafe(targetPath(dir));
|
|
@@ -670,6 +703,44 @@ var stopDaemonRunning = async (options = {}) => {
|
|
|
670
703
|
safeUnlink(lockPath(dir));
|
|
671
704
|
return { kind: "stopped" };
|
|
672
705
|
};
|
|
706
|
+
var needsLoginPath = (dir) => join(dir, "daemon-needs-login.json");
|
|
707
|
+
var isLoginReason = (value) => value === "key_rejected" || value === "plan_inactive";
|
|
708
|
+
var parseDaemonNeedsLogin = (value) => {
|
|
709
|
+
if (typeof value !== "object" || value === null) return null;
|
|
710
|
+
const record = value;
|
|
711
|
+
if (!isLoginReason(record.reason) || !isTimestamp(record.at)) return null;
|
|
712
|
+
if (!(record.configurationId === null || isString(record.configurationId))) return null;
|
|
713
|
+
return { reason: record.reason, at: record.at, configurationId: record.configurationId };
|
|
714
|
+
};
|
|
715
|
+
var expectedConfigurationId = (options) => options.configurationId === void 0 ? currentConfigurationId() : options.configurationId;
|
|
716
|
+
var writeDaemonNeedsLogin = (reason, options = {}) => {
|
|
717
|
+
const record = {
|
|
718
|
+
reason,
|
|
719
|
+
at: new Date((options.now ?? Date.now)()).toISOString(),
|
|
720
|
+
configurationId: expectedConfigurationId(options)
|
|
721
|
+
};
|
|
722
|
+
writeJsonAtomic(needsLoginPath(options.dir ?? pusharyDir()), record, 384);
|
|
723
|
+
return record;
|
|
724
|
+
};
|
|
725
|
+
var readDaemonNeedsLogin = (options = {}) => {
|
|
726
|
+
const stored = readJsonSafe(needsLoginPath(options.dir ?? pusharyDir()));
|
|
727
|
+
const record = stored.kind === "ok" ? parseDaemonNeedsLogin(stored.value) : null;
|
|
728
|
+
if (!record) return { kind: "none" };
|
|
729
|
+
return record.configurationId === expectedConfigurationId(options) ? { kind: "blocked", record } : { kind: "stale", record };
|
|
730
|
+
};
|
|
731
|
+
var clearDaemonNeedsLogin = (options = {}) => {
|
|
732
|
+
const path = needsLoginPath(options.dir ?? pusharyDir());
|
|
733
|
+
if (!existsSync(path)) return false;
|
|
734
|
+
safeUnlink(path);
|
|
735
|
+
return true;
|
|
736
|
+
};
|
|
737
|
+
var describeDaemonLoginBlock = (record) => record.reason === "key_rejected" ? `this machine's key was rejected at ${record.at}; run \`pushary login\` to sign in again` : `this workspace had no active plan at ${record.at}; pick one at pushary.com/dashboard/settings?tab=billing, then run \`pushary login\``;
|
|
738
|
+
var recoverDaemonAfterLogin = (options = {}) => {
|
|
739
|
+
const cleared = clearDaemonNeedsLogin(options);
|
|
740
|
+
if (!cleared || !hasDaemonServiceDefinition(options)) return { cleared, restarted: false, detail: null };
|
|
741
|
+
const started = manageDaemonService("start", options);
|
|
742
|
+
return started.kind === "ok" ? { cleared, restarted: true, detail: null } : { cleared, restarted: false, detail: started.detail };
|
|
743
|
+
};
|
|
673
744
|
var deactivateDaemonService = async (action, options) => {
|
|
674
745
|
const platform = options.platform ?? process.platform;
|
|
675
746
|
const supported = ["darwin", "linux", "win32"].includes(platform);
|
|
@@ -966,6 +1037,10 @@ var ensureDaemonRunning = async (options = {}) => {
|
|
|
966
1037
|
return { kind: "not-configured", status: initial, detail: "Pushary is not configured on this machine" };
|
|
967
1038
|
}
|
|
968
1039
|
if (initial.kind === "running") return { kind: "running", status: initial };
|
|
1040
|
+
const loginBlock = readDaemonNeedsLogin(options);
|
|
1041
|
+
if (loginBlock.kind === "blocked") {
|
|
1042
|
+
return { kind: "unavailable", status: initial, detail: describeDaemonLoginBlock(loginBlock.record) };
|
|
1043
|
+
}
|
|
969
1044
|
let handoffStatus;
|
|
970
1045
|
try {
|
|
971
1046
|
handoffStatus = await requestDaemonHandoff(initial, options);
|
|
@@ -1020,10 +1095,17 @@ export {
|
|
|
1020
1095
|
parseDaemonAction,
|
|
1021
1096
|
manageDaemonService,
|
|
1022
1097
|
hasDaemonServiceDefinition,
|
|
1098
|
+
daemonServiceDefinitionPath,
|
|
1099
|
+
readInstalledDaemonService,
|
|
1023
1100
|
readDaemonStatus,
|
|
1024
1101
|
acquireDaemonLease,
|
|
1025
1102
|
requestDaemonHandoff,
|
|
1026
1103
|
stopDaemonRunning,
|
|
1104
|
+
writeDaemonNeedsLogin,
|
|
1105
|
+
readDaemonNeedsLogin,
|
|
1106
|
+
clearDaemonNeedsLogin,
|
|
1107
|
+
describeDaemonLoginBlock,
|
|
1108
|
+
recoverDaemonAfterLogin,
|
|
1027
1109
|
stopDaemonService,
|
|
1028
1110
|
disableDaemonService,
|
|
1029
1111
|
replaceDaemonService,
|
|
@@ -189,10 +189,27 @@ var removePendingCommand = (sessionId, id, namespace = "") => {
|
|
|
189
189
|
}
|
|
190
190
|
};
|
|
191
191
|
var isDefaultSession = (sessionId) => sanitize(sessionId) === DEFAULT_SESSION;
|
|
192
|
-
var savePendingQuestion = (sessionId, correlationId) => {
|
|
192
|
+
var savePendingQuestion = (sessionId, correlationId, toolUseId) => {
|
|
193
193
|
const dir = dirFor(sessionId);
|
|
194
194
|
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
195
|
-
writeFileSync(join(dir, correlationId), "", "utf-8");
|
|
195
|
+
writeFileSync(join(dir, correlationId), toolUseId ?? "", "utf-8");
|
|
196
|
+
};
|
|
197
|
+
var listPendingQuestionsForToolUse = (sessionId, toolUseId) => {
|
|
198
|
+
if (!toolUseId) return [];
|
|
199
|
+
const dir = dirFor(sessionId);
|
|
200
|
+
let files;
|
|
201
|
+
try {
|
|
202
|
+
files = readdirSync(dir);
|
|
203
|
+
} catch {
|
|
204
|
+
return [];
|
|
205
|
+
}
|
|
206
|
+
return files.filter((name) => {
|
|
207
|
+
try {
|
|
208
|
+
return readFileSync(join(dir, name), "utf-8") === toolUseId;
|
|
209
|
+
} catch {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
});
|
|
196
213
|
};
|
|
197
214
|
var listPendingQuestions = (sessionId) => {
|
|
198
215
|
const dir = dirFor(sessionId);
|
|
@@ -241,6 +258,7 @@ export {
|
|
|
241
258
|
removePendingCommand,
|
|
242
259
|
isDefaultSession,
|
|
243
260
|
savePendingQuestion,
|
|
261
|
+
listPendingQuestionsForToolUse,
|
|
244
262
|
listPendingQuestions,
|
|
245
263
|
removePendingQuestion,
|
|
246
264
|
removePendingSession
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PRETOOLUSE_GATED_TOOLS,
|
|
3
3
|
PRETOOLUSE_PHONE_ANSWERED_TOOLS
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2LAHXHBR.js";
|
|
5
5
|
import {
|
|
6
6
|
guardBinary
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-EZIEXHYM.js";
|
|
8
8
|
import {
|
|
9
9
|
isProtectedByScope
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-KUZWXPUS.js";
|
|
11
11
|
import {
|
|
12
12
|
HOOK_BUDGETS,
|
|
13
13
|
HOOK_LOCATOR_BINARY
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-VNMKIJZB.js";
|
|
15
15
|
|
|
16
16
|
// src/claude-config.ts
|
|
17
17
|
import { join } from "path";
|
|
@@ -234,6 +234,7 @@ var GEMINI_HOOK_EVENTS = [
|
|
|
234
234
|
{ event: "BeforeTool", matcher: "run_shell_command|write_file|replace", delivery: "approval", timeoutMs: HOOK_BUDGETS.gemini.budgetSeconds * 1e3 },
|
|
235
235
|
{ event: "AfterTool", matcher: "run_shell_command|write_file|replace", delivery: "telemetry", timeoutMs: 1e4 },
|
|
236
236
|
{ event: "BeforeAgent", delivery: "telemetry", timeoutMs: 1e4 },
|
|
237
|
+
{ event: "AfterAgent", delivery: "telemetry", timeoutMs: 1e4 },
|
|
237
238
|
{ event: "SessionStart", delivery: "telemetry", timeoutMs: 1e4 },
|
|
238
239
|
{ event: "SessionEnd", delivery: "telemetry", timeoutMs: 1e4 }
|
|
239
240
|
];
|
|
@@ -330,6 +331,7 @@ var missingGeminiHookEvents = (settings) => {
|
|
|
330
331
|
export {
|
|
331
332
|
parseVersion,
|
|
332
333
|
compareVersion,
|
|
334
|
+
CLAUDE_HOOK_EVENTS,
|
|
333
335
|
addClaudeMcpServer,
|
|
334
336
|
isClaudeMcpSnapshot,
|
|
335
337
|
captureClaudeMcpServer,
|
|
@@ -340,6 +342,7 @@ export {
|
|
|
340
342
|
addPusharyHooks,
|
|
341
343
|
removePusharySettings,
|
|
342
344
|
GEMINI_HOOK_BINARY,
|
|
345
|
+
GEMINI_HOOK_EVENTS,
|
|
343
346
|
addGeminiMcpServer,
|
|
344
347
|
addGeminiHooks,
|
|
345
348
|
removeGeminiSettings,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
HOOK_BUDGETS,
|
|
3
3
|
HOOK_LOCATOR_BINARY
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VNMKIJZB.js";
|
|
5
5
|
|
|
6
6
|
// src/removal-scope.ts
|
|
7
7
|
var namesAppLocator = (command) => command.includes(HOOK_LOCATOR_BINARY);
|
|
@@ -29,7 +29,7 @@ var codexHooksJson = () => join(codexHome(), "hooks.json");
|
|
|
29
29
|
var codexAgentsMd = () => join(codexHome(), "AGENTS.md");
|
|
30
30
|
var codexSkillDir = () => join(codexHome(), "skills", "pushary");
|
|
31
31
|
var CODEX_HOOK_EVENTS = [
|
|
32
|
-
{ event: "PermissionRequest",
|
|
32
|
+
{ event: "PermissionRequest", delivery: "approval", timeout: HOOK_BUDGETS.codex.budgetSeconds, statusMessage: "Waiting for your phone" },
|
|
33
33
|
{ event: "PreToolUse", matcher: "Bash|apply_patch", delivery: "approval", timeout: HOOK_BUDGETS.codex.budgetSeconds, statusMessage: "Checking Pushary policy" },
|
|
34
34
|
{ event: "PostToolUse", matcher: "Bash|apply_patch", delivery: "telemetry", timeout: 10 },
|
|
35
35
|
{ event: "UserPromptSubmit", delivery: "telemetry", timeout: 10 },
|
|
@@ -286,6 +286,7 @@ export {
|
|
|
286
286
|
codexHooksJson,
|
|
287
287
|
codexAgentsMd,
|
|
288
288
|
codexSkillDir,
|
|
289
|
+
CODEX_HOOK_EVENTS,
|
|
289
290
|
addCodexMcpServer,
|
|
290
291
|
readCodexMcpAuth,
|
|
291
292
|
addCodexHooks,
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
FILE_TARGET_TOOLS,
|
|
6
6
|
redactSecrets,
|
|
7
7
|
redactSecretsDeep
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-VNMKIJZB.js";
|
|
9
9
|
|
|
10
10
|
// ../hook-mapping/src/describe.ts
|
|
11
11
|
import { isAbsolute, relative, resolve } from "path";
|
|
@@ -44,6 +44,48 @@ var eventPrefixes = {
|
|
|
44
44
|
Read: (input) => `read: ${input.file_path ?? "unknown"}`,
|
|
45
45
|
TodoWrite: (input) => describeTodoProgress(input.todos)
|
|
46
46
|
};
|
|
47
|
+
var MCP_TOOL_PREFIX = "mcp__";
|
|
48
|
+
var parseMcpToolName = (toolName) => {
|
|
49
|
+
if (!toolName.startsWith(MCP_TOOL_PREFIX)) return void 0;
|
|
50
|
+
const rest = toolName.slice(MCP_TOOL_PREFIX.length);
|
|
51
|
+
const split = rest.indexOf("__");
|
|
52
|
+
if (split <= 0 || split + 2 >= rest.length) return void 0;
|
|
53
|
+
return { server: rest.slice(0, split), tool: rest.slice(split + 2) };
|
|
54
|
+
};
|
|
55
|
+
var NETWORK_TARGET_KEYS = ["url", "urls", "href", "host", "hosts", "hostname", "domain", "domains"];
|
|
56
|
+
var ABSOLUTE_HTTP_URL = /^https?:\/\//i;
|
|
57
|
+
var HOSTNAME = /^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+(?::\d{1,5})?$/i;
|
|
58
|
+
var hostOfUrl = (value) => {
|
|
59
|
+
try {
|
|
60
|
+
return new URL(value).host || void 0;
|
|
61
|
+
} catch {
|
|
62
|
+
return void 0;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
var hostOf = (value, bareHostnames) => {
|
|
66
|
+
if (typeof value !== "string") return void 0;
|
|
67
|
+
const trimmed = value.trim();
|
|
68
|
+
if (ABSOLUTE_HTTP_URL.test(trimmed)) return hostOfUrl(trimmed);
|
|
69
|
+
return bareHostnames && HOSTNAME.test(trimmed) ? trimmed : void 0;
|
|
70
|
+
};
|
|
71
|
+
var firstHost = (value, bareHostnames) => Array.isArray(value) ? value.map((entry) => hostOf(entry, bareHostnames)).find((host) => host !== void 0) : hostOf(value, bareHostnames);
|
|
72
|
+
var deriveNetworkTarget = (toolInput) => {
|
|
73
|
+
for (const key of NETWORK_TARGET_KEYS) {
|
|
74
|
+
const host = firstHost(toolInput[key], true);
|
|
75
|
+
if (host) return host;
|
|
76
|
+
}
|
|
77
|
+
return Object.values(toolInput).map((value) => firstHost(value, false)).find((host) => host !== void 0);
|
|
78
|
+
};
|
|
79
|
+
var describeUnbuiltCall = (toolName, toolInput, format) => {
|
|
80
|
+
const mcp = parseMcpToolName(toolName);
|
|
81
|
+
const host = deriveNetworkTarget(toolInput);
|
|
82
|
+
if (mcp) {
|
|
83
|
+
if (format === "event") return `called ${mcp.tool} on ${mcp.server}`;
|
|
84
|
+
return host ? `call ${mcp.tool} on ${mcp.server} to reach ${host}` : `call ${mcp.tool} on ${mcp.server}`;
|
|
85
|
+
}
|
|
86
|
+
if (host) return format === "event" ? `accessed ${host}` : `network access to ${host}`;
|
|
87
|
+
return void 0;
|
|
88
|
+
};
|
|
47
89
|
var EVENT_ACTION_MAX = 120;
|
|
48
90
|
var HOOK_FALLBACK_MAX = 200;
|
|
49
91
|
var UNNAMED_ACTION = "this request";
|
|
@@ -51,11 +93,12 @@ var describeToolCall = (toolName, toolInput, format = "hook") => {
|
|
|
51
93
|
if (!toolName) return "";
|
|
52
94
|
const prefixes = format === "hook" ? hookPrefixes : eventPrefixes;
|
|
53
95
|
const builder = prefixes[toolName];
|
|
96
|
+
const unbuilt = builder ? void 0 : describeUnbuiltCall(toolName, toolInput ?? {}, format);
|
|
54
97
|
const detail = JSON.stringify(toolInput ?? {});
|
|
55
|
-
const raw = builder ? builder(toolInput) : format === "hook" ? detail === "{}" || detail === void 0 ? toolName : `${toolName}: ${detail}` : `${toolName}: done
|
|
98
|
+
const raw = builder ? builder(toolInput) : unbuilt ?? (format === "hook" ? detail === "{}" || detail === void 0 ? toolName : `${toolName}: ${detail}` : `${toolName}: done`);
|
|
56
99
|
const redacted = redactSecrets(raw);
|
|
57
100
|
if (format === "event") return redacted.slice(0, EVENT_ACTION_MAX);
|
|
58
|
-
return builder ? redacted : redacted.slice(0, HOOK_FALLBACK_MAX);
|
|
101
|
+
return builder || unbuilt ? redacted : redacted.slice(0, HOOK_FALLBACK_MAX);
|
|
59
102
|
};
|
|
60
103
|
var TOOL_TARGET_MAX_LENGTH = 80;
|
|
61
104
|
var deriveCommandHead = (command) => {
|
|
@@ -76,7 +119,9 @@ var deriveToolTarget = (toolName, toolInput) => {
|
|
|
76
119
|
if (dot <= 0) return void 0;
|
|
77
120
|
return base.slice(dot).slice(0, TOOL_TARGET_MAX_LENGTH);
|
|
78
121
|
}
|
|
79
|
-
|
|
122
|
+
const mcp = parseMcpToolName(toolName);
|
|
123
|
+
if (mcp) return mcp.server.slice(0, TOOL_TARGET_MAX_LENGTH);
|
|
124
|
+
return deriveNetworkTarget(toolInput)?.slice(0, TOOL_TARGET_MAX_LENGTH);
|
|
80
125
|
};
|
|
81
126
|
var SCRIPT_RUNNERS = /* @__PURE__ */ new Set(["npm", "pnpm", "yarn", "bun", "npx", "deno", "rake", "make", "just", "task", "turbo"]);
|
|
82
127
|
var RUN_SUBCOMMANDS = /* @__PURE__ */ new Set(["run", "run-script", "exec", "task"]);
|
|
@@ -210,7 +255,7 @@ var rawActionBody = (toolName, toolInput) => {
|
|
|
210
255
|
if (toolName === "Bash" || toolName === "PowerShell" || toolName === "Monitor" || toolName === "run_shell_command" || toolName === "shell" || toolName === "apply_patch") {
|
|
211
256
|
return firstString(toolInput.command);
|
|
212
257
|
}
|
|
213
|
-
return
|
|
258
|
+
return firstString(toolInput.url, toolInput.href);
|
|
214
259
|
};
|
|
215
260
|
var deriveActionBody = (toolName, toolInput) => {
|
|
216
261
|
try {
|
|
@@ -264,11 +309,36 @@ var summarizeStop = (input) => {
|
|
|
264
309
|
if (running > 0) return `Paused with ${running} background task${running === 1 ? "" : "s"} still running`;
|
|
265
310
|
const crons = countArray(input.session_crons);
|
|
266
311
|
if (crons > 0) return `Idle until a scheduled task wakes it (${crons} pending)`;
|
|
267
|
-
return summarizeFinalMessage(input.last_assistant_message);
|
|
312
|
+
return summarizeFinalMessage(input.last_assistant_message ?? input.prompt_response);
|
|
313
|
+
};
|
|
314
|
+
var subagentStopAction = (agentType) => {
|
|
315
|
+
const name = typeof agentType === "string" ? agentType.replace(/\s+/g, " ").trim() : "";
|
|
316
|
+
return name ? `${name} subagent finished` : "Subagent finished";
|
|
317
|
+
};
|
|
318
|
+
var subagentStopSummary = (input) => {
|
|
319
|
+
const message = input.last_assistant_message ?? input.prompt_response;
|
|
320
|
+
if (typeof message === "string" && message.trim()) return summarizeStop(input);
|
|
321
|
+
return subagentStopAction(input.agent_type);
|
|
322
|
+
};
|
|
323
|
+
var COMPACTION_TRIGGERS = {
|
|
324
|
+
manual: "on request",
|
|
325
|
+
auto: "automatically"
|
|
326
|
+
};
|
|
327
|
+
var compactionAction = (hookEvent, trigger) => {
|
|
328
|
+
const how = typeof trigger === "string" ? COMPACTION_TRIGGERS[trigger] : void 0;
|
|
329
|
+
const base = hookEvent === "PostCompact" ? "Compacted context" : "Compacting context";
|
|
330
|
+
return how ? `${base} ${how}` : base;
|
|
268
331
|
};
|
|
269
332
|
var sessionStartAction = (source) => source === "resume" ? "Session resumed" : "Session started";
|
|
270
333
|
var sessionEndAction = (reason) => typeof reason === "string" && SESSION_END_ACTIONS[reason] || "Session ended";
|
|
271
334
|
var taskTitleFrom = (prompt) => typeof prompt === "string" ? prompt.replace(/\s+/g, " ").trim().slice(0, TASK_TITLE_MAX_LENGTH) || void 0 : void 0;
|
|
335
|
+
var asString = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
|
|
336
|
+
var sessionIdentityOf = (payload) => {
|
|
337
|
+
const sessionId = asString(payload.session_id);
|
|
338
|
+
const agentId = asString(payload.agent_id);
|
|
339
|
+
if (!agentId) return { sessionId };
|
|
340
|
+
return { sessionId: agentId, parentSessionId: sessionId };
|
|
341
|
+
};
|
|
272
342
|
|
|
273
343
|
export {
|
|
274
344
|
HOOK_FALLBACK_MAX,
|
|
@@ -287,7 +357,10 @@ export {
|
|
|
287
357
|
deriveBlocker,
|
|
288
358
|
AGENT_IDENTITIES,
|
|
289
359
|
summarizeStop,
|
|
360
|
+
subagentStopSummary,
|
|
361
|
+
compactionAction,
|
|
290
362
|
sessionStartAction,
|
|
291
363
|
sessionEndAction,
|
|
292
|
-
taskTitleFrom
|
|
364
|
+
taskTitleFrom,
|
|
365
|
+
sessionIdentityOf
|
|
293
366
|
};
|