@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
package/src/genai.ts ADDED
@@ -0,0 +1,321 @@
1
+ // Google GenAI Live session manager for real-time voice interactions.
2
+ // Establishes bidirectional audio streaming with Gemini, handles tool calls,
3
+ // and manages the assistant's audio output for Discord voice channels.
4
+
5
+ import {
6
+ GoogleGenAI,
7
+ LiveServerMessage,
8
+ MediaResolution,
9
+ Modality,
10
+ Session,
11
+ } from '@google/genai'
12
+ import type { CallableTool } from '@google/genai'
13
+ import { writeFile } from 'fs'
14
+ import type { AnyTool } from './ai-tool.js'
15
+
16
+ import { createLogger, LogPrefix } from './logger.js'
17
+ import { aiToolToCallableTool } from './ai-tool-to-genai.js'
18
+
19
+ const genaiLogger = createLogger(LogPrefix.GENAI)
20
+
21
+ const audioParts: Buffer[] = []
22
+
23
+ function saveBinaryFile(fileName: string, content: Buffer) {
24
+ writeFile(fileName, content, 'utf8', (err) => {
25
+ if (err) {
26
+ genaiLogger.error(`Error writing file ${fileName}:`, err)
27
+ return
28
+ }
29
+ genaiLogger.log(`Appending stream content to file ${fileName}.`)
30
+ })
31
+ }
32
+
33
+ interface WavConversionOptions {
34
+ numChannels: number
35
+ sampleRate: number
36
+ bitsPerSample: number
37
+ }
38
+
39
+ function convertToWav(rawData: Buffer[], mimeType: string) {
40
+ const options = parseMimeType(mimeType)
41
+ const dataLength = rawData.reduce((a, b) => a + b.length, 0)
42
+ const wavHeader = createWavHeader(dataLength, options)
43
+ const buffer = Buffer.concat(rawData)
44
+
45
+ return Buffer.concat([wavHeader, buffer])
46
+ }
47
+
48
+ function parseMimeType(mimeType: string) {
49
+ const [fileType, ...params] = mimeType.split(';').map((s) => s.trim())
50
+ const [_, format] = fileType?.split('/') || []
51
+
52
+ const options: Partial<WavConversionOptions> = {
53
+ numChannels: 1,
54
+ bitsPerSample: 16,
55
+ }
56
+
57
+ if (format && format.startsWith('L')) {
58
+ const bits = parseInt(format.slice(1), 10)
59
+ if (!isNaN(bits)) {
60
+ options.bitsPerSample = bits
61
+ }
62
+ }
63
+
64
+ for (const param of params) {
65
+ const [key, value] = param.split('=').map((s) => s.trim())
66
+ if (key === 'rate') {
67
+ options.sampleRate = parseInt(value || '', 10)
68
+ }
69
+ }
70
+
71
+ return options as WavConversionOptions
72
+ }
73
+
74
+ function createWavHeader(dataLength: number, options: WavConversionOptions) {
75
+ const { numChannels, sampleRate, bitsPerSample } = options
76
+
77
+ // http://soundfile.sapp.org/doc/WaveFormat
78
+
79
+ const byteRate = (sampleRate * numChannels * bitsPerSample) / 8
80
+ const blockAlign = (numChannels * bitsPerSample) / 8
81
+ const buffer = Buffer.alloc(44)
82
+
83
+ buffer.write('RIFF', 0) // ChunkID
84
+ buffer.writeUInt32LE(36 + dataLength, 4) // ChunkSize
85
+ buffer.write('WAVE', 8) // Format
86
+ buffer.write('fmt ', 12) // Subchunk1ID
87
+ buffer.writeUInt32LE(16, 16) // Subchunk1Size (PCM)
88
+ buffer.writeUInt16LE(1, 20) // AudioFormat (1 = PCM)
89
+ buffer.writeUInt16LE(numChannels, 22) // NumChannels
90
+ buffer.writeUInt32LE(sampleRate, 24) // SampleRate
91
+ buffer.writeUInt32LE(byteRate, 28) // ByteRate
92
+ buffer.writeUInt16LE(blockAlign, 32) // BlockAlign
93
+ buffer.writeUInt16LE(bitsPerSample, 34) // BitsPerSample
94
+ buffer.write('data', 36) // Subchunk2ID
95
+ buffer.writeUInt32LE(dataLength, 40) // Subchunk2Size
96
+
97
+ return buffer
98
+ }
99
+
100
+ function defaultAudioChunkHandler({
101
+ data,
102
+ mimeType,
103
+ }: {
104
+ data: Buffer
105
+ mimeType: string
106
+ }) {
107
+ audioParts.push(data)
108
+ const fileName = 'audio.wav'
109
+ const buffer = convertToWav(audioParts, mimeType)
110
+ saveBinaryFile(fileName, buffer)
111
+ }
112
+
113
+ export async function startGenAiSession({
114
+ onAssistantAudioChunk,
115
+ onAssistantStartSpeaking,
116
+ onAssistantStopSpeaking,
117
+ onAssistantInterruptSpeaking,
118
+ systemMessage,
119
+ tools,
120
+ geminiApiKey,
121
+ }: {
122
+ onAssistantAudioChunk?: (args: { data: Buffer; mimeType: string }) => void
123
+ onAssistantStartSpeaking?: () => void
124
+ onAssistantStopSpeaking?: () => void
125
+ onAssistantInterruptSpeaking?: () => void
126
+ systemMessage?: string
127
+ tools?: Record<string, AnyTool>
128
+ geminiApiKey?: string | null
129
+ } = {}) {
130
+ let session: Session | undefined = undefined
131
+ const callableTools: Array<CallableTool & { name: string }> = []
132
+ let isAssistantSpeaking = false
133
+
134
+ const audioChunkHandler = onAssistantAudioChunk || defaultAudioChunkHandler
135
+
136
+ // Convert AI SDK tools to GenAI CallableTools
137
+ if (tools) {
138
+ for (const [name, tool] of Object.entries(tools)) {
139
+ callableTools.push(aiToolToCallableTool(tool, name))
140
+ }
141
+ }
142
+
143
+ function handleModelTurn(message: LiveServerMessage) {
144
+ if (message.toolCall) {
145
+ genaiLogger.log('Tool call:', message.toolCall)
146
+
147
+ // Handle tool calls
148
+ if (message.toolCall.functionCalls && callableTools.length > 0) {
149
+ for (const tool of callableTools) {
150
+ if (
151
+ !message.toolCall.functionCalls.some((x) => x.name === tool.name)
152
+ ) {
153
+ continue
154
+ }
155
+ tool
156
+ .callTool(message.toolCall.functionCalls)
157
+ .then((parts) => {
158
+ const functionResponses = parts
159
+ .filter((part) => part.functionResponse)
160
+ .map((part) => ({
161
+ response: part.functionResponse!.response as Record<
162
+ string,
163
+ unknown
164
+ >,
165
+ id: part.functionResponse!.id,
166
+ name: part.functionResponse!.name,
167
+ }))
168
+
169
+ if (functionResponses.length > 0 && session) {
170
+ session.sendToolResponse({ functionResponses })
171
+ genaiLogger.log(
172
+ 'client-toolResponse: ' +
173
+ JSON.stringify({ functionResponses }),
174
+ )
175
+ }
176
+ })
177
+ .catch((error) => {
178
+ genaiLogger.error('Error handling tool calls:', error)
179
+ })
180
+ }
181
+ }
182
+ }
183
+ if (message.serverContent?.modelTurn?.parts) {
184
+ for (const part of message.serverContent.modelTurn.parts) {
185
+ if (part?.fileData) {
186
+ genaiLogger.log(`File: ${part?.fileData.fileUri}`)
187
+ }
188
+
189
+ if (part?.inlineData) {
190
+ const inlineData = part.inlineData
191
+ if (
192
+ !inlineData.mimeType ||
193
+ !inlineData.mimeType.startsWith('audio/')
194
+ ) {
195
+ genaiLogger.log(
196
+ 'Skipping non-audio inlineData:',
197
+ inlineData.mimeType,
198
+ )
199
+ continue
200
+ }
201
+
202
+ // Trigger start speaking callback the first time audio is received
203
+ if (!isAssistantSpeaking && onAssistantStartSpeaking) {
204
+ isAssistantSpeaking = true
205
+ onAssistantStartSpeaking()
206
+ }
207
+
208
+ const buffer = Buffer.from(inlineData?.data ?? '', 'base64')
209
+ audioChunkHandler({
210
+ data: buffer,
211
+ mimeType: inlineData.mimeType ?? '',
212
+ })
213
+ }
214
+
215
+ if (part?.text) {
216
+ genaiLogger.log('Text:', part.text)
217
+ }
218
+ }
219
+ }
220
+ // Handle input transcription (user's audio transcription)
221
+ if (message.serverContent?.inputTranscription?.text) {
222
+ genaiLogger.log(
223
+ '[user transcription]',
224
+ message.serverContent.inputTranscription.text,
225
+ )
226
+ }
227
+
228
+ // Handle output transcription (model's audio transcription)
229
+ if (message.serverContent?.outputTranscription?.text) {
230
+ genaiLogger.log(
231
+ '[assistant transcription]',
232
+ message.serverContent.outputTranscription.text,
233
+ )
234
+ }
235
+ if (message.serverContent?.interrupted) {
236
+ genaiLogger.log('Assistant was interrupted')
237
+ if (isAssistantSpeaking && onAssistantInterruptSpeaking) {
238
+ isAssistantSpeaking = false
239
+ onAssistantInterruptSpeaking()
240
+ }
241
+ }
242
+ if (message.serverContent?.turnComplete) {
243
+ genaiLogger.log('Assistant turn complete')
244
+ if (isAssistantSpeaking && onAssistantStopSpeaking) {
245
+ isAssistantSpeaking = false
246
+ onAssistantStopSpeaking()
247
+ }
248
+ }
249
+ }
250
+
251
+ const apiKey = geminiApiKey || process.env.GEMINI_API_KEY
252
+
253
+ if (!apiKey) {
254
+ genaiLogger.error('No Gemini API key provided')
255
+ throw new Error('Gemini API key is required for voice interactions')
256
+ }
257
+
258
+ const ai = new GoogleGenAI({
259
+ apiKey,
260
+ })
261
+
262
+ const model = 'gemini-3.1-flash-live-preview'
263
+
264
+ session = await ai.live.connect({
265
+ model,
266
+ callbacks: {
267
+ onopen: function () {
268
+ genaiLogger.debug('Opened')
269
+ },
270
+ onmessage: function (message: LiveServerMessage) {
271
+ // genaiLogger.log(message)
272
+ try {
273
+ handleModelTurn(message)
274
+ } catch (error) {
275
+ genaiLogger.error('Error handling turn:', error)
276
+ }
277
+ },
278
+ onerror: function (e: { message?: string }) {
279
+ genaiLogger.debug('Error:', e.message)
280
+ },
281
+ onclose: function (e: { reason?: string }) {
282
+ genaiLogger.debug('Close:', e.reason)
283
+ },
284
+ },
285
+ config: {
286
+ tools: callableTools,
287
+ responseModalities: [Modality.AUDIO],
288
+ mediaResolution: MediaResolution.MEDIA_RESOLUTION_MEDIUM,
289
+ inputAudioTranscription: {}, // transcribes your input speech
290
+ outputAudioTranscription: {}, // transcribes the model's spoken audio
291
+ systemInstruction: {
292
+ parts: [
293
+ {
294
+ text: systemMessage || '',
295
+ },
296
+ ],
297
+ },
298
+ speechConfig: {
299
+ voiceConfig: {
300
+ prebuiltVoiceConfig: {
301
+ voiceName: 'Charon', // Orus also not bad
302
+ },
303
+ },
304
+ },
305
+ contextWindowCompression: {
306
+ triggerTokens: '25600',
307
+
308
+ slidingWindow: { targetTokens: '12800' },
309
+ },
310
+ },
311
+ })
312
+
313
+ return {
314
+ session,
315
+ stop: () => {
316
+ const currentSession = session
317
+ session = undefined
318
+ currentSession?.close()
319
+ },
320
+ }
321
+ }
@@ -0,0 +1,114 @@
1
+
2
+ /* !!! This is code generated by Prisma. Do not edit directly. !!! */
3
+ /* eslint-disable */
4
+ // biome-ignore-all lint: generated file
5
+ // @ts-nocheck
6
+ /*
7
+ * This file should be your main import to use Prisma-related types and utilities in a browser.
8
+ * Use it to get access to models, enums, and input types.
9
+ *
10
+ * This file does not contain a `PrismaClient` class, nor several other helpers that are intended as server-side only.
11
+ * See `client.ts` for the standard, server-side entry point.
12
+ *
13
+ * 🟢 You can import this file directly.
14
+ */
15
+
16
+ import * as Prisma from './internal/prismaNamespaceBrowser.js'
17
+ export { Prisma }
18
+ export * as $Enums from './enums.js'
19
+ export * from './enums.js';
20
+ /**
21
+ * Model thread_sessions
22
+ *
23
+ */
24
+ export type thread_sessions = Prisma.thread_sessionsModel
25
+ /**
26
+ * Model session_events
27
+ *
28
+ */
29
+ export type session_events = Prisma.session_eventsModel
30
+ /**
31
+ * Model part_messages
32
+ *
33
+ */
34
+ export type part_messages = Prisma.part_messagesModel
35
+ /**
36
+ * Model bot_tokens
37
+ *
38
+ */
39
+ export type bot_tokens = Prisma.bot_tokensModel
40
+ /**
41
+ * Model channel_directories
42
+ *
43
+ */
44
+ export type channel_directories = Prisma.channel_directoriesModel
45
+ /**
46
+ * Model bot_api_keys
47
+ *
48
+ */
49
+ export type bot_api_keys = Prisma.bot_api_keysModel
50
+ /**
51
+ * Model thread_worktrees
52
+ *
53
+ */
54
+ export type thread_worktrees = Prisma.thread_worktreesModel
55
+ /**
56
+ * Model channel_models
57
+ *
58
+ */
59
+ export type channel_models = Prisma.channel_modelsModel
60
+ /**
61
+ * Model session_models
62
+ *
63
+ */
64
+ export type session_models = Prisma.session_modelsModel
65
+ /**
66
+ * Model channel_agents
67
+ *
68
+ */
69
+ export type channel_agents = Prisma.channel_agentsModel
70
+ /**
71
+ * Model session_agents
72
+ *
73
+ */
74
+ export type session_agents = Prisma.session_agentsModel
75
+ /**
76
+ * Model channel_worktrees
77
+ *
78
+ */
79
+ export type channel_worktrees = Prisma.channel_worktreesModel
80
+ /**
81
+ * Model channel_verbosity
82
+ *
83
+ */
84
+ export type channel_verbosity = Prisma.channel_verbosityModel
85
+ /**
86
+ * Model channel_mention_mode
87
+ *
88
+ */
89
+ export type channel_mention_mode = Prisma.channel_mention_modeModel
90
+ /**
91
+ * Model global_models
92
+ *
93
+ */
94
+ export type global_models = Prisma.global_modelsModel
95
+ /**
96
+ * Model scheduled_tasks
97
+ *
98
+ */
99
+ export type scheduled_tasks = Prisma.scheduled_tasksModel
100
+ /**
101
+ * Model session_start_sources
102
+ *
103
+ */
104
+ export type session_start_sources = Prisma.session_start_sourcesModel
105
+ /**
106
+ * Model forum_sync_configs
107
+ *
108
+ */
109
+ export type forum_sync_configs = Prisma.forum_sync_configsModel
110
+ /**
111
+ * Model ipc_requests
112
+ *
113
+ */
114
+ export type ipc_requests = Prisma.ipc_requestsModel
@@ -0,0 +1,138 @@
1
+
2
+ /* !!! This is code generated by Prisma. Do not edit directly. !!! */
3
+ /* eslint-disable */
4
+ // biome-ignore-all lint: generated file
5
+ // @ts-nocheck
6
+ /*
7
+ * This file should be your main import to use Prisma. Through it you get access to all the models, enums, and input types.
8
+ * If you're looking for something you can import in the client-side of your application, please refer to the `browser.ts` file instead.
9
+ *
10
+ * 🟢 You can import this file directly.
11
+ */
12
+
13
+ import * as process from 'node:process'
14
+ import * as path from 'node:path'
15
+ import { fileURLToPath } from 'node:url'
16
+ globalThis['__dirname'] = path.dirname(fileURLToPath(import.meta.url))
17
+
18
+ import * as runtime from "@prisma/client/runtime/client"
19
+ import * as $Enums from "./enums.js"
20
+ import * as $Class from "./internal/class.js"
21
+ import * as Prisma from "./internal/prismaNamespace.js"
22
+
23
+ export * as $Enums from './enums.js'
24
+ export * from "./enums.js"
25
+ /**
26
+ * ## Prisma Client
27
+ *
28
+ * Type-safe database client for TypeScript
29
+ * @example
30
+ * ```
31
+ * const prisma = new PrismaClient({
32
+ * adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL })
33
+ * })
34
+ * // Fetch zero or more Thread_sessions
35
+ * const thread_sessions = await prisma.thread_sessions.findMany()
36
+ * ```
37
+ *
38
+ * Read more in our [docs](https://pris.ly/d/client).
39
+ */
40
+ export const PrismaClient = $Class.getPrismaClientClass()
41
+ export type PrismaClient<LogOpts extends Prisma.LogLevel = never, OmitOpts extends Prisma.PrismaClientOptions["omit"] = Prisma.PrismaClientOptions["omit"], ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = $Class.PrismaClient<LogOpts, OmitOpts, ExtArgs>
42
+ export { Prisma }
43
+
44
+ /**
45
+ * Model thread_sessions
46
+ *
47
+ */
48
+ export type thread_sessions = Prisma.thread_sessionsModel
49
+ /**
50
+ * Model session_events
51
+ *
52
+ */
53
+ export type session_events = Prisma.session_eventsModel
54
+ /**
55
+ * Model part_messages
56
+ *
57
+ */
58
+ export type part_messages = Prisma.part_messagesModel
59
+ /**
60
+ * Model bot_tokens
61
+ *
62
+ */
63
+ export type bot_tokens = Prisma.bot_tokensModel
64
+ /**
65
+ * Model channel_directories
66
+ *
67
+ */
68
+ export type channel_directories = Prisma.channel_directoriesModel
69
+ /**
70
+ * Model bot_api_keys
71
+ *
72
+ */
73
+ export type bot_api_keys = Prisma.bot_api_keysModel
74
+ /**
75
+ * Model thread_worktrees
76
+ *
77
+ */
78
+ export type thread_worktrees = Prisma.thread_worktreesModel
79
+ /**
80
+ * Model channel_models
81
+ *
82
+ */
83
+ export type channel_models = Prisma.channel_modelsModel
84
+ /**
85
+ * Model session_models
86
+ *
87
+ */
88
+ export type session_models = Prisma.session_modelsModel
89
+ /**
90
+ * Model channel_agents
91
+ *
92
+ */
93
+ export type channel_agents = Prisma.channel_agentsModel
94
+ /**
95
+ * Model session_agents
96
+ *
97
+ */
98
+ export type session_agents = Prisma.session_agentsModel
99
+ /**
100
+ * Model channel_worktrees
101
+ *
102
+ */
103
+ export type channel_worktrees = Prisma.channel_worktreesModel
104
+ /**
105
+ * Model channel_verbosity
106
+ *
107
+ */
108
+ export type channel_verbosity = Prisma.channel_verbosityModel
109
+ /**
110
+ * Model channel_mention_mode
111
+ *
112
+ */
113
+ export type channel_mention_mode = Prisma.channel_mention_modeModel
114
+ /**
115
+ * Model global_models
116
+ *
117
+ */
118
+ export type global_models = Prisma.global_modelsModel
119
+ /**
120
+ * Model scheduled_tasks
121
+ *
122
+ */
123
+ export type scheduled_tasks = Prisma.scheduled_tasksModel
124
+ /**
125
+ * Model session_start_sources
126
+ *
127
+ */
128
+ export type session_start_sources = Prisma.session_start_sourcesModel
129
+ /**
130
+ * Model forum_sync_configs
131
+ *
132
+ */
133
+ export type forum_sync_configs = Prisma.forum_sync_configsModel
134
+ /**
135
+ * Model ipc_requests
136
+ *
137
+ */
138
+ export type ipc_requests = Prisma.ipc_requestsModel