pushary 1.9.83 → 1.9.84
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 +12 -0
- package/dist/{api-EKLKVJQG.js → api-4WEMR2G3.js} +10 -10
- package/dist/bin/pushary-bell-hook.js +26 -26
- package/dist/bin/pushary-bell.js +10 -10
- package/dist/bin/pushary-claude.js +32 -31
- package/dist/bin/pushary-clean.js +34 -33
- package/dist/bin/pushary-codex-bridge.js +21 -21
- package/dist/bin/pushary-codex-hook.js +44 -43
- package/dist/bin/pushary-codex-session.js +8 -8
- package/dist/bin/pushary-codex.js +14 -13
- package/dist/bin/pushary-connect.js +27 -26
- package/dist/bin/pushary-cowork.js +5 -5
- package/dist/bin/pushary-daemon.js +70 -43
- package/dist/bin/pushary-disconnect.js +26 -25
- package/dist/bin/pushary-display-hook.js +17 -17
- package/dist/bin/pushary-doctor.js +42 -41
- package/dist/bin/pushary-elicitation-hook.js +26 -26
- package/dist/bin/pushary-gemini-bridge.js +15 -15
- package/dist/bin/pushary-gemini-hook.js +35 -34
- package/dist/bin/pushary-hook.js +30 -30
- package/dist/bin/pushary-login.js +20 -20
- package/dist/bin/pushary-logout.js +25 -24
- package/dist/bin/pushary-mcp.js +11 -11
- package/dist/bin/pushary-mode.js +15 -15
- package/dist/bin/pushary-notification-hook.js +25 -25
- package/dist/bin/pushary-opencode-hook.js +35 -34
- package/dist/bin/pushary-permission-denied-hook.js +30 -30
- package/dist/bin/pushary-permission-hook.js +30 -30
- package/dist/bin/pushary-post-hook.js +25 -25
- package/dist/bin/pushary-prompt-hook.js +25 -25
- package/dist/bin/pushary-session-end-hook.js +27 -27
- package/dist/bin/pushary-session-start-hook.js +35 -35
- package/dist/bin/pushary-setup.js +48 -47
- package/dist/bin/pushary-stats.js +5 -5
- package/dist/bin/pushary-status.js +32 -31
- package/dist/bin/pushary-stop-hook.js +25 -25
- package/dist/bin/pushary-stopfailure-hook.js +25 -25
- package/dist/bin/pushary-suggestions.js +15 -15
- package/dist/bin/pushary-transcript-register.js +21 -20
- package/dist/bin/pushary-transcripts.js +30 -20
- package/dist/bin/pushary-upgrade.js +40 -39
- package/dist/bin/pushary-wait.js +15 -15
- package/dist/bin/pushary.js +7 -7
- package/dist/{chunk-BLM6O2QL.js → chunk-254B34JU.js} +1 -1
- package/dist/{chunk-XYEGVQST.js → chunk-2VZY5XQ5.js} +7 -7
- package/dist/chunk-3MWQZKIO.js +843 -0
- package/dist/{chunk-46P53RBT.js → chunk-42DNYOC4.js} +23 -21
- package/dist/{chunk-7YYJASRF.js → chunk-4J3NGYHG.js} +2 -2
- package/dist/{chunk-ZGZ2L3QN.js → chunk-4OP5GWHQ.js} +5 -5
- package/dist/{chunk-5UPZR3C3.js → chunk-4QGV3II7.js} +4 -4
- package/dist/{chunk-MHUKYYYR.js → chunk-4TMKTLQX.js} +44 -1
- package/dist/{chunk-2B7YU4EK.js → chunk-5Z43EFX2.js} +2 -2
- package/dist/{chunk-YIAJOV2X.js → chunk-64XK7DLE.js} +3 -3
- package/dist/{chunk-VRHVOMH2.js → chunk-6HBWJXU6.js} +3 -3
- package/dist/{chunk-IUZCERPQ.js → chunk-7GYDMVHV.js} +2 -2
- package/dist/{chunk-BG4YJEFE.js → chunk-7ZYVX2KN.js} +1 -1
- package/dist/{chunk-KR3KVDXD.js → chunk-BGMYSRMY.js} +1 -1
- package/dist/{chunk-OUYFUUWB.js → chunk-BS5MTP34.js} +2 -2
- package/dist/{chunk-VCMDY6YL.js → chunk-BUS7MXEE.js} +3 -3
- package/dist/{chunk-EMT7I74E.js → chunk-CIICMXVH.js} +3 -3
- package/dist/{chunk-4P256ZAU.js → chunk-CSOVOAX5.js} +6 -6
- package/dist/{chunk-VBY2AHSX.js → chunk-CZ7C5AJT.js} +1 -1
- package/dist/{chunk-HCLP2QBX.js → chunk-DNBBWBYA.js} +5 -5
- package/dist/{chunk-BJN7LMMK.js → chunk-EKWDNEPN.js} +3 -3
- package/dist/{chunk-TNWQ6SKS.js → chunk-EX33ZFJ6.js} +3 -3
- package/dist/{chunk-TMBLBDPB.js → chunk-FNC4SPOD.js} +2 -2
- package/dist/{chunk-IBULUTHA.js → chunk-FRPR4OTH.js} +4 -4
- package/dist/{chunk-ACM4OINM.js → chunk-FSSA76HW.js} +1 -1
- package/dist/{chunk-J2PAQ3HF.js → chunk-G2GOVKBU.js} +6 -6
- package/dist/{chunk-2KVELJZX.js → chunk-GGGOFJBL.js} +1 -1
- package/dist/{chunk-GKWPIE6R.js → chunk-GWHZUHIK.js} +1 -1
- package/dist/{chunk-BUXMFD5C.js → chunk-H6IJOGDH.js} +4 -4
- package/dist/{chunk-SN22OXY3.js → chunk-HARHFDZM.js} +1 -1
- package/dist/{chunk-44R5ATBR.js → chunk-HLAW7HUT.js} +2 -2
- package/dist/{chunk-G4HTRKCP.js → chunk-HVZJ2EEI.js} +6 -6
- package/dist/{chunk-6BD5ZZLL.js → chunk-HWT42Z4O.js} +5 -5
- package/dist/{chunk-L4THAI7Q.js → chunk-JHWOM55B.js} +2 -0
- package/dist/{chunk-NDLOWIYO.js → chunk-JJCMQRBF.js} +3 -3
- package/dist/{chunk-7MRX5JYA.js → chunk-JLJWVKMJ.js} +54 -835
- package/dist/{chunk-TBU4WXA4.js → chunk-JSZT4Q23.js} +1 -1
- package/dist/{chunk-MA6FJ7U3.js → chunk-LUSWC2MV.js} +3 -3
- package/dist/{chunk-C5EWCNJF.js → chunk-OGTZ7JR7.js} +1 -1
- package/dist/{chunk-FGWRVOBP.js → chunk-OKWHHDV5.js} +5 -5
- package/dist/{chunk-XHHX63PY.js → chunk-OSEGZLCO.js} +3 -3
- package/dist/{chunk-B2RDWRKR.js → chunk-PHBZK4SC.js} +2 -2
- package/dist/{chunk-S55CXRFD.js → chunk-POKCUYIQ.js} +1 -1
- package/dist/{chunk-YZVAAY6B.js → chunk-QF6OJUWQ.js} +1 -1
- package/dist/{chunk-5FM4BQOM.js → chunk-QG5Y5A36.js} +10 -10
- package/dist/{chunk-UNEJNC6X.js → chunk-QSDZE2B7.js} +5 -5
- package/dist/{chunk-Y32CL7XZ.js → chunk-RPNT4D3K.js} +1 -1
- package/dist/{chunk-6CJ4MSZU.js → chunk-SAPRO7FI.js} +6 -6
- package/dist/{chunk-LLQBPDFQ.js → chunk-SBK7WGSE.js} +2 -2
- package/dist/{chunk-GMZTABMV.js → chunk-TD5PW2VI.js} +6 -6
- package/dist/{chunk-VUI4HK5O.js → chunk-TFJQAPIA.js} +2 -2
- package/dist/{chunk-OKZC4FHN.js → chunk-TNPKYKXU.js} +166 -24
- package/dist/{chunk-2BDGGE2G.js → chunk-TSCFJJIB.js} +6 -6
- package/dist/{chunk-MND7HQ4P.js → chunk-TZDEHPYZ.js} +1 -1
- package/dist/{chunk-FEF3ILT6.js → chunk-UGELL4RB.js} +2 -2
- package/dist/{chunk-6WOG2SCC.js → chunk-UIDWJ24H.js} +6 -13
- package/dist/{chunk-ZS27XXDA.js → chunk-UWL6VVE3.js} +4 -4
- package/dist/{chunk-JIC5PGNI.js → chunk-V4JZHAOY.js} +2 -2
- package/dist/{chunk-35ABA2JQ.js → chunk-VD24OIWR.js} +1 -1
- package/dist/{chunk-GGI6GTBL.js → chunk-VJZGR4N3.js} +7 -5
- package/dist/{chunk-CVPVP4KP.js → chunk-VVWL6AB4.js} +5 -5
- package/dist/{chunk-A3TMREYJ.js → chunk-W2IRYDG5.js} +4 -4
- package/dist/{chunk-SSNLMIFR.js → chunk-WRKRZJCW.js} +10 -8
- package/dist/{chunk-ASEHRBD4.js → chunk-YQCCJ6U5.js} +3 -3
- package/dist/{chunk-42RQG2VG.js → chunk-YU5ACKJP.js} +4 -4
- package/dist/{chunk-HIMEVTA5.js → chunk-Z75D2NJN.js} +3 -3
- package/dist/{chunk-6PWU2LBT.js → chunk-ZHL6F2KC.js} +3 -3
- package/dist/{chunk-SVAGMJOH.js → chunk-ZNFAF74M.js} +1 -1
- package/dist/{chunk-ELYJNNXG.js → chunk-ZUZ7NTWO.js} +181 -75
- package/dist/{chunk-QPJQAE2L.js → chunk-ZWKF7WE4.js} +4 -4
- package/dist/{codex-app-cards-switch-CTAOTOCH.js → codex-app-cards-switch-26N5XSSZ.js} +11 -11
- package/dist/{codex-desktop-launch-2DZVA5C7.js → codex-desktop-launch-UU6CPB2I.js} +1 -1
- package/dist/{codex-session-launch-TMOSTWEH.js → codex-session-launch-66LBR4MG.js} +18 -18
- package/dist/{config-OV6WLZXO.js → config-ESAAVJWO.js} +3 -3
- package/dist/{global-upgrade-FI42NJNL.js → global-upgrade-QJONTWQI.js} +10 -10
- package/dist/{identity-PCA25OI5.js → identity-IZVPSC7B.js} +4 -4
- package/dist/{live-capabilities-CYFXHTOI.js → live-capabilities-OEUPZX67.js} +5 -5
- package/dist/{paths-4YFDMUK6.js → paths-GDWS3B46.js} +3 -3
- package/dist/{reapply-PBQ46BPS.js → reapply-P2VOZGWQ.js} +28 -27
- package/dist/src/index.js +29 -29
- package/dist/{upgrade-lock-22J2AMVY.js → upgrade-lock-3QABNXBZ.js} +4 -4
- package/dist/{usage-7KTINNRK.js → usage-KDRZPUZS.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-7EIMASAA.js +0 -74
|
@@ -1,6 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AGENT_IDENTITIES,
|
|
3
|
+
COST_TRACKING_ENV,
|
|
4
|
+
DEFAULT_MODEL_PRICES,
|
|
5
|
+
TEAMMATE_IDLE_ACTION,
|
|
6
|
+
canonicalGateInputs,
|
|
7
|
+
compactionAction,
|
|
8
|
+
deriveReceiptMeta,
|
|
9
|
+
deriveToolTarget,
|
|
10
|
+
describeStopFailure,
|
|
11
|
+
describeToolCall,
|
|
12
|
+
estimateMessageCostUsd,
|
|
13
|
+
isModelPrice,
|
|
14
|
+
isToolResultError,
|
|
15
|
+
notificationAction,
|
|
16
|
+
notificationTypeOf,
|
|
17
|
+
parseApplyPatchFiles,
|
|
18
|
+
parseApplyPatchOps,
|
|
19
|
+
readTranscriptMessageUsage,
|
|
20
|
+
rememberTranscriptMessage,
|
|
21
|
+
sessionEndAction,
|
|
22
|
+
sessionIdentityOf,
|
|
23
|
+
sessionStartAction,
|
|
24
|
+
subagentStopSummary,
|
|
25
|
+
summarizeStop,
|
|
26
|
+
taskTitleFrom,
|
|
27
|
+
toolResultErrorText,
|
|
28
|
+
transcriptTokensIn,
|
|
29
|
+
transcriptUsageRequest
|
|
30
|
+
} from "./chunk-3MWQZKIO.js";
|
|
1
31
|
import {
|
|
2
32
|
repoKeyFor
|
|
3
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-OGTZ7JR7.js";
|
|
4
34
|
import {
|
|
5
35
|
cancelQuestion,
|
|
6
36
|
clientErrorKindOf,
|
|
@@ -8,847 +38,54 @@ import {
|
|
|
8
38
|
reportClientError,
|
|
9
39
|
sendNotification,
|
|
10
40
|
waitForAnswer
|
|
11
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-HWT42Z4O.js";
|
|
12
42
|
import {
|
|
13
43
|
withRetry
|
|
14
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-ZWKF7WE4.js";
|
|
15
45
|
import {
|
|
16
46
|
getMachineId
|
|
17
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-V4JZHAOY.js";
|
|
18
48
|
import {
|
|
19
49
|
reportedInstallSource
|
|
20
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-UGELL4RB.js";
|
|
21
51
|
import {
|
|
22
52
|
IDLE_PROMPT_NOTIFICATION,
|
|
23
53
|
NOTIFICATION_PUSH_TYPES,
|
|
24
54
|
POSTTOOLUSE_MIRROR_ONLY_TOOLS,
|
|
25
55
|
canonicalJson,
|
|
26
56
|
claudeConfigDir
|
|
27
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-PHBZK4SC.js";
|
|
28
58
|
import {
|
|
29
59
|
compareVersion,
|
|
30
60
|
parseVersion,
|
|
31
61
|
writeFileAtomic,
|
|
32
62
|
writeJsonAtomicDurable
|
|
33
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-64XK7DLE.js";
|
|
34
64
|
import {
|
|
35
65
|
getApiKey,
|
|
36
66
|
getBaseUrl
|
|
37
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-JSZT4Q23.js";
|
|
38
68
|
import {
|
|
39
|
-
ACTION_BODY_MAX,
|
|
40
|
-
AGENTS,
|
|
41
|
-
AGENT_LABELS_BY_TYPE,
|
|
42
|
-
BLANK_TASK_INPUT_TOOL,
|
|
43
69
|
BLOCKED_ACTION_GRANT_TTL_SECONDS,
|
|
44
|
-
CODEX_SHELL_COMMAND_FLAGS,
|
|
45
70
|
COMMAND_RECOVERY,
|
|
46
|
-
DECISION_LINE_MAX,
|
|
47
|
-
FILE_TARGET_TOOLS,
|
|
48
|
-
GATE_MAX_TOOL_INPUTS,
|
|
49
|
-
HOOK_COMPATIBLE_PROFILES,
|
|
50
71
|
HOOK_SOURCES,
|
|
51
72
|
REPO_AWARE_AGENTS,
|
|
52
|
-
TASK_OUTPUT_TOOL,
|
|
53
|
-
TASK_STOP_TOOL,
|
|
54
73
|
blockedActionIdentity,
|
|
55
74
|
canCarryPendingCommand,
|
|
56
|
-
canonicalToolName,
|
|
57
75
|
claudeTurnEndOutput,
|
|
58
|
-
conversationText,
|
|
59
76
|
gateOutputFor,
|
|
60
|
-
hookCompatibleProfileBySource,
|
|
61
77
|
isAutoApprove,
|
|
62
78
|
isClaudeWakePrompt,
|
|
63
79
|
isRecord,
|
|
64
|
-
isTokenCount,
|
|
65
80
|
modeStateFromResponse,
|
|
66
81
|
nativeRecord,
|
|
67
|
-
parseMcpToolName,
|
|
68
82
|
pendingCommandEvents,
|
|
69
83
|
pendingCommandInstruction,
|
|
70
84
|
questionLimitHandBack,
|
|
71
|
-
redactSecrets,
|
|
72
|
-
redactSecretsDeep,
|
|
73
|
-
reportableSessionId,
|
|
74
85
|
resolveAutoResolveOrigin,
|
|
75
86
|
resolvePolicy,
|
|
76
|
-
toToolLookup,
|
|
77
|
-
truncateLine,
|
|
78
87
|
unansweredRefusalReason
|
|
79
|
-
} from "./chunk-
|
|
80
|
-
|
|
81
|
-
// ../hook-mapping/src/describe.ts
|
|
82
|
-
import { isAbsolute, relative, resolve } from "path";
|
|
83
|
-
var hookPrefixes = {
|
|
84
|
-
Bash: (input) => `bash: ${input.command ?? "(no command)"}`,
|
|
85
|
-
PowerShell: (input) => `powershell: ${input.command ?? "(no command)"}`,
|
|
86
|
-
Monitor: (input) => `monitor: ${input.command ?? "(no command)"}`,
|
|
87
|
-
Write: (input) => `write file: ${input.file_path ?? "(unknown path)"}`,
|
|
88
|
-
Edit: (input) => `edit file: ${editTarget(input) ?? "(unknown path)"}`,
|
|
89
|
-
MultiEdit: (input) => `edit file: ${editTarget(input) ?? "(unknown path)"}`,
|
|
90
|
-
Read: (input) => `read file: ${input.file_path ?? "(unknown path)"}`,
|
|
91
|
-
// Without an entry here the fallback stringifies the whole tool input, and for
|
|
92
|
-
// ExitPlanMode that input IS the plan: the action line became a truncated dump of
|
|
93
|
-
// the plan markdown. The plan belongs in the body, not the one-line summary.
|
|
94
|
-
ExitPlanMode: () => "finished planning and wants to start coding",
|
|
95
|
-
// Mirrored on PostToolUse since the matcher was widened. Without entries the
|
|
96
|
-
// fallback prints `Task: done` and `WebSearch: done`, which name the tool and
|
|
97
|
-
// drop the only part a person reads: which subagent, and what it looked for.
|
|
98
|
-
Task: (input) => `subagent: ${describeTaskCall(input)}`,
|
|
99
|
-
WebSearch: (input) => `web search: ${firstString(input.query) ?? "(no query)"}`,
|
|
100
|
-
[TASK_OUTPUT_TOOL]: (input) => {
|
|
101
|
-
const task = firstString(input.task_id);
|
|
102
|
-
return task ? `check background task ${task}` : "list background tasks";
|
|
103
|
-
},
|
|
104
|
-
[TASK_STOP_TOOL]: (input) => `stop background task ${firstString(input.task_id) ?? "(unnamed)"}`,
|
|
105
|
-
[BLANK_TASK_INPUT_TOOL]: (input) => `send blank input, such as Enter, to background task ${firstString(input.task_id) ?? "(unnamed)"}`
|
|
106
|
-
};
|
|
107
|
-
var describeTaskCall = (input) => firstString(input.description) ?? firstString(input.subagent_type) ?? "(unnamed)";
|
|
108
|
-
var describeTodoProgress = (todos) => {
|
|
109
|
-
if (!Array.isArray(todos)) return "updated the plan";
|
|
110
|
-
const items = todos.filter((t) => !!t && typeof t === "object");
|
|
111
|
-
const total = items.length;
|
|
112
|
-
if (total === 0) return "updated the plan";
|
|
113
|
-
const done = items.filter((t) => t.status === "completed").length;
|
|
114
|
-
const current = items.find((t) => t.status === "in_progress");
|
|
115
|
-
const label = current ? [current.activeForm, current.content].find((v) => typeof v === "string" && v.trim().length > 0) : void 0;
|
|
116
|
-
if (done >= total) return `finished all ${total} tasks`;
|
|
117
|
-
if (label) return `${label.trim()} (${done}/${total} done)`;
|
|
118
|
-
return `${done}/${total} tasks done`;
|
|
119
|
-
};
|
|
120
|
-
var editTarget = (input) => {
|
|
121
|
-
if (typeof input.file_path === "string") return input.file_path;
|
|
122
|
-
if (!Array.isArray(input.file_paths) || !input.file_paths.every((path) => typeof path === "string")) return void 0;
|
|
123
|
-
return input.file_paths.join(", ");
|
|
124
|
-
};
|
|
125
|
-
var eventPrefixes = {
|
|
126
|
-
Bash: (input) => `ran: ${String(input.command ?? "")}`,
|
|
127
|
-
PowerShell: (input) => `ran: ${String(input.command ?? "")}`,
|
|
128
|
-
Monitor: (input) => `ran: ${String(input.command ?? "")}`,
|
|
129
|
-
Write: (input) => `wrote: ${input.file_path ?? "unknown"}`,
|
|
130
|
-
Edit: (input) => `edited: ${editTarget(input) ?? "unknown"}`,
|
|
131
|
-
MultiEdit: (input) => `edited: ${editTarget(input) ?? "unknown"}`,
|
|
132
|
-
Read: (input) => `read: ${input.file_path ?? "unknown"}`,
|
|
133
|
-
TodoWrite: (input) => describeTodoProgress(input.todos),
|
|
134
|
-
Task: (input) => `ran subagent: ${describeTaskCall(input)}`,
|
|
135
|
-
WebSearch: (input) => `searched: ${firstString(input.query) ?? "the web"}`
|
|
136
|
-
};
|
|
137
|
-
var NETWORK_TARGET_KEYS = ["url", "urls", "href", "host", "hosts", "hostname", "domain", "domains"];
|
|
138
|
-
var ABSOLUTE_HTTP_URL = /^https?:\/\//i;
|
|
139
|
-
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;
|
|
140
|
-
var hostOfUrl = (value) => {
|
|
141
|
-
try {
|
|
142
|
-
return new URL(value).host || void 0;
|
|
143
|
-
} catch {
|
|
144
|
-
return void 0;
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
var hostOf = (value, bareHostnames) => {
|
|
148
|
-
if (typeof value !== "string") return void 0;
|
|
149
|
-
const trimmed = value.trim();
|
|
150
|
-
if (ABSOLUTE_HTTP_URL.test(trimmed)) return hostOfUrl(trimmed);
|
|
151
|
-
return bareHostnames && HOSTNAME.test(trimmed) ? trimmed : void 0;
|
|
152
|
-
};
|
|
153
|
-
var firstHost = (value, bareHostnames) => Array.isArray(value) ? value.map((entry) => hostOf(entry, bareHostnames)).find((host) => host !== void 0) : hostOf(value, bareHostnames);
|
|
154
|
-
var deriveNetworkTarget = (toolInput) => {
|
|
155
|
-
for (const key of NETWORK_TARGET_KEYS) {
|
|
156
|
-
const host = firstHost(toolInput[key], true);
|
|
157
|
-
if (host) return host;
|
|
158
|
-
}
|
|
159
|
-
return Object.values(toolInput).map((value) => firstHost(value, false)).find((host) => host !== void 0);
|
|
160
|
-
};
|
|
161
|
-
var describeUnbuiltCall = (toolName, toolInput, format) => {
|
|
162
|
-
const mcp = parseMcpToolName(toolName);
|
|
163
|
-
const host = deriveNetworkTarget(toolInput);
|
|
164
|
-
if (mcp) {
|
|
165
|
-
if (format === "event") return `called ${mcp.tool} on ${mcp.server}`;
|
|
166
|
-
return host ? `call ${mcp.tool} on ${mcp.server} to reach ${host}` : `call ${mcp.tool} on ${mcp.server}`;
|
|
167
|
-
}
|
|
168
|
-
if (host) return format === "event" ? `accessed ${host}` : `network access to ${host}`;
|
|
169
|
-
return void 0;
|
|
170
|
-
};
|
|
171
|
-
var EVENT_ACTION_MAX = 120;
|
|
172
|
-
var HOOK_FALLBACK_MAX = 200;
|
|
173
|
-
var UNNAMED_ACTION = "this request";
|
|
174
|
-
var describeToolCall = (toolName, toolInput, format = "hook") => {
|
|
175
|
-
if (!toolName) return "";
|
|
176
|
-
const prefixes = format === "hook" ? hookPrefixes : eventPrefixes;
|
|
177
|
-
const builder = prefixes[toolName];
|
|
178
|
-
const unbuilt = builder ? void 0 : describeUnbuiltCall(toolName, toolInput ?? {}, format);
|
|
179
|
-
const detail = JSON.stringify(toolInput ?? {});
|
|
180
|
-
const raw = builder ? builder(toolInput) : unbuilt ?? (format === "hook" ? detail === "{}" || detail === void 0 ? toolName : `${toolName}: ${detail}` : `${toolName}: done`);
|
|
181
|
-
const redacted = redactSecrets(raw);
|
|
182
|
-
if (format === "event") return redacted.slice(0, EVENT_ACTION_MAX);
|
|
183
|
-
return builder || unbuilt ? redacted : redacted.slice(0, HOOK_FALLBACK_MAX);
|
|
184
|
-
};
|
|
185
|
-
var TOOL_TARGET_MAX_LENGTH = 80;
|
|
186
|
-
var deriveCommandHead = (command) => {
|
|
187
|
-
if (typeof command !== "string") return void 0;
|
|
188
|
-
const head = command.trim().split(/\s+/).slice(0, 2).join(" ");
|
|
189
|
-
return head ? redactSecrets(head).slice(0, TOOL_TARGET_MAX_LENGTH) : void 0;
|
|
190
|
-
};
|
|
191
|
-
var deriveToolTarget = (toolName, toolInput) => {
|
|
192
|
-
if (toolName === "Bash" || toolName === "PowerShell" || toolName === "Monitor") {
|
|
193
|
-
return deriveCommandHead(toolInput.command);
|
|
194
|
-
}
|
|
195
|
-
if (FILE_TARGET_TOOLS.has(toolName)) {
|
|
196
|
-
const filePath = toolInput.file_path;
|
|
197
|
-
if (typeof filePath !== "string") return void 0;
|
|
198
|
-
const separator = Math.max(filePath.lastIndexOf("/"), filePath.lastIndexOf("\\"));
|
|
199
|
-
const base = filePath.slice(separator + 1);
|
|
200
|
-
const dot = base.lastIndexOf(".");
|
|
201
|
-
if (dot <= 0) return void 0;
|
|
202
|
-
return base.slice(dot).slice(0, TOOL_TARGET_MAX_LENGTH);
|
|
203
|
-
}
|
|
204
|
-
const mcp = parseMcpToolName(toolName);
|
|
205
|
-
if (mcp) return mcp.server.slice(0, TOOL_TARGET_MAX_LENGTH);
|
|
206
|
-
return deriveNetworkTarget(toolInput)?.slice(0, TOOL_TARGET_MAX_LENGTH);
|
|
207
|
-
};
|
|
208
|
-
var SCRIPT_RUNNERS = /* @__PURE__ */ new Set(["npm", "pnpm", "yarn", "bun", "npx", "deno", "rake", "make", "just", "task", "turbo"]);
|
|
209
|
-
var RUN_SUBCOMMANDS = /* @__PURE__ */ new Set(["run", "run-script", "exec", "task"]);
|
|
210
|
-
var deriveReceiptCommandHead = (command) => {
|
|
211
|
-
if (typeof command !== "string") return void 0;
|
|
212
|
-
const tokens = command.trim().split(/\s+/);
|
|
213
|
-
const [first, second] = tokens;
|
|
214
|
-
const keep = first && second && SCRIPT_RUNNERS.has(first.toLowerCase()) && RUN_SUBCOMMANDS.has(second.toLowerCase()) ? 3 : 2;
|
|
215
|
-
const head = tokens.slice(0, keep).join(" ");
|
|
216
|
-
return head ? redactSecrets(head).slice(0, TOOL_TARGET_MAX_LENGTH) : void 0;
|
|
217
|
-
};
|
|
218
|
-
var RECEIPT_TARGET_MAX_LENGTH = 256;
|
|
219
|
-
var parseApplyPatchOps = (command) => {
|
|
220
|
-
if (typeof command !== "string") return [];
|
|
221
|
-
const ops = [];
|
|
222
|
-
for (const line of command.split("\n")) {
|
|
223
|
-
const file = line.match(/^\s*\*\*\*\s+(Add|Update|Delete) File:\s+(.+?)\s*$/);
|
|
224
|
-
if (file) {
|
|
225
|
-
ops.push({ op: file[1].toLowerCase(), path: file[2] });
|
|
226
|
-
continue;
|
|
227
|
-
}
|
|
228
|
-
const move = line.match(/^\s*\*\*\*\s+Move to:\s+(.+?)\s*$/);
|
|
229
|
-
if (move) ops.push({ op: "move", path: move[1] });
|
|
230
|
-
}
|
|
231
|
-
return ops;
|
|
232
|
-
};
|
|
233
|
-
var parseApplyPatchFiles = (command) => [...new Set(parseApplyPatchOps(command).map((entry) => entry.path))];
|
|
234
|
-
var patchDeletesFiles = (toolName, toolInput) => toolName === "apply_patch" && parseApplyPatchOps(toolInput.command).some((entry) => entry.op === "delete");
|
|
235
|
-
var OPENCODE_TOOL_NAMES = {
|
|
236
|
-
bash: "Bash",
|
|
237
|
-
shell: "Bash",
|
|
238
|
-
// A shell command reaching outside the worktree asks a second time under its
|
|
239
|
-
// own key. It is still the same command, and still Bash.
|
|
240
|
-
external_directory: "Bash",
|
|
241
|
-
edit: "Edit",
|
|
242
|
-
patch: "Edit",
|
|
243
|
-
apply_patch: "Edit",
|
|
244
|
-
write: "Write",
|
|
245
|
-
read: "Read",
|
|
246
|
-
glob: "Glob",
|
|
247
|
-
grep: "Grep",
|
|
248
|
-
webfetch: "WebFetch",
|
|
249
|
-
websearch: "WebSearch",
|
|
250
|
-
task: "Task",
|
|
251
|
-
subagent: "Task"
|
|
252
|
-
};
|
|
253
|
-
var PATCH_ARG_KEYS = ["command", "patch", "input"];
|
|
254
|
-
var patchedFilesIn = (input) => [...new Set(PATCH_ARG_KEYS.flatMap((key) => parseApplyPatchFiles(input[key])))];
|
|
255
|
-
var lookupsForInput = (profile, toolName, input, absolute) => {
|
|
256
|
-
const gateInput = profile.source === "grok" && toolName === "apply_patch" ? { patch: input.patch, diff: input.patch } : input;
|
|
257
|
-
const lookup = toToolLookup(profile, toolName, gateInput, absolute);
|
|
258
|
-
if (!lookup.unreadable) return [lookup];
|
|
259
|
-
const files = patchedFilesIn(gateInput);
|
|
260
|
-
if (files.length === 0) return [lookup];
|
|
261
|
-
return files.slice(0, GATE_MAX_TOOL_INPUTS + 1).map((file) => toToolLookup(profile, toolName, { ...gateInput, file_path: absolute(file) }, absolute));
|
|
262
|
-
};
|
|
263
|
-
var compatibleToolLookup = (profile, toolName, input, cwd) => {
|
|
264
|
-
const absolute = (path) => cwd && !isAbsolute(path) ? resolve(cwd, path) : path;
|
|
265
|
-
const lookups = lookupsForInput(profile, toolName, input, absolute);
|
|
266
|
-
const first = lookups[0];
|
|
267
|
-
if (!first) return { tool: canonicalToolName(profile, toolName), input, unreadable: true };
|
|
268
|
-
if (lookups.length === 1) return first;
|
|
269
|
-
const { file_path, ...content } = first.input;
|
|
270
|
-
return {
|
|
271
|
-
tool: first.tool,
|
|
272
|
-
input: { ...content, file_paths: lookups.map((lookup) => lookup.input.file_path) },
|
|
273
|
-
unreadable: lookups.length > GATE_MAX_TOOL_INPUTS || lookups.some((lookup) => lookup.unreadable)
|
|
274
|
-
};
|
|
275
|
-
};
|
|
276
|
-
var compatibleGateInputs = (profile, toolName, toolInputs, cwd) => {
|
|
277
|
-
const absolute = (path) => cwd && !isAbsolute(path) ? resolve(cwd, path) : path;
|
|
278
|
-
const lookups = toolInputs.flatMap((input) => lookupsForInput(profile, toolName, input, absolute));
|
|
279
|
-
if (lookups.length > GATE_MAX_TOOL_INPUTS) return null;
|
|
280
|
-
if (lookups.some((lookup) => lookup.unreadable)) return null;
|
|
281
|
-
return {
|
|
282
|
-
toolName: lookups[0]?.tool ?? canonicalToolName(profile, toolName),
|
|
283
|
-
toolInputs: lookups.map((lookup) => lookup.input)
|
|
284
|
-
};
|
|
285
|
-
};
|
|
286
|
-
var canonicalGateInputs = (source, toolName, toolInputs, cwd) => {
|
|
287
|
-
if (source === "codex" && toolName === "apply_patch" || source === "vscode" && ["apply_patch", "applyPatch", "copilot_applyPatch"].includes(toolName)) {
|
|
288
|
-
const paths = [...new Set(toolInputs.flatMap((input) => parseApplyPatchFiles(input.command ?? input.input ?? input.patch)))];
|
|
289
|
-
if (paths.length > GATE_MAX_TOOL_INPUTS) return null;
|
|
290
|
-
return {
|
|
291
|
-
toolName: "Edit",
|
|
292
|
-
toolInputs: paths.length === 0 ? toolInputs.map((input) => ({ file_path: input.command })) : paths.map((path) => ({ file_path: cwd && !isAbsolute(path) ? resolve(cwd, path) : path }))
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
if (source === "opencode") {
|
|
296
|
-
const canonical2 = OPENCODE_TOOL_NAMES[toolName] ?? toolName;
|
|
297
|
-
return {
|
|
298
|
-
toolName: canonical2,
|
|
299
|
-
toolInputs: toolInputs.map((input) => {
|
|
300
|
-
const path = input.file_path;
|
|
301
|
-
return typeof path === "string" && path.length > 0 && cwd && !isAbsolute(path) ? { ...input, file_path: resolve(cwd, path) } : input;
|
|
302
|
-
})
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
if (source === "vscode" || source === "cursor") {
|
|
306
|
-
if (source === "vscode" && toolName.startsWith("mcp_pushary_")) return { toolName: `mcp__pushary__${toolName.slice("mcp_pushary_".length)}`, toolInputs };
|
|
307
|
-
const alias = toolName.replace(/^copilot_/, "").toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
308
|
-
const shells = [
|
|
309
|
-
"runterminalcommand",
|
|
310
|
-
"runinterminal",
|
|
311
|
-
"runcommand",
|
|
312
|
-
"terminalcommand",
|
|
313
|
-
"executecommand",
|
|
314
|
-
"runinterminalcommand",
|
|
315
|
-
"bash",
|
|
316
|
-
"shell",
|
|
317
|
-
"terminal",
|
|
318
|
-
"sendtoterminal",
|
|
319
|
-
"powershell",
|
|
320
|
-
"localshell"
|
|
321
|
-
];
|
|
322
|
-
const canonical2 = shells.includes(alias) ? "Bash" : ["createfile", "write", "createdirectory", "createnewjupyternotebook"].includes(alias) ? "Write" : ["replacestringinfile", "multireplacestringinfile", "replacestring", "multireplacestring", "inserteditintofile", "insertedit", "edit", "editfile", "editfiles", "editnotebookfile", "editnotebook"].includes(alias) ? "Edit" : [
|
|
323
|
-
"readfile",
|
|
324
|
-
"viewimage",
|
|
325
|
-
"listdir",
|
|
326
|
-
"listdirectory",
|
|
327
|
-
"filesearch",
|
|
328
|
-
"findfiles",
|
|
329
|
-
"grepsearch",
|
|
330
|
-
"findtextinfiles",
|
|
331
|
-
"semanticsearch",
|
|
332
|
-
"searchcodebase",
|
|
333
|
-
"searchworkspacesymbols",
|
|
334
|
-
"geterrors",
|
|
335
|
-
"getchangedfiles",
|
|
336
|
-
"readprojectstructure",
|
|
337
|
-
"getnotebooksummary",
|
|
338
|
-
"readnotebookcelloutput",
|
|
339
|
-
"testsearch",
|
|
340
|
-
"findtestfiles",
|
|
341
|
-
"testfailure",
|
|
342
|
-
"getvscodeapi",
|
|
343
|
-
"getterminaloutput",
|
|
344
|
-
"gettaskoutput",
|
|
345
|
-
"terminalselection",
|
|
346
|
-
"terminallastcommand"
|
|
347
|
-
].includes(alias) ? "Read" : toolName;
|
|
348
|
-
const inputs = toolInputs.flatMap((input) => ["multireplacestringinfile", "multireplacestring"].includes(alias) && Array.isArray(input.replacements) ? input.replacements.filter((item) => !!item && typeof item === "object" && !Array.isArray(item)) : alias === "editfiles" && Array.isArray(input.files) ? input.files.map((file) => typeof file === "string" ? { file_path: file } : file).filter((file) => !!file && typeof file === "object" && !Array.isArray(file)) : [input]);
|
|
349
|
-
if (inputs.length > GATE_MAX_TOOL_INPUTS) return null;
|
|
350
|
-
return { toolName: canonical2, toolInputs: inputs.map((input) => {
|
|
351
|
-
if (canonical2 === "Bash") return { ...input, command: [input.command, input.commandLine, input.command_line, input.cmd, input.script, input.input, input.text].find((value) => typeof value === "string") };
|
|
352
|
-
const path = input.file_path ?? input.filePath ?? input.path;
|
|
353
|
-
return typeof path === "string" ? { ...input, file_path: cwd && !isAbsolute(path) ? resolve(cwd, path) : path } : input;
|
|
354
|
-
}) };
|
|
355
|
-
}
|
|
356
|
-
const profile = hookCompatibleProfileBySource(source);
|
|
357
|
-
if (profile) return compatibleGateInputs(profile, toolName, toolInputs, cwd);
|
|
358
|
-
if (source !== "gemini") return { toolName, toolInputs };
|
|
359
|
-
if (toolName === "run_shell_command") {
|
|
360
|
-
return { toolName: "Bash", toolInputs: toolInputs.map((input) => ({ command: input.command })) };
|
|
361
|
-
}
|
|
362
|
-
const canonical = { write_file: "Write", replace: "Edit", read_file: "Read" }[toolName];
|
|
363
|
-
if (!canonical) return { toolName, toolInputs };
|
|
364
|
-
return {
|
|
365
|
-
toolName: canonical,
|
|
366
|
-
toolInputs: toolInputs.map((input) => {
|
|
367
|
-
const path = [input.file_path, input.absolute_path, input.path].find((value) => typeof value === "string" && value.length > 0);
|
|
368
|
-
return path ? { file_path: cwd && !isAbsolute(path) ? resolve(cwd, path) : path } : {};
|
|
369
|
-
})
|
|
370
|
-
};
|
|
371
|
-
};
|
|
372
|
-
var EXIT_CODE_FAILURE = /^Error: Exit code \d+/;
|
|
373
|
-
var isToolResultError = (toolResult) => {
|
|
374
|
-
try {
|
|
375
|
-
if (typeof toolResult === "string") return EXIT_CODE_FAILURE.test(toolResult);
|
|
376
|
-
if (!toolResult || typeof toolResult !== "object") return false;
|
|
377
|
-
return "error" in toolResult || "is_error" in toolResult;
|
|
378
|
-
} catch {
|
|
379
|
-
return false;
|
|
380
|
-
}
|
|
381
|
-
};
|
|
382
|
-
var toolResultErrorText = (toolResult) => {
|
|
383
|
-
try {
|
|
384
|
-
const raw = typeof toolResult === "string" ? toolResult : toolResult && typeof toolResult === "object" ? String(
|
|
385
|
-
toolResult.error ?? toolResult.stderr ?? ""
|
|
386
|
-
) : "";
|
|
387
|
-
return redactSecrets(raw);
|
|
388
|
-
} catch {
|
|
389
|
-
return "";
|
|
390
|
-
}
|
|
391
|
-
};
|
|
392
|
-
var relativizeReceiptPath = (filePath, cwd) => {
|
|
393
|
-
if (!cwd || !isAbsolute(filePath)) return filePath;
|
|
394
|
-
return relative(cwd, filePath);
|
|
395
|
-
};
|
|
396
|
-
var deriveReceiptMeta = (toolName, toolInput, toolResult, cwd) => {
|
|
397
|
-
try {
|
|
398
|
-
const ok = !isToolResultError(toolResult);
|
|
399
|
-
if (toolName === "apply_patch") {
|
|
400
|
-
const files = parseApplyPatchFiles(toolInput.command);
|
|
401
|
-
const target = files.length === 1 ? files[0] : toolInput.command;
|
|
402
|
-
if (typeof target !== "string" || !target) return void 0;
|
|
403
|
-
return { kind: "edit", target: redactSecrets(target).slice(0, RECEIPT_TARGET_MAX_LENGTH), ok };
|
|
404
|
-
}
|
|
405
|
-
const canonicalTool = {
|
|
406
|
-
run_shell_command: "Bash",
|
|
407
|
-
write_file: "Write",
|
|
408
|
-
replace: "Edit"
|
|
409
|
-
}[toolName] ?? toolName;
|
|
410
|
-
const canonicalInput = canonicalTool === toolName ? toolInput : {
|
|
411
|
-
...toolInput,
|
|
412
|
-
file_path: toolInput.file_path ?? toolInput.absolute_path ?? toolInput.path
|
|
413
|
-
};
|
|
414
|
-
if (canonicalTool === "Edit" && Array.isArray(canonicalInput.file_paths)) {
|
|
415
|
-
const patch = firstString(canonicalInput.diff, canonicalInput.command, canonicalInput.patch, canonicalInput.input);
|
|
416
|
-
if (patch) return { kind: "edit", target: redactSecrets(patch).slice(0, RECEIPT_TARGET_MAX_LENGTH), ok };
|
|
417
|
-
}
|
|
418
|
-
if (FILE_TARGET_TOOLS.has(canonicalTool)) {
|
|
419
|
-
const filePath = canonicalInput.file_path;
|
|
420
|
-
if (typeof filePath !== "string" || !filePath) return void 0;
|
|
421
|
-
return {
|
|
422
|
-
kind: canonicalTool === "Write" ? "write" : "edit",
|
|
423
|
-
// A path is an unlikely place for a credential but not an impossible one
|
|
424
|
-
// (a token in a temp directory name), and this field is persisted.
|
|
425
|
-
target: redactSecrets(relativizeReceiptPath(filePath, cwd)).slice(0, RECEIPT_TARGET_MAX_LENGTH),
|
|
426
|
-
ok
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
|
-
if (canonicalTool === "Bash" || canonicalTool === "PowerShell" || canonicalTool === "Monitor") {
|
|
430
|
-
const head = deriveReceiptCommandHead(canonicalInput.command);
|
|
431
|
-
if (!head) return void 0;
|
|
432
|
-
return {
|
|
433
|
-
kind: head === "git commit" ? "commit" : "bash",
|
|
434
|
-
target: head,
|
|
435
|
-
ok
|
|
436
|
-
};
|
|
437
|
-
}
|
|
438
|
-
return void 0;
|
|
439
|
-
} catch {
|
|
440
|
-
return void 0;
|
|
441
|
-
}
|
|
442
|
-
};
|
|
443
|
-
var scopePathFor = (toolName, toolInput, cwd) => {
|
|
444
|
-
const meta = deriveReceiptMeta(toolName, toolInput, void 0, cwd);
|
|
445
|
-
if (!meta) return void 0;
|
|
446
|
-
return meta.kind === "edit" || meta.kind === "write" ? meta.target : void 0;
|
|
447
|
-
};
|
|
448
|
-
var firstString = (...values) => values.find((v) => typeof v === "string" && v.length > 0);
|
|
449
|
-
var ACTION_BODY_TRUNCATION_MARKER = "\n\u2026 [truncated]";
|
|
450
|
-
var capActionBody = (text) => truncateLine(text, ACTION_BODY_MAX, ACTION_BODY_TRUNCATION_MARKER);
|
|
451
|
-
var rawActionBody = (toolName, toolInput) => {
|
|
452
|
-
if (toolName === "Edit" || toolName === "replace") {
|
|
453
|
-
const before = firstString(toolInput.old_string);
|
|
454
|
-
const after = firstString(toolInput.new_string);
|
|
455
|
-
if (before === void 0 && after === void 0) return firstString(toolInput.diff);
|
|
456
|
-
return `- ${before ?? ""}
|
|
457
|
-
+ ${after ?? ""}`;
|
|
458
|
-
}
|
|
459
|
-
if (toolName === "Write" || toolName === "write_file") {
|
|
460
|
-
return firstString(toolInput.content) ?? firstString(toolInput.diff);
|
|
461
|
-
}
|
|
462
|
-
if (toolName === "ExitPlanMode") return firstString(toolInput.plan);
|
|
463
|
-
if (toolName === "Bash" || toolName === "PowerShell" || toolName === "Monitor" || toolName === "run_shell_command" || toolName === "shell" || toolName === "apply_patch") {
|
|
464
|
-
return firstString(toolInput.command);
|
|
465
|
-
}
|
|
466
|
-
if (toolName === "write_stdin" || toolName === "request_permissions") return JSON.stringify(toolInput, null, 2);
|
|
467
|
-
return firstString(toolInput.url, toolInput.href);
|
|
468
|
-
};
|
|
469
|
-
var deriveActionBody = (toolName, toolInput) => {
|
|
470
|
-
try {
|
|
471
|
-
const raw = rawActionBody(toolName, toolInput);
|
|
472
|
-
if (!raw) return void 0;
|
|
473
|
-
return capActionBody(redactSecretsDeep(raw));
|
|
474
|
-
} catch {
|
|
475
|
-
return void 0;
|
|
476
|
-
}
|
|
477
|
-
};
|
|
478
|
-
var deriveAction = (toolName, toolInput) => truncateLine(describeToolCall(toolName, toolInput, "hook"), DECISION_LINE_MAX);
|
|
479
|
-
var BLOCKER_BY_MODE = {
|
|
480
|
-
push_only: "Approval required before this runs",
|
|
481
|
-
push_first: "Paused for your approval before continuing",
|
|
482
|
-
escalate: "Escalated to you after the approval timeout"
|
|
483
|
-
};
|
|
484
|
-
var deriveBlocker = (mode, reason) => {
|
|
485
|
-
const text = reason?.replace(/\s+/g, " ").trim() || BLOCKER_BY_MODE[mode] || "Waiting for your approval";
|
|
486
|
-
return truncateLine(text, DECISION_LINE_MAX);
|
|
487
|
-
};
|
|
488
|
-
|
|
489
|
-
// ../hook-mapping/src/map.ts
|
|
490
|
-
import { basename } from "path";
|
|
491
|
-
var AGENT_IDENTITIES = {
|
|
492
|
-
claude: { type: "claude_code", label: AGENT_LABELS_BY_TYPE.claude_code },
|
|
493
|
-
codex: { type: "codex", label: AGENT_LABELS_BY_TYPE.codex },
|
|
494
|
-
gemini: { type: "gemini_cli", label: AGENT_LABELS_BY_TYPE.gemini_cli },
|
|
495
|
-
cursor: { type: "cursor", label: AGENT_LABELS_BY_TYPE.cursor },
|
|
496
|
-
vscode: { type: "vscode", label: AGENT_LABELS_BY_TYPE.vscode },
|
|
497
|
-
opencode: { type: "opencode", label: AGENT_LABELS_BY_TYPE.opencode },
|
|
498
|
-
qwen: { type: "qwen_code", label: AGENT_LABELS_BY_TYPE.qwen_code },
|
|
499
|
-
codebuddy: { type: "codebuddy", label: AGENT_LABELS_BY_TYPE.codebuddy },
|
|
500
|
-
qoder: { type: "qoder", label: AGENT_LABELS_BY_TYPE.qoder },
|
|
501
|
-
droid: { type: "droid", label: AGENT_LABELS_BY_TYPE.droid },
|
|
502
|
-
devin: { type: "devin", label: AGENT_LABELS_BY_TYPE.devin },
|
|
503
|
-
antigravity: { type: "antigravity_cli", label: AGENT_LABELS_BY_TYPE.antigravity_cli },
|
|
504
|
-
grok: { type: "grok", label: AGENTS.grok.label }
|
|
505
|
-
};
|
|
506
|
-
var TEAMMATE_IDLE_ACTION = "A teammate went idle";
|
|
507
|
-
var CLAUDE_MEANINGS = {
|
|
508
|
-
PostToolUse: { kind: "tool", event: "tool_complete" },
|
|
509
|
-
UserPromptSubmit: { kind: "prompt", event: "user_prompt" },
|
|
510
|
-
Stop: { kind: "stop", event: "session_end" },
|
|
511
|
-
SubagentStop: { kind: "subagent_stop", event: "session_end" },
|
|
512
|
-
PreCompact: { kind: "compaction", event: "compaction" },
|
|
513
|
-
PostCompact: { kind: "compaction", event: "compaction" },
|
|
514
|
-
SessionStart: { kind: "session_start", event: "session_start" },
|
|
515
|
-
SessionEnd: { kind: "session_closed", event: "session_closed" },
|
|
516
|
-
SubagentStart: { kind: "session_start", event: "session_start", action: "Subagent started" },
|
|
517
|
-
Notification: { kind: "notification", event: "notification" },
|
|
518
|
-
TeammateIdle: { kind: "teammate_idle", event: "teammate_idle", action: TEAMMATE_IDLE_ACTION },
|
|
519
|
-
StopFailure: { kind: "stop_failure", event: "turn_error" },
|
|
520
|
-
PermissionDenied: { kind: "permission_denied", event: "permission_denied" }
|
|
521
|
-
};
|
|
522
|
-
var compatibleMeanings = (agentType) => {
|
|
523
|
-
const events = HOOK_COMPATIBLE_PROFILES.find((profile) => profile.agentType === agentType)?.events ?? [];
|
|
524
|
-
return Object.fromEntries(events.flatMap((event) => {
|
|
525
|
-
const meaning = CLAUDE_MEANINGS[event];
|
|
526
|
-
return meaning ? [[event, meaning]] : [];
|
|
527
|
-
}));
|
|
528
|
-
};
|
|
529
|
-
var MEANING_BY_HOOK = {
|
|
530
|
-
claude: CLAUDE_MEANINGS,
|
|
531
|
-
qwen: compatibleMeanings("qwen_code"),
|
|
532
|
-
codebuddy: compatibleMeanings("codebuddy"),
|
|
533
|
-
qoder: compatibleMeanings("qoder"),
|
|
534
|
-
droid: compatibleMeanings("droid"),
|
|
535
|
-
devin: compatibleMeanings("devin"),
|
|
536
|
-
antigravity: compatibleMeanings("antigravity_cli"),
|
|
537
|
-
grok: { ...compatibleMeanings("grok"), PostToolUseFailure: { kind: "tool", event: "tool_complete" }, StopCancelled: { kind: "stop_failure", event: "turn_error" } },
|
|
538
|
-
codex: {
|
|
539
|
-
PostToolUse: { kind: "tool", event: "tool_complete" },
|
|
540
|
-
UserPromptSubmit: { kind: "prompt", event: "user_prompt" },
|
|
541
|
-
Stop: { kind: "stop", event: "session_end" },
|
|
542
|
-
SessionStart: { kind: "session_start", event: "session_begin", action: "Session started" },
|
|
543
|
-
SessionEnd: { kind: "session_closed", event: "session_closed" },
|
|
544
|
-
// Codex names all four in its own HookEventName enum, and the CLI registers
|
|
545
|
-
// them. A row missing here is the same defect as the dropped Codex
|
|
546
|
-
// SessionEnd: the CLI reports the event, the Mac app forwards the identical
|
|
547
|
-
// envelope, and only the app's copy vanishes.
|
|
548
|
-
SubagentStart: { kind: "session_start", event: "session_begin", action: "Subagent started" },
|
|
549
|
-
SubagentStop: { kind: "subagent_stop", event: "session_end" },
|
|
550
|
-
PreCompact: { kind: "compaction", event: "compaction" },
|
|
551
|
-
PostCompact: { kind: "compaction", event: "compaction" }
|
|
552
|
-
},
|
|
553
|
-
gemini: {
|
|
554
|
-
AfterTool: { kind: "tool", event: "tool_complete" },
|
|
555
|
-
BeforeAgent: { kind: "prompt", event: "user_prompt" },
|
|
556
|
-
AfterAgent: { kind: "stop", event: "session_end" },
|
|
557
|
-
SessionStart: { kind: "session_start", event: "session_begin", action: "Session started" },
|
|
558
|
-
SessionEnd: { kind: "session_closed", event: "session_closed" }
|
|
559
|
-
},
|
|
560
|
-
cursor: {
|
|
561
|
-
afterShellExecution: { kind: "tool", event: "tool_complete" },
|
|
562
|
-
afterFileEdit: { kind: "tool", event: "tool_complete" },
|
|
563
|
-
postToolUse: { kind: "tool", event: "tool_complete" },
|
|
564
|
-
stop: { kind: "stop", event: "session_end" },
|
|
565
|
-
sessionStart: { kind: "session_start", event: "session_begin" },
|
|
566
|
-
sessionEnd: { kind: "session_closed", event: "session_closed" },
|
|
567
|
-
beforeSubmitPrompt: { kind: "prompt", event: "user_prompt" },
|
|
568
|
-
preCompact: { kind: "compaction", event: "compaction" },
|
|
569
|
-
subagentStart: { kind: "session_start", event: "session_begin", action: "Subagent started" },
|
|
570
|
-
subagentStop: { kind: "subagent_stop", event: "notification" }
|
|
571
|
-
},
|
|
572
|
-
vscode: {
|
|
573
|
-
PostToolUse: { kind: "tool", event: "tool_complete" },
|
|
574
|
-
Stop: { kind: "stop", event: "session_end" },
|
|
575
|
-
SessionStart: { kind: "session_start", event: "session_begin" },
|
|
576
|
-
UserPromptSubmit: { kind: "prompt", event: "user_prompt" },
|
|
577
|
-
PreCompact: { kind: "compaction", event: "compaction" },
|
|
578
|
-
SubagentStart: { kind: "session_start", event: "session_begin", action: "Subagent started" },
|
|
579
|
-
SubagentStop: { kind: "subagent_stop", event: "session_end" }
|
|
580
|
-
},
|
|
581
|
-
// OpenCode's own names, because the plugin sends the hook it was called from
|
|
582
|
-
// rather than translating. `session.idle` is the turn boundary — its Stop, not
|
|
583
|
-
// its SessionEnd — and there is no session-start entry on purpose: OpenCode
|
|
584
|
-
// publishes `session.created` for every subagent fork too.
|
|
585
|
-
opencode: {
|
|
586
|
-
"tool.execute.after": { kind: "tool", event: "tool_complete" },
|
|
587
|
-
"chat.message": { kind: "prompt", event: "user_prompt" },
|
|
588
|
-
"session.idle": { kind: "stop", event: "session_end" }
|
|
589
|
-
}
|
|
590
|
-
};
|
|
591
|
-
var TASK_TITLE_MAX_LENGTH = 120;
|
|
592
|
-
var STOP_SUMMARY_MAX_LENGTH = 200;
|
|
593
|
-
var SESSION_END_ACTIONS = {
|
|
594
|
-
clear: "Session cleared",
|
|
595
|
-
logout: "Logged out",
|
|
596
|
-
resume: "Session suspended",
|
|
597
|
-
prompt_input_exit: "Session ended",
|
|
598
|
-
bypass_permissions_disabled: "Session ended",
|
|
599
|
-
other: "Session ended"
|
|
600
|
-
};
|
|
601
|
-
var countArray = (value) => Array.isArray(value) ? value.length : 0;
|
|
602
|
-
var summarizeFinalMessage = (message) => {
|
|
603
|
-
if (typeof message !== "string") return "Session ended";
|
|
604
|
-
const collapsed = conversationText(message).replace(/\s+/g, " ").trim();
|
|
605
|
-
if (!collapsed) return "Session ended";
|
|
606
|
-
return collapsed.slice(0, STOP_SUMMARY_MAX_LENGTH);
|
|
607
|
-
};
|
|
608
|
-
var summarizeStop = (input) => {
|
|
609
|
-
const running = countArray(input.background_tasks);
|
|
610
|
-
if (running > 0) return `Paused with ${running} background task${running === 1 ? "" : "s"} still running`;
|
|
611
|
-
const crons = countArray(input.session_crons);
|
|
612
|
-
if (crons > 0) return `Idle until a scheduled task wakes it (${crons} pending)`;
|
|
613
|
-
return summarizeFinalMessage(input.last_assistant_message ?? input.prompt_response);
|
|
614
|
-
};
|
|
615
|
-
var subagentStopAction = (agentType) => {
|
|
616
|
-
const name = typeof agentType === "string" ? agentType.replace(/\s+/g, " ").trim() : "";
|
|
617
|
-
return name ? `${name} subagent finished` : "Subagent finished";
|
|
618
|
-
};
|
|
619
|
-
var subagentStopSummary = (input) => {
|
|
620
|
-
const message = input.last_assistant_message ?? input.prompt_response;
|
|
621
|
-
if (typeof message === "string" && message.trim()) return summarizeStop(input);
|
|
622
|
-
return subagentStopAction(input.agent_type);
|
|
623
|
-
};
|
|
624
|
-
var COMPACTION_TRIGGERS = {
|
|
625
|
-
manual: "on request",
|
|
626
|
-
auto: "automatically"
|
|
627
|
-
};
|
|
628
|
-
var compactionAction = (hookEvent, trigger) => {
|
|
629
|
-
const how = typeof trigger === "string" ? COMPACTION_TRIGGERS[trigger] : void 0;
|
|
630
|
-
const base = hookEvent === "PostCompact" ? "Compacted context" : "Compacting context";
|
|
631
|
-
return how ? `${base} ${how}` : base;
|
|
632
|
-
};
|
|
633
|
-
var sessionStartAction = (source) => source === "resume" ? "Session resumed" : "Session started";
|
|
634
|
-
var sessionEndAction = (reason) => typeof reason === "string" && SESSION_END_ACTIONS[reason] || "Session ended";
|
|
635
|
-
var taskTitleFrom = (prompt) => typeof prompt === "string" && !isClaudeWakePrompt(prompt) ? conversationText(prompt).replace(/\s+/g, " ").trim().slice(0, TASK_TITLE_MAX_LENGTH) || void 0 : void 0;
|
|
636
|
-
var asString = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
|
|
637
|
-
var NOTIFICATION_ACTION_MAX_LENGTH = 200;
|
|
638
|
-
var STOP_FAILURE_REASON_MAX_LENGTH = 300;
|
|
639
|
-
var notificationTypeOf = (payload) => asString(payload.notification_type) ?? asString(payload.type);
|
|
640
|
-
var notificationAction = (payload) => {
|
|
641
|
-
const text = asString(payload.message) ?? asString(payload.title);
|
|
642
|
-
const collapsed = redactSecrets(text ?? "").replace(/\s+/g, " ").trim();
|
|
643
|
-
return collapsed ? collapsed.slice(0, NOTIFICATION_ACTION_MAX_LENGTH) : "Notification";
|
|
644
|
-
};
|
|
645
|
-
var STOP_FAILURE_REASONS = {
|
|
646
|
-
rate_limit: "Rate limited by the API",
|
|
647
|
-
overloaded: "The API is overloaded right now",
|
|
648
|
-
authentication_failed: "Authentication failed",
|
|
649
|
-
billing_error: "A billing error stopped the turn"
|
|
650
|
-
};
|
|
651
|
-
var STOP_FAILURE_FALLBACK = "The turn ended on an API error (rate limit, billing, or auth).";
|
|
652
|
-
var describeStopFailure = (error) => {
|
|
653
|
-
const fromString = (value) => {
|
|
654
|
-
const trimmed = value.trim();
|
|
655
|
-
if (!trimmed) return void 0;
|
|
656
|
-
return STOP_FAILURE_REASONS[trimmed] ?? redactSecrets(trimmed).slice(0, STOP_FAILURE_REASON_MAX_LENGTH);
|
|
657
|
-
};
|
|
658
|
-
if (typeof error === "string") {
|
|
659
|
-
const described = fromString(error);
|
|
660
|
-
if (described) return described;
|
|
661
|
-
} else if (error && typeof error === "object") {
|
|
662
|
-
for (const key of ["type", "message", "error", "code"]) {
|
|
663
|
-
const value = error[key];
|
|
664
|
-
if (typeof value === "string") {
|
|
665
|
-
const described = fromString(value);
|
|
666
|
-
if (described) return described;
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
return STOP_FAILURE_FALLBACK;
|
|
671
|
-
};
|
|
672
|
-
var permissionDeniedAction = (toolName) => {
|
|
673
|
-
const tool = asString(toolName);
|
|
674
|
-
return tool ? `Auto-mode blocked ${tool}` : "Auto-mode blocked a tool call";
|
|
675
|
-
};
|
|
676
|
-
var sessionIdentityOf = (payload) => {
|
|
677
|
-
const sessionId = asString(payload.session_id ?? payload.sessionId ?? payload.conversation_id);
|
|
678
|
-
const agentId = asString(payload.agent_id);
|
|
679
|
-
if (!agentId) return { sessionId };
|
|
680
|
-
return { sessionId: agentId, parentSessionId: sessionId };
|
|
681
|
-
};
|
|
682
|
-
|
|
683
|
-
// ../hook-mapping/src/json-record.ts
|
|
684
|
-
var asRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
685
|
-
var parseRecord = (text) => {
|
|
686
|
-
try {
|
|
687
|
-
return asRecord(JSON.parse(text));
|
|
688
|
-
} catch {
|
|
689
|
-
return null;
|
|
690
|
-
}
|
|
691
|
-
};
|
|
692
|
-
|
|
693
|
-
// ../hook-mapping/src/codex-rollout.ts
|
|
694
|
-
var CODEX_TURN_CONTEXT_TYPE = "turn_context";
|
|
695
|
-
var CODEX_AUTO_REVIEWER = "auto_review";
|
|
696
|
-
var CODEX_GUARDIAN_THREAD_SOURCE = "guardian_review";
|
|
697
|
-
var CODEX_PLANNED_ACTION_MARKER = "Planned action JSON:\n";
|
|
698
|
-
var CODEX_APPROVAL_REQUEST_END = ">>> APPROVAL REQUEST END";
|
|
699
|
-
var CODEX_SHELL_TOOL = "exec_command";
|
|
700
|
-
var nonEmptyString = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
|
|
701
|
-
var isTimestamp = (value) => typeof value === "string" && Number.isFinite(Date.parse(value));
|
|
702
|
-
var readCodexTurnContext = (line) => {
|
|
703
|
-
const entry = parseRecord(line);
|
|
704
|
-
if (entry?.type !== CODEX_TURN_CONTEXT_TYPE) return null;
|
|
705
|
-
const payload = asRecord(entry.payload);
|
|
706
|
-
const turnId = nonEmptyString(payload?.turn_id);
|
|
707
|
-
if (!payload || !turnId) return null;
|
|
708
|
-
return {
|
|
709
|
-
turnId,
|
|
710
|
-
approvalsReviewer: payload.approvals_reviewer === CODEX_AUTO_REVIEWER ? "auto_review" : "user",
|
|
711
|
-
...isTimestamp(entry.timestamp) ? { startedAt: entry.timestamp } : {}
|
|
712
|
-
};
|
|
713
|
-
};
|
|
714
|
-
var isCodexGuardianRolloutHead = (line, sessionId) => {
|
|
715
|
-
if (!sessionId) return false;
|
|
716
|
-
const entry = parseRecord(line);
|
|
717
|
-
const payload = asRecord(entry?.payload);
|
|
718
|
-
return entry?.type === "session_meta" && payload?.parent_thread_id === sessionId && payload.thread_source === CODEX_GUARDIAN_THREAD_SOURCE;
|
|
719
|
-
};
|
|
720
|
-
var readCodexPlannedAction = (message) => {
|
|
721
|
-
const marker = message.lastIndexOf(CODEX_PLANNED_ACTION_MARKER);
|
|
722
|
-
if (marker < 0) return null;
|
|
723
|
-
const body = message.slice(marker + CODEX_PLANNED_ACTION_MARKER.length);
|
|
724
|
-
const end = body.lastIndexOf(CODEX_APPROVAL_REQUEST_END);
|
|
725
|
-
if (end < 0 || body.slice(end + CODEX_APPROVAL_REQUEST_END.length).trim().length > 0) return null;
|
|
726
|
-
return parseRecord(body.slice(0, end).trim());
|
|
727
|
-
};
|
|
728
|
-
var readCodexReviewVerdict = (message) => {
|
|
729
|
-
const verdict = parseRecord(message.trim());
|
|
730
|
-
if (verdict?.outcome !== "allow" && verdict?.outcome !== "deny") return null;
|
|
731
|
-
const rationale = typeof verdict.rationale === "string" ? verdict.rationale.trim() : "";
|
|
732
|
-
return { outcome: verdict.outcome, ...rationale ? { rationale } : {} };
|
|
733
|
-
};
|
|
734
|
-
var scanCodexGuardianReviews = (lines) => {
|
|
735
|
-
const reviews = [];
|
|
736
|
-
let pending = null;
|
|
737
|
-
for (const line of lines) {
|
|
738
|
-
const entry = parseRecord(line.text);
|
|
739
|
-
const payload = asRecord(entry?.payload);
|
|
740
|
-
if (entry?.type !== "event_msg" || typeof payload?.message !== "string") continue;
|
|
741
|
-
if (payload.type === "user_message") {
|
|
742
|
-
const plannedAction = readCodexPlannedAction(payload.message);
|
|
743
|
-
pending = plannedAction ? { offset: line.offset, plannedAction, ...isTimestamp(entry.timestamp) ? { requestedAt: entry.timestamp } : {} } : null;
|
|
744
|
-
continue;
|
|
745
|
-
}
|
|
746
|
-
if (payload.type !== "agent_message" || !pending) continue;
|
|
747
|
-
const verdict = readCodexReviewVerdict(payload.message);
|
|
748
|
-
if (!verdict) continue;
|
|
749
|
-
reviews.push({ ...pending, verdict });
|
|
750
|
-
pending = null;
|
|
751
|
-
}
|
|
752
|
-
return { reviews, ...pending ? { pendingOffset: pending.offset } : {} };
|
|
753
|
-
};
|
|
754
|
-
var codexPlannedShellCommand = (plannedAction) => {
|
|
755
|
-
if (plannedAction?.tool !== CODEX_SHELL_TOOL) return null;
|
|
756
|
-
const argv = plannedAction.command;
|
|
757
|
-
if (!Array.isArray(argv) || argv.length !== 3) return null;
|
|
758
|
-
const [shell, flag, command] = argv;
|
|
759
|
-
if (typeof shell !== "string" || shell.trim().length === 0) return null;
|
|
760
|
-
if (typeof flag !== "string" || !CODEX_SHELL_COMMAND_FLAGS.includes(flag)) return null;
|
|
761
|
-
if (typeof command !== "string" || command.trim().length === 0) return null;
|
|
762
|
-
const cwd = nonEmptyString(plannedAction.cwd);
|
|
763
|
-
return { command, ...cwd ? { cwd } : {} };
|
|
764
|
-
};
|
|
765
|
-
var codexReviewerDenialsSince = (reviews, since) => {
|
|
766
|
-
const sinceMs = Date.parse(since);
|
|
767
|
-
if (!Number.isFinite(sinceMs)) return [];
|
|
768
|
-
return reviews.flatMap((review) => {
|
|
769
|
-
if (review.verdict.outcome !== "deny" || !review.requestedAt) return [];
|
|
770
|
-
if (Date.parse(review.requestedAt) < sinceMs) return [];
|
|
771
|
-
const shell = codexPlannedShellCommand(review.plannedAction);
|
|
772
|
-
if (!shell) return [];
|
|
773
|
-
return [{
|
|
774
|
-
...shell,
|
|
775
|
-
offset: review.offset,
|
|
776
|
-
requestedAt: review.requestedAt,
|
|
777
|
-
plannedAction: review.plannedAction,
|
|
778
|
-
...review.verdict.rationale ? { rationale: review.verdict.rationale } : {}
|
|
779
|
-
}];
|
|
780
|
-
});
|
|
781
|
-
};
|
|
782
|
-
|
|
783
|
-
// ../hook-mapping/src/transcript-usage.ts
|
|
784
|
-
var TRANSCRIPT_ASSISTANT_TYPE = "assistant";
|
|
785
|
-
var TRANSCRIPT_SYNTHETIC_MODEL = "<synthetic>";
|
|
786
|
-
var TRANSCRIPT_RECENT_ID_LIMIT = 200;
|
|
787
|
-
var TRANSCRIPT_USAGE_EVENTS = ["PostToolUse", "Stop"];
|
|
788
|
-
var TRANSCRIPT_USAGE_SOURCES = ["claude", "qwen", "codebuddy", "qoder", "droid", "devin"];
|
|
789
|
-
var COST_TRACKING_ENV = "PUSHARY_COST_TRACKING";
|
|
790
|
-
var COST_TRACKING_OFF = "off";
|
|
791
|
-
var TURN_END_EVENT = "Stop";
|
|
792
|
-
var DEFAULT_MODEL_PRICES = [
|
|
793
|
-
{ match: "opus-4-1", in: 15, out: 75 },
|
|
794
|
-
{ match: "opus-4-0", in: 15, out: 75 },
|
|
795
|
-
{ match: "3-opus", in: 15, out: 75 },
|
|
796
|
-
{ match: "opus", in: 5, out: 25 },
|
|
797
|
-
{ match: "haiku", in: 1, out: 5 },
|
|
798
|
-
{ match: "sonnet", in: 3, out: 15 }
|
|
799
|
-
];
|
|
800
|
-
var FALLBACK_MODEL_PRICE = { match: "", in: 3, out: 15 };
|
|
801
|
-
var CACHE_WRITE_MULTIPLIER = 1.25;
|
|
802
|
-
var CACHE_READ_MULTIPLIER = 0.1;
|
|
803
|
-
var TOKENS_PER_PRICE_UNIT = 1e6;
|
|
804
|
-
var isPrice = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
805
|
-
var isModelPrice = (value) => {
|
|
806
|
-
const price = asRecord(value);
|
|
807
|
-
return price !== null && typeof price.match === "string" && isPrice(price.in) && isPrice(price.out);
|
|
808
|
-
};
|
|
809
|
-
var estimateMessageCostUsd = (usage, model, prices = DEFAULT_MODEL_PRICES) => {
|
|
810
|
-
const price = prices.find((candidate) => model.includes(candidate.match)) ?? FALLBACK_MODEL_PRICE;
|
|
811
|
-
const perTokenIn = price.in / TOKENS_PER_PRICE_UNIT;
|
|
812
|
-
const perTokenOut = price.out / TOKENS_PER_PRICE_UNIT;
|
|
813
|
-
return usage.inputTokens * perTokenIn + usage.outputTokens * perTokenOut + usage.cacheCreationTokens * perTokenIn * CACHE_WRITE_MULTIPLIER + usage.cacheReadTokens * perTokenIn * CACHE_READ_MULTIPLIER;
|
|
814
|
-
};
|
|
815
|
-
var transcriptTokensIn = (usage) => usage.inputTokens + usage.cacheCreationTokens + usage.cacheReadTokens;
|
|
816
|
-
var tokenCountOf = (value) => isTokenCount(value) ? value : 0;
|
|
817
|
-
var nonEmptyString2 = (value) => typeof value === "string" && value.length > 0 ? value : null;
|
|
818
|
-
var readTranscriptMessageUsage = (line) => {
|
|
819
|
-
const entry = parseRecord(line);
|
|
820
|
-
if (entry?.type !== TRANSCRIPT_ASSISTANT_TYPE) return null;
|
|
821
|
-
const message = asRecord(entry.message);
|
|
822
|
-
const usage = asRecord(message?.usage);
|
|
823
|
-
if (!message || !usage) return null;
|
|
824
|
-
const model = typeof message.model === "string" ? message.model : "";
|
|
825
|
-
if (model.includes(TRANSCRIPT_SYNTHETIC_MODEL)) return null;
|
|
826
|
-
return {
|
|
827
|
-
...typeof message.id === "string" ? { id: message.id } : {},
|
|
828
|
-
model,
|
|
829
|
-
usage: {
|
|
830
|
-
inputTokens: tokenCountOf(usage.input_tokens),
|
|
831
|
-
outputTokens: tokenCountOf(usage.output_tokens),
|
|
832
|
-
cacheCreationTokens: tokenCountOf(usage.cache_creation_input_tokens),
|
|
833
|
-
cacheReadTokens: tokenCountOf(usage.cache_read_input_tokens)
|
|
834
|
-
}
|
|
835
|
-
};
|
|
836
|
-
};
|
|
837
|
-
var rememberTranscriptMessage = (recentIds, id) => {
|
|
838
|
-
if (!id) return { counted: true, recentIds };
|
|
839
|
-
if (recentIds.includes(id)) return { counted: false, recentIds };
|
|
840
|
-
return { counted: true, recentIds: [...recentIds, id].slice(-TRANSCRIPT_RECENT_ID_LIMIT) };
|
|
841
|
-
};
|
|
842
|
-
var isTranscriptUsageEvent = (event) => TRANSCRIPT_USAGE_EVENTS.includes(event);
|
|
843
|
-
var endsASubagentTurn = (hook) => hook.event === TURN_END_EVENT && nonEmptyString2(hook.payload.agent_id) !== null;
|
|
844
|
-
var transcriptUsageRequest = (hook) => {
|
|
845
|
-
if (hook.costTracking === COST_TRACKING_OFF) return null;
|
|
846
|
-
if (!TRANSCRIPT_USAGE_SOURCES.includes(hook.source) || !isTranscriptUsageEvent(hook.event)) return null;
|
|
847
|
-
if (endsASubagentTurn(hook)) return null;
|
|
848
|
-
const transcriptPath = nonEmptyString2(hook.payload.transcript_path);
|
|
849
|
-
const sessionId = reportableSessionId(hook.payload.session_id);
|
|
850
|
-
return transcriptPath && sessionId ? { transcriptPath, sessionId } : null;
|
|
851
|
-
};
|
|
88
|
+
} from "./chunk-JHWOM55B.js";
|
|
852
89
|
|
|
853
90
|
// src/pending.ts
|
|
854
91
|
import { join } from "path";
|
|
@@ -1078,8 +315,8 @@ var stageHookCommand = (command) => {
|
|
|
1078
315
|
staged.push(command);
|
|
1079
316
|
return true;
|
|
1080
317
|
};
|
|
1081
|
-
var writeOutput = (output) => new Promise((
|
|
1082
|
-
process.stdout.write(output, (error) => error ? reject(error) :
|
|
318
|
+
var writeOutput = (output) => new Promise((resolve2, reject) => {
|
|
319
|
+
process.stdout.write(output, (error) => error ? reject(error) : resolve2());
|
|
1083
320
|
});
|
|
1084
321
|
var emitHookOutput = async (render, write = writeOutput) => {
|
|
1085
322
|
const staged = [];
|
|
@@ -1400,7 +637,7 @@ var readNewUsage = (transcriptPath, sessionId) => {
|
|
|
1400
637
|
};
|
|
1401
638
|
|
|
1402
639
|
// src/codex-adapter.ts
|
|
1403
|
-
import { resolve
|
|
640
|
+
import { resolve } from "path";
|
|
1404
641
|
var CODEX_AGENT = { type: "codex", label: "Codex" };
|
|
1405
642
|
var codexAllow = () => ({ kind: "allow" });
|
|
1406
643
|
var codexDeny = (reason) => ({ kind: "deny", reason });
|
|
@@ -1429,7 +666,7 @@ var toPolicyLookup = (toolName, toolInput, cwd) => {
|
|
|
1429
666
|
const command = toolInput.command;
|
|
1430
667
|
const files = parseApplyPatchFiles(command);
|
|
1431
668
|
if (files.length === 1) {
|
|
1432
|
-
return { tool: "Edit", input: { file_path: cwd ?
|
|
669
|
+
return { tool: "Edit", input: { file_path: cwd ? resolve(cwd, files[0]) : files[0] } };
|
|
1433
670
|
}
|
|
1434
671
|
return { tool: "Edit", input: typeof command === "string" ? { file_path: command } : {} };
|
|
1435
672
|
};
|
|
@@ -1445,7 +682,7 @@ var toPolicyLookups = (toolName, toolInput, cwd) => {
|
|
|
1445
682
|
}
|
|
1446
683
|
return {
|
|
1447
684
|
tool: "Edit",
|
|
1448
|
-
inputs: files.map((file) => ({ file_path: cwd ?
|
|
685
|
+
inputs: files.map((file) => ({ file_path: cwd ? resolve(cwd, file) : file }))
|
|
1449
686
|
};
|
|
1450
687
|
};
|
|
1451
688
|
var codexQuestionLimitDecision = (facts) => {
|
|
@@ -1776,7 +1013,7 @@ var isWaitingOnBackgroundWork = (sessionKey, nowMs = Date.now()) => {
|
|
|
1776
1013
|
};
|
|
1777
1014
|
|
|
1778
1015
|
// src/events.ts
|
|
1779
|
-
import { basename
|
|
1016
|
+
import { basename, join as join9 } from "path";
|
|
1780
1017
|
import { existsSync as existsSync6, mkdirSync as mkdirSync7, readFileSync as readFileSync7, statSync as statSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
1781
1018
|
import { tmpdir as tmpdir8 } from "os";
|
|
1782
1019
|
var INTENT_DIR = join9(tmpdir8(), "pushary-intent");
|
|
@@ -2084,7 +1321,7 @@ var handlePostToolUse = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
2084
1321
|
const deadline = Date.now() + HOOK_BUDGET_MS;
|
|
2085
1322
|
const signal = AbortSignal.timeout(HOOK_BUDGET_MS);
|
|
2086
1323
|
try {
|
|
2087
|
-
const projectName =
|
|
1324
|
+
const projectName = basename(input.cwd ?? process.cwd());
|
|
2088
1325
|
const action = describeToolCall(input.tool_name, input.tool_input, "event");
|
|
2089
1326
|
const lookup = toPolicyLookup(input.tool_name, input.tool_input);
|
|
2090
1327
|
const toolResult = input.tool_response ?? input.tool_result;
|
|
@@ -2151,7 +1388,7 @@ var handleUserPrompt = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
2151
1388
|
const deadline = Date.now() + HOOK_BUDGET_MS;
|
|
2152
1389
|
const signal = AbortSignal.timeout(HOOK_BUDGET_MS);
|
|
2153
1390
|
try {
|
|
2154
|
-
const projectName =
|
|
1391
|
+
const projectName = basename(input.cwd ?? process.cwd());
|
|
2155
1392
|
const sessionKey = input.session_id || DEFAULT_SESSION;
|
|
2156
1393
|
const titlesEnabled = process.env.PUSHARY_TASK_TITLES !== "off";
|
|
2157
1394
|
const taskTitle = titlesEnabled ? taskTitleFrom(input.prompt) : void 0;
|
|
@@ -2190,7 +1427,7 @@ var handleStop = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
2190
1427
|
const deadline = Date.now() + HOOK_BUDGET_MS;
|
|
2191
1428
|
const signal = AbortSignal.timeout(HOOK_BUDGET_MS);
|
|
2192
1429
|
try {
|
|
2193
|
-
const projectName =
|
|
1430
|
+
const projectName = basename(input.cwd ?? process.cwd());
|
|
2194
1431
|
const sessionKey = input.session_id || DEFAULT_SESSION;
|
|
2195
1432
|
noteBackgroundWork(sessionKey, hasRunningBackgroundTasks(input.background_tasks));
|
|
2196
1433
|
const late = await reconcilePendingQuestions(sessionKey, void 0, signal);
|
|
@@ -2231,7 +1468,7 @@ var isSubagentStop = (input) => input.hook_event_name === "SubagentStop" || type
|
|
|
2231
1468
|
var SUBAGENT_STOP_REPORT_TIMEOUT_MS = 4e3;
|
|
2232
1469
|
var handleSubagentStop = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
2233
1470
|
try {
|
|
2234
|
-
const projectName =
|
|
1471
|
+
const projectName = basename(input.cwd ?? process.cwd());
|
|
2235
1472
|
await reportEvent({
|
|
2236
1473
|
event: "session_end",
|
|
2237
1474
|
agentType: agent.type,
|
|
@@ -2249,7 +1486,7 @@ var isCompactionEvent = (hookEventName) => hookEventName === "PreCompact" || hoo
|
|
|
2249
1486
|
var COMPACTION_REPORT_TIMEOUT_MS = 4e3;
|
|
2250
1487
|
var handleCompaction = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
2251
1488
|
try {
|
|
2252
|
-
const projectName =
|
|
1489
|
+
const projectName = basename(input.cwd ?? process.cwd());
|
|
2253
1490
|
await reportEvent({
|
|
2254
1491
|
event: "compaction",
|
|
2255
1492
|
agentType: agent.type,
|
|
@@ -2262,7 +1499,7 @@ var handleCompaction = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
2262
1499
|
};
|
|
2263
1500
|
var handleSessionStart = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
2264
1501
|
try {
|
|
2265
|
-
const projectName =
|
|
1502
|
+
const projectName = basename(input.cwd ?? process.cwd());
|
|
2266
1503
|
const action = input.agent_id ? "Subagent started" : sessionStartAction(input.source);
|
|
2267
1504
|
await reportEvent({
|
|
2268
1505
|
event: "session_start",
|
|
@@ -2276,7 +1513,7 @@ var handleSessionStart = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
2276
1513
|
};
|
|
2277
1514
|
var handleSessionEnd = async (input, agent = CLAUDE_CODE_AGENT, options = {}) => {
|
|
2278
1515
|
try {
|
|
2279
|
-
const projectName =
|
|
1516
|
+
const projectName = basename(input.cwd ?? process.cwd());
|
|
2280
1517
|
const action = sessionEndAction(input.reason);
|
|
2281
1518
|
const sessionKey = input.session_id || DEFAULT_SESSION;
|
|
2282
1519
|
if (options.reconcile ?? true) {
|
|
@@ -2304,7 +1541,7 @@ var pushesNotification = (notifType, sessionKey) => NOTIFICATION_PUSH_TYPES.has(
|
|
|
2304
1541
|
var handleNotification = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
2305
1542
|
const signal = AbortSignal.timeout(HOOK_BUDGET_MS);
|
|
2306
1543
|
try {
|
|
2307
|
-
const projectName =
|
|
1544
|
+
const projectName = basename(input.cwd ?? process.cwd());
|
|
2308
1545
|
const notifType = notificationTypeOf(input) ?? "";
|
|
2309
1546
|
const sessionKey = input.session_id || DEFAULT_SESSION;
|
|
2310
1547
|
const teammateIdle = input.hook_event_name === "TeammateIdle";
|
|
@@ -2365,7 +1602,7 @@ var handleStopFailure = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
2365
1602
|
} catch {
|
|
2366
1603
|
return;
|
|
2367
1604
|
}
|
|
2368
|
-
const projectName =
|
|
1605
|
+
const projectName = basename(input.cwd ?? process.cwd());
|
|
2369
1606
|
const reason = describeStopFailure(input.error);
|
|
2370
1607
|
await reportEvent({
|
|
2371
1608
|
event: "turn_error",
|
|
@@ -2395,24 +1632,6 @@ var handleStopFailure = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
2395
1632
|
};
|
|
2396
1633
|
|
|
2397
1634
|
export {
|
|
2398
|
-
HOOK_FALLBACK_MAX,
|
|
2399
|
-
UNNAMED_ACTION,
|
|
2400
|
-
describeToolCall,
|
|
2401
|
-
deriveToolTarget,
|
|
2402
|
-
patchDeletesFiles,
|
|
2403
|
-
OPENCODE_TOOL_NAMES,
|
|
2404
|
-
compatibleToolLookup,
|
|
2405
|
-
canonicalGateInputs,
|
|
2406
|
-
scopePathFor,
|
|
2407
|
-
deriveActionBody,
|
|
2408
|
-
deriveAction,
|
|
2409
|
-
deriveBlocker,
|
|
2410
|
-
permissionDeniedAction,
|
|
2411
|
-
sessionIdentityOf,
|
|
2412
|
-
readCodexTurnContext,
|
|
2413
|
-
isCodexGuardianRolloutHead,
|
|
2414
|
-
scanCodexGuardianReviews,
|
|
2415
|
-
codexReviewerDenialsSince,
|
|
2416
1635
|
DEFAULT_SESSION,
|
|
2417
1636
|
readPendingCommandById,
|
|
2418
1637
|
readPendingCommand,
|