reasonix 0.48.0 → 0.48.1

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 (106) hide show
  1. package/README.md +9 -0
  2. package/dist/cli/{acp-4ROCGYNH.js → acp-QJGGHQLA.js} +52 -135
  3. package/dist/cli/acp-QJGGHQLA.js.map +1 -0
  4. package/dist/cli/{chat-GZNB5625.js → chat-ZXF227MP.js} +23 -23
  5. package/dist/cli/{chunk-JMDE6IO3.js → chunk-3FULTFRB.js} +2 -2
  6. package/dist/cli/{chunk-7M4YYMKW.js → chunk-43ROGEX2.js} +47 -55
  7. package/dist/cli/{chunk-7M4YYMKW.js.map → chunk-43ROGEX2.js.map} +1 -1
  8. package/dist/cli/{chunk-3WGTGXO4.js → chunk-4E2BHJU4.js} +4 -4
  9. package/dist/cli/chunk-4E2BHJU4.js.map +1 -0
  10. package/dist/cli/{chunk-HR5NBKEM.js → chunk-5AW6NIHU.js} +2 -2
  11. package/dist/cli/{chunk-TE5UIIFL.js → chunk-5U5LMMFF.js} +2 -2
  12. package/dist/cli/{chunk-WZGNXR6E.js → chunk-6FRNXWDZ.js} +320 -75
  13. package/dist/cli/chunk-6FRNXWDZ.js.map +1 -0
  14. package/dist/cli/{chunk-6MZTZO7A.js → chunk-DABAOQSV.js} +1826 -1793
  15. package/dist/cli/chunk-DABAOQSV.js.map +1 -0
  16. package/dist/cli/{chunk-EMMENC4O.js → chunk-EO6RPTJG.js} +5 -5
  17. package/dist/cli/{chunk-2QSTA2QV.js → chunk-FD7SNDWW.js} +3 -3
  18. package/dist/cli/{chunk-CDVSFSAK.js → chunk-FPME5QOO.js} +19 -4
  19. package/dist/cli/chunk-FPME5QOO.js.map +1 -0
  20. package/dist/cli/{chunk-5OHHAQ4W.js → chunk-H2F4LDNH.js} +2 -2
  21. package/dist/cli/{chunk-OG5JANQ4.js → chunk-IKSYVBBZ.js} +2 -2
  22. package/dist/cli/{chunk-OPYALNTT.js → chunk-JFBGSWQB.js} +77 -38
  23. package/dist/cli/chunk-JFBGSWQB.js.map +1 -0
  24. package/dist/cli/{chunk-RUDBUHO4.js → chunk-KH5JIJJD.js} +2 -2
  25. package/dist/cli/{chunk-H4CCXMDD.js → chunk-NQZ5U37J.js} +2 -2
  26. package/dist/cli/{chunk-I4M5QJNL.js → chunk-O3AGYTG2.js} +2 -2
  27. package/dist/cli/{chunk-YW63N3ZR.js → chunk-PIC5HJRD.js} +124 -18
  28. package/dist/cli/chunk-PIC5HJRD.js.map +1 -0
  29. package/dist/cli/{chunk-NMQSUNLB.js → chunk-PJIQIYTV.js} +6 -3
  30. package/dist/cli/chunk-PJIQIYTV.js.map +1 -0
  31. package/dist/cli/{chunk-V4Y732RQ.js → chunk-R7U44O3Y.js} +2 -2
  32. package/dist/cli/{chunk-OB4BUJBL.js → chunk-RCLS63KE.js} +5 -2
  33. package/dist/cli/chunk-RCLS63KE.js.map +1 -0
  34. package/dist/cli/{chunk-FY4S7TJZ.js → chunk-SLAFMXAZ.js} +10 -2
  35. package/dist/cli/chunk-SLAFMXAZ.js.map +1 -0
  36. package/dist/cli/{chunk-DOWEOA6E.js → chunk-SWUMD2LX.js} +2 -2
  37. package/dist/cli/{chunk-S2RMQULY.js → chunk-TIJ4ZHD6.js} +7 -7
  38. package/dist/cli/{chunk-MOJYKO2A.js → chunk-WKOXKCF3.js} +3 -3
  39. package/dist/cli/{chunk-MRZG4GBF.js → chunk-XMR2VCGT.js} +3 -3
  40. package/dist/cli/{code-PMPJWXEO.js → code-OKA5YPOH.js} +26 -26
  41. package/dist/cli/{commands-QS6TG4G3.js → commands-3U6PUVSS.js} +4 -4
  42. package/dist/cli/{commit-XPRSKUBF.js → commit-HFB7SRBU.js} +3 -3
  43. package/dist/cli/{desktop-562OPWIU.js → desktop-G7UMW3CJ.js} +60 -23
  44. package/dist/cli/desktop-G7UMW3CJ.js.map +1 -0
  45. package/dist/cli/{diff-I6W4AUWJ.js → diff-PGXW4YZD.js} +8 -8
  46. package/dist/cli/{doctor-6XVZKT4U.js → doctor-WWJFLVCB.js} +8 -8
  47. package/dist/cli/index.js +33 -33
  48. package/dist/cli/{mcp-7W7ANO2Y.js → mcp-Y3VKIK3T.js} +2 -2
  49. package/dist/cli/{mcp-browse-LA4I4YIZ.js → mcp-browse-4IN2QIFR.js} +2 -2
  50. package/dist/cli/{mcp-inspect-LWXXU7BY.js → mcp-inspect-BUXFXDHB.js} +2 -2
  51. package/dist/cli/{prompt-RKZD4X6Y.js → prompt-US57R6BA.js} +5 -4
  52. package/dist/cli/{replay-2X7MVXOI.js → replay-EQJMZRB3.js} +8 -8
  53. package/dist/cli/{run-TPKXIJ27.js → run-KVEI66TR.js} +14 -14
  54. package/dist/cli/{server-NHQ3QXOZ.js → server-D6C4GHWN.js} +13 -11
  55. package/dist/cli/server-D6C4GHWN.js.map +1 -0
  56. package/dist/cli/{sessions-2A4DGSHA.js → sessions-TGVS2RQZ.js} +13 -13
  57. package/dist/cli/{setup-GOLP7J4C.js → setup-WLKX6GGG.js} +5 -5
  58. package/dist/cli/{stats-CGDAFDKI.js → stats-TCD7Q6MB.js} +6 -6
  59. package/dist/cli/{version-FIL4ZFOS.js → version-BCWWS2OU.js} +13 -13
  60. package/dist/index.d.ts +8 -2
  61. package/dist/index.js +200 -46
  62. package/dist/index.js.map +1 -1
  63. package/package.json +5 -2
  64. package/dist/cli/acp-4ROCGYNH.js.map +0 -1
  65. package/dist/cli/chunk-3WGTGXO4.js.map +0 -1
  66. package/dist/cli/chunk-6MZTZO7A.js.map +0 -1
  67. package/dist/cli/chunk-CDVSFSAK.js.map +0 -1
  68. package/dist/cli/chunk-FY4S7TJZ.js.map +0 -1
  69. package/dist/cli/chunk-NMQSUNLB.js.map +0 -1
  70. package/dist/cli/chunk-OB4BUJBL.js.map +0 -1
  71. package/dist/cli/chunk-OPYALNTT.js.map +0 -1
  72. package/dist/cli/chunk-WZGNXR6E.js.map +0 -1
  73. package/dist/cli/chunk-YW63N3ZR.js.map +0 -1
  74. package/dist/cli/desktop-562OPWIU.js.map +0 -1
  75. package/dist/cli/server-NHQ3QXOZ.js.map +0 -1
  76. /package/dist/cli/{chat-GZNB5625.js.map → chat-ZXF227MP.js.map} +0 -0
  77. /package/dist/cli/{chunk-JMDE6IO3.js.map → chunk-3FULTFRB.js.map} +0 -0
  78. /package/dist/cli/{chunk-HR5NBKEM.js.map → chunk-5AW6NIHU.js.map} +0 -0
  79. /package/dist/cli/{chunk-TE5UIIFL.js.map → chunk-5U5LMMFF.js.map} +0 -0
  80. /package/dist/cli/{chunk-EMMENC4O.js.map → chunk-EO6RPTJG.js.map} +0 -0
  81. /package/dist/cli/{chunk-2QSTA2QV.js.map → chunk-FD7SNDWW.js.map} +0 -0
  82. /package/dist/cli/{chunk-5OHHAQ4W.js.map → chunk-H2F4LDNH.js.map} +0 -0
  83. /package/dist/cli/{chunk-OG5JANQ4.js.map → chunk-IKSYVBBZ.js.map} +0 -0
  84. /package/dist/cli/{chunk-RUDBUHO4.js.map → chunk-KH5JIJJD.js.map} +0 -0
  85. /package/dist/cli/{chunk-H4CCXMDD.js.map → chunk-NQZ5U37J.js.map} +0 -0
  86. /package/dist/cli/{chunk-I4M5QJNL.js.map → chunk-O3AGYTG2.js.map} +0 -0
  87. /package/dist/cli/{chunk-V4Y732RQ.js.map → chunk-R7U44O3Y.js.map} +0 -0
  88. /package/dist/cli/{chunk-DOWEOA6E.js.map → chunk-SWUMD2LX.js.map} +0 -0
  89. /package/dist/cli/{chunk-S2RMQULY.js.map → chunk-TIJ4ZHD6.js.map} +0 -0
  90. /package/dist/cli/{chunk-MOJYKO2A.js.map → chunk-WKOXKCF3.js.map} +0 -0
  91. /package/dist/cli/{chunk-MRZG4GBF.js.map → chunk-XMR2VCGT.js.map} +0 -0
  92. /package/dist/cli/{code-PMPJWXEO.js.map → code-OKA5YPOH.js.map} +0 -0
  93. /package/dist/cli/{commands-QS6TG4G3.js.map → commands-3U6PUVSS.js.map} +0 -0
  94. /package/dist/cli/{commit-XPRSKUBF.js.map → commit-HFB7SRBU.js.map} +0 -0
  95. /package/dist/cli/{diff-I6W4AUWJ.js.map → diff-PGXW4YZD.js.map} +0 -0
  96. /package/dist/cli/{doctor-6XVZKT4U.js.map → doctor-WWJFLVCB.js.map} +0 -0
  97. /package/dist/cli/{mcp-7W7ANO2Y.js.map → mcp-Y3VKIK3T.js.map} +0 -0
  98. /package/dist/cli/{mcp-browse-LA4I4YIZ.js.map → mcp-browse-4IN2QIFR.js.map} +0 -0
  99. /package/dist/cli/{mcp-inspect-LWXXU7BY.js.map → mcp-inspect-BUXFXDHB.js.map} +0 -0
  100. /package/dist/cli/{prompt-RKZD4X6Y.js.map → prompt-US57R6BA.js.map} +0 -0
  101. /package/dist/cli/{replay-2X7MVXOI.js.map → replay-EQJMZRB3.js.map} +0 -0
  102. /package/dist/cli/{run-TPKXIJ27.js.map → run-KVEI66TR.js.map} +0 -0
  103. /package/dist/cli/{sessions-2A4DGSHA.js.map → sessions-TGVS2RQZ.js.map} +0 -0
  104. /package/dist/cli/{setup-GOLP7J4C.js.map → setup-WLKX6GGG.js.map} +0 -0
  105. /package/dist/cli/{stats-CGDAFDKI.js.map → stats-TCD7Q6MB.js.map} +0 -0
  106. /package/dist/cli/{version-FIL4ZFOS.js.map → version-BCWWS2OU.js.map} +0 -0
@@ -2,7 +2,7 @@
2
2
  import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
3
3
  import {
4
4
  t
5
- } from "./chunk-YW63N3ZR.js";
5
+ } from "./chunk-PIC5HJRD.js";
6
6
 
7
7
  // src/cli/ui/mcp-lifecycle.ts
8
8
  var STATE = {
@@ -11,8 +11,8 @@ var STATE = {
11
11
  failed: { glyph: "\u2716", label: () => t("mcpLifecycle.failed") },
12
12
  disabled: { glyph: "\u25CB", label: () => t("mcpLifecycle.disabled") },
13
13
  reconnect: { glyph: "\u21BB", label: () => t("mcpLifecycle.reconnect") },
14
- "tools-ready": { glyph: "\u26A1", label: () => "tools ready" },
15
- warn: { glyph: "\u26A0", label: () => "warn" }
14
+ "tools-ready": { glyph: "\u26A1", label: () => t("mcpLifecycle.toolsReady") },
15
+ warn: { glyph: "\u26A0", label: () => t("mcpLifecycle.warnLabel") }
16
16
  };
17
17
  var NAME_COL = 22;
18
18
  var STATE_COL = 15;
@@ -47,4 +47,4 @@ export {
47
47
  formatMcpLifecycleEvent,
48
48
  formatMcpSlowToast
49
49
  };
50
- //# sourceMappingURL=chunk-3WGTGXO4.js.map
50
+ //# sourceMappingURL=chunk-4E2BHJU4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/ui/mcp-lifecycle.ts","../../src/cli/ui/mcp-toast.ts"],"sourcesContent":["/** Formats one-liner MCP lifecycle events per `docs/design/agent-tui-terminal.html` §37. */\n\nimport { t } from \"../../i18n/index.js\";\n\nexport type McpLifecycleEvent =\n | { state: \"handshake\"; name: string }\n | {\n state: \"connected\";\n name: string;\n tools: number;\n resources?: number;\n prompts?: number;\n ms: number;\n }\n | { state: \"failed\"; name: string; reason: string }\n | { state: \"disabled\"; name: string }\n | { state: \"reconnect\"; name: string }\n | { state: \"tools-ready\"; name: string; tools: number; ms: number }\n | { state: \"warn\"; name: string; reason: string };\n\nconst STATE: Record<McpLifecycleEvent[\"state\"], { glyph: string; label: () => string }> = {\n handshake: { glyph: \"↻\", label: () => t(\"mcpLifecycle.handshake\") },\n connected: { glyph: \"✓\", label: () => t(\"mcpLifecycle.connected\") },\n failed: { glyph: \"✖\", label: () => t(\"mcpLifecycle.failed\") },\n disabled: { glyph: \"○\", label: () => t(\"mcpLifecycle.disabled\") },\n reconnect: { glyph: \"↻\", label: () => t(\"mcpLifecycle.reconnect\") },\n \"tools-ready\": { glyph: \"⚡\", label: () => t(\"mcpLifecycle.toolsReady\") },\n warn: { glyph: \"⚠\", label: () => t(\"mcpLifecycle.warnLabel\") },\n};\n\nconst NAME_COL = 22;\nconst STATE_COL = 15;\n\nexport function formatMcpLifecycleEvent(ev: McpLifecycleEvent): string {\n const { glyph, label } = STATE[ev.state];\n const namePart = `MCP · ${ev.name}`;\n const namePad = \" \".repeat(Math.max(1, NAME_COL - namePart.length));\n const stateField = `${glyph} ${label()}`.padEnd(STATE_COL);\n return `⌘ ${namePart}${namePad}${stateField}${describeDetail(ev)}`;\n}\n\nfunction describeDetail(ev: McpLifecycleEvent): string {\n if (ev.state === \"handshake\") return t(\"mcpLifecycle.initDetail\");\n if (ev.state === \"failed\") return ev.reason;\n if (ev.state === \"disabled\") return t(\"mcpLifecycle.disabledDetail\", { name: ev.name });\n if (ev.state === \"reconnect\") return t(\"mcpLifecycle.reconnectDetail\");\n if (ev.state === \"tools-ready\") return `${ev.tools} tools · ${ev.ms}ms`;\n if (ev.state === \"warn\") return ev.reason;\n const parts: string[] = [`${ev.tools} tools`];\n if (ev.resources && ev.resources > 0) parts.push(`${ev.resources} resources`);\n if (ev.prompts && ev.prompts > 0) parts.push(`${ev.prompts} prompts`);\n parts.push(`${ev.ms}ms`);\n return parts.join(\" · \");\n}\n","/** One-line warn toast emitted when an MCP server's p95 crosses the slow threshold (design §32). */\n\nimport { t } from \"../../i18n/index.js\";\n\nexport interface McpSlowToast {\n name: string;\n p95Ms: number;\n sampleSize: number;\n}\n\nexport function formatMcpSlowToast(tst: McpSlowToast): string {\n const seconds = (tst.p95Ms / 1000).toFixed(1);\n return t(\"mcpHealth.slowToast\", { name: tst.name, seconds, sampleSize: tst.sampleSize });\n}\n"],"mappings":";;;;;;;AAoBA,IAAM,QAAoF;AAAA,EACxF,WAAW,EAAE,OAAO,UAAK,OAAO,MAAM,EAAE,wBAAwB,EAAE;AAAA,EAClE,WAAW,EAAE,OAAO,UAAK,OAAO,MAAM,EAAE,wBAAwB,EAAE;AAAA,EAClE,QAAQ,EAAE,OAAO,UAAK,OAAO,MAAM,EAAE,qBAAqB,EAAE;AAAA,EAC5D,UAAU,EAAE,OAAO,UAAK,OAAO,MAAM,EAAE,uBAAuB,EAAE;AAAA,EAChE,WAAW,EAAE,OAAO,UAAK,OAAO,MAAM,EAAE,wBAAwB,EAAE;AAAA,EAClE,eAAe,EAAE,OAAO,UAAK,OAAO,MAAM,EAAE,yBAAyB,EAAE;AAAA,EACvE,MAAM,EAAE,OAAO,UAAK,OAAO,MAAM,EAAE,wBAAwB,EAAE;AAC/D;AAEA,IAAM,WAAW;AACjB,IAAM,YAAY;AAEX,SAAS,wBAAwB,IAA+B;AACrE,QAAM,EAAE,OAAO,MAAM,IAAI,MAAM,GAAG,KAAK;AACvC,QAAM,WAAW,YAAS,GAAG,IAAI;AACjC,QAAM,UAAU,IAAI,OAAO,KAAK,IAAI,GAAG,WAAW,SAAS,MAAM,CAAC;AAClE,QAAM,aAAa,GAAG,KAAK,IAAI,MAAM,CAAC,GAAG,OAAO,SAAS;AACzD,SAAO,UAAK,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,eAAe,EAAE,CAAC;AAClE;AAEA,SAAS,eAAe,IAA+B;AACrD,MAAI,GAAG,UAAU,YAAa,QAAO,EAAE,yBAAyB;AAChE,MAAI,GAAG,UAAU,SAAU,QAAO,GAAG;AACrC,MAAI,GAAG,UAAU,WAAY,QAAO,EAAE,+BAA+B,EAAE,MAAM,GAAG,KAAK,CAAC;AACtF,MAAI,GAAG,UAAU,YAAa,QAAO,EAAE,8BAA8B;AACrE,MAAI,GAAG,UAAU,cAAe,QAAO,GAAG,GAAG,KAAK,eAAY,GAAG,EAAE;AACnE,MAAI,GAAG,UAAU,OAAQ,QAAO,GAAG;AACnC,QAAM,QAAkB,CAAC,GAAG,GAAG,KAAK,QAAQ;AAC5C,MAAI,GAAG,aAAa,GAAG,YAAY,EAAG,OAAM,KAAK,GAAG,GAAG,SAAS,YAAY;AAC5E,MAAI,GAAG,WAAW,GAAG,UAAU,EAAG,OAAM,KAAK,GAAG,GAAG,OAAO,UAAU;AACpE,QAAM,KAAK,GAAG,GAAG,EAAE,IAAI;AACvB,SAAO,MAAM,KAAK,QAAK;AACzB;;;AC3CO,SAAS,mBAAmB,KAA2B;AAC5D,QAAM,WAAW,IAAI,QAAQ,KAAM,QAAQ,CAAC;AAC5C,SAAO,EAAE,uBAAuB,EAAE,MAAM,IAAI,MAAM,SAAS,YAAY,IAAI,WAAW,CAAC;AACzF;","names":[]}
@@ -8,7 +8,7 @@ import {
8
8
  compileFilters,
9
9
  defaultIndexConfig,
10
10
  resolveSemanticEmbeddingConfig
11
- } from "./chunk-CDVSFSAK.js";
11
+ } from "./chunk-FPME5QOO.js";
12
12
 
13
13
  // src/index/semantic/builder.ts
14
14
  import { promises as fs3 } from "fs";
@@ -882,4 +882,4 @@ export {
882
882
  indexExists,
883
883
  indexCompatible
884
884
  };
885
- //# sourceMappingURL=chunk-HR5NBKEM.js.map
885
+ //# sourceMappingURL=chunk-5AW6NIHU.js.map
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-25T6CVUP.js";
6
6
  import {
7
7
  loadRateLimit
8
- } from "./chunk-CDVSFSAK.js";
8
+ } from "./chunk-FPME5QOO.js";
9
9
 
10
10
  // src/retry.ts
11
11
  var DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504];
@@ -351,4 +351,4 @@ export {
351
351
  pickPrimaryBalance,
352
352
  DeepSeekClient
353
353
  };
354
- //# sourceMappingURL=chunk-TE5UIIFL.js.map
354
+ //# sourceMappingURL=chunk-5U5LMMFF.js.map
@@ -2,7 +2,7 @@
2
2
  import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
3
3
  import {
4
4
  addProjectShellAllowed
5
- } from "./chunk-CDVSFSAK.js";
5
+ } from "./chunk-FPME5QOO.js";
6
6
 
7
7
  // src/core/pause-gate.ts
8
8
  var PauseGate = class {
@@ -128,6 +128,322 @@ function safeCancelVerdict(kind) {
128
128
  }
129
129
  var pauseGate = new PauseGate();
130
130
 
131
+ // packages/core-utils/src/derive-prefix.ts
132
+ function derivePrefix(command) {
133
+ const tokens = command.trim().split(/\s+/).filter(Boolean);
134
+ if (tokens.length === 0) return "";
135
+ if (tokens.length === 1) return tokens[0];
136
+ const first = tokens[0];
137
+ const TWO_TOKEN_WRAPPERS = /* @__PURE__ */ new Set([
138
+ "npm",
139
+ "npx",
140
+ "pnpm",
141
+ "yarn",
142
+ "bun",
143
+ "git",
144
+ "cargo",
145
+ "go",
146
+ "docker",
147
+ "kubectl",
148
+ "python",
149
+ "python3",
150
+ "deno",
151
+ "pip",
152
+ "pip3",
153
+ "make",
154
+ "rake",
155
+ "bundle",
156
+ "gem"
157
+ ]);
158
+ return TWO_TOKEN_WRAPPERS.has(first) ? `${first} ${tokens[1]}` : first;
159
+ }
160
+
161
+ // packages/core-utils/src/approval-prompt.ts
162
+ function toApprovalPrompt(req) {
163
+ const payload = req.payload;
164
+ switch (req.kind) {
165
+ case "run_command":
166
+ return shellPrompt(req.id, payload, false);
167
+ case "run_background":
168
+ return shellPrompt(req.id, payload, true);
169
+ case "path_access":
170
+ return pathPrompt(req.id, payload);
171
+ case "plan_proposed":
172
+ return planPrompt(req.id, payload);
173
+ case "plan_checkpoint":
174
+ return checkpointPrompt(req.id, payload);
175
+ case "plan_revision":
176
+ return revisionPrompt(req.id, payload);
177
+ case "choice":
178
+ return choicePrompt(req.id, payload);
179
+ default:
180
+ return {
181
+ id: req.id,
182
+ kind: "shell",
183
+ tone: "warn",
184
+ title: "Unrecognized request",
185
+ subtitle: String(req.kind),
186
+ actions: [{ id: "deny", label: "Dismiss", kind: "reject" }]
187
+ };
188
+ }
189
+ }
190
+ function shellPrompt(id, payload, isBackground) {
191
+ const command = String(payload.command ?? "");
192
+ const cwd = payload.cwd ? String(payload.cwd) : void 0;
193
+ const timeoutSec = !isBackground && typeof payload.timeoutSec === "number" ? payload.timeoutSec : void 0;
194
+ const waitSec = isBackground && typeof payload.waitSec === "number" ? payload.waitSec : void 0;
195
+ const prefix = derivePrefix(command);
196
+ const meta = {};
197
+ if (cwd) meta.cwd = cwd;
198
+ if (timeoutSec !== void 0) meta.timeout = `${timeoutSec}s`;
199
+ if (waitSec !== void 0) meta.wait = `${waitSec}s`;
200
+ return {
201
+ id,
202
+ kind: "shell",
203
+ tone: "warn",
204
+ title: isBackground ? "Run background command" : "Run command",
205
+ subtitle: command,
206
+ preview: command,
207
+ meta: Object.keys(meta).length > 0 ? meta : void 0,
208
+ actions: [
209
+ {
210
+ id: "run_once",
211
+ label: "Run once",
212
+ kind: "allow_once"
213
+ },
214
+ {
215
+ id: "always_allow",
216
+ label: `Always allow \u2014 ${prefix}`,
217
+ kind: "allow_always"
218
+ },
219
+ {
220
+ id: "deny",
221
+ label: "Deny",
222
+ kind: "reject",
223
+ secondaryInput: {
224
+ hint: "Reason for denial (optional)",
225
+ required: false
226
+ }
227
+ }
228
+ ],
229
+ data: { prefix }
230
+ };
231
+ }
232
+ function pathPrompt(id, payload) {
233
+ const path = String(payload.path ?? "");
234
+ const intent = payload.intent === "write" ? "write" : "read";
235
+ const toolName = String(payload.toolName ?? "");
236
+ const sandboxRoot = String(payload.sandboxRoot ?? "");
237
+ const allowPrefix = String(payload.allowPrefix ?? "");
238
+ const meta = {};
239
+ if (sandboxRoot) meta.sandboxRoot = sandboxRoot;
240
+ return {
241
+ id,
242
+ kind: "path",
243
+ tone: "warn",
244
+ title: `Access path \u2014 ${intent}`,
245
+ subtitle: path,
246
+ preview: `${toolName} \u2192 ${path}`,
247
+ meta: Object.keys(meta).length > 0 ? meta : void 0,
248
+ actions: [
249
+ {
250
+ id: "run_once",
251
+ label: intent === "write" ? "Allow write" : "Allow read",
252
+ kind: "allow_once"
253
+ },
254
+ {
255
+ id: "always_allow",
256
+ label: `Always allow \u2014 ${allowPrefix}`,
257
+ kind: "allow_always"
258
+ },
259
+ {
260
+ id: "deny",
261
+ label: "Deny",
262
+ kind: "reject",
263
+ secondaryInput: {
264
+ hint: "Reason for denial (optional)",
265
+ required: false
266
+ }
267
+ }
268
+ ],
269
+ data: { prefix: allowPrefix, intent }
270
+ };
271
+ }
272
+ function planPrompt(id, payload) {
273
+ const plan = String(payload.plan ?? "");
274
+ const summary = payload.summary ? String(payload.summary) : void 0;
275
+ const steps = Array.isArray(payload.steps) ? payload.steps : [];
276
+ const subtitle = summary ?? (plan.length > 80 ? `${plan.slice(0, 80)}\u2026` : plan);
277
+ const meta = {};
278
+ if (steps.length > 0) meta.steps = String(steps.length);
279
+ return {
280
+ id,
281
+ kind: "plan",
282
+ tone: "accent",
283
+ title: "Approve plan",
284
+ subtitle,
285
+ preview: plan,
286
+ meta: Object.keys(meta).length > 0 ? meta : void 0,
287
+ actions: [
288
+ { id: "approve", label: "Approve", kind: "allow_once" },
289
+ { id: "refine", label: "Refine", kind: "custom" },
290
+ { id: "cancel", label: "Cancel", kind: "reject" }
291
+ ]
292
+ };
293
+ }
294
+ function checkpointPrompt(id, payload) {
295
+ const titleText = String(payload.title ?? "step complete");
296
+ const result = String(payload.result ?? "");
297
+ const notes = payload.notes ? String(payload.notes) : void 0;
298
+ const completed = typeof payload.completed === "number" ? payload.completed : 0;
299
+ const total = typeof payload.total === "number" ? payload.total : 0;
300
+ const meta = {};
301
+ if (total > 0) meta.progress = `${completed}/${total}`;
302
+ let preview = result;
303
+ if (notes) preview += `
304
+ ${notes}`;
305
+ return {
306
+ id,
307
+ kind: "checkpoint",
308
+ tone: "info",
309
+ title: `Checkpoint \u2014 ${titleText}`,
310
+ subtitle: result,
311
+ preview: preview || void 0,
312
+ meta: Object.keys(meta).length > 0 ? meta : void 0,
313
+ actions: [
314
+ { id: "continue", label: "Continue", kind: "allow_once" },
315
+ { id: "revise", label: "Revise", kind: "custom" },
316
+ { id: "stop", label: "Stop", kind: "reject" }
317
+ ]
318
+ };
319
+ }
320
+ function revisionPrompt(id, payload) {
321
+ const reason = String(payload.reason ?? "");
322
+ const remainingSteps = Array.isArray(payload.remainingSteps) ? payload.remainingSteps : [];
323
+ const summary = payload.summary ? String(payload.summary) : void 0;
324
+ const subtitle = summary ?? (reason.length > 80 ? `${reason.slice(0, 80)}\u2026` : reason);
325
+ const meta = {};
326
+ if (remainingSteps.length > 0) meta.steps = String(remainingSteps.length);
327
+ return {
328
+ id,
329
+ kind: "revision",
330
+ tone: "warn",
331
+ title: "Approve plan revision",
332
+ subtitle,
333
+ preview: reason,
334
+ meta: Object.keys(meta).length > 0 ? meta : void 0,
335
+ actions: [
336
+ { id: "accept", label: "Accept", kind: "allow_once" },
337
+ { id: "reject", label: "Keep original", kind: "reject" }
338
+ ]
339
+ };
340
+ }
341
+ function choicePrompt(id, payload) {
342
+ const question = String(payload.question ?? "Choose an option");
343
+ const rawOptions = Array.isArray(payload.options) ? payload.options : [];
344
+ const allowCustom = payload.allowCustom === true;
345
+ const actions = rawOptions.map((o) => {
346
+ const opt = o;
347
+ const optId = String(opt.id ?? "");
348
+ const optTitle = String(opt.title ?? optId);
349
+ return { id: optId, label: optTitle, kind: "custom" };
350
+ });
351
+ actions.push({ id: "cancel", label: "Cancel", kind: "reject" });
352
+ return {
353
+ id,
354
+ kind: "choice",
355
+ tone: "info",
356
+ title: question,
357
+ actions,
358
+ data: allowCustom ? { allowCustom: true } : void 0
359
+ };
360
+ }
361
+ function resolveApprovalPrompt(prompt, actionId, secondaryInput) {
362
+ const action = prompt.actions.find((a) => a.id === actionId);
363
+ if (!action) {
364
+ return safeDefaultForKind(prompt.kind);
365
+ }
366
+ switch (prompt.kind) {
367
+ case "shell":
368
+ case "path": {
369
+ if (action.kind === "reject") {
370
+ return { type: "deny", denyContext: secondaryInput };
371
+ }
372
+ if (action.kind === "allow_always") {
373
+ return {
374
+ type: "always_allow",
375
+ prefix: String(prompt.data?.prefix ?? "")
376
+ };
377
+ }
378
+ return { type: "run_once" };
379
+ }
380
+ case "plan": {
381
+ if (action.id === "approve") return { type: "approve" };
382
+ if (action.id === "refine") return { type: "refine" };
383
+ return { type: "cancel" };
384
+ }
385
+ case "checkpoint": {
386
+ if (action.id === "continue") return { type: "continue" };
387
+ if (action.id === "revise") return { type: "revise" };
388
+ return { type: "stop" };
389
+ }
390
+ case "revision": {
391
+ if (action.id === "accept") return { type: "accepted" };
392
+ return { type: "rejected" };
393
+ }
394
+ case "choice": {
395
+ if (action.kind === "reject") return { type: "cancel" };
396
+ return { type: "pick", optionId: action.id };
397
+ }
398
+ }
399
+ }
400
+ function safeDefaultForKind(kind) {
401
+ switch (kind) {
402
+ case "shell":
403
+ case "path":
404
+ return { type: "deny" };
405
+ case "plan":
406
+ return { type: "cancel" };
407
+ case "checkpoint":
408
+ return { type: "stop" };
409
+ case "revision":
410
+ return { type: "rejected" };
411
+ case "choice":
412
+ return { type: "cancel" };
413
+ }
414
+ }
415
+
416
+ // packages/core-utils/src/tildeify.ts
417
+ import { homedir } from "os";
418
+
419
+ // packages/core-utils/src/tool-kind.ts
420
+ var READ_TOOLS = /* @__PURE__ */ new Set([
421
+ "read_file",
422
+ "list_directory",
423
+ "directory_tree",
424
+ "get_file_info",
425
+ "glob"
426
+ ]);
427
+ var EDIT_TOOLS = /* @__PURE__ */ new Set([
428
+ "write_file",
429
+ "edit_file",
430
+ "multi_edit",
431
+ "create_directory",
432
+ "delete_file",
433
+ "delete_directory",
434
+ "move_file",
435
+ "copy_file"
436
+ ]);
437
+ var SEARCH_TOOLS = /* @__PURE__ */ new Set(["search_content", "search_files"]);
438
+ var EXECUTE_TOOLS = /* @__PURE__ */ new Set(["run_command", "run_background"]);
439
+ function toolKindFor(name) {
440
+ if (READ_TOOLS.has(name)) return "read";
441
+ if (EDIT_TOOLS.has(name)) return "edit";
442
+ if (SEARCH_TOOLS.has(name)) return "search";
443
+ if (EXECUTE_TOOLS.has(name)) return "execute";
444
+ return "other";
445
+ }
446
+
131
447
  // src/tools/jobs.ts
132
448
  import { spawn as spawn3 } from "child_process";
133
449
  import * as pathMod5 from "path";
@@ -573,78 +889,6 @@ var OutputBuffer = class {
573
889
  // src/tools/shell/parse.ts
574
890
  import { homedir as homedir2 } from "os";
575
891
  import * as pathMod2 from "path";
576
-
577
- // packages/core-utils/src/derive-prefix.ts
578
- function derivePrefix(command) {
579
- const tokens = command.trim().split(/\s+/).filter(Boolean);
580
- if (tokens.length === 0) return "";
581
- if (tokens.length === 1) return tokens[0];
582
- const first = tokens[0];
583
- const TWO_TOKEN_WRAPPERS = /* @__PURE__ */ new Set([
584
- "npm",
585
- "npx",
586
- "pnpm",
587
- "yarn",
588
- "bun",
589
- "git",
590
- "cargo",
591
- "go",
592
- "docker",
593
- "kubectl",
594
- "python",
595
- "python3",
596
- "deno",
597
- "pip",
598
- "pip3",
599
- "make",
600
- "rake",
601
- "bundle",
602
- "gem"
603
- ]);
604
- return TWO_TOKEN_WRAPPERS.has(first) ? `${first} ${tokens[1]}` : first;
605
- }
606
-
607
- // packages/core-utils/src/tildeify.ts
608
- import { homedir } from "os";
609
- function tildeify(p) {
610
- const home = homedir();
611
- if (!home) return p;
612
- const normalized = home.replace(/[\\/]+$/, "");
613
- if (p === normalized) return "~";
614
- if (p.startsWith(`${normalized}/`)) return `~/${p.slice(normalized.length + 1)}`;
615
- if (p.startsWith(`${normalized}\\`)) return `~\\${p.slice(normalized.length + 1)}`;
616
- return p;
617
- }
618
-
619
- // packages/core-utils/src/tool-kind.ts
620
- var READ_TOOLS = /* @__PURE__ */ new Set([
621
- "read_file",
622
- "list_directory",
623
- "directory_tree",
624
- "get_file_info",
625
- "glob"
626
- ]);
627
- var EDIT_TOOLS = /* @__PURE__ */ new Set([
628
- "write_file",
629
- "edit_file",
630
- "multi_edit",
631
- "create_directory",
632
- "delete_file",
633
- "delete_directory",
634
- "move_file",
635
- "copy_file"
636
- ]);
637
- var SEARCH_TOOLS = /* @__PURE__ */ new Set(["search_content", "search_files"]);
638
- var EXECUTE_TOOLS = /* @__PURE__ */ new Set(["run_command", "run_background"]);
639
- function toolKindFor(name) {
640
- if (READ_TOOLS.has(name)) return "read";
641
- if (EDIT_TOOLS.has(name)) return "edit";
642
- if (SEARCH_TOOLS.has(name)) return "search";
643
- if (EXECUTE_TOOLS.has(name)) return "execute";
644
- return "other";
645
- }
646
-
647
- // src/tools/shell/parse.ts
648
892
  var BUILTIN_ALLOWLIST = [
649
893
  // Repo inspection
650
894
  "git status",
@@ -2010,11 +2254,12 @@ export {
2010
2254
  lineDiff,
2011
2255
  JobRegistry,
2012
2256
  derivePrefix,
2013
- tildeify,
2014
2257
  toolKindFor,
2258
+ toApprovalPrompt,
2259
+ resolveApprovalPrompt,
2015
2260
  BUILTIN_ALLOWLIST,
2016
2261
  runCommand,
2017
2262
  registerShellTools,
2018
2263
  formatCommandResult
2019
2264
  };
2020
- //# sourceMappingURL=chunk-WZGNXR6E.js.map
2265
+ //# sourceMappingURL=chunk-6FRNXWDZ.js.map