@otto-assistant/bridge 0.4.92

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 (483) hide show
  1. package/bin.js +2 -0
  2. package/dist/agent-model.e2e.test.js +755 -0
  3. package/dist/ai-tool-to-genai.js +233 -0
  4. package/dist/ai-tool-to-genai.test.js +267 -0
  5. package/dist/ai-tool.js +6 -0
  6. package/dist/anthropic-auth-plugin.js +728 -0
  7. package/dist/anthropic-auth-plugin.test.js +125 -0
  8. package/dist/anthropic-auth-state.js +231 -0
  9. package/dist/bin.js +90 -0
  10. package/dist/channel-management.js +227 -0
  11. package/dist/cli-parsing.test.js +137 -0
  12. package/dist/cli-send-thread.e2e.test.js +356 -0
  13. package/dist/cli.js +3276 -0
  14. package/dist/commands/abort.js +65 -0
  15. package/dist/commands/action-buttons.js +245 -0
  16. package/dist/commands/add-project.js +113 -0
  17. package/dist/commands/agent.js +335 -0
  18. package/dist/commands/ask-question.js +274 -0
  19. package/dist/commands/btw.js +116 -0
  20. package/dist/commands/compact.js +120 -0
  21. package/dist/commands/context-usage.js +140 -0
  22. package/dist/commands/create-new-project.js +130 -0
  23. package/dist/commands/diff.js +63 -0
  24. package/dist/commands/file-upload.js +275 -0
  25. package/dist/commands/fork.js +220 -0
  26. package/dist/commands/gemini-apikey.js +70 -0
  27. package/dist/commands/login.js +885 -0
  28. package/dist/commands/mcp.js +239 -0
  29. package/dist/commands/memory-snapshot.js +24 -0
  30. package/dist/commands/mention-mode.js +44 -0
  31. package/dist/commands/merge-worktree.js +159 -0
  32. package/dist/commands/model-variant.js +364 -0
  33. package/dist/commands/model.js +776 -0
  34. package/dist/commands/new-worktree.js +366 -0
  35. package/dist/commands/paginated-select.js +57 -0
  36. package/dist/commands/permissions.js +274 -0
  37. package/dist/commands/queue.js +206 -0
  38. package/dist/commands/remove-project.js +115 -0
  39. package/dist/commands/restart-opencode-server.js +127 -0
  40. package/dist/commands/resume.js +149 -0
  41. package/dist/commands/run-command.js +79 -0
  42. package/dist/commands/screenshare.js +303 -0
  43. package/dist/commands/screenshare.test.js +20 -0
  44. package/dist/commands/session-id.js +78 -0
  45. package/dist/commands/session.js +176 -0
  46. package/dist/commands/share.js +80 -0
  47. package/dist/commands/tasks.js +205 -0
  48. package/dist/commands/types.js +2 -0
  49. package/dist/commands/undo-redo.js +305 -0
  50. package/dist/commands/unset-model.js +138 -0
  51. package/dist/commands/upgrade.js +42 -0
  52. package/dist/commands/user-command.js +155 -0
  53. package/dist/commands/verbosity.js +125 -0
  54. package/dist/commands/worktree-settings.js +43 -0
  55. package/dist/commands/worktrees.js +410 -0
  56. package/dist/condense-memory.js +33 -0
  57. package/dist/config.js +94 -0
  58. package/dist/context-awareness-plugin.js +363 -0
  59. package/dist/context-awareness-plugin.test.js +124 -0
  60. package/dist/critique-utils.js +95 -0
  61. package/dist/database.js +1310 -0
  62. package/dist/db.js +251 -0
  63. package/dist/db.test.js +138 -0
  64. package/dist/debounce-timeout.js +28 -0
  65. package/dist/debounced-process-flush.js +77 -0
  66. package/dist/discord-bot.js +1008 -0
  67. package/dist/discord-command-registration.js +524 -0
  68. package/dist/discord-urls.js +81 -0
  69. package/dist/discord-utils.js +591 -0
  70. package/dist/discord-utils.test.js +134 -0
  71. package/dist/errors.js +157 -0
  72. package/dist/escape-backticks.test.js +429 -0
  73. package/dist/event-stream-real-capture.e2e.test.js +533 -0
  74. package/dist/eventsource-parser.test.js +327 -0
  75. package/dist/exec-async.js +26 -0
  76. package/dist/external-opencode-sync.js +480 -0
  77. package/dist/format-tables.js +302 -0
  78. package/dist/format-tables.test.js +308 -0
  79. package/dist/forum-sync/config.js +79 -0
  80. package/dist/forum-sync/discord-operations.js +154 -0
  81. package/dist/forum-sync/index.js +5 -0
  82. package/dist/forum-sync/markdown.js +113 -0
  83. package/dist/forum-sync/sync-to-discord.js +417 -0
  84. package/dist/forum-sync/sync-to-files.js +190 -0
  85. package/dist/forum-sync/types.js +53 -0
  86. package/dist/forum-sync/watchers.js +307 -0
  87. package/dist/gateway-proxy-reconnect.e2e.test.js +394 -0
  88. package/dist/gateway-proxy.e2e.test.js +483 -0
  89. package/dist/genai-worker-wrapper.js +111 -0
  90. package/dist/genai-worker.js +311 -0
  91. package/dist/genai.js +232 -0
  92. package/dist/generated/browser.js +17 -0
  93. package/dist/generated/client.js +37 -0
  94. package/dist/generated/commonInputTypes.js +10 -0
  95. package/dist/generated/enums.js +52 -0
  96. package/dist/generated/internal/class.js +49 -0
  97. package/dist/generated/internal/prismaNamespace.js +253 -0
  98. package/dist/generated/internal/prismaNamespaceBrowser.js +223 -0
  99. package/dist/generated/models/bot_api_keys.js +1 -0
  100. package/dist/generated/models/bot_tokens.js +1 -0
  101. package/dist/generated/models/channel_agents.js +1 -0
  102. package/dist/generated/models/channel_directories.js +1 -0
  103. package/dist/generated/models/channel_mention_mode.js +1 -0
  104. package/dist/generated/models/channel_models.js +1 -0
  105. package/dist/generated/models/channel_verbosity.js +1 -0
  106. package/dist/generated/models/channel_worktrees.js +1 -0
  107. package/dist/generated/models/forum_sync_configs.js +1 -0
  108. package/dist/generated/models/global_models.js +1 -0
  109. package/dist/generated/models/ipc_requests.js +1 -0
  110. package/dist/generated/models/part_messages.js +1 -0
  111. package/dist/generated/models/scheduled_tasks.js +1 -0
  112. package/dist/generated/models/session_agents.js +1 -0
  113. package/dist/generated/models/session_events.js +1 -0
  114. package/dist/generated/models/session_models.js +1 -0
  115. package/dist/generated/models/session_start_sources.js +1 -0
  116. package/dist/generated/models/thread_sessions.js +1 -0
  117. package/dist/generated/models/thread_worktrees.js +1 -0
  118. package/dist/generated/models.js +1 -0
  119. package/dist/heap-monitor.js +122 -0
  120. package/dist/hrana-server.js +263 -0
  121. package/dist/hrana-server.test.js +370 -0
  122. package/dist/html-actions.js +123 -0
  123. package/dist/html-actions.test.js +70 -0
  124. package/dist/html-components.js +117 -0
  125. package/dist/html-components.test.js +34 -0
  126. package/dist/image-optimizer-plugin.js +153 -0
  127. package/dist/image-utils.js +112 -0
  128. package/dist/interaction-handler.js +397 -0
  129. package/dist/ipc-polling.js +252 -0
  130. package/dist/ipc-tools-plugin.js +193 -0
  131. package/dist/kimaki-digital-twin.e2e.test.js +161 -0
  132. package/dist/kimaki-opencode-plugin-loading.e2e.test.js +87 -0
  133. package/dist/kimaki-opencode-plugin.js +17 -0
  134. package/dist/kimaki-opencode-plugin.test.js +98 -0
  135. package/dist/limit-heading-depth.js +25 -0
  136. package/dist/limit-heading-depth.test.js +105 -0
  137. package/dist/logger.js +165 -0
  138. package/dist/markdown.js +342 -0
  139. package/dist/markdown.test.js +257 -0
  140. package/dist/message-finish-field.e2e.test.js +165 -0
  141. package/dist/message-formatting.js +413 -0
  142. package/dist/message-formatting.test.js +73 -0
  143. package/dist/message-preprocessing.js +330 -0
  144. package/dist/onboarding-tutorial.js +172 -0
  145. package/dist/onboarding-welcome.js +37 -0
  146. package/dist/openai-realtime.js +224 -0
  147. package/dist/opencode-command-detection.js +65 -0
  148. package/dist/opencode-command-detection.test.js +240 -0
  149. package/dist/opencode-command.js +129 -0
  150. package/dist/opencode-command.test.js +48 -0
  151. package/dist/opencode-interrupt-plugin.js +361 -0
  152. package/dist/opencode-interrupt-plugin.test.js +458 -0
  153. package/dist/opencode.js +861 -0
  154. package/dist/otto/branding.js +22 -0
  155. package/dist/otto/index.js +21 -0
  156. package/dist/parse-permission-rules.test.js +117 -0
  157. package/dist/patch-text-parser.js +97 -0
  158. package/dist/plugin-logger.js +59 -0
  159. package/dist/privacy-sanitizer.js +105 -0
  160. package/dist/queue-advanced-abort.e2e.test.js +293 -0
  161. package/dist/queue-advanced-action-buttons.e2e.test.js +206 -0
  162. package/dist/queue-advanced-e2e-setup.js +786 -0
  163. package/dist/queue-advanced-footer.e2e.test.js +472 -0
  164. package/dist/queue-advanced-model-switch.e2e.test.js +299 -0
  165. package/dist/queue-advanced-permissions-typing.e2e.test.js +180 -0
  166. package/dist/queue-advanced-question.e2e.test.js +261 -0
  167. package/dist/queue-advanced-typing-interrupt.e2e.test.js +114 -0
  168. package/dist/queue-advanced-typing.e2e.test.js +153 -0
  169. package/dist/queue-drain-after-interactive-ui.e2e.test.js +119 -0
  170. package/dist/queue-interrupt-drain.e2e.test.js +135 -0
  171. package/dist/queue-question-select-drain.e2e.test.js +120 -0
  172. package/dist/runtime-idle-sweeper.js +52 -0
  173. package/dist/runtime-lifecycle.e2e.test.js +508 -0
  174. package/dist/sentry.js +23 -0
  175. package/dist/session-handler/agent-utils.js +67 -0
  176. package/dist/session-handler/event-stream-state.js +420 -0
  177. package/dist/session-handler/event-stream-state.test.js +563 -0
  178. package/dist/session-handler/model-utils.js +124 -0
  179. package/dist/session-handler/opencode-session-event-log.js +94 -0
  180. package/dist/session-handler/thread-runtime-state.js +104 -0
  181. package/dist/session-handler/thread-session-runtime.js +3258 -0
  182. package/dist/session-handler.js +9 -0
  183. package/dist/session-search.js +100 -0
  184. package/dist/session-search.test.js +40 -0
  185. package/dist/session-title-rename.test.js +80 -0
  186. package/dist/startup-service.js +153 -0
  187. package/dist/startup-time.e2e.test.js +296 -0
  188. package/dist/store.js +17 -0
  189. package/dist/system-message.js +613 -0
  190. package/dist/system-message.test.js +602 -0
  191. package/dist/task-runner.js +295 -0
  192. package/dist/task-schedule.js +209 -0
  193. package/dist/task-schedule.test.js +71 -0
  194. package/dist/test-utils.js +299 -0
  195. package/dist/thinking-utils.js +35 -0
  196. package/dist/thread-message-queue.e2e.test.js +999 -0
  197. package/dist/tools.js +357 -0
  198. package/dist/undo-redo.e2e.test.js +161 -0
  199. package/dist/unnest-code-blocks.js +146 -0
  200. package/dist/unnest-code-blocks.test.js +673 -0
  201. package/dist/upgrade.js +114 -0
  202. package/dist/utils.js +144 -0
  203. package/dist/voice-attachment.js +34 -0
  204. package/dist/voice-handler.js +646 -0
  205. package/dist/voice-message.e2e.test.js +1021 -0
  206. package/dist/voice.js +447 -0
  207. package/dist/voice.test.js +235 -0
  208. package/dist/wait-session.js +94 -0
  209. package/dist/websockify.js +69 -0
  210. package/dist/worker-types.js +4 -0
  211. package/dist/worktree-lifecycle.e2e.test.js +308 -0
  212. package/dist/worktree-utils.js +3 -0
  213. package/dist/worktrees.js +929 -0
  214. package/dist/worktrees.test.js +189 -0
  215. package/dist/xml.js +92 -0
  216. package/dist/xml.test.js +32 -0
  217. package/package.json +98 -0
  218. package/schema.prisma +295 -0
  219. package/skills/batch/SKILL.md +87 -0
  220. package/skills/critique/SKILL.md +112 -0
  221. package/skills/egaki/SKILL.md +100 -0
  222. package/skills/errore/SKILL.md +647 -0
  223. package/skills/event-sourcing-state/SKILL.md +252 -0
  224. package/skills/gitchamber/SKILL.md +93 -0
  225. package/skills/goke/SKILL.md +644 -0
  226. package/skills/jitter/EDITOR.md +219 -0
  227. package/skills/jitter/EXPORT-INTERNALS.md +309 -0
  228. package/skills/jitter/SKILL.md +158 -0
  229. package/skills/jitter/jitter-clipboard.json +1042 -0
  230. package/skills/jitter/package.json +14 -0
  231. package/skills/jitter/tsconfig.json +15 -0
  232. package/skills/jitter/utils/actions.ts +212 -0
  233. package/skills/jitter/utils/export.ts +114 -0
  234. package/skills/jitter/utils/index.ts +141 -0
  235. package/skills/jitter/utils/snapshot.ts +154 -0
  236. package/skills/jitter/utils/traverse.ts +246 -0
  237. package/skills/jitter/utils/types.ts +279 -0
  238. package/skills/jitter/utils/wait.ts +133 -0
  239. package/skills/lintcn/SKILL.md +873 -0
  240. package/skills/new-skill/SKILL.md +211 -0
  241. package/skills/npm-package/SKILL.md +239 -0
  242. package/skills/playwriter/SKILL.md +35 -0
  243. package/skills/proxyman/SKILL.md +215 -0
  244. package/skills/security-review/SKILL.md +208 -0
  245. package/skills/simplify/SKILL.md +58 -0
  246. package/skills/spiceflow/SKILL.md +14 -0
  247. package/skills/termcast/SKILL.md +945 -0
  248. package/skills/tuistory/SKILL.md +250 -0
  249. package/skills/usecomputer/SKILL.md +264 -0
  250. package/skills/x-articles/SKILL.md +554 -0
  251. package/skills/zele/SKILL.md +112 -0
  252. package/skills/zustand-centralized-state/SKILL.md +1004 -0
  253. package/src/agent-model.e2e.test.ts +976 -0
  254. package/src/ai-tool-to-genai.test.ts +296 -0
  255. package/src/ai-tool-to-genai.ts +283 -0
  256. package/src/ai-tool.ts +39 -0
  257. package/src/anthropic-auth-plugin.test.ts +159 -0
  258. package/src/anthropic-auth-plugin.ts +861 -0
  259. package/src/anthropic-auth-state.ts +282 -0
  260. package/src/bin.ts +111 -0
  261. package/src/channel-management.ts +334 -0
  262. package/src/cli-parsing.test.ts +195 -0
  263. package/src/cli-send-thread.e2e.test.ts +464 -0
  264. package/src/cli.ts +4581 -0
  265. package/src/commands/abort.ts +89 -0
  266. package/src/commands/action-buttons.ts +364 -0
  267. package/src/commands/add-project.ts +149 -0
  268. package/src/commands/agent.ts +473 -0
  269. package/src/commands/ask-question.ts +390 -0
  270. package/src/commands/btw.ts +164 -0
  271. package/src/commands/compact.ts +157 -0
  272. package/src/commands/context-usage.ts +199 -0
  273. package/src/commands/create-new-project.ts +190 -0
  274. package/src/commands/diff.ts +91 -0
  275. package/src/commands/file-upload.ts +389 -0
  276. package/src/commands/fork.ts +321 -0
  277. package/src/commands/gemini-apikey.ts +104 -0
  278. package/src/commands/login.ts +1173 -0
  279. package/src/commands/mcp.ts +307 -0
  280. package/src/commands/memory-snapshot.ts +30 -0
  281. package/src/commands/mention-mode.ts +68 -0
  282. package/src/commands/merge-worktree.ts +223 -0
  283. package/src/commands/model-variant.ts +483 -0
  284. package/src/commands/model.ts +1053 -0
  285. package/src/commands/new-worktree.ts +510 -0
  286. package/src/commands/paginated-select.ts +81 -0
  287. package/src/commands/permissions.ts +397 -0
  288. package/src/commands/queue.ts +271 -0
  289. package/src/commands/remove-project.ts +155 -0
  290. package/src/commands/restart-opencode-server.ts +162 -0
  291. package/src/commands/resume.ts +230 -0
  292. package/src/commands/run-command.ts +123 -0
  293. package/src/commands/screenshare.test.ts +30 -0
  294. package/src/commands/screenshare.ts +366 -0
  295. package/src/commands/session-id.ts +109 -0
  296. package/src/commands/session.ts +227 -0
  297. package/src/commands/share.ts +106 -0
  298. package/src/commands/tasks.ts +293 -0
  299. package/src/commands/types.ts +25 -0
  300. package/src/commands/undo-redo.ts +386 -0
  301. package/src/commands/unset-model.ts +173 -0
  302. package/src/commands/upgrade.ts +52 -0
  303. package/src/commands/user-command.ts +198 -0
  304. package/src/commands/verbosity.ts +173 -0
  305. package/src/commands/worktree-settings.ts +70 -0
  306. package/src/commands/worktrees.ts +552 -0
  307. package/src/condense-memory.ts +36 -0
  308. package/src/config.ts +111 -0
  309. package/src/context-awareness-plugin.test.ts +142 -0
  310. package/src/context-awareness-plugin.ts +510 -0
  311. package/src/critique-utils.ts +139 -0
  312. package/src/database.ts +1876 -0
  313. package/src/db.test.ts +162 -0
  314. package/src/db.ts +286 -0
  315. package/src/debounce-timeout.ts +43 -0
  316. package/src/debounced-process-flush.ts +104 -0
  317. package/src/discord-bot.ts +1330 -0
  318. package/src/discord-command-registration.ts +693 -0
  319. package/src/discord-urls.ts +88 -0
  320. package/src/discord-utils.test.ts +153 -0
  321. package/src/discord-utils.ts +800 -0
  322. package/src/errors.ts +201 -0
  323. package/src/escape-backticks.test.ts +469 -0
  324. package/src/event-stream-real-capture.e2e.test.ts +692 -0
  325. package/src/eventsource-parser.test.ts +351 -0
  326. package/src/exec-async.ts +35 -0
  327. package/src/external-opencode-sync.ts +685 -0
  328. package/src/format-tables.test.ts +335 -0
  329. package/src/format-tables.ts +445 -0
  330. package/src/forum-sync/config.ts +92 -0
  331. package/src/forum-sync/discord-operations.ts +241 -0
  332. package/src/forum-sync/index.ts +9 -0
  333. package/src/forum-sync/markdown.ts +172 -0
  334. package/src/forum-sync/sync-to-discord.ts +595 -0
  335. package/src/forum-sync/sync-to-files.ts +294 -0
  336. package/src/forum-sync/types.ts +175 -0
  337. package/src/forum-sync/watchers.ts +454 -0
  338. package/src/gateway-proxy-reconnect.e2e.test.ts +523 -0
  339. package/src/gateway-proxy.e2e.test.ts +640 -0
  340. package/src/genai-worker-wrapper.ts +164 -0
  341. package/src/genai-worker.ts +386 -0
  342. package/src/genai.ts +321 -0
  343. package/src/generated/browser.ts +114 -0
  344. package/src/generated/client.ts +138 -0
  345. package/src/generated/commonInputTypes.ts +736 -0
  346. package/src/generated/enums.ts +88 -0
  347. package/src/generated/internal/class.ts +384 -0
  348. package/src/generated/internal/prismaNamespace.ts +2386 -0
  349. package/src/generated/internal/prismaNamespaceBrowser.ts +326 -0
  350. package/src/generated/models/bot_api_keys.ts +1288 -0
  351. package/src/generated/models/bot_tokens.ts +1656 -0
  352. package/src/generated/models/channel_agents.ts +1256 -0
  353. package/src/generated/models/channel_directories.ts +1859 -0
  354. package/src/generated/models/channel_mention_mode.ts +1300 -0
  355. package/src/generated/models/channel_models.ts +1288 -0
  356. package/src/generated/models/channel_verbosity.ts +1228 -0
  357. package/src/generated/models/channel_worktrees.ts +1300 -0
  358. package/src/generated/models/forum_sync_configs.ts +1452 -0
  359. package/src/generated/models/global_models.ts +1288 -0
  360. package/src/generated/models/ipc_requests.ts +1485 -0
  361. package/src/generated/models/part_messages.ts +1302 -0
  362. package/src/generated/models/scheduled_tasks.ts +2320 -0
  363. package/src/generated/models/session_agents.ts +1086 -0
  364. package/src/generated/models/session_events.ts +1439 -0
  365. package/src/generated/models/session_models.ts +1114 -0
  366. package/src/generated/models/session_start_sources.ts +1408 -0
  367. package/src/generated/models/thread_sessions.ts +1781 -0
  368. package/src/generated/models/thread_worktrees.ts +1356 -0
  369. package/src/generated/models.ts +30 -0
  370. package/src/heap-monitor.ts +152 -0
  371. package/src/hrana-server.test.ts +434 -0
  372. package/src/hrana-server.ts +314 -0
  373. package/src/html-actions.test.ts +87 -0
  374. package/src/html-actions.ts +174 -0
  375. package/src/html-components.test.ts +38 -0
  376. package/src/html-components.ts +181 -0
  377. package/src/image-optimizer-plugin.ts +194 -0
  378. package/src/image-utils.ts +149 -0
  379. package/src/interaction-handler.ts +576 -0
  380. package/src/ipc-polling.ts +326 -0
  381. package/src/ipc-tools-plugin.ts +236 -0
  382. package/src/kimaki-digital-twin.e2e.test.ts +199 -0
  383. package/src/kimaki-opencode-plugin-loading.e2e.test.ts +109 -0
  384. package/src/kimaki-opencode-plugin.test.ts +108 -0
  385. package/src/kimaki-opencode-plugin.ts +18 -0
  386. package/src/limit-heading-depth.test.ts +116 -0
  387. package/src/limit-heading-depth.ts +26 -0
  388. package/src/logger.ts +208 -0
  389. package/src/markdown.test.ts +308 -0
  390. package/src/markdown.ts +410 -0
  391. package/src/message-finish-field.e2e.test.ts +192 -0
  392. package/src/message-formatting.test.ts +81 -0
  393. package/src/message-formatting.ts +533 -0
  394. package/src/message-preprocessing.ts +455 -0
  395. package/src/onboarding-tutorial.ts +176 -0
  396. package/src/onboarding-welcome.ts +49 -0
  397. package/src/openai-realtime.ts +358 -0
  398. package/src/opencode-command-detection.test.ts +307 -0
  399. package/src/opencode-command-detection.ts +76 -0
  400. package/src/opencode-command.test.ts +70 -0
  401. package/src/opencode-command.ts +188 -0
  402. package/src/opencode-interrupt-plugin.test.ts +677 -0
  403. package/src/opencode-interrupt-plugin.ts +477 -0
  404. package/src/opencode.ts +1110 -0
  405. package/src/otto/branding.ts +23 -0
  406. package/src/otto/index.ts +22 -0
  407. package/src/parse-permission-rules.test.ts +127 -0
  408. package/src/patch-text-parser.ts +107 -0
  409. package/src/plugin-logger.ts +68 -0
  410. package/src/privacy-sanitizer.ts +142 -0
  411. package/src/queue-advanced-abort.e2e.test.ts +382 -0
  412. package/src/queue-advanced-action-buttons.e2e.test.ts +268 -0
  413. package/src/queue-advanced-e2e-setup.ts +873 -0
  414. package/src/queue-advanced-footer.e2e.test.ts +576 -0
  415. package/src/queue-advanced-model-switch.e2e.test.ts +383 -0
  416. package/src/queue-advanced-permissions-typing.e2e.test.ts +245 -0
  417. package/src/queue-advanced-question.e2e.test.ts +316 -0
  418. package/src/queue-advanced-typing-interrupt.e2e.test.ts +146 -0
  419. package/src/queue-advanced-typing.e2e.test.ts +199 -0
  420. package/src/queue-drain-after-interactive-ui.e2e.test.ts +151 -0
  421. package/src/queue-interrupt-drain.e2e.test.ts +166 -0
  422. package/src/queue-question-select-drain.e2e.test.ts +152 -0
  423. package/src/runtime-idle-sweeper.ts +76 -0
  424. package/src/runtime-lifecycle.e2e.test.ts +641 -0
  425. package/src/schema.sql +173 -0
  426. package/src/sentry.ts +26 -0
  427. package/src/session-handler/agent-utils.ts +97 -0
  428. package/src/session-handler/event-stream-fixtures/real-session-action-buttons.jsonl +45 -0
  429. package/src/session-handler/event-stream-fixtures/real-session-footer-suppressed-on-pre-idle-interrupt.jsonl +40 -0
  430. package/src/session-handler/event-stream-fixtures/real-session-permission-external-file.jsonl +23 -0
  431. package/src/session-handler/event-stream-fixtures/real-session-task-normal.jsonl +22 -0
  432. package/src/session-handler/event-stream-fixtures/real-session-task-three-parallel-sleeps.jsonl +277 -0
  433. package/src/session-handler/event-stream-fixtures/real-session-task-user-interruption.jsonl +46 -0
  434. package/src/session-handler/event-stream-fixtures/session-abort-after-idle-race.jsonl +21 -0
  435. package/src/session-handler/event-stream-fixtures/session-concurrent-messages-serialized.jsonl +56 -0
  436. package/src/session-handler/event-stream-fixtures/session-explicit-abort.jsonl +44 -0
  437. package/src/session-handler/event-stream-fixtures/session-normal-completion.jsonl +29 -0
  438. package/src/session-handler/event-stream-fixtures/session-tool-call-noisy-stream.jsonl +29 -0
  439. package/src/session-handler/event-stream-fixtures/session-two-completions-same-session.jsonl +50 -0
  440. package/src/session-handler/event-stream-fixtures/session-user-interruption.jsonl +59 -0
  441. package/src/session-handler/event-stream-fixtures/session-voice-queued-followup.jsonl +52 -0
  442. package/src/session-handler/event-stream-state.test.ts +645 -0
  443. package/src/session-handler/event-stream-state.ts +608 -0
  444. package/src/session-handler/model-utils.ts +183 -0
  445. package/src/session-handler/opencode-session-event-log.ts +130 -0
  446. package/src/session-handler/thread-runtime-state.ts +212 -0
  447. package/src/session-handler/thread-session-runtime.ts +4281 -0
  448. package/src/session-handler.ts +15 -0
  449. package/src/session-search.test.ts +50 -0
  450. package/src/session-search.ts +148 -0
  451. package/src/session-title-rename.test.ts +112 -0
  452. package/src/startup-service.ts +200 -0
  453. package/src/startup-time.e2e.test.ts +373 -0
  454. package/src/store.ts +122 -0
  455. package/src/system-message.test.ts +612 -0
  456. package/src/system-message.ts +723 -0
  457. package/src/task-runner.ts +421 -0
  458. package/src/task-schedule.test.ts +84 -0
  459. package/src/task-schedule.ts +311 -0
  460. package/src/test-utils.ts +435 -0
  461. package/src/thinking-utils.ts +61 -0
  462. package/src/thread-message-queue.e2e.test.ts +1219 -0
  463. package/src/tools.ts +430 -0
  464. package/src/undici.d.ts +12 -0
  465. package/src/undo-redo.e2e.test.ts +209 -0
  466. package/src/unnest-code-blocks.test.ts +713 -0
  467. package/src/unnest-code-blocks.ts +185 -0
  468. package/src/upgrade.ts +127 -0
  469. package/src/utils.ts +212 -0
  470. package/src/voice-attachment.ts +51 -0
  471. package/src/voice-handler.ts +908 -0
  472. package/src/voice-message.e2e.test.ts +1255 -0
  473. package/src/voice.test.ts +281 -0
  474. package/src/voice.ts +627 -0
  475. package/src/wait-session.ts +147 -0
  476. package/src/websockify.ts +101 -0
  477. package/src/worker-types.ts +64 -0
  478. package/src/worktree-lifecycle.e2e.test.ts +391 -0
  479. package/src/worktree-utils.ts +4 -0
  480. package/src/worktrees.test.ts +223 -0
  481. package/src/worktrees.ts +1294 -0
  482. package/src/xml.test.ts +38 -0
  483. package/src/xml.ts +121 -0
@@ -0,0 +1,420 @@
1
+ // Pure event-stream derivation functions for session lifecycle state.
2
+ // These functions derive lifecycle decisions from an event buffer array.
3
+ // Zero imports from thread-session-runtime.ts, store.ts, or state.ts.
4
+ // Only types from @opencode-ai/sdk/v2 and the getOpencodeEventSessionId helper.
5
+ import { getOpencodeEventSessionId } from './opencode-session-event-log.js';
6
+ function getTaskChildSessionId({ part, }) {
7
+ // Event-shape reference:
8
+ // - cli/src/session-handler/event-stream-fixtures/real-session-task-three-parallel-sleeps.jsonl
9
+ // - In real task events, state.metadata.sessionId appears on running/completed
10
+ // tool updates and is the canonical child-session identifier.
11
+ // We intentionally do not parse state.output because it is user-facing text
12
+ // and can change format across providers/versions.
13
+ const metadataValue = part.state.metadata;
14
+ const metadataSessionId = metadataValue && typeof metadataValue === 'object'
15
+ ? metadataValue.sessionId
16
+ : undefined;
17
+ if (typeof metadataSessionId === 'string' && metadataSessionId.length > 0) {
18
+ return metadataSessionId;
19
+ }
20
+ return undefined;
21
+ }
22
+ function getTaskCandidateFromEvent({ event, mainSessionId, }) {
23
+ if (event.type !== 'message.part.updated') {
24
+ return undefined;
25
+ }
26
+ const part = event.properties.part;
27
+ if (part.sessionID !== mainSessionId) {
28
+ return undefined;
29
+ }
30
+ if (part.type !== 'tool' || part.tool !== 'task') {
31
+ return undefined;
32
+ }
33
+ const childSessionId = getTaskChildSessionId({ part });
34
+ if (!childSessionId) {
35
+ return undefined;
36
+ }
37
+ const subagentType = part.state.input?.subagent_type;
38
+ return {
39
+ assistantMessageId: part.messageID,
40
+ childSessionId,
41
+ subagentType: typeof subagentType === 'string' ? subagentType : undefined,
42
+ };
43
+ }
44
+ // Scans backward for most recent session-scoped lifecycle event.
45
+ // Returns true if the latest lifecycle event for sessionId is session.status busy.
46
+ export function isSessionBusy({ events, sessionId, upToIndex, }) {
47
+ const end = upToIndex ?? events.length - 1;
48
+ for (let i = end; i >= 0; i--) {
49
+ const entry = events[i];
50
+ if (!entry) {
51
+ continue;
52
+ }
53
+ const e = entry.event;
54
+ const eid = getOpencodeEventSessionId(e);
55
+ if (eid !== sessionId) {
56
+ continue;
57
+ }
58
+ if (e.type === 'session.idle') {
59
+ return false;
60
+ }
61
+ if (e.type === 'session.status') {
62
+ return e.properties.status.type === 'busy';
63
+ }
64
+ }
65
+ return false;
66
+ }
67
+ export function isAssistantMessageNaturalCompletion({ message, }) {
68
+ if (typeof message.time.completed !== 'number') {
69
+ return false;
70
+ }
71
+ if (message.error) {
72
+ return false;
73
+ }
74
+ // finish="tool-calls" means the model's last step was tool execution.
75
+ // Mid-turn tool-call steps don't get footers — the footer comes from the
76
+ // final text response (finish="stop") that follows. If the turn ends with
77
+ // only tool-calls and no text follow-up, no footer is emitted. This is
78
+ // acceptable since models almost always follow up with text after tools.
79
+ return message.finish !== 'tool-calls';
80
+ }
81
+ export function hasAssistantMessageCompletedBefore({ events, sessionId, messageId, upToIndex, }) {
82
+ const end = upToIndex ?? events.length - 1;
83
+ for (let i = end; i >= 0; i--) {
84
+ const entry = events[i];
85
+ if (!entry) {
86
+ continue;
87
+ }
88
+ const event = entry.event;
89
+ if (event.type !== 'message.updated') {
90
+ continue;
91
+ }
92
+ const info = event.properties.info;
93
+ if (info.sessionID !== sessionId || info.role !== 'assistant' || info.id !== messageId) {
94
+ continue;
95
+ }
96
+ return typeof info.time.completed === 'number';
97
+ }
98
+ return false;
99
+ }
100
+ export function getLatestUserMessage({ events, sessionId, upToIndex, }) {
101
+ const end = upToIndex ?? events.length - 1;
102
+ let latestUserMessage;
103
+ for (let i = end; i >= 0; i--) {
104
+ const entry = events[i];
105
+ if (!entry) {
106
+ continue;
107
+ }
108
+ const event = entry.event;
109
+ if (event.type !== 'message.updated') {
110
+ continue;
111
+ }
112
+ const info = event.properties.info;
113
+ if (info.sessionID !== sessionId || info.role !== 'user') {
114
+ continue;
115
+ }
116
+ if (!latestUserMessage) {
117
+ latestUserMessage = info;
118
+ continue;
119
+ }
120
+ if (info.time.created > latestUserMessage.time.created) {
121
+ latestUserMessage = info;
122
+ }
123
+ }
124
+ return latestUserMessage;
125
+ }
126
+ export function getCurrentTurnStartTime({ events, sessionId, upToIndex, }) {
127
+ const latestUserMessage = getLatestUserMessage({
128
+ events,
129
+ sessionId,
130
+ upToIndex,
131
+ });
132
+ return latestUserMessage?.time.created;
133
+ }
134
+ // Token total helper — sum of input + output + reasoning + cache.read + cache.write
135
+ function getTokenTotal(tokens) {
136
+ return tokens.input + tokens.output + tokens.reasoning + tokens.cache.read + tokens.cache.write;
137
+ }
138
+ // Scans backward for most recent message.updated with role=assistant for sessionId.
139
+ // Extracts model, providerID, agent, tokensUsed.
140
+ export function getLatestRunInfo({ events, sessionId, upToIndex, }) {
141
+ const result = {
142
+ model: undefined,
143
+ providerID: undefined,
144
+ agent: undefined,
145
+ tokensUsed: 0,
146
+ };
147
+ const end = upToIndex ?? events.length - 1;
148
+ for (let i = end; i >= 0; i--) {
149
+ const entry = events[i];
150
+ if (!entry) {
151
+ continue;
152
+ }
153
+ const e = entry.event;
154
+ if (e.type !== 'message.updated') {
155
+ continue;
156
+ }
157
+ const msg = e.properties.info;
158
+ if (msg.sessionID !== sessionId || msg.role !== 'assistant') {
159
+ continue;
160
+ }
161
+ return {
162
+ model: 'modelID' in msg ? msg.modelID : undefined,
163
+ providerID: 'providerID' in msg ? msg.providerID : undefined,
164
+ agent: 'mode' in msg ? msg.mode : undefined,
165
+ tokensUsed: 'tokens' in msg && msg.tokens
166
+ ? getTokenTotal(msg.tokens)
167
+ : 0,
168
+ };
169
+ }
170
+ return result;
171
+ }
172
+ export function getAssistantMessageIdsForLatestUserTurn({ events, sessionId, upToIndex, }) {
173
+ const latestUserMessage = getLatestUserMessage({
174
+ events,
175
+ sessionId,
176
+ upToIndex,
177
+ });
178
+ if (!latestUserMessage) {
179
+ return new Set();
180
+ }
181
+ const end = upToIndex === undefined ? events.length : upToIndex + 1;
182
+ const assistantMessageIds = new Set();
183
+ for (let i = 0; i < end; i++) {
184
+ const entry = events[i];
185
+ if (!entry) {
186
+ continue;
187
+ }
188
+ const e = entry.event;
189
+ if (e.type !== 'message.updated') {
190
+ continue;
191
+ }
192
+ const msg = e.properties.info;
193
+ if (msg.sessionID !== sessionId || msg.role !== 'assistant') {
194
+ continue;
195
+ }
196
+ if (msg.parentID === latestUserMessage.id) {
197
+ assistantMessageIds.add(msg.id);
198
+ }
199
+ }
200
+ return assistantMessageIds;
201
+ }
202
+ export function getLatestAssistantMessageIdForLatestUserTurn({ events, sessionId, upToIndex, }) {
203
+ const latestUserMessage = getLatestUserMessage({
204
+ events,
205
+ sessionId,
206
+ upToIndex,
207
+ });
208
+ if (!latestUserMessage) {
209
+ return undefined;
210
+ }
211
+ const end = upToIndex ?? events.length - 1;
212
+ let latestAssistantMessage;
213
+ for (let i = end; i >= 0; i--) {
214
+ const entry = events[i];
215
+ if (!entry) {
216
+ continue;
217
+ }
218
+ const event = entry.event;
219
+ if (event.type !== 'message.updated') {
220
+ continue;
221
+ }
222
+ const info = event.properties.info;
223
+ if (info.sessionID !== sessionId || info.role !== 'assistant') {
224
+ continue;
225
+ }
226
+ if (info.parentID !== latestUserMessage.id) {
227
+ continue;
228
+ }
229
+ if (!latestAssistantMessage) {
230
+ latestAssistantMessage = info;
231
+ continue;
232
+ }
233
+ if (info.time.created > latestAssistantMessage.time.created) {
234
+ latestAssistantMessage = info;
235
+ }
236
+ }
237
+ return latestAssistantMessage?.id;
238
+ }
239
+ function hasRenderablePartSummary(message) {
240
+ if (!('partsSummary' in message) || !Array.isArray(message.partsSummary)) {
241
+ return false;
242
+ }
243
+ return message.partsSummary.some((part) => {
244
+ return part.type === 'text' || part.type === 'tool';
245
+ });
246
+ }
247
+ function hasAssistantPartEvidence({ events, sessionId, messageId, upToIndex, }) {
248
+ const end = upToIndex ?? events.length - 1;
249
+ for (let i = end; i >= 0; i--) {
250
+ const entry = events[i];
251
+ if (!entry) {
252
+ continue;
253
+ }
254
+ const event = entry.event;
255
+ if (event.type === 'message.updated') {
256
+ const info = event.properties.info;
257
+ if (info.sessionID !== sessionId || info.role !== 'assistant' || info.id !== messageId) {
258
+ continue;
259
+ }
260
+ if (hasRenderablePartSummary(info)) {
261
+ return true;
262
+ }
263
+ continue;
264
+ }
265
+ if (event.type !== 'message.part.updated') {
266
+ continue;
267
+ }
268
+ const { part } = event.properties;
269
+ if (part.messageID !== messageId) {
270
+ continue;
271
+ }
272
+ if (part.type === 'text' || part.type === 'tool') {
273
+ return true;
274
+ }
275
+ }
276
+ return false;
277
+ }
278
+ function hasAssistantStepFinished({ events, messageId, upToIndex, }) {
279
+ const end = upToIndex ?? events.length - 1;
280
+ for (let i = end; i >= 0; i--) {
281
+ const entry = events[i];
282
+ if (!entry || entry.event.type !== 'message.part.updated') {
283
+ continue;
284
+ }
285
+ const { part } = entry.event.properties;
286
+ if (part.messageID !== messageId) {
287
+ continue;
288
+ }
289
+ if (part.type === 'step-finish') {
290
+ return true;
291
+ }
292
+ }
293
+ return false;
294
+ }
295
+ export function doesLatestUserTurnHaveNaturalCompletion({ events, sessionId, upToIndex, }) {
296
+ const latestAssistantMessageId = getLatestAssistantMessageIdForLatestUserTurn({
297
+ events,
298
+ sessionId,
299
+ upToIndex,
300
+ });
301
+ if (!latestAssistantMessageId) {
302
+ return false;
303
+ }
304
+ const end = upToIndex ?? events.length - 1;
305
+ let latestAssistantMessage;
306
+ for (let i = end; i >= 0; i--) {
307
+ const entry = events[i];
308
+ if (!entry) {
309
+ continue;
310
+ }
311
+ const event = entry.event;
312
+ if (event.type !== 'message.updated') {
313
+ continue;
314
+ }
315
+ const info = event.properties.info;
316
+ if (info.sessionID !== sessionId || info.role !== 'assistant') {
317
+ continue;
318
+ }
319
+ if (info.id !== latestAssistantMessageId) {
320
+ continue;
321
+ }
322
+ latestAssistantMessage = info;
323
+ if (isAssistantMessageNaturalCompletion({ message: info })) {
324
+ return true;
325
+ }
326
+ break;
327
+ }
328
+ if (!latestAssistantMessage) {
329
+ return false;
330
+ }
331
+ if (latestAssistantMessage.error) {
332
+ return false;
333
+ }
334
+ if (latestAssistantMessage.finish === 'tool-calls') {
335
+ return false;
336
+ }
337
+ return hasAssistantStepFinished({
338
+ events,
339
+ messageId: latestAssistantMessageId,
340
+ upToIndex,
341
+ }) && hasAssistantPartEvidence({
342
+ events,
343
+ sessionId,
344
+ messageId: latestAssistantMessageId,
345
+ upToIndex,
346
+ });
347
+ }
348
+ export function isAssistantMessageInLatestUserTurn({ events, sessionId, messageId, upToIndex, }) {
349
+ const assistantMessageIds = getAssistantMessageIdsForLatestUserTurn({
350
+ events,
351
+ sessionId,
352
+ upToIndex,
353
+ });
354
+ return assistantMessageIds.has(messageId);
355
+ }
356
+ // Returns a stable 1-based subtask index for candidateSessionId.
357
+ // Indexing scope is the parent assistant message that spawned the task tool calls,
358
+ // so numbering restarts at 1 for each assistant message.
359
+ export function getDerivedSubtaskIndex({ events, mainSessionId, candidateSessionId, upToIndex, }) {
360
+ const end = upToIndex ?? events.length - 1;
361
+ let parentAssistantMessageId;
362
+ for (let i = end; i >= 0; i--) {
363
+ const entry = events[i];
364
+ if (!entry) {
365
+ continue;
366
+ }
367
+ const candidate = getTaskCandidateFromEvent({
368
+ event: entry.event,
369
+ mainSessionId,
370
+ });
371
+ if (!candidate) {
372
+ continue;
373
+ }
374
+ if (candidate.childSessionId !== candidateSessionId) {
375
+ continue;
376
+ }
377
+ parentAssistantMessageId = candidate.assistantMessageId;
378
+ break;
379
+ }
380
+ if (!parentAssistantMessageId) {
381
+ return undefined;
382
+ }
383
+ const indexByChildSessionId = new Map();
384
+ for (let i = 0; i <= end; i++) {
385
+ const entry = events[i];
386
+ if (!entry) {
387
+ continue;
388
+ }
389
+ const candidate = getTaskCandidateFromEvent({
390
+ event: entry.event,
391
+ mainSessionId,
392
+ });
393
+ if (!candidate || candidate.assistantMessageId !== parentAssistantMessageId) {
394
+ continue;
395
+ }
396
+ if (!indexByChildSessionId.has(candidate.childSessionId)) {
397
+ indexByChildSessionId.set(candidate.childSessionId, indexByChildSessionId.size + 1);
398
+ }
399
+ }
400
+ return indexByChildSessionId.get(candidateSessionId);
401
+ }
402
+ // Returns the subagent_type (e.g. "explore", "general") for a given child session.
403
+ // Used to build labels like "explore-1" instead of generic "task-1".
404
+ export function getDerivedSubtaskAgentType({ events, mainSessionId, candidateSessionId, }) {
405
+ for (let i = events.length - 1; i >= 0; i--) {
406
+ const entry = events[i];
407
+ if (!entry) {
408
+ continue;
409
+ }
410
+ const candidate = getTaskCandidateFromEvent({
411
+ event: entry.event,
412
+ mainSessionId,
413
+ });
414
+ if (!candidate || candidate.childSessionId !== candidateSessionId) {
415
+ continue;
416
+ }
417
+ return candidate.subagentType;
418
+ }
419
+ return undefined;
420
+ }