@pushary/agent-hooks 0.89.13 → 0.90.1
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 +73 -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 +187 -63
- 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-OX35BSPV.js → chunk-4LOPSGLP.js} +70 -11
- 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-B6H2KAQC.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-JHJHCMAF.js → chunk-F7OURW3C.js} +24 -6
- package/dist/{chunk-VASZ6TWW.js → chunk-FQL5E6NG.js} +2 -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-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
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
reapplyAllAgents
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-BQBEH6TV.js";
|
|
5
|
+
import "../chunk-H2QZRQR2.js";
|
|
6
6
|
import {
|
|
7
7
|
waitForMachineReadiness
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-
|
|
8
|
+
} from "../chunk-7TPQEWUZ.js";
|
|
9
|
+
import "../chunk-DZDI62LY.js";
|
|
10
|
+
import "../chunk-GL3FFM7A.js";
|
|
11
|
+
import "../chunk-2LAHXHBR.js";
|
|
12
|
+
import "../chunk-EZIEXHYM.js";
|
|
13
13
|
import {
|
|
14
14
|
daemonHasRemoteProof,
|
|
15
15
|
daemonServiceManagerAvailable,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
replaceDaemonService,
|
|
21
21
|
stopDaemonService,
|
|
22
22
|
waitForDaemonRemoteProof
|
|
23
|
-
} from "../chunk-
|
|
23
|
+
} from "../chunk-F2ICEWZL.js";
|
|
24
24
|
import {
|
|
25
25
|
detectProviderLiveCapabilities,
|
|
26
26
|
hasSpawnProvider,
|
|
@@ -34,32 +34,32 @@ import {
|
|
|
34
34
|
npmErrorMessage,
|
|
35
35
|
resolveGlobalBinary
|
|
36
36
|
} from "../chunk-L4ZCFMWW.js";
|
|
37
|
-
import "../chunk-
|
|
37
|
+
import "../chunk-54ELC7D7.js";
|
|
38
38
|
import {
|
|
39
39
|
claudeJson,
|
|
40
40
|
codexConfigToml,
|
|
41
41
|
cursorPluginDir,
|
|
42
42
|
geminiSettings,
|
|
43
43
|
vscodePluginDir
|
|
44
|
-
} from "../chunk-
|
|
44
|
+
} from "../chunk-KUZWXPUS.js";
|
|
45
45
|
import {
|
|
46
46
|
exitOnHelpFlag
|
|
47
|
-
} from "../chunk-
|
|
48
|
-
import "../chunk-
|
|
47
|
+
} from "../chunk-BVBEURWJ.js";
|
|
48
|
+
import "../chunk-43GMYSS4.js";
|
|
49
49
|
import {
|
|
50
50
|
isNewerVersion
|
|
51
51
|
} from "../chunk-DINDL2CF.js";
|
|
52
52
|
import {
|
|
53
53
|
readControlMode
|
|
54
|
-
} from "../chunk-
|
|
54
|
+
} from "../chunk-OSALSIUF.js";
|
|
55
55
|
import "../chunk-BC3VCZ3E.js";
|
|
56
56
|
import "../chunk-KZERVKTD.js";
|
|
57
|
-
import "../chunk-
|
|
57
|
+
import "../chunk-JW4KO5AF.js";
|
|
58
58
|
import "../chunk-4LL6LG5X.js";
|
|
59
59
|
import {
|
|
60
60
|
getApiKey
|
|
61
61
|
} from "../chunk-2UMNXADU.js";
|
|
62
|
-
import "../chunk-
|
|
62
|
+
import "../chunk-VNMKIJZB.js";
|
|
63
63
|
|
|
64
64
|
// bin/pushary-upgrade.ts
|
|
65
65
|
import { existsSync } from "fs";
|
package/dist/bin/pushary-wait.js
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
} from "../chunk-IIENZE2J.js";
|
|
5
5
|
import {
|
|
6
6
|
exitOnFailedResponse
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-DYP6SMOR.js";
|
|
8
|
+
import "../chunk-AJYV3VGU.js";
|
|
9
9
|
import {
|
|
10
10
|
createIo
|
|
11
11
|
} from "../chunk-5RUIFDTP.js";
|
|
@@ -14,8 +14,8 @@ import {
|
|
|
14
14
|
} from "../chunk-GMXKITVA.js";
|
|
15
15
|
import {
|
|
16
16
|
exitOnHelpFlag
|
|
17
|
-
} from "../chunk-
|
|
18
|
-
import "../chunk-
|
|
17
|
+
} from "../chunk-BVBEURWJ.js";
|
|
18
|
+
import "../chunk-43GMYSS4.js";
|
|
19
19
|
import "../chunk-DINDL2CF.js";
|
|
20
20
|
import "../chunk-SAF6HGAA.js";
|
|
21
21
|
import {
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
getApiKey,
|
|
29
29
|
getBaseUrl
|
|
30
30
|
} from "../chunk-2UMNXADU.js";
|
|
31
|
-
import "../chunk-
|
|
31
|
+
import "../chunk-VNMKIJZB.js";
|
|
32
32
|
|
|
33
33
|
// bin/pushary-wait.ts
|
|
34
34
|
exitOnHelpFlag("wait");
|
package/dist/bin/pushary.js
CHANGED
|
@@ -149,6 +149,7 @@ var SETUP_OPTIONS = [
|
|
|
149
149
|
["--control auto|on|off", "Manage phone-start automatically (default), require it, or disable its background service"],
|
|
150
150
|
["--transcripts on|off", "Enable or disable encrypted transcript sync on this machine"],
|
|
151
151
|
["--skip-phone", "Skip the phone connect step"],
|
|
152
|
+
["--take-over-hooks", "Replace hooks the Pushary Mac app owns with the CLI's. Without it the app's wiring is kept"],
|
|
152
153
|
["--verify roundtrip", "Send a real question and wait for you to answer it (default when a human is present)"],
|
|
153
154
|
["--verify push", "Only prove a notification was delivered. Automatic when nobody is at the terminal"],
|
|
154
155
|
["--verify none", "Skip the final check entirely"],
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
isDefaultSession,
|
|
5
5
|
isPolicyConfig,
|
|
6
6
|
listPendingQuestions,
|
|
7
|
+
listPendingQuestionsForToolUse,
|
|
7
8
|
markPendingCommandDelivered,
|
|
8
9
|
readPendingCommand,
|
|
9
10
|
removePendingCommand,
|
|
@@ -12,9 +13,10 @@ import {
|
|
|
12
13
|
savePendingCommand,
|
|
13
14
|
sendNotification,
|
|
14
15
|
waitForAnswer
|
|
15
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-F7OURW3C.js";
|
|
16
17
|
import {
|
|
17
18
|
AGENT_IDENTITIES,
|
|
19
|
+
compactionAction,
|
|
18
20
|
deriveReceiptMeta,
|
|
19
21
|
deriveToolTarget,
|
|
20
22
|
describeToolCall,
|
|
@@ -22,20 +24,22 @@ import {
|
|
|
22
24
|
parseApplyPatchFiles,
|
|
23
25
|
parseApplyPatchOps,
|
|
24
26
|
sessionEndAction,
|
|
27
|
+
sessionIdentityOf,
|
|
25
28
|
sessionStartAction,
|
|
29
|
+
subagentStopSummary,
|
|
26
30
|
summarizeStop,
|
|
27
31
|
taskTitleFrom,
|
|
28
32
|
toolResultErrorText
|
|
29
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-L4E2BIJ2.js";
|
|
30
34
|
import {
|
|
31
35
|
getMachineId
|
|
32
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-54ELC7D7.js";
|
|
33
37
|
import {
|
|
34
38
|
withRetry
|
|
35
39
|
} from "./chunk-BSZYIAZL.js";
|
|
36
40
|
import {
|
|
37
41
|
reportedInstallSource
|
|
38
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-JW4KO5AF.js";
|
|
39
43
|
import {
|
|
40
44
|
getApiKey,
|
|
41
45
|
getBaseUrl
|
|
@@ -51,7 +55,7 @@ import {
|
|
|
51
55
|
pendingCommandEvents,
|
|
52
56
|
resolveAutoResolveOrigin,
|
|
53
57
|
resolvePolicy
|
|
54
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-VNMKIJZB.js";
|
|
55
59
|
|
|
56
60
|
// src/policy.ts
|
|
57
61
|
import { createHash } from "crypto";
|
|
@@ -505,6 +509,15 @@ var permissionTimeoutDecision = (timeoutAction) => {
|
|
|
505
509
|
};
|
|
506
510
|
var preToolUseTimeoutDecision = (timeoutAction, denyReason = "No response within timeout") => timeoutAction === "deny" ? codexDeny(denyReason) : codexPass();
|
|
507
511
|
|
|
512
|
+
// src/driver.ts
|
|
513
|
+
var DRIVER_ENV = "PUSHARY_DRIVER";
|
|
514
|
+
var PHONE_DRIVER = "phone";
|
|
515
|
+
var driverFromEnv = (env) => env[DRIVER_ENV] === PHONE_DRIVER ? PHONE_DRIVER : void 0;
|
|
516
|
+
var phoneDrivenEnv = (base) => ({
|
|
517
|
+
...base,
|
|
518
|
+
[DRIVER_ENV]: PHONE_DRIVER
|
|
519
|
+
});
|
|
520
|
+
|
|
508
521
|
// src/throttle.ts
|
|
509
522
|
import { join as join4 } from "path";
|
|
510
523
|
import { tmpdir as tmpdir3 } from "os";
|
|
@@ -552,10 +565,13 @@ var readLastPrompt = (sessionId) => {
|
|
|
552
565
|
return void 0;
|
|
553
566
|
}
|
|
554
567
|
};
|
|
555
|
-
var
|
|
568
|
+
var pendingQuestionsToSettle = (sessionId, toolUseId) => {
|
|
569
|
+
const settledElsewhere = toolUseId ? listPendingQuestionsForToolUse(sessionId, toolUseId) : [];
|
|
570
|
+
return [.../* @__PURE__ */ new Set([...settledElsewhere, ...listPendingQuestions(sessionId)])];
|
|
571
|
+
};
|
|
572
|
+
var reconcileQuestions = async (sessionId, files) => {
|
|
556
573
|
const late = [];
|
|
557
574
|
try {
|
|
558
|
-
const files = listPendingQuestions(sessionId);
|
|
559
575
|
if (files.length === 0) return late;
|
|
560
576
|
const apiKey = getApiKey();
|
|
561
577
|
for (const correlationId of files) {
|
|
@@ -576,6 +592,7 @@ var reconcilePendingQuestions = async (sessionId) => {
|
|
|
576
592
|
}
|
|
577
593
|
return late;
|
|
578
594
|
};
|
|
595
|
+
var reconcilePendingQuestions = (sessionId, toolUseId) => reconcileQuestions(sessionId, pendingQuestionsToSettle(sessionId, toolUseId));
|
|
579
596
|
var describeLateAnswer = (value) => {
|
|
580
597
|
const v = (value ?? "").trim();
|
|
581
598
|
if (v === "yes") return "approved it";
|
|
@@ -724,6 +741,7 @@ var reportEvent = async (event, options = {}) => {
|
|
|
724
741
|
// Link-back for a phone-spawned session: forward the spawn id the daemon
|
|
725
742
|
// set in the environment so the server can map spawnId -> sessionId.
|
|
726
743
|
...process.env.PUSHARY_SPAWN_ID ? { spawnId: process.env.PUSHARY_SPAWN_ID } : {},
|
|
744
|
+
...driverFromEnv(process.env) ? { driver: driverFromEnv(process.env) } : {},
|
|
727
745
|
canDrainCommand: clientCanDrain && !storedCommand,
|
|
728
746
|
ackMode: clientCanDrain && !storedCommand,
|
|
729
747
|
skipCommandDrain: storedCommand != null
|
|
@@ -780,6 +798,11 @@ var reportEvent = async (event, options = {}) => {
|
|
|
780
798
|
}, { maxAttempts: options.maxAttempts ?? 2, baseDelayMs: 300 });
|
|
781
799
|
};
|
|
782
800
|
var NON_GATED_MIRROR_TOOLS = /* @__PURE__ */ new Set(["TodoWrite"]);
|
|
801
|
+
var settleQuestionsForToolUse = async (sessionId, toolUseId) => {
|
|
802
|
+
if (!toolUseId) return;
|
|
803
|
+
const late = await reconcileQuestions(sessionId, listPendingQuestionsForToolUse(sessionId, toolUseId));
|
|
804
|
+
for (const answer of late) removePendingQuestion(sessionId, answer.correlationId);
|
|
805
|
+
};
|
|
783
806
|
var handlePostToolUse = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
784
807
|
try {
|
|
785
808
|
const projectName = basename2(input.cwd ?? process.cwd());
|
|
@@ -790,7 +813,7 @@ var handlePostToolUse = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
790
813
|
const receiptsEnabled = process.env.PUSHARY_RECEIPTS !== "off";
|
|
791
814
|
const sessionKey = input.session_id || DEFAULT_SESSION;
|
|
792
815
|
const liveMode = await fetchModeState(getApiKey(), input.session_id, MODE_REUSE_MS);
|
|
793
|
-
const late = await reconcilePendingQuestions(sessionKey);
|
|
816
|
+
const late = await reconcilePendingQuestions(sessionKey, input.tool_use_id);
|
|
794
817
|
let additionalContext;
|
|
795
818
|
if (late.length > 0 && agent.type === CLAUDE_CODE_AGENT.type) {
|
|
796
819
|
additionalContext = buildLateAnswerContext(late);
|
|
@@ -875,7 +898,7 @@ var handleStop = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
875
898
|
agentType: agent.type,
|
|
876
899
|
agentName: `${agent.label} - ${projectName}`,
|
|
877
900
|
action: summarizeStop(input),
|
|
878
|
-
|
|
901
|
+
...sessionIdentityOf(input),
|
|
879
902
|
usage: deriveUsage(input.transcript_path, input.session_id)
|
|
880
903
|
}, { maxAttempts: 1 })
|
|
881
904
|
];
|
|
@@ -897,16 +920,46 @@ var handleStop = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
897
920
|
return void 0;
|
|
898
921
|
}
|
|
899
922
|
};
|
|
923
|
+
var isSubagentStop = (input) => input.hook_event_name === "SubagentStop" || typeof input.agent_id === "string" && input.agent_id.length > 0;
|
|
924
|
+
var SUBAGENT_STOP_REPORT_TIMEOUT_MS = 4e3;
|
|
925
|
+
var handleSubagentStop = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
926
|
+
try {
|
|
927
|
+
const projectName = basename2(input.cwd ?? process.cwd());
|
|
928
|
+
await reportEvent({
|
|
929
|
+
event: "session_end",
|
|
930
|
+
agentType: agent.type,
|
|
931
|
+
agentName: `${agent.label} - ${projectName}`,
|
|
932
|
+
action: subagentStopSummary(input),
|
|
933
|
+
...sessionIdentityOf(input)
|
|
934
|
+
}, { maxAttempts: 1, timeoutMs: SUBAGENT_STOP_REPORT_TIMEOUT_MS });
|
|
935
|
+
} catch {
|
|
936
|
+
}
|
|
937
|
+
};
|
|
938
|
+
var isCompactionEvent = (hookEventName) => hookEventName === "PreCompact" || hookEventName === "PostCompact";
|
|
939
|
+
var COMPACTION_REPORT_TIMEOUT_MS = 4e3;
|
|
940
|
+
var handleCompaction = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
941
|
+
try {
|
|
942
|
+
const projectName = basename2(input.cwd ?? process.cwd());
|
|
943
|
+
await reportEvent({
|
|
944
|
+
event: "compaction",
|
|
945
|
+
agentType: agent.type,
|
|
946
|
+
agentName: `${agent.label} - ${projectName}`,
|
|
947
|
+
action: compactionAction(input.hook_event_name, input.trigger),
|
|
948
|
+
sessionId: input.session_id
|
|
949
|
+
}, { maxAttempts: 1, timeoutMs: COMPACTION_REPORT_TIMEOUT_MS });
|
|
950
|
+
} catch {
|
|
951
|
+
}
|
|
952
|
+
};
|
|
900
953
|
var handleSessionStart = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
901
954
|
try {
|
|
902
955
|
const projectName = basename2(input.cwd ?? process.cwd());
|
|
903
|
-
const action = sessionStartAction(input.source);
|
|
956
|
+
const action = input.agent_id ? "Subagent started" : sessionStartAction(input.source);
|
|
904
957
|
await reportEvent({
|
|
905
958
|
event: "session_start",
|
|
906
959
|
agentType: agent.type,
|
|
907
960
|
agentName: `${agent.label} - ${projectName}`,
|
|
908
961
|
action,
|
|
909
|
-
|
|
962
|
+
...sessionIdentityOf(input)
|
|
910
963
|
}, { maxAttempts: 2, timeoutMs: 4e3 });
|
|
911
964
|
} catch {
|
|
912
965
|
}
|
|
@@ -1033,6 +1086,7 @@ export {
|
|
|
1033
1086
|
getPolicy,
|
|
1034
1087
|
fetchModeState,
|
|
1035
1088
|
fetchModeOverride,
|
|
1089
|
+
phoneDrivenEnv,
|
|
1036
1090
|
repoKeyFor,
|
|
1037
1091
|
throttlePass,
|
|
1038
1092
|
readLastUserPrompt,
|
|
@@ -1048,9 +1102,14 @@ export {
|
|
|
1048
1102
|
preToolUseTimeoutDecision,
|
|
1049
1103
|
readLastPrompt,
|
|
1050
1104
|
reportEvent,
|
|
1105
|
+
settleQuestionsForToolUse,
|
|
1051
1106
|
handlePostToolUse,
|
|
1052
1107
|
handleUserPrompt,
|
|
1053
1108
|
handleStop,
|
|
1109
|
+
isSubagentStop,
|
|
1110
|
+
handleSubagentStop,
|
|
1111
|
+
isCompactionEvent,
|
|
1112
|
+
handleCompaction,
|
|
1054
1113
|
handleSessionStart,
|
|
1055
1114
|
handleSessionEnd,
|
|
1056
1115
|
handleNotification,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
redactSecrets
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VNMKIJZB.js";
|
|
4
4
|
|
|
5
5
|
// src/crypto.ts
|
|
6
6
|
import nacl from "tweetnacl";
|
|
@@ -98,7 +98,17 @@ var INTERNAL_TYPES = /* @__PURE__ */ new Set([
|
|
|
98
98
|
"file-history-snapshot",
|
|
99
99
|
"change",
|
|
100
100
|
"queue-operation",
|
|
101
|
-
"summary"
|
|
101
|
+
"summary",
|
|
102
|
+
"last-prompt",
|
|
103
|
+
"mode",
|
|
104
|
+
"permission-mode",
|
|
105
|
+
"atis-latch",
|
|
106
|
+
"frame-link",
|
|
107
|
+
"cost-state",
|
|
108
|
+
"agent-name",
|
|
109
|
+
"bridge-session",
|
|
110
|
+
"artifact-autoreact-ledger",
|
|
111
|
+
"artifact-comment-monitor"
|
|
102
112
|
]);
|
|
103
113
|
var redactDeep = (value) => {
|
|
104
114
|
if (typeof value === "string") return redactSecrets(value);
|
|
@@ -232,9 +232,43 @@ var runHermesPythonScript = (python, script, ...args) => {
|
|
|
232
232
|
}
|
|
233
233
|
};
|
|
234
234
|
|
|
235
|
+
// src/cli/dry-run.ts
|
|
236
|
+
import { execSync } from "child_process";
|
|
237
|
+
import { rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
238
|
+
var createGuards = (isDryRun, note) => ({
|
|
239
|
+
write: (path, contents) => {
|
|
240
|
+
if (isDryRun()) return note("rewrite", path);
|
|
241
|
+
writeFileSync2(path, contents, "utf-8");
|
|
242
|
+
},
|
|
243
|
+
remove: (path, options = {}) => {
|
|
244
|
+
if (isDryRun()) return note("remove ", path);
|
|
245
|
+
rmSync2(path, { recursive: true, force: options.force ?? false });
|
|
246
|
+
},
|
|
247
|
+
exec: (command, options, describe) => {
|
|
248
|
+
if (isDryRun()) return note("run ", describe);
|
|
249
|
+
execSync(command, options);
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
var describeService = (effects) => {
|
|
253
|
+
if (effects.controlMode === "off") return "skip the phone-start background service (--control off)";
|
|
254
|
+
const where = effects.serviceDefinitionPath ?? "the phone-start service definition";
|
|
255
|
+
const condition = effects.controlMode === "on" ? "" : ", when a supported agent and a service manager are present";
|
|
256
|
+
return `write ${where} and register it with the OS${condition}`;
|
|
257
|
+
};
|
|
258
|
+
var describeSetupSideEffects = (effects) => [
|
|
259
|
+
`run npm install -g @pushary/agent-hooks@${effects.version} (the hooks run from the global copy; up to two minutes)`,
|
|
260
|
+
`write ${effects.configFile} (the API key, mode 600)`,
|
|
261
|
+
effects.rcPath ? `edit ${effects.rcPath} (export PUSHARY_API_KEY)` : "print the export line for your shell, since no rc file was found",
|
|
262
|
+
describeService(effects),
|
|
263
|
+
"ask Add Pushary instructions to this project's CLAUDE.md/AGENTS.md? (default no)",
|
|
264
|
+
"ask Alias claude to pushary claude? (default no)"
|
|
265
|
+
];
|
|
266
|
+
|
|
235
267
|
export {
|
|
236
268
|
isHermesConfigReceipt,
|
|
237
269
|
HERMES_CONFIG_SCRIPT,
|
|
238
270
|
resolveHermesPython,
|
|
239
|
-
runHermesPythonScript
|
|
271
|
+
runHermesPythonScript,
|
|
272
|
+
createGuards,
|
|
273
|
+
describeSetupSideEffects
|
|
240
274
|
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PRETOOLUSE_HANDLED_TOOLS,
|
|
3
3
|
PRETOOLUSE_PHONE_ANSWERED_TOOLS
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2LAHXHBR.js";
|
|
5
5
|
import {
|
|
6
6
|
defersToNativeMode
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-I463AEG3.js";
|
|
8
8
|
import {
|
|
9
9
|
isGatingMoment,
|
|
10
10
|
recordKeylessMoment
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-VHWCVD42.js";
|
|
12
12
|
import {
|
|
13
13
|
denyReasonFrom,
|
|
14
14
|
isDeferAnswer
|
|
@@ -19,8 +19,9 @@ import {
|
|
|
19
19
|
readLastPrompt,
|
|
20
20
|
readLastUserPrompt,
|
|
21
21
|
repoKeyFor,
|
|
22
|
+
settleQuestionsForToolUse,
|
|
22
23
|
throttlePass
|
|
23
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-4LOPSGLP.js";
|
|
24
25
|
import {
|
|
25
26
|
DEFAULT_SESSION,
|
|
26
27
|
askUser,
|
|
@@ -28,7 +29,7 @@ import {
|
|
|
28
29
|
pollForAnswer,
|
|
29
30
|
savePendingQuestion,
|
|
30
31
|
sendNotification
|
|
31
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-F7OURW3C.js";
|
|
32
33
|
import {
|
|
33
34
|
UNNAMED_ACTION,
|
|
34
35
|
deriveAction,
|
|
@@ -37,10 +38,10 @@ import {
|
|
|
37
38
|
deriveToolTarget,
|
|
38
39
|
describeToolCall,
|
|
39
40
|
scopePathFor
|
|
40
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-L4E2BIJ2.js";
|
|
41
42
|
import {
|
|
42
43
|
getMachineId
|
|
43
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-54ELC7D7.js";
|
|
44
45
|
import {
|
|
45
46
|
getApiKey,
|
|
46
47
|
getBaseUrl
|
|
@@ -52,10 +53,12 @@ import {
|
|
|
52
53
|
effectiveWaitSeconds,
|
|
53
54
|
hookWaitClamped,
|
|
54
55
|
hookWaitDeadline,
|
|
56
|
+
isPusharyOwnTool,
|
|
55
57
|
parseAgentQuestionAnswers,
|
|
56
58
|
parseAgentQuestions,
|
|
57
|
-
resolveGate
|
|
58
|
-
|
|
59
|
+
resolveGate,
|
|
60
|
+
stoppedOutput
|
|
61
|
+
} from "./chunk-VNMKIJZB.js";
|
|
59
62
|
|
|
60
63
|
// src/decision-episode.ts
|
|
61
64
|
var EPISODE_PATH = "/api/agent/decision-episode";
|
|
@@ -88,6 +91,7 @@ var allow = () => claudePreToolUseOutput("allow");
|
|
|
88
91
|
var deny = (reason) => claudePreToolUseOutput("deny", reason);
|
|
89
92
|
var allowWithInput = (updatedInput) => claudePreToolUseOutput("allow", void 0, updatedInput);
|
|
90
93
|
var ask = (reason) => claudePreToolUseOutput("ask", reason);
|
|
94
|
+
var halted = (reason) => stoppedOutput(deny(reason), reason);
|
|
91
95
|
var storedWaitDeadline = (result, requestedDeadline) => {
|
|
92
96
|
const stored = result.waitEndsAt ? Date.parse(result.waitEndsAt) : Number.NaN;
|
|
93
97
|
return Number.isFinite(stored) ? Math.min(stored, requestedDeadline) : requestedDeadline;
|
|
@@ -148,7 +152,7 @@ var handlePushOnly = async (apiKey, description, projectName, timeoutSeconds, ti
|
|
|
148
152
|
return answer.value === "yes" ? allow() : deny(denyReasonFrom(answer.value, answer.note));
|
|
149
153
|
}
|
|
150
154
|
if (timeoutAction === "wait" || clampCut) {
|
|
151
|
-
savePendingQuestion(sessionId || DEFAULT_SESSION, result.correlationId);
|
|
155
|
+
savePendingQuestion(sessionId || DEFAULT_SESSION, result.correlationId, decision.toolUseId);
|
|
152
156
|
return ask(timeoutAction === "wait" ? "Still waiting on your phone. Answer here, or on your phone and it will be applied on the next step." : "This step cannot wait any longer. Answer here, or on your phone and it will be applied on the next step.");
|
|
153
157
|
}
|
|
154
158
|
switch (timeoutAction) {
|
|
@@ -157,7 +161,7 @@ var handlePushOnly = async (apiKey, description, projectName, timeoutSeconds, ti
|
|
|
157
161
|
case "deny":
|
|
158
162
|
return deny("No response within timeout");
|
|
159
163
|
default:
|
|
160
|
-
savePendingQuestion(sessionId || DEFAULT_SESSION, result.correlationId);
|
|
164
|
+
savePendingQuestion(sessionId || DEFAULT_SESSION, result.correlationId, decision.toolUseId);
|
|
161
165
|
return ask("No push response, asking in terminal");
|
|
162
166
|
}
|
|
163
167
|
};
|
|
@@ -201,7 +205,7 @@ var handlePushFirst = async (apiKey, description, projectName, pushFirstSeconds,
|
|
|
201
205
|
signals.humanDecision = true;
|
|
202
206
|
return answer.value === "yes" ? allow() : deny(denyReasonFrom(answer.value, answer.note));
|
|
203
207
|
}
|
|
204
|
-
savePendingQuestion(sessionId || DEFAULT_SESSION, result.correlationId);
|
|
208
|
+
savePendingQuestion(sessionId || DEFAULT_SESSION, result.correlationId, decision.toolUseId);
|
|
205
209
|
return ask("Sent as push notification. You can also approve here.");
|
|
206
210
|
};
|
|
207
211
|
var handleNotifyOnly = async (apiKey, description, projectName, sessionId, machineId) => {
|
|
@@ -359,7 +363,7 @@ var askAsOneCard = async (apiKey, input, parsed, projectName, deadline) => {
|
|
|
359
363
|
const answer = returnedAnswer(result) ?? await pollForAnswer(apiKey, result.correlationId, storedWaitDeadline(result, deadline));
|
|
360
364
|
const values = answer.answered && answer.value ? parseAgentQuestionAnswers(parsed, answer.value) : null;
|
|
361
365
|
if (!values || isDeferAnswer(answer.value)) {
|
|
362
|
-
savePendingQuestion(input.session_id || DEFAULT_SESSION, result.correlationId);
|
|
366
|
+
savePendingQuestion(input.session_id || DEFAULT_SESSION, result.correlationId, input.tool_use_id);
|
|
363
367
|
return void 0;
|
|
364
368
|
}
|
|
365
369
|
return values;
|
|
@@ -400,14 +404,15 @@ var askQuestionByQuestion = async (apiKey, input, parsed, projectName, deadline)
|
|
|
400
404
|
})) : null;
|
|
401
405
|
const value = values?.[question.question];
|
|
402
406
|
if (!value || isDeferAnswer(answer.value)) {
|
|
403
|
-
savePendingQuestion(input.session_id || DEFAULT_SESSION, result.correlationId);
|
|
407
|
+
savePendingQuestion(input.session_id || DEFAULT_SESSION, result.correlationId, input.tool_use_id);
|
|
404
408
|
return void 0;
|
|
405
409
|
}
|
|
406
410
|
answers[question.question] = value;
|
|
407
411
|
}
|
|
408
412
|
return answers;
|
|
409
413
|
};
|
|
410
|
-
var handleAskUserQuestion = async (apiKey, input) => {
|
|
414
|
+
var handleAskUserQuestion = async (apiKey, input, modeState) => {
|
|
415
|
+
if (modeState.askHandoff) return void 0;
|
|
411
416
|
const parsed = parseQuestions(input.tool_input ?? {});
|
|
412
417
|
if (!parsed) return void 0;
|
|
413
418
|
const projectName = basename(input.cwd ?? process.cwd());
|
|
@@ -452,7 +457,7 @@ var handleExitPlanMode = async (apiKey, input) => {
|
|
|
452
457
|
const answer = returnedAnswer(result) ?? await pollForAnswer(apiKey, result.correlationId, storedWaitDeadline(result, deadline));
|
|
453
458
|
const value = answer.answered ? (answer.value ?? "").trim() : "";
|
|
454
459
|
if (!value || isDeferAnswer(answer.value)) {
|
|
455
|
-
savePendingQuestion(input.session_id || DEFAULT_SESSION, result.correlationId);
|
|
460
|
+
savePendingQuestion(input.session_id || DEFAULT_SESSION, result.correlationId, input.tool_use_id);
|
|
456
461
|
return void 0;
|
|
457
462
|
}
|
|
458
463
|
if (value === PLAN_APPROVE) return allow();
|
|
@@ -487,7 +492,7 @@ var claudeGateInput = (modeState, config, input) => {
|
|
|
487
492
|
};
|
|
488
493
|
};
|
|
489
494
|
var handlePreToolUse = async (input) => {
|
|
490
|
-
if (input.tool_name
|
|
495
|
+
if (isPusharyOwnTool(input.tool_name)) return void 0;
|
|
491
496
|
let apiKey;
|
|
492
497
|
try {
|
|
493
498
|
apiKey = getApiKey();
|
|
@@ -498,10 +503,10 @@ var handlePreToolUse = async (input) => {
|
|
|
498
503
|
const modeState = await fetchModeState(apiKey, input.session_id);
|
|
499
504
|
const policy = await getPolicy(apiKey, modeState.policyVersion, "claude_code", true, input.session_id);
|
|
500
505
|
const verdict = resolveGate(claudeGateInput(modeState, policy, input));
|
|
501
|
-
if (verdict.kind === "kill") return
|
|
506
|
+
if (verdict.kind === "kill") return halted(verdict.reason);
|
|
502
507
|
if (verdict.kind === "deny") return deny(verdict.reason);
|
|
503
508
|
if (input.tool_name === "AskUserQuestion") {
|
|
504
|
-
return handleAskUserQuestion(apiKey, input);
|
|
509
|
+
return handleAskUserQuestion(apiKey, input, modeState);
|
|
505
510
|
}
|
|
506
511
|
if (input.tool_name === "ExitPlanMode") {
|
|
507
512
|
return handleExitPlanMode(apiKey, input);
|
|
@@ -528,6 +533,7 @@ var handlePreToolUse = async (input) => {
|
|
|
528
533
|
};
|
|
529
534
|
var permReqAllow = (updatedInput) => claudePermissionRequestOutput("allow", void 0, updatedInput);
|
|
530
535
|
var permReqDeny = (message) => claudePermissionRequestOutput("deny", message);
|
|
536
|
+
var permReqHalted = (reason) => stoppedOutput(permReqDeny(reason), reason);
|
|
531
537
|
var toPermissionRequestOutput = (hookOutput) => {
|
|
532
538
|
if (!hookOutput) return void 0;
|
|
533
539
|
const d = hookOutput.hookSpecificOutput;
|
|
@@ -540,7 +546,7 @@ var handlePermissionRequest = async (input) => {
|
|
|
540
546
|
const reclaimDeferredExec = !PRETOOLUSE_PHONE_ANSWERED_TOOLS.includes(input.tool_name) && shouldDeferToNativeMode(input.permission_mode, input.tool_name);
|
|
541
547
|
if (!reclaimDeferredExec) return void 0;
|
|
542
548
|
}
|
|
543
|
-
if (input.tool_name
|
|
549
|
+
if (isPusharyOwnTool(input.tool_name)) return void 0;
|
|
544
550
|
let apiKey;
|
|
545
551
|
try {
|
|
546
552
|
apiKey = getApiKey();
|
|
@@ -553,7 +559,7 @@ var handlePermissionRequest = async (input) => {
|
|
|
553
559
|
const verdict = resolveGate(claudeGateInput(modeState, policy, input));
|
|
554
560
|
switch (verdict.kind) {
|
|
555
561
|
case "kill":
|
|
556
|
-
return
|
|
562
|
+
return permReqHalted(verdict.reason);
|
|
557
563
|
case "allow":
|
|
558
564
|
return permReqAllow();
|
|
559
565
|
case "deny":
|
|
@@ -577,7 +583,7 @@ var automodeRetryEnabled = () => {
|
|
|
577
583
|
return flag === "1" || flag === "true";
|
|
578
584
|
};
|
|
579
585
|
var handlePermissionDenied = async (input) => {
|
|
580
|
-
if (input.tool_name
|
|
586
|
+
if (isPusharyOwnTool(input.tool_name)) return void 0;
|
|
581
587
|
let apiKey;
|
|
582
588
|
try {
|
|
583
589
|
apiKey = getApiKey();
|
|
@@ -587,6 +593,7 @@ var handlePermissionDenied = async (input) => {
|
|
|
587
593
|
try {
|
|
588
594
|
const projectName = basename(input.cwd ?? process.cwd());
|
|
589
595
|
const sessionKey = input.session_id || DEFAULT_SESSION;
|
|
596
|
+
await settleQuestionsForToolUse(sessionKey, input.tool_use_id);
|
|
590
597
|
if (!throttlePass(`permdenied:${sessionKey}:${input.tool_name}`, PERMISSION_DENIED_WINDOW_MS)) return void 0;
|
|
591
598
|
const mode = await fetchModeState(apiKey, input.session_id).catch(() => null);
|
|
592
599
|
if (mode?.kill || mode?.mode === "terminal_only") return void 0;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
detectClaudeVersion
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-H2QZRQR2.js";
|
|
4
4
|
import {
|
|
5
5
|
claudeWired,
|
|
6
6
|
codexWired,
|
|
7
7
|
geminiWired
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-DZDI62LY.js";
|
|
9
9
|
import {
|
|
10
10
|
GEMINI_HOOK_BINARY,
|
|
11
11
|
addClaudeMcpServer,
|
|
@@ -14,10 +14,10 @@ import {
|
|
|
14
14
|
addPusharyHooks,
|
|
15
15
|
addPusharyToolPermissions,
|
|
16
16
|
hasGeminiHooks
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-GL3FFM7A.js";
|
|
18
18
|
import {
|
|
19
19
|
guardBinary
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-EZIEXHYM.js";
|
|
21
21
|
import {
|
|
22
22
|
resolveGlobalBinDir,
|
|
23
23
|
resolveGlobalBinary
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
codexHooksJson,
|
|
33
33
|
hasCodexHooks,
|
|
34
34
|
vscodePluginMcp
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-KUZWXPUS.js";
|
|
36
36
|
import {
|
|
37
37
|
readJsonSafe
|
|
38
38
|
} from "./chunk-4LL6LG5X.js";
|