@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,69 @@
1
+ import { sessionIdOf, errorMessageOf } from '../opencode-events.js';
2
+ /** One-line tool-arg summary (was inside stream-accumulator; opencode-specific). */
3
+ function summarizeArgs(tool, input) {
4
+ if (!input)
5
+ return '';
6
+ if (tool === 'bash' && typeof input.cmd === 'string') {
7
+ return input.cmd.length > 60 ? input.cmd.slice(0, 57) + '...' : input.cmd;
8
+ }
9
+ const keys = Object.keys(input);
10
+ if (keys.length === 0)
11
+ return '';
12
+ const first = String(input[keys[0]]);
13
+ return first.length > 60 ? first.slice(0, 57) + '...' : first;
14
+ }
15
+ function mapToolStatus(s) {
16
+ return s === 'error' ? 'error' : s === 'done' || s === 'completed' ? 'done' : 'running';
17
+ }
18
+ function normalizePart(part) {
19
+ if (!part)
20
+ return null;
21
+ // Opencode parts carry an id; synthesize a stable one when missing so the
22
+ // accumulator can still key it (matches the relay's previous effectiveId).
23
+ const id = typeof part.id === 'string'
24
+ ? part.id
25
+ : `${part.type ?? 'unknown'}:${JSON.stringify(part.state?.input ?? {}).slice(0, 60)}`;
26
+ if (part.type === 'text')
27
+ return { id, type: 'text', text: part.text };
28
+ if (part.type === 'reasoning')
29
+ return { id, type: 'reasoning', text: part.text };
30
+ if (part.type === 'tool' && typeof part.tool === 'string') {
31
+ return { id, type: 'tool', tool: part.tool, args: summarizeArgs(part.tool, part.state?.input), status: mapToolStatus(part.state?.status) };
32
+ }
33
+ return null;
34
+ }
35
+ /** Normalize one opencode event, or null when it's not relevant to the relay. */
36
+ export function normalizeOpencodeEvent(ev) {
37
+ const type = ev.type;
38
+ if (!type)
39
+ return null;
40
+ const p = ev.properties ?? {};
41
+ const sessionId = sessionIdOf(ev);
42
+ if (type === 'message.part.updated') {
43
+ if (!sessionId)
44
+ return null;
45
+ const part = normalizePart(p.part);
46
+ if (!part)
47
+ return null;
48
+ return { kind: 'part', sessionId, messageId: p.part?.messageID, part };
49
+ }
50
+ if (type === 'message.part.delta') {
51
+ if (!sessionId)
52
+ return null;
53
+ const partId = typeof p.partID === 'string' ? p.partID : undefined;
54
+ if (!partId || p.field !== 'text' || typeof p.delta !== 'string')
55
+ return null;
56
+ return { kind: 'delta', sessionId, messageId: typeof p.messageID === 'string' ? p.messageID : undefined, partId, text: p.delta };
57
+ }
58
+ if (type === 'session.idle') {
59
+ if (!sessionId)
60
+ return null;
61
+ return { kind: 'idle', sessionId };
62
+ }
63
+ if (type === 'session.error') {
64
+ return { kind: 'error', sessionId: sessionId ?? 'unknown', message: errorMessageOf(p) };
65
+ }
66
+ // message.updated and everything else are not relay-relevant.
67
+ return null;
68
+ }
69
+ //# sourceMappingURL=opencode-normalizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-normalizer.js","sourceRoot":"","sources":["../../../src/core/agent/opencode-normalizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * A trivial registry over a single backend — every session resolves to it. For
3
+ * single-backend callers (the opencode plugin, a one-agent host) and tests that
4
+ * don't need session→backend persistence.
5
+ */
6
+ export function singleBackendRegistry(backend) {
7
+ return {
8
+ list: () => [{ id: backend.id, capabilities: backend.capabilities }],
9
+ all: () => [{ id: backend.id, backend }],
10
+ get: (id) => (id === backend.id ? backend : undefined),
11
+ has: (id) => id === backend.id,
12
+ primaryId: () => backend.id,
13
+ activeId: () => backend.id,
14
+ active: () => backend,
15
+ idForSession: () => backend.id,
16
+ forSession: () => backend,
17
+ tag: () => { },
18
+ };
19
+ }
20
+ export function createBackendRegistry(opts) {
21
+ const { state } = opts;
22
+ if (opts.backends.length === 0)
23
+ throw new Error('BackendRegistry needs at least one backend');
24
+ const byId = new Map(opts.backends.map((b) => [b.id, b.backend]));
25
+ const primary = opts.primaryId && byId.has(opts.primaryId) ? opts.primaryId : opts.backends[0].id;
26
+ const resolveId = (sid) => {
27
+ const tagged = state.getSessionBackend(sid);
28
+ if (tagged && byId.has(tagged))
29
+ return tagged;
30
+ return primary;
31
+ };
32
+ const activeId = () => {
33
+ const a = state.getActiveBackend();
34
+ return a && byId.has(a) ? a : primary;
35
+ };
36
+ return {
37
+ list: () => opts.backends.map((b) => ({ id: b.id, capabilities: b.backend.capabilities })),
38
+ all: () => opts.backends.slice(),
39
+ get: (id) => byId.get(id),
40
+ has: (id) => byId.has(id),
41
+ primaryId: () => primary,
42
+ activeId,
43
+ // Closure arrow like every other member — a method shorthand relying on
44
+ // `this` breaks when destructured (e.g. `const { active } = registry`).
45
+ active: () => byId.get(activeId()),
46
+ idForSession: resolveId,
47
+ forSession: (sid) => byId.get(resolveId(sid)),
48
+ tag: (sid, backendId) => {
49
+ if (byId.has(backendId) && state.getSessionBackend(sid) !== backendId) {
50
+ state.setSessionBackend(sid, backendId);
51
+ }
52
+ },
53
+ };
54
+ }
55
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/core/agent/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,176 @@
1
+ import { createLogger } from '../../utils/logger.js';
2
+ const log = createLogger('v2-backend');
3
+ const CAPABILITIES = {
4
+ liveMirror: true, // in-process: the host IS the local session runner
5
+ tuiSelect: false, // no TUI navigation in V2 ctx
6
+ workspaces: false, // P2a: directory routing
7
+ freeformWorkspace: false,
8
+ diff: false,
9
+ todos: false,
10
+ catalog: false, // ctx has no models/agents enumeration slice (yet)
11
+ mcp: false,
12
+ commands: false,
13
+ sessionControls: false,
14
+ imageInput: false,
15
+ };
16
+ function msTime(v) {
17
+ if (typeof v === 'number')
18
+ return v;
19
+ if (typeof v === 'string') {
20
+ const t = Date.parse(v);
21
+ return Number.isFinite(t) ? t : undefined;
22
+ }
23
+ return undefined;
24
+ }
25
+ function mapSessionInfo(info) {
26
+ const model = typeof info.model === 'string' ? info.model : info.model ? [info.model.providerID, info.model.modelID].filter(Boolean).join('/') : undefined;
27
+ const tokens = info.tokens && (info.tokens.input !== undefined || info.tokens.output !== undefined)
28
+ ? { input: Number(info.tokens.input ?? 0), output: Number(info.tokens.output ?? 0) }
29
+ : undefined;
30
+ return {
31
+ agent: typeof info.agent === 'string' ? info.agent : undefined,
32
+ model: model || undefined,
33
+ cost: typeof info.cost === 'number' ? info.cost : undefined,
34
+ tokens,
35
+ };
36
+ }
37
+ export function createV2Backend(ctx) {
38
+ /** Sessions seen on the event stream — V2 ctx has no session.list. Seeded by
39
+ * create/get calls and kept fresh by the control-plane's event feed. */
40
+ const seen = new Map();
41
+ const remember = (info) => {
42
+ const id = info?.id;
43
+ if (typeof id !== 'string' || !id)
44
+ return;
45
+ seen.set(id, {
46
+ id,
47
+ title: typeof info.title === 'string' ? info.title : seen.get(id)?.title,
48
+ updatedAt: Date.now(),
49
+ agent: typeof info.agent === 'string' ? info.agent : seen.get(id)?.agent,
50
+ });
51
+ };
52
+ const backend = {
53
+ id: 'opencode',
54
+ capabilities: CAPABILITIES,
55
+ async prompt(sessionId, input) {
56
+ await ctx.session.prompt({ sessionID: sessionId, id: { text: input.text } });
57
+ },
58
+ async abort(id) {
59
+ await ctx.session.interrupt({ sessionID: id });
60
+ },
61
+ async hasSession(id) {
62
+ if (seen.has(id))
63
+ return true;
64
+ try {
65
+ remember(await ctx.session.get({ sessionID: id }));
66
+ return true;
67
+ }
68
+ catch {
69
+ return false;
70
+ }
71
+ },
72
+ async listSessions() {
73
+ return [...seen.values()]
74
+ .sort((a, b) => b.updatedAt - a.updatedAt)
75
+ .map((s) => ({ id: s.id, title: s.title, updatedAt: s.updatedAt }));
76
+ },
77
+ async listSessionSummaries() {
78
+ return [...seen.values()]
79
+ .sort((a, b) => b.updatedAt - a.updatedAt)
80
+ .map((s) => ({ id: s.id, title: s.title, agent: s.agent, lastActiveAt: s.updatedAt, unread: false }));
81
+ },
82
+ async createSession(opts) {
83
+ const info = (await ctx.session.create({
84
+ id: { title: opts.title },
85
+ ...(opts.directory ? { location: { directory: opts.directory } } : {}),
86
+ }));
87
+ remember(info);
88
+ return { id: String(info?.id ?? '') };
89
+ },
90
+ async deleteSession(_id) {
91
+ // V2 ctx does not expose session removal (yet).
92
+ throw new Error('session deletion is not supported on opencode V2 hosts yet');
93
+ },
94
+ async renameSession(id, title) {
95
+ await ctx.session.rename({ sessionID: id, id: { title } });
96
+ const s = seen.get(id);
97
+ if (s)
98
+ s.title = title;
99
+ },
100
+ async getSessionMeta(id) {
101
+ remember(await ctx.session.get({ sessionID: id }));
102
+ return mapSessionInfo(await ctx.session.get({ sessionID: id }));
103
+ },
104
+ async getContext(id) {
105
+ const info = await ctx.session.get({ sessionID: id });
106
+ remember(info);
107
+ return { ...mapSessionInfo(info), directory: info.directory };
108
+ },
109
+ // ── reads not exposed by the V2 ctx — honest empties (capability-gated) ──
110
+ async getHistory(_id, _limit, _offset) {
111
+ return [];
112
+ },
113
+ async getMessageBlocks(_sessionId, _messageId) {
114
+ return [];
115
+ },
116
+ async getDiff(_id) {
117
+ return [];
118
+ },
119
+ async getTodos(_id) {
120
+ return [];
121
+ },
122
+ async getSessionsStatus() {
123
+ const all = [...seen.values()];
124
+ return { sessions: all.length, busy: 0, backend: 'opencode-v2' };
125
+ },
126
+ async ping() {
127
+ // In-process: the host is alive iff we are.
128
+ return true;
129
+ },
130
+ // ── catalog / commands ──
131
+ async getAgents(_directory) {
132
+ return [];
133
+ },
134
+ async getModels(_directory) {
135
+ return [];
136
+ },
137
+ async getMcp(_directory) {
138
+ return [];
139
+ },
140
+ async listWorkspaces() {
141
+ return [];
142
+ },
143
+ async listCommands() {
144
+ return [];
145
+ },
146
+ async runCommand(_id, _command, _args) {
147
+ throw new Error('slash-commands are not supported on opencode V2 hosts yet');
148
+ },
149
+ // ── permissions ──
150
+ async resolvePermission(id, requestId, decision) {
151
+ // V2 PermissionReply is exactly "once" | "always" | "reject" — same
152
+ // semantics as V1/OCRC, zero mapping (docs/v2-api-notes.md §3).
153
+ await ctx.permission.reply({ sessionID: id, requestID: requestId, reply: decision });
154
+ },
155
+ };
156
+ /** Session-registry maintenance, fed by the control plane's event loop. */
157
+ function observeSessionEvent(ev) {
158
+ if (!ev.sessionID)
159
+ return;
160
+ if (ev.type === 'session.deleted') {
161
+ seen.delete(ev.sessionID);
162
+ return;
163
+ }
164
+ if (ev.type === 'session.created' || ev.type === 'session.updated' || ev.type === 'session.renamed') {
165
+ const prev = seen.get(ev.sessionID);
166
+ seen.set(ev.sessionID, {
167
+ id: ev.sessionID,
168
+ title: ev.title ?? prev?.title,
169
+ agent: ev.agent ?? prev?.agent,
170
+ updatedAt: Date.now(),
171
+ });
172
+ }
173
+ }
174
+ return { backend, observeSessionEvent };
175
+ }
176
+ //# sourceMappingURL=v2-backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2-backend.js","sourceRoot":"","sources":["../../../src/core/agent/v2-backend.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEpD,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,CAAC,CAAA;AAEtC,MAAM,YAAY,GAAwB;IACxC,UAAU,EAAE,IAAI,EAAO,mDAAmD;IAC1E,SAAS,EAAE,KAAK,EAAO,8BAA8B;IACrD,UAAU,EAAE,KAAK,EAAM,yBAAyB;IAChD,iBAAiB,EAAE,KAAK;IACxB,IAAI,EAAE,KAAK;IACX,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,KAAK,EAAS,mDAAmD;IAC1E,GAAG,EAAE,KAAK;IACV,QAAQ,EAAE,KAAK;IACf,eAAe,EAAE,KAAK;IACtB,UAAU,EAAE,KAAK;CAClB,CAAA;AAED,SAAS,MAAM,CAAC,CAAU;IACxB,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAA;IACnC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAAC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAAC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAAC,CAAC;IACjG,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,cAAc,CAAC,IAAmB;IACzC,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC1J,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC;QACjG,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE;QACpF,CAAC,CAAC,SAAS,CAAA;IACb,OAAO;QACL,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QAC9D,KAAK,EAAE,KAAK,IAAI,SAAS;QACzB,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QAC3D,MAAM;KACP,CAAA;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAc;IAC5C;6EACyE;IACzE,MAAM,IAAI,GAAG,IAAI,GAAG,EAA6E,CAAA;IAEjG,MAAM,QAAQ,GAAG,CAAC,IAA+B,EAAE,EAAE;QACnD,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,CAAA;QACnB,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,EAAE;YAAE,OAAM;QACzC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE;YACX,EAAE;YACF,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK;YACxE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK;SACzE,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,OAAO,GAAiB;QAC5B,EAAE,EAAE,UAAU;QACd,YAAY,EAAE,YAAY;QAE1B,KAAK,CAAC,MAAM,CAAC,SAAiB,EAAE,KAAkB;YAChD,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAC9E,CAAC;QAED,KAAK,CAAC,KAAK,CAAC,EAAU;YACpB,MAAM,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAA;QAChD,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,EAAU;YACzB,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,OAAO,IAAI,CAAA;YAC7B,IAAI,CAAC;gBACH,QAAQ,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;gBAClD,OAAO,IAAI,CAAA;YACb,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAA;YACd,CAAC;QACH,CAAC;QAED,KAAK,CAAC,YAAY;YAChB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;iBACtB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;iBACzC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;QACvE,CAAC;QAED,KAAK,CAAC,oBAAoB;YACxB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;iBACtB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;iBACzC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;QACzG,CAAC;QAED,KAAK,CAAC,aAAa,CAAC,IAA2C;YAC7D,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;gBACrC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;gBACzB,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACvE,CAAC,CAAkB,CAAA;YACpB,QAAQ,CAAC,IAAI,CAAC,CAAA;YACd,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAA;QACvC,CAAC;QAED,KAAK,CAAC,aAAa,CAAC,GAAW;YAC7B,gDAAgD;YAChD,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAA;QAC/E,CAAC;QAED,KAAK,CAAC,aAAa,CAAC,EAAU,EAAE,KAAa;YAC3C,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;YAC1D,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACtB,IAAI,CAAC;gBAAE,CAAC,CAAC,KAAK,GAAG,KAAK,CAAA;QACxB,CAAC;QAED,KAAK,CAAC,cAAc,CAAC,EAAU;YAC7B,QAAQ,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;YAClD,OAAO,cAAc,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QACjE,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,EAAU;YACzB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAA;YACrD,QAAQ,CAAC,IAAI,CAAC,CAAA;YACd,OAAO,EAAE,GAAG,cAAc,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAA;QAC/D,CAAC;QAED,4EAA4E;QAC5E,KAAK,CAAC,UAAU,CAAC,GAAW,EAAE,MAAe,EAAE,OAAgB;YAC7D,OAAO,EAAE,CAAA;QACX,CAAC;QACD,KAAK,CAAC,gBAAgB,CAAC,UAAkB,EAAE,UAAkB;YAC3D,OAAO,EAAE,CAAA;QACX,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,GAAW;YACvB,OAAO,EAAE,CAAA;QACX,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,GAAW;YACxB,OAAO,EAAE,CAAA;QACX,CAAC;QACD,KAAK,CAAC,iBAAiB;YACrB,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;YAC9B,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,CAAA;QAClE,CAAC;QACD,KAAK,CAAC,IAAI;YACR,4CAA4C;YAC5C,OAAO,IAAI,CAAA;QACb,CAAC;QAED,2BAA2B;QAC3B,KAAK,CAAC,SAAS,CAAC,UAAmB;YACjC,OAAO,EAAE,CAAA;QACX,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,UAAmB;YACjC,OAAO,EAAE,CAAA;QACX,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,UAAmB;YAC9B,OAAO,EAAE,CAAA;QACX,CAAC;QACD,KAAK,CAAC,cAAc;YAClB,OAAO,EAAE,CAAA;QACX,CAAC;QACD,KAAK,CAAC,YAAY;YAChB,OAAO,EAAE,CAAA;QACX,CAAC;QACD,KAAK,CAAC,UAAU,CAAC,GAAW,EAAE,QAAgB,EAAE,KAAc;YAC5D,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAA;QAC9E,CAAC;QAED,oBAAoB;QACpB,KAAK,CAAC,iBAAiB,CAAC,EAAU,EAAE,SAAiB,EAAE,QAAsC;YAC3F,oEAAoE;YACpE,gEAAgE;YAChE,MAAM,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;QACtF,CAAC;KACF,CAAA;IAED,2EAA2E;IAC3E,SAAS,mBAAmB,CAAC,EAAyD;QACpF,IAAI,CAAC,EAAE,CAAC,SAAS;YAAE,OAAM;QACzB,IAAI,EAAE,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAA;YACzB,OAAM;QACR,CAAC;QACD,IAAI,EAAE,CAAC,IAAI,KAAK,iBAAiB,IAAI,EAAE,CAAC,IAAI,KAAK,iBAAiB,IAAI,EAAE,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YACpG,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,CAAA;YACnC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE;gBACrB,EAAE,EAAE,EAAE,CAAC,SAAS;gBAChB,KAAK,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,EAAE,KAAK;gBAC9B,KAAK,EAAG,EAAU,CAAC,KAAK,IAAI,IAAI,EAAE,KAAK;gBACvC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAA;AACzC,CAAC"}
@@ -0,0 +1,74 @@
1
+ import { createLogger } from '../utils/logger.js';
2
+ const log = createLogger('card-bus');
3
+ const DEFAULT_BUFFER = 256;
4
+ export function createCardBus(bufferSize = DEFAULT_BUFFER) {
5
+ const perSession = new Map();
6
+ const all = new Set();
7
+ const buffers = new Map();
8
+ const seqCounters = new Map();
9
+ function sessionIdOf(c) {
10
+ return 'sessionId' in c ? c.sessionId : undefined;
11
+ }
12
+ function safe(fn, c) {
13
+ try {
14
+ fn(c);
15
+ }
16
+ catch (err) {
17
+ const sid = 'sessionId' in c ? c.sessionId : undefined;
18
+ log.warn('subscriber error', err.message, { kind: c.kind, sessionId: sid });
19
+ }
20
+ }
21
+ return {
22
+ publish(card) {
23
+ const sid = sessionIdOf(card);
24
+ // Stamp a per-session monotonic seq + a stable id (callers may pre-set id
25
+ // for streaming/assistant so the UI upserts the turn in place).
26
+ if (sid) {
27
+ const next = (seqCounters.get(sid) ?? 0) + 1;
28
+ seqCounters.set(sid, next);
29
+ card.seq = next;
30
+ }
31
+ if (!card.id)
32
+ card.id = `${card.kind}:${card.seq ?? Date.now()}`;
33
+ log.debug(`cardBus.publish: kind=${card.kind} id=${card.id} seq=${card.seq ?? '-'} sessionId=${sid ?? 'none'}`);
34
+ if (sid) {
35
+ const buf = buffers.get(sid) ?? [];
36
+ buf.push(card);
37
+ if (buf.length > bufferSize)
38
+ buf.shift();
39
+ buffers.set(sid, buf);
40
+ perSession.get(sid)?.forEach((fn) => safe(fn, card));
41
+ }
42
+ all.forEach((fn) => safe(fn, card));
43
+ },
44
+ subscribe(sessionId, fn) {
45
+ let s = perSession.get(sessionId);
46
+ if (!s) {
47
+ s = new Set();
48
+ perSession.set(sessionId, s);
49
+ }
50
+ s.add(fn);
51
+ return () => { s.delete(fn); };
52
+ },
53
+ subscribeAll(fn) {
54
+ all.add(fn);
55
+ return () => { all.delete(fn); };
56
+ },
57
+ recent(sessionId, limit = bufferSize) {
58
+ const buf = buffers.get(sessionId) ?? [];
59
+ return buf.slice(-limit);
60
+ },
61
+ oldestSeq(sessionId) {
62
+ return buffers.get(sessionId)?.[0]?.seq;
63
+ },
64
+ currentSeq(sessionId) {
65
+ return seqCounters.get(sessionId) ?? 0;
66
+ },
67
+ drop(sessionId) {
68
+ buffers.delete(sessionId);
69
+ perSession.delete(sessionId);
70
+ seqCounters.delete(sessionId);
71
+ },
72
+ };
73
+ }
74
+ //# sourceMappingURL=card-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-bus.js","sourceRoot":"","sources":["../../src/core/card-bus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { createLogger } from '../utils/logger.js';
4
+ const log = createLogger('channels');
5
+ const DEFAULT_IDS = [
6
+ { id: 'tg-default', channel: 'telegram' },
7
+ { id: 'wechat-default', channel: 'wechat' },
8
+ { id: 'lark-default', channel: 'lark' },
9
+ ];
10
+ function defaults() {
11
+ return DEFAULT_IDS.map(({ id, channel }) => ({
12
+ id,
13
+ channel,
14
+ enabled: channel === 'telegram', // the channel that actually ships today
15
+ credentials: {},
16
+ replyGranularity: 'standard', // ZCode 标准回复: hide the tool-call process
17
+ workspaces: { mode: 'all' },
18
+ }));
19
+ }
20
+ export function createChannelsStore(path) {
21
+ let bots = defaults();
22
+ function load() {
23
+ if (!existsSync(path))
24
+ return;
25
+ try {
26
+ const raw = JSON.parse(readFileSync(path, 'utf-8'));
27
+ if (!Array.isArray(raw.bots))
28
+ return;
29
+ // Merge by id so newly-added channel defaults appear on upgrade while
30
+ // persisted values win over defaults.
31
+ for (const saved of raw.bots) {
32
+ const target = bots.find((b) => b.id === saved?.id);
33
+ if (target)
34
+ Object.assign(target, saved, { channel: target.channel });
35
+ }
36
+ }
37
+ catch (err) {
38
+ log.warn(`failed to load ${path}: ${err.message}`);
39
+ }
40
+ }
41
+ let writeQueued;
42
+ function persist() {
43
+ if (writeQueued)
44
+ clearTimeout(writeQueued);
45
+ writeQueued = setTimeout(() => {
46
+ try {
47
+ mkdirSync(dirname(path), { recursive: true });
48
+ const tmp = `${path}.tmp`;
49
+ writeFileSync(tmp, JSON.stringify({ bots }, null, 2), { mode: 0o600 });
50
+ renameSync(tmp, path);
51
+ }
52
+ catch (err) {
53
+ log.warn(`persist failed: ${err.message}`);
54
+ }
55
+ }, 100);
56
+ writeQueued.unref?.();
57
+ }
58
+ load();
59
+ return {
60
+ list: () => bots.map((b) => ({ ...b })),
61
+ get: (id) => {
62
+ const b = bots.find((x) => x.id === id);
63
+ return b ? { ...b } : undefined;
64
+ },
65
+ update: (id, patch) => {
66
+ const b = bots.find((x) => x.id === id);
67
+ if (!b)
68
+ return undefined;
69
+ if (patch.enabled !== undefined)
70
+ b.enabled = patch.enabled;
71
+ if (patch.credentials !== undefined)
72
+ b.credentials = { ...patch.credentials };
73
+ if (patch.replyGranularity !== undefined)
74
+ b.replyGranularity = patch.replyGranularity;
75
+ if (patch.workspaces !== undefined)
76
+ b.workspaces = patch.workspaces;
77
+ persist();
78
+ return { ...b };
79
+ },
80
+ reset: (id) => {
81
+ const fresh = defaults().find((b) => b.id === id);
82
+ const idx = bots.findIndex((b) => b.id === id);
83
+ if (!fresh || idx === -1)
84
+ return undefined;
85
+ bots[idx] = fresh;
86
+ persist();
87
+ return { ...fresh };
88
+ },
89
+ };
90
+ }
91
+ /** Default on-disk location: ~/.ocrc/channels.json */
92
+ export function channelsPath(home) {
93
+ return join(home, 'channels.json');
94
+ }
95
+ //# sourceMappingURL=channels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channels.js","sourceRoot":"","sources":["../../src/core/channels.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ export function summarizeToolArgs(tool, input) {
2
+ if (tool === 'bash')
3
+ return (input?.command ?? '').slice(0, 60);
4
+ if (tool === 'read' || tool === 'edit' || tool === 'write')
5
+ return input?.filePath ?? '';
6
+ if (tool === 'grep' || tool === 'find')
7
+ return input?.pattern ?? input?.query ?? '';
8
+ return '';
9
+ }
10
+ export function messageToCards(sessionId, msg) {
11
+ // opencode SDK returns { info: {id, role, time, agent, model, ...}, parts: [...] }.
12
+ const info = msg.info ?? msg;
13
+ const parts = msg.parts ?? info?.parts ?? [];
14
+ const role = info?.role;
15
+ if (role === 'user') {
16
+ const textParts = [];
17
+ for (const part of parts) {
18
+ if (part.type === 'text' && typeof part.text === 'string') {
19
+ textParts.push(part.text);
20
+ }
21
+ }
22
+ const ts = (typeof info.time?.created === 'number' ? info.time.created : info.ts) ?? Date.now();
23
+ return [{
24
+ kind: 'user',
25
+ sessionId,
26
+ text: textParts.join('') || '(empty)',
27
+ ts,
28
+ }];
29
+ }
30
+ if (role === 'assistant') {
31
+ const blocks = [];
32
+ for (const part of parts) {
33
+ if (part.type === 'text' && typeof part.text === 'string') {
34
+ blocks.push({ type: 'text', text: part.text });
35
+ }
36
+ if (part.type === 'tool' && typeof part.tool === 'string') {
37
+ const status = part.state?.status ?? 'running';
38
+ blocks.push({
39
+ type: 'tool',
40
+ tool: part.tool,
41
+ args: summarizeToolArgs(part.tool, part.state?.input ?? {}),
42
+ // opencode's terminal status is 'completed' (never 'done'); without
43
+ // mapping it, finished tools stay 'running' and blink forever.
44
+ status: status === 'error' ? 'error'
45
+ : status === 'completed' || status === 'done' ? 'done'
46
+ : 'running',
47
+ });
48
+ }
49
+ }
50
+ const meta = {};
51
+ const agentName = typeof info.agent === 'string' ? info.agent : info.agent?.name;
52
+ if (agentName)
53
+ meta.agent = agentName;
54
+ const modelStr = typeof info.model === 'string'
55
+ ? info.model
56
+ : info.model?.modelID ?? info.model?.id;
57
+ if (modelStr)
58
+ meta.model = modelStr;
59
+ if (typeof info.cost === 'number')
60
+ meta.cost = info.cost;
61
+ if (info.tokens)
62
+ meta.tokens = info.tokens;
63
+ return [{
64
+ kind: 'assistant',
65
+ sessionId,
66
+ blocks,
67
+ meta,
68
+ }];
69
+ }
70
+ return [];
71
+ }
72
+ /**
73
+ * Default cap on history depth. Long sessions (hundreds of messages with
74
+ * subagent tool calls) blow up client-side rendering — 569-card sessions
75
+ * froze the browser. Callers can pass `limit` to override.
76
+ */
77
+ export const DEFAULT_HISTORY_LIMIT = 50;
78
+ export function cardsFromMessages(sessionId, messages, limit = DEFAULT_HISTORY_LIMIT, offset = 0) {
79
+ // Window [len - limit - offset, len - offset): offset=0 is the default
80
+ // "last `limit` messages" view; larger offsets page backwards through
81
+ // older history (client-side "load earlier" in long sessions).
82
+ const end = Math.max(0, messages.length - Math.max(0, offset));
83
+ const start = limit > 0 ? Math.max(0, end - limit) : 0;
84
+ const recent = messages.slice(start, end);
85
+ const cards = [];
86
+ for (const msg of recent) {
87
+ cards.push(...messageToCards(sessionId, msg));
88
+ }
89
+ return cards;
90
+ }
91
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/core/history.ts"],"names":[],"mappings":"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"}