@pushary/agent-hooks 1.7.3 → 1.8.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 (102) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +13 -1
  3. package/data/cursor-plugin/scripts/pushary-gate.mjs +2 -21
  4. package/data/cursor-plugin/scripts/redaction.mjs +51 -0
  5. package/data/vscode-plugin/scripts/pushary-gate.mjs +1 -21
  6. package/data/vscode-plugin/scripts/redaction.mjs +51 -0
  7. package/dist/bin/pushary-bell-hook.js +23 -23
  8. package/dist/bin/pushary-bell.js +9 -9
  9. package/dist/bin/pushary-claude.js +26 -26
  10. package/dist/bin/pushary-clean.js +91 -107
  11. package/dist/bin/pushary-codex-bridge.js +18 -18
  12. package/dist/bin/pushary-codex-hook.js +42 -43
  13. package/dist/bin/pushary-codex.js +13 -13
  14. package/dist/bin/pushary-connect.js +13 -13
  15. package/dist/bin/pushary-cowork.js +5 -5
  16. package/dist/bin/pushary-daemon.js +27 -27
  17. package/dist/bin/pushary-disconnect.js +18 -18
  18. package/dist/bin/pushary-doctor.js +85 -79
  19. package/dist/bin/pushary-elicitation-hook.js +25 -25
  20. package/dist/bin/pushary-gemini-bridge.js +12 -12
  21. package/dist/bin/pushary-gemini-hook.js +29 -30
  22. package/dist/bin/pushary-hook.js +32 -32
  23. package/dist/bin/pushary-login.js +12 -12
  24. package/dist/bin/pushary-logout.js +7 -7
  25. package/dist/bin/pushary-mcp.js +85 -28
  26. package/dist/bin/pushary-mode.js +9 -9
  27. package/dist/bin/pushary-notification-hook.js +28 -28
  28. package/dist/bin/pushary-opencode-hook.js +28 -29
  29. package/dist/bin/pushary-permission-denied-hook.js +32 -32
  30. package/dist/bin/pushary-permission-hook.js +31 -31
  31. package/dist/bin/pushary-post-hook.js +28 -28
  32. package/dist/bin/pushary-prompt-hook.js +28 -28
  33. package/dist/bin/pushary-session-end-hook.js +28 -28
  34. package/dist/bin/pushary-session-start-hook.js +32 -32
  35. package/dist/bin/pushary-setup.js +60 -127
  36. package/dist/bin/pushary-stats.js +5 -5
  37. package/dist/bin/pushary-status.js +15 -15
  38. package/dist/bin/pushary-stop-hook.js +28 -28
  39. package/dist/bin/pushary-stopfailure-hook.js +28 -28
  40. package/dist/bin/pushary-suggestions.js +4 -4
  41. package/dist/bin/pushary-transcript-register.js +19 -19
  42. package/dist/bin/pushary-transcripts.js +7 -7
  43. package/dist/bin/pushary-upgrade.js +231 -105
  44. package/dist/bin/pushary-wait.js +9 -9
  45. package/dist/bin/pushary.js +6 -6
  46. package/dist/{chunk-EEEJ2JIL.js → chunk-2ABTSGFT.js} +3 -3
  47. package/dist/{chunk-DUQO4C4I.js → chunk-2OY3ZZ5N.js} +3 -3
  48. package/dist/{chunk-MIXWMA73.js → chunk-3EVPNIBE.js} +3 -3
  49. package/dist/{chunk-WTJM7PSL.js → chunk-6J2JC2RT.js} +3 -3
  50. package/dist/{chunk-EADXTSHE.js → chunk-7Z7Q4GGS.js} +2 -2
  51. package/dist/{chunk-MZBRL5H5.js → chunk-A2A2YTMG.js} +108 -25
  52. package/dist/{chunk-KEL5MXRL.js → chunk-AHV4LNB5.js} +1 -1
  53. package/dist/{chunk-G3OMOTJ4.js → chunk-AXPCESYO.js} +3 -3
  54. package/dist/{chunk-3EUBQARL.js → chunk-C2WCPBF7.js} +1 -1
  55. package/dist/chunk-CJVVKOSR.js +73 -0
  56. package/dist/{chunk-U6RVDUJ5.js → chunk-CULUZTWQ.js} +283 -41
  57. package/dist/{chunk-N5MZH5A6.js → chunk-CVQYGMSR.js} +4 -4
  58. package/dist/{chunk-VKVSRCBO.js → chunk-D2FX3EPW.js} +1 -1
  59. package/dist/{chunk-62CVUUNU.js → chunk-DB3ONZB4.js} +2 -2
  60. package/dist/{chunk-WGMW7OXW.js → chunk-DE4Y6TCC.js} +6 -6
  61. package/dist/{chunk-YYCTF4Q5.js → chunk-E4FJTUH4.js} +1 -1
  62. package/dist/{chunk-EUGNVLMG.js → chunk-EPCXUP3P.js} +3 -1
  63. package/dist/{chunk-PRNFSORD.js → chunk-EX3GAPA4.js} +1 -1
  64. package/dist/{chunk-TCVMK6GI.js → chunk-EYK3GSRH.js} +4 -4
  65. package/dist/{chunk-R6OYCUNK.js → chunk-GPEGOGRJ.js} +1 -1
  66. package/dist/chunk-GU3EJCVV.js +43 -0
  67. package/dist/{chunk-Y4ZH64UK.js → chunk-HQ6G3B5R.js} +2 -2
  68. package/dist/{chunk-5S2VBSJI.js → chunk-HZVVNGEW.js} +2 -2
  69. package/dist/{chunk-IWJKSIB4.js → chunk-IPVKH2ST.js} +1 -1
  70. package/dist/{chunk-UOQRM7JQ.js → chunk-J5TIV3J6.js} +5 -5
  71. package/dist/{chunk-IRZG3HEU.js → chunk-JU6W3XAU.js} +1 -1
  72. package/dist/{chunk-G62JL2NT.js → chunk-JYG4B33G.js} +1 -1
  73. package/dist/{chunk-OTNOANMX.js → chunk-JZTHGAPA.js} +8 -8
  74. package/dist/{chunk-7RUJKCR4.js → chunk-KGDWDSNL.js} +2 -2
  75. package/dist/{chunk-6JQFIHZC.js → chunk-KVQBWI5T.js} +3 -3
  76. package/dist/{chunk-OVC5QXN5.js → chunk-LXQ5FBBD.js} +1 -1
  77. package/dist/{chunk-VE7TXLR4.js → chunk-M5ICYGHT.js} +3 -3
  78. package/dist/{chunk-YPUBA2FL.js → chunk-M5JDZ45W.js} +4 -4
  79. package/dist/{chunk-O3JDWNLU.js → chunk-MDEPU45E.js} +183 -28
  80. package/dist/{chunk-P2VIBGXA.js → chunk-MPWXGONV.js} +1 -1
  81. package/dist/{chunk-YC27PROF.js → chunk-NGDD6TXY.js} +20 -5
  82. package/dist/{chunk-G4GLCLKK.js → chunk-NQTHFF4W.js} +138 -17
  83. package/dist/{chunk-NOI3XTCY.js → chunk-OKXS7WDZ.js} +1 -1
  84. package/dist/{chunk-LPNJLKBQ.js → chunk-OLQRRFBX.js} +1 -1
  85. package/dist/{chunk-D6OODZCM.js → chunk-P7WQEVWA.js} +2 -2
  86. package/dist/{chunk-62VT3BPH.js → chunk-Q7E4I6UA.js} +28 -16
  87. package/dist/{chunk-BIH2Y2HP.js → chunk-R7437YI3.js} +2 -2
  88. package/dist/{chunk-RLW3JWDY.js → chunk-RHR6NARM.js} +2 -2
  89. package/dist/{chunk-WPX67AKT.js → chunk-SAXBC4AZ.js} +1 -1
  90. package/dist/{chunk-IPSRMLCJ.js → chunk-SIFVFP6T.js} +1 -1
  91. package/dist/{chunk-7OA34PNW.js → chunk-SLFABHW3.js} +40 -10
  92. package/dist/{chunk-AWVNAYGD.js → chunk-TY4JT7W3.js} +1 -1
  93. package/dist/{chunk-KJXUIPS4.js → chunk-UI36QSBI.js} +28 -16
  94. package/dist/{chunk-G6RRVJOG.js → chunk-VQKRG3AC.js} +6 -6
  95. package/dist/{chunk-ZKJ34T2F.js → chunk-WE2J62NC.js} +31 -17
  96. package/dist/{chunk-LHC45YUC.js → chunk-ZSZSSJCV.js} +1 -1
  97. package/dist/{chunk-BGBLLHZ4.js → chunk-ZVSKMPBZ.js} +1 -1
  98. package/dist/{reapply-PH5T4BGR.js → reapply-CW3MA66V.js} +9 -9
  99. package/dist/src/index.js +20 -20
  100. package/package.json +1 -1
  101. package/dist/chunk-5GB22QYL.js +0 -255
  102. package/dist/chunk-VYPJHGG6.js +0 -92
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  detectClaudeVersion
3
- } from "./chunk-IPSRMLCJ.js";
3
+ } from "./chunk-SIFVFP6T.js";
4
4
  import {
5
5
  ensureCodexTrustsPusharyHooks
6
- } from "./chunk-RLW3JWDY.js";
6
+ } from "./chunk-RHR6NARM.js";
7
7
  import {
8
8
  addClaudeMcpServer,
9
9
  addPusharyHooks,
10
10
  addPusharyToolPermissions
11
- } from "./chunk-G3OMOTJ4.js";
11
+ } from "./chunk-AXPCESYO.js";
12
12
  import {
13
13
  claudeUnprovenHolds,
14
14
  claudeWired,
15
15
  codexUnprovenHolds,
16
16
  codexWired,
17
17
  geminiWired
18
- } from "./chunk-WTJM7PSL.js";
18
+ } from "./chunk-6J2JC2RT.js";
19
19
  import {
20
20
  CLAUDE_HOOK_BINARY,
21
21
  CLAUDE_HOOK_EVENTS,
@@ -27,7 +27,7 @@ import {
27
27
  needsReregistration,
28
28
  registrationSignatures,
29
29
  supportedClaudeEvents
30
- } from "./chunk-MIXWMA73.js";
30
+ } from "./chunk-3EVPNIBE.js";
31
31
  import {
32
32
  CODEX_HOOK_BINARY,
33
33
  addCodexHookTrust,
@@ -47,7 +47,7 @@ import {
47
47
  registrationHolderOf,
48
48
  resolveGlobalBinary,
49
49
  vscodePluginMcp
50
- } from "./chunk-MZBRL5H5.js";
50
+ } from "./chunk-A2A2YTMG.js";
51
51
  import {
52
52
  readJsonSafe,
53
53
  writeFileAtomic,
@@ -4,14 +4,14 @@ import {
4
4
  } from "./chunk-XHKBHWLX.js";
5
5
  import {
6
6
  readControlMode
7
- } from "./chunk-D6OODZCM.js";
7
+ } from "./chunk-P7WQEVWA.js";
8
8
  import {
9
9
  getMachineId
10
- } from "./chunk-OVC5QXN5.js";
10
+ } from "./chunk-LXQ5FBBD.js";
11
11
  import {
12
12
  pusharyDir,
13
13
  resolveGlobalBinary
14
- } from "./chunk-MZBRL5H5.js";
14
+ } from "./chunk-A2A2YTMG.js";
15
15
  import {
16
16
  readJsonSafe,
17
17
  writeFileAtomic,
@@ -20,10 +20,14 @@ import {
20
20
  } from "./chunk-T7E75EKA.js";
21
21
  import {
22
22
  getApiKey
23
- } from "./chunk-R6OYCUNK.js";
23
+ } from "./chunk-GPEGOGRJ.js";
24
24
  import {
25
- getPackageVersion
26
- } from "./chunk-G4GLCLKK.js";
25
+ CLI_PACKAGE_NAMES,
26
+ cmdShimTarget,
27
+ getPackageVersion,
28
+ globalPackageFolder,
29
+ globalRootFor
30
+ } from "./chunk-NQTHFF4W.js";
27
31
 
28
32
  // src/daemon-lifecycle.ts
29
33
  import { dirname, join, win32 as win32Path } from "path";
@@ -279,6 +283,26 @@ WantedBy=default.target
279
283
  }
280
284
  return null;
281
285
  };
286
+ var WINDOWS_DAEMON_ENTRY_SEGMENTS = ["dist", "bin", "pushary-daemon.js"];
287
+ var WINDOWS_CMD_SHIM = /\.cmd$/i;
288
+ var readTextFile = (path) => readFileSync(path, "utf8");
289
+ var windowsShimTarget = (shim, readFile) => {
290
+ if (!WINDOWS_CMD_SHIM.test(shim)) return void 0;
291
+ try {
292
+ return cmdShimTarget(win32Path.dirname(shim), readFile(shim));
293
+ } catch {
294
+ return void 0;
295
+ }
296
+ };
297
+ var windowsPackageDaemonEntries = (globalPrefix) => {
298
+ const root = globalRootFor(globalPrefix, "win32");
299
+ return CLI_PACKAGE_NAMES.map((name) => win32Path.join(globalPackageFolder(root, name, "win32"), ...WINDOWS_DAEMON_ENTRY_SEGMENTS));
300
+ };
301
+ var windowsDaemonEntryCandidates = (shim, readFile) => {
302
+ const shimEntry = windowsShimTarget(shim, readFile);
303
+ const packageEntries = windowsPackageDaemonEntries(win32Path.dirname(shim));
304
+ return shimEntry === void 0 ? packageEntries : [shimEntry, ...packageEntries];
305
+ };
282
306
  var resolveDaemonServiceDefinition = (options = {}) => {
283
307
  const platform = options.platform ?? process.platform;
284
308
  const exists = options.entryExists ?? existsSync;
@@ -286,17 +310,7 @@ var resolveDaemonServiceDefinition = (options = {}) => {
286
310
  let daemonEntry = options.daemonEntry;
287
311
  if (!daemonEntry && globalBinary) {
288
312
  if (platform === "win32") {
289
- const globalRoot = win32Path.dirname(globalBinary);
290
- const candidate = win32Path.join(
291
- globalRoot,
292
- "node_modules",
293
- "@pushary",
294
- "agent-hooks",
295
- "dist",
296
- "bin",
297
- "pushary-daemon.js"
298
- );
299
- if (exists(candidate)) daemonEntry = candidate;
313
+ daemonEntry = windowsDaemonEntryCandidates(globalBinary, options.readFile ?? readTextFile).find((candidate) => exists(candidate));
300
314
  } else {
301
315
  try {
302
316
  const candidate = (options.realpath ?? realpathSync)(globalBinary);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-MZBRL5H5.js";
3
+ } from "./chunk-A2A2YTMG.js";
4
4
  import {
5
5
  readJsonSafe
6
6
  } from "./chunk-T7E75EKA.js";
@@ -9,7 +9,7 @@ import {
9
9
  SETUP_CONNECT_MODES,
10
10
  isSetupConnectMode,
11
11
  isValidApiKey
12
- } from "./chunk-G4GLCLKK.js";
12
+ } from "./chunk-NQTHFF4W.js";
13
13
 
14
14
  // src/setup/options.ts
15
15
  var AGENT_CHOICES = SETUP_AGENT_CHOICES;
@@ -9,17 +9,17 @@ import {
9
9
  reapplyGeminiSettings,
10
10
  reapplyVsCodePlugin,
11
11
  repairCodexHolds
12
- } from "./chunk-G6RRVJOG.js";
13
- import "./chunk-IPSRMLCJ.js";
14
- import "./chunk-RLW3JWDY.js";
15
- import "./chunk-G3OMOTJ4.js";
16
- import "./chunk-WTJM7PSL.js";
17
- import "./chunk-MIXWMA73.js";
12
+ } from "./chunk-VQKRG3AC.js";
13
+ import "./chunk-SIFVFP6T.js";
14
+ import "./chunk-RHR6NARM.js";
15
+ import "./chunk-AXPCESYO.js";
16
+ import "./chunk-6J2JC2RT.js";
17
+ import "./chunk-3EVPNIBE.js";
18
18
  import "./chunk-XHKBHWLX.js";
19
- import "./chunk-EUGNVLMG.js";
20
- import "./chunk-MZBRL5H5.js";
19
+ import "./chunk-EPCXUP3P.js";
20
+ import "./chunk-A2A2YTMG.js";
21
21
  import "./chunk-T7E75EKA.js";
22
- import "./chunk-G4GLCLKK.js";
22
+ import "./chunk-NQTHFF4W.js";
23
23
  export {
24
24
  ensureCodexTrustAfterReapply,
25
25
  inspectConfiguredManagedProviders,
package/dist/src/index.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  handlePreToolUse
3
- } from "../chunk-62VT3BPH.js";
4
- import "../chunk-UOQRM7JQ.js";
5
- import "../chunk-G3OMOTJ4.js";
6
- import "../chunk-5GB22QYL.js";
7
- import "../chunk-IRZG3HEU.js";
3
+ } from "../chunk-Q7E4I6UA.js";
4
+ import "../chunk-J5TIV3J6.js";
5
+ import "../chunk-AXPCESYO.js";
6
+ import "../chunk-CJVVKOSR.js";
7
+ import "../chunk-JU6W3XAU.js";
8
8
  import "../chunk-5OP5MQI7.js";
9
- import "../chunk-MIXWMA73.js";
9
+ import "../chunk-3EVPNIBE.js";
10
10
  import {
11
11
  fetchAccountPublicKey
12
- } from "../chunk-WPX67AKT.js";
12
+ } from "../chunk-SAXBC4AZ.js";
13
13
  import {
14
14
  fetchModeOverride,
15
15
  fetchModeState,
@@ -18,33 +18,33 @@ import {
18
18
  handlePostToolUse,
19
19
  handleStop,
20
20
  reportEvent
21
- } from "../chunk-U6RVDUJ5.js";
21
+ } from "../chunk-CULUZTWQ.js";
22
22
  import "../chunk-N6IOSZOE.js";
23
- import "../chunk-EUGNVLMG.js";
23
+ import "../chunk-EPCXUP3P.js";
24
24
  import {
25
25
  askUser,
26
26
  cancelQuestion,
27
27
  waitForAnswer
28
- } from "../chunk-YC27PROF.js";
29
- import "../chunk-N5MZH5A6.js";
28
+ } from "../chunk-NGDD6TXY.js";
29
+ import "../chunk-CVQYGMSR.js";
30
30
  import "../chunk-POFBE6ZY.js";
31
- import "../chunk-VE7TXLR4.js";
32
- import "../chunk-EEEJ2JIL.js";
33
- import "../chunk-DUQO4C4I.js";
34
- import "../chunk-OVC5QXN5.js";
31
+ import "../chunk-M5ICYGHT.js";
32
+ import "../chunk-2ABTSGFT.js";
33
+ import "../chunk-2OY3ZZ5N.js";
34
+ import "../chunk-LXQ5FBBD.js";
35
35
  import "../chunk-7QLSKOSU.js";
36
36
  import "../chunk-KZERVKTD.js";
37
- import "../chunk-62CVUUNU.js";
38
- import "../chunk-MZBRL5H5.js";
37
+ import "../chunk-DB3ONZB4.js";
38
+ import "../chunk-A2A2YTMG.js";
39
39
  import "../chunk-T7E75EKA.js";
40
40
  import {
41
41
  getApiKey,
42
42
  getBaseUrl
43
- } from "../chunk-R6OYCUNK.js";
44
- import "../chunk-YYCTF4Q5.js";
43
+ } from "../chunk-GPEGOGRJ.js";
44
+ import "../chunk-E4FJTUH4.js";
45
45
  import {
46
46
  resolvePolicy
47
- } from "../chunk-G4GLCLKK.js";
47
+ } from "../chunk-NQTHFF4W.js";
48
48
  export {
49
49
  askUser,
50
50
  cancelQuestion,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushary/agent-hooks",
3
- "version": "1.7.3",
3
+ "version": "1.8.0",
4
4
  "description": "Permission hooks for AI coding agents: route tool approvals through Pushary push notifications",
5
5
  "keywords": [
6
6
  "pushary",
@@ -1,255 +0,0 @@
1
- import {
2
- AUTO_DECISION_WINDOW_MS,
3
- canonicalGateInputs,
4
- claimThrottle,
5
- deriveToolTarget,
6
- permissionDeniedAction,
7
- releaseThrottle,
8
- reportEvent
9
- } from "./chunk-U6RVDUJ5.js";
10
- import {
11
- DEFAULT_SESSION
12
- } from "./chunk-N6IOSZOE.js";
13
- import {
14
- canonicalJson
15
- } from "./chunk-MZBRL5H5.js";
16
- import {
17
- writeFileAtomic
18
- } from "./chunk-T7E75EKA.js";
19
- import {
20
- BLOCKED_ACTION_GRANT_TTL_SECONDS,
21
- blockedActionIdentity,
22
- machineDecisionFor,
23
- shouldDeferToNativeMode,
24
- wireVerdictFor
25
- } from "./chunk-G4GLCLKK.js";
26
-
27
- // src/machine-decision-audit.ts
28
- import { basename } from "path";
29
- var reportMachineDenial = async (input, verdict, agent) => {
30
- const decision = machineDecisionFor(wireVerdictFor(verdict, 0));
31
- if (!decision) return;
32
- const sessionKey = input.session_id || DEFAULT_SESSION;
33
- const toolTarget = deriveToolTarget(input.tool_name, input.tool_input);
34
- const throttleKey = `machinedecision:${agent.type}:${sessionKey}:${input.tool_name}:${decision.origin}:${toolTarget ?? ""}`;
35
- const throttle = claimThrottle(throttleKey, AUTO_DECISION_WINDOW_MS);
36
- if (throttle === "throttled") return;
37
- if (throttle === "unavailable") {
38
- console.error("[Pushary] Could not access the audit throttle; reporting this denial without deduplication.");
39
- }
40
- try {
41
- const response = await reportEvent({
42
- event: "permission_denied",
43
- occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
44
- toolUseId: input.tool_use_id,
45
- agentType: agent.type,
46
- agentName: `${agent.label} - ${basename(input.cwd ?? process.cwd())}`,
47
- action: permissionDeniedAction(input.tool_name),
48
- sessionId: input.session_id,
49
- decisionSource: "policy_auto",
50
- decisionOrigin: decision.origin,
51
- decisionOutcome: decision.outcome,
52
- toolName: input.tool_name,
53
- toolTarget
54
- }, { maxAttempts: 1, timeoutMs: 800, requireOk: true, skipDrain: true });
55
- if (response?.ok !== true) throw new Error("Audit delivery was not acknowledged");
56
- } catch {
57
- console.error("[Pushary] Could not record the machine denial. The action remains blocked; its audit delivery will be retried on the next matching denial.");
58
- if (throttle === "passed") {
59
- try {
60
- releaseThrottle(throttleKey);
61
- } catch {
62
- console.error("[Pushary] Could not reset the failed audit throttle.");
63
- }
64
- }
65
- }
66
- };
67
-
68
- // src/native-defer.ts
69
- var nativeDeferOptions = () => {
70
- const respect = process.env.PUSHARY_RESPECT_PERMISSION_MODE;
71
- const bypass = process.env.PUSHARY_DEFER_BYPASS;
72
- return {
73
- respectPermissionMode: !(respect === "0" || respect === "false"),
74
- deferBypass: bypass === "1" || bypass === "true"
75
- };
76
- };
77
- var defersToNativeMode = (permissionMode, toolName) => shouldDeferToNativeMode(permissionMode, toolName, nativeDeferOptions());
78
-
79
- // src/codex-call-decision.ts
80
- import { createHash } from "crypto";
81
- import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "fs";
82
- import { tmpdir, userInfo } from "os";
83
- import { join } from "path";
84
- var CODEX_DECISION_TTL_MS = 60 * 1e3;
85
- var userScope = () => {
86
- try {
87
- const info = userInfo();
88
- const id = typeof info.uid === "number" && info.uid >= 0 ? String(info.uid) : info.username;
89
- return id.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, 128) || "default";
90
- } catch {
91
- return "default";
92
- }
93
- };
94
- var decisionDir = () => join(tmpdir(), `pushary-codex-decisions-${userScope()}`);
95
- var decisionFile = (key) => join(decisionDir(), key);
96
- var PRESENTATION_ONLY_INPUT_KEYS = ["description"];
97
- var identifyingToolInput = (toolInput) => {
98
- if (!toolInput) return {};
99
- const identifying = {};
100
- for (const [key, value] of Object.entries(toolInput)) {
101
- if (PRESENTATION_ONLY_INPUT_KEYS.includes(key)) continue;
102
- identifying[key] = value;
103
- }
104
- return identifying;
105
- };
106
- var codexCallKey = (identity) => {
107
- if (!identity.sessionId || !identity.turnId || !identity.toolName) return null;
108
- const material = canonicalJson([
109
- identity.sessionId,
110
- identity.turnId,
111
- identity.toolName,
112
- identifyingToolInput(identity.toolInput)
113
- ]);
114
- return createHash("sha256").update(material, "utf-8").digest("hex").slice(0, 32);
115
- };
116
- var parseDecision = (raw) => {
117
- try {
118
- const parsed = JSON.parse(raw);
119
- if (parsed.kind === "approved") {
120
- return typeof parsed.toolUseId === "string" && parsed.toolUseId ? { kind: "approved", toolUseId: parsed.toolUseId } : null;
121
- }
122
- if (parsed.kind === "handled") return { kind: "handled" };
123
- if (parsed.kind === "denied") {
124
- return { kind: "denied", reason: typeof parsed.reason === "string" ? parsed.reason : "" };
125
- }
126
- return null;
127
- } catch {
128
- return null;
129
- }
130
- };
131
- var sweepExpired = (dir, nowMs) => {
132
- try {
133
- for (const name of readdirSync(dir)) {
134
- const path = join(dir, name);
135
- try {
136
- if (nowMs - statSync(path).mtimeMs >= CODEX_DECISION_TTL_MS) rmSync(path, { force: true });
137
- } catch {
138
- continue;
139
- }
140
- }
141
- } catch {
142
- return;
143
- }
144
- };
145
- var recordCodexCallDecision = (key, decision) => {
146
- if (!key) return;
147
- try {
148
- const dir = decisionDir();
149
- if (!existsSync(dir)) mkdirSync(dir, { recursive: true, mode: 448 });
150
- else sweepExpired(dir, Date.now());
151
- writeFileSync(decisionFile(key), JSON.stringify(decision), { encoding: "utf-8", mode: 384 });
152
- } catch {
153
- return;
154
- }
155
- };
156
- var consumeCodexCallDecision = (key) => {
157
- if (!key) return null;
158
- const path = decisionFile(key);
159
- try {
160
- const fresh = Date.now() - statSync(path).mtimeMs < CODEX_DECISION_TTL_MS;
161
- const raw = readFileSync(path, "utf-8");
162
- rmSync(path, { force: true });
163
- return fresh ? parseDecision(raw) : null;
164
- } catch {
165
- return null;
166
- }
167
- };
168
-
169
- // src/blocked-action-hint.ts
170
- import { createHash as createHash2 } from "crypto";
171
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2 } from "fs";
172
- import { tmpdir as tmpdir2 } from "os";
173
- import { join as join2 } from "path";
174
- var BLOCKED_ACTION_HINT_TTL_MS = BLOCKED_ACTION_GRANT_TTL_SECONDS * 1e3;
175
- var FINGERPRINT = /^[0-9a-f]{64}$/;
176
- var isFingerprint = (value) => typeof value === "string" && FINGERPRINT.test(value);
177
- var blockedActionSubject = (source, sessionId, toolName, toolInput, cwd) => {
178
- if (source !== "claude") return { source, sessionId, toolName, toolInput };
179
- return cwd ? { source, sessionId, cwd, toolName, toolInput } : null;
180
- };
181
- var blockedActionFingerprint = ({ source = "claude", sessionId, toolName, toolInput, cwd }) => {
182
- if (!sessionId || !toolInput) return null;
183
- const canonical = canonicalGateInputs(source, toolName, [toolInput], cwd);
184
- if (!canonical || canonical.toolInputs.length !== 1) return null;
185
- const [canonicalInput] = canonical.toolInputs;
186
- if (!canonicalInput) return null;
187
- const subject = blockedActionSubject(source, sessionId, canonical.toolName, canonicalInput, cwd);
188
- return subject ? createHash2("sha256").update(blockedActionIdentity(subject), "utf8").digest("hex") : null;
189
- };
190
- var hintDir = () => join2(tmpdir2(), `pushary-blocked-action-hints-${userScope()}`);
191
- var hintFile = (fingerprint) => join2(hintDir(), fingerprint);
192
- var isExpired = (mtimeMs, nowMs) => nowMs - mtimeMs >= BLOCKED_ACTION_HINT_TTL_MS;
193
- var sweepExpired2 = (dir, nowMs) => {
194
- try {
195
- for (const name of readdirSync2(dir)) {
196
- const path = join2(dir, name);
197
- try {
198
- if (isExpired(statSync2(path).mtimeMs, nowMs)) rmSync2(path, { force: true });
199
- } catch {
200
- continue;
201
- }
202
- }
203
- } catch {
204
- return;
205
- }
206
- };
207
- var recordBlockedActionHint = (fingerprint) => {
208
- if (!isFingerprint(fingerprint)) return false;
209
- try {
210
- const dir = hintDir();
211
- if (!existsSync2(dir)) mkdirSync2(dir, { recursive: true, mode: 448 });
212
- else sweepExpired2(dir, Date.now());
213
- writeFileAtomic(hintFile(fingerprint), JSON.stringify({ fingerprint }), 384);
214
- return true;
215
- } catch {
216
- return false;
217
- }
218
- };
219
- var hasBlockedActionHint = (fingerprint) => {
220
- if (!isFingerprint(fingerprint)) return false;
221
- const path = hintFile(fingerprint);
222
- try {
223
- const stat = statSync2(path);
224
- if (!stat.isFile()) return false;
225
- if (isExpired(stat.mtimeMs, Date.now())) {
226
- rmSync2(path, { force: true });
227
- return false;
228
- }
229
- const parsed = JSON.parse(readFileSync2(path, "utf-8"));
230
- return parsed?.fingerprint === fingerprint;
231
- } catch {
232
- return false;
233
- }
234
- };
235
- var forgetBlockedActionHint = (fingerprint) => {
236
- if (!isFingerprint(fingerprint)) return;
237
- try {
238
- rmSync2(hintFile(fingerprint), { force: true });
239
- } catch {
240
- return;
241
- }
242
- };
243
-
244
- export {
245
- reportMachineDenial,
246
- defersToNativeMode,
247
- userScope,
248
- codexCallKey,
249
- recordCodexCallDecision,
250
- consumeCodexCallDecision,
251
- blockedActionFingerprint,
252
- recordBlockedActionHint,
253
- hasBlockedActionHint,
254
- forgetBlockedActionHint
255
- };
@@ -1,92 +0,0 @@
1
- import {
2
- NpmMissingError
3
- } from "./chunk-MZBRL5H5.js";
4
- import {
5
- NPX_LATEST_COMMAND
6
- } from "./chunk-YYCTF4Q5.js";
7
-
8
- // src/setup/agent-failure.ts
9
- var AgentConfigError = class extends Error {
10
- kind;
11
- filePath;
12
- constructor(kind, filePath, message) {
13
- super(message);
14
- this.name = "AgentConfigError";
15
- this.kind = kind;
16
- this.filePath = filePath;
17
- }
18
- };
19
- var configFailureKind = (readFailure) => readFailure === "unparseable" ? "config-unparseable" : "config-unreadable";
20
- var AGENT_FAILURE_DETAILS = {
21
- "not-wired": "reported success but its config is not there.",
22
- "app-account-mismatch": "Mac app hooks kept, but their Pushary account could not be matched to this setup."
23
- };
24
- var describedAgentFailure = (agent, kind) => ({
25
- agent,
26
- kind,
27
- detail: AGENT_FAILURE_DETAILS[kind],
28
- remedy: "retry-agent"
29
- });
30
- var agentFailureFromError = (agent, error, describeError) => ({
31
- agent,
32
- kind: error instanceof AgentConfigError ? error.kind : "installer-error",
33
- detail: describeError(error),
34
- remedy: error instanceof NpmMissingError ? "install-node" : "retry-agent"
35
- });
36
- var retryAgentCommand = (agent) => `${NPX_LATEST_COMMAND} setup --agents ${agent}`;
37
- var REMAINING_AGENTS_CONTINUE = "Other agents will continue. Re-run setup to retry.";
38
- var afterAgentFailureNote = (agentsStillToSetUp) => agentsStillToSetUp > 0 ? REMAINING_AGENTS_CONTINUE : null;
39
- var failedAgentsContext = (configuredAgentNames) => configuredAgentNames.length > 0 ? `(configured: ${configuredAgentNames.join(", ")})` : null;
40
- var agentFailureWire = (failures) => failures.map(({ agent, kind }) => ({ agent, kind }));
41
-
42
- // src/diagnostics/service-runtime.ts
43
- var unescapeXml = (value) => value.replaceAll("&quot;", '"').replaceAll("&apos;", "'").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
44
- var unquoteSystemd = (value) => value.replaceAll('\\"', '"').replaceAll("\\\\", "\\").replaceAll("%%", "%");
45
- var readServiceExecPath = (contents, platform) => {
46
- if (platform === "darwin") {
47
- const program = contents.match(/<key>ProgramArguments<\/key>\s*<array>\s*<string>([^<]*)<\/string>/)?.[1];
48
- return program ? unescapeXml(program) : null;
49
- }
50
- if (platform === "linux") {
51
- const exec = contents.match(/^ExecStart="((?:[^"\\]|\\.)*)"/m)?.[1];
52
- return exec ? unquoteSystemd(exec) : null;
53
- }
54
- if (platform === "win32") {
55
- const command = contents.match(/<Command>([^<]*)<\/Command>/)?.[1];
56
- return command ? unescapeXml(command) : null;
57
- }
58
- return null;
59
- };
60
- var MANAGER_SEGMENTS = [
61
- [".nvm", "nvm"],
62
- ["nvm", "nvm"],
63
- ["fnm", "fnm"],
64
- [".fnm", "fnm"],
65
- [".volta", "volta"],
66
- ["volta", "volta"],
67
- [".asdf", "asdf"],
68
- ["asdf", "asdf"]
69
- ];
70
- var versionManagerOf = (execPath) => {
71
- const segments = execPath.split(/[/\\]/);
72
- for (const segment of segments) {
73
- const hit = MANAGER_SEGMENTS.find(([name]) => name === segment);
74
- if (hit) return hit[1];
75
- }
76
- return null;
77
- };
78
- var describeVersionManagerPin = (execPath, manager) => `The background service is pinned to ${execPath}, which ${manager} manages. Switching Node versions strands it; run pushary daemon install afterwards.`;
79
-
80
- export {
81
- AgentConfigError,
82
- configFailureKind,
83
- describedAgentFailure,
84
- agentFailureFromError,
85
- retryAgentCommand,
86
- afterAgentFailureNote,
87
- failedAgentsContext,
88
- agentFailureWire,
89
- readServiceExecPath,
90
- versionManagerOf,
91
- describeVersionManagerPin
92
- };