pushary 1.9.35 → 1.9.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/dist/bin/pushary-bell-hook.js +25 -25
  4. package/dist/bin/pushary-bell.js +9 -9
  5. package/dist/bin/pushary-claude.js +24 -24
  6. package/dist/bin/pushary-clean.js +52 -45
  7. package/dist/bin/pushary-codex-bridge.js +17 -17
  8. package/dist/bin/pushary-codex-hook.js +65 -41
  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 +31 -28
  14. package/dist/bin/pushary-doctor.js +35 -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 +34 -30
  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 +65 -56
  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-7FQL5NWJ.js → chunk-235LKHLW.js} +301 -90
  43. package/dist/{chunk-LOYSI2CZ.js → chunk-2WZJHJAB.js} +5 -5
  44. package/dist/{chunk-YABMIGR3.js → chunk-3Y73MQPF.js} +1 -1
  45. package/dist/{chunk-GC3SUMYD.js → chunk-4OQHT5IJ.js} +4 -4
  46. package/dist/{chunk-QJ3ENGBT.js → chunk-6SYU5LVK.js} +3 -3
  47. package/dist/{chunk-NKAMF2YJ.js → chunk-6VUVVVVN.js} +1 -1
  48. package/dist/{chunk-3LS3GFJW.js → chunk-AZXPJLKC.js} +1 -1
  49. package/dist/{chunk-A455TSHF.js → chunk-B7SE22M7.js} +2 -2
  50. package/dist/{chunk-XLXG6MA5.js → chunk-DG5QHKJA.js} +3 -3
  51. package/dist/{chunk-7IVV4LLF.js → chunk-DYALNCS6.js} +3 -3
  52. package/dist/{chunk-PEEJP4HN.js → chunk-EK6PRPCY.js} +4 -4
  53. package/dist/{chunk-FPYBX36E.js → chunk-F3J6JFR2.js} +5 -5
  54. package/dist/{chunk-Z6HDYK2A.js → chunk-FFRH7KZP.js} +2 -2
  55. package/dist/{chunk-V4ZIG66K.js → chunk-GKTVIN4F.js} +1 -1
  56. package/dist/{chunk-YRDNKY77.js → chunk-GQSJVYKN.js} +6 -6
  57. package/dist/{chunk-EGTRIM74.js → chunk-GSP7CC52.js} +4 -4
  58. package/dist/{chunk-NMQLY4PE.js → chunk-GUHM2UQO.js} +2 -2
  59. package/dist/{chunk-OZMGO4WF.js → chunk-HA22GGDG.js} +5 -5
  60. package/dist/{chunk-WFPXKCN4.js → chunk-HJF57K2U.js} +5 -5
  61. package/dist/{chunk-VTAC5FBZ.js → chunk-HK2RPWAD.js} +1 -1
  62. package/dist/{chunk-SMSX4TCC.js → chunk-HQR6DYVG.js} +1 -1
  63. package/dist/{chunk-FQQSW7MD.js → chunk-ISNGKZG4.js} +1 -1
  64. package/dist/{chunk-EJWSE7S7.js → chunk-JLQV3XLV.js} +4 -4
  65. package/dist/{chunk-A5FFSXZE.js → chunk-JMLJHKJN.js} +2 -2
  66. package/dist/{chunk-7S7H7V5V.js → chunk-KHLYOIPY.js} +97 -40
  67. package/dist/{chunk-HVUBWLER.js → chunk-KZ3XE3JG.js} +34 -109
  68. package/dist/{chunk-CK3W7Q5S.js → chunk-MAGB6VW6.js} +1 -1
  69. package/dist/{chunk-DCBSD22V.js → chunk-N5WEEYV6.js} +3 -3
  70. package/dist/{chunk-U7CN5HG2.js → chunk-NDQXKLGE.js} +5 -5
  71. package/dist/{chunk-IRU7DKJW.js → chunk-NPE44CX4.js} +7 -3
  72. package/dist/{chunk-22YSHBTI.js → chunk-NWSWP3KY.js} +3 -3
  73. package/dist/{chunk-HQKYWUBF.js → chunk-OSLC7G3D.js} +2 -2
  74. package/dist/{chunk-7UGGCTTW.js → chunk-PDDJKGIW.js} +2 -2
  75. package/dist/chunk-PDRKQSC6.js +184 -0
  76. package/dist/{chunk-4PIAOJAW.js → chunk-PYWLW7PC.js} +1 -1
  77. package/dist/{chunk-6OGDGQTT.js → chunk-Q3TCLMYC.js} +5 -5
  78. package/dist/{chunk-57FFQR46.js → chunk-Q52PBCN7.js} +1 -1
  79. package/dist/{chunk-DQKEGNTI.js → chunk-QUKATQ66.js} +1 -1
  80. package/dist/{chunk-UPRNSD2T.js → chunk-RFIHLLRH.js} +9 -6
  81. package/dist/{chunk-36ZCFJUI.js → chunk-SNI4FGOV.js} +1 -1
  82. package/dist/{chunk-43H2FUNN.js → chunk-SNUNAIKK.js} +4 -4
  83. package/dist/{chunk-WMB3OCI4.js → chunk-T2NKNQPM.js} +2 -2
  84. package/dist/{chunk-WPSI4246.js → chunk-UEIL72RN.js} +1 -1
  85. package/dist/{chunk-UDECNZYI.js → chunk-UK3WY3LE.js} +2 -2
  86. package/dist/{chunk-E2OZZZKP.js → chunk-UKCGR5T2.js} +2 -2
  87. package/dist/{chunk-CPYOJRDN.js → chunk-V7Q7DQXL.js} +8 -8
  88. package/dist/{chunk-ULJFIF5N.js → chunk-VA36Q6BD.js} +1 -1
  89. package/dist/{chunk-FDNMQEU6.js → chunk-VMIDUNOT.js} +2 -2
  90. package/dist/{chunk-SMRMWDFE.js → chunk-W73URGML.js} +43 -17
  91. package/dist/{chunk-45OXG3VR.js → chunk-WXA3CFZR.js} +1 -1
  92. package/dist/{chunk-4TFD3WAA.js → chunk-YNJ372JU.js} +2 -2
  93. package/dist/{chunk-H52HBSOD.js → chunk-Z5ORWTY3.js} +3 -3
  94. package/dist/{chunk-B5RLJ6QD.js → chunk-ZMR3DSMH.js} +9 -5
  95. package/dist/{chunk-HJNCVY5F.js → chunk-ZQD6GVS7.js} +7 -7
  96. package/dist/{global-upgrade-IZCB4WIE.js → global-upgrade-R57HCUTC.js} +6 -6
  97. package/dist/{paths-4WAA57P5.js → paths-G2AYNZCD.js} +2 -2
  98. package/dist/{reapply-GJ73ZHDD.js → reapply-FHCOPXEN.js} +20 -20
  99. package/dist/src/index.js +19 -19
  100. package/dist/{upgrade-lock-J5PIKSYV.js → upgrade-lock-3I7AF7E3.js} +3 -3
  101. package/package.json +1 -1
  102. package/dist/chunk-FYQG2UTK.js +0 -71
@@ -241,6 +241,20 @@ var AGENTS = {
241
241
  enforcementDetail: "Shell commands, file writes, edits and MCP calls through native PreToolUse hooks in ~/.gemini/config/hooks.json, answered allow or deny.",
242
242
  capabilityNote: 'Antigravity CLI ignores a hook\'s allow unless it runs in always-proceed mode, so connecting it sets `toolPermission: "always-proceed"` when you never chose a mode, and disconnecting puts it back. Pushary is then the only gate: it answers allow or deny and never ask, and a call it cannot decide, one nobody answers, or one made after Pushary was removed is blocked with a reason.'
243
243
  },
244
+ grok: {
245
+ ...defaults,
246
+ label: "Grok Build",
247
+ hookSource: "grok",
248
+ bridged: true,
249
+ policyAgent: "grok",
250
+ repoAware: true,
251
+ disconnectable: true,
252
+ enforcement: "enforced",
253
+ connectVia: "Native hooks + MCP",
254
+ setupCommand: PUSHARY_SETUP_COMMAND,
255
+ enforcementDetail: "Shell, edits and MCP calls through native PreToolUse hooks. Grok's own permission checks still apply after a phone approval.",
256
+ capabilityNote: "Grok fails open if it kills a hook or cannot run it. Setup leaves Grok's permission mode unchanged. Native question and plan dialogs stay in Grok; proactive phone questions use Pushary MCP."
257
+ },
244
258
  windsurf: {
245
259
  ...defaults,
246
260
  label: "Windsurf",
@@ -296,6 +310,59 @@ var normalizeAgentId = (value, accepted) => {
296
310
  return accepted.find((candidate) => names.includes(candidate)) ?? null;
297
311
  };
298
312
 
313
+ // ../contracts/src/json-record.ts
314
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
315
+
316
+ // ../contracts/src/grok.ts
317
+ var GROK_FIELD_ALIASES = {
318
+ sessionId: "session_id",
319
+ transcriptPath: "transcript_path",
320
+ permissionMode: "permission_mode",
321
+ toolName: "tool_name",
322
+ toolInput: "tool_input",
323
+ toolUseId: "tool_use_id",
324
+ toolResult: "tool_response",
325
+ notificationType: "notification_type",
326
+ lastAssistantMessage: "last_assistant_message",
327
+ stopHookActive: "stop_hook_active",
328
+ subagentId: "agent_id",
329
+ subagentType: "agent_type",
330
+ modelId: "model",
331
+ errorDetails: "error_details",
332
+ durationMs: "duration_ms"
333
+ };
334
+ var grokToolResult = (value) => {
335
+ if (!isRecord(value)) return value;
336
+ const { is_error, ...result } = value;
337
+ if (is_error === true) return { ...result, error: "Grok reported an MCP tool error." };
338
+ if (value.type === "Bash" && typeof value.exit_code === "number" && value.exit_code !== 0) {
339
+ return { ...result, error: `Command exited with code ${value.exit_code}.` };
340
+ }
341
+ if (value.type === "SearchReplace" && value.EditsApplied === void 0) return { ...result, error: "Grok could not apply the edit." };
342
+ if (value.type === "ApplyPatch" && value.Success === void 0) return { ...result, error: "Grok could not apply the patch." };
343
+ return is_error === false ? result : value;
344
+ };
345
+ var GROK_UNREADABLE_CALL = "Pushary could not read the complete Grok tool call. Nothing was approved; retry the call.";
346
+ var isGrokHookPayload = (value) => isRecord(value) && typeof value.hookEventName === "string" && typeof value.sessionId === "string";
347
+ var isGrokSessionEndStop = (event, reason) => event === "Stop" && (reason === "channel_closed" || reason === "shutdown");
348
+ var grokHookInput = (event, payload) => {
349
+ const shaped = { ...payload };
350
+ for (const [native, canonical] of Object.entries(GROK_FIELD_ALIASES)) {
351
+ if (payload[native] !== void 0) shaped[canonical] = payload[native];
352
+ }
353
+ const name = typeof payload.hook_event_name === "string" && payload.hook_event_name.length > 0 ? payload.hook_event_name : event;
354
+ if (name) shaped.hook_event_name = name;
355
+ const tool = shaped.tool_name;
356
+ if (typeof tool === "string" && !tool.startsWith("mcp__") && /^[^_].*__.+$/.test(tool)) {
357
+ shaped.tool_name = `mcp__${tool}`;
358
+ }
359
+ if (shaped.tool_response !== void 0) shaped.tool_response = grokToolResult(shaped.tool_response);
360
+ if (payload.toolInputTruncated === true || name === "PreToolUse" && shaped.tool_input === void 0) shaped.tool_input = null;
361
+ if (name === "PostToolUseFailure") shaped.tool_response = { error: payload.error };
362
+ if (name === "StopCancelled") shaped.error = payload.reason ?? "cancelled";
363
+ return shaped;
364
+ };
365
+
299
366
  // ../contracts/src/shell-tools.ts
300
367
  var SHELL_TOOL = "Bash";
301
368
  var POWERSHELL_TOOL = "PowerShell";
@@ -312,8 +379,10 @@ var POSIX_SHELL_TOOLS = new Set(
312
379
  var toolNameForAPosixReading = (toolName) => shellDialectOf(toolName) === "posix" ? SHELL_TOOL : toolName;
313
380
 
314
381
  // ../contracts/src/agent-wiring.ts
315
- var COMPATIBLE_AGENT_TYPES = ["qwen_code", "codebuddy", "qoder", "droid", "devin", "antigravity_cli"];
382
+ var COMPATIBLE_AGENT_TYPES = ["qwen_code", "codebuddy", "qoder", "droid", "devin", "antigravity_cli", "grok"];
316
383
  var isCompatibleAgentType = (value) => typeof value === "string" && COMPATIBLE_AGENT_TYPES.includes(value);
384
+ var homeJson = (...path) => ({ root: "home", path, format: "json" });
385
+ var homeFile = (...path) => ({ root: "home", path });
317
386
  var CANONICAL_PATH_KEYS = ["file_path", "path", "notebook_path"];
318
387
  var CANONICAL_COMMAND_KEYS = ["command"];
319
388
  var SHELL_TOOLS = /* @__PURE__ */ new Set([SHELL_TOOL, POWERSHELL_TOOL]);
@@ -406,7 +475,7 @@ var renderPreToolUseVerdict = (profile, verdict) => {
406
475
  var homePath = (segments) => `~/${segments.join("/")}`;
407
476
  var pusharyMissingReason = (profile) => {
408
477
  const settingBack = profile.soleGate ? ` and remove ${profile.soleGate.key} from ${homePath(profile.soleGate.file)}` : "";
409
- return `Pushary is not installed on this computer any more, so nothing can approve this call and it did not run. Reinstall Pushary, or remove the pushary hook from ${homePath(profile.configFile)}${settingBack}.`;
478
+ return `Pushary is not installed on this computer any more, so nothing can approve this call and it did not run. Reinstall Pushary, or remove the pushary hook from ${homePath(defaultHomeSegments(profile.configFile))}${settingBack}.`;
410
479
  };
411
480
  var refusalOutput = (profile, reason) => JSON.stringify(renderPreToolUseVerdict(profile, {
412
481
  hookSpecificOutput: { permissionDecision: "deny", permissionDecisionReason: reason }
@@ -445,7 +514,10 @@ var fromAntigravity = (event, payload) => {
445
514
  ...error ? { tool_response: { error } } : {}
446
515
  };
447
516
  };
448
- var claudeShapedHookInput = (dialect, event, payload) => dialect === "antigravity" ? fromAntigravity(event, payload) : payload;
517
+ var claudeShapedHookInput = (dialect, event, payload) => {
518
+ if (dialect === "grok") return grokHookInput(event, payload);
519
+ return dialect === "antigravity" ? fromAntigravity(event, payload) : payload;
520
+ };
449
521
  var CLAUDE_SHAPED_EVENTS = [
450
522
  "PreToolUse",
451
523
  "PostToolUse",
@@ -470,7 +542,7 @@ var QWEN_CODE = {
470
542
  source: "qwen",
471
543
  label: "Qwen Code",
472
544
  binary: "qwen",
473
- configFile: [".qwen", "settings.json"],
545
+ configFile: homeJson(".qwen", "settings.json"),
474
546
  hooksKeyPath: ["hooks"],
475
547
  toolAliases: {
476
548
  run_shell_command: "Bash",
@@ -492,8 +564,8 @@ var QWEN_CODE = {
492
564
  wire: "permission_decision",
493
565
  payload: "claude",
494
566
  nonToolEntries: "nested",
495
- mcp: { shape: "gemini_http", file: [".qwen", "settings.json"], trusted: true },
496
- instructions: { file: [".qwen", "QWEN.md"], label: "Qwen Code" },
567
+ mcp: { shape: "gemini_http", file: homeJson(".qwen", "settings.json"), container: "mcpServers", trusted: true },
568
+ instructions: { file: homeFile(".qwen", "QWEN.md"), label: "Qwen Code" },
497
569
  permissionRuleFile: null,
498
570
  configDirIsShared: false,
499
571
  soleGate: null,
@@ -504,7 +576,7 @@ var CODEBUDDY = {
504
576
  source: "codebuddy",
505
577
  label: "CodeBuddy",
506
578
  binary: "codebuddy",
507
- configFile: [".codebuddy", "settings.json"],
579
+ configFile: homeJson(".codebuddy", "settings.json"),
508
580
  hooksKeyPath: ["hooks"],
509
581
  toolAliases: {},
510
582
  inputKeyAliases: {},
@@ -516,9 +588,9 @@ var CODEBUDDY = {
516
588
  wire: "permission_decision",
517
589
  payload: "claude",
518
590
  nonToolEntries: "nested",
519
- mcp: { shape: "claude_http", file: [".codebuddy", ".mcp.json"], trusted: false },
520
- instructions: { file: [".codebuddy", "CODEBUDDY.md"], label: "CodeBuddy" },
521
- permissionRuleFile: [".codebuddy", "settings.json"],
591
+ mcp: { shape: "claude_http", file: homeJson(".codebuddy", ".mcp.json"), container: "mcpServers", trusted: false },
592
+ instructions: { file: homeFile(".codebuddy", "CODEBUDDY.md"), label: "CodeBuddy" },
593
+ permissionRuleFile: homeJson(".codebuddy", "settings.json"),
522
594
  configDirIsShared: false,
523
595
  soleGate: null,
524
596
  taskControl: null
@@ -528,7 +600,7 @@ var QODER = {
528
600
  source: "qoder",
529
601
  label: "Qoder",
530
602
  binary: "qoder",
531
- configFile: [".qoder", "settings.json"],
603
+ configFile: homeJson(".qoder", "settings.json"),
532
604
  hooksKeyPath: ["hooks"],
533
605
  toolAliases: {},
534
606
  inputKeyAliases: {},
@@ -540,7 +612,7 @@ var QODER = {
540
612
  wire: "permission_decision",
541
613
  payload: "claude",
542
614
  nonToolEntries: "nested",
543
- mcp: { shape: "claude_http", file: [".qoder", "settings.json"], trusted: true },
615
+ mcp: { shape: "claude_http", file: homeJson(".qoder", "settings.json"), container: "mcpServers", trusted: true },
544
616
  instructions: null,
545
617
  permissionRuleFile: null,
546
618
  configDirIsShared: false,
@@ -552,7 +624,7 @@ var DROID = {
552
624
  source: "droid",
553
625
  label: "Droid",
554
626
  binary: "droid",
555
- configFile: [".factory", "hooks.json"],
627
+ configFile: homeJson(".factory", "hooks.json"),
556
628
  hooksKeyPath: [],
557
629
  toolAliases: {
558
630
  Execute: "Bash",
@@ -581,7 +653,7 @@ var DEVIN = {
581
653
  source: "devin",
582
654
  label: "Devin CLI",
583
655
  binary: "devin",
584
- configFile: [".config", "devin", "config.json"],
656
+ configFile: homeJson(".config", "devin", "config.json"),
585
657
  hooksKeyPath: ["hooks"],
586
658
  toolAliases: {
587
659
  exec: "Bash",
@@ -624,7 +696,7 @@ var ANTIGRAVITY_CLI = {
624
696
  source: "antigravity",
625
697
  label: "Antigravity CLI",
626
698
  binary: "agy",
627
- configFile: [".gemini", "config", "hooks.json"],
699
+ configFile: homeJson(".gemini", "config", "hooks.json"),
628
700
  hooksKeyPath: ["pushary"],
629
701
  toolAliases: {
630
702
  run_command: "Bash",
@@ -648,7 +720,7 @@ var ANTIGRAVITY_CLI = {
648
720
  wire: "allow_deny_decision",
649
721
  payload: "antigravity",
650
722
  nonToolEntries: "handler",
651
- mcp: { shape: "antigravity_http", file: [".gemini", "config", "mcp_config.json"], trusted: false },
723
+ mcp: { shape: "antigravity_http", file: homeJson(".gemini", "config", "mcp_config.json"), container: "mcpServers", trusted: false },
652
724
  instructions: null,
653
725
  permissionRuleFile: null,
654
726
  configDirIsShared: true,
@@ -661,13 +733,48 @@ var ANTIGRAVITY_CLI = {
661
733
  },
662
734
  taskControl: ANTIGRAVITY_TASK_CONTROL
663
735
  };
664
- var HOOK_COMPATIBLE_PROFILES = Object.freeze([QWEN_CODE, CODEBUDDY, QODER, DROID, DEVIN, ANTIGRAVITY_CLI]);
736
+ var GROK = {
737
+ agentType: "grok",
738
+ source: "grok",
739
+ label: "Grok Build",
740
+ binary: "grok",
741
+ configFile: { root: "grok_home", path: ["hooks", "pushary.json"], format: "json" },
742
+ hooksKeyPath: ["hooks"],
743
+ toolAliases: {
744
+ run_terminal_command: "Bash",
745
+ search_replace: "Edit",
746
+ apply_patch: "Edit",
747
+ read_file: "Read",
748
+ web_search: "WebSearch",
749
+ web_fetch: "WebFetch",
750
+ spawn_subagent: "Task",
751
+ task_output: "BashOutput",
752
+ kill_task: "KillShell"
753
+ },
754
+ inputKeyAliases: {},
755
+ extraMatchers: [".*"],
756
+ pathInputKeys: [],
757
+ shellCommandKeys: [],
758
+ shellContextKeys: ["cwd"],
759
+ events: ["PreToolUse", "PostToolUse", "PostToolUseFailure", "Stop", "StopCancelled", "StopFailure", "UserPromptSubmit", "Notification", "SessionStart", "SessionEnd", "SubagentStart", "SubagentStop", "PreCompact", "PostCompact"],
760
+ wire: "permission_decision",
761
+ payload: "grok",
762
+ nonToolEntries: "nested",
763
+ mcp: { shape: "grok_http", file: { root: "grok_home", path: ["config.toml"], format: "toml" }, container: "mcp_servers", trusted: false },
764
+ instructions: { file: { root: "grok_home", path: ["rules", "pushary.md"] }, label: "Grok Build" },
765
+ permissionRuleFile: null,
766
+ configDirIsShared: false,
767
+ soleGate: null,
768
+ taskControl: null
769
+ };
770
+ var HOOK_COMPATIBLE_PROFILES = Object.freeze([QWEN_CODE, CODEBUDDY, QODER, DROID, DEVIN, ANTIGRAVITY_CLI, GROK]);
665
771
  var hookCompatibleProfile = (agentType) => HOOK_COMPATIBLE_PROFILES.find((profile) => profile.agentType === agentType);
666
772
  var hookCompatibleProfileBySource = (source) => HOOK_COMPATIBLE_PROFILES.find((profile) => profile.source === source);
773
+ var defaultHomeSegments = (file) => file.root === "home" ? file.path : [".grok", ...file.path];
667
774
  var compatibleTargetFiles = (profile) => {
668
775
  const seen = /* @__PURE__ */ new Map();
669
776
  for (const file of [profile.configFile, profile.mcp?.file, profile.permissionRuleFile, profile.instructions?.file]) {
670
- if (file) seen.set(file.join("/"), file);
777
+ if (file) seen.set(`${file.root}/${file.path.join("/")}`, file);
671
778
  }
672
779
  return [...seen.values()];
673
780
  };
@@ -736,9 +843,6 @@ var redactSecrets = (text) => applyRedactionRules(SECRET_REDACTION_RULES, text);
736
843
  var redactSecretsFromContent = (text) => applyRedactionRules(CUT_OFF_TEXT_REDACTION_RULES, text);
737
844
  var redactSecretsDeep = (text) => redactSecrets(text).replace(HIGH_ENTROPY_RULE.pattern, HIGH_ENTROPY_RULE.replacement);
738
845
 
739
- // ../contracts/src/json-record.ts
740
- var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
741
-
742
846
  // ../contracts/src/shell-analysis.ts
743
847
  var SHELL_WORD_SEPARATOR = /[ \t\n]/;
744
848
  var ARITHMETIC_EVALUATING_EXPANSION = /\$[#+=~^]*(?:[A-Za-z_][A-Za-z0-9_]*|[0-9]+|[-?$!@*#])?\[/;
@@ -1458,41 +1562,33 @@ var DOTNET_DOWNLOAD = /\.Download(?:String|Data|File)(?:Async|TaskAsync)?\s*\(/i
1458
1562
  var SCRIPTBLOCK_FROM_TEXT = /\[(?:System\.Management\.Automation\.)?ScriptBlock\]::Create\s*\(/i;
1459
1563
  var POWERSHELL_HOSTS = /* @__PURE__ */ new Set(["powershell", "pwsh", "powershell_ise"]);
1460
1564
  var WINDOWS_POWERSHELL_HOST = "powershell";
1461
- var POWERSHELL_HOST_COMMAND_SWITCHES = /* @__PURE__ */ new Set(["-c", "-command", "--command", "/c", "/command"]);
1462
- var POWERSHELL_HOST_SWITCHES_THAT_HIDE_THE_COMMAND = /* @__PURE__ */ new Set([
1463
- "-f",
1464
- "-file",
1465
- "/f",
1466
- "/file",
1467
- "-e",
1468
- "-ec",
1469
- "-enc",
1470
- "-encodedcommand",
1471
- "/encodedcommand"
1565
+ var POWERSHELL_HOST_COMMAND_PARAMETER = "command";
1566
+ var POWERSHELL_HOST_COMMAND_WITH_ARGS_PARAMETERS = /* @__PURE__ */ new Set(["commandwithargs", "cwa"]);
1567
+ var POWERSHELL_HOST_FILE_PARAMETER = "file";
1568
+ var POWERSHELL_HOST_ENCODED_PARAMETER = "encodedcommand";
1569
+ var POWERSHELL_HOST_ENCODED_ALIAS = "ec";
1570
+ var POWERSHELL_HOST_OPTIONS_WITH_A_VALUE = /* @__PURE__ */ new Map([
1571
+ ["executionpolicy", "ex"],
1572
+ ["ep", "ep"],
1573
+ ["windowstyle", "w"],
1574
+ ["workingdirectory", "wo"],
1575
+ ["wd", "wd"],
1576
+ ["configurationname", "config"],
1577
+ ["configurationfile", "configurationfile"],
1578
+ ["custompipename", "cus"],
1579
+ ["inputformat", "inp"],
1580
+ ["if", "if"],
1581
+ ["outputformat", "o"],
1582
+ ["of", "of"],
1583
+ ["version", "v"],
1584
+ ["settingsfile", "settings"],
1585
+ ["psconsolefile", "ps"],
1586
+ ["token", "to"],
1587
+ ["encodedarguments", "encodeda"],
1588
+ ["ea", "ea"]
1472
1589
  ]);
1473
- var POWERSHELL_HOST_OPTIONS_WITH_A_VALUE = /* @__PURE__ */ new Set([
1474
- "-executionpolicy",
1475
- "-ep",
1476
- "-ex",
1477
- "-windowstyle",
1478
- "-w",
1479
- "-workingdirectory",
1480
- "-wd",
1481
- "-configurationname",
1482
- "-config",
1483
- "-inputformat",
1484
- "-inf",
1485
- "-if",
1486
- "-outputformat",
1487
- "-of",
1488
- "-o",
1489
- "-version",
1490
- "-v",
1491
- "-settingsfile",
1492
- "-custompipename",
1493
- "-psconsolefile"
1494
- ]);
1495
- var POWERSHELL_HOST_SWITCH = /^[-/]/;
1590
+ var POWERSHELL_HOST_SWITCH = /^[-/–—―]/;
1591
+ var POWERSHELL_HOST_SWITCH_PREFIX = /^([-–—―])\1?|^\//;
1496
1592
  var POWERSHELL_FILE_RUNNERS = /* @__PURE__ */ new Set(["start-process", "invoke-item", "msiexec"]);
1497
1593
  var WINDOWS_SWITCH = /^[-/–—―]/;
1498
1594
  var CMD_PROGRAM = "cmd";
@@ -1648,23 +1744,33 @@ var runsADownloadedFile = (stages, judge) => {
1648
1744
  });
1649
1745
  };
1650
1746
  var invokedExpressionsOf = (command) => command.cmdlet === INVOKE_EXPRESSION ? positionalTextsOf(command) : [];
1651
- var positionalHostCommandOf = (texts) => {
1652
- let index = 0;
1653
- while (index < texts.length && POWERSHELL_HOST_SWITCH.test(texts[index] ?? "")) {
1654
- index += POWERSHELL_HOST_OPTIONS_WITH_A_VALUE.has((texts[index] ?? "").toLowerCase()) ? 2 : 1;
1747
+ var hostOptionTakesValue = (option) => {
1748
+ for (const [name, shortest] of POWERSHELL_HOST_OPTIONS_WITH_A_VALUE) {
1749
+ if (option.length >= shortest.length && name.startsWith(option)) return true;
1655
1750
  }
1656
- return index < texts.length ? texts.slice(index).join(" ") : void 0;
1751
+ return false;
1657
1752
  };
1658
1753
  var hostedPowerShellScriptOf = (command) => {
1659
- if (!POWERSHELL_HOSTS.has(command.name)) return void 0;
1754
+ if (!POWERSHELL_HOSTS.has(command.name)) return { kind: "none" };
1660
1755
  const texts = command.args.map((arg) => arg.text);
1661
- const lowered = texts.map((text) => text.toLowerCase());
1662
- const commandSwitch = lowered.findIndex((text) => POWERSHELL_HOST_COMMAND_SWITCHES.has(text));
1663
- if (commandSwitch !== -1) return texts.slice(commandSwitch + 1).join(" ");
1664
- if (command.name !== WINDOWS_POWERSHELL_HOST || lowered.some((text) => POWERSHELL_HOST_SWITCHES_THAT_HIDE_THE_COMMAND.has(text))) {
1665
- return void 0;
1756
+ for (let index = 0; index < texts.length; index += 1) {
1757
+ const text = (texts[index] ?? "").trim();
1758
+ if (!text) continue;
1759
+ if (!POWERSHELL_HOST_SWITCH.test(text)) {
1760
+ return command.name === WINDOWS_POWERSHELL_HOST ? { kind: "script", script: texts.slice(index).join(" ") } : { kind: "none" };
1761
+ }
1762
+ const option = text.toLowerCase().replace(POWERSHELL_HOST_SWITCH_PREFIX, "");
1763
+ if (option && (POWERSHELL_HOST_ENCODED_PARAMETER.startsWith(option) || option === POWERSHELL_HOST_ENCODED_ALIAS)) {
1764
+ return { kind: "incomplete", reason: "encoded_command" };
1765
+ }
1766
+ if (option && POWERSHELL_HOST_COMMAND_PARAMETER.startsWith(option)) {
1767
+ return { kind: "script", script: texts.slice(index + 1).join(" ") };
1768
+ }
1769
+ if (POWERSHELL_HOST_COMMAND_WITH_ARGS_PARAMETERS.has(option)) return { kind: "script", script: texts[index + 1] ?? "" };
1770
+ if (option && POWERSHELL_HOST_FILE_PARAMETER.startsWith(option)) return { kind: "none" };
1771
+ if (hostOptionTakesValue(option)) index += 1;
1666
1772
  }
1667
- return positionalHostCommandOf(texts);
1773
+ return { kind: "none" };
1668
1774
  };
1669
1775
  var cmdScriptOf = (command) => {
1670
1776
  if (command.name !== CMD_PROGRAM) return void 0;
@@ -1714,38 +1820,51 @@ var scriptsInsideTheStage = (stage) => {
1714
1820
  const groups = [...stage.words, ...stage.redirectTargets].flatMap((word) => word.nested);
1715
1821
  const command = powerShellCommandOf(stage);
1716
1822
  if (command === null) return { ...NO_SCRIPTS_INSIDE, powerShell: groups };
1823
+ const hosted = hostedPowerShellScriptOf(command);
1824
+ if (hosted.kind === "incomplete") return hosted;
1717
1825
  const cmd = presentOnly(cmdScriptOf(command));
1718
1826
  return {
1719
- powerShell: [...groups, ...invokedExpressionsOf(command), ...presentOnly(hostedPowerShellScriptOf(command)), ...cmd.flatMap(cmdPiecesOf)],
1827
+ powerShell: [...groups, ...invokedExpressionsOf(command), ...hosted.kind === "script" ? [hosted.script] : [], ...cmd.flatMap(cmdPiecesOf)],
1720
1828
  cmd,
1721
1829
  posix: presentOnly(wslCommandWordsOf(command))
1722
1830
  };
1723
1831
  };
1724
1832
  var powerShellReadingAt = (command, depth) => {
1725
1833
  const statements = powerShellStatementsOf(command);
1726
- if (statements === null) return null;
1727
- const inside = depth >= MAX_NESTED_SCRIPT_DEPTH ? [] : statements.flatMap((statement) => statement.stages).map(scriptsInsideTheStage);
1728
- const nested = inside.flatMap((scripts) => scripts.powerShell).map((script) => ({ script, reading: powerShellReadingAt(script, depth + 1) }));
1729
- const readings = nested.flatMap(({ reading }) => reading === null ? [] : [reading]);
1834
+ if (statements === null) return { kind: "incomplete", reason: "syntax" };
1835
+ const inside = [];
1836
+ for (const stage of statements.flatMap((statement) => statement.stages)) {
1837
+ const scripts = scriptsInsideTheStage(stage);
1838
+ if ("kind" in scripts) return scripts;
1839
+ inside.push(scripts);
1840
+ }
1841
+ const nested = inside.flatMap((scripts) => scripts.powerShell);
1842
+ if (nested.length > 0 && depth >= MAX_NESTED_SCRIPT_DEPTH) return { kind: "incomplete", reason: "nesting_limit" };
1843
+ const readings = [];
1844
+ for (const script of nested) {
1845
+ const analysis = powerShellReadingAt(script, depth + 1);
1846
+ if (analysis.kind === "incomplete") return analysis;
1847
+ readings.push(analysis.reading);
1848
+ }
1730
1849
  return {
1731
- statements: [...statements, ...readings.flatMap((reading) => reading.statements)],
1732
- cmdScripts: [...inside.flatMap((scripts) => scripts.cmd), ...readings.flatMap((reading) => reading.cmdScripts)],
1733
- posixCommands: [...inside.flatMap((scripts) => scripts.posix), ...readings.flatMap((reading) => reading.posixCommands)],
1734
- unreadScripts: [
1735
- ...nested.flatMap(({ script, reading }) => reading === null ? [script] : []),
1736
- ...readings.flatMap((reading) => reading.unreadScripts)
1737
- ]
1850
+ kind: "complete",
1851
+ reading: {
1852
+ statements: [...statements, ...readings.flatMap((reading) => reading.statements)],
1853
+ cmdScripts: [...inside.flatMap((scripts) => scripts.cmd), ...readings.flatMap((reading) => reading.cmdScripts)],
1854
+ posixCommands: [...inside.flatMap((scripts) => scripts.posix), ...readings.flatMap((reading) => reading.posixCommands)]
1855
+ }
1738
1856
  };
1739
1857
  };
1740
1858
  var stagesOfTheReading = (reading) => reading.statements.flatMap((statement) => statement.stages);
1741
- var powerShellReadingIsDestructive = (reading, judge) => stagesOfTheReading(reading).some((stage) => stageIsDestructive(stage, judge)) || reading.cmdScripts.some(cmdScriptRemovesRecursively) || reading.unreadScripts.some((script) => judge.namesADestructiveAction(script));
1859
+ var powerShellReadingIsDestructive = (reading, judge) => stagesOfTheReading(reading).some((stage) => stageIsDestructive(stage, judge)) || reading.cmdScripts.some(cmdScriptRemovesRecursively);
1742
1860
  var powerShellCommandIsDestructive = (command, judge) => {
1743
- const reading = powerShellReadingAt(command, TOP_LEVEL_SCRIPT);
1744
- return reading === null ? judge.namesADestructiveAction(command) : powerShellReadingIsDestructive(reading, judge);
1861
+ const analysis = powerShellReadingAt(command, TOP_LEVEL_SCRIPT);
1862
+ return analysis.kind === "incomplete" || powerShellReadingIsDestructive(analysis.reading, judge);
1745
1863
  };
1746
1864
  var powerShellCommandHasAVisibleConsequence = (command, judge) => {
1747
- const reading = powerShellReadingAt(command, TOP_LEVEL_SCRIPT);
1748
- if (reading === null) return judge.namesADestructiveAction(command);
1865
+ const analysis = powerShellReadingAt(command, TOP_LEVEL_SCRIPT);
1866
+ if (analysis.kind === "incomplete") return true;
1867
+ const { reading } = analysis;
1749
1868
  const stages = stagesOfTheReading(reading);
1750
1869
  return powerShellReadingIsDestructive(reading, judge) || stages.some((stage) => stageHasAVisibleConsequence(stage, judge)) || reading.statements.some(listsRecursivelyIntoARemoval) || runsFetchedPowerShellCode(stages, judge) || runsADownloadedFile(stages, judge) || reading.posixCommands.some((words) => judge.commandShowsAConsequence(words));
1751
1870
  };
@@ -2410,6 +2529,16 @@ var KEY_SCOPES = ["full_access", "agent", "connector", "bound"];
2410
2529
  var normalizeKeyScope = (value) => typeof value === "string" && KEY_SCOPES.includes(value) ? value : null;
2411
2530
  var APPROVAL_MODES = ["push_only", "terminal_only", "push_first", "notify_only"];
2412
2531
  var isApprovalMode = (value) => typeof value === "string" && APPROVAL_MODES.includes(value);
2532
+ var approvalWaitsAtTheAgentsPrompt = (mode) => {
2533
+ switch (mode) {
2534
+ case "push_first":
2535
+ case "push_only":
2536
+ return false;
2537
+ case "notify_only":
2538
+ case "terminal_only":
2539
+ return true;
2540
+ }
2541
+ };
2413
2542
  var approvalModeWithoutLocalPrompt = (mode) => {
2414
2543
  switch (mode) {
2415
2544
  case "push_first":
@@ -2456,6 +2585,25 @@ var parseAgentQuestions = (toolInput) => {
2456
2585
  }
2457
2586
  return parsed;
2458
2587
  };
2588
+ var isAgentQuestionSet = (value) => {
2589
+ if (!Array.isArray(value) || value.length === 0 || value.length > 4) return false;
2590
+ const questions = /* @__PURE__ */ new Set();
2591
+ for (const item of value) {
2592
+ if (!item || typeof item !== "object" || Array.isArray(item)) return false;
2593
+ const question = item;
2594
+ if (typeof question.question !== "string" || question.question.length === 0 || questions.has(question.question) || question.header !== void 0 && typeof question.header !== "string" || typeof question.multiSelect !== "boolean" || question.allowOther !== void 0 && typeof question.allowOther !== "boolean" || !Array.isArray(question.options) || question.options.length < 2 || question.options.length > 4) return false;
2595
+ const labels = /* @__PURE__ */ new Set();
2596
+ for (const option of question.options) {
2597
+ if (!option || typeof option !== "object" || Array.isArray(option)) return false;
2598
+ const record = option;
2599
+ const label = record.label;
2600
+ if (typeof label !== "string" || label.length === 0 || labels.has(label) || record.description !== void 0 && typeof record.description !== "string") return false;
2601
+ labels.add(label);
2602
+ }
2603
+ questions.add(question.question);
2604
+ }
2605
+ return true;
2606
+ };
2459
2607
  var parseAgentQuestionAnswers = (questions, value) => {
2460
2608
  let parsed;
2461
2609
  try {
@@ -2487,6 +2635,29 @@ var parseAgentQuestionAnswers = (questions, value) => {
2487
2635
  }
2488
2636
  return answers;
2489
2637
  };
2638
+ var isQuestionRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
2639
+ var codexAsyncQuestionFields = (raw) => {
2640
+ if (!isQuestionRecord(raw)) return void 0;
2641
+ const labels = Array.isArray(raw.options) ? raw.options : [];
2642
+ return { question: raw.title, options: labels.map((label) => ({ label })) };
2643
+ };
2644
+ var codexBlockingQuestionFields = (raw) => isQuestionRecord(raw) && raw.isOther === false ? { ...raw, allowOther: false } : raw;
2645
+ var asksForASecret = (questions) => questions.some((question) => isQuestionRecord(question) && question.isSecret === true);
2646
+ var parseCodexQuestions = (toolName, toolInput) => {
2647
+ const raw = Array.isArray(toolInput.questions) ? toolInput.questions : [];
2648
+ if (asksForASecret(raw)) return void 0;
2649
+ const questions = raw.map(toolName === CODEX_ASYNC_QUESTION_TOOL ? codexAsyncQuestionFields : codexBlockingQuestionFields);
2650
+ const parsed = parseAgentQuestions({ questions });
2651
+ return parsed && isAgentQuestionSet(parsed) ? parsed : void 0;
2652
+ };
2653
+ var CODEX_QUESTION_ANSWERED_IN_PUSHARY = "The user already answered this question in Pushary, so it was not shown again";
2654
+ var CODEX_QUESTION_CONTINUE = "Continue with this answer and do not ask it again";
2655
+ var quotedAnswerPair = ([question, answer]) => `${JSON.stringify(question)}: ${JSON.stringify(answer)}`;
2656
+ var codexQuestionAnswerReason = (answers) => {
2657
+ const pairs = Object.entries(answers);
2658
+ const answered = pairs.length === 1 ? `Their answer: ${JSON.stringify(pairs[0]?.[1] ?? "")}` : `Their answers: ${pairs.map(quotedAnswerPair).join("; ")}`;
2659
+ return `${CODEX_QUESTION_ANSWERED_IN_PUSHARY}. ${answered}. ${CODEX_QUESTION_CONTINUE}`;
2660
+ };
2490
2661
  var INSTALL_SOURCES = [
2491
2662
  /** `npx pushary@latest ...`, the documented one-liner. */
2492
2663
  "npx",
@@ -2537,7 +2708,8 @@ var HOOK_BUDGETS = {
2537
2708
  qoder: { budgetSeconds: 600, guardSeconds: 10 },
2538
2709
  droid: { budgetSeconds: 600, guardSeconds: 10 },
2539
2710
  devin: { budgetSeconds: 600, guardSeconds: 10 },
2540
- antigravity: { budgetSeconds: 600, guardSeconds: 10 }
2711
+ antigravity: { budgetSeconds: 600, guardSeconds: 10 },
2712
+ grok: { budgetSeconds: 600, guardSeconds: 10 }
2541
2713
  };
2542
2714
  var hookMaxWaitSeconds = (agent) => Math.max(HOOK_BUDGETS[agent].budgetSeconds - HOOK_BUDGETS[agent].guardSeconds, 1);
2543
2715
  var HOOK_HOLD_BUDGET_FLAG = "--hold-budget";
@@ -5119,17 +5291,32 @@ var shouldDeferToNativeMode = (permissionMode, toolName, options = {}) => {
5119
5291
  return false;
5120
5292
  };
5121
5293
  var AGENT_QUESTION_TOOL = "AskUserQuestion";
5122
- var AGENT_QUESTION_STRATEGY = { native: "native_dialog", updatedInput: "updated_input", none: "not_a_question" };
5294
+ var AGENT_QUESTION_STRATEGY = {
5295
+ native: "native_dialog",
5296
+ updatedInput: "updated_input",
5297
+ answeredInRefusal: "answered_in_refusal",
5298
+ none: "not_a_question"
5299
+ };
5123
5300
  var UPDATED_INPUT_QUESTION_SOURCES = /* @__PURE__ */ new Set(["claude", "qoder", "codebuddy", "droid"]);
5301
+ var GROK_NATIVE_DIALOG_TOOLS = /* @__PURE__ */ new Set(["ask_user_question", "exit_plan_mode"]);
5302
+ var CODEX_QUESTION_TOOL = "request_user_input";
5303
+ var CODEX_ASYNC_QUESTION_TOOL = "request_user_input_async";
5304
+ var CODEX_QUESTION_TOOLS = [CODEX_QUESTION_TOOL, CODEX_ASYNC_QUESTION_TOOL];
5305
+ var CODEX_QUESTION_TOOL_NAMES = new Set(CODEX_QUESTION_TOOLS);
5306
+ var isCodexQuestionTool = (toolName) => typeof toolName === "string" && CODEX_QUESTION_TOOL_NAMES.has(toolName);
5307
+ var isCodexQuestionCall = (source, event, toolName) => source === "codex" && event === "PreToolUse" && isCodexQuestionTool(toolName);
5308
+ var codexQuestionGoesToPushary = (verdict) => verdict.kind === "gate" && !approvalWaitsAtTheAgentsPrompt(verdict.policy.mode);
5124
5309
  function agentQuestionStrategy(source, event, toolName) {
5310
+ if (source === "grok" && GROK_NATIVE_DIALOG_TOOLS.has(toolName)) return AGENT_QUESTION_STRATEGY.native;
5311
+ if (isCodexQuestionCall(source, event, toolName)) return AGENT_QUESTION_STRATEGY.answeredInRefusal;
5125
5312
  if (toolName !== AGENT_QUESTION_TOOL) return AGENT_QUESTION_STRATEGY.none;
5126
5313
  if (source !== null && event === "PreToolUse" && UPDATED_INPUT_QUESTION_SOURCES.has(source)) return AGENT_QUESTION_STRATEGY.updatedInput;
5127
5314
  return AGENT_QUESTION_STRATEGY.native;
5128
5315
  }
5129
- var questionHandedToTheTerminal = (toolName, modeState) => toolName === AGENT_QUESTION_TOOL && modeState.askHandoff === true;
5316
+ var questionHandedToTheTerminal = (toolName, modeState) => (toolName === AGENT_QUESTION_TOOL || isCodexQuestionTool(toolName)) && modeState.askHandoff === true;
5130
5317
  var EXIT_PLAN_MODE_TOOL = "ExitPlanMode";
5131
5318
  var ASKED_IN_EVERY_MODE_TOOLS = [AGENT_QUESTION_TOOL, EXIT_PLAN_MODE_TOOL];
5132
- var ASKED_IN_EVERY_MODE = new Set(ASKED_IN_EVERY_MODE_TOOLS);
5319
+ var ASKED_IN_EVERY_MODE = /* @__PURE__ */ new Set([...ASKED_IN_EVERY_MODE_TOOLS, ...CODEX_QUESTION_TOOLS]);
5133
5320
  var isAskedInEveryMode = (toolName) => ASKED_IN_EVERY_MODE.has(toolName);
5134
5321
  var NATIVE_BLOCK_EVENTS = /* @__PURE__ */ new Set(["PermissionDenied"]);
5135
5322
  var isNativeBlockEvent = (event) => typeof event === "string" && NATIVE_BLOCK_EVENTS.has(event);
@@ -5244,7 +5431,20 @@ var editsAFileThatNeedsAPerson = ({ toolName, toolInputs }) => toolInputs.some((
5244
5431
  const path = extractPolicyArg(toolName, toolInput);
5245
5432
  return path !== void 0 && fileEditNeedsAPerson(toolName, path);
5246
5433
  });
5434
+ var runsADestructiveCommand = ({ toolName, toolInputs }) => SHELL_DIALECT_BY_TOOL.has(toolName) && toolInputs.some((toolInput) => {
5435
+ const command = extractPolicyArg(toolName, toolInput);
5436
+ return command !== void 0 && classifyDecisionRisk(toolName, command) === "destructive";
5437
+ });
5438
+ var codexCallIsDestructive = (input, call) => call.deletesFiles || runsADestructiveCommand(input);
5247
5439
  var codexCallNeedsAPerson = (input, verdict, call) => onlyCodexPreToolUseCanAsk(verdict, call.permissionMode) || verdict.kind === "gate" && (aChosenRuleGoverns(input) || call.deletesFiles || runsACommandThatNeedsAPerson(input) || editsAFileThatNeedsAPerson(input));
5440
+ var CODEX_PRE_TOOL_USE_PASSES = { kind: "pass" };
5441
+ var codexPreToolUseDelivery = (input, verdict, call) => {
5442
+ if (verdict.kind !== "gate" || !codexCallNeedsAPerson(input, verdict, call)) return CODEX_PRE_TOOL_USE_PASSES;
5443
+ const noPromptOfItsOwn = codexHasNoPromptOfItsOwn(scopeBreachReasonOf(verdict), call.permissionMode);
5444
+ const mode = noPromptOfItsOwn ? approvalModeWithoutLocalPrompt(verdict.policy.mode) : verdict.policy.mode;
5445
+ if (mode === "push_first" && !codexCallIsDestructive(input, call)) return CODEX_PRE_TOOL_USE_PASSES;
5446
+ return { kind: "ask", policy: { ...verdict.policy, mode }, agentPromptFollows: !noPromptOfItsOwn };
5447
+ };
5248
5448
  var MAX_AGENT_PERMISSION_RULES_PER_KIND = 256;
5249
5449
  var MAX_AGENT_PERMISSION_RULE_LENGTH = 512;
5250
5450
  var isAgentPermissionRule = (value) => typeof value === "string" && value.length > 0 && value.length <= MAX_AGENT_PERMISSION_RULE_LENGTH;
@@ -5400,6 +5600,8 @@ var pendingCommandEvents = (source) => {
5400
5600
  // so there is nothing for this to print.
5401
5601
  case "opencode":
5402
5602
  return [];
5603
+ case "grok":
5604
+ return ["PostToolUse"];
5403
5605
  case "qwen":
5404
5606
  case "codebuddy":
5405
5607
  case "qoder":
@@ -5788,6 +5990,10 @@ export {
5788
5990
  MANAGED_PROVIDERS,
5789
5991
  DISCONNECT_AGENT_IDS,
5790
5992
  normalizeAgentId,
5993
+ isRecord,
5994
+ GROK_UNREADABLE_CALL,
5995
+ isGrokHookPayload,
5996
+ isGrokSessionEndStop,
5791
5997
  isCompatibleAgentType,
5792
5998
  PHONE_ANSWERED_TOOLS,
5793
5999
  canonicalToolName,
@@ -5809,7 +6015,6 @@ export {
5809
6015
  redactSecrets,
5810
6016
  redactSecretsFromContent,
5811
6017
  redactSecretsDeep,
5812
- isRecord,
5813
6018
  degradedLine,
5814
6019
  hookWritePath,
5815
6020
  MAX_HOOK_ACTIVATION_EVIDENCE_ROWS,
@@ -5837,6 +6042,8 @@ export {
5837
6042
  parseAgentQuestion,
5838
6043
  parseAgentQuestions,
5839
6044
  parseAgentQuestionAnswers,
6045
+ parseCodexQuestions,
6046
+ codexQuestionAnswerReason,
5840
6047
  normalizeInstallSource,
5841
6048
  HOOK_BUDGETS,
5842
6049
  HOOK_HOLD_BUDGET_ENV,
@@ -5876,7 +6083,11 @@ export {
5876
6083
  KILL_REASON,
5877
6084
  isPusharyOwnTool,
5878
6085
  shouldDeferToNativeMode,
6086
+ AGENT_QUESTION_TOOL,
5879
6087
  AGENT_QUESTION_STRATEGY,
6088
+ CODEX_QUESTION_TOOLS,
6089
+ isCodexQuestionTool,
6090
+ codexQuestionGoesToPushary,
5880
6091
  agentQuestionStrategy,
5881
6092
  questionHandedToTheTerminal,
5882
6093
  CODEX_RESCUE_TOOL_NAME,
@@ -5897,7 +6108,7 @@ export {
5897
6108
  HAND_BACK_WITHOUT_A_PROMPT,
5898
6109
  codexDeferredPreToolUse,
5899
6110
  scopeBreachReasonOf,
5900
- codexCallNeedsAPerson,
6111
+ codexPreToolUseDelivery,
5901
6112
  claudePermissionRulesFromSettings,
5902
6113
  claudeConsultsItsAllowlist,
5903
6114
  agentRulesAllowEveryInput,