@bd7pil/ocrc 0.9.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 (292) hide show
  1. package/LICENSE +34 -0
  2. package/README.md +330 -0
  3. package/dist/cli/host-backends.js +216 -0
  4. package/dist/cli/host-backends.js.map +1 -0
  5. package/dist/cli/host.js +185 -0
  6. package/dist/cli/host.js.map +1 -0
  7. package/dist/cli/index.js +67 -0
  8. package/dist/cli/index.js.map +1 -0
  9. package/dist/cli/init.js +68 -0
  10. package/dist/cli/init.js.map +1 -0
  11. package/dist/cli/install.js +220 -0
  12. package/dist/cli/install.js.map +1 -0
  13. package/dist/cli/pair.js +11 -0
  14. package/dist/cli/pair.js.map +1 -0
  15. package/dist/cli/uninstall.js +75 -0
  16. package/dist/cli/uninstall.js.map +1 -0
  17. package/dist/connectivity/auth/cf-access.js +20 -0
  18. package/dist/connectivity/auth/cf-access.js.map +1 -0
  19. package/dist/connectivity/auth/index.js +2 -0
  20. package/dist/connectivity/auth/index.js.map +1 -0
  21. package/dist/connectivity/auth/select.js +19 -0
  22. package/dist/connectivity/auth/select.js.map +1 -0
  23. package/dist/connectivity/auth/token.js +157 -0
  24. package/dist/connectivity/auth/token.js.map +1 -0
  25. package/dist/connectivity/exposure/cloudflared.js +77 -0
  26. package/dist/connectivity/exposure/cloudflared.js.map +1 -0
  27. package/dist/connectivity/exposure/index.js +2 -0
  28. package/dist/connectivity/exposure/index.js.map +1 -0
  29. package/dist/connectivity/exposure/providers.js +49 -0
  30. package/dist/connectivity/exposure/providers.js.map +1 -0
  31. package/dist/connectivity/pairing.js +29 -0
  32. package/dist/connectivity/pairing.js.map +1 -0
  33. package/dist/core/agent/acp-backend.js +539 -0
  34. package/dist/core/agent/acp-backend.js.map +1 -0
  35. package/dist/core/agent/acp-connect.js +92 -0
  36. package/dist/core/agent/acp-connect.js.map +1 -0
  37. package/dist/core/agent/acp-normalizer.js +81 -0
  38. package/dist/core/agent/acp-normalizer.js.map +1 -0
  39. package/dist/core/agent/acp-replay.js +89 -0
  40. package/dist/core/agent/acp-replay.js.map +1 -0
  41. package/dist/core/agent/acp-store.js +129 -0
  42. package/dist/core/agent/acp-store.js.map +1 -0
  43. package/dist/core/agent/backend.js +2 -0
  44. package/dist/core/agent/backend.js.map +1 -0
  45. package/dist/core/agent/diff-util.js +70 -0
  46. package/dist/core/agent/diff-util.js.map +1 -0
  47. package/dist/core/agent/event.js +12 -0
  48. package/dist/core/agent/event.js.map +1 -0
  49. package/dist/core/agent/opencode-backend.js +598 -0
  50. package/dist/core/agent/opencode-backend.js.map +1 -0
  51. package/dist/core/agent/opencode-normalizer.js +69 -0
  52. package/dist/core/agent/opencode-normalizer.js.map +1 -0
  53. package/dist/core/agent/registry.js +55 -0
  54. package/dist/core/agent/registry.js.map +1 -0
  55. package/dist/core/agent/v2-backend.js +176 -0
  56. package/dist/core/agent/v2-backend.js.map +1 -0
  57. package/dist/core/card-bus.js +74 -0
  58. package/dist/core/card-bus.js.map +1 -0
  59. package/dist/core/channels.js +95 -0
  60. package/dist/core/channels.js.map +1 -0
  61. package/dist/core/history.js +91 -0
  62. package/dist/core/history.js.map +1 -0
  63. package/dist/core/list-files.js +50 -0
  64. package/dist/core/list-files.js.map +1 -0
  65. package/dist/core/opencode-events.js +29 -0
  66. package/dist/core/opencode-events.js.map +1 -0
  67. package/dist/core/primary-election.js +91 -0
  68. package/dist/core/primary-election.js.map +1 -0
  69. package/dist/core/push.js +152 -0
  70. package/dist/core/push.js.map +1 -0
  71. package/dist/core/relay.js +400 -0
  72. package/dist/core/relay.js.map +1 -0
  73. package/dist/core/scheduler.js +150 -0
  74. package/dist/core/scheduler.js.map +1 -0
  75. package/dist/core/state.js +222 -0
  76. package/dist/core/state.js.map +1 -0
  77. package/dist/core/stream-accumulator.js +76 -0
  78. package/dist/core/stream-accumulator.js.map +1 -0
  79. package/dist/core/structured-card.js +2 -0
  80. package/dist/core/structured-card.js.map +1 -0
  81. package/dist/core/types.js +2 -0
  82. package/dist/core/types.js.map +1 -0
  83. package/dist/index.js +3 -0
  84. package/dist/index.js.map +1 -0
  85. package/dist/opencode/global-events.js +57 -0
  86. package/dist/opencode/global-events.js.map +1 -0
  87. package/dist/opencode/list-sessions.js +122 -0
  88. package/dist/opencode/list-sessions.js.map +1 -0
  89. package/dist/opencode/submit.js +39 -0
  90. package/dist/opencode/submit.js.map +1 -0
  91. package/dist/opencode/workspaces.js +51 -0
  92. package/dist/opencode/workspaces.js.map +1 -0
  93. package/dist/plugin/config.js +128 -0
  94. package/dist/plugin/config.js.map +1 -0
  95. package/dist/plugin/control-plane.js +133 -0
  96. package/dist/plugin/control-plane.js.map +1 -0
  97. package/dist/plugin/entry.js +409 -0
  98. package/dist/plugin/entry.js.map +1 -0
  99. package/dist/plugin/v2/event-map.js +193 -0
  100. package/dist/plugin/v2/event-map.js.map +1 -0
  101. package/dist/plugin/v2/types.js +15 -0
  102. package/dist/plugin/v2/types.js.map +1 -0
  103. package/dist/transport/interface.js +2 -0
  104. package/dist/transport/interface.js.map +1 -0
  105. package/dist/transport/telegram/esc.js +9 -0
  106. package/dist/transport/telegram/esc.js.map +1 -0
  107. package/dist/transport/telegram/handlers/info-commands.js +101 -0
  108. package/dist/transport/telegram/handlers/info-commands.js.map +1 -0
  109. package/dist/transport/telegram/handlers.js +1348 -0
  110. package/dist/transport/telegram/handlers.js.map +1 -0
  111. package/dist/transport/telegram/i18n/en.js +538 -0
  112. package/dist/transport/telegram/i18n/en.js.map +1 -0
  113. package/dist/transport/telegram/i18n/index.js +83 -0
  114. package/dist/transport/telegram/i18n/index.js.map +1 -0
  115. package/dist/transport/telegram/i18n/zh.js +538 -0
  116. package/dist/transport/telegram/i18n/zh.js.map +1 -0
  117. package/dist/transport/telegram/index.js +792 -0
  118. package/dist/transport/telegram/index.js.map +1 -0
  119. package/dist/transport/telegram/main-keyboard.js +36 -0
  120. package/dist/transport/telegram/main-keyboard.js.map +1 -0
  121. package/dist/transport/telegram/managers/abort-suppression-manager.js +33 -0
  122. package/dist/transport/telegram/managers/abort-suppression-manager.js.map +1 -0
  123. package/dist/transport/telegram/managers/external-input-suppression-manager.js +51 -0
  124. package/dist/transport/telegram/managers/external-input-suppression-manager.js.map +1 -0
  125. package/dist/transport/telegram/managers/interaction-manager.js +254 -0
  126. package/dist/transport/telegram/managers/interaction-manager.js.map +1 -0
  127. package/dist/transport/telegram/managers/permission-manager.js +242 -0
  128. package/dist/transport/telegram/managers/permission-manager.js.map +1 -0
  129. package/dist/transport/telegram/managers/question-manager.js +191 -0
  130. package/dist/transport/telegram/managers/question-manager.js.map +1 -0
  131. package/dist/transport/telegram/managers/rename-manager.js +56 -0
  132. package/dist/transport/telegram/managers/rename-manager.js.map +1 -0
  133. package/dist/transport/telegram/menus.js +77 -0
  134. package/dist/transport/telegram/menus.js.map +1 -0
  135. package/dist/transport/telegram/permission-flow.js +156 -0
  136. package/dist/transport/telegram/permission-flow.js.map +1 -0
  137. package/dist/transport/telegram/question-flow.js +224 -0
  138. package/dist/transport/telegram/question-flow.js.map +1 -0
  139. package/dist/transport/telegram/render/block-parser.js +365 -0
  140. package/dist/transport/telegram/render/block-parser.js.map +1 -0
  141. package/dist/transport/telegram/render/block-plain-text.js +87 -0
  142. package/dist/transport/telegram/render/block-plain-text.js.map +1 -0
  143. package/dist/transport/telegram/render/block-splitter.js +152 -0
  144. package/dist/transport/telegram/render/block-splitter.js.map +1 -0
  145. package/dist/transport/telegram/render/chunker.js +71 -0
  146. package/dist/transport/telegram/render/chunker.js.map +1 -0
  147. package/dist/transport/telegram/render/limits.js +13 -0
  148. package/dist/transport/telegram/render/limits.js.map +1 -0
  149. package/dist/transport/telegram/render/markdown-normalizer.js +102 -0
  150. package/dist/transport/telegram/render/markdown-normalizer.js.map +1 -0
  151. package/dist/transport/telegram/render/markdown-to-telegram-v2.js +116 -0
  152. package/dist/transport/telegram/render/markdown-to-telegram-v2.js.map +1 -0
  153. package/dist/transport/telegram/render/part-signature.js +14 -0
  154. package/dist/transport/telegram/render/part-signature.js.map +1 -0
  155. package/dist/transport/telegram/render/pipeline.js +23 -0
  156. package/dist/transport/telegram/render/pipeline.js.map +1 -0
  157. package/dist/transport/telegram/render/rich-blocks.js +311 -0
  158. package/dist/transport/telegram/render/rich-blocks.js.map +1 -0
  159. package/dist/transport/telegram/render/text-splitter.js +64 -0
  160. package/dist/transport/telegram/render/text-splitter.js.map +1 -0
  161. package/dist/transport/telegram/render/types.js +2 -0
  162. package/dist/transport/telegram/render/types.js.map +1 -0
  163. package/dist/transport/telegram/renderer.js +305 -0
  164. package/dist/transport/telegram/renderer.js.map +1 -0
  165. package/dist/transport/telegram/streaming/duration-formatter.js +68 -0
  166. package/dist/transport/telegram/streaming/duration-formatter.js.map +1 -0
  167. package/dist/transport/telegram/streaming/finalize-assistant-response.js +37 -0
  168. package/dist/transport/telegram/streaming/finalize-assistant-response.js.map +1 -0
  169. package/dist/transport/telegram/streaming/response-streamer.js +400 -0
  170. package/dist/transport/telegram/streaming/response-streamer.js.map +1 -0
  171. package/dist/transport/telegram/streaming/running-tool-tracker.js +150 -0
  172. package/dist/transport/telegram/streaming/running-tool-tracker.js.map +1 -0
  173. package/dist/transport/telegram/streaming/stream-throttle.js +57 -0
  174. package/dist/transport/telegram/streaming/stream-throttle.js.map +1 -0
  175. package/dist/transport/telegram/streaming/tool-call-streamer.js +390 -0
  176. package/dist/transport/telegram/streaming/tool-call-streamer.js.map +1 -0
  177. package/dist/transport/telegram/streaming-render.js +182 -0
  178. package/dist/transport/telegram/streaming-render.js.map +1 -0
  179. package/dist/transport/telegram/types/interaction.js +2 -0
  180. package/dist/transport/telegram/types/interaction.js.map +1 -0
  181. package/dist/transport/telegram/types/model.js +25 -0
  182. package/dist/transport/telegram/types/model.js.map +1 -0
  183. package/dist/transport/telegram/types/permission.js +2 -0
  184. package/dist/transport/telegram/types/permission.js.map +1 -0
  185. package/dist/transport/telegram/types/question.js +2 -0
  186. package/dist/transport/telegram/types/question.js.map +1 -0
  187. package/dist/transport/telegram/types/rename.js +2 -0
  188. package/dist/transport/telegram/types/rename.js.map +1 -0
  189. package/dist/transport/telegram/types/scheduled-task.js +23 -0
  190. package/dist/transport/telegram/types/scheduled-task.js.map +1 -0
  191. package/dist/transport/telegram/types/session.js +2 -0
  192. package/dist/transport/telegram/types/session.js.map +1 -0
  193. package/dist/transport/telegram/ui.js +28 -0
  194. package/dist/transport/telegram/ui.js.map +1 -0
  195. package/dist/transport/web/index.js +148 -0
  196. package/dist/transport/web/index.js.map +1 -0
  197. package/dist/transport/web/middleware/cf-access.js +104 -0
  198. package/dist/transport/web/middleware/cf-access.js.map +1 -0
  199. package/dist/transport/web/opencode-config.js +15 -0
  200. package/dist/transport/web/opencode-config.js.map +1 -0
  201. package/dist/transport/web/routes/abort.js +12 -0
  202. package/dist/transport/web/routes/abort.js.map +1 -0
  203. package/dist/transport/web/routes/approval.js +16 -0
  204. package/dist/transport/web/routes/approval.js.map +1 -0
  205. package/dist/transport/web/routes/catalog.js +11 -0
  206. package/dist/transport/web/routes/catalog.js.map +1 -0
  207. package/dist/transport/web/routes/channels.js +53 -0
  208. package/dist/transport/web/routes/channels.js.map +1 -0
  209. package/dist/transport/web/routes/commands.js +15 -0
  210. package/dist/transport/web/routes/commands.js.map +1 -0
  211. package/dist/transport/web/routes/context.js +17 -0
  212. package/dist/transport/web/routes/context.js.map +1 -0
  213. package/dist/transport/web/routes/controls.js +34 -0
  214. package/dist/transport/web/routes/controls.js.map +1 -0
  215. package/dist/transport/web/routes/create-session.js +21 -0
  216. package/dist/transport/web/routes/create-session.js.map +1 -0
  217. package/dist/transport/web/routes/diff.js +7 -0
  218. package/dist/transport/web/routes/diff.js.map +1 -0
  219. package/dist/transport/web/routes/files.js +22 -0
  220. package/dist/transport/web/routes/files.js.map +1 -0
  221. package/dist/transport/web/routes/logs.js +9 -0
  222. package/dist/transport/web/routes/logs.js.map +1 -0
  223. package/dist/transport/web/routes/m8.js +69 -0
  224. package/dist/transport/web/routes/m8.js.map +1 -0
  225. package/dist/transport/web/routes/mcp.js +7 -0
  226. package/dist/transport/web/routes/mcp.js.map +1 -0
  227. package/dist/transport/web/routes/message.js +32 -0
  228. package/dist/transport/web/routes/message.js.map +1 -0
  229. package/dist/transport/web/routes/overrides.js +20 -0
  230. package/dist/transport/web/routes/overrides.js.map +1 -0
  231. package/dist/transport/web/routes/question.js +32 -0
  232. package/dist/transport/web/routes/question.js.map +1 -0
  233. package/dist/transport/web/routes/rename.js +12 -0
  234. package/dist/transport/web/routes/rename.js.map +1 -0
  235. package/dist/transport/web/routes/schedules.js +28 -0
  236. package/dist/transport/web/routes/schedules.js.map +1 -0
  237. package/dist/transport/web/routes/session.js +20 -0
  238. package/dist/transport/web/routes/session.js.map +1 -0
  239. package/dist/transport/web/routes/sessions.js +25 -0
  240. package/dist/transport/web/routes/sessions.js.map +1 -0
  241. package/dist/transport/web/routes/subagents.js +11 -0
  242. package/dist/transport/web/routes/subagents.js.map +1 -0
  243. package/dist/transport/web/routes/suggestions.js +7 -0
  244. package/dist/transport/web/routes/suggestions.js.map +1 -0
  245. package/dist/transport/web/routes/todo.js +7 -0
  246. package/dist/transport/web/routes/todo.js.map +1 -0
  247. package/dist/transport/web/routes/version.js +5 -0
  248. package/dist/transport/web/routes/version.js.map +1 -0
  249. package/dist/transport/web/routes/workspaces.js +7 -0
  250. package/dist/transport/web/routes/workspaces.js.map +1 -0
  251. package/dist/transport/web/server.js +111 -0
  252. package/dist/transport/web/server.js.map +1 -0
  253. package/dist/transport/web/session-summary.js +46 -0
  254. package/dist/transport/web/session-summary.js.map +1 -0
  255. package/dist/transport/web/ws-hub.js +83 -0
  256. package/dist/transport/web/ws-hub.js.map +1 -0
  257. package/dist/utils/logger.js +105 -0
  258. package/dist/utils/logger.js.map +1 -0
  259. package/dist/utils/markdown.js +129 -0
  260. package/dist/utils/markdown.js.map +1 -0
  261. package/dist/utils/paths.js +18 -0
  262. package/dist/utils/paths.js.map +1 -0
  263. package/dist/utils/version.js +44 -0
  264. package/dist/utils/version.js.map +1 -0
  265. package/package.json +91 -0
  266. package/web/dist/_app/env.js +1 -0
  267. package/web/dist/_app/immutable/assets/0.DxN3RsuG.css +1 -0
  268. package/web/dist/_app/immutable/assets/2.BNuGfmZP.css +1 -0
  269. package/web/dist/_app/immutable/assets/3.CTDprntu.css +1 -0
  270. package/web/dist/_app/immutable/chunks/BUpwHpMJ.js +1 -0
  271. package/web/dist/_app/immutable/chunks/BjY4dxcB.js +2 -0
  272. package/web/dist/_app/immutable/chunks/C2FuqD3s.js +1 -0
  273. package/web/dist/_app/immutable/chunks/CUHGq08X.js +2 -0
  274. package/web/dist/_app/immutable/chunks/CWj6FrbW.js +1 -0
  275. package/web/dist/_app/immutable/chunks/ClvoqtGj.js +1 -0
  276. package/web/dist/_app/immutable/chunks/DIEDQ_hk.js +1 -0
  277. package/web/dist/_app/immutable/entry/app.BoRpcVMj.js +2 -0
  278. package/web/dist/_app/immutable/entry/start.Cj-PQNTq.js +1 -0
  279. package/web/dist/_app/immutable/nodes/0.y9YEms5p.js +3 -0
  280. package/web/dist/_app/immutable/nodes/1.CPhhiRM2.js +1 -0
  281. package/web/dist/_app/immutable/nodes/2.B_c84Mc9.js +1 -0
  282. package/web/dist/_app/immutable/nodes/3.ClTd0J3D.js +64 -0
  283. package/web/dist/_app/version.json +1 -0
  284. package/web/dist/apple-touch-icon.png +0 -0
  285. package/web/dist/favicon.png +0 -0
  286. package/web/dist/favicon.svg +17 -0
  287. package/web/dist/icon-192.png +0 -0
  288. package/web/dist/icon-512-maskable.png +0 -0
  289. package/web/dist/icon-512.png +0 -0
  290. package/web/dist/index.html +73 -0
  291. package/web/dist/manifest.webmanifest +28 -0
  292. package/web/dist/service-worker.js +1 -0
@@ -0,0 +1,22 @@
1
+ import { listFiles } from '../../../core/list-files.js';
2
+ /**
3
+ * Files in a session's working directory — backs the composer's @-mention picker.
4
+ * GET /api/session/:id/files?q=<filter> → workspace-relative paths (bounded).
5
+ */
6
+ export function registerFiles(app, reg, state) {
7
+ app.get('/api/session/:id/files', async (c) => {
8
+ const id = state.normalizeSessionId(c.req.param('id'));
9
+ const q = c.req.query('q') ?? '';
10
+ let dir;
11
+ try {
12
+ dir = (await reg.forSession(id).getContext(id)).directory;
13
+ }
14
+ catch {
15
+ dir = undefined;
16
+ }
17
+ if (!dir)
18
+ return c.json([]);
19
+ return c.json(await listFiles(dir, q));
20
+ });
21
+ }
22
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/files.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAA;AAEvD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,GAAS,EAAE,GAAoB,EAAE,KAAmB;IAChF,GAAG,CAAC,GAAG,CAAC,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC5C,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QACtD,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAA;QAChC,IAAI,GAAuB,CAAA;QAC3B,IAAI,CAAC;YAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,GAAG,GAAG,SAAS,CAAA;QAAC,CAAC;QAC3F,IAAI,CAAC,GAAG;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC3B,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;IACxC,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { recentLogs } from '../../../utils/logger.js';
2
+ export function registerLogs(app) {
3
+ app.get('/api/logs', (c) => {
4
+ const limitRaw = Number(c.req.query('limit') ?? 200);
5
+ const limit = Number.isFinite(limitRaw) ? Math.min(Math.max(limitRaw, 1), 500) : 200;
6
+ return c.json({ lines: recentLogs(limit) });
7
+ });
8
+ }
9
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/logs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAErD,MAAM,UAAU,YAAY,CAAC,GAAS;IACpC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE;QACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,CAAA;QACpD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;QACpF,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAC7C,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * M8: skills / files / worktree sandboxes — thin proxies over the active
3
+ * backend. `directory` defaults to the active workspace when the client
4
+ * doesn't pin one.
5
+ */
6
+ export function registerM8(app, reg, state) {
7
+ // Hono's Context.query has overloads that fight structural typing — any here.
8
+ const dir = (c) => {
9
+ const q = String(c.req?.query('directory') ?? '');
10
+ if (q)
11
+ return q;
12
+ const active = state.getActiveWorkspace();
13
+ return active ?? '';
14
+ };
15
+ app.get('/api/skills', async (c) => {
16
+ const b = reg.active();
17
+ if (!b.getSkills)
18
+ return c.json({ skills: [] });
19
+ const d = dir(c);
20
+ return c.json({ skills: await b.getSkills(d || undefined) });
21
+ });
22
+ app.get('/api/browse', async (c) => {
23
+ const b = reg.active();
24
+ if (!b.listFiles)
25
+ return c.json({ files: [] });
26
+ const d = dir(c);
27
+ return c.json({ files: await b.listFiles(d || undefined, c.req.query('path') ?? '.') });
28
+ });
29
+ app.get('/api/file-content', async (c) => {
30
+ const b = reg.active();
31
+ if (!b.readFile)
32
+ return c.json({ error: 'unsupported' }, 400);
33
+ try {
34
+ const d = dir(c);
35
+ return c.json(await b.readFile(d || undefined, c.req.query('path') ?? '.'));
36
+ }
37
+ catch (err) {
38
+ return c.json({ error: err.message }, 500);
39
+ }
40
+ });
41
+ app.get('/api/worktrees', async (c) => {
42
+ const b = reg.active();
43
+ if (!b.listWorktreeSandboxes)
44
+ return c.json({ worktrees: [] });
45
+ const d = dir(c);
46
+ return c.json({ worktrees: await b.listWorktreeSandboxes(d || undefined) });
47
+ });
48
+ app.post('/api/worktrees', async (c) => {
49
+ const b = reg.active();
50
+ if (!b.createWorktreeSandboxes)
51
+ return c.json({ error: 'unsupported' }, 400);
52
+ const body = (await c.req.json().catch(() => ({})));
53
+ const name = typeof body.name === 'string' ? body.name.trim() : '';
54
+ if (!name)
55
+ return c.json({ error: 'name required' }, 400);
56
+ const d = dir(c);
57
+ const created = await b.createWorktreeSandboxes(d || undefined, name);
58
+ return c.json(created ? { worktree: created } : { error: 'create failed' }, created ? 200 : 500);
59
+ });
60
+ app.delete('/api/worktrees', async (c) => {
61
+ const b = reg.active();
62
+ const name = c.req.query('name') ?? '';
63
+ if (!b.removeWorktreeSandboxes || !name)
64
+ return c.json({ ok: false }, 400);
65
+ const d = dir(c);
66
+ return c.json({ ok: await b.removeWorktreeSandboxes(d || undefined, name) });
67
+ });
68
+ }
69
+ //# sourceMappingURL=m8.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"m8.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/m8.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export function registerMcp(app, reg) {
2
+ app.get('/api/mcp', async (c) => {
3
+ const b = reg.get(c.req.query('backend') ?? '') ?? reg.active();
4
+ return c.json(await b.getMcp());
5
+ });
6
+ }
7
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/mcp.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,WAAW,CAAC,GAAS,EAAE,GAAoB;IACzD,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC9B,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAA;QAC/D,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAA;IACjC,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { createLogger } from '../../../utils/logger.js';
2
+ const log = createLogger('web');
3
+ export function registerMessage(app, onMessage) {
4
+ app.post('/api/message', async (c) => {
5
+ const body = await c.req.json().catch(() => ({}));
6
+ const images = Array.isArray(body.images)
7
+ ? body.images.filter((i) => !!i && typeof i.data === 'string' && typeof i.mimeType === 'string')
8
+ : [];
9
+ const text = typeof body.text === 'string' ? body.text : '';
10
+ if (text.trim() === '' && images.length === 0) {
11
+ return c.json({ error: 'text or images required' }, 400);
12
+ }
13
+ const user = c.get('user');
14
+ // Use the client-supplied id so the echoed user card carries the same id as
15
+ // the optimistic card the UI already inserted — they reconcile (no dupe).
16
+ const messageId = typeof body.clientId === 'string' && body.clientId ? body.clientId : `web_${Date.now()}`;
17
+ const msg = {
18
+ userId: user.sub ?? user.email,
19
+ chatId: `web:${user.email}`,
20
+ text,
21
+ images: images.length ? images : undefined,
22
+ messageId,
23
+ // Route to the session the web UI is viewing, not the global pinned one,
24
+ // so web and Telegram can converse with different sessions independently.
25
+ sessionId: typeof body.sessionId === 'string' && body.sessionId ? body.sessionId : undefined,
26
+ origin: 'web',
27
+ };
28
+ void onMessage(msg).catch((e) => log.warn(`onMessage handler rejected: ${e.message}`));
29
+ return c.json({ messageId });
30
+ });
31
+ }
32
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAEvD,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;AAE/B,MAAM,UAAU,eAAe,CAC7B,GAAS,EACT,SAAkD;IAElD,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAmH,CAAA;QACnK,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;YACvC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAA2C,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC;YACzI,CAAC,CAAC,EAAE,CAAA;QACN,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;QAC3D,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,EAAE,GAAG,CAAC,CAAA;QAC1D,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAmC,CAAA;QAC5D,4EAA4E;QAC5E,0EAA0E;QAC1E,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,EAAE,CAAA;QAC1G,MAAM,GAAG,GAAoB;YAC3B,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK;YAC9B,MAAM,EAAE,OAAO,IAAI,CAAC,KAAK,EAAE;YAC3B,IAAI;YACJ,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;YAC1C,SAAS;YACT,yEAAyE;YACzE,0EAA0E;YAC1E,SAAS,EAAE,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YAC5F,MAAM,EAAE,KAAK;SACd,CAAA;QACD,KAAK,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,+BAAgC,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QACjG,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAA;IAC9B,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ export function registerOverrides(app, state) {
2
+ app.get('/api/overrides', (c) => c.json({ agent: state.getNextAgent() ?? null, model: state.getNextModel() ?? null }));
3
+ app.post('/api/overrides', async (c) => {
4
+ const body = await c.req.json().catch(() => ({}));
5
+ if ('model' in body) {
6
+ // Validate before persisting — a malformed model would be written to disk
7
+ // and silently break the next session's model selection.
8
+ const m = body.model;
9
+ if (m != null && (typeof m !== 'object' || typeof m.providerID !== 'string' || typeof m.modelID !== 'string')) {
10
+ return c.json({ error: 'model must be { providerID: string, modelID: string } or null' }, 400);
11
+ }
12
+ }
13
+ if ('agent' in body)
14
+ state.setNextAgent(body.agent ?? undefined);
15
+ if ('model' in body)
16
+ state.setNextModel(body.model ?? undefined);
17
+ return c.json({ ok: true });
18
+ });
19
+ }
20
+ //# sourceMappingURL=overrides.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overrides.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/overrides.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,iBAAiB,CAAC,GAAS,EAAE,KAAmB;IAC9D,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,EAAE,CAC9B,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,IAAI,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAA;IAEvF,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAG/C,CAAA;QACD,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;YACpB,0EAA0E;YAC1E,yDAAyD;YACzD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAA;YACpB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,EAAE,CAAC;gBAC9G,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+DAA+D,EAAE,EAAE,GAAG,CAAC,CAAA;YAChG,CAAC;QACH,CAAC;QACD,IAAI,OAAO,IAAI,IAAI;YAAE,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC,CAAA;QAChE,IAAI,OAAO,IAAI,IAAI;YAAE,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC,CAAA;QAChE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,32 @@
1
+ function isStringArrayArray(v) {
2
+ return Array.isArray(v) && v.every((row) => Array.isArray(row) && row.every((x) => typeof x === 'string'));
3
+ }
4
+ export function registerQuestion(app, reg, state) {
5
+ app.post('/api/question/reply', async (c) => {
6
+ const body = await c.req.json().catch(() => ({}));
7
+ if (typeof body.sessionId !== 'string' || !body.sessionId)
8
+ return c.json({ error: 'sessionId required' }, 400);
9
+ if (typeof body.requestId !== 'string' || !body.requestId)
10
+ return c.json({ error: 'requestId required' }, 400);
11
+ if (!isStringArrayArray(body.answers))
12
+ return c.json({ error: 'answers must be string[][]' }, 400);
13
+ const id = state.normalizeSessionId(body.sessionId);
14
+ const backend = reg.forSession(id);
15
+ if (!backend.answerQuestion)
16
+ return c.json({ error: 'unsupported' }, 400);
17
+ return c.json(await backend.answerQuestion(id, body.requestId, body.answers));
18
+ });
19
+ app.post('/api/question/reject', async (c) => {
20
+ const body = await c.req.json().catch(() => ({}));
21
+ if (typeof body.sessionId !== 'string' || !body.sessionId)
22
+ return c.json({ error: 'sessionId required' }, 400);
23
+ if (typeof body.requestId !== 'string' || !body.requestId)
24
+ return c.json({ error: 'requestId required' }, 400);
25
+ const id = state.normalizeSessionId(body.sessionId);
26
+ const backend = reg.forSession(id);
27
+ if (!backend.rejectQuestion)
28
+ return c.json({ error: 'unsupported' }, 400);
29
+ return c.json(await backend.rejectQuestion(id, body.requestId));
30
+ });
31
+ }
32
+ //# sourceMappingURL=question.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/question.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export function registerRename(app, reg, state) {
2
+ app.post('/api/sessions/:id/rename', async (c) => {
3
+ const id = state.normalizeSessionId(c.req.param('id'));
4
+ const body = await c.req.json().catch(() => ({}));
5
+ const title = typeof body.title === 'string' ? body.title.trim() : '';
6
+ if (!title)
7
+ return c.json({ error: 'title required' }, 400);
8
+ await reg.forSession(id).renameSession(id, title);
9
+ return c.json({ ok: true });
10
+ });
11
+ }
12
+ //# sourceMappingURL=rename.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rename.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/rename.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,cAAc,CAAC,GAAS,EAAE,GAAoB,EAAE,KAAmB;IACjF,GAAG,CAAC,IAAI,CAAC,0BAA0B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC/C,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QACtD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAuB,CAAA;QACvE,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACrE,IAAI,CAAC,KAAK;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,GAAG,CAAC,CAAA;QAC3D,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;QACjD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ /** P2b-M7: cross-channel scheduled tasks — web front-end (CRUD). */
2
+ export function registerSchedules(app, scheduler) {
3
+ if (!scheduler)
4
+ return;
5
+ app.get('/api/schedules', (c) => c.json({ schedules: scheduler.list() }));
6
+ app.post('/api/schedules', async (c) => {
7
+ const body = (await c.req.json().catch(() => ({})));
8
+ const s = scheduler.add({
9
+ name: typeof body.name === 'string' ? body.name : undefined,
10
+ prompt: typeof body.prompt === 'string' ? body.prompt : '',
11
+ spec: body.spec,
12
+ enabled: body.enabled ?? true,
13
+ });
14
+ return c.json(s ? { schedule: s } : { error: 'invalid schedule' }, s ? 200 : 400);
15
+ });
16
+ app.patch('/api/schedules/:id', async (c) => {
17
+ const id = c.req.param('id');
18
+ const body = (await c.req.json().catch(() => ({})));
19
+ if (typeof body.enabled !== 'boolean')
20
+ return c.json({ error: 'enabled required' }, 400);
21
+ const s = scheduler.setEnabled(id, body.enabled);
22
+ return c.json(s ? { schedule: s } : { error: 'not found' }, s ? 200 : 404);
23
+ });
24
+ app.delete('/api/schedules/:id', (c) => {
25
+ return c.json({ ok: scheduler.remove(c.req.param('id')) });
26
+ });
27
+ }
28
+ //# sourceMappingURL=schedules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedules.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/schedules.ts"],"names":[],"mappings":"AAGA,oEAAoE;AACpE,MAAM,UAAU,iBAAiB,CAAC,GAAS,EAAE,SAAqB;IAChE,IAAI,CAAC,SAAS;QAAE,OAAM;IAEtB,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAA;IAEzE,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAgD,CAAA;QAClG,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC;YACtB,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;YAC3D,MAAM,EAAE,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YAC1D,IAAI,EAAE,IAAI,CAAC,IAA6B;YACxC,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI;SAC9B,CAAC,CAAA;QACF,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IACnF,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC1C,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC5B,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAA0B,CAAA;QAC5E,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,SAAS;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,GAAG,CAAC,CAAA;QACxF,MAAM,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;QAChD,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAC5E,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC,CAAC,EAAE,EAAE;QACrC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAA;IAC5D,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { DEFAULT_HISTORY_LIMIT } from '../../../core/history.js';
2
+ export function registerSession(app, reg, cardBus, state) {
3
+ app.get('/api/session/:id', async (c) => {
4
+ const rawId = c.req.param('id');
5
+ const id = state.normalizeSessionId(rawId);
6
+ const raw = c.req.query('limit');
7
+ const limit = raw ? Math.max(0, Math.min(500, parseInt(raw, 10) || 0)) : undefined;
8
+ const rawOffset = c.req.query('offset');
9
+ const offset = rawOffset ? Math.max(0, Math.min(2000, parseInt(rawOffset, 10) || 0)) : 0;
10
+ const effectiveLimit = limit ?? DEFAULT_HISTORY_LIMIT;
11
+ const cards = await reg.forSession(id).getHistory(id, limit, offset);
12
+ // Heuristic: a full page means older messages may exist. Card count can
13
+ // fall below message count (roles without cards), so this errs toward an
14
+ // extra empty page — the client hides the button when a page comes back
15
+ // short, never loses history.
16
+ const hasMore = cards.length >= effectiveLimit;
17
+ return c.json({ cards, lastSeq: cardBus.currentSeq(id), hasMore });
18
+ });
19
+ }
20
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/session.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,MAAM,UAAU,eAAe,CAAC,GAAS,EAAE,GAAoB,EAAE,OAAgB,EAAE,KAAmB;IACpG,GAAG,CAAC,GAAG,CAAC,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACtC,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC/B,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAA;QAC1C,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAChC,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAClF,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QACvC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACxF,MAAM,cAAc,GAAG,KAAK,IAAI,qBAAqB,CAAA;QACrD,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QACpE,wEAAwE;QACxE,yEAAyE;QACzE,wEAAwE;QACxE,8BAA8B;QAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,IAAI,cAAc,CAAA;QAC9C,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;IACpE,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { fetchSessionSummaries, cleanupSubagentSessions } from '../session-summary.js';
2
+ import { createLogger } from '../../../utils/logger.js';
3
+ const log = createLogger('web');
4
+ export function registerSessions(app, reg, state) {
5
+ app.get('/api/sessions', async (c) => {
6
+ const summaries = await fetchSessionSummaries(reg, state);
7
+ return c.json(summaries);
8
+ });
9
+ app.post('/api/sessions/cleanup-subagents', async (c) => {
10
+ const deleted = await cleanupSubagentSessions(reg);
11
+ return c.json({ deleted });
12
+ });
13
+ app.post('/api/sessions/:id/delete', async (c) => {
14
+ const id = state.normalizeSessionId(c.req.param('id'));
15
+ try {
16
+ await reg.forSession(id).deleteSession(id);
17
+ return c.json({ ok: true });
18
+ }
19
+ catch (e) {
20
+ log.warn(`delete session ${id} failed: ${e.message}`);
21
+ return c.json({ ok: false, error: 'failed to delete session' }, 500);
22
+ }
23
+ });
24
+ }
25
+ //# sourceMappingURL=sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/sessions.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACtF,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAEvD,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;AAE/B,MAAM,UAAU,gBAAgB,CAAC,GAAS,EAAE,GAAoB,EAAE,KAAmB;IACnF,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACnC,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACzD,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAC1B,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,IAAI,CAAC,iCAAiC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACtD,MAAM,OAAO,GAAG,MAAM,uBAAuB,CAAC,GAAG,CAAC,CAAA;QAClD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,IAAI,CAAC,0BAA0B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC/C,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QACtD,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;YAC1C,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;QAC7B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,YAAa,CAAW,CAAC,OAAO,EAAE,CAAC,CAAA;YAChE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,EAAE,GAAG,CAAC,CAAA;QACtE,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ /** Subagent (child) sessions of a turn — feeds the plan-HUD badge/list. */
2
+ export function registerSubagents(app, reg, state) {
3
+ app.get('/api/session/:id/subagents', async (c) => {
4
+ const b = reg.forSession(c.req.param('id'));
5
+ if (!b.getSubagents)
6
+ return c.json({ subagents: [] });
7
+ const id = state.normalizeSessionId(c.req.param('id'));
8
+ return c.json({ subagents: await b.getSubagents(id) });
9
+ });
10
+ }
11
+ //# sourceMappingURL=subagents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagents.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/subagents.ts"],"names":[],"mappings":"AAIA,2EAA2E;AAC3E,MAAM,UAAU,iBAAiB,CAAC,GAAS,EAAE,GAAoB,EAAE,KAAmB;IACpF,GAAG,CAAC,GAAG,CAAC,4BAA4B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAChD,MAAM,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QAC3C,IAAI,CAAC,CAAC,CAAC,YAAY;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAA;QACrD,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QACtD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ /** Tier2 suggested follow-ups for a session (generated post-finalize, in-memory). */
2
+ export function registerSuggestions(app, state) {
3
+ app.get('/api/session/:id/suggestions', async (c) => {
4
+ return c.json({ suggestions: state.getSessionSuggestions(c.req.param('id')) ?? [] });
5
+ });
6
+ }
7
+ //# sourceMappingURL=suggestions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggestions.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/suggestions.ts"],"names":[],"mappings":"AAGA,qFAAqF;AACrF,MAAM,UAAU,mBAAmB,CAAC,GAAS,EAAE,KAAmB;IAChE,GAAG,CAAC,GAAG,CAAC,8BAA8B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAClD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IACtF,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ export function registerTodo(app, reg, state) {
2
+ app.get('/api/session/:id/todo', async (c) => {
3
+ const id = state.normalizeSessionId(c.req.param('id'));
4
+ return c.json(await reg.forSession(id).getTodos(id));
5
+ });
6
+ }
7
+ //# sourceMappingURL=todo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todo.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/todo.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,YAAY,CAAC,GAAS,EAAE,GAAoB,EAAE,KAAmB;IAC/E,GAAG,CAAC,GAAG,CAAC,uBAAuB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC3C,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QACtD,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { getVersionInfo } from '../../../utils/version.js';
2
+ export function registerVersion(app) {
3
+ app.get('/api/version', (c) => c.json(getVersionInfo()));
4
+ }
5
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/version.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAE1D,MAAM,UAAU,eAAe,CAAC,GAAS;IACvC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,CAAA;AAC1D,CAAC"}
@@ -0,0 +1,7 @@
1
+ export function registerWorkspaces(app, reg) {
2
+ app.get('/api/workspaces', async (c) => {
3
+ const b = reg.get(c.req.query('backend') ?? '') ?? reg.active();
4
+ return c.json(await b.listWorkspaces());
5
+ });
6
+ }
7
+ //# sourceMappingURL=workspaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/workspaces.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,kBAAkB,CAAC,GAAS,EAAE,GAAoB;IAChE,GAAG,CAAC,GAAG,CAAC,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACrC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAA;QAC/D,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,cAAc,EAAE,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,111 @@
1
+ import { Hono } from 'hono';
2
+ import { createLogger } from '../../utils/logger.js';
3
+ import { hostname } from 'node:os';
4
+ const log = createLogger('web');
5
+ import { registerSessions } from './routes/sessions.js';
6
+ import { registerSession } from './routes/session.js';
7
+ import { registerMessage } from './routes/message.js';
8
+ import { registerAbort } from './routes/abort.js';
9
+ import { registerDiff } from './routes/diff.js';
10
+ import { registerTodo } from './routes/todo.js';
11
+ import { registerControls } from './routes/controls.js';
12
+ import { registerFiles } from './routes/files.js';
13
+ import { registerContext } from './routes/context.js';
14
+ import { registerApproval } from './routes/approval.js';
15
+ import { registerQuestion } from './routes/question.js';
16
+ import { registerVersion } from './routes/version.js';
17
+ import { registerLogs } from './routes/logs.js';
18
+ import { registerMcp } from './routes/mcp.js';
19
+ import { registerCatalog } from './routes/catalog.js';
20
+ import { registerOverrides } from './routes/overrides.js';
21
+ import { registerWorkspaces } from './routes/workspaces.js';
22
+ import { registerCreateSession } from './routes/create-session.js';
23
+ import { registerCommands } from './routes/commands.js';
24
+ import { registerRename } from './routes/rename.js';
25
+ import { registerSuggestions } from './routes/suggestions.js';
26
+ import { registerSchedules } from './routes/schedules.js';
27
+ import { registerChannels } from './routes/channels.js';
28
+ import { registerSubagents } from './routes/subagents.js';
29
+ import { registerM8 } from './routes/m8.js';
30
+ export function buildServer(opts) {
31
+ const app = new Hono();
32
+ app.use('/api/*', async (c, next) => {
33
+ const t0 = Date.now();
34
+ await next();
35
+ log.info(`${c.req.method} ${c.req.path} → ${c.res.status} ${Date.now() - t0}ms`);
36
+ });
37
+ app.use('/api/*', opts.auth.httpMiddleware());
38
+ app.get('/api/me', (c) => {
39
+ const user = c.get('user');
40
+ if (!user)
41
+ return c.json({ error: 'unauthorized' }, 401);
42
+ return c.json({ email: user.email });
43
+ });
44
+ const reg = opts.registry;
45
+ // Backwards-compatible single-backend shape: the ACTIVE backend (the one new
46
+ // sessions use). The frontend reads /api/backends for the full set + per-session
47
+ // capabilities (each session row carries its backendId).
48
+ app.get('/api/capabilities', (c) => {
49
+ const active = reg.get(reg.activeId());
50
+ return c.json({ id: active.id, capabilities: active.capabilities });
51
+ });
52
+ // Multi-backend ("agents"): the full set + display name + connection status + which
53
+ // one new sessions go to. status comes from a bounded ping per backend.
54
+ app.get('/api/backends', async (c) => {
55
+ const backends = await Promise.all(reg.all().map(async ({ id, backend }) => {
56
+ let online = false;
57
+ try {
58
+ online = await Promise.race([
59
+ backend.ping(),
60
+ new Promise((r) => setTimeout(() => r(false), 1500)),
61
+ ]);
62
+ }
63
+ catch {
64
+ online = false;
65
+ }
66
+ return {
67
+ id,
68
+ name: id.startsWith('acp:') ? id.slice(4) : id,
69
+ host: hostname(),
70
+ status: online ? 'online' : 'offline',
71
+ capabilities: backend.capabilities,
72
+ };
73
+ }));
74
+ return c.json({ backends, activeId: reg.activeId() });
75
+ });
76
+ app.post('/api/backends/active', async (c) => {
77
+ const body = (await c.req.json().catch(() => ({})));
78
+ if (!body.backendId || !reg.has(body.backendId))
79
+ return c.json({ error: 'unknown backendId' }, 400);
80
+ opts.state.setActiveBackend(body.backendId);
81
+ return c.json({ ok: true, activeId: reg.activeId() });
82
+ });
83
+ registerSessions(app, reg, opts.state);
84
+ registerSession(app, reg, opts.cardBus, opts.state);
85
+ if (opts.onMessage)
86
+ registerMessage(app, opts.onMessage);
87
+ registerAbort(app, reg, opts.state);
88
+ registerDiff(app, reg, opts.state);
89
+ registerTodo(app, reg, opts.state);
90
+ registerControls(app, reg, opts.state);
91
+ registerFiles(app, reg, opts.state);
92
+ registerContext(app, reg, opts.state);
93
+ registerApproval(app, reg, opts.state);
94
+ registerQuestion(app, reg, opts.state);
95
+ registerVersion(app);
96
+ registerLogs(app);
97
+ registerMcp(app, reg);
98
+ registerCatalog(app, reg);
99
+ registerOverrides(app, opts.state);
100
+ registerWorkspaces(app, reg);
101
+ registerCreateSession(app, reg);
102
+ registerCommands(app, reg, opts.state);
103
+ registerRename(app, reg, opts.state);
104
+ registerSuggestions(app, opts.state);
105
+ registerSchedules(app, opts.scheduler);
106
+ registerChannels(app, opts.channels, opts.telegramStatus);
107
+ registerSubagents(app, reg, opts.state);
108
+ registerM8(app, reg, opts.state);
109
+ return app;
110
+ }
111
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/transport/web/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Aggregate session summaries across every backend in the registry, tagging each
3
+ * row with its owning `backendId` (and recording that ownership in the registry
4
+ * so later per-session routing resolves correctly). Costs are filled from OCRC
5
+ * state. A backend that fails to list is skipped, not fatal.
6
+ */
7
+ export async function fetchSessionSummaries(registry, state) {
8
+ const out = [];
9
+ for (const { id, backend } of registry.all()) {
10
+ let rows;
11
+ try {
12
+ rows = await backend.listSessionSummaries();
13
+ }
14
+ catch {
15
+ continue;
16
+ }
17
+ for (const s of rows) {
18
+ registry.tag(s.id, id);
19
+ out.push({ ...s, backendId: id, cost: state.getSessionCost(s.id) ?? s.cost });
20
+ }
21
+ }
22
+ return out;
23
+ }
24
+ export async function cleanupSubagentSessions(registry) {
25
+ let deleted = 0;
26
+ for (const { backend } of registry.all()) {
27
+ let children;
28
+ try {
29
+ children = (await backend.listSessions()).filter((s) => !!s.parentID);
30
+ }
31
+ catch {
32
+ continue;
33
+ }
34
+ for (const s of children) {
35
+ try {
36
+ await backend.deleteSession(s.id);
37
+ deleted++;
38
+ }
39
+ catch {
40
+ /* skip ones that fail; report how many succeeded */
41
+ }
42
+ }
43
+ }
44
+ return deleted;
45
+ }
46
+ //# sourceMappingURL=session-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-summary.js","sourceRoot":"","sources":["../../../src/transport/web/session-summary.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,QAAyB,EACzB,KAAmB;IAEnB,MAAM,GAAG,GAAqB,EAAE,CAAA;IAChC,KAAK,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC;QAC7C,IAAI,IAAsB,CAAA;QAC1B,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,OAAO,CAAC,oBAAoB,EAAE,CAAA;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,SAAQ;QACV,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;YACtB,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;QAC/E,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,QAAyB;IACrE,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC;QACzC,IAAI,QAAQ,CAAA;QACZ,IAAI,CAAC;YACH,QAAQ,GAAG,CAAC,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;QACvE,CAAC;QAAC,MAAM,CAAC;YACP,SAAQ;QACV,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;gBACjC,OAAO,EAAE,CAAA;YACX,CAAC;YAAC,MAAM,CAAC;gBACP,oDAAoD;YACtD,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC"}