@sortedyuan/maybecode 0.3.2 → 0.5.0

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 (295) hide show
  1. package/README.md +166 -55
  2. package/README.zh-CN.md +267 -0
  3. package/dist/application.d.ts +40 -34
  4. package/dist/application.d.ts.map +1 -1
  5. package/dist/application.js +290 -170
  6. package/dist/application.js.map +1 -1
  7. package/dist/args.d.ts +2 -2
  8. package/dist/args.d.ts.map +1 -1
  9. package/dist/args.js +50 -27
  10. package/dist/args.js.map +1 -1
  11. package/dist/bin.js +82 -71
  12. package/dist/bin.js.map +4 -4
  13. package/dist/cli/chunk-3IORPKBL.js +3572 -0
  14. package/dist/cli/chunk-3IORPKBL.js.map +7 -0
  15. package/dist/cli/{chunk-LVTRXPDS.js → chunk-4B2Z6KW7.js} +1547 -1536
  16. package/dist/cli/chunk-4B2Z6KW7.js.map +7 -0
  17. package/dist/cli/{chunk-JT6VBKOM.js → chunk-4WG6JIJJ.js} +127 -33
  18. package/dist/cli/{chunk-JT6VBKOM.js.map → chunk-4WG6JIJJ.js.map} +3 -3
  19. package/dist/cli/{chunk-K5JWPNSY.js → chunk-5SLWALZK.js} +3521 -16164
  20. package/dist/cli/chunk-5SLWALZK.js.map +7 -0
  21. package/dist/cli/chunk-MNBYXL5Y.js +132 -0
  22. package/dist/cli/chunk-MNBYXL5Y.js.map +7 -0
  23. package/dist/cli/{chunk-F4XRPLUM.js → chunk-SLWLUEHQ.js} +226 -86
  24. package/dist/cli/chunk-SLWLUEHQ.js.map +7 -0
  25. package/dist/cli/chunk-UQDZ55LQ.js +199 -0
  26. package/dist/cli/chunk-UQDZ55LQ.js.map +7 -0
  27. package/dist/cli/{chunk-7ISOHFS7.js → chunk-WMSG5ZTR.js} +717 -388
  28. package/dist/cli/chunk-WMSG5ZTR.js.map +7 -0
  29. package/dist/cli/chunk-WVIRS76R.js +4057 -0
  30. package/dist/cli/chunk-WVIRS76R.js.map +7 -0
  31. package/dist/cli/{chunk-HOU5ITUK.js → chunk-XTEMRAQW.js} +1 -1
  32. package/dist/cli/chunk-XTEMRAQW.js.map +7 -0
  33. package/dist/cli/chunk-Z3BOPBVU.js +91 -0
  34. package/dist/cli/chunk-Z3BOPBVU.js.map +7 -0
  35. package/dist/cli/{configured-WHY3GGAJ.js → configured-ACNM6TRQ.js} +10 -9
  36. package/dist/cli/{file-type-R2T7TBHI.js → file-type-HLHPV7WC.js} +817 -13
  37. package/dist/cli/file-type-HLHPV7WC.js.map +7 -0
  38. package/dist/cli/mcp-auth-XD5U7WCV.js +74 -0
  39. package/dist/cli/mcp-auth-XD5U7WCV.js.map +7 -0
  40. package/dist/cli/onboarding-WQWCPYEO.js +530 -0
  41. package/dist/cli/onboarding-WQWCPYEO.js.map +7 -0
  42. package/dist/cli/onboarding-check-HRRI5OJ7.js +32 -0
  43. package/dist/cli/onboarding-check-HRRI5OJ7.js.map +7 -0
  44. package/dist/cli/{retained-tui-VJ3VX4R3.js → retained-tui-QF5VMYLC.js} +788 -332
  45. package/dist/cli/retained-tui-QF5VMYLC.js.map +7 -0
  46. package/dist/cli/{sixel-LWTCM76G.js → sixel-ISZ4FZ3U.js} +37 -37
  47. package/dist/cli/{sixel-LWTCM76G.js.map → sixel-ISZ4FZ3U.js.map} +1 -1
  48. package/dist/cli/{team-T7G7PPNN.js → team-O2I5BXHM.js} +7 -6
  49. package/dist/cli/{team-v2-JGBBQ7FR.js → team-v2-YYO2G7DJ.js} +816 -390
  50. package/dist/cli/team-v2-YYO2G7DJ.js.map +7 -0
  51. package/dist/cli/{web-server-FOMNPY7Q.js → web-server-SXMH6FGA.js} +55 -19
  52. package/dist/cli/web-server-SXMH6FGA.js.map +7 -0
  53. package/dist/cli/{web-ui-COB6PKC5.js → web-ui-UWQUFE4W.js} +7 -6
  54. package/dist/config-schema.json +337 -0
  55. package/dist/configured.d.ts +18 -11
  56. package/dist/configured.d.ts.map +1 -1
  57. package/dist/configured.js +213 -390
  58. package/dist/configured.js.map +1 -1
  59. package/dist/controller.d.ts +19 -18
  60. package/dist/controller.d.ts.map +1 -1
  61. package/dist/delegation-commands.d.ts +1 -1
  62. package/dist/delegation-commands.d.ts.map +1 -1
  63. package/dist/delegation-commands.js +8 -8
  64. package/dist/delegation-commands.js.map +1 -1
  65. package/dist/errors.d.ts +2 -1
  66. package/dist/errors.d.ts.map +1 -1
  67. package/dist/errors.js +2 -1
  68. package/dist/errors.js.map +1 -1
  69. package/dist/events.d.ts +8 -6
  70. package/dist/events.d.ts.map +1 -1
  71. package/dist/fork-picker.d.ts.map +1 -1
  72. package/dist/fork-picker.js +19 -5
  73. package/dist/fork-picker.js.map +1 -1
  74. package/dist/git-request.d.ts +6 -6
  75. package/dist/git-request.d.ts.map +1 -1
  76. package/dist/git-request.js +28 -15
  77. package/dist/git-request.js.map +1 -1
  78. package/dist/goal-commands.d.ts +1 -1
  79. package/dist/goal-commands.d.ts.map +1 -1
  80. package/dist/goal-commands.js +12 -5
  81. package/dist/goal-commands.js.map +1 -1
  82. package/dist/index.d.ts +5 -37
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +3 -36
  85. package/dist/index.js.map +1 -1
  86. package/dist/instructions.d.ts +2 -7
  87. package/dist/instructions.d.ts.map +1 -1
  88. package/dist/instructions.js +7 -15
  89. package/dist/instructions.js.map +1 -1
  90. package/dist/keymap.d.ts +2 -2
  91. package/dist/keymap.d.ts.map +1 -1
  92. package/dist/keymap.js +2 -2
  93. package/dist/keymap.js.map +1 -1
  94. package/dist/maybecode-config.schema.json +1765 -0
  95. package/dist/mcp-auth.d.ts +1 -1
  96. package/dist/mcp-auth.d.ts.map +1 -1
  97. package/dist/mcp-auth.js +11 -8
  98. package/dist/mcp-auth.js.map +1 -1
  99. package/dist/mcp-commands.d.ts.map +1 -1
  100. package/dist/mcp-commands.js +18 -4
  101. package/dist/mcp-commands.js.map +1 -1
  102. package/dist/mcp-interaction-ui.d.ts.map +1 -1
  103. package/dist/mcp-interaction-ui.js +11 -4
  104. package/dist/mcp-interaction-ui.js.map +1 -1
  105. package/dist/media-history.d.ts +1 -1
  106. package/dist/media-history.d.ts.map +1 -1
  107. package/dist/media-history.js +8 -2
  108. package/dist/media-history.js.map +1 -1
  109. package/dist/model-picker.d.ts.map +1 -1
  110. package/dist/model-picker.js +10 -11
  111. package/dist/model-picker.js.map +1 -1
  112. package/dist/model-transition.d.ts +11 -0
  113. package/dist/model-transition.d.ts.map +1 -0
  114. package/dist/model-transition.js +48 -0
  115. package/dist/model-transition.js.map +1 -0
  116. package/dist/model.d.ts +2 -2
  117. package/dist/model.d.ts.map +1 -1
  118. package/dist/model.js +8 -4
  119. package/dist/model.js.map +1 -1
  120. package/dist/onboarding-check.d.ts +3 -0
  121. package/dist/onboarding-check.d.ts.map +1 -0
  122. package/dist/onboarding-check.js +22 -0
  123. package/dist/onboarding-check.js.map +1 -0
  124. package/dist/onboarding.d.ts +6 -0
  125. package/dist/onboarding.d.ts.map +1 -0
  126. package/dist/onboarding.js +463 -0
  127. package/dist/onboarding.js.map +1 -0
  128. package/dist/plugins/application.d.ts +6 -4
  129. package/dist/plugins/application.d.ts.map +1 -1
  130. package/dist/plugins/application.js +106 -52
  131. package/dist/plugins/application.js.map +1 -1
  132. package/dist/plugins/instructions.d.ts +1 -1
  133. package/dist/plugins/instructions.d.ts.map +1 -1
  134. package/dist/plugins/instructions.js +24 -11
  135. package/dist/plugins/instructions.js.map +1 -1
  136. package/dist/plugins/resources.d.ts +2 -2
  137. package/dist/plugins/resources.d.ts.map +1 -1
  138. package/dist/plugins/resources.js +22 -12
  139. package/dist/plugins/resources.js.map +1 -1
  140. package/dist/policy.d.ts +1 -1
  141. package/dist/policy.d.ts.map +1 -1
  142. package/dist/policy.js +59 -11
  143. package/dist/policy.js.map +1 -1
  144. package/dist/run.d.ts +2 -0
  145. package/dist/run.d.ts.map +1 -1
  146. package/dist/run.js +38 -33
  147. package/dist/run.js.map +1 -1
  148. package/dist/runtime-instructions.d.ts +1 -1
  149. package/dist/runtime-instructions.d.ts.map +1 -1
  150. package/dist/runtime-instructions.js +15 -7
  151. package/dist/runtime-instructions.js.map +1 -1
  152. package/dist/session-navigation.d.ts +6 -0
  153. package/dist/session-navigation.d.ts.map +1 -0
  154. package/dist/session-navigation.js +64 -0
  155. package/dist/session-navigation.js.map +1 -0
  156. package/dist/session-picker.d.ts +1 -1
  157. package/dist/session-picker.d.ts.map +1 -1
  158. package/dist/session-picker.js +23 -32
  159. package/dist/session-picker.js.map +1 -1
  160. package/dist/settings.d.ts +718 -0
  161. package/dist/settings.d.ts.map +1 -0
  162. package/dist/settings.js +14 -0
  163. package/dist/settings.js.map +1 -0
  164. package/dist/skills.d.ts +1 -1
  165. package/dist/skills.d.ts.map +1 -1
  166. package/dist/skills.js +10 -12
  167. package/dist/skills.js.map +1 -1
  168. package/dist/slash-commands.d.ts +2 -2
  169. package/dist/slash-commands.d.ts.map +1 -1
  170. package/dist/slash-commands.js +149 -67
  171. package/dist/slash-commands.js.map +1 -1
  172. package/dist/team-execution.d.ts +10 -0
  173. package/dist/team-execution.d.ts.map +1 -0
  174. package/dist/team-execution.js +29 -0
  175. package/dist/team-execution.js.map +1 -0
  176. package/dist/team-patches.d.ts.map +1 -1
  177. package/dist/team-patches.js +149 -52
  178. package/dist/team-patches.js.map +1 -1
  179. package/dist/team-plan.d.ts +2 -2
  180. package/dist/team-plan.d.ts.map +1 -1
  181. package/dist/team-plan.js +115 -34
  182. package/dist/team-plan.js.map +1 -1
  183. package/dist/team-recovery.d.ts +1 -1
  184. package/dist/team-recovery.d.ts.map +1 -1
  185. package/dist/team-recovery.js +40 -10
  186. package/dist/team-recovery.js.map +1 -1
  187. package/dist/team-v2.d.ts.map +1 -1
  188. package/dist/team-v2.js +335 -104
  189. package/dist/team-v2.js.map +1 -1
  190. package/dist/team-verification.d.ts +4 -2
  191. package/dist/team-verification.d.ts.map +1 -1
  192. package/dist/team-verification.js +300 -97
  193. package/dist/team-verification.js.map +1 -1
  194. package/dist/team.d.ts +2 -2
  195. package/dist/team.d.ts.map +1 -1
  196. package/dist/team.js +172 -62
  197. package/dist/team.js.map +1 -1
  198. package/dist/terminal-web.d.ts +1 -0
  199. package/dist/terminal-web.d.ts.map +1 -1
  200. package/dist/terminal-web.js +28 -10
  201. package/dist/terminal-web.js.map +1 -1
  202. package/dist/ui/actions.d.ts.map +1 -1
  203. package/dist/ui/actions.js.map +1 -1
  204. package/dist/ui/retained-tui.d.ts.map +1 -1
  205. package/dist/ui/retained-tui.js +231 -173
  206. package/dist/ui/retained-tui.js.map +1 -1
  207. package/dist/ui/{prototype-view.d.ts → terminal-view.d.ts} +7 -7
  208. package/dist/ui/terminal-view.d.ts.map +1 -0
  209. package/dist/ui/{prototype-view.js → terminal-view.js} +185 -98
  210. package/dist/ui/terminal-view.js.map +1 -0
  211. package/dist/web-commands.d.ts.map +1 -1
  212. package/dist/web-commands.js +160 -57
  213. package/dist/web-commands.js.map +1 -1
  214. package/dist/web-extension.d.ts.map +1 -1
  215. package/dist/web-extension.js +14 -4
  216. package/dist/web-extension.js.map +1 -1
  217. package/dist/web-server.d.ts.map +1 -1
  218. package/dist/web-server.js +2 -1
  219. package/dist/web-server.js.map +1 -1
  220. package/dist/web-ui.d.ts.map +1 -1
  221. package/dist/web-ui.js +167 -40
  222. package/dist/web-ui.js.map +1 -1
  223. package/dist/workspace-configuration.d.ts +7 -0
  224. package/dist/workspace-configuration.d.ts.map +1 -0
  225. package/dist/workspace-configuration.js +134 -0
  226. package/dist/workspace-configuration.js.map +1 -0
  227. package/dist/workspace-state.d.ts +20 -0
  228. package/dist/workspace-state.d.ts.map +1 -0
  229. package/dist/workspace-state.js +2 -0
  230. package/dist/workspace-state.js.map +1 -0
  231. package/dist/workspace.d.ts +26 -43
  232. package/dist/workspace.d.ts.map +1 -1
  233. package/dist/workspace.js +261 -323
  234. package/dist/workspace.js.map +1 -1
  235. package/package.json +21 -31
  236. package/dist/cli/chunk-7ISOHFS7.js.map +0 -7
  237. package/dist/cli/chunk-F4XRPLUM.js.map +0 -7
  238. package/dist/cli/chunk-H7SNBFO4.js +0 -5522
  239. package/dist/cli/chunk-H7SNBFO4.js.map +0 -7
  240. package/dist/cli/chunk-HOU5ITUK.js.map +0 -7
  241. package/dist/cli/chunk-K5JWPNSY.js.map +0 -7
  242. package/dist/cli/chunk-LVTRXPDS.js.map +0 -7
  243. package/dist/cli/chunk-VAZMCNBB.js +0 -686
  244. package/dist/cli/chunk-VAZMCNBB.js.map +0 -7
  245. package/dist/cli/chunk-WOFEI42C.js +0 -7820
  246. package/dist/cli/chunk-WOFEI42C.js.map +0 -7
  247. package/dist/cli/file-type-R2T7TBHI.js.map +0 -7
  248. package/dist/cli/mcp-auth-UNRHSIKJ.js +0 -63
  249. package/dist/cli/mcp-auth-UNRHSIKJ.js.map +0 -7
  250. package/dist/cli/retained-tui-VJ3VX4R3.js.map +0 -7
  251. package/dist/cli/team-v2-JGBBQ7FR.js.map +0 -7
  252. package/dist/cli/tui-SA74DKMA.js +0 -1705
  253. package/dist/cli/tui-SA74DKMA.js.map +0 -7
  254. package/dist/cli/web-server-FOMNPY7Q.js.map +0 -7
  255. package/dist/delegation.d.ts +0 -2
  256. package/dist/delegation.d.ts.map +0 -1
  257. package/dist/delegation.js +0 -2
  258. package/dist/delegation.js.map +0 -1
  259. package/dist/history-memory.d.ts +0 -2
  260. package/dist/history-memory.d.ts.map +0 -1
  261. package/dist/history-memory.js +0 -2
  262. package/dist/history-memory.js.map +0 -1
  263. package/dist/subagent-budget.d.ts +0 -2
  264. package/dist/subagent-budget.d.ts.map +0 -1
  265. package/dist/subagent-budget.js +0 -2
  266. package/dist/subagent-budget.js.map +0 -1
  267. package/dist/subagent-files.d.ts +0 -2
  268. package/dist/subagent-files.d.ts.map +0 -1
  269. package/dist/subagent-files.js +0 -2
  270. package/dist/subagent-files.js.map +0 -1
  271. package/dist/subagent-host.d.ts +0 -2
  272. package/dist/subagent-host.d.ts.map +0 -1
  273. package/dist/subagent-host.js +0 -2
  274. package/dist/subagent-host.js.map +0 -1
  275. package/dist/subagent-instructions.d.ts +0 -2
  276. package/dist/subagent-instructions.d.ts.map +0 -1
  277. package/dist/subagent-instructions.js +0 -2
  278. package/dist/subagent-instructions.js.map +0 -1
  279. package/dist/subagents.d.ts +0 -2
  280. package/dist/subagents.d.ts.map +0 -1
  281. package/dist/subagents.js +0 -2
  282. package/dist/subagents.js.map +0 -1
  283. package/dist/summarizer.d.ts +0 -2
  284. package/dist/summarizer.d.ts.map +0 -1
  285. package/dist/summarizer.js +0 -2
  286. package/dist/summarizer.js.map +0 -1
  287. package/dist/tui.d.ts +0 -7
  288. package/dist/tui.d.ts.map +0 -1
  289. package/dist/tui.js +0 -1109
  290. package/dist/tui.js.map +0 -1
  291. package/dist/ui/prototype-view.d.ts.map +0 -1
  292. package/dist/ui/prototype-view.js.map +0 -1
  293. /package/dist/cli/{configured-WHY3GGAJ.js.map → configured-ACNM6TRQ.js.map} +0 -0
  294. /package/dist/cli/{team-T7G7PPNN.js.map → team-O2I5BXHM.js.map} +0 -0
  295. /package/dist/cli/{web-ui-COB6PKC5.js.map → web-ui-UWQUFE4W.js.map} +0 -0
@@ -1,29 +1,35 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
+ import {
3
+ SlashCommandRegistry
4
+ } from "./chunk-Z3BOPBVU.js";
2
5
  import {
3
6
  UiError,
4
7
  commandArgs
5
- } from "./chunk-HOU5ITUK.js";
8
+ } from "./chunk-XTEMRAQW.js";
6
9
  import {
7
- GitCheckpointError,
8
- GitWorkspaceConflictError,
9
10
  parsePermissionMode
10
- } from "./chunk-H7SNBFO4.js";
11
+ } from "./chunk-MNBYXL5Y.js";
11
12
  import {
12
13
  MaybeCodeUsageError,
13
14
  mcpPromptToUserMessage,
14
15
  mcpResourceToUserMessage,
15
16
  previewMcpMessage
16
- } from "./chunk-K5JWPNSY.js";
17
+ } from "./chunk-5SLWALZK.js";
17
18
  import {
18
19
  __name
19
20
  } from "./chunk-E732GDOI.js";
20
21
 
22
+ // apps/maybecode/src/web-ui.ts
23
+ import { omitUndefined } from "@sortedyuan/may/core";
24
+
21
25
  // packages/ui/client/dist/application.js
22
26
  import { createHash as createHash2, randomUUID } from "node:crypto";
23
27
  import { readEmbeddedImage } from "@sortedyuan/media";
28
+ import { AsyncStateSerializer } from "@sortedyuan/may/core";
24
29
 
25
30
  // packages/ui/client/dist/projection.js
26
31
  import { displayParts, imageAttachment } from "@sortedyuan/media";
32
+ import { isSessionRunTerminalEvent, readSessionTranscript, sessionToolFailureStatus } from "@sortedyuan/may/session";
27
33
  var LIMIT = 65536;
28
34
  function bounded(text) {
29
35
  return text.length > LIMIT ? text.slice(0, LIMIT) + "\n\u2026\u663E\u793A\u5DF2\u622A\u65AD\uFF0C\u8BF7\u5728\u5BBF\u4E3B\u4E2D\u67E5\u770B\u5B8C\u6574\u5185\u5BB9\u3002" : text;
@@ -87,27 +93,21 @@ var UiProjection = class {
87
93
  }
88
94
  history(events) {
89
95
  let inputId;
90
- const steering = /* @__PURE__ */ new Map();
91
- for (const event of events) {
92
- if (event.type === "input.submitted") {
93
- if (event.inputId !== void 0)
94
- steering.delete(event.inputId);
95
- inputId = `input:${event.seq}`;
96
- this.set({ id: inputId, kind: "user", text: contentText(event.message.content), content: this.content(event.message.content) });
97
- } else if (event.type === "input.steering.queued")
98
- steering.set(event.input.inputId, event.input.message);
99
- else if (event.type === "input.steering.delivered") {
100
- this.steered(event.runId, event.step, event.inputIds.map((id) => {
101
- const message = steering.get(id);
102
- if (message === void 0)
103
- throw new Error(`Missing steering input in UI history: ${id}`);
104
- steering.delete(id);
105
- return message;
106
- }));
107
- } else if (event.type === "input.steering.finished" && event.status === "cancelled")
108
- for (const id of event.inputIds)
109
- steering.delete(id);
110
- else if (event.type === "run.started" && inputId) {
96
+ for (const entry of readSessionTranscript(events)) {
97
+ if (entry.type === "user-message") {
98
+ if (entry.source !== "steering")
99
+ inputId = entry.id;
100
+ this.set({
101
+ id: entry.id,
102
+ kind: "user",
103
+ text: contentText(entry.message.content),
104
+ content: this.content(entry.message.content),
105
+ ...entry.runId === void 0 ? {} : { runId: entry.runId }
106
+ });
107
+ continue;
108
+ }
109
+ const event = entry.event;
110
+ if (event.type === "run.started" && inputId) {
111
111
  const input = this.blocks.get(inputId);
112
112
  if (input)
113
113
  this.set({ ...input, runId: event.runId });
@@ -134,7 +134,13 @@ var UiProjection = class {
134
134
  status: recovery.status
135
135
  });
136
136
  }
137
- this.set({ id: `run:${event.runId}`, kind: "notice", runId: event.runId, text: "\u8FD0\u884C\u4E2D\u65AD\uFF1B\u8BF7\u6838\u5BF9\u5BBF\u4E3B\u6062\u590D\u8BC1\u636E\u3002\u4E0D\u4F1A\u81EA\u52A8\u91CD\u8DD1\u5DE5\u5177\u3002", status: "interrupted" });
137
+ this.set({
138
+ id: `run:${event.runId}`,
139
+ kind: "notice",
140
+ runId: event.runId,
141
+ text: "\u8FD0\u884C\u4E2D\u65AD\uFF1B\u8BF7\u6838\u5BF9\u5BBF\u4E3B\u6062\u590D\u8BC1\u636E\u3002\u4E0D\u4F1A\u81EA\u52A8\u91CD\u8DD1\u5DE5\u5177\u3002",
142
+ status: "interrupted"
143
+ });
138
144
  } else if (event.type === "tool.started" || event.type === "tool.completed" || event.type === "tool.failed" || event.type === "run.failed" || event.type === "run.cancelled" || event.type === "run.completed" || event.type === "run.yielded")
139
145
  this.run(event);
140
146
  }
@@ -169,7 +175,13 @@ var UiProjection = class {
169
175
  }
170
176
  steered(runId, step, messages) {
171
177
  for (const [index, message] of messages.entries())
172
- this.set({ id: `steering:${runId}:${step}:${index}`, kind: "user", runId, text: contentText(message.content), content: this.content(message.content) });
178
+ this.set({
179
+ id: `steering:${runId}:${step}:${index}`,
180
+ kind: "user",
181
+ runId,
182
+ text: contentText(message.content),
183
+ content: this.content(message.content)
184
+ });
173
185
  }
174
186
  permission(event, live) {
175
187
  if (event.type === "approval.requested") {
@@ -223,7 +235,9 @@ var UiProjection = class {
223
235
  id: event.requestId,
224
236
  status: cancelled ? "cancelled" : denied ? "denied" : "allowed",
225
237
  ...block.approval.scopeDescription === void 0 ? {} : { scopeDescription: block.approval.scopeDescription },
226
- ...!cancelled && !denied ? { scope: event.decision === "allow-session" ? "session" : event.decision === "allow-persistent" ? "persistent" : "once" } : {}
238
+ ...!cancelled && !denied ? {
239
+ scope: event.decision === "allow-session" ? "session" : event.decision === "allow-persistent" ? "persistent" : "once"
240
+ } : {}
227
241
  }
228
242
  });
229
243
  break;
@@ -232,14 +246,28 @@ var UiProjection = class {
232
246
  }
233
247
  presentation(event) {
234
248
  const id = `tool:${event.runId}:${event.toolCallId}`;
235
- this.set({ id, kind: "tool", runId: event.runId, toolCallId: event.toolCallId, text: "", ...this.blocks.get(id), presentation: { kind: event.kind, version: event.version, text: displayValue(event.data) } });
249
+ this.set({
250
+ id,
251
+ kind: "tool",
252
+ runId: event.runId,
253
+ toolCallId: event.toolCallId,
254
+ text: "",
255
+ ...this.blocks.get(id),
256
+ presentation: { kind: event.kind, version: event.version, text: displayValue(event.data) }
257
+ });
236
258
  }
237
259
  run(event) {
238
260
  if (event.type === "input.received")
239
261
  this.steered(event.runId, event.step, event.messages);
240
262
  if ("step" in event && event.type.startsWith("model.")) {
241
263
  const id = `assistant:${event.runId}:${event.step}`;
242
- const previous = this.blocks.get(id) ?? { id, kind: "assistant", runId: event.runId, text: "", status: "streaming" };
264
+ const previous = this.blocks.get(id) ?? {
265
+ id,
266
+ kind: "assistant",
267
+ runId: event.runId,
268
+ text: "",
269
+ status: "streaming"
270
+ };
243
271
  if (event.type === "model.text.delta")
244
272
  this.set({ ...previous, text: (previous.text + event.delta).slice(0, LIMIT) });
245
273
  else if (event.type === "model.reasoning.delta")
@@ -253,7 +281,7 @@ var UiProjection = class {
253
281
  const id = `tool:${event.runId}:${event.call.id}`, previous = this.blocks.get(id);
254
282
  let status = event.type === "tool.completed" ? "completed" : "running";
255
283
  if (event.type === "tool.failed")
256
- status = event.error.code === "PERMISSION_DENIED" ? "denied" : event.error.code === "TOOL_SKIPPED" ? "not-started" : event.error.code === "RUN_CANCELLED" ? previous?.approval?.status === "cancelled" ? "not-started" : "unknown" : "failed";
284
+ status = sessionToolFailureStatus(event.error, previous?.approval?.status === "cancelled");
257
285
  const text = event.type === "tool.completed" ? displayValue(event.output) : event.type === "tool.output.delta" ? ((previous?.text ?? "") + event.delta).slice(-LIMIT) : previous?.text ?? "";
258
286
  this.set({
259
287
  ...previous,
@@ -279,13 +307,14 @@ var UiProjection = class {
279
307
  ...event.type === "run.failed" ? { diagnostic: diagnostic(event.error) } : {},
280
308
  status: event.type === "run.failed" ? "failed" : "cancelled"
281
309
  });
282
- if (["run.completed", "run.failed", "run.cancelled", "run.yielded"].includes(event.type))
310
+ if (isSessionRunTerminalEvent(event))
283
311
  this.settle(event.runId);
284
312
  }
285
313
  };
286
314
 
287
315
  // packages/ui/client/dist/reading.js
288
316
  import { createHash } from "node:crypto";
317
+ import { readSessionTranscript as readSessionTranscript2, readRecordedModelRequests } from "@sortedyuan/may/session";
289
318
  var PAGE_SIZE = 50;
290
319
  var PAGE_CHARACTERS = 262144;
291
320
  function readPage(hostId, scope, items, request, matches, backwards = false) {
@@ -325,7 +354,7 @@ function historyPage(hostId, selectedId, blocks, request = {}, matches) {
325
354
  }
326
355
  __name(historyPage, "historyPage");
327
356
  function fieldText(block, field) {
328
- return field === "diagnostic" ? block.diagnostic?.message ?? "" : field === "presentation" ? block.presentation?.text ?? "" : block[field] ?? "";
357
+ return field === "request" ? "" : field === "diagnostic" ? block.diagnostic?.message ?? "" : field === "presentation" ? block.presentation?.text ?? "" : block[field] ?? "";
329
358
  }
330
359
  __name(fieldText, "fieldText");
331
360
  function display(value) {
@@ -338,54 +367,56 @@ function display(value) {
338
367
  __name(display, "display");
339
368
  function eventFields(event) {
340
369
  if (event.type === "approval.requested")
341
- return { id: `tool:${event.request.runId}:${event.request.toolCallId}`, fields: { input: display(event.request.input) } };
370
+ return {
371
+ id: `tool:${event.request.runId}:${event.request.toolCallId}`,
372
+ fields: { input: display(event.request.input) }
373
+ };
342
374
  if ("runId" in event && "call" in event)
343
- return { id: `tool:${event.runId}:${event.call.id}`, fields: {
344
- input: display(event.call.input),
345
- ...event.type === "tool.completed" ? { text: display(event.output) } : {},
346
- ...event.type === "tool.failed" ? { diagnostic: event.error.message } : {}
347
- } };
375
+ return {
376
+ id: `tool:${event.runId}:${event.call.id}`,
377
+ fields: {
378
+ input: display(event.call.input),
379
+ ...event.type === "tool.completed" ? { text: display(event.output) } : {},
380
+ ...event.type === "tool.failed" ? { diagnostic: event.error.message } : {}
381
+ }
382
+ };
348
383
  if (event.type === "tool.presentation")
349
384
  return { id: `tool:${event.runId}:${event.toolCallId}`, fields: { presentation: display(event.data) } };
350
385
  if (event.type === "assistant.completed")
351
- return { id: `assistant:${event.runId}:${event.step}`, fields: {
352
- text: event.message.content.filter((part) => part.type === "text").map((part) => part.text).join(""),
353
- reasoning: event.message.content.filter((part) => part.type === "reasoning").map((part) => part.text).join("")
354
- } };
355
- if (event.type === "input.submitted")
356
- return { id: `input:${event.seq}`, fields: { text: event.message.content.filter((part) => part.type === "text").map((part) => part.text).join("") } };
386
+ return {
387
+ id: `assistant:${event.runId}:${event.step}`,
388
+ fields: {
389
+ text: event.message.content.filter((part) => part.type === "text").map((part) => part.text).join(""),
390
+ reasoning: event.message.content.filter((part) => part.type === "reasoning").map((part) => part.text).join("")
391
+ }
392
+ };
357
393
  if (event.type === "run.failed")
358
394
  return { id: `run:${event.runId}`, fields: { diagnostic: event.error.message } };
359
395
  return void 0;
360
396
  }
361
397
  __name(eventFields, "eventFields");
362
398
  function* historyFields(events) {
363
- const steering = /* @__PURE__ */ new Map();
364
- for (const event of events) {
365
- if (event.type === "input.steering.queued")
366
- steering.set(event.input.inputId, event.input.message.content.filter((part) => part.type === "text").map((part) => part.text).join(""));
367
- else if (event.type === "input.steering.delivered") {
368
- for (const [index, inputId] of event.inputIds.entries()) {
369
- const text = steering.get(inputId);
370
- if (text === void 0)
371
- throw new Error(`Missing steering input in UI history: ${inputId}`);
372
- steering.delete(inputId);
373
- yield { id: `steering:${event.runId}:${event.step}:${index}`, fields: { text } };
374
- }
399
+ for (const entry of readSessionTranscript2(events)) {
400
+ if (entry.type === "user-message") {
401
+ yield {
402
+ id: entry.id,
403
+ fields: {
404
+ text: entry.message.content.filter((part) => part.type === "text").map((part) => part.text).join("")
405
+ }
406
+ };
375
407
  } else {
376
- if (event.type === "input.submitted" && event.inputId !== void 0)
377
- steering.delete(event.inputId);
378
- if (event.type === "input.steering.finished" && event.status === "cancelled")
379
- for (const inputId of event.inputIds)
380
- steering.delete(inputId);
381
- const entry = eventFields(event);
382
- if (entry)
383
- yield entry;
408
+ const fields = eventFields(entry.event);
409
+ if (fields)
410
+ yield fields;
384
411
  }
385
412
  }
386
413
  }
387
414
  __name(historyFields, "historyFields");
388
415
  function recordedField(events, block, field) {
416
+ if (field === "request") {
417
+ const requests = readRecordedModelRequests(events).filter((request) => block.id === `assistant:${request.runId}:${request.step}` || block.id === `run:${request.runId}`);
418
+ return requests.length > 0 ? JSON.stringify(requests, null, 2) : "\u6B64\u5904\u6CA1\u6709\u5DF2\u4FDD\u5B58\u7684\u6A21\u578B\u8BF7\u6C42\u3002";
419
+ }
389
420
  let text = fieldText(block, field);
390
421
  for (const entry of historyFields(events))
391
422
  if (entry.id === block.id && entry.fields[field] !== void 0)
@@ -413,7 +444,14 @@ function fieldPage(hostId, selectedId, request, text) {
413
444
  let end = Math.min(text.length, offset + 32768);
414
445
  if (end < text.length && /[\uD800-\uDBFF]/u.test(text[end - 1]))
415
446
  end--;
416
- return { hostId, text: text.slice(offset, end), offset, nextOffset: end < text.length ? end : null, total: text.length, version };
447
+ return {
448
+ hostId,
449
+ text: text.slice(offset, end),
450
+ offset,
451
+ nextOffset: end < text.length ? end : null,
452
+ total: text.length,
453
+ version
454
+ };
417
455
  }
418
456
  __name(fieldPage, "fieldPage");
419
457
 
@@ -430,7 +468,10 @@ var ApplicationUiHost = class {
430
468
  listeners = /* @__PURE__ */ new Set();
431
469
  iterator;
432
470
  relay;
433
- mutation = Promise.resolve();
471
+ mutations = new AsyncStateSerializer();
472
+ pendingCommands = /* @__PURE__ */ new Set();
473
+ closed = false;
474
+ closing;
434
475
  fault;
435
476
  constructor(app, options) {
436
477
  this.app = app;
@@ -442,6 +483,7 @@ var ApplicationUiHost = class {
442
483
  });
443
484
  }
444
485
  subscribe(listener) {
486
+ this.assertOpen();
445
487
  this.listeners.add(listener);
446
488
  return () => this.listeners.delete(listener);
447
489
  }
@@ -470,12 +512,31 @@ var ApplicationUiHost = class {
470
512
  return this.queuedSnapshot();
471
513
  }
472
514
  queuedSnapshot(selectedId, all = false) {
473
- const work = this.mutation.then(() => this.buildSnapshot(selectedId, 0, all));
474
- this.mutation = work.catch(() => {
475
- });
476
- return work;
515
+ this.assertOpen();
516
+ return this.mutations.idle().then(() => this.buildSnapshot(selectedId, 0, all));
517
+ }
518
+ commandNames(viewingActive = true) {
519
+ if (this.closed || this.fault)
520
+ return [];
521
+ const running = this.app.isRunning, commands = [];
522
+ if (!running)
523
+ commands.push("session.new", "session.activate", "session.delete");
524
+ if (viewingActive) {
525
+ commands.push(...running ? ["run.cancel", ...this.projection.interactions.size ? ["approval.resolve"] : []] : ["message.submit", "session.rename", "context.compact", ...this.options.commands ?? []]);
526
+ commands.push(...this.options.concurrentCommands ?? []);
527
+ if (this.options.permissionRules !== void 0)
528
+ commands.push("permission.rules.list", "permission.rules.revoke");
529
+ if (this.options.permissionRules?.create !== void 0)
530
+ commands.push("permission.rules.create");
531
+ }
532
+ return this.options.available ? commands.filter((name) => this.options.available(name)) : commands;
533
+ }
534
+ assertOpen() {
535
+ if (this.closed)
536
+ throw new UiError(503, "\u5BBF\u4E3B\u6B63\u5728\u5173\u95ED\u3002");
477
537
  }
478
538
  async buildSnapshot(selectedId, attempt = 0, all = false) {
539
+ this.assertOpen();
479
540
  const revision = this.revision, activeId = this.app.sessionId, running = this.app.isRunning;
480
541
  const viewingId = selectedId ?? activeId, viewingActive = viewingId === activeId;
481
542
  const sessions = await this.app.listSessions();
@@ -485,7 +546,13 @@ var ApplicationUiHost = class {
485
546
  throw new UiError(409, "\u5F53\u524D\u5BBF\u4E3B\u4E0D\u652F\u6301\u53EA\u8BFB\u5386\u53F2\u6D4F\u89C8\u3002");
486
547
  const history = viewingActive ? await this.app.history() : await this.app.readSessionHistory(viewingId);
487
548
  const visibleSessions = sessions.filter((session, index) => index < 500 || session.id === viewingId || session.id === activeId);
488
- const resources = visibleSessions.map((s) => ({ id: s.id, kind: "session", title: s.title ?? s.preview?.slice(0, 72) ?? "\u65B0\u4F1A\u8BDD", status: s.id === activeId && running ? "running" : "idle", updatedAt: s.lastUsedAt }));
549
+ const resources = visibleSessions.map((s) => ({
550
+ id: s.id,
551
+ kind: "session",
552
+ title: s.title ?? s.preview?.slice(0, 72) ?? "\u65B0\u4F1A\u8BDD",
553
+ status: s.id === activeId && running ? "running" : "idle",
554
+ updatedAt: s.lastUsedAt
555
+ }));
489
556
  const resourcesVersion = createHash2("sha256").update(JSON.stringify([...sessions].sort((a, b) => b.createdAt - a.createdAt || a.id.localeCompare(b.id)).map((s) => [s.id, s.createdAt, s.title ?? s.preview?.slice(0, 72) ?? "\u65B0\u4F1A\u8BDD"]))).digest("hex");
490
557
  const projected = new UiProjection(Infinity);
491
558
  projected.history(history);
@@ -500,24 +567,7 @@ var ApplicationUiHost = class {
500
567
  ...interaction,
501
568
  choices: this.options.permissionActor === void 0 ? interaction.choices.filter((choice) => choice.value !== "allow-persistent") : interaction.choices
502
569
  })) : [];
503
- const commands = [];
504
- if (!running)
505
- commands.push("session.new", "session.activate", "session.delete");
506
- if (viewingActive)
507
- commands.push(...running ? ["run.cancel", ...interactions.length ? ["approval.resolve"] : []] : ["message.submit", "session.rename", "context.compact", ...this.options.commands ?? []]);
508
- if (viewingActive)
509
- commands.push(...this.options.concurrentCommands ?? []);
510
- if (viewingActive && this.options.permissionRules !== void 0)
511
- commands.push("permission.rules.list", "permission.rules.revoke");
512
- if (viewingActive && this.options.permissionRules?.create !== void 0)
513
- commands.push("permission.rules.create");
514
- if (this.options.available) {
515
- for (let index = commands.length - 1; index >= 0; index--)
516
- if (!this.options.available(commands[index]))
517
- commands.splice(index, 1);
518
- }
519
- if (this.fault)
520
- commands.length = 0;
570
+ const commands = this.commandNames(viewingActive);
521
571
  const panels = viewingActive ? await this.options.panels?.() ?? [] : [];
522
572
  const choices = viewingActive ? await this.options.choices?.() ?? [] : [];
523
573
  const workspace = await this.options.workspace?.();
@@ -528,6 +578,7 @@ var ApplicationUiHost = class {
528
578
  });
529
579
  const checkpoints = await this.options.checkpoints?.(viewingId);
530
580
  const worktrees = await this.options.worktrees?.();
581
+ this.assertOpen();
531
582
  if (activeId !== this.app.sessionId || running !== this.app.isRunning) {
532
583
  if (attempt < 2)
533
584
  return this.buildSnapshot(selectedId, attempt + 1, all);
@@ -550,13 +601,32 @@ var ApplicationUiHost = class {
550
601
  activeId,
551
602
  blocks: all ? [...projected.blocks.values()] : page.items,
552
603
  historyPage: { nextCursor: page.nextCursor, total: page.total },
553
- reads: { resources: true, history: Boolean(this.app.readSessionHistory), fields: Boolean(this.app.readSessionHistory) },
604
+ reads: {
605
+ resources: true,
606
+ history: Boolean(this.app.readSessionHistory),
607
+ fields: Boolean(this.app.readSessionHistory)
608
+ },
554
609
  interactions,
555
610
  commands,
556
611
  panels: [
557
- { id: "workspace", title: "\u5DE5\u4F5C\u533A", fields: [{ label: "\u76EE\u5F55", value: this.app.workspace }, { label: "\u5F53\u524D\u4F1A\u8BDD", value: viewingId }, { label: "\u6267\u884C\u72B6\u6001", value: running ? "\u8FD0\u884C\u4E2D" : "\u7A7A\u95F2" }] },
612
+ {
613
+ id: "workspace",
614
+ title: "\u5DE5\u4F5C\u533A",
615
+ fields: [
616
+ { label: "\u76EE\u5F55", value: this.app.workspace },
617
+ { label: "\u5F53\u524D\u4F1A\u8BDD", value: viewingId },
618
+ { label: "\u6267\u884C\u72B6\u6001", value: running ? "\u8FD0\u884C\u4E2D" : "\u7A7A\u95F2" }
619
+ ]
620
+ },
558
621
  ...panels,
559
- ...viewingActive && this.options.permissionRules !== void 0 ? [{ id: "permission-rules", title: "\u6301\u4E45\u6743\u9650\u89C4\u5219", fields: [], actions: [{ label: "\u67E5\u770B\u548C\u7BA1\u7406\u89C4\u5219", command: "permission.rules.list", args: {} }] }] : []
622
+ ...viewingActive && this.options.permissionRules !== void 0 ? [
623
+ {
624
+ id: "permission-rules",
625
+ title: "\u6301\u4E45\u6743\u9650\u89C4\u5219",
626
+ fields: [],
627
+ actions: [{ label: "\u67E5\u770B\u548C\u7BA1\u7406\u89C4\u5219", command: "permission.rules.list", args: {} }]
628
+ }
629
+ ] : []
560
630
  ],
561
631
  choices,
562
632
  ...viewingActive && this.options.controls ? { controls: this.options.controls() } : {},
@@ -564,11 +634,19 @@ var ApplicationUiHost = class {
564
634
  };
565
635
  }
566
636
  async resources(request) {
637
+ this.assertOpen();
567
638
  const sessions = [...await this.app.listSessions()].sort((a, b) => b.createdAt - a.createdAt || a.id.localeCompare(b.id));
568
- const items = sessions.map((s) => ({ id: s.id, kind: "session", title: s.title ?? s.preview?.slice(0, 72) ?? "\u65B0\u4F1A\u8BDD", status: s.id === this.app.sessionId && this.app.isRunning ? "running" : "idle", updatedAt: s.lastUsedAt }));
639
+ const items = sessions.map((s) => ({
640
+ id: s.id,
641
+ kind: "session",
642
+ title: s.title ?? s.preview?.slice(0, 72) ?? "\u65B0\u4F1A\u8BDD",
643
+ status: s.id === this.app.sessionId && this.app.isRunning ? "running" : "idle",
644
+ updatedAt: s.lastUsedAt
645
+ }));
569
646
  return readPage(this.hostId, "resources", items, request, (item, query) => item.title.toLocaleLowerCase().includes(query));
570
647
  }
571
648
  async media(selectedId, id) {
649
+ this.assertOpen();
572
650
  if (!(await this.app.listSessions()).some((session) => session.id === selectedId))
573
651
  throw new UiError(404, "\u4F1A\u8BDD\u4E0D\u5B58\u5728\u6216\u4E0D\u5C5E\u4E8E\u5F53\u524D\u5DE5\u4F5C\u533A\u3002");
574
652
  const events = selectedId === this.app.sessionId ? await this.app.history() : await this.app.readSessionHistory?.(selectedId);
@@ -596,14 +674,16 @@ var ApplicationUiHost = class {
596
674
  return fieldPage(this.hostId, selectedId, request, recordedField(events, block, request.field));
597
675
  }
598
676
  execute(command) {
599
- if (this.options.concurrentCommands?.includes(command.name))
600
- return this.apply(command);
601
- const work = this.mutation.then(() => this.apply(command));
602
- this.mutation = work.catch(() => {
603
- });
677
+ if (this.closed)
678
+ return Promise.reject(new UiError(503, "\u5BBF\u4E3B\u6B63\u5728\u5173\u95ED\u3002"));
679
+ const concurrent = this.options.concurrentCommands?.includes(command.name) === true;
680
+ const work = concurrent ? Promise.resolve().then(() => this.apply(command)) : this.mutations.run(() => this.apply(command));
681
+ this.pendingCommands.add(work);
682
+ void work.then(() => this.pendingCommands.delete(work), () => this.pendingCommands.delete(work));
604
683
  return work;
605
684
  }
606
685
  async complete(selectedId, text) {
686
+ this.assertOpen();
607
687
  if (selectedId !== this.app.sessionId || !this.options.complete)
608
688
  throw new UiError(409, "\u5F53\u524D\u4F1A\u8BDD\u4E0D\u652F\u6301\u547D\u4EE4\u8865\u5168\u3002");
609
689
  return { hostId: this.hostId, items: await this.options.complete(text) };
@@ -613,20 +693,22 @@ var ApplicationUiHost = class {
613
693
  if (!command.targetId)
614
694
  throw new UiError(409, "\u8BF7\u6307\u5B9A\u4F1A\u8BDD\u3002");
615
695
  const assertCurrent = /* @__PURE__ */ __name(() => {
696
+ this.assertOpen();
616
697
  if (command.hostId !== this.hostId || (transition ? command.expectedActiveId !== this.app.sessionId : command.targetId !== this.app.sessionId))
617
698
  throw new UiError(409, "\u5F53\u524D\u4F1A\u8BDD\u5DF2\u6539\u53D8\uFF0C\u8BF7\u68C0\u67E5\u5F53\u524D\u72B6\u6001\u540E\u91CD\u8BD5\u3002");
618
699
  }, "assertCurrent");
700
+ const assertAllowed = /* @__PURE__ */ __name(() => {
701
+ assertCurrent();
702
+ if (!this.commandNames().includes(command.name))
703
+ throw new UiError(409, "\u5F53\u524D\u72B6\u6001\u4E0D\u5141\u8BB8\u6B64\u64CD\u4F5C\u3002");
704
+ }, "assertAllowed");
619
705
  assertCurrent();
620
706
  if (this.options.interactionCommands?.includes(command.name)) {
621
707
  if (!this.options.available?.(command.name) || !this.options.execute)
622
708
  throw new UiError(409, "\u4EA4\u4E92\u5DF2\u4E0D\u53EF\u7528\u3002");
623
709
  return this.options.execute(command);
624
710
  }
625
- if (!(await this.buildSnapshot()).commands.includes(command.name))
626
- throw new UiError(409, "\u5F53\u524D\u72B6\u6001\u4E0D\u5141\u8BB8\u6B64\u64CD\u4F5C\u3002");
627
- if (this.options.available && !this.options.available(command.name))
628
- throw new UiError(409, "\u5F53\u524D\u72B6\u6001\u4E0D\u5141\u8BB8\u6B64\u64CD\u4F5C\u3002");
629
- assertCurrent();
711
+ assertAllowed();
630
712
  switch (command.name) {
631
713
  case "message.submit": {
632
714
  commandArgs(command, ["text"]);
@@ -635,6 +717,7 @@ var ApplicationUiHost = class {
635
717
  const receipt = await this.options.submit?.(command.args.text);
636
718
  if (receipt)
637
719
  return receipt;
720
+ assertAllowed();
638
721
  const run = await this.app.submit({ input: command.args.text, inputId: `web:${command.requestId}` });
639
722
  void run.result.catch(() => {
640
723
  }).finally(() => this.changed());
@@ -662,19 +745,33 @@ var ApplicationUiHost = class {
662
745
  case "permission.rules.list": {
663
746
  commandArgs(command, []);
664
747
  const rules = await this.options.permissionRules.list();
665
- return { selectedId: this.app.sessionId, output: {
666
- title: "\u6301\u4E45\u6743\u9650\u89C4\u5219",
667
- text: rules.length === 0 ? "\u5F53\u524D\u6CA1\u6709\u6301\u4E45\u6743\u9650\u89C4\u5219\u3002" : rules.map((rule) => `${rule.decision === "allow" ? "\u5141\u8BB8" : "\u7981\u6B62"} \xB7 ${rule.toolName}
748
+ assertAllowed();
749
+ return {
750
+ selectedId: this.app.sessionId,
751
+ output: {
752
+ title: "\u6301\u4E45\u6743\u9650\u89C4\u5219",
753
+ text: rules.length === 0 ? "\u5F53\u524D\u6CA1\u6709\u6301\u4E45\u6743\u9650\u89C4\u5219\u3002" : rules.map((rule) => `${rule.decision === "allow" ? "\u5141\u8BB8" : "\u7981\u6B62"} \xB7 ${rule.toolName}
668
754
  ${rule.description}
669
755
  \u8303\u56F4\uFF1A${rule.scopeId}
670
756
  \u521B\u5EFA\u8005\uFF1A${rule.createdBy}
671
757
  \u6709\u6548\u671F\uFF1A${rule.expiresAt === void 0 ? "\u6301\u7EED\u6709\u6548" : new Date(rule.expiresAt).toISOString()}
672
758
  \u89C4\u5219 ID\uFF1A${rule.id}`).join("\n\n"),
673
- actions: rules.flatMap((rule) => [
674
- { label: `\u64A4\u9500 ${rule.description}`, command: "permission.rules.revoke", args: { id: rule.id }, confirm: `\u786E\u8BA4\u64A4\u9500\u89C4\u5219 ${rule.id}\uFF1F\u540E\u7EED\u5DE5\u5177\u8C03\u7528\u5C06\u91CD\u65B0\u68C0\u67E5\u6743\u9650\u3002` },
675
- ...this.options.permissionRules.create === void 0 ? [] : ["allow", "deny"].map((decision) => ({ label: `\u6309\u6B64\u8303\u56F4\u521B\u5EFA${decision === "allow" ? "\u5141\u8BB8" : "\u7981\u6B62"}\u89C4\u5219`, command: "permission.rules.create", args: { sourceId: rule.id, decision }, confirm: `\u786E\u8BA4${decision === "allow" ? "\u6301\u7EED\u5141\u8BB8" : "\u6301\u7EED\u7981\u6B62"}\uFF1A${rule.description}\uFF1F\u8303\u56F4\uFF1A${rule.scopeId}\u3002\u7981\u6B62\u89C4\u5219\u4F18\u5148\u4E8E\u5141\u8BB8\u89C4\u5219\u3002` }))
676
- ])
677
- } };
759
+ actions: rules.flatMap((rule) => [
760
+ {
761
+ label: `\u64A4\u9500 ${rule.description}`,
762
+ command: "permission.rules.revoke",
763
+ args: { id: rule.id },
764
+ confirm: `\u786E\u8BA4\u64A4\u9500\u89C4\u5219 ${rule.id}\uFF1F\u540E\u7EED\u5DE5\u5177\u8C03\u7528\u5C06\u91CD\u65B0\u68C0\u67E5\u6743\u9650\u3002`
765
+ },
766
+ ...this.options.permissionRules.create === void 0 ? [] : ["allow", "deny"].map((decision) => ({
767
+ label: `\u6309\u6B64\u8303\u56F4\u521B\u5EFA${decision === "allow" ? "\u5141\u8BB8" : "\u7981\u6B62"}\u89C4\u5219`,
768
+ command: "permission.rules.create",
769
+ args: { sourceId: rule.id, decision },
770
+ confirm: `\u786E\u8BA4${decision === "allow" ? "\u6301\u7EED\u5141\u8BB8" : "\u6301\u7EED\u7981\u6B62"}\uFF1A${rule.description}\uFF1F\u8303\u56F4\uFF1A${rule.scopeId}\u3002\u7981\u6B62\u89C4\u5219\u4F18\u5148\u4E8E\u5141\u8BB8\u89C4\u5219\u3002`
771
+ }))
772
+ ])
773
+ }
774
+ };
678
775
  }
679
776
  case "permission.rules.create": {
680
777
  commandArgs(command, ["sourceId", "decision"]);
@@ -683,6 +780,7 @@ ${rule.description}
683
780
  throw new UiError(400, "\u65E0\u6548\u7684\u89C4\u5219\u51B3\u5B9A\u3002");
684
781
  if (!(await this.options.permissionRules.list()).some((rule) => rule.id === command.args.sourceId))
685
782
  throw new UiError(404, "\u89C4\u5219\u4E0D\u5C5E\u4E8E\u5F53\u524D\u6743\u9650\u8303\u56F4\u3002");
783
+ assertAllowed();
686
784
  await this.options.permissionRules.create(command.args.sourceId, decision);
687
785
  break;
688
786
  }
@@ -690,6 +788,7 @@ ${rule.description}
690
788
  commandArgs(command, ["id"]);
691
789
  if (!(await this.options.permissionRules.list()).some((rule) => rule.id === command.args.id))
692
790
  throw new UiError(404, "\u89C4\u5219\u4E0D\u5C5E\u4E8E\u5F53\u524D\u6743\u9650\u8303\u56F4\u3002");
791
+ assertAllowed();
693
792
  if (!await this.options.permissionRules.revoke(command.args.id))
694
793
  throw new UiError(404, "\u89C4\u5219\u5DF2\u7ECF\u64A4\u9500\u3002");
695
794
  break;
@@ -703,7 +802,7 @@ ${rule.description}
703
802
  commandArgs(command, []);
704
803
  if (!(await this.app.listSessions()).some((session) => session.id === command.targetId))
705
804
  throw new UiError(404, "\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u5F53\u524D\u5DE5\u4F5C\u533A\u3002");
706
- assertCurrent();
805
+ assertAllowed();
707
806
  await this.app.resumeSession(command.targetId);
708
807
  this.projection = new UiProjection();
709
808
  break;
@@ -715,7 +814,7 @@ ${rule.description}
715
814
  const sessions = await this.app.listSessions();
716
815
  if (!sessions.some((session) => session.id === command.targetId))
717
816
  throw new UiError(404, "\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u5F53\u524D\u5DE5\u4F5C\u533A\u3002");
718
- assertCurrent();
817
+ assertAllowed();
719
818
  if (!await this.app.deleteSession(command.targetId))
720
819
  throw new UiError(404, "\u4F1A\u8BDD\u5DF2\u4E0D\u5B58\u5728\u3002");
721
820
  break;
@@ -739,14 +838,25 @@ ${rule.description}
739
838
  this.changed();
740
839
  return { selectedId: this.app.sessionId };
741
840
  }
742
- async close() {
743
- await this.mutation.catch(() => {
744
- });
745
- if (this.options.closeApplication !== false)
746
- await this.app.close();
747
- await this.iterator.return?.();
748
- await this.relay;
749
- this.listeners.clear();
841
+ close() {
842
+ if (this.closing)
843
+ return this.closing;
844
+ this.closed = true;
845
+ return this.closing = this.closeOnce();
846
+ }
847
+ async closeOnce() {
848
+ const [applicationClosing] = await Promise.allSettled([
849
+ this.options.closeApplication === false ? Promise.resolve() : Promise.resolve().then(() => this.app.close()),
850
+ ...this.pendingCommands
851
+ ]);
852
+ try {
853
+ await this.iterator.return?.();
854
+ await this.relay;
855
+ } finally {
856
+ this.listeners.clear();
857
+ }
858
+ if (applicationClosing?.status === "rejected")
859
+ throw applicationClosing.reason;
750
860
  }
751
861
  };
752
862
 
@@ -759,7 +869,10 @@ function createTelemetryPanel(data) {
759
869
  id: "telemetry",
760
870
  title: "\u8FD0\u884C\u8BCA\u65AD",
761
871
  fields: [
762
- { label: "\u8BB0\u5F55\u8303\u56F4", value: `${data.total} \u6761\u672C\u5730\u8BB0\u5F55\uFF0C${data.evictedSpans} \u6761\u5DF2\u8D85\u8FC7\u4FDD\u7559\u8303\u56F4${data.hasMore ? "\uFF0C\u8FD8\u6709\u540E\u7EED\u8BB0\u5F55" : ""}\u3002` },
872
+ {
873
+ label: "\u8BB0\u5F55\u8303\u56F4",
874
+ value: `${data.total} \u6761\u672C\u5730\u8BB0\u5F55\uFF0C${data.evictedSpans} \u6761\u5DF2\u8D85\u8FC7\u4FDD\u7559\u8303\u56F4${data.hasMore ? "\uFF0C\u8FD8\u6709\u540E\u7EED\u8BB0\u5F55" : ""}\u3002`
875
+ },
763
876
  ...spans.slice(0, 40).map((span) => ({
764
877
  label: `${new Date(span.startTime).toISOString()} \xB7 ${span.name}`,
765
878
  value: `${span.ended ? span.status ?? "\u672A\u77E5\u7ED3\u679C" : "\u6B63\u5728\u6267\u884C"} \xB7 ${span.durationMs === void 0 ? "\u8017\u65F6\u5C1A\u672A\u786E\u5B9A" : `${span.durationMs} ms`} \xB7 span ${span.context.spanId}${span.parentSpanId === void 0 ? "" : ` \xB7 parent ${span.parentSpanId}`} \xB7 ${span.sampled ? "\u5DF2\u9009\u62E9\u8FDC\u7A0B\u5BFC\u51FA" : "\u672C\u5730\u8BB0\u5F55"}`
@@ -769,6 +882,9 @@ function createTelemetryPanel(data) {
769
882
  }
770
883
  __name(createTelemetryPanel, "createTelemetryPanel");
771
884
 
885
+ // apps/maybecode/src/web-commands.ts
886
+ import { GitCheckpointError, GitWorkspaceConflictError } from "@sortedyuan/may/application/git-workspace";
887
+
772
888
  // apps/maybecode/src/mcp-commands.ts
773
889
  var MCP_COMMAND_USAGE = "/mcp [apps | catalog [server] | refresh [server] | reconnect server | read server uri | attach server uri [question] | template server uri-template {arguments} | prompt server name {arguments} | use-prompt server name {arguments} | complete server {params} | watch server uri | unwatch server uri | tasks [server] | task-get server id | task-wait server id | task-update server id | task-retry-input server id | task-cancel server id | task-forget server id | task-attach server id [question]]";
774
890
  async function executeMcpCommand(input, controller) {
@@ -776,18 +892,37 @@ async function executeMcpCommand(input, controller) {
776
892
  const [, action, serverId, tail] = match;
777
893
  const display2 = /* @__PURE__ */ __name((text) => ({ type: "mcp.display", text: text.slice(0, 16e3) }), "display");
778
894
  const usage2 = /* @__PURE__ */ __name(() => ({ type: "usage", usage: MCP_COMMAND_USAGE }), "usage");
779
- if (action === "apps") return display2("MCP Apps HTML is not supported in this terminal. Text tool results remain available; use an explicitly configured isolated graphical Host. No HTML was fetched or executed.");
895
+ if (action === "apps")
896
+ return display2(
897
+ "MCP Apps HTML is not supported in this terminal. Text tool results remain available; use an explicitly configured isolated graphical Host. No HTML was fetched or executed."
898
+ );
780
899
  if (action === void 0) return { type: "mcp.status", servers: await controller.getMcpStatus() };
781
900
  if (action === "tasks" && tail === void 0 && controller.listMcpTasks !== void 0) {
782
- const records = (await controller.listMcpTasks()).filter((record) => serverId === void 0 || record.binding.serverId === serverId);
783
- return display2(JSON.stringify(records.map(({ id, binding, status, cancellation }) => ({ id, server: binding.serverId, tool: binding.toolName, status, cancellation })), null, 2));
901
+ const records = (await controller.listMcpTasks()).filter(
902
+ (record) => serverId === void 0 || record.binding.serverId === serverId
903
+ );
904
+ return display2(
905
+ JSON.stringify(
906
+ records.map(({ id, binding, status, cancellation }) => ({
907
+ id,
908
+ server: binding.serverId,
909
+ tool: binding.toolName,
910
+ status,
911
+ cancellation
912
+ })),
913
+ null,
914
+ 2
915
+ )
916
+ );
784
917
  }
785
918
  if (action === "catalog" && tail === void 0 && controller.getMcpCatalog !== void 0) {
786
919
  const catalogs = controller.getMcpCatalog().filter((catalog) => serverId === void 0 || catalog.serverId === serverId);
787
920
  return display2(JSON.stringify(catalogs, null, 2));
788
921
  }
789
- if (action === "refresh" && tail === void 0 && controller.refreshMcp !== void 0) await controller.refreshMcp(serverId);
790
- else if (action === "reconnect" && serverId !== void 0 && tail === void 0 && controller.reconnectMcp !== void 0) await controller.reconnectMcp(serverId);
922
+ if (action === "refresh" && tail === void 0 && controller.refreshMcp !== void 0)
923
+ await controller.refreshMcp(serverId);
924
+ else if (action === "reconnect" && serverId !== void 0 && tail === void 0 && controller.reconnectMcp !== void 0)
925
+ await controller.reconnectMcp(serverId);
791
926
  else {
792
927
  if (serverId === void 0 || tail === void 0) return usage2();
793
928
  if (action === "complete" && controller.completeMcp !== void 0) {
@@ -796,15 +931,28 @@ async function executeMcpCommand(input, controller) {
796
931
  const target = /^(\S+)(?:\s+([\s\S]*))?$/u.exec(tail);
797
932
  const name = target[1];
798
933
  const rest = target[2];
799
- if (action === "task-attach" && controller.submitMcpTask !== void 0) return { type: "mcp.run-started", run: await controller.submitMcpTask(serverId, name, rest) };
934
+ if (action === "task-attach" && controller.submitMcpTask !== void 0)
935
+ return { type: "mcp.run-started", run: await controller.submitMcpTask(serverId, name, rest) };
800
936
  if (rest === void 0) {
801
- if (action === "task-get" && controller.getMcpTask !== void 0) return display2(JSON.stringify((await controller.getMcpTask(serverId, name)).state, null, 2));
802
- if (action === "task-wait" && controller.waitMcpTask !== void 0) return display2(JSON.stringify((await controller.waitMcpTask(serverId, name)).state, null, 2));
803
- if (action === "task-update" && controller.updateMcpTask !== void 0) return display2(JSON.stringify((await controller.updateMcpTask(serverId, name)).state, null, 2));
804
- if (action === "task-retry-input" && controller.updateMcpTask !== void 0) return display2(JSON.stringify((await controller.updateMcpTask(serverId, name, { retryAbandonedInputs: true })).state, null, 2));
937
+ if (action === "task-get" && controller.getMcpTask !== void 0)
938
+ return display2(JSON.stringify((await controller.getMcpTask(serverId, name)).state, null, 2));
939
+ if (action === "task-wait" && controller.waitMcpTask !== void 0)
940
+ return display2(JSON.stringify((await controller.waitMcpTask(serverId, name)).state, null, 2));
941
+ if (action === "task-update" && controller.updateMcpTask !== void 0)
942
+ return display2(JSON.stringify((await controller.updateMcpTask(serverId, name)).state, null, 2));
943
+ if (action === "task-retry-input" && controller.updateMcpTask !== void 0)
944
+ return display2(
945
+ JSON.stringify(
946
+ (await controller.updateMcpTask(serverId, name, { retryAbandonedInputs: true })).state,
947
+ null,
948
+ 2
949
+ )
950
+ );
805
951
  if (action === "task-cancel" && controller.cancelMcpTask !== void 0) {
806
952
  const record = await controller.cancelMcpTask(serverId, name);
807
- return display2(`Cancellation ${record.cancellation}; last observed status: ${record.status}. Acknowledgement does not prove the remote work stopped.`);
953
+ return display2(
954
+ `Cancellation ${record.cancellation}; last observed status: ${record.status}. Acknowledgement does not prove the remote work stopped.`
955
+ );
808
956
  }
809
957
  if (action === "task-forget" && controller.forgetMcpTask !== void 0) {
810
958
  await controller.forgetMcpTask(serverId, name);
@@ -815,16 +963,29 @@ async function executeMcpCommand(input, controller) {
815
963
  return display2(previewMcpMessage(mcpResourceToUserMessage(await controller.readMcpResource(serverId, name))));
816
964
  }
817
965
  if (action === "template" && rest !== void 0 && controller.readMcpResourceTemplate !== void 0) {
818
- return display2(previewMcpMessage(mcpResourceToUserMessage(await controller.readMcpResourceTemplate(serverId, name, JSON.parse(rest)))));
966
+ return display2(
967
+ previewMcpMessage(
968
+ mcpResourceToUserMessage(await controller.readMcpResourceTemplate(serverId, name, JSON.parse(rest)))
969
+ )
970
+ );
819
971
  }
820
972
  if (action === "attach" && controller.submitMcpResource !== void 0) {
821
973
  return { type: "mcp.run-started", run: await controller.submitMcpResource(serverId, name, rest) };
822
974
  }
823
975
  if (action === "prompt" && controller.getMcpPrompt !== void 0) {
824
- return display2(previewMcpMessage(mcpPromptToUserMessage(await controller.getMcpPrompt(serverId, name, rest === void 0 ? {} : JSON.parse(rest)))));
976
+ return display2(
977
+ previewMcpMessage(
978
+ mcpPromptToUserMessage(
979
+ await controller.getMcpPrompt(serverId, name, rest === void 0 ? {} : JSON.parse(rest))
980
+ )
981
+ )
982
+ );
825
983
  }
826
984
  if (action === "use-prompt" && controller.submitMcpPrompt !== void 0) {
827
- return { type: "mcp.run-started", run: await controller.submitMcpPrompt(serverId, name, rest === void 0 ? {} : JSON.parse(rest)) };
985
+ return {
986
+ type: "mcp.run-started",
987
+ run: await controller.submitMcpPrompt(serverId, name, rest === void 0 ? {} : JSON.parse(rest))
988
+ };
828
989
  }
829
990
  if (action === "watch" && rest === void 0 && controller.watchMcpResource !== void 0) {
830
991
  await controller.watchMcpResource(serverId, name);
@@ -852,7 +1013,8 @@ function parseGoalStart(arguments_) {
852
1013
  if (!(option in fields)) throw new Error(`Unknown goal option: ${option}`);
853
1014
  const field = fields[option];
854
1015
  const text = arguments_[index++];
855
- if (text === void 0 || !/^\d+$/u.test(text) || !Number.isSafeInteger(Number(text)) || Number(text) <= 0) throw new Error(`${option} requires a positive safe integer`);
1016
+ if (text === void 0 || !/^\d+$/u.test(text) || !Number.isSafeInteger(Number(text)) || Number(text) <= 0)
1017
+ throw new Error(`${option} requires a positive safe integer`);
856
1018
  if (budget[field] !== void 0) throw new Error(`Duplicate goal option: ${option}`);
857
1019
  budget[field] = Number(text);
858
1020
  }
@@ -862,7 +1024,6 @@ function parseGoalStart(arguments_) {
862
1024
  }
863
1025
  __name(parseGoalStart, "parseGoalStart");
864
1026
  async function executeGoalCommand(arguments_, app) {
865
- if (!app.getGoal) throw new Error("This controller does not support goals");
866
1027
  const [verb = "status", ...rest] = arguments_;
867
1028
  if (verb === "start") {
868
1029
  if (!app.startGoal) throw new Error("This controller cannot start goals");
@@ -870,7 +1031,7 @@ async function executeGoalCommand(arguments_, app) {
870
1031
  return formatGoal(await app.startGoal(objective, budget));
871
1032
  }
872
1033
  if (rest.length) throw new Error(GOAL_COMMAND_USAGE);
873
- if (verb === "status") return formatGoal(app.getGoal());
1034
+ if (verb === "status") return formatGoal(app.application.getGoal());
874
1035
  const method = verb === "pause" ? app.pauseGoal : verb === "resume" ? app.resumeGoal : verb === "cancel" ? app.cancelGoal : void 0;
875
1036
  if (!method) throw new Error(GOAL_COMMAND_USAGE);
876
1037
  return formatGoal(await method.call(app));
@@ -908,16 +1069,15 @@ function formatDelegationRequests(requests, active) {
908
1069
  }
909
1070
  __name(formatDelegationRequests, "formatDelegationRequests");
910
1071
  async function formatDelegationToolRecords(controller, taskId) {
911
- if (controller.delegationToolRecords === void 0) {
912
- throw new Error("Sub-agents are disabled in this workspace");
913
- }
914
- const records = await controller.delegationToolRecords(taskId);
1072
+ const records = await controller.application.delegationToolRecords(taskId);
915
1073
  if (records.records.length === 0) {
916
1074
  return `Task ${taskId} (${records.sessionId}) has no finished tool records.`;
917
1075
  }
918
1076
  return [
919
1077
  `Task ${taskId} \xB7 Session ${records.sessionId}`,
920
- ...records.records.map((record) => ` step ${record.step} ${record.status} ${record.name}: ${record.summary.replace(/\s+/gu, " ").slice(0, 160)}`),
1078
+ ...records.records.map(
1079
+ (record) => ` step ${record.step} ${record.status} ${record.name}: ${record.summary.replace(/\s+/gu, " ").slice(0, 160)}`
1080
+ ),
921
1081
  records.truncated ? " \u2026 more records were omitted" : ""
922
1082
  ].filter((line) => line !== "").join("\n");
923
1083
  }
@@ -929,18 +1089,20 @@ async function executeDelegationCommand(arguments_, controller) {
929
1089
  throw new Error(DELEGATION_COMMAND_USAGE);
930
1090
  }
931
1091
  if (mode !== "status") {
932
- if (controller.setDelegationNotifications === void 0) throw new Error("Delegation notifications are unavailable");
1092
+ if (controller.setDelegationNotifications === void 0)
1093
+ throw new Error("Delegation notifications are unavailable");
933
1094
  controller.setDelegationNotifications(mode === "on");
934
1095
  }
935
1096
  return `Delegation notifications: ${controller.delegationNotifications === true ? "on" : "off"}`;
936
1097
  }
937
- if (controller.listDelegationRequests === void 0) {
1098
+ const application = controller.application;
1099
+ if (application.subagents === void 0) {
938
1100
  return "Sub-agents are disabled in this workspace.";
939
1101
  }
940
- const requests = controller.listDelegationRequests();
1102
+ const requests = application.listDelegationRequests();
941
1103
  const verb = arguments_[0];
942
1104
  if (arguments_.length === 0 || verb === "show") {
943
- return formatDelegationRequests(requests, controller.getDelegationState?.());
1105
+ return formatDelegationRequests(requests, application.getDelegationState());
944
1106
  }
945
1107
  if (verb === "tools") {
946
1108
  if (arguments_.length !== 2) throw new Error(DELEGATION_COMMAND_USAGE);
@@ -1005,94 +1167,14 @@ function renderRequest(request, label) {
1005
1167
  lines.push(` ${renderDelegationTask(task)}`);
1006
1168
  }
1007
1169
  if ("budget" in request && request.budget !== void 0) {
1008
- lines.push(` request budget: ${request.budget.modelCalls}/${request.budget.maxModelCalls} model calls, ${request.budget.totalTokens} tokens${request.budget.usageComplete ? "" : " (some calls reported no usage or were charged by reservation)"}`);
1170
+ lines.push(
1171
+ ` request budget: ${request.budget.modelCalls}/${request.budget.maxModelCalls} model calls, ${request.budget.totalTokens} tokens${request.budget.usageComplete ? "" : " (some calls reported no usage or were charged by reservation)"}`
1172
+ );
1009
1173
  }
1010
1174
  return lines.join("\n");
1011
1175
  }
1012
1176
  __name(renderRequest, "renderRequest");
1013
1177
 
1014
- // packages/ui/tui/dist/slash-commands.js
1015
- var SlashCommandRegistry = class {
1016
- static {
1017
- __name(this, "SlashCommandRegistry");
1018
- }
1019
- definitions;
1020
- byName = /* @__PURE__ */ new Map();
1021
- names = [];
1022
- constructor(definitions) {
1023
- this.definitions = [...definitions];
1024
- for (const definition of definitions) {
1025
- this.registerName(definition.name, definition);
1026
- for (const alias of definition.aliases ?? []) {
1027
- this.registerName(alias, definition);
1028
- }
1029
- }
1030
- }
1031
- find(name) {
1032
- return this.byName.get(name.toLowerCase());
1033
- }
1034
- parse(input) {
1035
- const trimmed = input.trim();
1036
- if (!trimmed.startsWith("/"))
1037
- return { type: "not-command" };
1038
- const [invokedAs = "", ...arguments_] = trimmed.split(/\s+/u);
1039
- const definition = this.find(invokedAs);
1040
- return definition === void 0 ? { type: "unknown", command: invokedAs } : {
1041
- type: "command",
1042
- definition,
1043
- invokedAs,
1044
- arguments: arguments_
1045
- };
1046
- }
1047
- match(prefix) {
1048
- if (!prefix.startsWith("/") || /\s/u.test(prefix))
1049
- return [];
1050
- const normalized = prefix.toLowerCase();
1051
- return this.names.filter(({ value }) => value.toLowerCase().startsWith(normalized)).map(({ value, definition }) => ({
1052
- value,
1053
- label: value,
1054
- description: definition.description
1055
- }));
1056
- }
1057
- createSuggester(suggestArguments) {
1058
- return async (input) => {
1059
- if (!input.startsWith("/"))
1060
- return [];
1061
- const argumentInput = splitSlashCommandArgumentInput(input);
1062
- if (argumentInput === void 0)
1063
- return this.match(input);
1064
- const definition = this.find(argumentInput.invokedAs);
1065
- if (definition === void 0 || suggestArguments === void 0)
1066
- return [];
1067
- return suggestArguments({
1068
- input,
1069
- definition,
1070
- ...argumentInput
1071
- });
1072
- };
1073
- }
1074
- registerName(value, definition) {
1075
- if (!isCommandName(value)) {
1076
- throw new TypeError(`Invalid slash command name: ${JSON.stringify(value)}`);
1077
- }
1078
- const normalized = value.toLowerCase();
1079
- if (this.byName.has(normalized)) {
1080
- throw new Error(`Duplicate slash command name: ${value}`);
1081
- }
1082
- this.byName.set(normalized, definition);
1083
- this.names.push({ value, definition });
1084
- }
1085
- };
1086
- function splitSlashCommandArgumentInput(input) {
1087
- const match = /^(\/\S+)\s+(.*)$/u.exec(input);
1088
- return match === null ? void 0 : { invokedAs: match[1], argumentPrefix: match[2] };
1089
- }
1090
- __name(splitSlashCommandArgumentInput, "splitSlashCommandArgumentInput");
1091
- function isCommandName(value) {
1092
- return /^\/\S+$/u.test(value);
1093
- }
1094
- __name(isCommandName, "isCommandName");
1095
-
1096
1178
  // apps/maybecode/src/slash-commands.ts
1097
1179
  import { userInfo } from "node:os";
1098
1180
  var MAYBECODE_COMPACTION_STRATEGIES = [
@@ -1100,18 +1182,50 @@ var MAYBECODE_COMPACTION_STRATEGIES = [
1100
1182
  "provider-native"
1101
1183
  ];
1102
1184
  var MAYBECODE_SLASH_COMMANDS = [
1103
- { name: "/permissions", usage: "/permissions [list|allow <id>|deny <id>|revoke <id>]", description: "\u67E5\u770B\u3001\u521B\u5EFA\u6216\u64A4\u9500\u6301\u4E45\u6743\u9650\u89C4\u5219" },
1104
- { name: "/fork", usage: "/fork", description: "Choose a historical reply and fork in this workspace or a new worktree" },
1105
- { name: "/changes", usage: "/changes [run <run-id>|session|workspace|commit <commit>]", description: "Browse checkpoint and workspace file changes" },
1185
+ {
1186
+ name: "/permissions",
1187
+ usage: "/permissions [list|allow <id>|deny <id>|revoke <id>]",
1188
+ description: "\u67E5\u770B\u3001\u521B\u5EFA\u6216\u64A4\u9500\u6301\u4E45\u6743\u9650\u89C4\u5219"
1189
+ },
1190
+ {
1191
+ name: "/fork",
1192
+ usage: "/fork",
1193
+ description: "Choose a historical reply and fork in this workspace or a new worktree"
1194
+ },
1195
+ {
1196
+ name: "/changes",
1197
+ usage: "/changes [run <run-id>|session|workspace|commit <commit>]",
1198
+ description: "Browse checkpoint and workspace file changes"
1199
+ },
1106
1200
  { name: "/worktrees", usage: "/worktrees [open|delete <id>]", description: "List, open or delete managed worktrees" },
1107
- { name: "/steer", usage: "/steer <message>", description: "Deliver additional input after the current Step finishes" },
1201
+ {
1202
+ name: "/steer",
1203
+ usage: "/steer <message>",
1204
+ description: "Deliver additional input after the current Step finishes"
1205
+ },
1108
1206
  { name: "/stop", usage: "/stop", description: "Cancel the current operation" },
1109
- { name: "/yolo", usage: "/yolo [on|off|status]", description: "Enable automatic tool approval; use off to disable or status to inspect" },
1207
+ {
1208
+ name: "/yolo",
1209
+ usage: "/yolo [on|off|status]",
1210
+ description: "Enable automatic tool approval; use off to disable or status to inspect"
1211
+ },
1110
1212
  { name: "/goal", usage: GOAL_COMMAND_USAGE, description: "Start, inspect, pause, resume, or cancel a durable goal" },
1111
1213
  { name: "/web", usage: "/web", description: "Open the current workspace and session in a browser" },
1112
- { name: "/skills", usage: "/skills [show <name>|use <name> [task]]", description: "List skills, preview instructions, or activate a skill" },
1113
- { name: "/recovery", usage: "/recovery [resolve <id> <verified finding>]", description: "Inspect interrupted tools or record verified recovery findings" },
1114
- { name: "/delegations", usage: DELEGATION_COMMAND_USAGE, description: "Inspect sub-agent requests and tools, and control status notifications" },
1214
+ {
1215
+ name: "/skills",
1216
+ usage: "/skills [show <name>|use <name> [task]]",
1217
+ description: "List skills, preview instructions, or activate a skill"
1218
+ },
1219
+ {
1220
+ name: "/recovery",
1221
+ usage: "/recovery [resolve <id> <verified finding>]",
1222
+ description: "Inspect interrupted tools or record verified recovery findings"
1223
+ },
1224
+ {
1225
+ name: "/delegations",
1226
+ usage: DELEGATION_COMMAND_USAGE,
1227
+ description: "Inspect sub-agent requests and tools, and control status notifications"
1228
+ },
1115
1229
  {
1116
1230
  name: "/new",
1117
1231
  usage: "/new",
@@ -1179,9 +1293,7 @@ function formatMaybeCodeMcpStatus(servers) {
1179
1293
  const lines = ["MCP servers:"];
1180
1294
  for (const server of servers) {
1181
1295
  const requirement = server.required ? "required" : "optional";
1182
- lines.push(
1183
- `- ${server.serverId}: ${server.state} (${requirement}, ${server.transport})`
1184
- );
1296
+ lines.push(`- ${server.serverId}: ${server.state} (${requirement}, ${server.transport})`);
1185
1297
  if (server.protocolVersion !== void 0) {
1186
1298
  lines.push(` protocol: ${server.protocolVersion}`);
1187
1299
  }
@@ -1195,12 +1307,7 @@ function formatMaybeCodeMcpStatus(servers) {
1195
1307
  }
1196
1308
  if (server.diagnostic !== void 0) {
1197
1309
  const code = server.diagnostic.code === void 0 ? "" : ` [${server.diagnostic.code}]`;
1198
- lines.push(
1199
- ...indentLines(
1200
- ` error${code}: `,
1201
- server.diagnostic.message
1202
- )
1203
- );
1310
+ lines.push(...indentLines(` error${code}: `, server.diagnostic.message));
1204
1311
  }
1205
1312
  const stderr = server.stderr ?? server.diagnostic?.stderr;
1206
1313
  if (stderr !== void 0) {
@@ -1234,7 +1341,8 @@ function createMaybeCodeSlashCommandSuggester(controller, options = {}) {
1234
1341
  const { definition, invokedAs: command, argumentPrefix } = argumentInput;
1235
1342
  if (definition?.name === "/delegations") {
1236
1343
  const match = /^notifications\s+(\S*)$/u.exec(argumentPrefix);
1237
- if (match) return ["on", "off", "status"].filter((value) => value.startsWith(match[1])).map((value) => ({ value: `${command} notifications ${value}`, label: value }));
1344
+ if (match)
1345
+ return ["on", "off", "status"].filter((value) => value.startsWith(match[1])).map((value) => ({ value: `${command} notifications ${value}`, label: value }));
1238
1346
  return ["show", "notifications", "tools", "resolve"].filter((value) => value.startsWith(argumentPrefix)).map((value) => ({ value: `${command} ${value}`, label: value }));
1239
1347
  }
1240
1348
  if (definition?.name === "/yolo") {
@@ -1245,17 +1353,28 @@ function createMaybeCodeSlashCommandSuggester(controller, options = {}) {
1245
1353
  }
1246
1354
  if (definition?.name === "/skills") {
1247
1355
  const match = /^(show|use)\s+(\S*)$/u.exec(argumentPrefix);
1248
- if (match) return (controller.listSkills?.() ?? []).filter((skill) => skill.name.startsWith(match[2])).map((skill) => ({ value: `${command} ${match[1]} ${skill.name}`, label: skill.name, description: skill.description }));
1356
+ if (match)
1357
+ return controller.application.listSkills().filter((skill) => skill.name.startsWith(match[2])).map((skill) => ({
1358
+ value: `${command} ${match[1]} ${skill.name}`,
1359
+ label: skill.name,
1360
+ description: skill.description
1361
+ }));
1249
1362
  if (/\s/u.test(argumentPrefix)) return [];
1250
- return ["show", "use"].filter((verb) => verb.startsWith(argumentPrefix)).map((verb) => ({ value: `${command} ${verb}`, label: verb, description: verb === "show" ? "Preview without activation" : "Activate for the current session" }));
1363
+ return ["show", "use"].filter((verb) => verb.startsWith(argumentPrefix)).map((verb) => ({
1364
+ value: `${command} ${verb}`,
1365
+ label: verb,
1366
+ description: verb === "show" ? "Preview without activation" : "Activate for the current session"
1367
+ }));
1251
1368
  }
1252
1369
  if (definition?.name === "/compact") {
1253
1370
  if (/\s/u.test(argumentPrefix)) return [];
1254
- return MAYBECODE_COMPACTION_STRATEGIES.filter((strategy) => strategy.startsWith(argumentPrefix)).map((strategy) => ({
1255
- value: `${command} ${strategy}`,
1256
- label: strategy,
1257
- description: strategy === "provider-native" ? "Compact with the active model's native compactor" : "Keep the current request and fresh saved work notes"
1258
- }));
1371
+ return MAYBECODE_COMPACTION_STRATEGIES.filter((strategy) => strategy.startsWith(argumentPrefix)).map(
1372
+ (strategy) => ({
1373
+ value: `${command} ${strategy}`,
1374
+ label: strategy,
1375
+ description: strategy === "provider-native" ? "Compact with the active model's native compactor" : "Keep the current request and fresh saved work notes"
1376
+ })
1377
+ );
1259
1378
  }
1260
1379
  if (definition?.name === "/resume") {
1261
1380
  if (/\s/u.test(argumentPrefix)) return [];
@@ -1266,23 +1385,23 @@ function createMaybeCodeSlashCommandSuggester(controller, options = {}) {
1266
1385
  }));
1267
1386
  }
1268
1387
  if (definition?.name === "/model") {
1269
- const optionInput = /^(\S+)\s+(\S*)$/u.exec(
1270
- argumentPrefix
1271
- );
1388
+ const optionInput = /^(\S+)\s+(\S*)$/u.exec(argumentPrefix);
1272
1389
  if (optionInput !== null) {
1273
1390
  const optionPrefix = optionInput[2];
1274
- return "--default".startsWith(optionPrefix) ? [{
1275
- value: `${command} ${optionInput[1]} --default`,
1276
- label: "--default",
1277
- description: "Switch to this profile and make it the default"
1278
- }] : [];
1391
+ return "--default".startsWith(optionPrefix) ? [
1392
+ {
1393
+ value: `${command} ${optionInput[1]} --default`,
1394
+ label: "--default",
1395
+ description: "Switch to this profile and make it the default"
1396
+ }
1397
+ ] : [];
1279
1398
  }
1280
1399
  if (/\s/u.test(argumentPrefix)) return [];
1281
1400
  const normalized = argumentPrefix.toLowerCase();
1282
1401
  return (await controller.listModels()).filter((model) => model.name.toLowerCase().startsWith(normalized)).map((model) => ({
1283
1402
  value: `${command} ${model.name}`,
1284
1403
  label: model.name,
1285
- description: model.name === controller.modelInfo?.profile ? `Current \xB7 ${model.provider}/${model.model}` : `${model.provider}/${model.model} \xB7 ${model.adapter}`
1404
+ description: model.name === controller.application.modelInfo?.profile ? `Current \xB7 ${model.provider}/${model.model}` : `${model.provider}/${model.model} \xB7 ${model.adapter}`
1286
1405
  }));
1287
1406
  }
1288
1407
  if (definition?.name === "/effort") {
@@ -1309,8 +1428,10 @@ async function executeMaybeCodeSlashCommand(input, controller) {
1309
1428
  switch (definition.name) {
1310
1429
  case "/fork": {
1311
1430
  if (arguments_.length) return { type: "usage", usage: "/fork" };
1312
- if (!controller.getForkPoints || !controller.forkSession) throw new Error("Session forks are unavailable in this host");
1313
- if (controller.isRunning) throw new Error("Wait for the current request to finish before creating a Session fork");
1431
+ if (!controller.getForkPoints || !controller.forkSession)
1432
+ throw new Error("Session forks are unavailable in this host");
1433
+ if (controller.isRunning)
1434
+ throw new Error("Wait for the current request to finish before creating a Session fork");
1314
1435
  return { type: "fork.selection.requested", points: await controller.getForkPoints() };
1315
1436
  }
1316
1437
  case "/changes": {
@@ -1319,15 +1440,19 @@ async function executeMaybeCodeSlashCommand(input, controller) {
1319
1440
  if (arguments_.length > 2 || !["run", "session", "workspace", "commit"].includes(scope) || ["run", "commit"].includes(scope) && !value || ["session", "workspace"].includes(scope) && value) {
1320
1441
  return { type: "usage", usage: "/changes [run <run-id>|session|workspace|commit <commit>]" };
1321
1442
  }
1322
- return { type: "changes.selection.requested", diff: await controller.getChanges({
1323
- scope: scope === "commit" ? "workspace" : scope,
1324
- ...scope === "run" ? { runId: value } : scope === "commit" ? { commit: value } : {}
1325
- }) };
1443
+ return {
1444
+ type: "changes.selection.requested",
1445
+ diff: await controller.getChanges({
1446
+ scope: scope === "commit" ? "workspace" : scope,
1447
+ ...scope === "run" ? { runId: value } : scope === "commit" ? { commit: value } : {}
1448
+ })
1449
+ };
1326
1450
  }
1327
1451
  case "/worktrees": {
1328
1452
  if (!controller.getWorktrees) throw new Error("Worktree management is unavailable in this host");
1329
1453
  if (arguments_.length) {
1330
- if (arguments_.length !== 2 || !["open", "delete"].includes(arguments_[0])) return { type: "usage", usage: "/worktrees [open|delete <id>]" };
1454
+ if (arguments_.length !== 2 || !["open", "delete"].includes(arguments_[0]))
1455
+ return { type: "usage", usage: "/worktrees [open|delete <id>]" };
1331
1456
  if (arguments_[0] === "open") {
1332
1457
  if (!controller.openWorktree) throw new Error("Opening a worktree is unavailable in this host");
1333
1458
  await controller.openWorktree(arguments_[1]);
@@ -1348,26 +1473,34 @@ async function executeMaybeCodeSlashCommand(input, controller) {
1348
1473
  case "/stop": {
1349
1474
  const invalid = noArguments(arguments_, definition);
1350
1475
  if (invalid) return invalid;
1351
- return { type: "display", text: controller.cancel("Stopped by user") ? "Cancellation requested." : "No active operation." };
1476
+ return {
1477
+ type: "display",
1478
+ text: controller.cancel("Stopped by user") ? "Cancellation requested." : "No active operation."
1479
+ };
1352
1480
  }
1353
1481
  case "/yolo": {
1354
1482
  const action = arguments_[0] ?? "on";
1355
- if (arguments_.length > 1 || !["on", "off", "status"].includes(action)) return { type: "usage", usage: "/yolo [on|off|status]" };
1483
+ if (arguments_.length > 1 || !["on", "off", "status"].includes(action))
1484
+ return { type: "usage", usage: "/yolo [on|off|status]" };
1356
1485
  if (action !== "status") await controller.setPermissionMode(action === "on" ? "yolo" : "default");
1357
1486
  return { type: "display", text: controller.permissionMode === "yolo" ? "YOLO enabled" : "YOLO disabled" };
1358
1487
  }
1359
1488
  case "/permissions": {
1360
- if (controller.persistentRulesEnabled === false || !controller.listPermissionRules || !controller.revokePermissionRule) throw new Error("\u6B64\u5BBF\u4E3B\u6CA1\u6709\u542F\u7528\u89C4\u5219\u7BA1\u7406\u3002");
1489
+ if (!controller.application.persistentRulesEnabled || !controller.listPermissionRules || !controller.revokePermissionRule)
1490
+ throw new Error("\u6B64\u5BBF\u4E3B\u6CA1\u6709\u542F\u7528\u89C4\u5219\u7BA1\u7406\u3002");
1361
1491
  const action = arguments_[0] ?? "list";
1362
1492
  if (action === "list" && arguments_.length <= 1) {
1363
1493
  const rules = await controller.listPermissionRules();
1364
- return { type: "display", text: rules.length === 0 ? "\u5F53\u524D\u6CA1\u6709\u6301\u4E45\u6743\u9650\u89C4\u5219\u3002" : rules.map(
1365
- (rule) => `${rule.id}
1494
+ return {
1495
+ type: "display",
1496
+ text: rules.length === 0 ? "\u5F53\u524D\u6CA1\u6709\u6301\u4E45\u6743\u9650\u89C4\u5219\u3002" : rules.map(
1497
+ (rule) => `${rule.id}
1366
1498
  ${rule.decision === "allow" ? "\u5141\u8BB8" : "\u7981\u6B62"} \xB7 ${rule.description}
1367
1499
  \u8303\u56F4\uFF1A${rule.scopeId}
1368
1500
  \u521B\u5EFA\u8005\uFF1A${rule.createdBy}
1369
1501
  \u6709\u6548\u671F\uFF1A${rule.expiresAt === void 0 ? "\u6301\u7EED\u6709\u6548" : new Date(rule.expiresAt).toISOString()}`
1370
- ).join("\n\n") };
1502
+ ).join("\n\n")
1503
+ };
1371
1504
  }
1372
1505
  if (action === "revoke" && arguments_.length === 2) {
1373
1506
  if (!await controller.revokePermissionRule(arguments_[1])) throw new Error("\u89C4\u5219\u4E0D\u5B58\u5728\u3002");
@@ -1375,11 +1508,17 @@ ${rule.decision === "allow" ? "\u5141\u8BB8" : "\u7981\u6B62"} \xB7 ${rule.descr
1375
1508
  }
1376
1509
  if ((action === "allow" || action === "deny") && arguments_.length === 2) {
1377
1510
  if (!controller.createPermissionRuleFrom) throw new Error("\u6B64\u5BBF\u4E3B\u6CA1\u6709\u542F\u7528\u89C4\u5219\u521B\u5EFA\u3002");
1378
- const rule = await controller.createPermissionRuleFrom(arguments_[1], { decision: action, createdBy: `local:${userInfo().username}` });
1379
- return { type: "display", text: `\u5DF2\u521B\u5EFA${action === "allow" ? "\u5141\u8BB8" : "\u7981\u6B62"}\u89C4\u5219\uFF1A${rule.id}
1511
+ const rule = await controller.createPermissionRuleFrom(arguments_[1], {
1512
+ decision: action,
1513
+ createdBy: `local:${userInfo().username}`
1514
+ });
1515
+ return {
1516
+ type: "display",
1517
+ text: `\u5DF2\u521B\u5EFA${action === "allow" ? "\u5141\u8BB8" : "\u7981\u6B62"}\u89C4\u5219\uFF1A${rule.id}
1380
1518
  ${rule.description}
1381
1519
  \u8303\u56F4\uFF1A${rule.scopeId}
1382
- \u540C\u8303\u56F4\u7684\u7981\u6B62\u89C4\u5219\u4F18\u5148\u3002` };
1520
+ \u540C\u8303\u56F4\u7684\u7981\u6B62\u89C4\u5219\u4F18\u5148\u3002`
1521
+ };
1383
1522
  }
1384
1523
  return { type: "usage", usage: definition.usage };
1385
1524
  }
@@ -1389,11 +1528,16 @@ ${rule.description}
1389
1528
  return noArguments(arguments_, definition) ?? { type: "web.requested" };
1390
1529
  case "/skills": {
1391
1530
  if (arguments_.length === 0) {
1392
- const skills = controller.listSkills?.() ?? [];
1393
- const diagnostics = controller.getSkillDiagnostics?.() ?? [];
1394
- const text = skills.length === 0 ? "No skills discovered." : skills.map((skill) => `${skill.name}${skill.active ? " [active]" : ""} \u2014 ${skill.description}
1395
- ${skill.directory}`).join("\n");
1396
- return { type: "display", text: text + (diagnostics.length === 0 ? "" : "\n\nDiscovery diagnostics:\n" + diagnostics.map((item) => `${item.path}: ${item.message}`).join("\n")) };
1531
+ const skills = controller.application.listSkills();
1532
+ const diagnostics = controller.application.agent.skills?.registry.diagnostics ?? [];
1533
+ const text = skills.length === 0 ? "No skills discovered." : skills.map(
1534
+ (skill) => `${skill.name}${skill.active ? " [active]" : ""} \u2014 ${skill.description}
1535
+ ${skill.directory}`
1536
+ ).join("\n");
1537
+ return {
1538
+ type: "display",
1539
+ text: text + (diagnostics.length === 0 ? "" : "\n\nDiscovery diagnostics:\n" + diagnostics.map((item) => `${item.path}: ${item.message}`).join("\n"))
1540
+ };
1397
1541
  }
1398
1542
  const [verb, name, ...task] = arguments_;
1399
1543
  if (name === void 0 || !["show", "use"].includes(verb)) return usage(definition);
@@ -1401,11 +1545,14 @@ ${rule.description}
1401
1545
  if (task.length > 0) return usage(definition);
1402
1546
  if (!controller.readSkill) throw new Error("Skills are unsupported by this controller");
1403
1547
  const document = await controller.readSkill(name);
1404
- return { type: "display", text: `${document.name}
1548
+ return {
1549
+ type: "display",
1550
+ text: `${document.name}
1405
1551
  ${document.directory}
1406
1552
  Revision: ${document.revision}
1407
1553
 
1408
- ${document.body}` };
1554
+ ${document.body}`
1555
+ };
1409
1556
  }
1410
1557
  if (task.length > 0) {
1411
1558
  if (!controller.submitSkill) throw new Error("Skill submission is unsupported by this controller");
@@ -1417,9 +1564,14 @@ ${document.body}` };
1417
1564
  }
1418
1565
  case "/recovery": {
1419
1566
  if (arguments_.length === 0) {
1420
- const pending2 = controller.listRecoveries?.() ?? [];
1421
- return { type: "display", text: pending2.length === 0 ? "No unresolved recovery findings." : pending2.map((item) => `${item.id} \u2014 ${item.call.name}: outcome unknown
1422
- Input: ${JSON.stringify(item.call.input)}`).join("\n\n") + "\nVerify external effects, then use /recovery resolve <id> <verified finding>." };
1567
+ const pending2 = controller.listRecoveries();
1568
+ return {
1569
+ type: "display",
1570
+ text: pending2.length === 0 ? "No unresolved recovery findings." : pending2.map(
1571
+ (item) => `${item.id} \u2014 ${item.call.name}: outcome unknown
1572
+ Input: ${JSON.stringify(item.call.input)}`
1573
+ ).join("\n\n") + "\nVerify external effects, then use /recovery resolve <id> <verified finding>."
1574
+ };
1423
1575
  }
1424
1576
  if (arguments_[0] !== "resolve" || arguments_.length < 3) return usage(definition);
1425
1577
  if (!controller.resolveRecovery) throw new Error("Recovery resolution is unsupported");
@@ -1438,7 +1590,7 @@ Input: ${JSON.stringify(item.call.input)}`).join("\n\n") + "\nVerify external ef
1438
1590
  case "/instructions":
1439
1591
  return noArguments(arguments_, definition) ?? {
1440
1592
  type: "instructions",
1441
- instructions: controller.instructions
1593
+ instructions: controller.application.instructions
1442
1594
  };
1443
1595
  case "/retry": {
1444
1596
  const invalid = noArguments(arguments_, definition);
@@ -1499,9 +1651,7 @@ Input: ${JSON.stringify(item.call.input)}`).join("\n\n") + "\nVerify external ef
1499
1651
  return usage(definition);
1500
1652
  }
1501
1653
  const normalized = query.toLowerCase();
1502
- const selected = (await controller.listModels()).find(
1503
- (model2) => model2.name.toLowerCase().startsWith(normalized)
1504
- );
1654
+ const selected = (await controller.listModels()).find((model2) => model2.name.toLowerCase().startsWith(normalized));
1505
1655
  if (selected === void 0) return { type: "model.not-found", query };
1506
1656
  const model = await controller.switchModel(selected.name);
1507
1657
  if (setDefault) await controller.setDefaultModel(selected.name);
@@ -1524,15 +1674,11 @@ Input: ${JSON.stringify(item.call.input)}`).join("\n\n") + "\nVerify external ef
1524
1674
  return { type: "effort.selection.requested", state };
1525
1675
  }
1526
1676
  const normalized = query.toLowerCase();
1527
- const selected = reasoningEffortChoices(state).find(
1528
- (effort) => effort.toLowerCase().startsWith(normalized)
1529
- );
1677
+ const selected = reasoningEffortChoices(state).find((effort) => effort.toLowerCase().startsWith(normalized));
1530
1678
  if (selected === void 0) return { type: "effort.not-found", query };
1531
1679
  return {
1532
1680
  type: "effort.changed",
1533
- state: await controller.setReasoningEffort(
1534
- selected === "default" ? void 0 : selected
1535
- )
1681
+ state: await controller.setReasoningEffort(selected === "default" ? void 0 : selected)
1536
1682
  };
1537
1683
  }
1538
1684
  }
@@ -1565,9 +1711,7 @@ function isCompactionStrategy(value) {
1565
1711
  __name(isCompactionStrategy, "isCompactionStrategy");
1566
1712
  function indentLines(prefix, value) {
1567
1713
  const lines = value.split("\n");
1568
- return lines.map(
1569
- (line, index) => index === 0 ? `${prefix}${line}` : ` ${line}`
1570
- );
1714
+ return lines.map((line, index) => index === 0 ? `${prefix}${line}` : ` ${line}`);
1571
1715
  }
1572
1716
  __name(indentLines, "indentLines");
1573
1717
 
@@ -1586,13 +1730,18 @@ var MaybeCodeWebCommands = class {
1586
1730
  busy = false;
1587
1731
  suggest;
1588
1732
  available(name) {
1589
- if (["session.fork", "worktree.open", "worktree.delete", "changes.restore.preview", "changes.restore.apply"].includes(name) && (this.app.isRunning || this.app.getGoal?.()?.status === "active" || this.app.getMcpInteractions?.().length)) return false;
1590
- if (name === "permission.set" && (this.app.isRunning || this.app.getGoal?.()?.status === "active" || this.app.getMcpInteractions?.().length)) return false;
1733
+ if (["session.fork", "worktree.open", "worktree.delete", "changes.restore.preview", "changes.restore.apply"].includes(
1734
+ name
1735
+ ) && (this.app.isRunning || this.app.application.getGoal()?.status === "active" || this.app.getMcpInteractions?.().length))
1736
+ return false;
1737
+ if (name === "permission.set" && (this.app.isRunning || this.app.application.getGoal()?.status === "active" || this.app.getMcpInteractions?.().length))
1738
+ return false;
1591
1739
  if (name === "message.submit") return !this.busy;
1592
1740
  if (name === "mcp.respond") return Boolean(this.app.getMcpInteractions?.().length);
1593
1741
  if (name === "console.cancel") return true;
1594
1742
  if (this.busy) return ["run.cancel", "approval.resolve"].includes(name);
1595
- if (this.app.getMcpInteractions?.().length && ["session.new", "session.activate", "session.delete", "console.action"].includes(name)) return false;
1743
+ if (this.app.getMcpInteractions?.().length && ["session.new", "session.activate", "session.delete", "console.action"].includes(name))
1744
+ return false;
1596
1745
  if (name === "console.execute") return true;
1597
1746
  if (name === "console.action") return !this.app.isRunning;
1598
1747
  return true;
@@ -1623,16 +1772,23 @@ ${request.params.message}`,
1623
1772
  const { id, action, content } = command.args;
1624
1773
  if (!["accept", "decline", "cancel"].includes(action)) throw new UiError(400, "\u4EA4\u4E92\u64CD\u4F5C\u65E0\u6548\u3002");
1625
1774
  const request = this.app.getMcpInteractions?.().find((item) => item.id === id);
1626
- if (!request || this.app.ownsSession?.(request.owner.sessionId) !== true) throw new UiError(409, "\u4EA4\u4E92\u5DF2\u7ED3\u675F\u6216\u4F1A\u8BDD\u5DF2\u6539\u53D8\u3002");
1775
+ if (!request || this.app.ownsSession?.(request.owner.sessionId) !== true)
1776
+ throw new UiError(409, "\u4EA4\u4E92\u5DF2\u7ED3\u675F\u6216\u4F1A\u8BDD\u5DF2\u6539\u53D8\u3002");
1627
1777
  const parsed = content === void 0 ? void 0 : JSON.parse(content);
1628
- if (parsed !== void 0 && (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))) throw new UiError(400, "\u8868\u5355\u5185\u5BB9\u5FC5\u987B\u4E3A JSON \u5BF9\u8C61\u3002");
1629
- if (!this.app.respondMcpInteraction?.(id, { action, ...parsed === void 0 ? {} : { content: parsed } })) throw new UiError(409, "\u4EA4\u4E92\u5DF2\u7ED3\u675F\u3002");
1778
+ if (parsed !== void 0 && (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)))
1779
+ throw new UiError(400, "\u8868\u5355\u5185\u5BB9\u5FC5\u987B\u4E3A JSON \u5BF9\u8C61\u3002");
1780
+ if (!this.app.respondMcpInteraction?.(id, {
1781
+ action,
1782
+ ...parsed === void 0 ? {} : { content: parsed }
1783
+ }))
1784
+ throw new UiError(409, "\u4EA4\u4E92\u5DF2\u7ED3\u675F\u3002");
1630
1785
  this.changed();
1631
1786
  return {};
1632
1787
  }
1633
1788
  if (command.name === "console.cancel") {
1634
1789
  commandArgs(command, []);
1635
- for (const request of this.app.getMcpInteractions?.() ?? []) this.app.respondMcpInteraction?.(request.id, { action: "cancel" });
1790
+ for (const request of this.app.getMcpInteractions?.() ?? [])
1791
+ this.app.respondMcpInteraction?.(request.id, { action: "cancel" });
1636
1792
  this.app.cancel("Cancelled from Web UI");
1637
1793
  this.changed();
1638
1794
  return {};
@@ -1645,29 +1801,37 @@ ${request.params.message}`,
1645
1801
  commandArgs(command, ["runId"], ["path", "paths"]);
1646
1802
  if (!this.app.previewRestore) throw new UiError(400, "\u6587\u4EF6\u6062\u590D\u80FD\u529B\u4E0D\u53EF\u7528\u3002");
1647
1803
  const paths = command.args.paths ? JSON.parse(command.args.paths) : command.args.path ? [command.args.path] : [];
1648
- if (!Array.isArray(paths) || paths.length === 0 || paths.some((path) => typeof path !== "string")) throw new UiError(400, "\u8BF7\u9009\u62E9\u9700\u8981\u6062\u590D\u7684\u6587\u4EF6\u3002");
1804
+ if (!Array.isArray(paths) || paths.length === 0 || paths.some((path) => typeof path !== "string"))
1805
+ throw new UiError(400, "\u8BF7\u9009\u62E9\u9700\u8981\u6062\u590D\u7684\u6587\u4EF6\u3002");
1649
1806
  return { diff: (await this.app.previewRestore(command.args.runId, paths)).diff };
1650
1807
  }
1651
1808
  if (command.name === "changes.restore.apply") {
1652
1809
  commandArgs(command, ["previewId"]);
1653
1810
  if (!this.app.restoreFiles) throw new UiError(400, "\u6587\u4EF6\u6062\u590D\u80FD\u529B\u4E0D\u53EF\u7528\u3002");
1654
1811
  await this.app.restoreFiles(command.args.previewId);
1655
- return { selectedId: this.app.sessionId, output: { title: "\u6587\u4EF6\u6062\u590D", text: "\u5DF2\u6062\u590D\u9009\u5B9A\u6587\u4EF6\u5E76\u66F4\u65B0\u5DE5\u4F5C\u533A\u7248\u672C\u8BB0\u5F55\u3002" } };
1812
+ return {
1813
+ selectedId: this.app.sessionId,
1814
+ output: { title: "\u6587\u4EF6\u6062\u590D", text: "\u5DF2\u6062\u590D\u9009\u5B9A\u6587\u4EF6\u5E76\u66F4\u65B0\u5DE5\u4F5C\u533A\u7248\u672C\u8BB0\u5F55\u3002" }
1815
+ };
1656
1816
  }
1657
1817
  if (command.name === "session.fork") {
1658
1818
  commandArgs(command, ["pointId", "mode"]);
1659
- if (!this.app.forkSession || !["current", "worktree"].includes(command.args.mode)) throw new UiError(400, "Session \u5206\u652F\u65B9\u5F0F\u65E0\u6548\u3002");
1819
+ if (!this.app.forkSession || !["current", "worktree"].includes(command.args.mode))
1820
+ throw new UiError(400, "Session \u5206\u652F\u65B9\u5F0F\u65E0\u6548\u3002");
1660
1821
  await this.app.forkSession(command.args.pointId, command.args.mode);
1661
1822
  return { selectedId: this.app.sessionId };
1662
1823
  }
1663
1824
  if (command.name === "changes.view") {
1664
1825
  commandArgs(command, ["scope"], ["runId", "commit"]);
1665
- if (!this.app.getChanges || !["run", "session", "workspace"].includes(command.args.scope)) throw new UiError(400, "\u6587\u4EF6\u53D8\u5316\u8303\u56F4\u65E0\u6548\u3002");
1666
- return { diff: await this.app.getChanges({
1667
- scope: command.args.scope,
1668
- ...command.args.runId ? { runId: command.args.runId } : {},
1669
- ...command.args.commit ? { commit: command.args.commit } : {}
1670
- }) };
1826
+ if (!this.app.getChanges || !["run", "session", "workspace"].includes(command.args.scope))
1827
+ throw new UiError(400, "\u6587\u4EF6\u53D8\u5316\u8303\u56F4\u65E0\u6548\u3002");
1828
+ return {
1829
+ diff: await this.app.getChanges({
1830
+ scope: command.args.scope,
1831
+ ...command.args.runId ? { runId: command.args.runId } : {},
1832
+ ...command.args.commit ? { commit: command.args.commit } : {}
1833
+ })
1834
+ };
1671
1835
  }
1672
1836
  if (command.name === "worktree.open" || command.name === "worktree.delete") {
1673
1837
  commandArgs(command, ["id"]);
@@ -1689,17 +1853,21 @@ ${request.params.message}`,
1689
1853
  const allowed = parsed.type === "command" && (parsed.definition.name === "/help" || parsed.definition.name === "/status" || parsed.definition.name === "/steer" || parsed.definition.name === "/stop" || parsed.definition.name === "/delegations" && (arguments_.length === 0 || ["show", "tools", "notifications"].includes(arguments_[0])) || parsed.definition.name === "/yolo" && parsed.arguments[0] === "status" || parsed.definition.name === "/goal" && ["status", "pause", "cancel"].includes(parsed.arguments[0] ?? "status"));
1690
1854
  if (!allowed) throw new UiError(409, "\u8BF7\u6682\u505C\u5F53\u524D\u8FD0\u884C\u540E\u6267\u884C\u6B64\u547D\u4EE4\u3002");
1691
1855
  }
1692
- if (this.app.getMcpInteractions?.().length && /^\/(?:new|resume)(?:\s|$)/u.test(command.args.text.trim())) throw new UiError(409, "\u8BF7\u5148\u5B8C\u6210\u6216\u53D6\u6D88\u5F53\u524D MCP \u4EA4\u4E92\u3002");
1856
+ if (this.app.getMcpInteractions?.().length && /^\/(?:new|resume)(?:\s|$)/u.test(command.args.text.trim()))
1857
+ throw new UiError(409, "\u8BF7\u5148\u5B8C\u6210\u6216\u53D6\u6D88\u5F53\u524D MCP \u4EA4\u4E92\u3002");
1693
1858
  const result = await executeMaybeCodeSlashCommand(command.args.text, this.app);
1694
1859
  return await this.present(result);
1695
1860
  }
1696
1861
  if (command.name === "permission.set") {
1697
1862
  commandArgs(command, ["value"]);
1698
1863
  await this.app.setPermissionMode(parsePermissionMode(command.args.value));
1699
- return { output: { title: "Permissions", text: this.app.permissionMode === "yolo" ? "YOLO enabled" : "YOLO disabled" } };
1864
+ return {
1865
+ output: { title: "Permissions", text: this.app.permissionMode === "yolo" ? "YOLO enabled" : "YOLO disabled" }
1866
+ };
1700
1867
  } else if (command.name === "model.capabilities.refresh") {
1701
1868
  commandArgs(command, []);
1702
- if (!this.app.getModelCapabilities || this.app.modelCapabilitiesAvailable === false) throw new UiError(400, "\u6A21\u578B\u80FD\u529B\u67E5\u8BE2\u4E0D\u53EF\u7528\u3002");
1869
+ if (!this.app.getModelCapabilities || this.app.modelCapabilitiesAvailable === false)
1870
+ throw new UiError(400, "\u6A21\u578B\u80FD\u529B\u67E5\u8BE2\u4E0D\u53EF\u7528\u3002");
1703
1871
  await this.app.getModelCapabilities(void 0, true);
1704
1872
  this.changed();
1705
1873
  } else if (command.name === "model.switch") {
@@ -1713,8 +1881,10 @@ ${request.params.message}`,
1713
1881
  } else throw new UiError(400, "\u4E0D\u652F\u6301\u7684\u64CD\u4F5C\u3002");
1714
1882
  return { selectedId: this.app.sessionId };
1715
1883
  } catch (error) {
1716
- if (error instanceof GitWorkspaceConflictError || error instanceof MaybeCodeUsageError) throw new UiError(409, error.message);
1717
- if (error instanceof GitCheckpointError) throw new UiError(409, "Git checkpoint \u4FDD\u5B58\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u9879\u76EE Git \u914D\u7F6E\u4E0E Hooks\u3002");
1884
+ if (error instanceof GitWorkspaceConflictError || error instanceof MaybeCodeUsageError)
1885
+ throw new UiError(409, error.message);
1886
+ if (error instanceof GitCheckpointError)
1887
+ throw new UiError(409, "Git checkpoint \u4FDD\u5B58\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u9879\u76EE Git \u914D\u7F6E\u4E0E Hooks\u3002");
1718
1888
  throw error;
1719
1889
  } finally {
1720
1890
  this.busy = false;
@@ -1728,33 +1898,68 @@ ${request.params.message}`,
1728
1898
  else if (action === "model.switch") await this.app.switchModel(value);
1729
1899
  else if (action === "effort.set") await this.app.setReasoningEffort(value === "default" ? void 0 : value);
1730
1900
  else if (["session.resume", "session.rename", "session.delete"].includes(action)) {
1731
- if (action === "session.delete" && value === this.app.sessionId) throw new UiError(409, "\u65E0\u6CD5\u5220\u9664\u5F53\u524D\u4F1A\u8BDD\uFF0C\u8BF7\u5148\u5207\u6362\u5230\u5176\u5B83\u4F1A\u8BDD\u3002");
1732
- if (!(await this.app.listSessions()).some((session) => session.id === value)) throw new UiError(404, "\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u5F53\u524D\u5DE5\u4F5C\u533A\u3002");
1901
+ if (action === "session.delete" && value === this.app.sessionId)
1902
+ throw new UiError(409, "\u65E0\u6CD5\u5220\u9664\u5F53\u524D\u4F1A\u8BDD\uFF0C\u8BF7\u5148\u5207\u6362\u5230\u5176\u5B83\u4F1A\u8BDD\u3002");
1903
+ if (!(await this.app.listSessions()).some((session) => session.id === value))
1904
+ throw new UiError(404, "\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u5F53\u524D\u5DE5\u4F5C\u533A\u3002");
1733
1905
  if (action === "session.resume") await this.app.resumeSession(value);
1734
1906
  else if (action === "session.rename") {
1735
1907
  if (!title?.trim() || title.length > 160) throw new UiError(400, "\u8BF7\u8F93\u5165\u4E0D\u8D85\u8FC7 160 \u4E2A\u5B57\u7B26\u7684\u540D\u79F0\u3002");
1736
1908
  await this.app.renameSession(value, title);
1737
1909
  } else await this.app.deleteSession(value);
1738
1910
  } else throw new UiError(400, "\u64CD\u4F5C\u540D\u79F0\u65E0\u6548\u3002");
1739
- const result = await executeMaybeCodeSlashCommand(action?.startsWith("session.") ? "/resume" : action?.startsWith("model.") ? "/model" : "/effort", this.app);
1911
+ const result = await executeMaybeCodeSlashCommand(
1912
+ action?.startsWith("session.") ? "/resume" : action?.startsWith("model.") ? "/model" : "/effort",
1913
+ this.app
1914
+ );
1740
1915
  return this.present(result);
1741
1916
  }
1742
1917
  async present(result) {
1743
- const output = /* @__PURE__ */ __name((title, text, actions) => ({ selectedId: this.app.sessionId, output: { title, text, ...actions ? { actions } : {} } }), "output");
1744
- const action = /* @__PURE__ */ __name((label, name, value) => ({ label, command: "console.action", args: { action: name, value } }), "action");
1918
+ const output = /* @__PURE__ */ __name((title, text, actions) => ({
1919
+ selectedId: this.app.sessionId,
1920
+ output: { title, text, ...actions ? { actions } : {} }
1921
+ }), "output");
1922
+ const action = /* @__PURE__ */ __name((label, name, value) => ({
1923
+ label,
1924
+ command: "console.action",
1925
+ args: { action: name, value }
1926
+ }), "action");
1745
1927
  switch (result.type) {
1746
1928
  case "fork.selection.requested":
1747
- return output("Session \u5206\u652F", "\u9009\u62E9\u5B8C\u6574\u56DE\u590D\u548C\u5DE5\u4F5C\u533A\u65B9\u5F0F\u3002", result.points.filter((point) => point.available).flatMap((point) => [
1748
- { label: `${point.userPreview} \xB7 \u5F53\u524D\u5DE5\u4F5C\u533A`, command: "session.fork", args: { pointId: point.id, mode: "current" } },
1749
- ...point.worktreeAvailable ? [{ label: `${point.userPreview} \xB7 \u65B0\u5EFA worktree`, command: "session.fork", args: { pointId: point.id, mode: "worktree" } }] : []
1750
- ]));
1929
+ return output(
1930
+ "Session \u5206\u652F",
1931
+ "\u9009\u62E9\u5B8C\u6574\u56DE\u590D\u548C\u5DE5\u4F5C\u533A\u65B9\u5F0F\u3002",
1932
+ result.points.filter((point) => point.available).flatMap((point) => [
1933
+ {
1934
+ label: `${point.userPreview} \xB7 \u5F53\u524D\u5DE5\u4F5C\u533A`,
1935
+ command: "session.fork",
1936
+ args: { pointId: point.id, mode: "current" }
1937
+ },
1938
+ ...point.worktreeAvailable ? [
1939
+ {
1940
+ label: `${point.userPreview} \xB7 \u65B0\u5EFA worktree`,
1941
+ command: "session.fork",
1942
+ args: { pointId: point.id, mode: "worktree" }
1943
+ }
1944
+ ] : []
1945
+ ])
1946
+ );
1751
1947
  case "changes.selection.requested":
1752
1948
  return { diff: result.diff };
1753
1949
  case "worktrees.display":
1754
- return output("worktrees", result.worktrees.map((tree) => `${tree.branch} \xB7 ${tree.path}`).join("\n"), result.worktrees.flatMap((tree) => [
1755
- { label: `\u6253\u5F00 ${tree.branch}`, command: "worktree.open", args: { id: tree.id } },
1756
- { label: `\u5220\u9664 ${tree.branch}`, command: "worktree.delete", args: { id: tree.id }, confirm: `\u5220\u9664\u5DE5\u4F5C\u533A ${tree.path}\uFF1F` }
1757
- ]));
1950
+ return output(
1951
+ "worktrees",
1952
+ result.worktrees.map((tree) => `${tree.branch} \xB7 ${tree.path}`).join("\n"),
1953
+ result.worktrees.flatMap((tree) => [
1954
+ { label: `\u6253\u5F00 ${tree.branch}`, command: "worktree.open", args: { id: tree.id } },
1955
+ {
1956
+ label: `\u5220\u9664 ${tree.branch}`,
1957
+ command: "worktree.delete",
1958
+ args: { id: tree.id },
1959
+ confirm: `\u5220\u9664\u5DE5\u4F5C\u533A ${tree.path}\uFF1F`
1960
+ }
1961
+ ])
1962
+ );
1758
1963
  case "exit":
1759
1964
  return { disconnect: true };
1760
1965
  case "web.requested":
@@ -1771,19 +1976,28 @@ ${request.params.message}`,
1771
1976
  case "mcp.display":
1772
1977
  return output("\u547D\u4EE4\u7ED3\u679C", result.text);
1773
1978
  case "help":
1774
- return output("\u547D\u4EE4\u5E2E\u52A9", result.commands.map((item) => `${item.usage} \u2014 ${item.description}`).join("\n") + "\n/details \u2014 \u5C55\u5F00\u6216\u6536\u8D77\u5DE5\u5177\u8BE6\u60C5\n/thinking \u2014 \u663E\u793A\u6216\u9690\u85CF\u601D\u8003\u8FC7\u7A0B");
1979
+ return output(
1980
+ "\u547D\u4EE4\u5E2E\u52A9",
1981
+ result.commands.map((item) => `${item.usage} \u2014 ${item.description}`).join("\n") + "\n/details \u2014 \u5C55\u5F00\u6216\u6536\u8D77\u5DE5\u5177\u8BE6\u60C5\n/thinking \u2014 \u663E\u793A\u6216\u9690\u85CF\u601D\u8003\u8FC7\u7A0B"
1982
+ );
1775
1983
  case "instructions":
1776
1984
  return output("\u5F53\u524D\u6307\u4EE4", result.instructions.effective);
1777
1985
  case "status":
1778
- return output("\u8FD0\u884C\u72B6\u6001", `Session: ${this.app.sessionId}
1986
+ return output(
1987
+ "\u8FD0\u884C\u72B6\u6001",
1988
+ `Session: ${this.app.sessionId}
1779
1989
  Workspace: ${this.app.workspace}
1780
- Model: ${this.app.modelInfo?.model ?? "\u672A\u77E5"}
1990
+ Model: ${this.app.application.modelInfo?.model ?? "\u672A\u77E5"}
1781
1991
  Effort: ${(await this.app.getReasoningEffort()).effectiveEffort ?? "\u9ED8\u8BA4"}
1782
- ${JSON.stringify(result.inspection, null, 2) ?? ""}`);
1992
+ ${JSON.stringify(result.inspection, null, 2) ?? ""}`
1993
+ );
1783
1994
  case "context":
1784
1995
  return output("\u4E0A\u4E0B\u6587", JSON.stringify(result.inspection, null, 2) ?? "\u5F53\u524D\u6A21\u578B\u6CA1\u6709\u63D0\u4F9B\u4E0A\u4E0B\u6587\u7528\u91CF\u3002");
1785
1996
  case "compacted":
1786
- return output("\u4E0A\u4E0B\u6587\u538B\u7F29", `${result.result.strategy}: ${result.result.before.messageCount} \u2192 ${result.result.after.messageCount}`);
1997
+ return output(
1998
+ "\u4E0A\u4E0B\u6587\u538B\u7F29",
1999
+ `${result.result.strategy}: ${result.result.before.messageCount} \u2192 ${result.result.after.messageCount}`
2000
+ );
1787
2001
  case "mcp.status":
1788
2002
  return output("MCP", formatMaybeCodeMcpStatus(result.servers));
1789
2003
  case "session.created":
@@ -1791,18 +2005,43 @@ ${JSON.stringify(result.inspection, null, 2) ?? ""}`);
1791
2005
  case "model.switched":
1792
2006
  return { selectedId: this.app.sessionId };
1793
2007
  case "session.selection.requested":
1794
- return output("\u4F1A\u8BDD\u7BA1\u7406", "\u9009\u62E9\u4F1A\u8BDD\u64CD\u4F5C\u3002", result.sessions.flatMap((session) => [
1795
- action(`\u7EE7\u7EED \xB7 ${session.title ?? session.id}`, "session.resume", session.id),
1796
- { ...action(`\u91CD\u547D\u540D \xB7 ${session.title ?? session.id}`, "session.rename", session.id), input: { name: "title", label: "\u4F1A\u8BDD\u540D\u79F0", value: session.title ?? "" } },
1797
- ...session.id === this.app.sessionId ? [] : [{ ...action(`\u5220\u9664 \xB7 ${session.title ?? session.id}`, "session.delete", session.id), confirm: `\u786E\u8BA4\u5220\u9664\u4F1A\u8BDD ${session.title ?? session.id} \u53CA\u5176\u5386\u53F2\u8BB0\u5F55\uFF1F` }]
1798
- ]));
2008
+ return output(
2009
+ "\u4F1A\u8BDD\u7BA1\u7406",
2010
+ "\u9009\u62E9\u4F1A\u8BDD\u64CD\u4F5C\u3002",
2011
+ result.sessions.flatMap((session) => [
2012
+ action(`\u7EE7\u7EED \xB7 ${session.title ?? session.id}`, "session.resume", session.id),
2013
+ {
2014
+ ...action(`\u91CD\u547D\u540D \xB7 ${session.title ?? session.id}`, "session.rename", session.id),
2015
+ input: { name: "title", label: "\u4F1A\u8BDD\u540D\u79F0", value: session.title ?? "" }
2016
+ },
2017
+ ...session.id === this.app.sessionId ? [] : [
2018
+ {
2019
+ ...action(`\u5220\u9664 \xB7 ${session.title ?? session.id}`, "session.delete", session.id),
2020
+ confirm: `\u786E\u8BA4\u5220\u9664\u4F1A\u8BDD ${session.title ?? session.id} \u53CA\u5176\u5386\u53F2\u8BB0\u5F55\uFF1F`
2021
+ }
2022
+ ]
2023
+ ])
2024
+ );
1799
2025
  case "model.selection.requested":
1800
- return output("\u6A21\u578B\u914D\u7F6E", `\u5F53\u524D\uFF1A${this.app.modelInfo?.profile ?? "\u672A\u77E5"}`, result.models.flatMap((model) => [action(`\u5207\u6362 \xB7 ${model.name}`, "model.switch", model.name), action(`${model.isDefault ? "\u5F53\u524D\u9ED8\u8BA4" : "\u8BBE\u4E3A\u9ED8\u8BA4"} \xB7 ${model.name}`, "model.default", model.name)]));
2026
+ return output(
2027
+ "\u6A21\u578B\u914D\u7F6E",
2028
+ `\u5F53\u524D\uFF1A${this.app.application.modelInfo?.profile ?? "\u672A\u77E5"}`,
2029
+ result.models.flatMap((model) => [
2030
+ action(`\u5207\u6362 \xB7 ${model.name}`, "model.switch", model.name),
2031
+ action(`${model.isDefault ? "\u5F53\u524D\u9ED8\u8BA4" : "\u8BBE\u4E3A\u9ED8\u8BA4"} \xB7 ${model.name}`, "model.default", model.name)
2032
+ ])
2033
+ );
1801
2034
  case "effort.selection.requested":
1802
2035
  case "effort.changed":
1803
- return output("Reasoning effort", `\u5F53\u524D\uFF1A${result.state.effectiveEffort ?? "\u9ED8\u8BA4"}
2036
+ return output(
2037
+ "Reasoning effort",
2038
+ `\u5F53\u524D\uFF1A${result.state.effectiveEffort ?? "\u9ED8\u8BA4"}
1804
2039
  Provider \u9ED8\u8BA4\uFF1A${result.state.defaultEffort ?? "\u672A\u63D0\u4F9B"}
1805
- \u80FD\u529B\u72B6\u6001\uFF1A${result.state.status}`, result.state.status === "known" ? ["default", ...result.state.efforts].map((effort) => action(effort === "default" ? "\u6062\u590D\u914D\u7F6E\u9ED8\u8BA4" : effort, "effort.set", effort)) : []);
2040
+ \u80FD\u529B\u72B6\u6001\uFF1A${result.state.status}`,
2041
+ result.state.status === "known" ? ["default", ...result.state.efforts].map(
2042
+ (effort) => action(effort === "default" ? "\u6062\u590D\u914D\u7F6E\u9ED8\u8BA4" : effort, "effort.set", effort)
2043
+ ) : []
2044
+ );
1806
2045
  case "skill.run-started":
1807
2046
  case "mcp.run-started":
1808
2047
  case "retry.started":
@@ -1820,12 +2059,22 @@ function createMaybeCodeWebHost(app, options = {}) {
1820
2059
  const host = new ApplicationUiHost(app, {
1821
2060
  ...options,
1822
2061
  permissionActor: /* @__PURE__ */ __name(() => `local:${userInfo2().username}`, "permissionActor"),
1823
- ...app.persistentRulesEnabled !== false && app.listPermissionRules && app.revokePermissionRule ? { permissionRules: {
1824
- list: /* @__PURE__ */ __name(() => app.listPermissionRules(), "list"),
1825
- revoke: /* @__PURE__ */ __name((id) => app.revokePermissionRule(id), "revoke"),
1826
- ...app.createPermissionRuleFrom ? { create: /* @__PURE__ */ __name((id, decision) => app.createPermissionRuleFrom(id, { decision, createdBy: `local:${userInfo2().username}` }), "create") } : {}
1827
- } } : {},
1828
- product: { id: "maybecode", title: "MaybeCode", resourceKind: "session", subtitle: "\u56F4\u7ED5\u4F60\u7684\u4EE3\u7801\u5DE5\u4F5C\u3002\u67E5\u770B\u5DE5\u5177\u6267\u884C\uFF0C\u5728\u5173\u952E\u64CD\u4F5C\u524D\u786E\u8BA4\uFF0C\u8BA9\u6BCF\u4E00\u6B65\u90FD\u6709\u8FF9\u53EF\u5FAA\u3002", suggestions: ["\u4ECB\u7ECD\u8FD9\u4E2A\u9879\u76EE\u7684\u7ED3\u6784", "\u68C0\u67E5\u5F53\u524D\u5DE5\u4F5C\u533A\u7684\u6539\u52A8", "\u5E2E\u6211\u5B9A\u4F4D\u4E00\u4E2A\u95EE\u9898"] },
2062
+ ...app.application.persistentRulesEnabled && app.listPermissionRules && app.revokePermissionRule ? {
2063
+ permissionRules: {
2064
+ list: /* @__PURE__ */ __name(() => app.listPermissionRules(), "list"),
2065
+ revoke: /* @__PURE__ */ __name((id) => app.revokePermissionRule(id), "revoke"),
2066
+ ...app.createPermissionRuleFrom ? {
2067
+ create: /* @__PURE__ */ __name((id, decision) => app.createPermissionRuleFrom(id, { decision, createdBy: `local:${userInfo2().username}` }), "create")
2068
+ } : {}
2069
+ }
2070
+ } : {},
2071
+ product: {
2072
+ id: "maybecode",
2073
+ title: "MaybeCode",
2074
+ resourceKind: "session",
2075
+ subtitle: "\u56F4\u7ED5\u4F60\u7684\u4EE3\u7801\u5DE5\u4F5C\u3002\u67E5\u770B\u5DE5\u5177\u6267\u884C\uFF0C\u5728\u5173\u952E\u64CD\u4F5C\u524D\u786E\u8BA4\uFF0C\u8BA9\u6BCF\u4E00\u6B65\u90FD\u6709\u8FF9\u53EF\u5FAA\u3002",
2076
+ suggestions: ["\u4ECB\u7ECD\u8FD9\u4E2A\u9879\u76EE\u7684\u7ED3\u6784", "\u68C0\u67E5\u5F53\u524D\u5DE5\u4F5C\u533A\u7684\u6539\u52A8", "\u5E2E\u6211\u5B9A\u4F4D\u4E00\u4E2A\u95EE\u9898"]
2077
+ },
1829
2078
  commands: [
1830
2079
  "model.switch",
1831
2080
  "effort.set",
@@ -1853,25 +2102,78 @@ function createMaybeCodeWebHost(app, options = {}) {
1853
2102
  choices: /* @__PURE__ */ __name(async () => {
1854
2103
  const models = await app.listModels();
1855
2104
  const effort = await app.getReasoningEffort();
1856
- const resetEffort = models.find((model) => model.name === app.modelInfo?.profile)?.reasoningEffort ?? effort.defaultEffort;
2105
+ const resetEffort = models.find((model) => model.name === app.application.modelInfo?.profile)?.reasoningEffort ?? effort.defaultEffort;
1857
2106
  return [
1858
- ...models.length ? [{ command: "model.switch", label: "\u6A21\u578B\u914D\u7F6E", value: app.modelInfo?.profile ?? models[0].name, options: models.map((m) => ({ value: m.name, label: m.name })) }] : [],
1859
- ...effort.status === "known" ? [{ command: "effort.set", label: "Reasoning effort", value: effort.overridden ? effort.effectiveEffort ?? "default" : "default", options: [{ value: "default", label: `\u914D\u7F6E\u9ED8\u8BA4 (${resetEffort ?? "Provider"})` }, ...effort.efforts.map((value) => ({ value, label: value }))] }] : [],
1860
- { command: "permission.set", label: "Permissions", value: app.permissionMode, options: [
1861
- { value: "default", label: "Default" },
1862
- { value: "yolo", label: "YOLO \xB7 Auto-approve" }
1863
- ] }
2107
+ ...models.length ? [
2108
+ {
2109
+ command: "model.switch",
2110
+ label: "\u6A21\u578B\u914D\u7F6E",
2111
+ value: app.application.modelInfo?.profile ?? models[0].name,
2112
+ options: models.map((m) => ({ value: m.name, label: m.name }))
2113
+ }
2114
+ ] : [],
2115
+ ...effort.status === "known" ? [
2116
+ {
2117
+ command: "effort.set",
2118
+ label: "Reasoning effort",
2119
+ value: effort.overridden ? effort.effectiveEffort ?? "default" : "default",
2120
+ options: [
2121
+ { value: "default", label: `\u914D\u7F6E\u9ED8\u8BA4 (${resetEffort ?? "Provider"})` },
2122
+ ...effort.efforts.map((value) => ({ value, label: value }))
2123
+ ]
2124
+ }
2125
+ ] : [],
2126
+ {
2127
+ command: "permission.set",
2128
+ label: "Permissions",
2129
+ value: app.permissionMode,
2130
+ options: [
2131
+ { value: "default", label: "Default" },
2132
+ { value: "yolo", label: "YOLO \xB7 Auto-approve" }
2133
+ ]
2134
+ }
1864
2135
  ];
1865
2136
  }, "choices"),
1866
2137
  panels: /* @__PURE__ */ __name(async () => [
1867
- { id: "permissions", title: "Permissions", fields: [{ label: "Mode", value: app.permissionMode === "yolo" ? "YOLO \xB7 Auto-approve" : "Default" }] },
1868
- { id: "model", title: "\u6A21\u578B", fields: [{ label: "\u5F53\u524D\u6A21\u578B", value: app.modelInfo?.model ?? "\u672A\u77E5" }, { label: "Provider", value: app.modelInfo?.provider ?? "\u672A\u77E5" }] },
1869
- ...app.getModelCapabilities && app.modelCapabilitiesAvailable !== false ? [{ id: "model-capabilities", title: "\u6A21\u578B\u80FD\u529B", fields: capabilityFields(await app.getModelCapabilities()), actions: [{ label: "\u5237\u65B0\u80FD\u529B\u4FE1\u606F", command: "model.capabilities.refresh", args: {} }] }] : [],
2138
+ {
2139
+ id: "permissions",
2140
+ title: "Permissions",
2141
+ fields: [{ label: "Mode", value: app.permissionMode === "yolo" ? "YOLO \xB7 Auto-approve" : "Default" }]
2142
+ },
2143
+ {
2144
+ id: "model",
2145
+ title: "\u6A21\u578B",
2146
+ fields: [
2147
+ { label: "\u5F53\u524D\u6A21\u578B", value: app.application.modelInfo?.model ?? "\u672A\u77E5" },
2148
+ { label: "Provider", value: app.application.modelInfo?.provider ?? "\u672A\u77E5" }
2149
+ ]
2150
+ },
2151
+ ...app.getModelCapabilities && app.modelCapabilitiesAvailable !== false ? [
2152
+ {
2153
+ id: "model-capabilities",
2154
+ title: "\u6A21\u578B\u80FD\u529B",
2155
+ fields: capabilityFields(await app.getModelCapabilities()),
2156
+ actions: [{ label: "\u5237\u65B0\u80FD\u529B\u4FE1\u606F", command: "model.capabilities.refresh", args: {} }]
2157
+ }
2158
+ ] : [],
1870
2159
  ...app.getTelemetry ? [createTelemetryPanel(app.getTelemetry({ limit: 40 }))] : [],
1871
2160
  { id: "subagents", title: "\u5B50 Agent", ...subagentPanel(app) },
1872
- { id: "recovery", title: "\u6062\u590D", fields: [{ label: "\u5F85\u5904\u7406\u9879", value: String(app.listRecoveries?.().length ?? 0) }, { label: "\u5904\u7406\u65B9\u5F0F", value: "\u4F7F\u7528 /recovery \u67E5\u770B\u8BC1\u636E\u5E76\u8BB0\u5F55\u6838\u67E5\u7ED3\u679C\u3002" }] },
1873
- ...app.getGoal ? [{ id: "goal", title: "\u76EE\u6807", fields: [{ label: "\u72B6\u6001", value: formatGoal(app.getGoal()) }] }] : [],
1874
- ...options.terminal ? [{ id: "terminal", title: "\u7EC8\u7AEF", fields: [{ label: "\u5171\u4EAB\u4F1A\u8BDD", value: "MCP \u4EA4\u4E92\u53EF\u4EE5\u5728\u7EC8\u7AEF\u6216\u5F53\u524D\u9875\u9762\u5904\u7406\u3002\u9000\u51FA\u5BBF\u4E3B\u4F1A\u5173\u95ED Web \u670D\u52A1\u3002" }] }] : []
2161
+ {
2162
+ id: "recovery",
2163
+ title: "\u6062\u590D",
2164
+ fields: [
2165
+ { label: "\u5F85\u5904\u7406\u9879", value: String(app.listRecoveries().length) },
2166
+ { label: "\u5904\u7406\u65B9\u5F0F", value: "\u4F7F\u7528 /recovery \u67E5\u770B\u8BC1\u636E\u5E76\u8BB0\u5F55\u6838\u67E5\u7ED3\u679C\u3002" }
2167
+ ]
2168
+ },
2169
+ { id: "goal", title: "\u76EE\u6807", fields: [{ label: "\u72B6\u6001", value: formatGoal(app.application.getGoal()) }] },
2170
+ ...options.terminal ? [
2171
+ {
2172
+ id: "terminal",
2173
+ title: "\u7EC8\u7AEF",
2174
+ fields: [{ label: "\u5171\u4EAB\u4F1A\u8BDD", value: "MCP \u4EA4\u4E92\u53EF\u4EE5\u5728\u7EC8\u7AEF\u6216\u5F53\u524D\u9875\u9762\u5904\u7406\u3002\u9000\u51FA\u5BBF\u4E3B\u4F1A\u5173\u95ED Web \u670D\u52A1\u3002" }]
2175
+ }
2176
+ ] : []
1875
2177
  ], "panels"),
1876
2178
  execute: /* @__PURE__ */ __name((command) => commands.execute(command), "execute")
1877
2179
  });
@@ -1879,28 +2181,45 @@ function createMaybeCodeWebHost(app, options = {}) {
1879
2181
  }
1880
2182
  __name(createMaybeCodeWebHost, "createMaybeCodeWebHost");
1881
2183
  function capabilityFields(capabilities) {
1882
- const names = { "input.text": "\u6587\u672C\u8F93\u5165", "input.image": "\u56FE\u7247\u8F93\u5165", "input.audio": "\u97F3\u9891\u8F93\u5165", "input.file": "\u6587\u4EF6\u8F93\u5165", "output.text": "\u6587\u672C\u8F93\u51FA", "output.image": "\u56FE\u7247\u8F93\u51FA", "output.audio": "\u97F3\u9891\u8F93\u51FA", tools: "\u5DE5\u5177\u8C03\u7528", "structuredOutput.json": "JSON \u8F93\u51FA", "structuredOutput.jsonSchema": "JSON Schema", contextCompaction: "Context \u538B\u7F29" };
2184
+ const names = {
2185
+ "input.text": "\u6587\u672C\u8F93\u5165",
2186
+ "input.image": "\u56FE\u7247\u8F93\u5165",
2187
+ "input.audio": "\u97F3\u9891\u8F93\u5165",
2188
+ "input.file": "\u6587\u4EF6\u8F93\u5165",
2189
+ "output.text": "\u6587\u672C\u8F93\u51FA",
2190
+ "output.image": "\u56FE\u7247\u8F93\u51FA",
2191
+ "output.audio": "\u97F3\u9891\u8F93\u51FA",
2192
+ tools: "\u5DE5\u5177\u8C03\u7528",
2193
+ "structuredOutput.json": "JSON \u8F93\u51FA",
2194
+ "structuredOutput.jsonSchema": "JSON Schema",
2195
+ contextCompaction: "Context \u538B\u7F29"
2196
+ };
1883
2197
  return [
1884
2198
  ...Object.entries(capabilities.fields ?? {}).slice(0, 40).map(([key, field]) => ({
1885
2199
  label: names[key] ?? key,
1886
2200
  value: field.status === "unknown" ? "\u80FD\u529B\u672A\u77E5" : field.status === "unsupported" ? `\u4E0D\u652F\u6301 \xB7 ${field.source}` : `${JSON.stringify(field.value)} \xB7 ${field.source}`
1887
2201
  })),
1888
2202
  ...capabilities.version === void 0 ? [] : [{ label: "\u80FD\u529B\u7248\u672C", value: capabilities.version }],
1889
- ...capabilities.diagnostics?.map((item) => ({ label: item.discovery, value: `${item.code} \xB7 ${new Date(item.observedAt).toISOString()}` })) ?? []
2203
+ ...capabilities.diagnostics?.map((item) => ({
2204
+ label: item.discovery,
2205
+ value: `${item.code} \xB7 ${new Date(item.observedAt).toISOString()}`
2206
+ })) ?? []
1890
2207
  ];
1891
2208
  }
1892
2209
  __name(capabilityFields, "capabilityFields");
1893
2210
  function subagentPanel(app) {
1894
- const state = app.getDelegationState?.();
1895
- const requests = app.listDelegationRequests?.() ?? [];
2211
+ const state = app.application.getDelegationState();
2212
+ const requests = app.application.listDelegationRequests();
1896
2213
  if (state === void 0 && requests.length === 0) {
1897
2214
  return { fields: [{ label: "\u72B6\u6001", value: "\u672C\u6B21\u4F1A\u8BDD\u8FD8\u6CA1\u6709\u5B50 Agent \u8BF7\u6C42\u3002" }] };
1898
2215
  }
1899
2216
  const tasks = state?.tasks ?? requests[0]?.tasks ?? [];
1900
- const fields = [{
1901
- label: "\u5F53\u524D\u8BF7\u6C42",
1902
- value: state === void 0 ? "\u7A7A\u95F2" : `${state.status} \xB7 ${state.requestId}`
1903
- }];
2217
+ const fields = [
2218
+ {
2219
+ label: "\u5F53\u524D\u8BF7\u6C42",
2220
+ value: state === void 0 ? "\u7A7A\u95F2" : `${state.status} \xB7 ${state.requestId}`
2221
+ }
2222
+ ];
1904
2223
  for (const task of [...tasks].sort((left, right) => left.depth - right.depth || left.id.localeCompare(right.id)).slice(0, 12)) {
1905
2224
  const detail = task.detail ?? (task.output === void 0 ? "" : task.output.replace(/\s+/gu, " ").slice(0, 80));
1906
2225
  fields.push({
@@ -1914,7 +2233,9 @@ function subagentPanel(app) {
1914
2233
  value: `${state.budget.modelCalls}/${state.budget.maxModelCalls} \u6B21\u6A21\u578B\u8C03\u7528 \xB7 ${state.budget.totalTokens} tokens${state.budget.usageComplete ? "" : "\uFF08\u542B\u9884\u7559\u503C\u8BA1\u8D26\uFF09"}`
1915
2234
  });
1916
2235
  }
1917
- const pending2 = (app.listDelegationRequests?.() ?? []).flatMap((request) => request.tasks.filter((task) => task.status === "recovery-required").map((task) => task.id));
2236
+ const pending2 = requests.flatMap(
2237
+ (request) => request.tasks.filter((task) => task.status === "recovery-required").map((task) => task.id)
2238
+ );
1918
2239
  fields.push({
1919
2240
  label: "\u67E5\u770B\u4E0E\u6062\u590D",
1920
2241
  value: pending2.length === 0 ? "/delegations \u67E5\u770B\u4EFB\u52A1\u6811\uFF0C/delegations tools <\u4EFB\u52A1> \u67E5\u770B\u5DE5\u5177\u8BB0\u5F55" : `/delegations resolve <\u4EFB\u52A1> <failed|cancelled> <\u6838\u67E5\u7ED3\u8BBA>\uFF08\u5F85\u6838\u5BF9\uFF1A${pending2.join(", ")}\uFF09`
@@ -1924,7 +2245,7 @@ function subagentPanel(app) {
1924
2245
  __name(subagentPanel, "subagentPanel");
1925
2246
  async function startMaybeCodeWebServer(host, options) {
1926
2247
  try {
1927
- const { startMaybeCodeWebServer: startServer } = await import("./web-server-FOMNPY7Q.js");
2248
+ const { startMaybeCodeWebServer: startServer } = await import("./web-server-SXMH6FGA.js");
1928
2249
  return await startServer(host, options);
1929
2250
  } catch (error) {
1930
2251
  await host.close();
@@ -1942,21 +2263,29 @@ async function runMaybeCodeWebUI(app, options) {
1942
2263
  await app.close();
1943
2264
  throw new Error("Set MAYBECODE_CONTROL_TOKEN (32..256 printable ASCII characters) before starting --ui web.");
1944
2265
  }
1945
- const server = await startMaybeCodeWebUI(app, { token, ...options.port === void 0 ? {} : { port: options.port } });
1946
- options.write(`MaybeCode Web UI: ${server.url}
2266
+ const server = await startMaybeCodeWebUI(app, omitUndefined({ token, port: options.port }));
2267
+ options.write(
2268
+ `MaybeCode Web UI: ${server.url}
1947
2269
  Enter MAYBECODE_CONTROL_TOKEN in the connection dialog. Closing a browser tab does not stop the agent. Ctrl+C stops the host.
1948
- `);
2270
+ `
2271
+ );
2272
+ let closing;
2273
+ let closingFailure;
1949
2274
  const stop = /* @__PURE__ */ __name(() => {
1950
- void server.close();
2275
+ closing ??= server.close().catch((error) => {
2276
+ closingFailure = error;
2277
+ });
1951
2278
  }, "stop");
1952
2279
  process.once("SIGINT", stop);
1953
2280
  process.once("SIGTERM", stop);
1954
2281
  try {
1955
2282
  await server.closed;
1956
- await server.close();
1957
2283
  } finally {
1958
2284
  process.removeListener("SIGINT", stop);
1959
2285
  process.removeListener("SIGTERM", stop);
2286
+ stop();
2287
+ await closing;
2288
+ if (closingFailure !== void 0) throw closingFailure;
1960
2289
  }
1961
2290
  }
1962
2291
  __name(runMaybeCodeWebUI, "runMaybeCodeWebUI");
@@ -1975,4 +2304,4 @@ export {
1975
2304
  startMaybeCodeWebUI,
1976
2305
  runMaybeCodeWebUI
1977
2306
  };
1978
- //# sourceMappingURL=chunk-7ISOHFS7.js.map
2307
+ //# sourceMappingURL=chunk-WMSG5ZTR.js.map