@pushary/agent-hooks 0.87.3 → 0.88.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/data/cursor-plugin/scripts/pushary-gate.mjs +9 -0
  2. package/data/cursor-plugin/scripts/pushary-gate.test.mjs +39 -0
  3. package/dist/bin/pushary-bell-hook.js +4 -4
  4. package/dist/bin/pushary-bell.js +5 -5
  5. package/dist/bin/pushary-claude.js +8 -8
  6. package/dist/bin/pushary-clean.js +9 -8
  7. package/dist/bin/pushary-codex-bridge.js +5 -5
  8. package/dist/bin/pushary-codex-hook.js +15 -9
  9. package/dist/bin/pushary-codex.js +4 -4
  10. package/dist/bin/pushary-connect.js +6 -6
  11. package/dist/bin/pushary-daemon.js +4 -4
  12. package/dist/bin/pushary-disconnect.js +5 -5
  13. package/dist/bin/pushary-doctor.js +15 -14
  14. package/dist/bin/pushary-elicitation-hook.js +1 -1
  15. package/dist/bin/pushary-gemini-bridge.js +5 -5
  16. package/dist/bin/pushary-gemini-hook.js +15 -9
  17. package/dist/bin/pushary-hook.js +6 -6
  18. package/dist/bin/pushary-login.js +4 -4
  19. package/dist/bin/pushary-logout.js +4 -4
  20. package/dist/bin/pushary-mode.js +3 -3
  21. package/dist/bin/pushary-notification-hook.js +4 -4
  22. package/dist/bin/pushary-opencode-hook.js +5 -5
  23. package/dist/bin/pushary-permission-denied-hook.js +6 -6
  24. package/dist/bin/pushary-permission-hook.js +6 -6
  25. package/dist/bin/pushary-post-hook.js +4 -4
  26. package/dist/bin/pushary-prompt-hook.js +4 -4
  27. package/dist/bin/pushary-session-end-hook.js +4 -4
  28. package/dist/bin/pushary-session-start-hook.js +4 -4
  29. package/dist/bin/pushary-setup.js +16 -16
  30. package/dist/bin/pushary-stats.js +2 -2
  31. package/dist/bin/pushary-status.js +5 -5
  32. package/dist/bin/pushary-stop-hook.js +4 -4
  33. package/dist/bin/pushary-stopfailure-hook.js +4 -4
  34. package/dist/bin/pushary-upgrade.js +5 -5
  35. package/dist/bin/pushary-wait.js +3 -3
  36. package/dist/{chunk-LGVHYFIB.js → chunk-3B3PYTKH.js} +1 -1
  37. package/dist/{chunk-DMW54VWK.js → chunk-3JL64GVE.js} +93 -3
  38. package/dist/{chunk-TD3M232T.js → chunk-3PSEZOC4.js} +1 -1
  39. package/dist/{chunk-VIHRP25S.js → chunk-4VYELDAH.js} +1 -1
  40. package/dist/{chunk-YX6ZKCC5.js → chunk-67TNJVJW.js} +1 -1
  41. package/dist/{chunk-KFAH6KRE.js → chunk-6BOE5NJZ.js} +1 -1
  42. package/dist/{chunk-ZGC3W23N.js → chunk-DSTZ2RBU.js} +1 -1
  43. package/dist/{chunk-ICERLAE2.js → chunk-DXBUFXPL.js} +1 -1
  44. package/dist/{chunk-EJL3PJU7.js → chunk-ESARAYRI.js} +1 -1
  45. package/dist/{chunk-7J67NYK4.js → chunk-F5W3AY6L.js} +2 -1
  46. package/dist/{chunk-QLMX5LLV.js → chunk-LEYXXXRN.js} +1 -1
  47. package/dist/{chunk-VOE4SYPR.js → chunk-MNXG6IIM.js} +23 -7
  48. package/dist/{chunk-K42RXJPG.js → chunk-MY5A4EPQ.js} +1 -1
  49. package/dist/{chunk-KCAFCGGY.js → chunk-OULRSHFB.js} +1 -1
  50. package/dist/{chunk-TAYHEJFF.js → chunk-RSUBLTMP.js} +2 -2
  51. package/dist/{chunk-DPUOW6NS.js → chunk-T2XZH7D5.js} +3 -7
  52. package/dist/{chunk-2JYQAW4B.js → chunk-U6HRYNHC.js} +2 -2
  53. package/dist/{chunk-OMA2OZRE.js → chunk-UTQCV46U.js} +27 -62
  54. package/dist/{chunk-VL5ZNK6V.js → chunk-VHHVGVFQ.js} +12 -2
  55. package/dist/{chunk-KBS53WOE.js → chunk-VSCSZ2LI.js} +1 -1
  56. package/dist/{chunk-YYTLTEGU.js → chunk-WXCHB6BO.js} +1 -1
  57. package/dist/{chunk-TV3UFGT7.js → chunk-XFHMGVMX.js} +1 -1
  58. package/dist/src/index.js +6 -6
  59. package/package.json +1 -1
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  detectClaudeVersion
4
- } from "../chunk-ICERLAE2.js";
4
+ } from "../chunk-DXBUFXPL.js";
5
5
  import {
6
6
  addClaudeMcpServer,
7
7
  addPusharyHooks,
8
8
  addPusharyToolPermissions
9
- } from "../chunk-2JYQAW4B.js";
9
+ } from "../chunk-U6HRYNHC.js";
10
10
  import {
11
11
  GEMINI_HOOK_BINARY,
12
12
  addGeminiHooks,
13
13
  addGeminiMcpServer,
14
14
  hasGeminiHooks
15
- } from "../chunk-K42RXJPG.js";
15
+ } from "../chunk-MY5A4EPQ.js";
16
16
  import "../chunk-ATBKJNWS.js";
17
17
  import {
18
18
  guardBinary
@@ -37,7 +37,7 @@ import {
37
37
  hasCodexHooks,
38
38
  vscodePluginDir,
39
39
  vscodePluginMcp
40
- } from "../chunk-VL5ZNK6V.js";
40
+ } from "../chunk-VHHVGVFQ.js";
41
41
  import "../chunk-GIRT7677.js";
42
42
  import {
43
43
  exitOnHelpFlag
@@ -53,7 +53,7 @@ import "../chunk-KZERVKTD.js";
53
53
  import {
54
54
  getApiKey
55
55
  } from "../chunk-2UMNXADU.js";
56
- import "../chunk-DMW54VWK.js";
56
+ import "../chunk-3JL64GVE.js";
57
57
 
58
58
  // bin/pushary-upgrade.ts
59
59
  import { existsSync as existsSync2 } from "fs";
@@ -4,8 +4,8 @@ import {
4
4
  } from "../chunk-IIENZE2J.js";
5
5
  import {
6
6
  exitOnFailedResponse
7
- } from "../chunk-TD3M232T.js";
8
- import "../chunk-KFAH6KRE.js";
7
+ } from "../chunk-3PSEZOC4.js";
8
+ import "../chunk-6BOE5NJZ.js";
9
9
  import {
10
10
  createIo
11
11
  } from "../chunk-5RUIFDTP.js";
@@ -28,7 +28,7 @@ import {
28
28
  getApiKey,
29
29
  getBaseUrl
30
30
  } from "../chunk-2UMNXADU.js";
31
- import "../chunk-DMW54VWK.js";
31
+ import "../chunk-3JL64GVE.js";
32
32
 
33
33
  // bin/pushary-wait.ts
34
34
  exitOnHelpFlag("wait");
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-VL5ZNK6V.js";
3
+ } from "./chunk-VHHVGVFQ.js";
4
4
  import {
5
5
  readJsonSafe
6
6
  } from "./chunk-6MTNS63X.js";
@@ -1,6 +1,39 @@
1
1
  // ../contracts/src/index.ts
2
2
  var APPROVAL_MODES = ["push_only", "terminal_only", "push_first", "notify_only"];
3
3
  var isApprovalMode = (value) => typeof value === "string" && APPROVAL_MODES.includes(value);
4
+ var MAX_AGENT_QUESTIONS = 4;
5
+ var parseAgentQuestion = (raw) => {
6
+ const q = raw;
7
+ if (!q || typeof q.question !== "string") return void 0;
8
+ const options = Array.isArray(q.options) ? q.options.flatMap((option) => {
9
+ if (!option || typeof option !== "object") return [];
10
+ const value = option;
11
+ if (typeof value.label !== "string" || value.label.length === 0) return [];
12
+ return [{
13
+ label: value.label,
14
+ ...typeof value.description === "string" ? { description: value.description } : {}
15
+ }];
16
+ }) : [];
17
+ if (options.length < 2) return void 0;
18
+ return {
19
+ question: q.question,
20
+ ...typeof q.header === "string" ? { header: q.header } : {},
21
+ multiSelect: q.multiSelect === true,
22
+ options
23
+ };
24
+ };
25
+ var parseAgentQuestions = (toolInput) => {
26
+ const questions = toolInput.questions;
27
+ if (!Array.isArray(questions) || questions.length === 0) return void 0;
28
+ if (questions.length > MAX_AGENT_QUESTIONS) return void 0;
29
+ const parsed = [];
30
+ for (const raw of questions) {
31
+ const one = parseAgentQuestion(raw);
32
+ if (!one || parsed.some((question) => question.question === one.question)) return void 0;
33
+ parsed.push(one);
34
+ }
35
+ return parsed;
36
+ };
4
37
  var parseAgentQuestionAnswers = (questions, value) => {
5
38
  let parsed;
6
39
  try {
@@ -72,6 +105,7 @@ var hookWaitDeadline = (startMs, policyWaitSeconds, agent, nowMs) => {
72
105
  };
73
106
  var hookWaitClamped = (startMs, policyWaitSeconds, agent, nowMs) => startMs + hookMaxWaitSeconds(agent) * 1e3 < nowMs + Math.max(policyWaitSeconds, 0) * 1e3;
74
107
  var effectiveWaitSeconds = (timeoutAction, policySeconds, agent) => timeoutAction === "wait" ? hookMaxWaitSeconds(agent) : policySeconds;
108
+ var HOOK_SOURCES = ["claude", "codex", "gemini", "cursor", "vscode", "opencode"];
75
109
  var AGENT_LABELS_BY_TYPE = {
76
110
  claude_code: "Claude Code",
77
111
  claude_cowork: "Claude Cowork",
@@ -86,6 +120,7 @@ var AGENT_LABELS_BY_TYPE = {
86
120
  unknown: "Agent"
87
121
  };
88
122
  var OPENCODE_APPROVAL_EVENT = "permission.ask";
123
+ var CURSOR_GATE_EVENTS = ["beforeShellExecution", "beforeMCPExecution"];
89
124
  var HOOK_LOCATOR_BINARY = "pushary-bridge";
90
125
  var HOOK_BATCH_MAX_BYTES = 4 * 1024 * 1024;
91
126
  var REPO_KEY_MAX_LENGTH = 200;
@@ -960,8 +995,15 @@ var resolveAutoResolveOrigin = (config, toolName, toolInput, cwd, repoKey, sessi
960
995
  var resolvePolicy = (config, toolName, modeOverride, toolInput, cwd, repoKey, sessionId) => {
961
996
  const args = toolInput ? policyArgForms(toolName, toolInput, cwd) : [];
962
997
  const arg = args[0];
963
- const match = selectGoverningRule(config.policies, toolName, args, repoKey, sessionId);
964
- let base = match?.policy ?? config.policies.find((p) => p.tool === "*") ?? {
998
+ const governing = (pool) => {
999
+ if (pool.length === 0) return void 0;
1000
+ const rule = selectGoverningRule(pool, toolName, args, repoKey, sessionId);
1001
+ if (rule) return rule;
1002
+ const wildcard = pool.find((p) => p.tool === "*");
1003
+ return wildcard ? { policy: wildcard, rank: "wildcard" } : void 0;
1004
+ };
1005
+ const match = governing(config.policies.filter((p) => !p.origin)) ?? governing(config.policies.filter((p) => p.origin === "preset")) ?? governing(config.policies.filter((p) => p.origin === "builtin"));
1006
+ let base = match?.policy ?? {
965
1007
  tool: toolName,
966
1008
  timeoutSeconds: config.defaultTimeoutSeconds,
967
1009
  timeoutAction: config.defaultTimeoutAction,
@@ -1013,6 +1055,21 @@ var strictestScopeVerdict = (scope, paths) => {
1013
1055
  return worst;
1014
1056
  };
1015
1057
  var survivesDegraded = (config, toolName, toolInputs, cwd, repoKey, sessionId) => toolInputs.length === 1 && resolveAutoResolveOrigin(config, toolName, toolInputs[0], cwd, repoKey, sessionId) === "safe_readonly";
1058
+ var FULL_DEFER_MODES = /* @__PURE__ */ new Set(["plan", "auto", "dontAsk"]);
1059
+ var ACCEPT_EDITS_DEFER_TOOLS = /* @__PURE__ */ new Set([
1060
+ "Write",
1061
+ "Edit",
1062
+ "MultiEdit",
1063
+ "NotebookEdit"
1064
+ ]);
1065
+ var shouldDeferToNativeMode = (permissionMode, toolName, options = {}) => {
1066
+ if (options.respectPermissionMode === false) return false;
1067
+ if (typeof permissionMode !== "string") return false;
1068
+ if (FULL_DEFER_MODES.has(permissionMode)) return true;
1069
+ if (permissionMode === "acceptEdits" && ACCEPT_EDITS_DEFER_TOOLS.has(toolName)) return true;
1070
+ if (permissionMode === "bypassPermissions") return options.deferBypass === true;
1071
+ return false;
1072
+ };
1016
1073
  var resolveGate = (input) => {
1017
1074
  const { modeState, config, toolName, toolInputs, cwd, repoKey, sessionId } = input;
1018
1075
  if (modeState.kill) return { kind: "kill", reason: KILL_REASON };
@@ -1068,6 +1125,33 @@ var claudePreToolUseOutput = (decision, reason, updatedInput) => ({
1068
1125
  ...updatedInput ? { updatedInput } : {}
1069
1126
  }
1070
1127
  });
1128
+ var PENDING_COMMAND_PREFIX = "The user sent a new instruction from their phone via Pushary:";
1129
+ var pendingCommandEvents = (source) => {
1130
+ switch (source) {
1131
+ case "claude":
1132
+ return ["PostToolUse", "UserPromptSubmit", "Stop"];
1133
+ // Codex carries context on its activity events and NOT on Stop, whose output
1134
+ // schema has no context field at all. Draining for it at the turn boundary
1135
+ // was therefore right to render nothing, and wrong to conclude that Codex
1136
+ // could not be sent a message.
1137
+ case "codex":
1138
+ return ["PostToolUse", "PreToolUse", "UserPromptSubmit"];
1139
+ case "gemini":
1140
+ return ["AfterTool", "BeforeTool", "BeforeAgent"];
1141
+ // Registered events only. Cursor's carriers are `postToolUse` and `stop`,
1142
+ // which this build does not write into the config; the ones it does write
1143
+ // (`afterShellExecution`, `afterFileEdit`, `afterAgentResponse`) are
1144
+ // observational and discard whatever they print.
1145
+ case "cursor":
1146
+ return [];
1147
+ case "vscode":
1148
+ return [];
1149
+ // The prompt is appended through the TUI rather than through a hook return,
1150
+ // so there is nothing for this to print.
1151
+ case "opencode":
1152
+ return [];
1153
+ }
1154
+ };
1071
1155
  var claudePermissionRequestOutput = (decision, reason, updatedInput) => ({
1072
1156
  hookSpecificOutput: {
1073
1157
  hookEventName: "PermissionRequest",
@@ -1103,7 +1187,7 @@ var gateOutputFor = (source, event, decision, reason) => {
1103
1187
  output = decision === "allow" ? { decision: "allow" } : { decision: "deny", reason: reason ?? "Denied from Pushary" };
1104
1188
  } else if (source === "opencode" && event === OPENCODE_APPROVAL_EVENT) {
1105
1189
  output = decision === "deny" ? { status: "deny", reason: reason ?? "Denied from Pushary" } : { status: decision };
1106
- } else if (source === "cursor" && event === "beforeShellExecution") {
1190
+ } else if (source === "cursor" && CURSOR_GATE_EVENTS.includes(event)) {
1107
1191
  output = decision === "allow" ? { permission: "allow" } : decision === "ask" ? { permission: "ask" } : {
1108
1192
  permission: "deny",
1109
1193
  user_message: "Command denied via Pushary.",
@@ -1125,14 +1209,17 @@ var claudeElicitationOutput = (event, action, content) => ({
1125
1209
  var renderElicitationOutput = (event, action, content) => ELICITATION_EVENTS.includes(event) ? JSON.stringify(claudeElicitationOutput(event, action, content)) : void 0;
1126
1210
 
1127
1211
  export {
1212
+ parseAgentQuestions,
1128
1213
  parseAgentQuestionAnswers,
1129
1214
  normalizeInstallSource,
1130
1215
  HOOK_BUDGETS,
1131
1216
  hookWaitDeadline,
1132
1217
  hookWaitClamped,
1133
1218
  effectiveWaitSeconds,
1219
+ HOOK_SOURCES,
1134
1220
  AGENT_LABELS_BY_TYPE,
1135
1221
  OPENCODE_APPROVAL_EVENT,
1222
+ CURSOR_GATE_EVENTS,
1136
1223
  HOOK_LOCATOR_BINARY,
1137
1224
  normalizeRepoRemote,
1138
1225
  localRepoKey,
@@ -1148,9 +1235,12 @@ export {
1148
1235
  resolveAutoResolveOrigin,
1149
1236
  resolvePolicy,
1150
1237
  KILL_REASON,
1238
+ shouldDeferToNativeMode,
1151
1239
  resolveGate,
1152
1240
  modeStateFromResponse,
1153
1241
  claudePreToolUseOutput,
1242
+ PENDING_COMMAND_PREFIX,
1243
+ pendingCommandEvents,
1154
1244
  claudePermissionRequestOutput,
1155
1245
  gateOutputFor,
1156
1246
  renderElicitationOutput
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  describeKeyCheck,
3
3
  keyCheckFromResponse
4
- } from "./chunk-KFAH6KRE.js";
4
+ } from "./chunk-6BOE5NJZ.js";
5
5
  import {
6
6
  createIo
7
7
  } from "./chunk-5RUIFDTP.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isSafeReadOnlyCommand
3
- } from "./chunk-DMW54VWK.js";
3
+ } from "./chunk-3JL64GVE.js";
4
4
 
5
5
  // src/ledger.ts
6
6
  import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync } from "fs";
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-6MTNS63X.js";
10
10
  import {
11
11
  resolveInstallSourceFor
12
- } from "./chunk-KBS53WOE.js";
12
+ } from "./chunk-VSCSZ2LI.js";
13
13
  import {
14
14
  configFilePath
15
15
  } from "./chunk-2UMNXADU.js";
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-2UMNXADU.js";
13
13
  import {
14
14
  isValidApiKey
15
- } from "./chunk-DMW54VWK.js";
15
+ } from "./chunk-3JL64GVE.js";
16
16
 
17
17
  // src/session.ts
18
18
  var IDENTITY_PATH = "/api/v1/server/identity";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  HOOK_BUDGETS,
3
3
  OPENCODE_APPROVAL_EVENT
4
- } from "./chunk-DMW54VWK.js";
4
+ } from "./chunk-3JL64GVE.js";
5
5
 
6
6
  // src/opencode-plugin.ts
7
7
  var OPENCODE_PLUGIN_MARKER = "pushary-opencode-plugin w1";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseVersion
3
- } from "./chunk-K42RXJPG.js";
3
+ } from "./chunk-MY5A4EPQ.js";
4
4
 
5
5
  // src/setup/agent-probe.ts
6
6
  import { execSync } from "child_process";
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-BSZYIAZL.js";
12
12
  import {
13
13
  reportedInstallSource
14
- } from "./chunk-KBS53WOE.js";
14
+ } from "./chunk-VSCSZ2LI.js";
15
15
 
16
16
  // src/reach.ts
17
17
  var reachVerdict = (channels) => {
@@ -5,7 +5,7 @@ import {
5
5
  FILE_TARGET_TOOLS,
6
6
  redactSecrets,
7
7
  redactSecretsDeep
8
- } from "./chunk-DMW54VWK.js";
8
+ } from "./chunk-3JL64GVE.js";
9
9
 
10
10
  // ../hook-mapping/src/describe.ts
11
11
  import { isAbsolute, relative, resolve } from "path";
@@ -280,6 +280,7 @@ export {
280
280
  deriveActionBody,
281
281
  deriveAction,
282
282
  deriveBlocker,
283
+ AGENT_IDENTITIES,
283
284
  summarizeStop,
284
285
  sessionStartAction,
285
286
  sessionEndAction,
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-2UMNXADU.js";
4
4
  import {
5
5
  redactSecrets
6
- } from "./chunk-DMW54VWK.js";
6
+ } from "./chunk-3JL64GVE.js";
7
7
 
8
8
  // src/crypto.ts
9
9
  import nacl from "tweetnacl";
@@ -10,6 +10,7 @@ import {
10
10
  waitForAnswer
11
11
  } from "./chunk-J3YDT4HM.js";
12
12
  import {
13
+ AGENT_IDENTITIES,
13
14
  deriveReceiptMeta,
14
15
  deriveToolTarget,
15
16
  describeToolCall,
@@ -21,7 +22,7 @@ import {
21
22
  summarizeStop,
22
23
  taskTitleFrom,
23
24
  toolResultErrorText
24
- } from "./chunk-7J67NYK4.js";
25
+ } from "./chunk-F5W3AY6L.js";
25
26
  import {
26
27
  getMachineId
27
28
  } from "./chunk-RN3NOEJF.js";
@@ -30,20 +31,23 @@ import {
30
31
  } from "./chunk-BSZYIAZL.js";
31
32
  import {
32
33
  reportedInstallSource
33
- } from "./chunk-KBS53WOE.js";
34
+ } from "./chunk-VSCSZ2LI.js";
34
35
  import {
35
36
  getApiKey,
36
37
  getBaseUrl
37
38
  } from "./chunk-2UMNXADU.js";
38
39
  import {
40
+ HOOK_SOURCES,
41
+ PENDING_COMMAND_PREFIX,
39
42
  gateOutputFor,
40
43
  isAutoApprove,
41
44
  localRepoKey,
42
45
  modeStateFromResponse,
43
46
  normalizeRepoRemote,
47
+ pendingCommandEvents,
44
48
  resolveAutoResolveOrigin,
45
49
  resolvePolicy
46
- } from "./chunk-DMW54VWK.js";
50
+ } from "./chunk-3JL64GVE.js";
47
51
 
48
52
  // src/policy.ts
49
53
  import { createHash } from "crypto";
@@ -648,7 +652,6 @@ var deriveUsage = (transcriptPath, sessionId) => {
648
652
  return void 0;
649
653
  }
650
654
  };
651
- var PENDING_COMMAND_PREFIX = "The user sent a new instruction from their phone via Pushary:";
652
655
  var mergeAdditionalContext = (existing, reported) => {
653
656
  const pendingCommand = reported.status === "fulfilled" ? reported.value?.pendingCommand : void 0;
654
657
  if (typeof pendingCommand !== "string" || pendingCommand.trim().length === 0) return existing;
@@ -657,6 +660,11 @@ var mergeAdditionalContext = (existing, reported) => {
657
660
 
658
661
  ${injected}` : injected;
659
662
  };
663
+ var consumesActivityContext = (agentType) => {
664
+ const source = HOOK_SOURCES.find((candidate) => AGENT_IDENTITIES[candidate].type === agentType);
665
+ if (!source) return false;
666
+ return pendingCommandEvents(source).some((event) => event !== "Stop");
667
+ };
660
668
  var detectInstallMode = () => (process.argv[1] ?? "").includes("_npx") ? "npx" : "cli";
661
669
  var reportEvent = async (event, options = {}) => {
662
670
  const apiKey = options.apiKey ?? getApiKey();
@@ -691,7 +699,15 @@ var reportEvent = async (event, options = {}) => {
691
699
  // Only Claude Code consumes additionalContext from these hooks; Codex and
692
700
  // Gemini keep their existing session_end-only drain, so they must NOT
693
701
  // advertise it or the server would pop-and-drop their queued command.
694
- canDrainCommand: event.agentType === CLAUDE_CODE_AGENT.type
702
+ //
703
+ // And only when this caller kept the full budget. The pop is a destructive
704
+ // LPOP that happens before the response is written, so a caller that
705
+ // abandons the request destroys the message: `user_prompt` runs on a human
706
+ // keystroke and gave it 800ms, which a cold function misses routinely.
707
+ // Asking the server to consume something we may not wait to receive is the
708
+ // one shape that loses it outright, and the instruction reaches the agent
709
+ // on its next tool call instead.
710
+ canDrainCommand: consumesActivityContext(event.agentType) && options.timeoutMs === void 0
695
711
  }),
696
712
  signal: AbortSignal.timeout(options.timeoutMs ?? 1e4)
697
713
  });
@@ -750,7 +766,7 @@ var handlePostToolUse = async (input, agent = CLAUDE_CODE_AGENT) => {
750
766
  );
751
767
  }
752
768
  const [reported] = await Promise.allSettled([toolReport, ...extraReports]);
753
- if (agent.type === CLAUDE_CODE_AGENT.type) {
769
+ if (consumesActivityContext(agent.type)) {
754
770
  additionalContext = mergeAdditionalContext(additionalContext, reported);
755
771
  }
756
772
  return additionalContext;
@@ -780,7 +796,7 @@ var handleUserPrompt = async (input, agent = CLAUDE_CODE_AGENT) => {
780
796
  taskTitle
781
797
  }, { maxAttempts: 1, timeoutMs: 800 })
782
798
  ]);
783
- if (agent.type === CLAUDE_CODE_AGENT.type) {
799
+ if (consumesActivityContext(agent.type)) {
784
800
  additionalContext = mergeAdditionalContext(additionalContext, reported);
785
801
  }
786
802
  return additionalContext;
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  HOOK_BUDGETS,
7
7
  HOOK_LOCATOR_BINARY
8
- } from "./chunk-DMW54VWK.js";
8
+ } from "./chunk-3JL64GVE.js";
9
9
 
10
10
  // src/gemini-config.ts
11
11
  var GEMINI_HOOK_BINARY = "pushary-gemini-hook";
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-VT4IVERX.js";
8
8
  import {
9
9
  pusharyDir
10
- } from "./chunk-VL5ZNK6V.js";
10
+ } from "./chunk-VHHVGVFQ.js";
11
11
  import {
12
12
  getMachineId
13
13
  } from "./chunk-RN3NOEJF.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  hasGeminiHooks
3
- } from "./chunk-K42RXJPG.js";
3
+ } from "./chunk-MY5A4EPQ.js";
4
4
  import {
5
5
  hasCodexHooks
6
- } from "./chunk-VL5ZNK6V.js";
6
+ } from "./chunk-VHHVGVFQ.js";
7
7
 
8
8
  // src/diagnostics/wiring.ts
9
9
  var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  openCodeConfigDirFrom
3
- } from "./chunk-ZGC3W23N.js";
3
+ } from "./chunk-DSTZ2RBU.js";
4
4
  import {
5
5
  codexHomeFrom
6
- } from "./chunk-VL5ZNK6V.js";
6
+ } from "./chunk-VHHVGVFQ.js";
7
7
 
8
8
  // src/vscode-config.ts
9
9
  import { homedir } from "os";
@@ -326,9 +326,6 @@ var hasInstructionBlock = (filePath) => {
326
326
  }
327
327
  };
328
328
 
329
- // src/hooks-spec.ts
330
- var CURSOR_GATE_EVENTS = ["beforeShellExecution", "beforeMCPExecution"];
331
-
332
329
  export {
333
330
  registerPluginLocation,
334
331
  unregisterPluginLocation,
@@ -345,6 +342,5 @@ export {
345
342
  renderProjectAgentInstructions,
346
343
  writeInstructionBlock,
347
344
  removeInstructionBlock,
348
- hasInstructionBlock,
349
- CURSOR_GATE_EVENTS
345
+ hasInstructionBlock
350
346
  };
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  CLAUDE_HOOK_EVENTS,
3
3
  supportedClaudeEvents
4
- } from "./chunk-K42RXJPG.js";
4
+ } from "./chunk-MY5A4EPQ.js";
5
5
  import {
6
6
  guardBinary
7
7
  } from "./chunk-B7ZBHWOW.js";
8
8
  import {
9
9
  HOOK_LOCATOR_BINARY
10
- } from "./chunk-DMW54VWK.js";
10
+ } from "./chunk-3JL64GVE.js";
11
11
 
12
12
  // src/claude-config.ts
13
13
  import { join } from "path";