pushary 1.9.35 → 1.9.36

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 (101) hide show
  1. package/CHANGELOG.md +7 -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 +30 -30
  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-4TFD3WAA.js → chunk-26AEFJSK.js} +2 -2
  43. package/dist/{chunk-7FQL5NWJ.js → chunk-2DZBIELP.js} +135 -23
  44. package/dist/{chunk-DCBSD22V.js → chunk-42FTY5II.js} +3 -3
  45. package/dist/{chunk-PEEJP4HN.js → chunk-4E4PZQFE.js} +4 -4
  46. package/dist/{chunk-6OGDGQTT.js → chunk-4NMDFPK7.js} +5 -5
  47. package/dist/{chunk-43H2FUNN.js → chunk-556JCOMK.js} +4 -4
  48. package/dist/{chunk-FQQSW7MD.js → chunk-55XIK7YS.js} +1 -1
  49. package/dist/{chunk-36ZCFJUI.js → chunk-5ML6E3L7.js} +1 -1
  50. package/dist/{chunk-NMQLY4PE.js → chunk-5S2P2CK6.js} +2 -2
  51. package/dist/{chunk-SMRMWDFE.js → chunk-6LKIK7V2.js} +43 -17
  52. package/dist/{chunk-U7CN5HG2.js → chunk-7GQILLZD.js} +5 -5
  53. package/dist/{chunk-B5RLJ6QD.js → chunk-7MOFAAZ3.js} +9 -5
  54. package/dist/{chunk-H52HBSOD.js → chunk-BS64ZHTB.js} +3 -3
  55. package/dist/{chunk-A455TSHF.js → chunk-CHNSFTD5.js} +2 -2
  56. package/dist/{chunk-WFPXKCN4.js → chunk-CHWJ7ZXI.js} +5 -5
  57. package/dist/{chunk-22YSHBTI.js → chunk-CRZ4CP7C.js} +3 -3
  58. package/dist/{chunk-WMB3OCI4.js → chunk-CRZKFEEO.js} +2 -2
  59. package/dist/{chunk-NKAMF2YJ.js → chunk-DC6KHRVH.js} +1 -1
  60. package/dist/{chunk-ULJFIF5N.js → chunk-EGTVN6YV.js} +1 -1
  61. package/dist/{chunk-A5FFSXZE.js → chunk-EH635XAR.js} +2 -2
  62. package/dist/{chunk-57FFQR46.js → chunk-EQXMVKKD.js} +1 -1
  63. package/dist/{chunk-EJWSE7S7.js → chunk-ETGGQWBR.js} +4 -4
  64. package/dist/{chunk-WPSI4246.js → chunk-F5W7B7YT.js} +1 -1
  65. package/dist/{chunk-OZMGO4WF.js → chunk-FBKGGIFB.js} +5 -5
  66. package/dist/{chunk-7IVV4LLF.js → chunk-GNESC5EF.js} +3 -3
  67. package/dist/{chunk-YABMIGR3.js → chunk-GTEF64CJ.js} +1 -1
  68. package/dist/{chunk-CK3W7Q5S.js → chunk-H3MOTS2C.js} +1 -1
  69. package/dist/{chunk-7UGGCTTW.js → chunk-HCKBZYBW.js} +2 -2
  70. package/dist/{chunk-HJNCVY5F.js → chunk-IPYCRJGM.js} +7 -7
  71. package/dist/{chunk-VTAC5FBZ.js → chunk-J36W6ARB.js} +1 -1
  72. package/dist/{chunk-GC3SUMYD.js → chunk-JAA7YJJZ.js} +4 -4
  73. package/dist/{chunk-FDNMQEU6.js → chunk-JWURAYXK.js} +2 -2
  74. package/dist/{chunk-UPRNSD2T.js → chunk-K5X25GUV.js} +4 -4
  75. package/dist/{chunk-UDECNZYI.js → chunk-KCUTE3EB.js} +2 -2
  76. package/dist/{chunk-CPYOJRDN.js → chunk-L25KSDIB.js} +8 -8
  77. package/dist/{chunk-45OXG3VR.js → chunk-LL256PHP.js} +1 -1
  78. package/dist/{chunk-Z6HDYK2A.js → chunk-MBBPLF5T.js} +2 -2
  79. package/dist/{chunk-XLXG6MA5.js → chunk-ML42WKI7.js} +3 -3
  80. package/dist/{chunk-FYQG2UTK.js → chunk-MNXHKEXB.js} +2 -2
  81. package/dist/{chunk-IRU7DKJW.js → chunk-NE5OPCD5.js} +7 -3
  82. package/dist/{chunk-3LS3GFJW.js → chunk-PRKH662J.js} +1 -1
  83. package/dist/{chunk-E2OZZZKP.js → chunk-QHL3Y6D2.js} +2 -2
  84. package/dist/{chunk-SMSX4TCC.js → chunk-QPUTCMAK.js} +1 -1
  85. package/dist/{chunk-HVUBWLER.js → chunk-RNRCOOQZ.js} +11 -11
  86. package/dist/{chunk-LOYSI2CZ.js → chunk-RYXSY3RH.js} +5 -5
  87. package/dist/{chunk-7S7H7V5V.js → chunk-SHLLDMPM.js} +97 -40
  88. package/dist/{chunk-V4ZIG66K.js → chunk-TRNSODJ6.js} +1 -1
  89. package/dist/{chunk-DQKEGNTI.js → chunk-U2PUHT4W.js} +1 -1
  90. package/dist/{chunk-HQKYWUBF.js → chunk-UDHT3W7I.js} +2 -2
  91. package/dist/{chunk-QJ3ENGBT.js → chunk-ULDOQF4Q.js} +3 -3
  92. package/dist/{chunk-EGTRIM74.js → chunk-VRALPR4B.js} +4 -4
  93. package/dist/{chunk-4PIAOJAW.js → chunk-X4BPD5RD.js} +1 -1
  94. package/dist/{chunk-FPYBX36E.js → chunk-Y5FCB66K.js} +5 -5
  95. package/dist/{chunk-YRDNKY77.js → chunk-YRAPCLOB.js} +6 -6
  96. package/dist/{global-upgrade-IZCB4WIE.js → global-upgrade-EF6RZBPU.js} +6 -6
  97. package/dist/{paths-4WAA57P5.js → paths-F645XTFZ.js} +2 -2
  98. package/dist/{reapply-GJ73ZHDD.js → reapply-HJOTWJAN.js} +20 -20
  99. package/dist/src/index.js +19 -19
  100. package/dist/{upgrade-lock-J5PIKSYV.js → upgrade-lock-APUN7YKQ.js} +3 -3
  101. package/package.json +1 -1
@@ -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]+|[-?$!@*#])?\[/;
@@ -2537,7 +2641,8 @@ var HOOK_BUDGETS = {
2537
2641
  qoder: { budgetSeconds: 600, guardSeconds: 10 },
2538
2642
  droid: { budgetSeconds: 600, guardSeconds: 10 },
2539
2643
  devin: { budgetSeconds: 600, guardSeconds: 10 },
2540
- antigravity: { budgetSeconds: 600, guardSeconds: 10 }
2644
+ antigravity: { budgetSeconds: 600, guardSeconds: 10 },
2645
+ grok: { budgetSeconds: 600, guardSeconds: 10 }
2541
2646
  };
2542
2647
  var hookMaxWaitSeconds = (agent) => Math.max(HOOK_BUDGETS[agent].budgetSeconds - HOOK_BUDGETS[agent].guardSeconds, 1);
2543
2648
  var HOOK_HOLD_BUDGET_FLAG = "--hold-budget";
@@ -5121,7 +5226,9 @@ var shouldDeferToNativeMode = (permissionMode, toolName, options = {}) => {
5121
5226
  var AGENT_QUESTION_TOOL = "AskUserQuestion";
5122
5227
  var AGENT_QUESTION_STRATEGY = { native: "native_dialog", updatedInput: "updated_input", none: "not_a_question" };
5123
5228
  var UPDATED_INPUT_QUESTION_SOURCES = /* @__PURE__ */ new Set(["claude", "qoder", "codebuddy", "droid"]);
5229
+ var GROK_NATIVE_DIALOG_TOOLS = /* @__PURE__ */ new Set(["ask_user_question", "exit_plan_mode"]);
5124
5230
  function agentQuestionStrategy(source, event, toolName) {
5231
+ if (source === "grok" && GROK_NATIVE_DIALOG_TOOLS.has(toolName)) return AGENT_QUESTION_STRATEGY.native;
5125
5232
  if (toolName !== AGENT_QUESTION_TOOL) return AGENT_QUESTION_STRATEGY.none;
5126
5233
  if (source !== null && event === "PreToolUse" && UPDATED_INPUT_QUESTION_SOURCES.has(source)) return AGENT_QUESTION_STRATEGY.updatedInput;
5127
5234
  return AGENT_QUESTION_STRATEGY.native;
@@ -5400,6 +5507,8 @@ var pendingCommandEvents = (source) => {
5400
5507
  // so there is nothing for this to print.
5401
5508
  case "opencode":
5402
5509
  return [];
5510
+ case "grok":
5511
+ return ["PostToolUse"];
5403
5512
  case "qwen":
5404
5513
  case "codebuddy":
5405
5514
  case "qoder":
@@ -5788,6 +5897,10 @@ export {
5788
5897
  MANAGED_PROVIDERS,
5789
5898
  DISCONNECT_AGENT_IDS,
5790
5899
  normalizeAgentId,
5900
+ isRecord,
5901
+ GROK_UNREADABLE_CALL,
5902
+ isGrokHookPayload,
5903
+ isGrokSessionEndStop,
5791
5904
  isCompatibleAgentType,
5792
5905
  PHONE_ANSWERED_TOOLS,
5793
5906
  canonicalToolName,
@@ -5809,7 +5922,6 @@ export {
5809
5922
  redactSecrets,
5810
5923
  redactSecretsFromContent,
5811
5924
  redactSecretsDeep,
5812
- isRecord,
5813
5925
  degradedLine,
5814
5926
  hookWritePath,
5815
5927
  MAX_HOOK_ACTIVATION_EVIDENCE_ROWS,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveInstallSourceFor
3
- } from "./chunk-NMQLY4PE.js";
3
+ } from "./chunk-5S2P2CK6.js";
4
4
  import {
5
5
  backupFile,
6
6
  readJsonSafe,
@@ -9,11 +9,11 @@ import {
9
9
  } from "./chunk-AQFEP65J.js";
10
10
  import {
11
11
  configFilePath
12
- } from "./chunk-3LS3GFJW.js";
12
+ } from "./chunk-PRKH662J.js";
13
13
  import {
14
14
  API_KEY_PREFIX_PATTERN,
15
15
  isRecord
16
- } from "./chunk-7FQL5NWJ.js";
16
+ } from "./chunk-2DZBIELP.js";
17
17
 
18
18
  // src/shell-alias.ts
19
19
  import { homedir } from "os";
@@ -2,25 +2,25 @@ import {
2
2
  SIGNED_OUT_ON_MAC_MESSAGE,
3
3
  describeSignedOutKey,
4
4
  readSignedOutDiagnosis
5
- } from "./chunk-FDNMQEU6.js";
5
+ } from "./chunk-JWURAYXK.js";
6
6
  import {
7
7
  createIo
8
8
  } from "./chunk-FO3MDD26.js";
9
9
  import {
10
10
  readKeySource
11
- } from "./chunk-DCBSD22V.js";
11
+ } from "./chunk-42FTY5II.js";
12
12
  import {
13
13
  absoluteUrl,
14
14
  checkApiKey,
15
15
  describeKeyCheck,
16
16
  keyCheckFromResponse
17
- } from "./chunk-7IVV4LLF.js";
17
+ } from "./chunk-GNESC5EF.js";
18
18
  import {
19
19
  EXIT
20
20
  } from "./chunk-KZERVKTD.js";
21
21
  import {
22
22
  getBaseUrl
23
- } from "./chunk-3LS3GFJW.js";
23
+ } from "./chunk-PRKH662J.js";
24
24
 
25
25
  // src/cli/report-key.ts
26
26
  var { dim, yellow } = createIo();
@@ -2,23 +2,23 @@ import {
2
2
  CLAUDE_HOOK_EVENTS,
3
3
  GEMINI_HOOK_EVENTS,
4
4
  hasGeminiHooks
5
- } from "./chunk-QJ3ENGBT.js";
5
+ } from "./chunk-ULDOQF4Q.js";
6
6
  import {
7
7
  AGENT_CHOICES
8
- } from "./chunk-57FFQR46.js";
8
+ } from "./chunk-EQXMVKKD.js";
9
9
  import {
10
10
  BELL_HOOK_BINARY
11
- } from "./chunk-36ZCFJUI.js";
11
+ } from "./chunk-5ML6E3L7.js";
12
12
  import {
13
13
  CODEX_HOOK_EVENTS,
14
14
  hasCodexHooks,
15
15
  holdBudgetOf
16
- } from "./chunk-UPRNSD2T.js";
16
+ } from "./chunk-K5X25GUV.js";
17
17
  import {
18
18
  CURSOR_GATE_EVENTS,
19
19
  HOOK_LOCATOR_BINARY,
20
20
  hookCommandHoldBudget
21
- } from "./chunk-7FQL5NWJ.js";
21
+ } from "./chunk-2DZBIELP.js";
22
22
 
23
23
  // src/diagnostics/bridge.ts
24
24
  import { execFileSync } from "child_process";
@@ -14,19 +14,19 @@ import {
14
14
  } from "./chunk-FO3MDD26.js";
15
15
  import {
16
16
  callMcpTool
17
- } from "./chunk-H52HBSOD.js";
17
+ } from "./chunk-BS64ZHTB.js";
18
18
  import {
19
19
  reportedInstallSource
20
- } from "./chunk-NMQLY4PE.js";
20
+ } from "./chunk-5S2P2CK6.js";
21
21
  import {
22
22
  NPX_LATEST_COMMAND
23
- } from "./chunk-45OXG3VR.js";
23
+ } from "./chunk-LL256PHP.js";
24
24
  import {
25
25
  NO_PAIRING_COMPUTER,
26
26
  PAIR_TTL_SECONDS,
27
27
  classifyConfirmResponse,
28
28
  isAnswerSource
29
- } from "./chunk-7FQL5NWJ.js";
29
+ } from "./chunk-2DZBIELP.js";
30
30
 
31
31
  // src/reach.ts
32
32
  var reachVerdict = (channels) => {
@@ -2,7 +2,7 @@ import {
2
2
  autoUpdateLock,
3
3
  installPackageGlobally,
4
4
  npmErrorMessage
5
- } from "./chunk-UPRNSD2T.js";
5
+ } from "./chunk-K5X25GUV.js";
6
6
  import {
7
7
  writeJsonAtomic
8
8
  } from "./chunk-AQFEP65J.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  guardBinary
3
- } from "./chunk-UPRNSD2T.js";
3
+ } from "./chunk-K5X25GUV.js";
4
4
 
5
5
  // src/bell/install.ts
6
6
  import { join } from "path";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  configFilePath
3
- } from "./chunk-3LS3GFJW.js";
3
+ } from "./chunk-PRKH662J.js";
4
4
  import {
5
5
  normalizeInstallSource
6
- } from "./chunk-7FQL5NWJ.js";
6
+ } from "./chunk-2DZBIELP.js";
7
7
 
8
8
  // src/install-source.ts
9
9
  import { readFileSync } from "fs";
@@ -2,7 +2,7 @@ import {
2
2
  IDLE_PROMPT_NOTIFICATION,
3
3
  NOTIFICATION_PUSH_TYPES,
4
4
  POSTTOOLUSE_MIRROR_ONLY_TOOLS
5
- } from "./chunk-DQKEGNTI.js";
5
+ } from "./chunk-U2PUHT4W.js";
6
6
  import {
7
7
  cancelQuestion,
8
8
  clientErrorKindOf,
@@ -10,28 +10,29 @@ import {
10
10
  reportClientError,
11
11
  sendNotification,
12
12
  waitForAnswer
13
- } from "./chunk-OZMGO4WF.js";
13
+ } from "./chunk-FBKGGIFB.js";
14
14
  import {
15
15
  withRetry
16
- } from "./chunk-H52HBSOD.js";
16
+ } from "./chunk-BS64ZHTB.js";
17
17
  import {
18
18
  getMachineId
19
- } from "./chunk-ULJFIF5N.js";
19
+ } from "./chunk-EGTVN6YV.js";
20
20
  import {
21
21
  reportedInstallSource
22
- } from "./chunk-NMQLY4PE.js";
22
+ } from "./chunk-5S2P2CK6.js";
23
23
  import {
24
24
  canonicalJson
25
- } from "./chunk-UPRNSD2T.js";
25
+ } from "./chunk-K5X25GUV.js";
26
26
  import {
27
27
  writeFileAtomic
28
28
  } from "./chunk-AQFEP65J.js";
29
29
  import {
30
30
  getApiKey,
31
31
  getBaseUrl
32
- } from "./chunk-3LS3GFJW.js";
32
+ } from "./chunk-PRKH662J.js";
33
33
  import {
34
34
  ACTION_BODY_MAX,
35
+ AGENTS,
35
36
  AGENT_LABELS_BY_TYPE,
36
37
  BLANK_TASK_INPUT_TOOL,
37
38
  BLOCKED_ACTION_GRANT_TTL_SECONDS,
@@ -63,7 +64,7 @@ import {
63
64
  toToolLookup,
64
65
  truncateLine,
65
66
  unansweredRefusalReason
66
- } from "./chunk-7FQL5NWJ.js";
67
+ } from "./chunk-2DZBIELP.js";
67
68
 
68
69
  // ../hook-mapping/src/describe.ts
69
70
  import { isAbsolute, relative, resolve } from "path";
@@ -72,8 +73,8 @@ var hookPrefixes = {
72
73
  PowerShell: (input) => `powershell: ${input.command ?? "(no command)"}`,
73
74
  Monitor: (input) => `monitor: ${input.command ?? "(no command)"}`,
74
75
  Write: (input) => `write file: ${input.file_path ?? "(unknown path)"}`,
75
- Edit: (input) => `edit file: ${input.file_path ?? "(unknown path)"}`,
76
- MultiEdit: (input) => `edit file: ${input.file_path ?? "(unknown path)"}`,
76
+ Edit: (input) => `edit file: ${editTarget(input) ?? "(unknown path)"}`,
77
+ MultiEdit: (input) => `edit file: ${editTarget(input) ?? "(unknown path)"}`,
77
78
  Read: (input) => `read file: ${input.file_path ?? "(unknown path)"}`,
78
79
  // Without an entry here the fallback stringifies the whole tool input, and for
79
80
  // ExitPlanMode that input IS the plan: the action line became a truncated dump of
@@ -104,13 +105,18 @@ var describeTodoProgress = (todos) => {
104
105
  if (label) return `${label.trim()} (${done}/${total} done)`;
105
106
  return `${done}/${total} tasks done`;
106
107
  };
108
+ var editTarget = (input) => {
109
+ if (typeof input.file_path === "string") return input.file_path;
110
+ if (!Array.isArray(input.file_paths) || !input.file_paths.every((path) => typeof path === "string")) return void 0;
111
+ return input.file_paths.join(", ");
112
+ };
107
113
  var eventPrefixes = {
108
114
  Bash: (input) => `ran: ${String(input.command ?? "")}`,
109
115
  PowerShell: (input) => `ran: ${String(input.command ?? "")}`,
110
116
  Monitor: (input) => `ran: ${String(input.command ?? "")}`,
111
117
  Write: (input) => `wrote: ${input.file_path ?? "unknown"}`,
112
- Edit: (input) => `edited: ${input.file_path ?? "unknown"}`,
113
- MultiEdit: (input) => `edited: ${input.file_path ?? "unknown"}`,
118
+ Edit: (input) => `edited: ${editTarget(input) ?? "unknown"}`,
119
+ MultiEdit: (input) => `edited: ${editTarget(input) ?? "unknown"}`,
114
120
  Read: (input) => `read: ${input.file_path ?? "unknown"}`,
115
121
  TodoWrite: (input) => describeTodoProgress(input.todos),
116
122
  Task: (input) => `ran subagent: ${describeTaskCall(input)}`,
@@ -233,11 +239,25 @@ var OPENCODE_TOOL_NAMES = {
233
239
  var PATCH_ARG_KEYS = ["command", "patch", "input"];
234
240
  var patchedFilesIn = (input) => [...new Set(PATCH_ARG_KEYS.flatMap((key) => parseApplyPatchFiles(input[key])))];
235
241
  var lookupsForInput = (profile, toolName, input, absolute) => {
236
- const lookup = toToolLookup(profile, toolName, input, absolute);
242
+ const gateInput = profile.source === "grok" && toolName === "apply_patch" ? { patch: input.patch, diff: input.patch } : input;
243
+ const lookup = toToolLookup(profile, toolName, gateInput, absolute);
237
244
  if (!lookup.unreadable) return [lookup];
238
- const files = patchedFilesIn(input);
245
+ const files = patchedFilesIn(gateInput);
239
246
  if (files.length === 0) return [lookup];
240
- return files.slice(0, GATE_MAX_TOOL_INPUTS + 1).map((file) => toToolLookup(profile, toolName, { ...input, file_path: absolute(file) }, absolute));
247
+ return files.slice(0, GATE_MAX_TOOL_INPUTS + 1).map((file) => toToolLookup(profile, toolName, { ...gateInput, file_path: absolute(file) }, absolute));
248
+ };
249
+ var compatibleToolLookup = (profile, toolName, input, cwd) => {
250
+ const absolute = (path) => cwd && !isAbsolute(path) ? resolve(cwd, path) : path;
251
+ const lookups = lookupsForInput(profile, toolName, input, absolute);
252
+ const first = lookups[0];
253
+ if (!first) return { tool: canonicalToolName(profile, toolName), input, unreadable: true };
254
+ if (lookups.length === 1) return first;
255
+ const { file_path, ...content } = first.input;
256
+ return {
257
+ tool: first.tool,
258
+ input: { ...content, file_paths: lookups.map((lookup) => lookup.input.file_path) },
259
+ unreadable: lookups.length > GATE_MAX_TOOL_INPUTS || lookups.some((lookup) => lookup.unreadable)
260
+ };
241
261
  };
242
262
  var compatibleGateInputs = (profile, toolName, toolInputs, cwd) => {
243
263
  const absolute = (path) => cwd && !isAbsolute(path) ? resolve(cwd, path) : path;
@@ -377,6 +397,10 @@ var deriveReceiptMeta = (toolName, toolInput, toolResult, cwd) => {
377
397
  ...toolInput,
378
398
  file_path: toolInput.file_path ?? toolInput.absolute_path ?? toolInput.path
379
399
  };
400
+ if (canonicalTool === "Edit" && Array.isArray(canonicalInput.file_paths)) {
401
+ const patch = firstString(canonicalInput.diff, canonicalInput.command, canonicalInput.patch, canonicalInput.input);
402
+ if (patch) return { kind: "edit", target: redactSecrets(patch).slice(0, RECEIPT_TARGET_MAX_LENGTH), ok };
403
+ }
380
404
  if (FILE_TARGET_TOOLS.has(canonicalTool)) {
381
405
  const filePath = canonicalInput.file_path;
382
406
  if (typeof filePath !== "string" || !filePath) return void 0;
@@ -462,7 +486,8 @@ var AGENT_IDENTITIES = {
462
486
  qoder: { type: "qoder", label: AGENT_LABELS_BY_TYPE.qoder },
463
487
  droid: { type: "droid", label: AGENT_LABELS_BY_TYPE.droid },
464
488
  devin: { type: "devin", label: AGENT_LABELS_BY_TYPE.devin },
465
- antigravity: { type: "antigravity_cli", label: AGENT_LABELS_BY_TYPE.antigravity_cli }
489
+ antigravity: { type: "antigravity_cli", label: AGENT_LABELS_BY_TYPE.antigravity_cli },
490
+ grok: { type: "grok", label: AGENTS.grok.label }
466
491
  };
467
492
  var TEAMMATE_IDLE_ACTION = "A teammate went idle";
468
493
  var CLAUDE_MEANINGS = {
@@ -495,6 +520,7 @@ var MEANING_BY_HOOK = {
495
520
  droid: compatibleMeanings("droid"),
496
521
  devin: compatibleMeanings("devin"),
497
522
  antigravity: compatibleMeanings("antigravity_cli"),
523
+ grok: { ...compatibleMeanings("grok"), PostToolUseFailure: { kind: "tool", event: "tool_complete" }, StopCancelled: { kind: "stop_failure", event: "turn_error" } },
498
524
  codex: {
499
525
  PostToolUse: { kind: "tool", event: "tool_complete" },
500
526
  UserPromptSubmit: { kind: "prompt", event: "user_prompt" },
@@ -2254,9 +2280,9 @@ export {
2254
2280
  UNNAMED_ACTION,
2255
2281
  describeToolCall,
2256
2282
  deriveToolTarget,
2257
- parseApplyPatchFiles,
2258
2283
  patchDeletesFiles,
2259
2284
  OPENCODE_TOOL_NAMES,
2285
+ compatibleToolLookup,
2260
2286
  canonicalGateInputs,
2261
2287
  scopePathFor,
2262
2288
  deriveActionBody,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  APPROVAL_SETTINGS_PATH
3
- } from "./chunk-PEEJP4HN.js";
3
+ } from "./chunk-4E4PZQFE.js";
4
4
  import {
5
5
  readMacAppAgentKey
6
- } from "./chunk-EGTRIM74.js";
6
+ } from "./chunk-VRALPR4B.js";
7
7
  import {
8
8
  findExportedKeyLines,
9
9
  isAdoptedMacAppKey,
@@ -13,13 +13,13 @@ import {
13
13
  readConfigFileKey,
14
14
  readKeySource,
15
15
  readMacAppKeyPrefix
16
- } from "./chunk-DCBSD22V.js";
16
+ } from "./chunk-42FTY5II.js";
17
17
  import {
18
18
  absoluteUrl
19
- } from "./chunk-7IVV4LLF.js";
19
+ } from "./chunk-GNESC5EF.js";
20
20
  import {
21
21
  isValidApiKey
22
- } from "./chunk-7FQL5NWJ.js";
22
+ } from "./chunk-2DZBIELP.js";
23
23
 
24
24
  // src/key-revocation.ts
25
25
  var SELF_REVOKE_PATH = "/api/v1/server/keys/self/revoke";