pushary 1.9.138 → 1.9.140

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 (134) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/data/vscode-plugin/README.md +2 -0
  3. package/dist/{api-J4XJ7XWW.js → api-ZV6JN5J3.js} +11 -11
  4. package/dist/bin/pushary-audit.js +3 -3
  5. package/dist/bin/pushary-bell-hook.js +28 -28
  6. package/dist/bin/pushary-bell.js +10 -10
  7. package/dist/bin/pushary-claude.js +27 -27
  8. package/dist/bin/pushary-clean.js +35 -35
  9. package/dist/bin/pushary-codex-bridge.js +23 -23
  10. package/dist/bin/pushary-codex-hook.js +35 -35
  11. package/dist/bin/pushary-codex-session.js +8 -8
  12. package/dist/bin/pushary-codex.js +16 -16
  13. package/dist/bin/pushary-connect.js +29 -29
  14. package/dist/bin/pushary-cowork.js +5 -5
  15. package/dist/bin/pushary-daemon.js +106 -95
  16. package/dist/bin/pushary-disconnect.js +28 -28
  17. package/dist/bin/pushary-display-hook.js +88 -7
  18. package/dist/bin/pushary-doctor.js +43 -43
  19. package/dist/bin/pushary-elicitation-hook.js +28 -28
  20. package/dist/bin/pushary-gemini-bridge.js +19 -18
  21. package/dist/bin/pushary-gemini-hook.js +32 -32
  22. package/dist/bin/pushary-hook.js +35 -35
  23. package/dist/bin/pushary-login.js +21 -21
  24. package/dist/bin/pushary-logout.js +27 -27
  25. package/dist/bin/pushary-mcp.js +12 -12
  26. package/dist/bin/pushary-mode.js +15 -15
  27. package/dist/bin/pushary-notification-hook.js +27 -27
  28. package/dist/bin/pushary-opencode-hook.js +31 -31
  29. package/dist/bin/pushary-permission-denied-hook.js +35 -35
  30. package/dist/bin/pushary-permission-hook.js +35 -35
  31. package/dist/bin/pushary-post-hook.js +28 -28
  32. package/dist/bin/pushary-prompt-hook.js +27 -27
  33. package/dist/bin/pushary-session-end-hook.js +27 -27
  34. package/dist/bin/pushary-session-start-hook.js +36 -36
  35. package/dist/bin/pushary-setup.js +50 -50
  36. package/dist/bin/pushary-stats.js +5 -5
  37. package/dist/bin/pushary-status.js +33 -33
  38. package/dist/bin/pushary-stop-hook.js +27 -27
  39. package/dist/bin/pushary-stopfailure-hook.js +27 -27
  40. package/dist/bin/pushary-suggestions.js +15 -15
  41. package/dist/bin/pushary-transcript-register.js +17 -17
  42. package/dist/bin/pushary-transcripts.js +25 -25
  43. package/dist/bin/pushary-upgrade.js +41 -41
  44. package/dist/bin/pushary-wait.js +15 -15
  45. package/dist/bin/pushary.js +7 -7
  46. package/dist/{chunk-B4UIRMOE.js → chunk-2MELVDYD.js} +2 -2
  47. package/dist/{chunk-SNMTACCY.js → chunk-3FJO3HIA.js} +3 -3
  48. package/dist/{chunk-33E75LIY.js → chunk-3HORJAQX.js} +2 -2
  49. package/dist/{chunk-LIZEMDE4.js → chunk-3TQ4NPFC.js} +3 -3
  50. package/dist/{chunk-QXATIKHQ.js → chunk-4IAFTTNQ.js} +1 -1
  51. package/dist/{chunk-KXKE3SW3.js → chunk-4SMS5DND.js} +3 -3
  52. package/dist/{chunk-52B2TQJM.js → chunk-4YIVV4PY.js} +2 -2
  53. package/dist/{chunk-WM7OY63L.js → chunk-5TPC3M45.js} +4 -5
  54. package/dist/{chunk-VVN3RPV6.js → chunk-6LK6I62M.js} +1 -1
  55. package/dist/{chunk-A2YJ2FBR.js → chunk-6WBHYQ2P.js} +1 -1
  56. package/dist/{chunk-APTNHX63.js → chunk-6Z7VJ65F.js} +5 -5
  57. package/dist/{chunk-Y47BMZUR.js → chunk-7AXEKUXY.js} +1 -1
  58. package/dist/{chunk-P6HLLS5J.js → chunk-7DPPMWTR.js} +2 -2
  59. package/dist/{chunk-DMZMPYLB.js → chunk-7LBMCU3S.js} +4 -4
  60. package/dist/{chunk-YOV3LHOL.js → chunk-7OBROSQL.js} +3 -3
  61. package/dist/{chunk-JFGM6VSU.js → chunk-7TXUHOQW.js} +10 -10
  62. package/dist/{chunk-5XDFQ6E3.js → chunk-7W4XA2WF.js} +1 -1
  63. package/dist/{chunk-DES272QQ.js → chunk-7WLNPGEY.js} +6 -6
  64. package/dist/{chunk-FQ3ASV5L.js → chunk-AQVXXXFZ.js} +4 -4
  65. package/dist/{chunk-FYLYAVQG.js → chunk-AXAO3JF5.js} +3 -12
  66. package/dist/{chunk-KN4YJ4QS.js → chunk-B4KAY45V.js} +30 -22
  67. package/dist/{chunk-L3UV4LLL.js → chunk-BAT4TJOE.js} +8 -8
  68. package/dist/{chunk-R7CQF2P3.js → chunk-BMBWFLIT.js} +1 -1
  69. package/dist/{chunk-RRUP72V6.js → chunk-D7AJ3ZCI.js} +1 -1
  70. package/dist/{chunk-VF4N6NHG.js → chunk-E4MC6B6U.js} +4 -4
  71. package/dist/{chunk-H5XLVJI7.js → chunk-E67Y7DSA.js} +2 -2
  72. package/dist/{chunk-HVRXBHX2.js → chunk-FSDTFT7J.js} +2 -2
  73. package/dist/{chunk-ICQU3SNR.js → chunk-GUVTHNCX.js} +5 -5
  74. package/dist/{chunk-PPCZSOCL.js → chunk-H2EXF6DB.js} +3 -3
  75. package/dist/{chunk-LPXHKIJC.js → chunk-HJFTPNP6.js} +2 -2
  76. package/dist/{chunk-42BVIKPZ.js → chunk-HNN46FYL.js} +4 -4
  77. package/dist/{chunk-MENTZJHA.js → chunk-IEHY7DCR.js} +1 -1
  78. package/dist/{chunk-TN5PGMH5.js → chunk-IJMWFHZZ.js} +2 -2
  79. package/dist/{chunk-FO5MHOBI.js → chunk-JHRJ3KKG.js} +5 -5
  80. package/dist/{chunk-NLJ2ILA7.js → chunk-JYOC6N7C.js} +2 -2
  81. package/dist/{chunk-EHQCMJHI.js → chunk-L7BWJD25.js} +1 -1
  82. package/dist/{chunk-CBTXOWB3.js → chunk-LAAGGP7K.js} +5 -5
  83. package/dist/{chunk-NIBF37NU.js → chunk-LURIPMCB.js} +6 -6
  84. package/dist/{chunk-NUG2A73X.js → chunk-LW7TXMCP.js} +1 -1
  85. package/dist/{chunk-IRIXOH4U.js → chunk-MDRNNK3L.js} +1 -1
  86. package/dist/{chunk-WHOFZB5W.js → chunk-MEFTOIUI.js} +1 -1
  87. package/dist/{chunk-OAGYR5LI.js → chunk-MFRNEOCN.js} +11 -11
  88. package/dist/{chunk-MQMVJDII.js → chunk-MGBYRHT3.js} +1 -1
  89. package/dist/{chunk-N3VCBXI6.js → chunk-MTVAACOE.js} +3 -3
  90. package/dist/{chunk-CULDO4UA.js → chunk-N346VCKX.js} +3 -3
  91. package/dist/{chunk-FJ7OESWX.js → chunk-NBJ7N7KL.js} +5 -5
  92. package/dist/{chunk-S47AAQFT.js → chunk-O55PACNP.js} +4 -4
  93. package/dist/{chunk-VQMGR32B.js → chunk-O66URN57.js} +3 -3
  94. package/dist/{chunk-NNDUDXOJ.js → chunk-OZY4EU6V.js} +11 -11
  95. package/dist/{chunk-O26H5X5M.js → chunk-PHZYLAHL.js} +2 -2
  96. package/dist/{chunk-TXPXK5Q6.js → chunk-QAT2PWRX.js} +16 -16
  97. package/dist/{chunk-DL67HX3D.js → chunk-QCIZDJSU.js} +322 -178
  98. package/dist/{chunk-AGVE7MXF.js → chunk-QDQHIQWH.js} +2 -2
  99. package/dist/{chunk-LNF36PTF.js → chunk-RACM64B6.js} +2 -2
  100. package/dist/{chunk-PNVTPEO5.js → chunk-RQPVEBKR.js} +3 -3
  101. package/dist/{chunk-6TK3DWSF.js → chunk-RVKCG7DK.js} +6 -6
  102. package/dist/{chunk-LF3ZRLUQ.js → chunk-S6LB3SZE.js} +12 -12
  103. package/dist/{chunk-K7YJBVR3.js → chunk-S7DTAH7Q.js} +1 -1
  104. package/dist/{chunk-YQQGIDBC.js → chunk-SANGITZF.js} +1 -1
  105. package/dist/{chunk-PNDL3OMR.js → chunk-SQB57AJR.js} +4 -4
  106. package/dist/{chunk-5ZK4RHYR.js → chunk-SSAGWDBN.js} +3 -3
  107. package/dist/{chunk-DK6CMXYI.js → chunk-T5GZUMBP.js} +5 -5
  108. package/dist/{chunk-KYD3LHFB.js → chunk-TA3YQY6I.js} +1 -1
  109. package/dist/{chunk-P7YVVWTW.js → chunk-TJX25WUQ.js} +2 -2
  110. package/dist/{chunk-TJCUGBCZ.js → chunk-TRCJWAZD.js} +6 -6
  111. package/dist/{chunk-B3AZPYRU.js → chunk-UGU566AU.js} +6 -6
  112. package/dist/{chunk-KTVMIG32.js → chunk-UH25VEQI.js} +4 -4
  113. package/dist/{chunk-LIUWN23V.js → chunk-UHB7G2XC.js} +5 -5
  114. package/dist/{chunk-U3OLXV5Z.js → chunk-ULRZGJSL.js} +2 -2
  115. package/dist/{chunk-EJSU5YWO.js → chunk-V5VSSRV6.js} +6 -6
  116. package/dist/{chunk-OXPYENHL.js → chunk-XJ6CRGD2.js} +4 -4
  117. package/dist/{chunk-IKBTG3OT.js → chunk-Y7LBB6YM.js} +1 -1
  118. package/dist/{chunk-ZWURBNA3.js → chunk-YB7V6V6O.js} +1 -1
  119. package/dist/{chunk-7WR3FDDX.js → chunk-YD3PTYOT.js} +37 -33
  120. package/dist/{chunk-IDGWQY3J.js → chunk-YIIGX653.js} +5 -5
  121. package/dist/{codex-app-cards-switch-R3MIDYFA.js → codex-app-cards-switch-YW4R5WTG.js} +11 -11
  122. package/dist/{codex-card-routing-LQJEJNTS.js → codex-card-routing-5EHXCS7Y.js} +2 -2
  123. package/dist/{codex-desktop-launch-2YRIBVDK.js → codex-desktop-launch-VEPL7OFZ.js} +1 -1
  124. package/dist/{codex-session-launch-CTMTMGHU.js → codex-session-launch-7UKI32XL.js} +20 -20
  125. package/dist/{config-34VUNHK6.js → config-5YVCM3JL.js} +3 -3
  126. package/dist/{global-upgrade-NMTIVAJ3.js → global-upgrade-YNLHN2LI.js} +9 -9
  127. package/dist/{identity-3XKATUN2.js → identity-ZF5BYVAH.js} +4 -4
  128. package/dist/{live-capabilities-MR35FXPF.js → live-capabilities-UDAEQC25.js} +14 -11
  129. package/dist/{paths-YA5ROXGC.js → paths-5CUJRNH3.js} +3 -3
  130. package/dist/{reapply-LIBOIVBT.js → reapply-EHYJUX67.js} +29 -29
  131. package/dist/src/index.js +34 -34
  132. package/dist/{upgrade-lock-LK4XD3HR.js → upgrade-lock-ONZN26ZJ.js} +4 -4
  133. package/dist/{usage-ZSV4LFDL.js → usage-GF3ZBAH4.js} +3 -3
  134. package/package.json +1 -1
@@ -118,9 +118,9 @@ var isAgentQuestionSet = (value) => {
118
118
  const labels = /* @__PURE__ */ new Set();
119
119
  for (const option of question.options) {
120
120
  if (!option || typeof option !== "object" || Array.isArray(option)) return false;
121
- const record4 = option;
122
- const label = record4.label;
123
- if (typeof label !== "string" || label.length === 0 || labels.has(label) || record4.description !== void 0 && typeof record4.description !== "string") return false;
121
+ const record5 = option;
122
+ const label = record5.label;
123
+ if (typeof label !== "string" || label.length === 0 || labels.has(label) || record5.description !== void 0 && typeof record5.description !== "string") return false;
124
124
  labels.add(label);
125
125
  }
126
126
  questions.add(question.question);
@@ -191,6 +191,42 @@ var codexQuestionAnswerReason = (answers) => {
191
191
  return `${CODEX_QUESTION_ANSWERED_IN_PUSHARY}. ${answered}. ${CODEX_QUESTION_CONTINUE}`;
192
192
  };
193
193
 
194
+ // ../contracts/src/session-runtime.ts
195
+ var SPAWN_CAPABILITY = "spawn";
196
+ var CLAUDE_BRIDGE_CAPABILITY = "claude-bridge";
197
+ var CLAUDE_RESUME_CAPABILITY = "claude-resume";
198
+ var CODEX_BRIDGE_CAPABILITY = "codex-bridge";
199
+ var CODEX_RESUME_CAPABILITY = "codex-resume";
200
+ var GEMINI_BRIDGE_CAPABILITY = "gemini-bridge";
201
+ var GEMINI_RESUME_CAPABILITY = "gemini-resume";
202
+ var SESSION_RUNTIMES = {
203
+ claude: {
204
+ provider: "claude",
205
+ label: "Claude",
206
+ protocol: "claude-stream-json",
207
+ bridgeCapability: CLAUDE_BRIDGE_CAPABILITY,
208
+ resumeCapability: CLAUDE_RESUME_CAPABILITY,
209
+ phoneResume: false
210
+ },
211
+ codex: {
212
+ provider: "codex",
213
+ label: "Codex",
214
+ protocol: "codex-app-server",
215
+ bridgeCapability: CODEX_BRIDGE_CAPABILITY,
216
+ resumeCapability: CODEX_RESUME_CAPABILITY,
217
+ phoneResume: true
218
+ },
219
+ gemini: {
220
+ provider: "gemini",
221
+ label: "Gemini",
222
+ protocol: "gemini-stream-json",
223
+ bridgeCapability: GEMINI_BRIDGE_CAPABILITY,
224
+ resumeCapability: GEMINI_RESUME_CAPABILITY,
225
+ phoneResume: true
226
+ }
227
+ };
228
+ var sessionProvidersAdvertisedBy = (capabilities) => Object.values(SESSION_RUNTIMES).filter((runtime) => capabilities.includes(runtime.bridgeCapability)).map((runtime) => runtime.provider);
229
+
194
230
  // ../contracts/src/claude-connector.ts
195
231
  var CLAUDE_DIRECTORY_URL = "https://claude.ai/directory/pushary";
196
232
  var CLAUDE_CONNECTOR_URL = "https://pushary.com/api/mcp/mcp";
@@ -236,7 +272,7 @@ var defaults = {
236
272
  policyAgent: null,
237
273
  repoAware: false,
238
274
  disconnectable: false,
239
- managedProvider: false,
275
+ sessionRuntime: null,
240
276
  bridged: false,
241
277
  enforcement: "cooperative",
242
278
  connectVia: "Plain MCP",
@@ -259,7 +295,7 @@ var AGENTS = {
259
295
  policyAgent: "claude_code",
260
296
  repoAware: true,
261
297
  disconnectable: true,
262
- managedProvider: true,
298
+ sessionRuntime: SESSION_RUNTIMES.claude,
263
299
  enforcement: "enforced",
264
300
  connectVia: "Native hooks + MCP",
265
301
  setupCommand: PUSHARY_SETUP_COMMAND,
@@ -287,7 +323,7 @@ var AGENTS = {
287
323
  policyAgent: "codex",
288
324
  repoAware: true,
289
325
  disconnectable: true,
290
- managedProvider: true,
326
+ sessionRuntime: SESSION_RUNTIMES.codex,
291
327
  enforcement: "enforced",
292
328
  connectVia: "Native hooks + MCP",
293
329
  setupCommand: PUSHARY_SETUP_COMMAND,
@@ -308,7 +344,7 @@ var AGENTS = {
308
344
  policyAgent: "gemini_cli",
309
345
  repoAware: true,
310
346
  disconnectable: true,
311
- managedProvider: true,
347
+ sessionRuntime: SESSION_RUNTIMES.gemini,
312
348
  enforcement: "enforced",
313
349
  connectVia: "Native hooks + MCP",
314
350
  setupCommand: PUSHARY_SETUP_COMMAND,
@@ -524,7 +560,7 @@ var SESSION_HISTORY_AGENT_TYPES = Object.freeze(
524
560
  );
525
561
  var DISCONNECTABLE_AGENTS = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.disconnectable && agent.hookSource !== null ? [agent.hookSource] : []));
526
562
  var REPO_AWARE_AGENTS = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.repoAware ? [agent.policyAgent] : []));
527
- var MANAGED_PROVIDERS = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.managedProvider ? [agent.hookSource] : []));
563
+ var MANAGED_PROVIDERS = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.sessionRuntime ? [agent.sessionRuntime.provider] : []));
528
564
  var BRIDGE_HOOK_SOURCES = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.bridged ? [agent.hookSource] : []));
529
565
  var isAgentId = (value) => Object.keys(AGENTS).includes(value);
530
566
  var isHooklessDisconnectableAgent = (value) => isAgentId(value) && AGENTS[value].disconnectable && AGENTS[value].hookSource === null;
@@ -616,18 +652,18 @@ var CANONICAL_COMMAND_KEYS = ["command"];
616
652
  var SHELL_TOOLS = /* @__PURE__ */ new Set([SHELL_TOOL, POWERSHELL_TOOL]);
617
653
  var PATH_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit", "MultiEdit", "NotebookEdit", "Read"]);
618
654
  var PHONE_ANSWERED_TOOLS = /* @__PURE__ */ new Set(["AskUserQuestion", "ExitPlanMode"]);
619
- var firstString = (record4, keys2) => {
620
- for (const key of keys2) {
621
- const value = record4[key];
655
+ var firstString = (record5, keys3) => {
656
+ for (const key of keys3) {
657
+ const value = record5[key];
622
658
  if (typeof value === "string" && value.length > 0) return value;
623
659
  }
624
660
  return void 0;
625
661
  };
626
- var pathsNamedIn = (record4, keys2) => keys2.flatMap((key) => {
627
- const value = record4[key];
662
+ var pathsNamedIn = (record5, keys3) => keys3.flatMap((key) => {
663
+ const value = record5[key];
628
664
  return typeof value === "string" && value.length > 0 ? [value] : [];
629
665
  });
630
- var namesOneFile = (paths, resolvePath) => new Set(paths.map(resolvePath)).size === 1;
666
+ var namesOneFile = (paths2, resolvePath) => new Set(paths2.map(resolvePath)).size === 1;
631
667
  var filePathKeysOf = (profile) => [...profile.pathInputKeys, ...CANONICAL_PATH_KEYS];
632
668
  var namesAFilePath = (profile, toolInput) => pathsNamedIn(toolInput, filePathKeysOf(profile)).length > 0;
633
669
  var withCanonicalInputKeys = (profile, toolInput) => {
@@ -673,9 +709,9 @@ var toToolLookup = (profile, toolName, toolInput, resolvePath = (path) => path)
673
709
  return { tool, input: { command, ...context }, unreadable: false };
674
710
  }
675
711
  if (!PATH_TOOLS.has(tool)) return { tool, input: toolInput, unreadable: false };
676
- const paths = pathsNamedIn(toolInput, filePathKeysOf(profile));
677
- const [filePath] = paths;
678
- if (!filePath || !namesOneFile(paths, resolvePath)) return { tool, input: toolInput, unreadable: true };
712
+ const paths2 = pathsNamedIn(toolInput, filePathKeysOf(profile));
713
+ const [filePath] = paths2;
714
+ if (!filePath || !namesOneFile(paths2, resolvePath)) return { tool, input: toolInput, unreadable: true };
679
715
  return { tool, input: { ...withCanonicalInputKeys(profile, toolInput), file_path: resolvePath(filePath) }, unreadable: false };
680
716
  };
681
717
  var NO_AGENT_PROMPT_REASON = "Pushary needs an answer from the phone before this can run, and this agent has no approval prompt of its own here, so nothing ran. Ask the user, then try again.";
@@ -1148,7 +1184,7 @@ var readNullableText = (value, field) => {
1148
1184
  var ASKED_TEXT_FIELDS = ["id", "siteId", "type", "content", "createdAt"];
1149
1185
  var ASKED_NULLABLE_FIELDS = ["questionType", "context", "contextPayloadSha256", "correlationId", "externalId", "sessionId", "agentType", "agentName", "machineId", "toolName", "toolTarget", "requestedByUserId"];
1150
1186
  var DECISION_NULLABLE_FIELDS = ["response", "responseSource", "note", "decisionOutcome", "decisionOrigin", "decidedByUserId", "decidedByActor", "riskClass", "answeredAt"];
1151
- var isComplete = (record4, fields) => fields.every((field) => field in record4);
1187
+ var isComplete = (record5, fields) => fields.every((field) => field in record5);
1152
1188
  var readFields = (value, fields, read) => {
1153
1189
  const result = {};
1154
1190
  for (const field of fields) {
@@ -1160,7 +1196,7 @@ var readFields = (value, fields, read) => {
1160
1196
  };
1161
1197
  var ASKED_PAYLOAD_KEYS = /* @__PURE__ */ new Set(["event", ...ASKED_TEXT_FIELDS, ...ASKED_NULLABLE_FIELDS]);
1162
1198
  var DECISION_PAYLOAD_KEYS = /* @__PURE__ */ new Set(["event", "id", "autoResolved", "decisionLatencyMs", ...DECISION_NULLABLE_FIELDS]);
1163
- var hasOnlyKeys = (value, keys2) => Object.keys(value).every((key) => keys2.has(key));
1199
+ var hasOnlyKeys = (value, keys3) => Object.keys(value).every((key) => keys3.has(key));
1164
1200
  var parseAskedPayload = (value) => {
1165
1201
  const text3 = readFields(value, ASKED_TEXT_FIELDS, readText);
1166
1202
  const nullable = readFields(value, ASKED_NULLABLE_FIELDS, readNullableText);
@@ -1205,7 +1241,7 @@ var parseAllOrNothing = (values, parse) => {
1205
1241
  }
1206
1242
  return parsed;
1207
1243
  };
1208
- var entriesFitPage = (entries, beforeSeq) => beforeSeq === null || entries.every((entry) => entry.seq < beforeSeq);
1244
+ var entriesFitPage = (entries, beforeSeq) => beforeSeq === null || entries.every((entry2) => entry2.seq < beforeSeq);
1209
1245
  var parseSite = (value) => {
1210
1246
  if (!isPlainObject(value)) return null;
1211
1247
  const { siteId, siteName, beforeSeq, retentionFloor } = value;
@@ -1230,68 +1266,68 @@ var boundaryGapFindings = (entries, beforeSeq) => {
1230
1266
  };
1231
1267
  var linkFindings = (entries) => {
1232
1268
  const findings = [];
1233
- entries.forEach((entry, index) => {
1269
+ entries.forEach((entry2, index) => {
1234
1270
  const previous = entries[index - 1];
1235
1271
  if (!previous) {
1236
- if (entry.seq === 1 && entry.prevHash !== AUDIT_CHAIN_GENESIS_HASH) findings.push({ kind: "genesis_mismatch", seq: entry.seq });
1272
+ if (entry2.seq === 1 && entry2.prevHash !== AUDIT_CHAIN_GENESIS_HASH) findings.push({ kind: "genesis_mismatch", seq: entry2.seq });
1237
1273
  return;
1238
1274
  }
1239
- if (entry.seq !== previous.seq + 1) findings.push({ kind: "sequence_gap", afterSeq: previous.seq, seq: entry.seq });
1240
- if (entry.prevHash !== previous.entryHash) findings.push({ kind: "broken_link", seq: entry.seq });
1275
+ if (entry2.seq !== previous.seq + 1) findings.push({ kind: "sequence_gap", afterSeq: previous.seq, seq: entry2.seq });
1276
+ if (entry2.prevHash !== previous.entryHash) findings.push({ kind: "broken_link", seq: entry2.seq });
1241
1277
  });
1242
1278
  return findings;
1243
1279
  };
1244
- var entryHashFindings = (entries, crypto) => entries.flatMap((entry) => crypto.sha256Hex(auditEntryMessage(entry)) === entry.entryHash ? [] : [{ kind: "entry_altered", seq: entry.seq }]);
1245
- var payloadMatchesEntry = (payload, entry, siteId, crypto) => {
1246
- if (payload.id !== entry.interactionId || auditPayloadHash(payload, crypto.sha256Hex) !== entry.payloadHash) return false;
1247
- return payload.event === "asked" ? payload.siteId === siteId && payload.createdAt === entry.interactionCreatedAt : isFinalAuditDecision(payload) === entry.decisionFinal;
1280
+ var entryHashFindings = (entries, crypto) => entries.flatMap((entry2) => crypto.sha256Hex(auditEntryMessage(entry2)) === entry2.entryHash ? [] : [{ kind: "entry_altered", seq: entry2.seq }]);
1281
+ var payloadMatchesEntry = (payload, entry2, siteId, crypto) => {
1282
+ if (payload.id !== entry2.interactionId || auditPayloadHash(payload, crypto.sha256Hex) !== entry2.payloadHash) return false;
1283
+ return payload.event === "asked" ? payload.siteId === siteId && payload.createdAt === entry2.interactionCreatedAt : isFinalAuditDecision(payload) === entry2.decisionFinal;
1248
1284
  };
1249
1285
  var lastDecisionSeqByInteraction = (entries) => {
1250
1286
  const lastSeq = /* @__PURE__ */ new Map();
1251
- for (const entry of entries) {
1252
- if (entry.event === "decision") lastSeq.set(entry.interactionId, Math.max(entry.seq, lastSeq.get(entry.interactionId) ?? 0));
1287
+ for (const entry2 of entries) {
1288
+ if (entry2.event === "decision") lastSeq.set(entry2.interactionId, Math.max(entry2.seq, lastSeq.get(entry2.interactionId) ?? 0));
1253
1289
  }
1254
1290
  return lastSeq;
1255
1291
  };
1256
- var goneBeforeRetentionEnded = (entry, retentionFloor) => retentionFloor === null || entry.interactionCreatedAt >= retentionFloor;
1292
+ var goneBeforeRetentionEnded = (entry2, retentionFloor) => retentionFloor === null || entry2.interactionCreatedAt >= retentionFloor;
1257
1293
  var payloadFindings = (site, entries, crypto) => {
1258
1294
  const lastDecisionSeq = lastDecisionSeqByInteraction(entries);
1259
- return entries.flatMap((entry) => {
1260
- const invalid = { kind: "invalid_status", seq: entry.seq, status: entry.payloadStatus };
1261
- const hasLaterDecision = entry.event === "decision" && (lastDecisionSeq.get(entry.interactionId) ?? 0) > entry.seq;
1262
- switch (entry.payloadStatus) {
1295
+ return entries.flatMap((entry2) => {
1296
+ const invalid = { kind: "invalid_status", seq: entry2.seq, status: entry2.payloadStatus };
1297
+ const hasLaterDecision = entry2.event === "decision" && (lastDecisionSeq.get(entry2.interactionId) ?? 0) > entry2.seq;
1298
+ switch (entry2.payloadStatus) {
1263
1299
  case "included":
1264
1300
  if (hasLaterDecision) return [invalid];
1265
- return entry.payload && payloadMatchesEntry(entry.payload, entry, site.siteId, crypto) ? [] : [{ kind: "entry_changed", seq: entry.seq }];
1301
+ return entry2.payload && payloadMatchesEntry(entry2.payload, entry2, site.siteId, crypto) ? [] : [{ kind: "entry_changed", seq: entry2.seq }];
1266
1302
  case "changed_since_recorded":
1267
- if (entry.event === "asked" || hasLaterDecision) return [invalid];
1268
- return [{ kind: entry.decisionFinal ? "entry_changed" : "unrecorded_change", seq: entry.seq }];
1303
+ if (entry2.event === "asked" || hasLaterDecision) return [invalid];
1304
+ return [{ kind: entry2.decisionFinal ? "entry_changed" : "unrecorded_change", seq: entry2.seq }];
1269
1305
  case "superseded":
1270
- return entry.event === "asked" || entry.decisionFinal || !hasLaterDecision && site.beforeSeq === null ? [invalid] : [];
1306
+ return entry2.event === "asked" || entry2.decisionFinal || !hasLaterDecision && site.beforeSeq === null ? [invalid] : [];
1271
1307
  case "aged_out":
1272
- return goneBeforeRetentionEnded(entry, site.retentionFloor) ? [{ kind: "row_missing", seq: entry.seq }] : [];
1308
+ return goneBeforeRetentionEnded(entry2, site.retentionFloor) ? [{ kind: "row_missing", seq: entry2.seq }] : [];
1273
1309
  }
1274
1310
  });
1275
1311
  };
1276
1312
  var decisionSequenceFindings = (entries) => {
1277
1313
  const asked = /* @__PURE__ */ new Set();
1278
1314
  const decidedFinally = /* @__PURE__ */ new Set();
1279
- return entries.flatMap((entry) => {
1280
- if (entry.event === "asked") {
1281
- const repeated = asked.has(entry.interactionId);
1282
- asked.add(entry.interactionId);
1283
- return repeated ? [{ kind: "asked_twice", seq: entry.seq }] : [];
1315
+ return entries.flatMap((entry2) => {
1316
+ if (entry2.event === "asked") {
1317
+ const repeated = asked.has(entry2.interactionId);
1318
+ asked.add(entry2.interactionId);
1319
+ return repeated ? [{ kind: "asked_twice", seq: entry2.seq }] : [];
1284
1320
  }
1285
- const afterFinal = decidedFinally.has(entry.interactionId);
1286
- if (entry.decisionFinal) decidedFinally.add(entry.interactionId);
1287
- return afterFinal ? [{ kind: "decision_rewritten", seq: entry.seq }] : [];
1321
+ const afterFinal = decidedFinally.has(entry2.interactionId);
1322
+ if (entry2.decisionFinal) decidedFinally.add(entry2.interactionId);
1323
+ return afterFinal ? [{ kind: "decision_rewritten", seq: entry2.seq }] : [];
1288
1324
  });
1289
1325
  };
1290
1326
  var payloadCountsOf = (entries) => ({
1291
- included: entries.filter((entry) => entry.payloadStatus === "included").length,
1292
- aged_out: entries.filter((entry) => entry.payloadStatus === "aged_out").length,
1293
- superseded: entries.filter((entry) => entry.payloadStatus === "superseded").length,
1294
- changed_since_recorded: entries.filter((entry) => entry.payloadStatus === "changed_since_recorded").length
1327
+ included: entries.filter((entry2) => entry2.payloadStatus === "included").length,
1328
+ aged_out: entries.filter((entry2) => entry2.payloadStatus === "aged_out").length,
1329
+ superseded: entries.filter((entry2) => entry2.payloadStatus === "superseded").length,
1330
+ changed_since_recorded: entries.filter((entry2) => entry2.payloadStatus === "changed_since_recorded").length
1295
1331
  });
1296
1332
  var findingsForCheckpoint = (checkpoint, siteId, hashBySeq, crypto, pinnedKeyIds) => {
1297
1333
  const findings = [];
@@ -1338,7 +1374,7 @@ var knownHeadFindings = (site, hashBySeq, lastSeq, exportedAt, known) => {
1338
1374
  };
1339
1375
  var verifyAuditChainSite = (site, crypto, options) => {
1340
1376
  const entries = [...site.entries].sort((left, right) => left.seq - right.seq);
1341
- const hashBySeq = new Map(entries.map((entry) => [entry.seq, entry.entryHash]));
1377
+ const hashBySeq = new Map(entries.map((entry2) => [entry2.seq, entry2.entryHash]));
1342
1378
  const firstSeq = entries[0]?.seq ?? null;
1343
1379
  const lastSeq = entries[entries.length - 1]?.seq ?? null;
1344
1380
  const checkpointResults = site.checkpoints.map((checkpoint) => ({
@@ -1763,7 +1799,6 @@ var A_SHELL_RUNNING_A_SUBSTITUTION = new RegExp(
1763
1799
  String.raw`${COMMAND_POSITION}${COMMAND_PREFIXES}(?:[^\s;&|()<>` + "`" + String.raw`]*/)?(?:sh|bash|zsh|dash|ksh|source|\.)(?:[ \t]+-[^\s<]*){0,8}[ \t]+(?:<[ \t]*)?[<=](?=\()`,
1764
1800
  "g"
1765
1801
  );
1766
- var AN_EVAL_THAT_RUNS = new RegExp(String.raw`${COMMAND_POSITION}${COMMAND_PREFIXES}eval[ \t]+`, "g");
1767
1802
  var CASE_HEAD = /(^|[\s;&|(])case[ \t]+(?:"[^"\n]*"|'[^'\n]*'|\S+)[ \t\n]+in(?=[\s;])/g;
1768
1803
  var CASE_ARM_OPENING = /;[;&]{0,2}[ \t\n]*\(?[^()\s;][^()\n;]*\)[ \t\n]*/g;
1769
1804
  var CASE_ARM_ENDING = /;;&?|;&/g;
@@ -1826,72 +1861,10 @@ var readingWithShellFormsSpelledOut = (text3) => {
1826
1861
  const reading = SHELL_FORM_REWRITES.reduce((current, rewrite) => rewrite(current), text3);
1827
1862
  return reading === text3 ? null : reading;
1828
1863
  };
1829
- var SHELLS_THAT_RUN_A_SCRIPT_ARGUMENT = /* @__PURE__ */ new Set(["sh", "bash", "zsh", "dash", "ksh"]);
1830
- var SHORT_FLAGS_WITH_THE_COMMAND_FLAG = /^-[A-Za-z]*c[A-Za-z]*$/;
1831
- var SHELL_LONG_OPTIONS_WITH_A_VALUE = /* @__PURE__ */ new Set(["--rcfile", "--init-file"]);
1832
- var SHELL_SHORT_FLAGS_ENDING_IN_AN_OPTION_NAME = /^[-+][A-Za-z]*[oO]$/;
1833
- var SHELL_OPTION_WORD = /^[-+]/;
1834
- var COMMAND_SEPARATOR_INSIDE_A_WORD = /[;&|()`]/;
1835
1864
  var DEEPEST_NESTED_SCRIPT_READ = 3;
1836
1865
  var MOST_SCRIPTS_READ_FROM_ONE_COMMAND = 16;
1837
- var programNamedBy = (word) => basenameOf(word.split(COMMAND_SEPARATOR_INSIDE_A_WORD).filter((piece) => piece !== "").pop() ?? "");
1838
- var scriptArgumentOfAShellAt = (words, index) => {
1839
- if (!SHELLS_THAT_RUN_A_SCRIPT_ARGUMENT.has(programNamedBy(words[index]?.text ?? ""))) return void 0;
1840
- for (let next = index + 1; SHELL_OPTION_WORD.test(words[next]?.text ?? ""); next += 1) {
1841
- const option = words[next]?.text ?? "";
1842
- if (SHORT_FLAGS_WITH_THE_COMMAND_FLAG.test(option)) return words[next + 1]?.text;
1843
- if (SHELL_LONG_OPTIONS_WITH_A_VALUE.has(option) || SHELL_SHORT_FLAGS_ENDING_IN_AN_OPTION_NAME.test(option)) next += 1;
1844
- }
1845
- return void 0;
1846
- };
1847
- var scriptsOfShellsIn = (text3) => {
1848
- const words = shellWordsOf(text3);
1849
- return words === null ? [] : words.flatMap((_, index) => scriptArgumentOfAShellAt(words, index) ?? []);
1850
- };
1851
- var endsTheCommandAsAControlOperator = (text3, index) => {
1852
- const char = text3.charAt(index);
1853
- const before = text3.charAt(index - 1);
1854
- if (char === "|") return before !== ">";
1855
- return char === "&" && before !== ">" && before !== "<" && text3.charAt(index + 1) !== ">";
1856
- };
1857
- var endOfTheSimpleCommandAt = (text3, from) => {
1858
- let depth = 0;
1859
- let quote = null;
1860
- let inBackticks = false;
1861
- for (let index = from; index < text3.length; index += 1) {
1862
- const char = text3.charAt(index);
1863
- if (quote === "'") {
1864
- if (char === "'") quote = null;
1865
- } else if (char === "\\") {
1866
- index += 1;
1867
- } else if (quote === '"') {
1868
- if (char === '"') quote = null;
1869
- } else if (char === "'" || char === '"') {
1870
- quote = char;
1871
- } else if (char === "`") {
1872
- inBackticks = !inBackticks;
1873
- } else if (inBackticks) {
1874
- continue;
1875
- } else if (char === "(") {
1876
- depth += 1;
1877
- } else if (char === ")" && depth > 0) {
1878
- depth -= 1;
1879
- } else if (depth === 0 && (char === "\n" || char === ";" || char === ")" || endsTheCommandAsAControlOperator(text3, index))) {
1880
- return index;
1881
- }
1882
- }
1883
- return text3.length;
1884
- };
1885
- var scriptOfAnEvalEndingAt = (text3, end) => {
1886
- const words = shellWordsOf(text3.slice(end, endOfTheSimpleCommandAt(text3, end)));
1887
- if (words === null) return [];
1888
- const firstComment = words.findIndex((word) => word.comment);
1889
- return [(firstComment === -1 ? words : words.slice(0, firstComment)).map((word) => word.text).join(" ")];
1890
- };
1891
- var scriptsOfEvalsIn = (text3) => [...text3.matchAll(AN_EVAL_THAT_RUNS)].slice(0, MOST_SCRIPTS_READ_FROM_ONE_COMMAND + 1).flatMap((match) => scriptOfAnEvalEndingAt(text3, match.index + match[0].length));
1892
- var scriptsDirectlyInside = (text3) => [...scriptsOfEvalsIn(text3), ...scriptsOfShellsIn(text3)];
1893
1866
  var READING_OF_SCRIPTS_TOO_MANY_TO_READ = ": | sh";
1894
- var readingsOfScriptsPassedToAShell = (text3) => {
1867
+ var readingsOfNestedShellScripts = (text3, scriptsDirectlyInside) => {
1895
1868
  const readings = [];
1896
1869
  let scriptsRead = 0;
1897
1870
  let level = [text3];
@@ -3860,16 +3833,41 @@ var scriptACodexShellCommandRuns = (command) => {
3860
3833
  return script.trim().length === 0 ? null : script;
3861
3834
  };
3862
3835
 
3836
+ // ../contracts/src/codex-permission-profile.ts
3837
+ var CODEX_PERMISSION_PROFILE_METHOD = "item/permissions/requestApproval";
3838
+ var CODEX_PERMISSION_PROFILE_CHOICES = { turn: "Allow this turn", session: "Allow this session", deny: "Deny" };
3839
+ var record2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
3840
+ var keys = (value, allowed) => Object.keys(value).every((key) => allowed.includes(key));
3841
+ var literalAbsolutePath = (value) => typeof value === "string" && value.length > 0 && value.length <= 4096 && /^(\/|[a-z]:[\\/])/i.test(value) && !/[\u0000-\u001f*?\[\]{}]/.test(value) && !value.split(/[\\/]/).some((part) => part === ".." || part === ".");
3842
+ var paths = (value) => value == null || Array.isArray(value) && value.length <= 32 && value.every(literalAbsolutePath);
3843
+ var entry = (value) => record2(value) && keys(value, ["path", "access"]) && (value.access === "read" || value.access === "write" || value.access === "deny") && record2(value.path) && keys(value.path, ["type", "path"]) && value.path.type === "path" && literalAbsolutePath(value.path.path);
3844
+ var isCodexPermissionProfile = (value) => {
3845
+ if (!record2(value) || !keys(value, ["network", "fileSystem"])) return false;
3846
+ const network = value.network;
3847
+ if (network != null && (!record2(network) || !keys(network, ["enabled"]) || network.enabled != null && typeof network.enabled !== "boolean")) return false;
3848
+ const files = value.fileSystem;
3849
+ if (files == null) return true;
3850
+ return record2(files) && keys(files, ["read", "write", "entries", "globScanMaxDepth"]) && paths(files.read) && paths(files.write) && (files.globScanMaxDepth == null || typeof files.globScanMaxDepth === "number" && Number.isSafeInteger(files.globScanMaxDepth) && files.globScanMaxDepth > 0) && (files.entries == null || Array.isArray(files.entries) && files.entries.length <= 32 && files.entries.every(entry));
3851
+ };
3852
+ var codexPermissionPaths = (profile, access) => [
3853
+ ...profile.fileSystem?.[access] ?? [],
3854
+ ...(profile.fileSystem?.entries ?? []).filter((entry2) => entry2.access === access).map((entry2) => entry2.path.path)
3855
+ ];
3856
+ var codexPermissionProfileResponse = (permissions, answer) => ({
3857
+ permissions: answer === CODEX_PERMISSION_PROFILE_CHOICES.turn || answer === CODEX_PERMISSION_PROFILE_CHOICES.session ? permissions : {},
3858
+ scope: answer === CODEX_PERMISSION_PROFILE_CHOICES.session ? "session" : "turn"
3859
+ });
3860
+
3863
3861
  // ../contracts/src/codex-native-approval.ts
3864
3862
  var CODEX_NATIVE_APPROVAL_CAPABILITY = "codex-native-approval-v1";
3865
- var CODEX_NATIVE_APPROVAL_METHODS = ["item/commandExecution/requestApproval", "item/fileChange/requestApproval", "mcpServer/elicitation/request"];
3863
+ var CODEX_NATIVE_APPROVAL_METHODS = ["item/commandExecution/requestApproval", "item/fileChange/requestApproval", "mcpServer/elicitation/request", CODEX_PERMISSION_PROFILE_METHOD];
3866
3864
  var CODEX_NATIVE_APPROVAL_CHOICES = { once: "Allow once", session: "Allow this conversation", deny: "Deny" };
3867
3865
  var CODEX_NATIVE_APPROVAL_REPLIES = { ask: "ask", deny: "deny", native: "native", allow: "allow" };
3868
- var record2 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
3866
+ var record3 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
3869
3867
  var identifier2 = (v) => typeof v === "string" && v.length > 0 && v.length <= 200;
3870
3868
  var text = (v) => typeof v === "string" && v.trim().length > 0 && v.length <= 16384;
3871
3869
  var optionalIdentifier = (v) => v == null || identifier2(v);
3872
- var keys = (v, allowed) => Object.keys(v).every((key) => allowed.includes(key));
3870
+ var keys2 = (v, allowed) => Object.keys(v).every((key) => allowed.includes(key));
3873
3871
  var isMethod = (v) => typeof v === "string" && CODEX_NATIVE_APPROVAL_METHODS.some((method) => method === v);
3874
3872
  var boundedJson = (value) => {
3875
3873
  try {
@@ -3882,12 +3880,12 @@ var BASE_KEYS = ["threadId", "turnId", "itemId", "startedAtMs", "reason"];
3882
3880
  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"];
3883
3881
  var MCP_FLAGS_THAT_ASK_FOR_A_PERSON = ["codex_requires_user_input", "codex_strict_auto_review", "codex_sensitive_action"];
3884
3882
  var COMPUTER_USE_META_KEYS = [...MCP_META_KEYS, "riskLevel", "subtitle", "tool_call_id"];
3885
- 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));
3883
+ var computerUseDisplay = (value) => Array.isArray(value) && value.length <= 16 && value.every((item) => record3(item) && keys2(item, ["name", "display_name", "value"]) && text(item.name) && text(item.display_name) && text(item.value));
3886
3884
  var isExecpolicyAmendment = (value) => Array.isArray(value) && value.length > 0 && value.length <= 128 && value.every((token) => typeof token === "string" && token.length <= 16384);
3887
3885
  var isCommandDecision = (value) => {
3888
3886
  if (typeof value === "string") return ["accept", "acceptForSession", "decline", "cancel"].includes(value);
3889
- if (!record2(value) || !keys(value, ["acceptWithExecpolicyAmendment"]) || !record2(value.acceptWithExecpolicyAmendment)) return false;
3890
- return keys(value.acceptWithExecpolicyAmendment, ["execpolicy_amendment"]) && isExecpolicyAmendment(value.acceptWithExecpolicyAmendment.execpolicy_amendment);
3887
+ if (!record3(value) || !keys2(value, ["acceptWithExecpolicyAmendment"]) || !record3(value.acceptWithExecpolicyAmendment)) return false;
3888
+ return keys2(value.acceptWithExecpolicyAmendment, ["execpolicy_amendment"]) && isExecpolicyAmendment(value.acceptWithExecpolicyAmendment.execpolicy_amendment);
3891
3889
  };
3892
3890
  var FILE_CHANGE_KINDS = ["add", "delete", "update"];
3893
3891
  var FILE_CHANGE_VERB = { add: "adding", delete: "deleting", update: "editing" };
@@ -3907,7 +3905,7 @@ var withCodexReason = (detail, reason) => text(reason) ? `${detail}
3907
3905
 
3908
3906
  Codex's reason: ${redactSecrets(reason)}` : detail;
3909
3907
  var parseCodexNativeApproval = (value) => {
3910
- if (!record2(value) || !keys(value, ["method", "params", "changes"]) || !isMethod(value.method) || !record2(value.params) || !boundedJson(value)) return null;
3908
+ if (!record3(value) || !keys2(value, ["method", "params", "changes"]) || !isMethod(value.method) || !record3(value.params) || !boundedJson(value)) return null;
3911
3909
  const p = value.params;
3912
3910
  if (!identifier2(p.threadId) || !optionalIdentifier(p.turnId) || !optionalIdentifier(p.itemId)) return null;
3913
3911
  const request = { method: value.method, params: p, ...Array.isArray(value.changes) ? { changes: value.changes } : {} };
@@ -3922,9 +3920,9 @@ var parseCodexNativeApproval = (value) => {
3922
3920
  };
3923
3921
  if (value.method === "mcpServer/elicitation/request") {
3924
3922
  const meta = p._meta;
3925
- const computerUse = record2(meta) && meta.connector_id === "computer-use";
3926
- 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;
3927
- 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;
3923
+ const computerUse = record3(meta) && meta.connector_id === "computer-use";
3924
+ if (value.changes !== void 0 || !keys2(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 || !record3(p.requestedSchema) || !keys2(p.requestedSchema, ["type", "properties", "required", "$schema"]) || p.requestedSchema.type !== "object" || !record3(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;
3925
+ if (!record3(meta) || !keys2(meta, computerUse ? COMPUTER_USE_META_KEYS : MCP_META_KEYS) || meta.codex_approval_kind !== "mcp_tool_call" || !identifier2(meta.tool_name) || !record3(meta.tool_params) || meta.tool_params_display != null && !(computerUse ? computerUseDisplay(meta.tool_params_display) : record3(meta.tool_params_display))) return null;
3928
3926
  if (computerUse && (meta.riskLevel !== "low" && meta.riskLevel !== "high" || meta.subtitle != null && !text(meta.subtitle) || !optionalIdentifier(meta.tool_call_id))) return null;
3929
3927
  if (MCP_FLAGS_THAT_ASK_FOR_A_PERSON.some((key) => meta[key] != null && typeof meta[key] !== "boolean")) return null;
3930
3928
  if (meta.approvals_reviewer != null && meta.approvals_reviewer !== "user") return null;
@@ -3956,8 +3954,23 @@ var parseCodexNativeApproval = (value) => {
3956
3954
  };
3957
3955
  }
3958
3956
  if (!identifier2(p.turnId) || !identifier2(p.itemId) || !Number.isSafeInteger(p.startedAtMs) || p.reason != null && !text(p.reason)) return null;
3957
+ if (value.method === CODEX_PERMISSION_PROFILE_METHOD) {
3958
+ if (value.changes !== void 0 || !keys2(p, [...BASE_KEYS, "cwd", "environmentId", "permissions"]) || !text(p.cwd) || p.environmentId != null && p.environmentId !== "local" || !isCodexPermissionProfile(p.permissions)) return null;
3959
+ return {
3960
+ ...base,
3961
+ permissionProfile: p.permissions,
3962
+ codexAsksForAPerson: true,
3963
+ cwd: p.cwd,
3964
+ toolName: "request_permissions",
3965
+ toolInputs: [{ permissions: p.permissions }],
3966
+ scopePaths: [...codexPermissionPaths(p.permissions, "read"), ...codexPermissionPaths(p.permissions, "write")],
3967
+ question: "Allow these permissions for this turn or session?",
3968
+ detail: withCodexReason(JSON.stringify(p.permissions, null, 2), p.reason),
3969
+ options: [CODEX_PERMISSION_PROFILE_CHOICES.turn, CODEX_PERMISSION_PROFILE_CHOICES.session, CODEX_PERMISSION_PROFILE_CHOICES.deny]
3970
+ };
3971
+ }
3959
3972
  if (value.method === "item/commandExecution/requestApproval") {
3960
- 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;
3973
+ if (value.changes !== void 0 || !keys2(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;
3961
3974
  const decisions = p.availableDecisions ?? ["accept", "decline", "cancel"];
3962
3975
  if (!Array.isArray(decisions) || !decisions.includes("accept") || !decisions.some((v) => v === "decline" || v === "cancel") || !decisions.every(isCommandDecision)) return null;
3963
3976
  const command = scriptACodexShellCommandRuns(p.command) ?? p.command;
@@ -3973,24 +3986,25 @@ Directory: ${redactSecrets(p.cwd)}`, p.reason),
3973
3986
  negativeDecision: decisions.includes("decline") ? "decline" : "cancel"
3974
3987
  };
3975
3988
  }
3976
- if (!keys(p, [...BASE_KEYS, "grantRoot"]) || p.grantRoot != null || !Array.isArray(value.changes) || value.changes.length === 0 || value.changes.length > 32) return null;
3989
+ if (!keys2(p, [...BASE_KEYS, "grantRoot"]) || p.grantRoot != null || !Array.isArray(value.changes) || value.changes.length === 0 || value.changes.length > 32) return null;
3977
3990
  const changes = [];
3978
3991
  for (const change of value.changes) {
3979
- 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;
3992
+ if (!record3(change) || !keys2(change, ["path", "kind", "diff"]) || !text(change.path) || typeof change.diff !== "string" || !record3(change.kind) || !keys2(change.kind, ["type", "move_path"]) || !isFileChangeKind(change.kind.type) || change.kind.move_path != null) return null;
3980
3993
  changes.push({ kind: change.kind.type, path: change.path, diff: change.diff });
3981
3994
  }
3982
- const paths = changes.map((change) => change.path);
3995
+ const paths2 = changes.map((change) => change.path);
3983
3996
  return {
3984
3997
  ...base,
3985
3998
  toolName: "Edit",
3986
- toolInputs: paths.map((file_path) => ({ file_path })),
3987
- scopePaths: paths,
3999
+ toolInputs: paths2.map((file_path) => ({ file_path })),
4000
+ scopePaths: paths2,
3988
4001
  question: fileChangeQuestion(changes),
3989
4002
  detail: withCodexReason(changes.map((change) => `${redactSecrets(labelledFileChange(change))}
3990
4003
  ${redactSecretsDeep(change.diff)}`).join("\n\n"), p.reason)
3991
4004
  };
3992
4005
  };
3993
4006
  var codexNativeApprovalResponse = (approval, answer) => {
4007
+ if (approval.permissionProfile) return codexPermissionProfileResponse(approval.permissionProfile, answer);
3994
4008
  const accepted = approval.options.includes(answer) && (answer === CODEX_NATIVE_APPROVAL_CHOICES.once || answer === CODEX_NATIVE_APPROVAL_CHOICES.session);
3995
4009
  if (approval.request.method === "mcpServer/elicitation/request") return {
3996
4010
  action: accepted ? "accept" : "decline",
@@ -4014,10 +4028,16 @@ var compressTranscriptRecord = (raw, deflateRaw) => {
4014
4028
  if (raw.length > TRANSCRIPT_RECORD_MAX_INFLATED_BYTES) return raw;
4015
4029
  const deflated = deflateRaw(raw);
4016
4030
  if (!compressionShrinks(raw, deflated)) return raw;
4017
- const record4 = new Uint8Array(deflated.length + 1);
4018
- record4[0] = COMPRESSED_TRANSCRIPT_RECORD_MARKER;
4019
- record4.set(deflated, 1);
4020
- return record4;
4031
+ const record5 = new Uint8Array(deflated.length + 1);
4032
+ record5[0] = COMPRESSED_TRANSCRIPT_RECORD_MARKER;
4033
+ record5.set(deflated, 1);
4034
+ return record5;
4035
+ };
4036
+
4037
+ // ../contracts/src/spawn-delivery.ts
4038
+ var SPAWN_RECOVERY = {
4039
+ receiptRetentionMs: 7 * 24 * 60 * 60 * 1e3,
4040
+ retrySendWindowMs: 60 * 60 * 1e3
4021
4041
  };
4022
4042
 
4023
4043
  // ../contracts/src/claude-inbox.ts
@@ -4034,11 +4054,11 @@ var CLAUDE_INBOX = {
4034
4054
  sender: "pushary",
4035
4055
  carrier: "native"
4036
4056
  };
4037
- var record3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
4057
+ var record4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
4038
4058
  var text2 = (value) => typeof value === "string" && value.length > 0;
4039
4059
  var sessionIdPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
4040
4060
  var parseClaudeInboxSession = (value, platform = "darwin") => {
4041
- if (!record3(value) || !Number.isSafeInteger(value.pid) || typeof value.pid !== "number" || value.pid <= 0 || !text2(value.sessionId) || !sessionIdPattern.test(value.sessionId) || !text2(value.cwd) || !text2(value.procStart) || platform === "linux" && !text2(value.pidDomain) || !text2(value.messagingSocketPath) || value.peerProtocol !== CLAUDE_INBOX.protocol || !text2(value.version) || !supportsClaudeInbox(value.version, platform))
4061
+ if (!record4(value) || !Number.isSafeInteger(value.pid) || typeof value.pid !== "number" || value.pid <= 0 || !text2(value.sessionId) || !sessionIdPattern.test(value.sessionId) || !text2(value.cwd) || !text2(value.procStart) || platform === "linux" && !text2(value.pidDomain) || !text2(value.messagingSocketPath) || value.peerProtocol !== CLAUDE_INBOX.protocol || !text2(value.version) || !supportsClaudeInbox(value.version, platform))
4042
4062
  return null;
4043
4063
  return {
4044
4064
  pid: value.pid,
@@ -4059,19 +4079,19 @@ var claudeInboxAction = (progress) => {
4059
4079
  }
4060
4080
  return progress.attempted ? "observe" /* observe */ : "submit" /* submit */;
4061
4081
  };
4062
- var isClaudeInboxReceipt = (value, sessionId, commandId) => record3(value) && value.type === "user" && value.sessionId === sessionId && value.uuid === commandId && record3(value.origin) && value.origin.kind === "peer" && value.origin.msg_id === commandId;
4082
+ var isClaudeInboxReceipt = (value, sessionId, commandId) => record4(value) && value.type === "user" && value.sessionId === sessionId && value.uuid === commandId && record4(value.origin) && value.origin.kind === "peer" && value.origin.msg_id === commandId;
4063
4083
  var CLAUDE_INBOX_MAX_SESSIONS = 128;
4064
4084
  var parseClaudeInboxCommand = (value) => {
4065
- if (!record3(value) || !text2(value.id) || !sessionIdPattern.test(value.id) || !text2(value.text) || typeof value.expiresAtMs !== "number" || !Number.isSafeInteger(value.expiresAtMs))
4085
+ if (!record4(value) || !text2(value.id) || !sessionIdPattern.test(value.id) || !text2(value.text) || typeof value.expiresAtMs !== "number" || !Number.isSafeInteger(value.expiresAtMs))
4066
4086
  return null;
4067
4087
  return { id: value.id, text: value.text, expiresAtMs: value.expiresAtMs };
4068
4088
  };
4069
4089
  var parseClaudeInboxPoll = (value) => {
4070
- if (!record3(value) || value.protocol !== CLAUDE_INBOX.protocol || !Array.isArray(value.sessionIds) || value.sessionIds.length > CLAUDE_INBOX_MAX_SESSIONS || !value.sessionIds.every((id) => nativeIdentifier(id)))
4090
+ if (!record4(value) || value.protocol !== CLAUDE_INBOX.protocol || !Array.isArray(value.sessionIds) || value.sessionIds.length > CLAUDE_INBOX_MAX_SESSIONS || !value.sessionIds.every((id) => nativeIdentifier(id)))
4071
4091
  return null;
4072
4092
  return value.sessionIds;
4073
4093
  };
4074
- var parseClaudeInboxClaim = (value) => record3(value) && value.protocol === CLAUDE_INBOX.protocol ? parseClaudeInboxCommand(value.command) : null;
4094
+ var parseClaudeInboxClaim = (value) => record4(value) && value.protocol === CLAUDE_INBOX.protocol ? parseClaudeInboxCommand(value.command) : null;
4075
4095
  var CLAUDE_INBOX_RECEIVER = {
4076
4096
  pollMs: 3e3,
4077
4097
  heartbeatMs: 6e4,
@@ -4388,13 +4408,7 @@ var patternToolName = (pattern) => {
4388
4408
  const open = argumentOpenIndex(pattern);
4389
4409
  return open === -1 ? pattern : pattern.slice(0, open);
4390
4410
  };
4391
- var matchToolPattern = (pattern, toolName, arg, intent = PATTERN_INTENT.grant) => {
4392
- const open = argumentOpenIndex(pattern);
4393
- if (open === -1) {
4394
- return pattern === toolName ? "tool" : "none";
4395
- }
4396
- if (patternToolName(pattern) !== toolName || arg === void 0) return "none";
4397
- const inner = pattern.slice(open + 1, -1);
4411
+ var rankOfArgument = (toolName, inner, arg, intent) => {
4398
4412
  if (inner.endsWith(":*")) {
4399
4413
  const prefix = inner.slice(0, -2);
4400
4414
  return rankWholeOrSegments(toolName, arg, intent, (segment) => segment.startsWith(prefix));
@@ -4407,6 +4421,17 @@ var matchToolPattern = (pattern, toolName, arg, intent = PATTERN_INTENT.grant) =
4407
4421
  }
4408
4422
  return arg === inner ? "exact" : "none";
4409
4423
  };
4424
+ var bestRankOf = (ranks) => ranks.reduce((best, rank) => matchRankWeight(rank) > matchRankWeight(best) ? rank : best, "none");
4425
+ var argumentSpellingsFor = (toolName, arg, intent) => toolName in POLICY_PATH_KEYS ? pathSpellingsFor(arg, intent) : [arg];
4426
+ var matchToolPattern = (pattern, toolName, arg, intent = PATTERN_INTENT.grant) => {
4427
+ const open = argumentOpenIndex(pattern);
4428
+ if (open === -1) {
4429
+ return pattern === toolName ? "tool" : "none";
4430
+ }
4431
+ if (patternToolName(pattern) !== toolName || arg === void 0) return "none";
4432
+ const inner = pattern.slice(open + 1, -1);
4433
+ return bestRankOf(argumentSpellingsFor(toolName, arg, intent).map((spelling) => rankOfArgument(toolName, inner, spelling, intent)));
4434
+ };
4410
4435
  var POLICY_PATH_KEYS = {
4411
4436
  Read: "file_path",
4412
4437
  Edit: "file_path",
@@ -4426,7 +4451,8 @@ var extractPolicyArg = (toolName, toolInput) => {
4426
4451
  return typeof value === "string" ? value : void 0;
4427
4452
  };
4428
4453
  var normalizeSeparators = (value) => value.replace(/\\/g, "/");
4429
- var isAbsolutePath = (value) => value.startsWith("/") || /^[A-Za-z]:\//.test(value);
4454
+ var DRIVE_ROOT = /^[A-Za-z]:\//;
4455
+ var isAbsolutePath = (value) => value.startsWith("/") || DRIVE_ROOT.test(value);
4430
4456
  var relativeToCwd = (path, cwd) => {
4431
4457
  const base = normalizeSeparators(cwd).replace(/\/+$/, "");
4432
4458
  if (!base) return void 0;
@@ -4435,10 +4461,86 @@ var relativeToCwd = (path, cwd) => {
4435
4461
  const rest = path.slice(prefix.length);
4436
4462
  return rest.length > 0 ? rest : void 0;
4437
4463
  };
4438
- var policyArgForms = (toolName, toolInput, cwd) => {
4439
- const raw = extractPolicyArg(toolName, toolInput);
4440
- if (raw === void 0) return [];
4441
- if (!(toolName in POLICY_PATH_KEYS)) return [raw];
4464
+ var CURRENT_SEGMENT = ".";
4465
+ var PARENT_SEGMENT = "..";
4466
+ var BACKSLASH2 = "\\";
4467
+ var NETWORK_SHARE_PREFIX = "//";
4468
+ var DOT_SEGMENT = /(?:^|[\\/])\.{1,2}(?=[\\/]|$)/;
4469
+ var WINDOWS_PATH = /^(?:[A-Za-z]:[\\/]|\\\\)/;
4470
+ var FIRST_SEGMENT_WITH_AN_UNKNOWN_BASE = /^(?:~|\$|%|[A-Za-z]:)/;
4471
+ var hasDotSegment = (path) => DOT_SEGMENT.test(path);
4472
+ var PATH_SPELLINGS_CACHE_MAX = 64;
4473
+ var anchorOf = (path) => {
4474
+ const drive = DRIVE_ROOT.exec(path)?.[0];
4475
+ if (drive !== void 0) return { base: "root", prefix: drive, segments: path.slice(drive.length).split("/") };
4476
+ if (path.startsWith("/")) return { base: "root", prefix: "/", segments: path.slice(1).split("/") };
4477
+ const [first = "", ...rest] = path.split("/");
4478
+ return FIRST_SEGMENT_WITH_AN_UNKNOWN_BASE.test(first) ? { base: "unknown", prefix: `${first}/`, segments: rest } : { base: "relative", prefix: "", segments: path.split("/") };
4479
+ };
4480
+ var joinedToDirectory = (directory, path) => directory.endsWith("/") ? `${directory}${path}` : `${directory}/${path}`;
4481
+ var standingOf = (base, climbs) => {
4482
+ if (climbs === 0) return "placed";
4483
+ return base === "relative" ? "above_its_start" : "unplaceable";
4484
+ };
4485
+ var readingOf = (path, directory) => {
4486
+ if (path.startsWith(NETWORK_SHARE_PREFIX)) return { spelling: path, standing: "unplaceable" };
4487
+ const anchor = anchorOf(path);
4488
+ if (anchor.base === "relative" && directory !== void 0) return readingOf(joinedToDirectory(directory, path), void 0);
4489
+ const kept = [];
4490
+ let climbs = 0;
4491
+ for (const segment of anchor.segments) {
4492
+ if (segment === "" || segment === CURRENT_SEGMENT) continue;
4493
+ if (segment !== PARENT_SEGMENT) kept.push(segment);
4494
+ else if (kept.length > 0) kept.pop();
4495
+ else if (anchor.base !== "root") climbs += 1;
4496
+ }
4497
+ const spelling = `${anchor.prefix}${[...Array(climbs).fill(PARENT_SEGMENT), ...kept].join("/")}`;
4498
+ return { spelling: spelling.length > 0 ? spelling : CURRENT_SEGMENT, standing: standingOf(anchor.base, climbs) };
4499
+ };
4500
+ var hasOneSeparatorReading = (path, directory) => !path.includes(BACKSLASH2) || WINDOWS_PATH.test(path) || directory !== void 0 && DRIVE_ROOT.test(directory);
4501
+ var separatorReadingsOf = (path, directory) => hasOneSeparatorReading(path, directory) ? [normalizeSeparators(path)] : [path, normalizeSeparators(path)];
4502
+ var spellingsOfReadings = (readings) => [...new Set(readings.map((reading) => reading.spelling))];
4503
+ var isPlaced = (reading) => reading.standing === "placed";
4504
+ var isUnplaceable = (reading) => reading.standing === "unplaceable";
4505
+ var locatePath = (path, directory) => {
4506
+ const readings = separatorReadingsOf(path, directory).map((reading) => readingOf(reading, directory));
4507
+ const [only, ...others] = spellingsOfReadings(readings);
4508
+ return only !== void 0 && others.length === 0 && readings.every(isPlaced) ? { kind: "located", path: only } : { kind: "unlocated", readings };
4509
+ };
4510
+ var isTooLongToMatch = (path) => path.length > GLOB_MAX_ARG_LENGTH;
4511
+ var locatedDirectoryOf = (cwd) => {
4512
+ if (!cwd) return void 0;
4513
+ const location = locatePath(cwd);
4514
+ return location.kind === "located" && isAbsolutePath(location.path) ? location.path : void 0;
4515
+ };
4516
+ var unlocatedPathSpellings = (path, readings) => [.../* @__PURE__ */ new Set([path, normalizeSeparators(path), ...spellingsOfReadings(readings)])];
4517
+ var matchSpellingsOf = (path) => {
4518
+ const location = locatePath(path);
4519
+ return location.kind === "located" ? { grant: [location.path], restrict: [location.path] } : { grant: [], restrict: unlocatedPathSpellings(path, location.readings) };
4520
+ };
4521
+ var pathSpellingsCache = /* @__PURE__ */ new Map();
4522
+ var cachedMatchSpellingsOf = (path) => {
4523
+ const cached = pathSpellingsCache.get(path);
4524
+ if (cached !== void 0) return cached;
4525
+ const spellings = matchSpellingsOf(path);
4526
+ if (pathSpellingsCache.size >= PATH_SPELLINGS_CACHE_MAX) pathSpellingsCache.clear();
4527
+ pathSpellingsCache.set(path, spellings);
4528
+ return spellings;
4529
+ };
4530
+ var pathSpellingsFor = (path, intent) => {
4531
+ if (isTooLongToMatch(path)) return intent === PATTERN_INTENT.restrict ? [path] : [];
4532
+ if (!hasDotSegment(path)) return [path];
4533
+ const spellings = cachedMatchSpellingsOf(path);
4534
+ return intent === PATTERN_INTENT.restrict ? spellings.restrict : spellings.grant;
4535
+ };
4536
+ var scopeSpellingsOf = (path) => {
4537
+ if (!hasDotSegment(path)) return [path];
4538
+ if (isTooLongToMatch(path)) return void 0;
4539
+ const location = locatePath(path);
4540
+ if (location.kind === "located") return [location.path];
4541
+ return location.readings.some(isUnplaceable) ? void 0 : spellingsOfReadings(location.readings);
4542
+ };
4543
+ var writtenPathForms = (raw, cwd) => {
4442
4544
  const forms = [raw];
4443
4545
  const normalized = normalizeSeparators(raw);
4444
4546
  if (normalized !== raw) forms.push(normalized);
@@ -4448,14 +4550,24 @@ var policyArgForms = (toolName, toolInput, cwd) => {
4448
4550
  }
4449
4551
  return forms;
4450
4552
  };
4553
+ var locatedPathForms = (path, directory) => {
4554
+ const relative = directory !== void 0 && isAbsolutePath(path) ? relativeToCwd(path, directory) : void 0;
4555
+ return relative === void 0 ? [path] : [path, relative];
4556
+ };
4557
+ var resolvedPathForms = (raw, cwd) => {
4558
+ const directory = locatedDirectoryOf(cwd);
4559
+ const location = locatePath(raw, directory);
4560
+ return location.kind === "located" ? locatedPathForms(location.path, directory) : [raw];
4561
+ };
4562
+ var policyArgForms = (toolName, toolInput, cwd) => {
4563
+ const raw = extractPolicyArg(toolName, toolInput);
4564
+ if (raw === void 0) return [];
4565
+ if (!(toolName in POLICY_PATH_KEYS)) return [raw];
4566
+ return !isTooLongToMatch(raw) && hasDotSegment(raw) ? resolvedPathForms(raw, cwd) : writtenPathForms(raw, cwd);
4567
+ };
4451
4568
  var matchToolPatternAny = (pattern, toolName, args, intent = PATTERN_INTENT.grant) => {
4452
4569
  if (args.length === 0) return matchToolPattern(pattern, toolName);
4453
- let best = "none";
4454
- for (const arg of args) {
4455
- const rank = matchToolPattern(pattern, toolName, arg, intent);
4456
- if (matchRankWeight(rank) > matchRankWeight(best)) best = rank;
4457
- }
4458
- return best;
4570
+ return bestRankOf(args.map((arg) => matchToolPattern(pattern, toolName, arg, intent)));
4459
4571
  };
4460
4572
  var SAFE_SHELL_COMMANDS = /* @__PURE__ */ new Set([
4461
4573
  "ls",
@@ -6811,9 +6923,17 @@ var substitutionFedTo = (pieces, index) => {
6811
6923
  const next = pieces[index + 1];
6812
6924
  return next !== void 0 && SUBSTITUTION_OPENERS.has(next.before) ? next.text : null;
6813
6925
  };
6926
+ var withoutOutputRedirectionTargets = (text3) => {
6927
+ const visible = shellVisibleText(text3);
6928
+ const removeVisibleRedirection = (match, _target, offset) => {
6929
+ const operator = offset + match.search(REDIRECTION_OPERATOR_CHARACTER);
6930
+ return visible === null || REDIRECTION_OPERATOR_CHARACTER.test(visible.charAt(operator)) ? " " : match;
6931
+ };
6932
+ return text3.replace(OUTPUT_REDIRECTION, removeVisibleRedirection);
6933
+ };
6814
6934
  var roughSegmentsOf = (command) => {
6815
6935
  const { text: text3, bodies } = withHeredocBodiesSetAside(commandForReading(command));
6816
- const pieces = roughPiecesOf(text3.replace(INPUT_REDIRECTION, ` ${REDIRECTED_INPUT_MARK} `).replace(OUTPUT_REDIRECTION, " "));
6936
+ const pieces = roughPiecesOf(withoutOutputRedirectionTargets(text3.replace(INPUT_REDIRECTION, ` ${REDIRECTED_INPUT_MARK} `)));
6817
6937
  let heredocsSeen = 0;
6818
6938
  return pieces.map((piece, index) => {
6819
6939
  const heredocCount = occurrencesOf(piece.text, HEREDOC_MARK);
@@ -7385,6 +7505,20 @@ var runnerReadingOf = (innermost) => {
7385
7505
  const commands = [.../* @__PURE__ */ new Set([...fromScript, ...named.map(verbatimInvocationText), ...afterEndOfOptions.map(verbatimInvocationText)])];
7386
7506
  return commands.length === 0 ? NO_INLINE_SCRIPT : { kind: "readable", scripts: commands };
7387
7507
  };
7508
+ var scriptsOfExecutablePiece = (piece) => {
7509
+ const invocation = innermostInvocation(invocationOfRoughPiece(piece.text));
7510
+ const scripts = inlineScriptsOf(invocation, []);
7511
+ const runner = runnerReadingOf(invocation);
7512
+ return [
7513
+ ...scripts.kind === "readable" ? scripts.scripts : [],
7514
+ ...runner.kind === "readable" ? runner.scripts : []
7515
+ ];
7516
+ };
7517
+ var scriptsExecutedBy = (command) => {
7518
+ const readable = readingWithoutCommentsOrAnsiEscapes(command) ?? command;
7519
+ return roughPiecesOf(withoutOutputRedirectionTargets(readable)).flatMap(scriptsOfExecutablePiece);
7520
+ };
7521
+ var readingsOfScriptsPassedToAShell = (command) => readingsOfNestedShellScripts(command, scriptsExecutedBy);
7388
7522
  var MAX_SPELLED_FORMS = 4096;
7389
7523
  var markTruncated = (accumulator) => {
7390
7524
  accumulator.hidesWhatItRuns = true;
@@ -8399,17 +8533,16 @@ var matchesGlobPath = (glob, path) => {
8399
8533
  return compiled ? matchGlobTokens(compiled, path) : false;
8400
8534
  };
8401
8535
  var SCOPE_PATH_MAX_LENGTH = 200;
8536
+ var allowedPathsCover = (allowedPaths, path) => scopeSpellingsOf(path)?.every((spelling) => allowedPaths.some((rule) => matchesGlobPath(rule, spelling))) ?? false;
8402
8537
  var evaluateScope = (contract, path) => {
8403
8538
  if (!contract) return { outcome: "no_contract" };
8404
8539
  if (typeof path !== "string" || path.length === 0) return { outcome: "in_scope" };
8540
+ const offLimitsSpellings = pathSpellingsFor(path, PATTERN_INTENT.restrict);
8405
8541
  for (const rule of contract.offLimitsPaths) {
8406
- if (matchesGlobPath(rule, path)) return { outcome: "off_limits", path, rule };
8542
+ if (offLimitsSpellings.some((spelling) => matchesGlobPath(rule, spelling))) return { outcome: "off_limits", path, rule };
8407
8543
  }
8408
8544
  if (contract.allowedPaths.length === 0) return { outcome: "in_scope" };
8409
- for (const rule of contract.allowedPaths) {
8410
- if (matchesGlobPath(rule, path)) return { outcome: "in_scope" };
8411
- }
8412
- return { outcome: "out_of_scope", path };
8545
+ return allowedPathsCover(contract.allowedPaths, path) ? { outcome: "in_scope" } : { outcome: "out_of_scope", path };
8413
8546
  };
8414
8547
  var scopeRequiresHuman = (verdict) => verdict.outcome === "out_of_scope" || verdict.outcome === "off_limits";
8415
8548
  var widenablePath = (path) => path.length > 0 && path.length <= SCOPE_PATH_MAX_LENGTH ? path : void 0;
@@ -8622,10 +8755,10 @@ var namesOneToolAfterPrefix = (toolName, prefix) => {
8622
8755
  return tool.length > 0 && !tool.includes(SERVER_AND_TOOL_SEPARATOR);
8623
8756
  };
8624
8757
  var isPusharyConnectorTool = (toolName) => PUSHARY_CONNECTOR_TOOL_PREFIXES.some((prefix) => namesOneToolAfterPrefix(toolName, prefix));
8625
- var strictestScopeVerdict = (scope, paths) => {
8626
- if (paths.length === 0) return evaluateScope(scope, void 0);
8758
+ var strictestScopeVerdict = (scope, paths2) => {
8759
+ if (paths2.length === 0) return evaluateScope(scope, void 0);
8627
8760
  let worst = { outcome: "in_scope" };
8628
- for (const path of paths) {
8761
+ for (const path of paths2) {
8629
8762
  const verdict = evaluateScope(scope, path);
8630
8763
  if (verdict.outcome === "off_limits") return verdict;
8631
8764
  if (verdict.outcome === "out_of_scope") worst = verdict;
@@ -8704,8 +8837,8 @@ var isBlockedActionRequest = (request) => isBlockedActionEvent(request) && block
8704
8837
  var canonicalJsonText = (value) => {
8705
8838
  if (Array.isArray(value)) return `[${value.map(canonicalJsonText).join(",")}]`;
8706
8839
  if (value !== null && typeof value === "object") {
8707
- const record4 = value;
8708
- return `{${Object.keys(record4).filter((key) => record4[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${canonicalJsonText(record4[key])}`).join(",")}}`;
8840
+ const record5 = value;
8841
+ return `{${Object.keys(record5).filter((key) => record5[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${canonicalJsonText(record5[key])}`).join(",")}}`;
8709
8842
  }
8710
8843
  return JSON.stringify(value) ?? "null";
8711
8844
  };
@@ -8908,7 +9041,10 @@ var runsACommandThatNeedsAPerson = ({ toolName, toolInputs }) => SHELL_DIALECT_B
8908
9041
  const command = extractPolicyArg(toolName, toolInput);
8909
9042
  return command !== void 0 && (commandNeedsAPerson(toolName, command) || commandWritesThroughARemoteApi(command));
8910
9043
  });
8911
- var namesASecretOrWorkflowFile = (path) => SECRET_FILE_NAME.test(basenameOf(path)) || CI_WORKFLOW_FILE.test(normalizeSeparators(path));
9044
+ var namesASecretOrWorkflowFile = (path) => {
9045
+ const written = withoutDotSegments(normalizeSeparators(path));
9046
+ return SECRET_FILE_NAME.test(basenameOf(written)) || CI_WORKFLOW_FILE.test(written);
9047
+ };
8912
9048
  var fileEditNeedsAPerson = (toolName, path) => FILE_EDIT_TOOLS.has(toolName) && namesASecretOrWorkflowFile(path);
8913
9049
  var fileEditNeedsAPersonWithPermissionsOff = (toolName, path) => FILE_EDIT_TOOLS.has(toolName) && pathNeedsAPersonToChange(path);
8914
9050
  var editsAFileThatNeedsAPerson = ({ toolName, toolInputs }) => toolInputs.some((toolInput) => {
@@ -9354,11 +9490,11 @@ var elicitationEnum = (property) => {
9354
9490
  return members.length === property.enum.length && members.length >= ELICITATION_MIN_OPTIONS ? members : null;
9355
9491
  };
9356
9492
  var readElicitationFields = (schema) => {
9357
- const record4 = elicitationRecord(schema);
9358
- const properties = elicitationRecord(record4?.properties);
9359
- if (!properties || record4?.type !== "object") return null;
9360
- if (Object.keys(record4).some((key) => !["type", "properties", "required", "$schema"].includes(key))) return null;
9361
- if (record4.required !== void 0 && (!Array.isArray(record4.required) || !record4.required.every((name) => typeof name === "string" && Object.hasOwn(properties, name)))) return null;
9493
+ const record5 = elicitationRecord(schema);
9494
+ const properties = elicitationRecord(record5?.properties);
9495
+ if (!properties || record5?.type !== "object") return null;
9496
+ if (Object.keys(record5).some((key) => !["type", "properties", "required", "$schema"].includes(key))) return null;
9497
+ if (record5.required !== void 0 && (!Array.isArray(record5.required) || !record5.required.every((name) => typeof name === "string" && Object.hasOwn(properties, name)))) return null;
9362
9498
  const entries = Object.entries(properties);
9363
9499
  if (entries.length === 0) return null;
9364
9500
  const fields = [];
@@ -9528,6 +9664,14 @@ export {
9528
9664
  isCodexQuestionTool,
9529
9665
  parseCodexQuestions,
9530
9666
  codexQuestionAnswerReason,
9667
+ SPAWN_CAPABILITY,
9668
+ CLAUDE_BRIDGE_CAPABILITY,
9669
+ CLAUDE_RESUME_CAPABILITY,
9670
+ CODEX_BRIDGE_CAPABILITY,
9671
+ CODEX_RESUME_CAPABILITY,
9672
+ GEMINI_BRIDGE_CAPABILITY,
9673
+ GEMINI_RESUME_CAPABILITY,
9674
+ sessionProvidersAdvertisedBy,
9531
9675
  CLAUDE_CONNECTOR_URL,
9532
9676
  CLAUDE_CONNECTOR_GUIDE,
9533
9677
  COWORK_CONNECTOR_LIMIT,