@pushary/agent-hooks 1.9.46 → 1.9.48

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 (103) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/bin/pushary-bell-hook.js +25 -25
  3. package/dist/bin/pushary-bell.js +9 -9
  4. package/dist/bin/pushary-claude.js +24 -24
  5. package/dist/bin/pushary-clean.js +142 -76
  6. package/dist/bin/pushary-codex-bridge.js +18 -18
  7. package/dist/bin/pushary-codex-hook.js +30 -30
  8. package/dist/bin/pushary-codex-session.js +22 -19
  9. package/dist/bin/pushary-codex.js +12 -12
  10. package/dist/bin/pushary-connect.js +24 -24
  11. package/dist/bin/pushary-cowork.js +5 -5
  12. package/dist/bin/pushary-daemon.js +32 -32
  13. package/dist/bin/pushary-disconnect.js +37 -30
  14. package/dist/bin/pushary-doctor.js +34 -34
  15. package/dist/bin/pushary-elicitation-hook.js +25 -25
  16. package/dist/bin/pushary-gemini-bridge.js +13 -13
  17. package/dist/bin/pushary-gemini-hook.js +27 -27
  18. package/dist/bin/pushary-hook.js +29 -29
  19. package/dist/bin/pushary-login.js +12 -12
  20. package/dist/bin/pushary-logout.js +24 -24
  21. package/dist/bin/pushary-mcp.js +9 -9
  22. package/dist/bin/pushary-mode.js +12 -12
  23. package/dist/bin/pushary-notification-hook.js +24 -24
  24. package/dist/bin/pushary-opencode-hook.js +26 -26
  25. package/dist/bin/pushary-permission-denied-hook.js +29 -29
  26. package/dist/bin/pushary-permission-hook.js +28 -28
  27. package/dist/bin/pushary-post-hook.js +24 -24
  28. package/dist/bin/pushary-prompt-hook.js +24 -24
  29. package/dist/bin/pushary-session-end-hook.js +24 -24
  30. package/dist/bin/pushary-session-start-hook.js +28 -28
  31. package/dist/bin/pushary-setup.js +62 -41
  32. package/dist/bin/pushary-stats.js +5 -5
  33. package/dist/bin/pushary-status.js +26 -26
  34. package/dist/bin/pushary-stop-hook.js +24 -24
  35. package/dist/bin/pushary-stopfailure-hook.js +24 -24
  36. package/dist/bin/pushary-suggestions.js +12 -12
  37. package/dist/bin/pushary-transcript-register.js +17 -17
  38. package/dist/bin/pushary-transcripts.js +7 -7
  39. package/dist/bin/pushary-upgrade.js +30 -30
  40. package/dist/bin/pushary-wait.js +12 -12
  41. package/dist/bin/pushary.js +6 -6
  42. package/dist/{chunk-W7MXYDGP.js → chunk-33QBP3M5.js} +2 -2
  43. package/dist/{chunk-HTQPDODV.js → chunk-3KHZZOT5.js} +4 -4
  44. package/dist/{chunk-CJKEU4EZ.js → chunk-755V3VD7.js} +4 -4
  45. package/dist/{chunk-WYD4PYTL.js → chunk-7S5HYDAO.js} +9 -9
  46. package/dist/{chunk-LA4S2KIM.js → chunk-A45ILEPI.js} +3 -3
  47. package/dist/{chunk-ON2WCBIN.js → chunk-AX7B7RSC.js} +10 -10
  48. package/dist/{chunk-EW52AGOV.js → chunk-B2DU67G6.js} +4 -4
  49. package/dist/{chunk-EP4MD6TH.js → chunk-C3HH6VQP.js} +5 -5
  50. package/dist/{chunk-BKJP2MQN.js → chunk-CIJV7IQU.js} +6 -6
  51. package/dist/{chunk-35TUEZ5E.js → chunk-CQ4VDI27.js} +3 -3
  52. package/dist/{chunk-UCRG5QGN.js → chunk-CQWXMLHZ.js} +1 -1
  53. package/dist/{chunk-FQWI6XQG.js → chunk-DQPFQGIN.js} +1 -1
  54. package/dist/{chunk-CA6F44OF.js → chunk-DR2L7VV4.js} +5 -5
  55. package/dist/{chunk-XAMFOUXA.js → chunk-EGARDTA5.js} +2 -2
  56. package/dist/{chunk-P2FHZ65U.js → chunk-EOT33AJN.js} +1 -1
  57. package/dist/{chunk-FMDGUCER.js → chunk-FFIITUQJ.js} +19 -10
  58. package/dist/{chunk-5O6GB64K.js → chunk-GFQT4KJO.js} +2 -2
  59. package/dist/{chunk-ULEX43F7.js → chunk-GLM263DW.js} +1 -1
  60. package/dist/{chunk-ZYS4UHEC.js → chunk-GMK24GEO.js} +4 -4
  61. package/dist/{chunk-I5EQ5NJD.js → chunk-GOSHI63C.js} +8 -8
  62. package/dist/{chunk-HX34VBPE.js → chunk-GYHX4NIW.js} +4 -4
  63. package/dist/{chunk-2UABJ75E.js → chunk-HF66SU3D.js} +2 -2
  64. package/dist/{chunk-GG6C4CHH.js → chunk-I7B4X232.js} +2 -2
  65. package/dist/{chunk-MOUUDZOZ.js → chunk-ICSA7SWY.js} +1 -1
  66. package/dist/{chunk-KJNWVAS6.js → chunk-IRTPMVIS.js} +3 -3
  67. package/dist/{chunk-JPGY5LSF.js → chunk-IVQA2XWE.js} +5 -5
  68. package/dist/{chunk-UI3WDOV3.js → chunk-IXWXGQRX.js} +2 -2
  69. package/dist/{chunk-NWZZTHWF.js → chunk-JN64AI53.js} +1 -1
  70. package/dist/{chunk-FQW7AV6U.js → chunk-JRB4U3S6.js} +3 -3
  71. package/dist/{chunk-T623UG5T.js → chunk-K6X6B76U.js} +3 -3
  72. package/dist/{chunk-GQZF6DPL.js → chunk-KRIG552M.js} +1 -1
  73. package/dist/{chunk-EKDSF3IX.js → chunk-LMFKL76J.js} +1 -1
  74. package/dist/{chunk-VTF7LKDB.js → chunk-LVA2RJNM.js} +5 -5
  75. package/dist/{chunk-SEKQAYVP.js → chunk-LZW7O3G4.js} +2 -2
  76. package/dist/{chunk-NULG2ZUG.js → chunk-MVW5KW6R.js} +4 -4
  77. package/dist/{chunk-PZPYL65I.js → chunk-N3GB5RQH.js} +1 -1
  78. package/dist/{chunk-2PTJHEX4.js → chunk-OJSWXJRB.js} +8 -2
  79. package/dist/{chunk-ELLN4XAF.js → chunk-Q7GNNQZ2.js} +2 -2
  80. package/dist/{chunk-NO3ADUD4.js → chunk-RZKVGP2P.js} +1 -1
  81. package/dist/{chunk-MBB4XJIN.js → chunk-S7ALO6PR.js} +7 -7
  82. package/dist/{chunk-UP2RNIHL.js → chunk-TIVYEX3X.js} +4 -4
  83. package/dist/{chunk-LEMQA4HM.js → chunk-TK23JLC3.js} +5 -5
  84. package/dist/{chunk-2X3PPRNC.js → chunk-TVBQTGM7.js} +3 -3
  85. package/dist/{chunk-LNO25UX4.js → chunk-V7VGDSNZ.js} +6 -6
  86. package/dist/{chunk-7XSIUY5F.js → chunk-W4H427YD.js} +1 -1
  87. package/dist/{chunk-WN3MDHAM.js → chunk-WNEEQ7GJ.js} +1 -1
  88. package/dist/{chunk-ZGGSQTCO.js → chunk-WSSBT75T.js} +1 -1
  89. package/dist/{chunk-G227SH2O.js → chunk-XDM6S75V.js} +2 -2
  90. package/dist/{chunk-UGXRDY3O.js → chunk-XOHT5UCY.js} +5 -5
  91. package/dist/{chunk-2ZD53EQW.js → chunk-XRFEWXGR.js} +2 -2
  92. package/dist/{chunk-5NXD6ZHQ.js → chunk-XTZ4HQKG.js} +2 -2
  93. package/dist/{chunk-2VNHP2OE.js → chunk-YUBWJHWE.js} +1 -1
  94. package/dist/{chunk-EDSXF7NV.js → chunk-YWFL5ANU.js} +112 -30
  95. package/dist/{chunk-PGULTXDJ.js → chunk-ZBNRG4LZ.js} +5 -5
  96. package/dist/{chunk-OI6YNNI5.js → chunk-ZRQPJHNJ.js} +8 -4
  97. package/dist/{chunk-2IFTZZ5K.js → chunk-ZSAQSKSK.js} +1 -1
  98. package/dist/{global-upgrade-A7EADTOL.js → global-upgrade-RKM4H55J.js} +6 -6
  99. package/dist/{paths-UIPHTZH4.js → paths-BHI23V4J.js} +2 -2
  100. package/dist/{reapply-JAT4DS6G.js → reapply-AZZZOU7B.js} +20 -20
  101. package/dist/src/index.js +19 -19
  102. package/dist/{upgrade-lock-YUSXU5I5.js → upgrade-lock-IJL5SSTD.js} +3 -3
  103. package/package.json +1 -1
@@ -10,7 +10,7 @@ import {
10
10
  isSetupConnectMode,
11
11
  isValidApiKey,
12
12
  normalizeAgentId
13
- } from "./chunk-EDSXF7NV.js";
13
+ } from "./chunk-YWFL5ANU.js";
14
14
 
15
15
  // src/setup/options.ts
16
16
  var AGENT_CHOICES = SETUP_AGENT_CHOICES;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ensureCodexTrustsPusharyHooks
3
- } from "./chunk-2ZD53EQW.js";
3
+ } from "./chunk-XRFEWXGR.js";
4
4
  import {
5
5
  OPENCODE_HOOK_BINARY,
6
6
  agentHookOwner,
@@ -9,7 +9,7 @@ import {
9
9
  openCodeHookArgv,
10
10
  openCodePluginDir,
11
11
  openCodeWired
12
- } from "./chunk-VTF7LKDB.js";
12
+ } from "./chunk-LVA2RJNM.js";
13
13
  import {
14
14
  addClaudeMcpServer,
15
15
  addCompatibleHooks,
@@ -17,7 +17,7 @@ import {
17
17
  addPusharyToolPermissions,
18
18
  compatibleConfigFile,
19
19
  hasCompatibleHooks
20
- } from "./chunk-OI6YNNI5.js";
20
+ } from "./chunk-ZRQPJHNJ.js";
21
21
  import {
22
22
  claudeUnprovenHolds,
23
23
  claudeWired,
@@ -25,7 +25,7 @@ import {
25
25
  codexWired,
26
26
  geminiWired,
27
27
  planHooks
28
- } from "./chunk-EP4MD6TH.js";
28
+ } from "./chunk-C3HH6VQP.js";
29
29
  import {
30
30
  CLAUDE_HOOK_BINARY,
31
31
  CLAUDE_HOOK_EVENTS,
@@ -36,7 +36,7 @@ import {
36
36
  needsReregistration,
37
37
  registrationSignatures,
38
38
  supportedClaudeEvents
39
- } from "./chunk-35TUEZ5E.js";
39
+ } from "./chunk-CQ4VDI27.js";
40
40
  import {
41
41
  detectClaudeVersion
42
42
  } from "./chunk-RIVNNBEK.js";
@@ -63,7 +63,7 @@ import {
63
63
  resolveGlobalBinDir,
64
64
  resolveGlobalBinary,
65
65
  vscodePluginMcp
66
- } from "./chunk-EW52AGOV.js";
66
+ } from "./chunk-B2DU67G6.js";
67
67
  import {
68
68
  readJsonSafe,
69
69
  writeFileAtomic,
@@ -73,7 +73,7 @@ import {
73
73
  HOOK_COMPATIBLE_PROFILES,
74
74
  isCompatibleAgentType,
75
75
  isRecord
76
- } from "./chunk-EDSXF7NV.js";
76
+ } from "./chunk-YWFL5ANU.js";
77
77
 
78
78
  // src/reapply.ts
79
79
  import { dirname, join } from "path";
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  macAppBridgeAvailable
3
- } from "./chunk-VTF7LKDB.js";
3
+ } from "./chunk-LVA2RJNM.js";
4
4
  import {
5
5
  keyPrefix
6
- } from "./chunk-LA4S2KIM.js";
6
+ } from "./chunk-A45ILEPI.js";
7
7
  import {
8
8
  bridgeAgentKey
9
- } from "./chunk-EW52AGOV.js";
9
+ } from "./chunk-B2DU67G6.js";
10
10
  import {
11
11
  readJsonSafe
12
12
  } from "./chunk-AQFEP65J.js";
13
13
  import {
14
14
  isValidApiKey
15
- } from "./chunk-EDSXF7NV.js";
15
+ } from "./chunk-YWFL5ANU.js";
16
16
 
17
17
  // src/shared-mcp-key.ts
18
18
  var asRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  MCP_BRIDGE_BINARY
3
- } from "./chunk-XAMFOUXA.js";
3
+ } from "./chunk-EGARDTA5.js";
4
4
  import {
5
5
  KEY_FILE_MODE
6
- } from "./chunk-LA4S2KIM.js";
6
+ } from "./chunk-A45ILEPI.js";
7
7
  import {
8
8
  NpmInstallError,
9
9
  NpmMissingError,
10
10
  NpmPermissionError
11
- } from "./chunk-EW52AGOV.js";
11
+ } from "./chunk-B2DU67G6.js";
12
12
  import {
13
13
  readJsonSafe,
14
14
  writeFileAtomic,
@@ -16,10 +16,10 @@ import {
16
16
  } from "./chunk-AQFEP65J.js";
17
17
  import {
18
18
  NPX_LATEST_COMMAND
19
- } from "./chunk-WN3MDHAM.js";
19
+ } from "./chunk-WNEEQ7GJ.js";
20
20
  import {
21
21
  readSetupAgentFailures
22
- } from "./chunk-EDSXF7NV.js";
22
+ } from "./chunk-YWFL5ANU.js";
23
23
 
24
24
  // src/instruction-file.ts
25
25
  import { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync } from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pusharyFetch
3
- } from "./chunk-KJNWVAS6.js";
3
+ } from "./chunk-IRTPMVIS.js";
4
4
  import {
5
5
  NetworkError
6
6
  } from "./chunk-7QLSKOSU.js";
@@ -9,11 +9,11 @@ import {
9
9
  } from "./chunk-KZERVKTD.js";
10
10
  import {
11
11
  getBaseUrl
12
- } from "./chunk-7XSIUY5F.js";
12
+ } from "./chunk-W4H427YD.js";
13
13
  import {
14
14
  isValidApiKey,
15
15
  normalizeKeyScope
16
- } from "./chunk-EDSXF7NV.js";
16
+ } from "./chunk-YWFL5ANU.js";
17
17
 
18
18
  // src/session.ts
19
19
  var samePusharyAccount = (left, right) => left.kind === "ok" && right.kind === "ok" && left.identity.workspaceId !== "" && left.identity.workspaceId === right.identity.workspaceId && left.identity.siteId === right.identity.siteId;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  announceSubscriptionRequired,
3
3
  isDeferAnswer
4
- } from "./chunk-GQZF6DPL.js";
4
+ } from "./chunk-KRIG552M.js";
5
5
  import {
6
6
  AUTO_DECISION_WINDOW_MS,
7
7
  DEFAULT_SESSION,
@@ -10,24 +10,24 @@ import {
10
10
  permissionDeniedAction,
11
11
  releaseThrottle,
12
12
  reportEvent
13
- } from "./chunk-WYD4PYTL.js";
13
+ } from "./chunk-7S5HYDAO.js";
14
14
  import {
15
15
  askUser,
16
16
  isDecisionStopped,
17
17
  waitForQuestion
18
- } from "./chunk-UGXRDY3O.js";
18
+ } from "./chunk-XOHT5UCY.js";
19
19
  import {
20
20
  SubscriptionRequiredError
21
- } from "./chunk-FQW7AV6U.js";
21
+ } from "./chunk-JRB4U3S6.js";
22
22
  import {
23
23
  getMachineId
24
- } from "./chunk-ULEX43F7.js";
24
+ } from "./chunk-GLM263DW.js";
25
25
  import {
26
26
  machineDecisionFor,
27
27
  parseAgentQuestionAnswers,
28
28
  shouldDeferToNativeMode,
29
29
  wireVerdictFor
30
- } from "./chunk-EDSXF7NV.js";
30
+ } from "./chunk-YWFL5ANU.js";
31
31
 
32
32
  // src/machine-decision-audit.ts
33
33
  import { basename } from "path";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  NPX_LATEST_COMMAND
3
- } from "./chunk-WN3MDHAM.js";
3
+ } from "./chunk-WNEEQ7GJ.js";
4
4
 
5
5
  // src/config.ts
6
6
  import { readFileSync } from "fs";
@@ -2,7 +2,7 @@ import {
2
2
  DISCONNECT_AGENT_IDS,
3
3
  SETUP_AGENT_CHOICES,
4
4
  isApprovalMode
5
- } from "./chunk-EDSXF7NV.js";
5
+ } from "./chunk-YWFL5ANU.js";
6
6
 
7
7
  // src/cli/mode-request.ts
8
8
  var parseDuration = (value) => {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readTranscriptPreference
3
- } from "./chunk-LA4S2KIM.js";
3
+ } from "./chunk-A45ILEPI.js";
4
4
 
5
5
  // src/transcript-setting.ts
6
6
  var transcriptEnvironmentPreference = () => {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  CODEX_HOOK_STATUS
3
- } from "./chunk-2ZD53EQW.js";
3
+ } from "./chunk-XRFEWXGR.js";
4
4
  import {
5
5
  NPX_LATEST_COMMAND
6
- } from "./chunk-WN3MDHAM.js";
6
+ } from "./chunk-WNEEQ7GJ.js";
7
7
 
8
8
  // src/setup/codex-trust.ts
9
9
  var CODEX_TRUST_TELEMETRY = {
@@ -5,18 +5,18 @@ import {
5
5
  import {
6
6
  SubscriptionRequiredError,
7
7
  callMcpTool
8
- } from "./chunk-FQW7AV6U.js";
8
+ } from "./chunk-JRB4U3S6.js";
9
9
  import {
10
10
  installNetworkDefaults,
11
11
  isNetworkFailure
12
- } from "./chunk-KJNWVAS6.js";
12
+ } from "./chunk-IRTPMVIS.js";
13
13
  import {
14
14
  clientReportClaims
15
- } from "./chunk-EW52AGOV.js";
15
+ } from "./chunk-B2DU67G6.js";
16
16
  import {
17
17
  getApiKey,
18
18
  getBaseUrl
19
- } from "./chunk-7XSIUY5F.js";
19
+ } from "./chunk-W4H427YD.js";
20
20
  import {
21
21
  ASK_AGENT_NAME_MAX,
22
22
  CLIENT_REPORT_PATH,
@@ -26,7 +26,7 @@ import {
26
26
  localRepoKey,
27
27
  normalizeRepoRemote,
28
28
  truncateLine
29
- } from "./chunk-EDSXF7NV.js";
29
+ } from "./chunk-YWFL5ANU.js";
30
30
 
31
31
  // src/client-report-claim.ts
32
32
  import { createHash } from "crypto";
@@ -8,10 +8,10 @@ import {
8
8
  codexHooksJsonIn,
9
9
  isPusharyCodexCommand,
10
10
  resolvePathBinary
11
- } from "./chunk-EW52AGOV.js";
11
+ } from "./chunk-B2DU67G6.js";
12
12
  import {
13
13
  getPackageVersion
14
- } from "./chunk-EDSXF7NV.js";
14
+ } from "./chunk-YWFL5ANU.js";
15
15
 
16
16
  // src/codex-app-server.ts
17
17
  import { existsSync, realpathSync } from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-EW52AGOV.js";
3
+ } from "./chunk-B2DU67G6.js";
4
4
  import {
5
5
  readJsonSafe,
6
6
  writeFileAtomic
@@ -13,7 +13,7 @@ import {
13
13
  serializeDeclinedAgents,
14
14
  withDeclinedAgent,
15
15
  withoutDeclinedAgent
16
- } from "./chunk-EDSXF7NV.js";
16
+ } from "./chunk-YWFL5ANU.js";
17
17
 
18
18
  // src/declined-agents-file.ts
19
19
  import { join } from "path";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getBaseUrl
3
- } from "./chunk-7XSIUY5F.js";
3
+ } from "./chunk-W4H427YD.js";
4
4
 
5
5
  // src/transcript-api.ts
6
6
  var fetchTranscriptRecipients = async (apiKey, baseUrl = getBaseUrl()) => {
@@ -1043,6 +1043,23 @@ var shellWordsOf = (command) => {
1043
1043
  finishWord();
1044
1044
  return words;
1045
1045
  };
1046
+ var basenameOf = (token) => {
1047
+ const slash = Math.max(token.lastIndexOf("/"), token.lastIndexOf("\\"));
1048
+ return slash === -1 ? token : token.slice(slash + 1);
1049
+ };
1050
+ var TRUSTED_EXE_PREFIXES = [
1051
+ "/bin/",
1052
+ "/sbin/",
1053
+ "/usr/bin/",
1054
+ "/usr/sbin/",
1055
+ "/usr/local/bin/",
1056
+ "/opt/homebrew/bin/"
1057
+ ];
1058
+ var isTrustedExecutable = (first) => {
1059
+ if (!first.includes("/")) return true;
1060
+ if (first.includes("..")) return false;
1061
+ return TRUSTED_EXE_PREFIXES.some((prefix) => first.startsWith(prefix));
1062
+ };
1046
1063
 
1047
1064
  // ../contracts/src/powershell-analysis.ts
1048
1065
  var SINGLE_QUOTES = /* @__PURE__ */ new Set(["'", "\u2018", "\u2019", "\u201A", "\u201B"]);
@@ -2568,6 +2585,8 @@ var SETUP_CONTROL_FAILURE_STAGES = [
2568
2585
  "unsupported"
2569
2586
  ];
2570
2587
  var isSetupControlFailureStage = (value) => typeof value === "string" && SETUP_CONTROL_FAILURE_STAGES.includes(value);
2588
+ var SETUP_CONTROL_PREREQUISITES = ["provider", "service-manager"];
2589
+ var isSetupControlPrerequisite = (value) => typeof value === "string" && SETUP_CONTROL_PREREQUISITES.includes(value);
2571
2590
  var SETUP_CONNECT_OUTCOMES = ["answered", "delivered", "unreachable", "skipped"];
2572
2591
  var isSetupConnectOutcome = (value) => typeof value === "string" && SETUP_CONNECT_OUTCOMES.includes(value);
2573
2592
  var CLI_VERSION_MAX_LENGTH = 64;
@@ -2592,6 +2611,7 @@ var readSetupOutcomeProperties = (body) => {
2592
2611
  skippedAgents: readSetupAgentChoices(body.skippedAgents),
2593
2612
  closingReason: readOptional(body.closingReason, isSetupClosingReason),
2594
2613
  controlFailureStage: readOptional(body.controlFailureStage, isSetupControlFailureStage),
2614
+ controlMissingPrerequisite: readOptional(body.controlMissingPrerequisite, isSetupControlPrerequisite),
2595
2615
  connectMode: readOptional(body.connectMode, isSetupConnectMode),
2596
2616
  connectOutcome: readOptional(body.connectOutcome, isSetupConnectOutcome),
2597
2617
  keyCheck: readOptional(body.keyCheck, isSetupKeyCheck),
@@ -2643,10 +2663,62 @@ var record = (value) => value !== null && typeof value === "object" && !Array.is
2643
2663
  var identifier = (value) => typeof value === "string" && value.length > 0 && value.length <= 200;
2644
2664
  var isQuestionOwner = (value) => record(value) && value.capability === PERSONAL_QUESTION_CAPABILITY && identifier(value.machineId) && identifier(value.generation) && identifier(value.threadId) && identifier(value.turnId) && identifier(value.itemId) && (identifier(value.requestId) || typeof value.requestId === "number" && Number.isSafeInteger(value.requestId)) && value.method === "item/tool/requestUserInput" && typeof value.subjectHash === "string" && /^[a-f0-9]{64}$/.test(value.subjectHash) && Object.keys(value).length === 9;
2645
2665
 
2666
+ // ../contracts/src/codex-shell-script.ts
2667
+ var CODEX_SHELL_COMMAND_FLAGS = ["-lc", "-c"];
2668
+ var SHELLS_CODEX_RUNS_A_SCRIPT_IN = ["sh", "bash", "zsh"];
2669
+ var WORDS_IN_A_SHELL_SCRIPT_COMMAND = 3;
2670
+ var WORD_SEPARATOR = " ";
2671
+ var ABSOLUTE_PATH_START = "/";
2672
+ var BARE_WORD_PART = /^[A-Za-z0-9_@+:./\]-]+/;
2673
+ var SINGLE_QUOTED_WORD_PART = /^'([^']*)'/;
2674
+ var DOUBLE_QUOTED_WORD_PART = /^"((?:[^"$`\\!]|\\["$`\\])*)"/;
2675
+ var ESCAPED_INSIDE_DOUBLE_QUOTES = /\\(["$`\\])/g;
2676
+ var leadingWordPart = (rest) => {
2677
+ const bare = BARE_WORD_PART.exec(rest);
2678
+ if (bare) return { text: bare[0], length: bare[0].length };
2679
+ const single = SINGLE_QUOTED_WORD_PART.exec(rest);
2680
+ if (single) return { text: single[1] ?? "", length: single[0].length };
2681
+ const double = DOUBLE_QUOTED_WORD_PART.exec(rest);
2682
+ return double ? { text: (double[1] ?? "").replace(ESCAPED_INSIDE_DOUBLE_QUOTES, "$1"), length: double[0].length } : null;
2683
+ };
2684
+ var leadingWord = (rest) => {
2685
+ let text2 = "";
2686
+ let length = 0;
2687
+ for (let part = leadingWordPart(rest); part !== null; part = leadingWordPart(rest.slice(length))) {
2688
+ text2 += part.text;
2689
+ length += part.length;
2690
+ }
2691
+ return length === 0 ? null : { text: text2, length };
2692
+ };
2693
+ var wordsOfAJoinedCommand = (joined) => {
2694
+ const words = [];
2695
+ let rest = joined;
2696
+ while (rest.length > 0) {
2697
+ const word = leadingWord(rest);
2698
+ if (word === null) return null;
2699
+ words.push(word.text);
2700
+ rest = rest.slice(word.length);
2701
+ if (rest.length === 0) break;
2702
+ if (!rest.startsWith(WORD_SEPARATOR) || rest.length === WORD_SEPARATOR.length) return null;
2703
+ rest = rest.slice(WORD_SEPARATOR.length);
2704
+ }
2705
+ return words;
2706
+ };
2707
+ var isASystemShell = (program) => program.startsWith(ABSOLUTE_PATH_START) && isTrustedExecutable(program) && SHELLS_CODEX_RUNS_A_SCRIPT_IN.includes(basenameOf(program));
2708
+ var scriptACodexShellCommandRuns = (command) => {
2709
+ const words = wordsOfAJoinedCommand(command);
2710
+ if (words === null || words.length !== WORDS_IN_A_SHELL_SCRIPT_COMMAND) return null;
2711
+ const [shell, flag, script] = words;
2712
+ if (shell === void 0 || flag === void 0 || script === void 0) return null;
2713
+ if (!isASystemShell(shell) || !CODEX_SHELL_COMMAND_FLAGS.includes(flag)) return null;
2714
+ return script.trim().length === 0 ? null : script;
2715
+ };
2716
+
2646
2717
  // ../contracts/src/codex-native-approval.ts
2647
2718
  var CODEX_NATIVE_APPROVAL_CAPABILITY = "codex-native-approval-v1";
2648
2719
  var CODEX_NATIVE_APPROVAL_METHODS = ["item/commandExecution/requestApproval", "item/fileChange/requestApproval", "mcpServer/elicitation/request"];
2649
2720
  var CODEX_NATIVE_APPROVAL_CHOICES = { once: "Allow once", session: "Allow this conversation", deny: "Deny" };
2721
+ var CODEX_NATIVE_APPROVAL_REPLIES = { ask: "ask", deny: "deny", native: "native", allow: "allow" };
2650
2722
  var record2 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
2651
2723
  var identifier2 = (v) => typeof v === "string" && v.length > 0 && v.length <= 200;
2652
2724
  var text = (v) => typeof v === "string" && v.trim().length > 0 && v.length <= 16384;
@@ -2662,6 +2734,7 @@ var boundedJson = (value) => {
2662
2734
  };
2663
2735
  var BASE_KEYS = ["threadId", "turnId", "itemId", "startedAtMs", "reason"];
2664
2736
  var MCP_META_KEYS = ["codex_approval_kind", "codex_requires_user_input", "codex_request_type", "codex_strict_auto_review", "codex_sensitive_action", "approvals_reviewer", "persist", "source", "connector_id", "connector_name", "connector_description", "tool_name", "tool_title", "tool_description", "tool_params", "tool_params_display"];
2737
+ var MCP_FLAGS_THAT_ASK_FOR_A_PERSON = ["codex_requires_user_input", "codex_strict_auto_review", "codex_sensitive_action"];
2665
2738
  var COMPUTER_USE_META_KEYS = [...MCP_META_KEYS, "riskLevel", "subtitle", "tool_call_id"];
2666
2739
  var computerUseDisplay = (value) => Array.isArray(value) && value.length <= 16 && value.every((item) => record2(item) && keys(item, ["name", "display_name", "value"]) && text(item.name) && text(item.display_name) && text(item.value));
2667
2740
  var isExecpolicyAmendment = (value) => Array.isArray(value) && value.length > 0 && value.length <= 128 && value.every((token) => typeof token === "string" && token.length <= 16384);
@@ -2670,6 +2743,22 @@ var isCommandDecision = (value) => {
2670
2743
  if (!record2(value) || !keys(value, ["acceptWithExecpolicyAmendment"]) || !record2(value.acceptWithExecpolicyAmendment)) return false;
2671
2744
  return keys(value.acceptWithExecpolicyAmendment, ["execpolicy_amendment"]) && isExecpolicyAmendment(value.acceptWithExecpolicyAmendment.execpolicy_amendment);
2672
2745
  };
2746
+ var FILE_CHANGE_KINDS = ["add", "delete", "update"];
2747
+ var FILE_CHANGE_VERB = { add: "adding", delete: "deleting", update: "editing" };
2748
+ var FILE_CHANGE_LABEL = { add: "Add", delete: "Delete", update: "Edit" };
2749
+ var FILE_CHANGES_NAMED_IN_A_QUESTION = 3;
2750
+ var isFileChangeKind = (v) => FILE_CHANGE_KINDS.some((kind) => kind === v);
2751
+ var labelledFileChange = ({ kind, path }) => `${FILE_CHANGE_LABEL[kind]} ${path}`;
2752
+ var fileChangeQuestion = (changes) => {
2753
+ const [only] = changes;
2754
+ if (only && changes.length === 1) return `Allow ${FILE_CHANGE_VERB[only.kind]} ${only.path} once?`;
2755
+ const named = changes.slice(0, FILE_CHANGES_NAMED_IN_A_QUESTION).map(labelledFileChange).join(", ");
2756
+ const unnamed = changes.length - FILE_CHANGES_NAMED_IN_A_QUESTION;
2757
+ return `Allow these ${changes.length} file changes once? ${named}${unnamed > 0 ? ` and ${unnamed} more` : ""}`;
2758
+ };
2759
+ var withCodexReason = (detail, reason) => text(reason) ? `${detail}
2760
+
2761
+ Codex's reason: ${redactSecrets(reason)}` : detail;
2673
2762
  var parseCodexNativeApproval = (value) => {
2674
2763
  if (!record2(value) || !keys(value, ["method", "params", "changes"]) || !isMethod(value.method) || !record2(value.params) || !boundedJson(value)) return null;
2675
2764
  const p = value.params;
@@ -2681,7 +2770,8 @@ var parseCodexNativeApproval = (value) => {
2681
2770
  turnId: typeof p.turnId === "string" ? p.turnId : null,
2682
2771
  itemId: typeof p.itemId === "string" ? p.itemId : null,
2683
2772
  options: [CODEX_NATIVE_APPROVAL_CHOICES.once, CODEX_NATIVE_APPROVAL_CHOICES.deny],
2684
- negativeDecision: "decline"
2773
+ negativeDecision: "decline",
2774
+ codexAsksForAPerson: false
2685
2775
  };
2686
2776
  if (value.method === "mcpServer/elicitation/request") {
2687
2777
  const meta = p._meta;
@@ -2689,29 +2779,32 @@ var parseCodexNativeApproval = (value) => {
2689
2779
  if (value.changes !== void 0 || !keys(p, ["threadId", "turnId", "serverName", "mode", "message", "requestedSchema", "_meta"]) || !(p.mode === "form" || computerUse && (p.mode === "openai/form" || p.mode === "openaiForm")) || !identifier2(p.serverName) || !text(p.message) || p.message.length > 500 || !record2(p.requestedSchema) || !keys(p.requestedSchema, ["type", "properties", "required", "$schema"]) || p.requestedSchema.type !== "object" || !record2(p.requestedSchema.properties) || Object.keys(p.requestedSchema.properties).length !== 0 || p.requestedSchema.required != null && (!Array.isArray(p.requestedSchema.required) || p.requestedSchema.required.length !== 0)) return null;
2690
2780
  if (!record2(meta) || !keys(meta, computerUse ? COMPUTER_USE_META_KEYS : MCP_META_KEYS) || meta.codex_approval_kind !== "mcp_tool_call" || !identifier2(meta.tool_name) || !record2(meta.tool_params) || meta.tool_params_display != null && !(computerUse ? computerUseDisplay(meta.tool_params_display) : record2(meta.tool_params_display))) return null;
2691
2781
  if (computerUse && (meta.riskLevel !== "low" && meta.riskLevel !== "high" || meta.subtitle != null && !text(meta.subtitle) || !optionalIdentifier(meta.tool_call_id))) return null;
2692
- if (["codex_requires_user_input", "codex_strict_auto_review", "codex_sensitive_action"].some((key) => meta[key] != null && typeof meta[key] !== "boolean")) return null;
2782
+ if (MCP_FLAGS_THAT_ASK_FOR_A_PERSON.some((key) => meta[key] != null && typeof meta[key] !== "boolean")) return null;
2693
2783
  if (meta.approvals_reviewer != null && meta.approvals_reviewer !== "user") return null;
2694
2784
  if (meta.codex_request_type != null && meta.codex_request_type !== "approval_request") return null;
2695
2785
  if (["source", "connector_id", "connector_name", "connector_description", "tool_title", "tool_description"].some((key) => meta[key] != null && !text(meta[key]))) return null;
2696
2786
  const persistence = meta.persist == null ? [] : typeof meta.persist === "string" ? [meta.persist] : meta.persist;
2787
+ const codexAsksForAPerson = MCP_FLAGS_THAT_ASK_FOR_A_PERSON.some((key) => meta[key] === true);
2697
2788
  if (!Array.isArray(persistence) || persistence.some((v) => v !== "session" && v !== "always")) return null;
2698
2789
  if (computerUse) {
2699
2790
  if (!persistence.includes("session")) return null;
2700
2791
  return {
2701
2792
  ...base,
2793
+ codexAsksForAPerson,
2702
2794
  toolName: `mcp__${p.serverName}__${meta.tool_name}`,
2703
2795
  toolInputs: [meta.tool_params],
2704
2796
  question: p.message,
2705
- detail: [`Risk: ${meta.riskLevel}`, meta.subtitle, JSON.stringify(meta.tool_params)].filter(Boolean).join("\n"),
2797
+ detail: redactSecrets([`Risk: ${meta.riskLevel}`, meta.subtitle, JSON.stringify(meta.tool_params)].filter(Boolean).join("\n")),
2706
2798
  options: [CODEX_NATIVE_APPROVAL_CHOICES.session, CODEX_NATIVE_APPROVAL_CHOICES.deny]
2707
2799
  };
2708
2800
  }
2709
2801
  return {
2710
2802
  ...base,
2803
+ codexAsksForAPerson,
2711
2804
  toolName: `mcp__${p.serverName}__${meta.tool_name}`,
2712
2805
  toolInputs: [meta.tool_params],
2713
2806
  question: p.message,
2714
- detail: JSON.stringify(meta.tool_params),
2807
+ detail: redactSecrets(JSON.stringify(meta.tool_params)),
2715
2808
  options: persistence.includes("session") ? [CODEX_NATIVE_APPROVAL_CHOICES.once, CODEX_NATIVE_APPROVAL_CHOICES.session, CODEX_NATIVE_APPROVAL_CHOICES.deny] : base.options
2716
2809
  };
2717
2810
  }
@@ -2720,31 +2813,34 @@ var parseCodexNativeApproval = (value) => {
2720
2813
  if (value.changes !== void 0 || !keys(p, [...BASE_KEYS, "approvalId", "kind", "environmentId", "command", "cwd", "commandActions", "networkApprovalContext", "proposedExecpolicyAmendment", "proposedNetworkPolicyAmendments", "availableDecisions"]) || !optionalIdentifier(p.approvalId) || p.kind != null && p.kind !== "command" || p.environmentId != null && p.environmentId !== "local" || p.networkApprovalContext != null || p.proposedNetworkPolicyAmendments != null || p.proposedExecpolicyAmendment != null && !isExecpolicyAmendment(p.proposedExecpolicyAmendment) || !text(p.command) || !text(p.cwd)) return null;
2721
2814
  const decisions = p.availableDecisions ?? ["accept", "decline", "cancel"];
2722
2815
  if (!Array.isArray(decisions) || !decisions.includes("accept") || !decisions.some((v) => v === "decline" || v === "cancel") || !decisions.every(isCommandDecision)) return null;
2816
+ const command = scriptACodexShellCommandRuns(p.command) ?? p.command;
2723
2817
  return {
2724
2818
  ...base,
2725
2819
  toolName: "Bash",
2726
- toolInputs: [{ command: p.command }],
2820
+ toolInputs: [{ command }],
2727
2821
  cwd: p.cwd,
2728
2822
  question: "Allow this command once?",
2729
- detail: p.command,
2823
+ detail: withCodexReason(`${redactSecrets(command)}
2824
+
2825
+ Directory: ${redactSecrets(p.cwd)}`, p.reason),
2730
2826
  negativeDecision: decisions.includes("decline") ? "decline" : "cancel"
2731
2827
  };
2732
2828
  }
2733
2829
  if (!keys(p, [...BASE_KEYS, "grantRoot"]) || p.grantRoot != null || !Array.isArray(value.changes) || value.changes.length === 0 || value.changes.length > 32) return null;
2734
- const paths = [], diffs = [];
2830
+ const changes = [];
2735
2831
  for (const change of value.changes) {
2736
- if (!record2(change) || !keys(change, ["path", "kind", "diff"]) || !text(change.path) || typeof change.diff !== "string" || !record2(change.kind) || !keys(change.kind, ["type", "move_path"]) || !["add", "delete", "update"].includes(String(change.kind.type)) || change.kind.move_path != null) return null;
2737
- paths.push(change.path);
2738
- diffs.push(`${change.path}
2739
- ${change.diff}`);
2832
+ if (!record2(change) || !keys(change, ["path", "kind", "diff"]) || !text(change.path) || typeof change.diff !== "string" || !record2(change.kind) || !keys(change.kind, ["type", "move_path"]) || !isFileChangeKind(change.kind.type) || change.kind.move_path != null) return null;
2833
+ changes.push({ kind: change.kind.type, path: change.path, diff: change.diff });
2740
2834
  }
2835
+ const paths = changes.map((change) => change.path);
2741
2836
  return {
2742
2837
  ...base,
2743
2838
  toolName: "Edit",
2744
2839
  toolInputs: paths.map((file_path) => ({ file_path })),
2745
2840
  scopePaths: paths,
2746
- question: `Allow these ${paths.length} file changes once?`,
2747
- detail: diffs.join("\n\n")
2841
+ question: fileChangeQuestion(changes),
2842
+ detail: withCodexReason(changes.map((change) => `${redactSecrets(labelledFileChange(change))}
2843
+ ${redactSecretsDeep(change.diff)}`).join("\n\n"), p.reason)
2748
2844
  };
2749
2845
  };
2750
2846
  var codexNativeApprovalResponse = (approval, answer) => {
@@ -3326,23 +3422,6 @@ var SAFE_FIND_TOKENS = /* @__PURE__ */ new Set([
3326
3422
  "-O"
3327
3423
  ]);
3328
3424
  var SAFE_REDIRECTION = /\s*(?:[0-9]*>&[0-9-]+|(?:[0-9]*|&)>>?\s*\/dev\/null)/g;
3329
- var basenameOf = (token) => {
3330
- const slash = Math.max(token.lastIndexOf("/"), token.lastIndexOf("\\"));
3331
- return slash === -1 ? token : token.slice(slash + 1);
3332
- };
3333
- var TRUSTED_EXE_PREFIXES = [
3334
- "/bin/",
3335
- "/sbin/",
3336
- "/usr/bin/",
3337
- "/usr/sbin/",
3338
- "/usr/local/bin/",
3339
- "/opt/homebrew/bin/"
3340
- ];
3341
- var isTrustedExecutable = (first) => {
3342
- if (!first.includes("/")) return true;
3343
- if (first.includes("..")) return false;
3344
- return TRUSTED_EXE_PREFIXES.some((prefix) => first.startsWith(prefix));
3345
- };
3346
3425
  var isSafeSimpleCommand = (segment) => {
3347
3426
  const tokens = shellWordsOf(segment)?.map((word) => word.text);
3348
3427
  if (!tokens || tokens.length === 0) return false;
@@ -6283,8 +6362,11 @@ export {
6283
6362
  isAutoUpdateResult,
6284
6363
  PERSONAL_QUESTION_CAPABILITY,
6285
6364
  isQuestionOwner,
6365
+ CODEX_SHELL_COMMAND_FLAGS,
6286
6366
  CODEX_NATIVE_APPROVAL_CAPABILITY,
6287
6367
  CODEX_NATIVE_APPROVAL_METHODS,
6368
+ CODEX_NATIVE_APPROVAL_CHOICES,
6369
+ CODEX_NATIVE_APPROVAL_REPLIES,
6288
6370
  parseCodexNativeApproval,
6289
6371
  codexNativeApprovalResponse,
6290
6372
  normalizeKeyScope,
@@ -4,7 +4,7 @@ import {
4
4
  forkFinishWithUpgradeLock,
5
5
  installWithUpgradeLock,
6
6
  releaseAutoUpdateLock
7
- } from "./chunk-FQWI6XQG.js";
7
+ } from "./chunk-DQPFQGIN.js";
8
8
  import {
9
9
  describeAutoUpdateCheck,
10
10
  globalInstallLocation,
@@ -14,7 +14,7 @@ import {
14
14
  readAutoUpdateState,
15
15
  updateAutoUpdateState,
16
16
  upgradeEntryFor
17
- } from "./chunk-2UABJ75E.js";
17
+ } from "./chunk-HF66SU3D.js";
18
18
  import {
19
19
  EXIT
20
20
  } from "./chunk-KZERVKTD.js";
@@ -27,10 +27,10 @@ import {
27
27
  npmErrorMessage,
28
28
  readGlobalCliInstallAt,
29
29
  readGlobalPrefix
30
- } from "./chunk-EW52AGOV.js";
30
+ } from "./chunk-B2DU67G6.js";
31
31
  import {
32
32
  NPX_LATEST_COMMAND
33
- } from "./chunk-WN3MDHAM.js";
33
+ } from "./chunk-WNEEQ7GJ.js";
34
34
  import {
35
35
  commandsPackage,
36
36
  globalUpgradeEntry,
@@ -39,7 +39,7 @@ import {
39
39
  isSameMajorVersion,
40
40
  ownPackageRoot,
41
41
  packageVersionAt
42
- } from "./chunk-EDSXF7NV.js";
42
+ } from "./chunk-YWFL5ANU.js";
43
43
 
44
44
  // src/global-upgrade.ts
45
45
  import { existsSync } from "fs";
@@ -3,18 +3,18 @@ import {
3
3
  addGeminiMcpServer,
4
4
  removeGeminiMcpServer,
5
5
  supportedClaudeEvents
6
- } from "./chunk-35TUEZ5E.js";
6
+ } from "./chunk-CQ4VDI27.js";
7
7
  import {
8
8
  CLAUDE_CODE_AGENT,
9
9
  compatibleToolLookup
10
- } from "./chunk-WYD4PYTL.js";
10
+ } from "./chunk-7S5HYDAO.js";
11
11
  import {
12
12
  guardBinary,
13
13
  guardBinaryRefusing,
14
14
  holdBudgetOf,
15
15
  isProtectedByScope,
16
16
  registerHookEntry
17
- } from "./chunk-EW52AGOV.js";
17
+ } from "./chunk-B2DU67G6.js";
18
18
  import {
19
19
  HOOK_LOCATOR_BINARY,
20
20
  PHONE_ANSWERED_TOOLS,
@@ -25,7 +25,7 @@ import {
25
25
  pusharyMissingReason,
26
26
  refusalOutput,
27
27
  withHookHoldBudget
28
- } from "./chunk-EDSXF7NV.js";
28
+ } from "./chunk-YWFL5ANU.js";
29
29
 
30
30
  // src/claude-config.ts
31
31
  import { join } from "path";
@@ -284,6 +284,9 @@ var compatibleTargetPaths = (profile, home) => compatibleTargetFiles(profile).ma
284
284
  var compatibleConfigFile = (profile, home) => compatibleFilePath(profile.configFile, home);
285
285
  var compatibleMcpFile = (profile, home) => profile.mcp ? compatibleFilePath(profile.mcp.file, home) : null;
286
286
  var compatibleInstructionsFile = (profile, home) => profile.instructions ? compatibleFilePath(profile.instructions.file, home) : null;
287
+ var PUSHARY_OWNED_FILE_STEM = "pushary";
288
+ var isPusharyOwnedFile = (file) => file.path.at(-1)?.split(".")[0] === PUSHARY_OWNED_FILE_STEM;
289
+ var isEmptiedPusharyOwnedDocument = (file, document) => isPusharyOwnedFile(file) && Object.keys(document).length === 0;
287
290
  var asRecord2 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
288
291
  var ensureRecord2 = (target, key) => {
289
292
  const existing = asRecord2(target[key]);
@@ -490,6 +493,7 @@ export {
490
493
  compatibleConfigFile,
491
494
  compatibleMcpFile,
492
495
  compatibleInstructionsFile,
496
+ isEmptiedPusharyOwnedDocument,
493
497
  compatibleHookEvents,
494
498
  addCompatibleToolPermissions,
495
499
  addCompatibleHooks,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  HOOK_HOLD_BUDGET_ENV,
3
3
  hookHoldBudgetProof
4
- } from "./chunk-EDSXF7NV.js";
4
+ } from "./chunk-YWFL5ANU.js";
5
5
 
6
6
  // src/hold-budget.ts
7
7
  var takeHookHoldBudget = (args = process.argv.slice(2), env = process.env) => {