@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,11 +1,14 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  UiError
4
- } from "./chunk-HOU5ITUK.js";
4
+ } from "./chunk-XTEMRAQW.js";
5
5
  import {
6
6
  __name
7
7
  } from "./chunk-E732GDOI.js";
8
8
 
9
+ // apps/maybecode/src/web-server.ts
10
+ import { omitUndefined } from "@sortedyuan/may/core";
11
+
9
12
  // packages/ui/client/dist/server.js
10
13
  import { timingSafeEqual } from "node:crypto";
11
14
 
@@ -70,7 +73,11 @@ function createUiRouter(host, exit) {
70
73
  if (!selected || selected.length > 256 || !/^[a-f0-9]{64}$/.test(id))
71
74
  throw new UiError(400, "\u56FE\u7247\u53C2\u6570\u65E0\u6548\u3002");
72
75
  const media = await host.media(selected, id);
73
- res.writeHead(200, { "content-type": media.mediaType, "content-length": media.data.byteLength, "content-disposition": `inline; filename="${id}.${media.mediaType.slice(6)}"` });
76
+ res.writeHead(200, {
77
+ "content-type": media.mediaType,
78
+ "content-length": media.data.byteLength,
79
+ "content-disposition": `inline; filename="${id}.${media.mediaType.slice(6)}"`
80
+ });
74
81
  res.end(media.data);
75
82
  } else if (req.method === "GET" && url.pathname === "/api/ui/snapshot") {
76
83
  const selected = url.searchParams.get("selected") ?? void 0;
@@ -96,7 +103,7 @@ function createUiRouter(host, exit) {
96
103
  else if (url.pathname.endsWith("/field") && selected && host.field) {
97
104
  const blockId = url.searchParams.get("block") ?? "", field = url.searchParams.get("field");
98
105
  const offset = Number(url.searchParams.get("offset") ?? 0), version = url.searchParams.get("version");
99
- if (!blockId || blockId.length > 512 || !["input", "text", "reasoning", "diagnostic", "presentation"].includes(field) || !Number.isSafeInteger(offset) || offset < 0 || (version?.length ?? 0) > 128)
106
+ if (!blockId || blockId.length > 512 || !["input", "text", "reasoning", "diagnostic", "presentation", "request"].includes(field) || !Number.isSafeInteger(offset) || offset < 0 || (version?.length ?? 0) > 128)
100
107
  throw new UiError(400, "\u8BE6\u60C5\u53C2\u6570\u4E0D\u6B63\u786E\u3002");
101
108
  sendJson(res, 200, await host.field(selected, { blockId, field, offset, ...version ? { version } : {} }));
102
109
  } else
@@ -105,7 +112,11 @@ function createUiRouter(host, exit) {
105
112
  if (streams.size >= 16)
106
113
  throw new UiError(429, "\u8FDE\u63A5\u7A97\u53E3\u8FC7\u591A\u3002");
107
114
  streams.add(res);
108
- res.writeHead(200, { "content-type": "text/event-stream; charset=utf-8", "cache-control": "no-store", "x-accel-buffering": "no" });
115
+ res.writeHead(200, {
116
+ "content-type": "text/event-stream; charset=utf-8",
117
+ "cache-control": "no-store",
118
+ "x-accel-buffering": "no"
119
+ });
109
120
  res.write("event: invalidate\ndata: {}\n\n");
110
121
  let pending;
111
122
  const invalidate = /* @__PURE__ */ __name(() => {
@@ -130,7 +141,10 @@ function createUiRouter(host, exit) {
130
141
  const command = validateCommand(await readJson(req));
131
142
  if (command.hostId !== host.hostId)
132
143
  throw new UiError(409, "\u5BBF\u4E3B\u5DF2\u91CD\u542F\u3002\u8BF7\u68C0\u67E5\u6700\u65B0\u72B6\u6001\u540E\u91CD\u65B0\u64CD\u4F5C\u3002");
133
- const key = JSON.stringify({ ...command, args: Object.fromEntries(Object.entries(command.args).sort(([a], [b]) => a.localeCompare(b))) });
144
+ const key = JSON.stringify({
145
+ ...command,
146
+ args: Object.fromEntries(Object.entries(command.args).sort(([a], [b]) => a.localeCompare(b)))
147
+ });
134
148
  let receipt = receipts.get(command.requestId);
135
149
  if (receipt && receipt.key !== key)
136
150
  throw new UiError(409, "\u8BF7\u6C42 ID \u5DF2\u88AB\u5176\u5B83\u547D\u4EE4\u4F7F\u7528\u3002");
@@ -148,7 +162,9 @@ function createUiRouter(host, exit) {
148
162
  throw new UiError(404, "\u63A5\u53E3\u4E0D\u5B58\u5728\u3002");
149
163
  } catch (error) {
150
164
  if (!res.headersSent)
151
- sendJson(res, error instanceof UiError ? error.status : 400, { error: error instanceof UiError ? error.message : "\u64CD\u4F5C\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u5BBF\u4E3B\u65E5\u5FD7\u3001\u914D\u7F6E\u6216\u5F53\u524D\u72B6\u6001\u3002" });
165
+ sendJson(res, error instanceof UiError ? error.status : 400, {
166
+ error: error instanceof UiError ? error.message : "\u64CD\u4F5C\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u5BBF\u4E3B\u65E5\u5FD7\u3001\u914D\u7F6E\u6216\u5F53\u524D\u72B6\u6001\u3002"
167
+ });
152
168
  else
153
169
  res.destroy();
154
170
  }
@@ -172,7 +188,7 @@ async function startUiServer(options) {
172
188
  if (options.exit)
173
189
  options.exit();
174
190
  else
175
- void close();
191
+ close().catch(rejectClosed);
176
192
  });
177
193
  const login = options.browserLogin ? new BrowserLogin(options.token) : void 0;
178
194
  let origin = "";
@@ -230,21 +246,36 @@ async function startUiServer(options) {
230
246
  });
231
247
  origin = `http://127.0.0.1:${server.address().port}`;
232
248
  let closing;
233
- const closed = new Promise((resolve) => server.once("close", resolve));
249
+ let rejectClosed;
250
+ const closed = new Promise((resolve, reject) => {
251
+ rejectClosed = reject;
252
+ server.once("close", () => {
253
+ if (closing)
254
+ closing.then(resolve, reject);
255
+ else
256
+ resolve();
257
+ });
258
+ });
234
259
  const close = /* @__PURE__ */ __name(() => closing ??= (async () => {
235
260
  login?.clear();
236
261
  router.close();
237
262
  const stopped = new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve()));
238
263
  server.closeAllConnections();
239
- await options.close?.();
240
- await Promise.allSettled([...requests]);
241
- await stopped;
264
+ const results = await Promise.allSettled([Promise.resolve().then(() => options.close?.()), ...requests, stopped]);
265
+ const errors = results.filter((result) => result.status === "rejected").map((result) => result.reason);
266
+ if (errors.length)
267
+ throw new AggregateError(errors, "UI server shutdown failed");
242
268
  })(), "close");
243
- return { url: origin, closed, createLoginUrl: /* @__PURE__ */ __name(() => {
244
- if (!login || closing)
245
- throw new Error("\u5F53\u524D\u670D\u52A1\u4E0D\u63A5\u53D7\u6D4F\u89C8\u5668\u8FDE\u63A5\u51ED\u636E\u3002");
246
- return `${origin}/#may-connect=${login.issue()}`;
247
- }, "createLoginUrl"), close };
269
+ return {
270
+ url: origin,
271
+ closed,
272
+ createLoginUrl: /* @__PURE__ */ __name(() => {
273
+ if (!login || closing)
274
+ throw new Error("\u5F53\u524D\u670D\u52A1\u4E0D\u63A5\u53D7\u6D4F\u89C8\u5668\u8FDE\u63A5\u51ED\u636E\u3002");
275
+ return `${origin}/#may-connect=${login.issue()}`;
276
+ }, "createLoginUrl"),
277
+ close
278
+ };
248
279
  }
249
280
  __name(startUiServer, "startUiServer");
250
281
  function secureHeaders(res) {
@@ -302,12 +333,17 @@ __name(validateCommand, "validateCommand");
302
333
  import { webUiAssets } from "@sortedyuan/web-ui/assets";
303
334
  import { readFile } from "node:fs/promises";
304
335
  async function startMaybeCodeWebServer(host, options) {
305
- const extensionModule = await readFile(new URL("./web-extension.js", import.meta.resolve("@sortedyuan/maybecode")), "utf8");
336
+ const extensionModule = await readFile(
337
+ new URL("./web-extension.js", import.meta.resolve("@sortedyuan/maybecode")),
338
+ "utf8"
339
+ );
306
340
  const diffBundle = await readFile(new URL("./dist/diff.js", import.meta.resolve("diff/package.json")), "utf8");
307
341
  const diffEsm = `${diffBundle}
308
342
  export const { parsePatch } = globalThis.Diff;
309
343
  `;
310
- const assets = new Map(await webUiAssets("MaybeCode", "session", { extensionModule, ...options.browserLogin === void 0 ? {} : { browserLogin: options.browserLogin } }));
344
+ const assets = new Map(
345
+ await webUiAssets("MaybeCode", "session", omitUndefined({ extensionModule, browserLogin: options.browserLogin }))
346
+ );
311
347
  assets.set("/vendor-diff.js", { type: "text/javascript; charset=utf-8", body: diffEsm });
312
348
  return startUiServer({ host, assets, ...options, close: /* @__PURE__ */ __name(() => host.close(), "close") });
313
349
  }
@@ -315,4 +351,4 @@ __name(startMaybeCodeWebServer, "startMaybeCodeWebServer");
315
351
  export {
316
352
  startMaybeCodeWebServer
317
353
  };
318
- //# sourceMappingURL=web-server-FOMNPY7Q.js.map
354
+ //# sourceMappingURL=web-server-SXMH6FGA.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/web-server.ts", "../../../../packages/ui/client/src/server.ts", "../../../../packages/ui/client/src/browser-login.ts"],
4
+ "sourcesContent": ["import { omitUndefined } from \"@sortedyuan/may/core\";\nimport type { ApplicationUiHost } from \"@sortedyuan/ui-client/application\";\nimport { startUiServer } from \"@sortedyuan/ui-client/server\";\nimport { webUiAssets } from \"@sortedyuan/web-ui/assets\";\nimport { readFile } from \"node:fs/promises\";\n\nexport async function startMaybeCodeWebServer(\n host: ApplicationUiHost,\n options: { token: string; port?: number; browserLogin?: boolean; exit?: () => void },\n) {\n const extensionModule = await readFile(\n new URL(\"./web-extension.js\", import.meta.resolve(\"@sortedyuan/maybecode\")),\n \"utf8\",\n );\n const diffBundle = await readFile(new URL(\"./dist/diff.js\", import.meta.resolve(\"diff/package.json\")), \"utf8\");\n const diffEsm = `${diffBundle}\\nexport const { parsePatch } = globalThis.Diff;\\n`;\n const assets = new Map(\n await webUiAssets(\"MaybeCode\", \"session\", omitUndefined({ extensionModule, browserLogin: options.browserLogin })),\n );\n assets.set(\"/vendor-diff.js\", { type: \"text/javascript; charset=utf-8\", body: diffEsm });\n return startUiServer({ host, assets, ...options, close: () => host.close() });\n}\n", "import { timingSafeEqual } from \"node:crypto\";\nimport { BrowserLogin } from \"./browser-login.js\";\nexport { BrowserLogin } from \"./browser-login.js\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\nimport { UiError, type UiCommand, type UiHost, type UiReceipt, type UiField } from \"./protocol.js\";\n\n/** @experimental */\nexport type UiAssets = ReadonlyMap<string, { readonly type: string; readonly body: string }>;\n\n/**\n * Mount behind the host's authentication/origin checks. GET assets contain no secrets.\n * @experimental\n */\nexport function createUiRouter(host: UiHost, exit?: () => void) {\n const receipts = new Map<string, { key: string; result: Promise<UiReceipt> }>();\n const streams = new Set<ServerResponse>();\n let closed = false;\n return {\n async route(req: IncomingMessage, res: ServerResponse): Promise<boolean> {\n const url = new URL(req.url ?? \"/\", \"http://localhost\");\n if (!url.pathname.startsWith(\"/api/ui/\")) return false;\n try {\n if (closed) throw new UiError(503, \"\u5BBF\u4E3B\u6B63\u5728\u5173\u95ED\u3002\");\n if (req.method === \"GET\" && url.pathname === \"/api/ui/media\" && host.media) {\n const selected = url.searchParams.get(\"selected\") ?? \"\",\n id = url.searchParams.get(\"id\") ?? \"\";\n if (url.searchParams.get(\"hostId\") !== host.hostId) throw new UiError(409, \"\u5BBF\u4E3B\u5DF2\u6539\u53D8\u3002\");\n if (!selected || selected.length > 256 || !/^[a-f0-9]{64}$/.test(id))\n throw new UiError(400, \"\u56FE\u7247\u53C2\u6570\u65E0\u6548\u3002\");\n const media = await host.media(selected, id);\n res.writeHead(200, {\n \"content-type\": media.mediaType,\n \"content-length\": media.data.byteLength,\n \"content-disposition\": `inline; filename=\"${id}.${media.mediaType.slice(6)}\"`,\n });\n res.end(media.data);\n } else if (req.method === \"GET\" && url.pathname === \"/api/ui/snapshot\") {\n const selected = url.searchParams.get(\"selected\") ?? undefined;\n if (selected && selected.length > 256) throw new UiError(400, \"\u65E0\u6548\u7684\u8D44\u6E90 ID\u3002\");\n sendJson(res, 200, await host.snapshot(selected));\n } else if (req.method === \"GET\" && url.pathname === \"/api/ui/complete\" && host.complete) {\n const selected = url.searchParams.get(\"selected\") ?? \"\",\n text = url.searchParams.get(\"text\") ?? \"\";\n if (\n url.searchParams.get(\"hostId\") !== host.hostId ||\n !selected ||\n selected.length > 256 ||\n text.length > 16_384\n )\n throw new UiError(400, \"\u547D\u4EE4\u8865\u5168\u53C2\u6570\u65E0\u6548\u3002\");\n sendJson(res, 200, await host.complete(selected, text));\n } else if (\n req.method === \"GET\" &&\n [\"/api/ui/resources\", \"/api/ui/history\", \"/api/ui/field\"].includes(url.pathname)\n ) {\n if (url.searchParams.get(\"hostId\") !== host.hostId) throw new UiError(409, \"\u5BBF\u4E3B\u5DF2\u6539\u53D8\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BFB\u3002\");\n const selected = url.searchParams.get(\"selected\"),\n query = url.searchParams.get(\"query\") ?? \"\",\n cursor = url.searchParams.get(\"cursor\");\n if (query.length > 256 || (cursor?.length ?? 0) > 4096 || (selected?.length ?? 0) > 256)\n throw new UiError(400, \"\u8BFB\u53D6\u53C2\u6570\u8FC7\u957F\u3002\");\n const request = { query, ...(cursor ? { cursor } : {}) };\n if (url.pathname.endsWith(\"/resources\") && host.resources) sendJson(res, 200, await host.resources(request));\n else if (url.pathname.endsWith(\"/history\") && selected && host.history)\n sendJson(res, 200, await host.history(selected, request));\n else if (url.pathname.endsWith(\"/field\") && selected && host.field) {\n const blockId = url.searchParams.get(\"block\") ?? \"\",\n field = url.searchParams.get(\"field\") as UiField;\n const offset = Number(url.searchParams.get(\"offset\") ?? 0),\n version = url.searchParams.get(\"version\");\n if (\n !blockId ||\n blockId.length > 512 ||\n ![\"input\", \"text\", \"reasoning\", \"diagnostic\", \"presentation\", \"request\"].includes(field) ||\n !Number.isSafeInteger(offset) ||\n offset < 0 ||\n (version?.length ?? 0) > 128\n )\n throw new UiError(400, \"\u8BE6\u60C5\u53C2\u6570\u4E0D\u6B63\u786E\u3002\");\n sendJson(res, 200, await host.field(selected, { blockId, field, offset, ...(version ? { version } : {}) }));\n } else throw new UiError(400, \"\u5BBF\u4E3B\u4E0D\u652F\u6301\u6B64\u8BFB\u53D6\u6216\u672A\u6307\u5B9A\u8D44\u6E90\u3002\");\n } else if (req.method === \"GET\" && url.pathname === \"/api/ui/events\") {\n if (streams.size >= 16) throw new UiError(429, \"\u8FDE\u63A5\u7A97\u53E3\u8FC7\u591A\u3002\");\n streams.add(res);\n res.writeHead(200, {\n \"content-type\": \"text/event-stream; charset=utf-8\",\n \"cache-control\": \"no-store\",\n \"x-accel-buffering\": \"no\",\n });\n res.write(\"event: invalidate\\ndata: {}\\n\\n\");\n let pending: ReturnType<typeof setTimeout> | undefined;\n const invalidate = () => {\n if (pending || res.destroyed) return;\n pending = setTimeout(() => {\n pending = undefined;\n if (!res.write(\"event: invalidate\\ndata: {}\\n\\n\")) res.destroy();\n }, 120);\n };\n const unsubscribe = host.subscribe(invalidate);\n // Repairs missed invalidations and observes changes from CLI/channel owners too.\n const heartbeat = setInterval(invalidate, 2000);\n res.once(\"close\", () => {\n if (pending) clearTimeout(pending);\n clearInterval(heartbeat);\n unsubscribe();\n streams.delete(res);\n });\n } else if (req.method === \"POST\" && url.pathname === \"/api/ui/commands\") {\n const command = validateCommand(await readJson(req));\n if (command.hostId !== host.hostId) throw new UiError(409, \"\u5BBF\u4E3B\u5DF2\u91CD\u542F\u3002\u8BF7\u68C0\u67E5\u6700\u65B0\u72B6\u6001\u540E\u91CD\u65B0\u64CD\u4F5C\u3002\");\n const key = JSON.stringify({\n ...command,\n args: Object.fromEntries(Object.entries(command.args).sort(([a], [b]) => a.localeCompare(b))),\n });\n let receipt = receipts.get(command.requestId);\n if (receipt && receipt.key !== key) throw new UiError(409, \"\u8BF7\u6C42 ID \u5DF2\u88AB\u5176\u5B83\u547D\u4EE4\u4F7F\u7528\u3002\");\n if (!receipt) {\n // Do not silently evict a receipt and later repeat a side effect.\n if (receipts.size >= 4096) throw new UiError(429, \"\u672C\u6B21\u5BBF\u4E3B\u7684\u547D\u4EE4\u51ED\u636E\u5DF2\u6EE1\uFF0C\u8BF7\u5728\u7A7A\u95F2\u65F6\u91CD\u542F\u670D\u52A1\u3002\");\n receipt = { key, result: Promise.resolve().then(() => host.execute(command)) };\n receipts.set(command.requestId, receipt);\n }\n const result = await receipt.result;\n if (result.disconnect && exit) res.once(\"finish\", exit);\n sendJson(res, 200, result);\n } else throw new UiError(404, \"\u63A5\u53E3\u4E0D\u5B58\u5728\u3002\");\n } catch (error) {\n if (!res.headersSent)\n sendJson(res, error instanceof UiError ? error.status : 400, {\n error: error instanceof UiError ? error.message : \"\u64CD\u4F5C\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u5BBF\u4E3B\u65E5\u5FD7\u3001\u914D\u7F6E\u6216\u5F53\u524D\u72B6\u6001\u3002\",\n });\n else res.destroy();\n }\n return true;\n },\n close() {\n closed = true;\n for (const stream of streams) stream.destroy();\n streams.clear();\n },\n };\n}\n\n/** @experimental */\nexport async function startUiServer(options: {\n host: UiHost;\n assets: UiAssets;\n token: string;\n port?: number;\n browserLogin?: boolean;\n close?: () => Promise<void>;\n exit?: () => void;\n}) {\n validateToken(options.token);\n const port = options.port ?? 3940;\n if (!Number.isSafeInteger(port) || port < 0 || port > 65535) throw new Error(\"Invalid port\");\n const router = createUiRouter(options.host, () => {\n if (options.exit) options.exit();\n else close().catch(rejectClosed);\n });\n const login = options.browserLogin ? new BrowserLogin(options.token) : undefined;\n let origin = \"\";\n const requests = new Set<Promise<void>>();\n const server = createServer((req, res) => {\n const work = (async () => {\n secureHeaders(res);\n if (!trustedRequest(req, origin)) {\n sendJson(res, 403, { error: \"Untrusted origin or host\" });\n return;\n }\n if (login && req.method === \"POST\" && req.url === \"/api/ui/connect\") {\n try {\n const body = await readJson(req);\n if (\n !body ||\n typeof body !== \"object\" ||\n Array.isArray(body) ||\n Object.keys(body).length !== 1 ||\n !(\"ticket\" in body)\n )\n throw new UiError(400, \"\u8FDE\u63A5\u8BF7\u6C42\u65E0\u6548\u3002\");\n sendJson(res, 200, { token: login.redeem(body.ticket) });\n } catch (error) {\n if (!(error instanceof UiError)) throw error;\n sendJson(res, error.status, { error: error.message });\n }\n return;\n }\n const asset = options.assets.get(req.url ?? \"/\");\n if (req.method === \"GET\" && asset) {\n res.writeHead(200, { \"content-type\": asset.type });\n res.end(asset.body);\n return;\n }\n if (!authorized(req, options.token)) {\n sendJson(res, 401, { error: \"\u8BF7\u8F93\u5165\u63A7\u5236\u4EE4\u724C\u3002\" });\n return;\n }\n if (!(await router.route(req, res))) sendJson(res, 404, { error: \"Not found\" });\n })()\n .catch(() => {\n if (!res.headersSent) sendJson(res, 500, { error: \"Host unavailable\" });\n else res.destroy();\n })\n .finally(() => requests.delete(work));\n requests.add(work);\n });\n server.requestTimeout = 15_000;\n server.headersTimeout = 10_000;\n server.keepAliveTimeout = 3000;\n server.maxConnections = 64;\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(port, \"127.0.0.1\", () => {\n server.removeListener(\"error\", reject);\n resolve();\n });\n });\n origin = `http://127.0.0.1:${(server.address() as AddressInfo).port}`;\n let closing: Promise<void> | undefined;\n let rejectClosed: (error: unknown) => void;\n const closed = new Promise<void>((resolve, reject) => {\n rejectClosed = reject;\n server.once(\"close\", () => {\n if (closing) closing.then(resolve, reject);\n else resolve();\n });\n });\n const close = () =>\n (closing ??= (async () => {\n login?.clear();\n router.close();\n const stopped = new Promise<void>((resolve, reject) =>\n server.close((error) => (error ? reject(error) : resolve())),\n );\n server.closeAllConnections();\n const results = await Promise.allSettled([Promise.resolve().then(() => options.close?.()), ...requests, stopped]);\n const errors = results.filter((result) => result.status === \"rejected\").map((result) => result.reason as unknown);\n if (errors.length) throw new AggregateError(errors, \"UI server shutdown failed\");\n })());\n return {\n url: origin,\n closed,\n createLoginUrl: () => {\n if (!login || closing) throw new Error(\"\u5F53\u524D\u670D\u52A1\u4E0D\u63A5\u53D7\u6D4F\u89C8\u5668\u8FDE\u63A5\u51ED\u636E\u3002\");\n return `${origin}/#may-connect=${login.issue()}`;\n },\n close,\n };\n}\n\n/** @experimental */\nexport function secureHeaders(res: ServerResponse): void {\n res.setHeader(\"cache-control\", \"no-store\");\n res.setHeader(\"x-content-type-options\", \"nosniff\");\n res.setHeader(\"referrer-policy\", \"no-referrer\");\n res.setHeader(\n \"content-security-policy\",\n \"default-src 'none'; script-src 'self'; style-src 'self'; connect-src 'self'; img-src 'self' blob: https: http:; base-uri 'none'; frame-ancestors 'none'; form-action 'self'\",\n );\n}\n/** @experimental */\nexport function validateToken(token: string): void {\n if (!/^[\\x21-\\x7e]{32,256}$/.test(token))\n throw new Error(\"Control token must be 32..256 printable non-space ASCII characters\");\n}\n/** @experimental */\nexport function trustedRequest(req: IncomingMessage, origin: string): boolean {\n return (\n Boolean(origin) &&\n req.headers.host === new URL(origin).host &&\n (req.headers.origin === undefined || req.headers.origin === origin)\n );\n}\n/** @experimental */\nexport function authorized(req: IncomingMessage, token: string): boolean {\n const supplied = req.headers.authorization ?? \"\",\n expected = `Bearer ${token}`;\n return (\n Buffer.byteLength(supplied) === Buffer.byteLength(expected) &&\n timingSafeEqual(Buffer.from(supplied), Buffer.from(expected))\n );\n}\n/** @experimental */\nexport function sendJson(res: ServerResponse, status: number, data: unknown): void {\n res.writeHead(status, { \"content-type\": \"application/json; charset=utf-8\" });\n res.end(JSON.stringify(data));\n}\nasync function readJson(req: IncomingMessage): Promise<unknown> {\n if (req.headers[\"content-type\"]?.split(\";\")[0]?.trim() !== \"application/json\") throw new UiError(400, \"\u9700\u8981 JSON\u3002\");\n let size = 0;\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n const bytes = Buffer.from(chunk as Uint8Array);\n size += bytes.length;\n if (size > 256 * 1024) throw new UiError(413, \"\u8BF7\u6C42\u8FC7\u5927\u3002\");\n chunks.push(bytes);\n }\n return JSON.parse(Buffer.concat(chunks).toString(\"utf8\"));\n}\nfunction validateCommand(value: unknown): UiCommand {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) throw new UiError(400, \"\u65E0\u6548\u7684\u547D\u4EE4\u3002\");\n const c = value as UiCommand;\n if (\n Object.keys(c).some(\n (key) => ![\"version\", \"hostId\", \"requestId\", \"name\", \"targetId\", \"expectedActiveId\", \"args\"].includes(key),\n ) ||\n c.version !== 1 ||\n typeof c.hostId !== \"string\" ||\n c.hostId.length > 128 ||\n typeof c.requestId !== \"string\" ||\n !/^[a-zA-Z0-9._:-]{1,100}$/.test(c.requestId) ||\n (c.expectedActiveId !== undefined &&\n (typeof c.expectedActiveId !== \"string\" || !c.expectedActiveId || c.expectedActiveId.length > 256)) ||\n typeof c.name !== \"string\" ||\n !/^[a-z][a-z0-9.-]{1,80}$/.test(c.name) ||\n !(c.targetId === null || (typeof c.targetId === \"string\" && c.targetId.length <= 256)) ||\n !c.args ||\n typeof c.args !== \"object\" ||\n Array.isArray(c.args) ||\n Object.keys(c.args).length > 12 ||\n Object.values(c.args).some((v) => typeof v !== \"string\" || v.length > 64 * 1024)\n )\n throw new UiError(400, \"\u65E0\u6548\u7684\u547D\u4EE4\u3002\");\n return c;\n}\n", "import { randomBytes } from \"node:crypto\";\nimport { UiError } from \"./protocol.js\";\n\n/** @experimental */\nexport class BrowserLogin {\n private readonly tickets = new Map<string, number>();\n\n constructor(\n private readonly token: string,\n private readonly lifetimeMs = 60_000,\n ) {\n if (!Number.isSafeInteger(lifetimeMs) || lifetimeMs <= 0) throw new Error(\"\u8FDE\u63A5\u51ED\u636E\u6709\u6548\u671F\u5FC5\u987B\u4E3A\u6B63\u6574\u6570\u3002\");\n }\n\n issue(): string {\n const now = Date.now();\n for (const [ticket, expiresAt] of this.tickets) if (expiresAt <= now) this.tickets.delete(ticket);\n if (this.tickets.size >= 8) throw new UiError(429, \"\u5F85\u8FDE\u63A5\u9875\u9762\u8FC7\u591A\uFF0C\u8BF7\u7A0D\u540E\u91CD\u65B0\u6253\u5F00\u3002\");\n const ticket = randomBytes(32).toString(\"base64url\");\n this.tickets.set(ticket, now + this.lifetimeMs);\n return ticket;\n }\n\n redeem(ticket: unknown): string {\n if (typeof ticket !== \"string\") throw new UiError(401, \"\u8FDE\u63A5\u51ED\u636E\u65E0\u6548\u3002\");\n const expiresAt = this.tickets.get(ticket);\n this.tickets.delete(ticket);\n if (expiresAt === undefined || expiresAt <= Date.now())\n throw new UiError(401, \"\u8FDE\u63A5\u5DF2\u5931\u6548\uFF0C\u8BF7\u4ECE\u542F\u52A8\u7A0B\u5E8F\u91CD\u65B0\u6253\u5F00\u9875\u9762\u3002\");\n return this.token;\n }\n\n clear(): void {\n this.tickets.clear();\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["ticket"]
7
+ }
@@ -4,11 +4,12 @@ import {
4
4
  runMaybeCodeWebUI,
5
5
  startMaybeCodeWebServer,
6
6
  startMaybeCodeWebUI
7
- } from "./chunk-7ISOHFS7.js";
8
- import "./chunk-HOU5ITUK.js";
9
- import "./chunk-H7SNBFO4.js";
10
- import "./chunk-VAZMCNBB.js";
11
- import "./chunk-K5JWPNSY.js";
7
+ } from "./chunk-WMSG5ZTR.js";
8
+ import "./chunk-Z3BOPBVU.js";
9
+ import "./chunk-XTEMRAQW.js";
10
+ import "./chunk-MNBYXL5Y.js";
11
+ import "./chunk-5SLWALZK.js";
12
+ import "./chunk-UQDZ55LQ.js";
12
13
  import "./chunk-BSBNNF34.js";
13
14
  import "./chunk-E732GDOI.js";
14
15
  export {
@@ -17,4 +18,4 @@ export {
17
18
  startMaybeCodeWebServer,
18
19
  startMaybeCodeWebUI
19
20
  };
20
- //# sourceMappingURL=web-ui-COB6PKC5.js.map
21
+ //# sourceMappingURL=web-ui-UWQUFE4W.js.map
@@ -0,0 +1,337 @@
1
+ {
2
+ "type": "object",
3
+ "description": "MaybeCode settings.",
4
+ "properties": {
5
+ "execution": {
6
+ "default": { "mode": "host" },
7
+ "oneOf": [
8
+ {
9
+ "type": "object",
10
+ "properties": { "mode": { "const": "host" } },
11
+ "required": ["mode"],
12
+ "additionalProperties": false
13
+ },
14
+ {
15
+ "type": "object",
16
+ "properties": {
17
+ "mode": { "const": "container" },
18
+ "image": { "$ref": "#/$defs/nonEmptyString" },
19
+ "network": { "const": "none" },
20
+ "memoryBytes": { "$ref": "#/$defs/positiveInteger" },
21
+ "cpuCount": { "type": "number", "exclusiveMinimum": 0 }
22
+ },
23
+ "required": ["mode", "image", "network", "memoryBytes", "cpuCount"],
24
+ "additionalProperties": false
25
+ }
26
+ ]
27
+ },
28
+ "fetch": {
29
+ "type": "object",
30
+ "properties": {
31
+ "allowedOrigins": {
32
+ "type": "array",
33
+ "uniqueItems": true,
34
+ "items": { "type": "string", "pattern": "^https?://(?:[A-Za-z0-9.-]+|\\[[A-Fa-f0-9:]+\\])(?::[0-9]{1,5})?$" }
35
+ },
36
+ "maxBytes": { "$ref": "#/$defs/positiveInteger" },
37
+ "timeoutMs": { "$ref": "#/$defs/positiveInteger" },
38
+ "maxRedirects": { "type": "integer", "minimum": 0 }
39
+ },
40
+ "additionalProperties": false
41
+ },
42
+ "requestRecording": { "enum": ["off", "required"], "default": "required" },
43
+ "providerBodyRecording": { "type": "boolean", "default": false },
44
+ "git": {
45
+ "oneOf": [
46
+ { "const": false },
47
+ {
48
+ "type": "object",
49
+ "properties": {
50
+ "autoCommit": { "type": "boolean", "default": true },
51
+ "readOnly": { "type": "boolean", "default": false },
52
+ "dataRoot": { "$ref": "#/$defs/nonEmptyString" },
53
+ "worktreesRoot": { "$ref": "#/$defs/nonEmptyString" },
54
+ "excludedPaths": { "type": "array", "items": { "$ref": "#/$defs/nonEmptyString" } }
55
+ },
56
+ "additionalProperties": false
57
+ }
58
+ ]
59
+ },
60
+ "plugins": { "$ref": "#/$defs/pluginSelections" },
61
+ "permissionMode": {
62
+ "enum": ["default", "yolo"],
63
+ "default": "default",
64
+ "description": "Tool approval mode. yolo auto-approves requests while preserving explicit policy denials."
65
+ },
66
+ "persistentRules": {
67
+ "type": "boolean",
68
+ "default": false,
69
+ "description": "Enable project-scoped persistent file permissions in .may/permission-rules.json."
70
+ },
71
+ "delegationNotifications": {
72
+ "type": "boolean",
73
+ "default": false,
74
+ "description": "Show a notice when a sub-agent task finishes."
75
+ },
76
+ "instructionsDirectory": { "$ref": "#/$defs/nonEmptyString" },
77
+ "skills": {
78
+ "oneOf": [
79
+ { "const": false },
80
+ {
81
+ "type": "object",
82
+ "properties": {
83
+ "directories": { "type": "array", "maxItems": 32, "items": { "$ref": "#/$defs/nonEmptyString" } }
84
+ },
85
+ "additionalProperties": false
86
+ }
87
+ ]
88
+ },
89
+ "runBudget": { "$ref": "#/$defs/runBudget" },
90
+ "subagents": {
91
+ "oneOf": [
92
+ { "const": false },
93
+ {
94
+ "type": "object",
95
+ "properties": {
96
+ "enabled": {
97
+ "type": "boolean",
98
+ "default": true,
99
+ "description": "Sub-agent delegation for ordinary requests. Enabled by default."
100
+ },
101
+ "roles": {
102
+ "type": "object",
103
+ "minProperties": 1,
104
+ "maxProperties": 8,
105
+ "propertyNames": { "$ref": "#/$defs/subagentIdentifier" },
106
+ "additionalProperties": { "$ref": "#/$defs/subagentRole" }
107
+ },
108
+ "defaultRole": { "$ref": "#/$defs/subagentIdentifier" },
109
+ "limits": {
110
+ "type": "object",
111
+ "properties": {
112
+ "maxConcurrent": { "type": "integer", "minimum": 1, "maximum": 8, "default": 2 },
113
+ "maxTasks": { "type": "integer", "minimum": 1, "maximum": 128, "default": 24 },
114
+ "maxDepth": { "type": "integer", "minimum": 2, "maximum": 4, "default": 3 },
115
+ "maxTaskTurns": { "type": "integer", "minimum": 2, "maximum": 16, "default": 6 },
116
+ "maxDurationMs": { "type": "integer", "minimum": 1, "maximum": 3600000, "default": 900000 },
117
+ "maxInputBytes": { "type": "integer", "minimum": 1, "maximum": 65536, "default": 32768 },
118
+ "maxOutputBytes": { "type": "integer", "minimum": 1, "maximum": 262144, "default": 65536 }
119
+ },
120
+ "additionalProperties": false
121
+ },
122
+ "runBudget": { "$ref": "#/$defs/runBudget", "description": "Per child Run budget." },
123
+ "maxModelCalls": {
124
+ "type": "integer",
125
+ "minimum": 1,
126
+ "maximum": 10000,
127
+ "default": 128,
128
+ "description": "Model calls reserved across the main Run, child Runs and compaction of one request."
129
+ },
130
+ "maxTotalTokens": {
131
+ "$ref": "#/$defs/positiveInteger",
132
+ "description": "Optional token ceiling checked against per-call reservations."
133
+ },
134
+ "reservationTokens": { "type": "integer", "minimum": 1, "maximum": 10000000, "default": 32768 }
135
+ },
136
+ "additionalProperties": false
137
+ }
138
+ ]
139
+ },
140
+ "autoCompaction": {
141
+ "type": "object",
142
+ "properties": {
143
+ "mode": {
144
+ "enum": ["prune-summary", "history-reference", "provider-native"],
145
+ "default": "prune-summary"
146
+ }
147
+ },
148
+ "additionalProperties": false
149
+ },
150
+ "retry": {
151
+ "oneOf": [
152
+ { "const": false },
153
+ {
154
+ "type": "object",
155
+ "properties": {
156
+ "maxAttempts": { "$ref": "#/$defs/positiveInteger" },
157
+ "baseDelayMs": { "type": "number", "minimum": 0 },
158
+ "maxDelayMs": { "type": "number", "minimum": 0 },
159
+ "jitterRatio": { "type": "number", "minimum": 0, "maximum": 1 }
160
+ },
161
+ "additionalProperties": false
162
+ }
163
+ ]
164
+ },
165
+ "observability": {
166
+ "oneOf": [
167
+ { "const": false },
168
+ {
169
+ "type": "object",
170
+ "properties": {
171
+ "enabled": { "type": "boolean", "default": true },
172
+ "exporter": { "const": "file", "default": "file" },
173
+ "file": { "$ref": "#/$defs/nonEmptyString" },
174
+ "samplingRatio": { "type": "number", "minimum": 0, "maximum": 1 },
175
+ "retentionDays": { "$ref": "#/$defs/positiveInteger", "default": 60 },
176
+ "batch": {
177
+ "type": "object",
178
+ "properties": {
179
+ "maxQueueSize": { "$ref": "#/$defs/positiveInteger" },
180
+ "maxExportBatchSize": { "$ref": "#/$defs/positiveInteger" },
181
+ "scheduledDelayMs": { "type": "number", "minimum": 0 }
182
+ },
183
+ "additionalProperties": false
184
+ }
185
+ },
186
+ "additionalProperties": false
187
+ }
188
+ ]
189
+ },
190
+ "mcpServers": {
191
+ "oneOf": [
192
+ { "const": false },
193
+ {
194
+ "type": "object",
195
+ "propertyNames": { "pattern": "^[A-Za-z0-9_-]+$" },
196
+ "additionalProperties": {
197
+ "oneOf": [{ "$ref": "#/$defs/mcpStdioServer" }, { "$ref": "#/$defs/mcpHttpServer" }]
198
+ }
199
+ }
200
+ ]
201
+ }
202
+ },
203
+ "additionalProperties": false,
204
+ "$defs": {
205
+ "subagentIdentifier": {
206
+ "type": "string",
207
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$",
208
+ "not": { "enum": ["constructor", "prototype"] }
209
+ },
210
+ "subagentRole": {
211
+ "type": "object",
212
+ "properties": {
213
+ "model": {
214
+ "$ref": "#/$defs/subagentIdentifier",
215
+ "description": "Model profile name. Without it the role inherits the main Session model and reasoning effort."
216
+ },
217
+ "reasoningEffort": { "type": "string", "pattern": "\\S", "maxLength": 64 },
218
+ "instructions": { "type": "string", "pattern": "^[^\\u0000]*\\S[^\\u0000]*$", "maxLength": 16384 },
219
+ "tools": {
220
+ "type": "array",
221
+ "maxItems": 7,
222
+ "uniqueItems": true,
223
+ "items": { "enum": ["read", "shell", "edit", "write", "glob", "grep", "fetch"] }
224
+ },
225
+ "delegateTo": {
226
+ "type": "array",
227
+ "maxItems": 8,
228
+ "uniqueItems": true,
229
+ "items": { "$ref": "#/$defs/subagentIdentifier" }
230
+ },
231
+ "runBudget": { "$ref": "#/$defs/runBudget" }
232
+ },
233
+ "additionalProperties": false
234
+ },
235
+ "mcpStdioServer": {
236
+ "type": "object",
237
+ "properties": {
238
+ "enabled": { "type": "boolean", "default": true },
239
+ "required": { "type": "boolean", "default": true },
240
+ "transport": { "const": "stdio", "default": "stdio" },
241
+ "protocolMode": { "enum": ["legacy", "auto"], "default": "legacy" },
242
+ "host": { "$ref": "#/$defs/mcpHostOptions" },
243
+ "tasks": {
244
+ "type": "boolean",
245
+ "default": false,
246
+ "description": "Enable the modern Tasks extension with durable encrypted handles."
247
+ },
248
+ "command": { "$ref": "#/$defs/nonEmptyString" },
249
+ "args": {
250
+ "type": "array",
251
+ "items": { "type": "string" }
252
+ },
253
+ "cwd": { "$ref": "#/$defs/nonEmptyString" },
254
+ "env": {
255
+ "type": "object",
256
+ "propertyNames": { "minLength": 1 },
257
+ "additionalProperties": { "type": "string" }
258
+ },
259
+ "requestTimeoutMs": { "$ref": "#/$defs/positiveInteger" },
260
+ "maxTotalTimeoutMs": { "$ref": "#/$defs/positiveInteger" },
261
+ "maxBufferSize": { "$ref": "#/$defs/positiveInteger" },
262
+ "stderrMaxBytes": {
263
+ "$ref": "#/$defs/positiveInteger",
264
+ "default": 16384
265
+ }
266
+ },
267
+ "anyOf": [
268
+ {
269
+ "required": ["enabled"],
270
+ "properties": { "enabled": { "const": false } }
271
+ },
272
+ { "required": ["command"] }
273
+ ],
274
+ "additionalProperties": false
275
+ },
276
+ "mcpHttpServer": {
277
+ "type": "object",
278
+ "required": ["transport"],
279
+ "properties": {
280
+ "enabled": { "type": "boolean", "default": true },
281
+ "required": { "type": "boolean", "default": true },
282
+ "transport": { "const": "streamable-http" },
283
+ "url": {
284
+ "$ref": "#/$defs/nonEmptyString",
285
+ "description": "HTTPS endpoint (HTTP only on loopback); redirects and URL credentials are refused at runtime."
286
+ },
287
+ "headers": {
288
+ "type": "object",
289
+ "propertyNames": { "minLength": 1 },
290
+ "additionalProperties": { "type": "string" }
291
+ },
292
+ "auth": { "$ref": "#/$defs/mcpOAuthOptions" },
293
+ "protocolMode": { "enum": ["legacy", "auto"], "default": "auto" },
294
+ "host": { "$ref": "#/$defs/mcpHostOptions" },
295
+ "tasks": {
296
+ "type": "boolean",
297
+ "default": false,
298
+ "description": "Enable the modern Tasks extension with durable encrypted handles."
299
+ },
300
+ "requestTimeoutMs": { "$ref": "#/$defs/positiveInteger" },
301
+ "maxTotalTimeoutMs": { "$ref": "#/$defs/positiveInteger" }
302
+ },
303
+ "anyOf": [{ "required": ["enabled"], "properties": { "enabled": { "const": false } } }, { "required": ["url"] }],
304
+ "additionalProperties": false
305
+ },
306
+ "mcpHostOptions": {
307
+ "type": "object",
308
+ "description": "Explicit compatibility options; an active interaction UI and host services are also required.",
309
+ "properties": {
310
+ "roots": { "type": "boolean", "default": false },
311
+ "sampling": { "type": "boolean", "default": false },
312
+ "legacyRequests": {
313
+ "const": "isolated",
314
+ "description": "Use a fresh process/session for each legacy interactive operation, never shared or reused."
315
+ }
316
+ },
317
+ "additionalProperties": false
318
+ },
319
+ "mcpOAuthOptions": {
320
+ "type": "object",
321
+ "required": ["type"],
322
+ "properties": {
323
+ "type": { "const": "oauth" },
324
+ "account": { "$ref": "#/$defs/nonEmptyString" },
325
+ "clientId": { "$ref": "#/$defs/nonEmptyString" },
326
+ "expectedIssuer": { "$ref": "#/$defs/nonEmptyString" },
327
+ "clientMetadataUrl": { "$ref": "#/$defs/nonEmptyString" },
328
+ "scopes": { "type": "array", "items": { "$ref": "#/$defs/nonEmptyString" } },
329
+ "authorizationOrigins": { "type": "array", "items": { "$ref": "#/$defs/nonEmptyString" } },
330
+ "callbackPort": { "type": "integer", "minimum": 0, "maximum": 65535 }
331
+ },
332
+ "dependentRequired": { "clientId": ["expectedIssuer"] },
333
+ "not": { "required": ["clientId", "clientMetadataUrl"] },
334
+ "additionalProperties": false
335
+ }
336
+ }
337
+ }