@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,106 @@
1
+ // /share command - Share the current session as a public URL.
2
+
3
+ import {
4
+ ChannelType,
5
+ MessageFlags,
6
+ type TextChannel,
7
+ type ThreadChannel,
8
+ } from 'discord.js'
9
+ import type { CommandContext } from './types.js'
10
+ import { getThreadSession } from '../database.js'
11
+ import { initializeOpencodeForDirectory } from '../opencode.js'
12
+ import {
13
+ resolveWorkingDirectory,
14
+ SILENT_MESSAGE_FLAGS,
15
+ } from '../discord-utils.js'
16
+ import { createLogger, LogPrefix } from '../logger.js'
17
+
18
+ const logger = createLogger(LogPrefix.SHARE)
19
+
20
+ export async function handleShareCommand({
21
+ command,
22
+ }: CommandContext): Promise<void> {
23
+ const channel = command.channel
24
+
25
+ if (!channel) {
26
+ await command.reply({
27
+ content: 'This command can only be used in a channel',
28
+ flags: MessageFlags.Ephemeral | SILENT_MESSAGE_FLAGS,
29
+ })
30
+ return
31
+ }
32
+
33
+ const isThread = [
34
+ ChannelType.PublicThread,
35
+ ChannelType.PrivateThread,
36
+ ChannelType.AnnouncementThread,
37
+ ].includes(channel.type)
38
+
39
+ if (!isThread) {
40
+ await command.reply({
41
+ content:
42
+ 'This command can only be used in a thread with an active session',
43
+ flags: MessageFlags.Ephemeral | SILENT_MESSAGE_FLAGS,
44
+ })
45
+ return
46
+ }
47
+
48
+ const resolved = await resolveWorkingDirectory({
49
+ channel: channel as TextChannel | ThreadChannel,
50
+ })
51
+
52
+ if (!resolved) {
53
+ await command.reply({
54
+ content: 'Could not determine project directory for this channel',
55
+ flags: MessageFlags.Ephemeral | SILENT_MESSAGE_FLAGS,
56
+ })
57
+ return
58
+ }
59
+
60
+ const { projectDirectory } = resolved
61
+
62
+ const sessionId = await getThreadSession(channel.id)
63
+
64
+ if (!sessionId) {
65
+ await command.reply({
66
+ content: 'No active session in this thread',
67
+ flags: MessageFlags.Ephemeral | SILENT_MESSAGE_FLAGS,
68
+ })
69
+ return
70
+ }
71
+
72
+ const getClient = await initializeOpencodeForDirectory(projectDirectory)
73
+ if (getClient instanceof Error) {
74
+ await command.reply({
75
+ content: `Failed to share session: ${getClient.message}`,
76
+ flags: MessageFlags.Ephemeral | SILENT_MESSAGE_FLAGS,
77
+ })
78
+ return
79
+ }
80
+
81
+ try {
82
+ const response = await getClient().session.share({
83
+ sessionID: sessionId,
84
+ })
85
+
86
+ if (!response.data?.share?.url) {
87
+ await command.reply({
88
+ content: 'Failed to generate share URL',
89
+ flags: MessageFlags.Ephemeral | SILENT_MESSAGE_FLAGS,
90
+ })
91
+ return
92
+ }
93
+
94
+ await command.reply({
95
+ content: `🔗 **Session shared:** ${response.data.share.url}`,
96
+ flags: SILENT_MESSAGE_FLAGS,
97
+ })
98
+ logger.log(`Session ${sessionId} shared: ${response.data.share.url}`)
99
+ } catch (error) {
100
+ logger.error('[SHARE] Error:', error)
101
+ await command.reply({
102
+ content: `Failed to share session: ${error instanceof Error ? error.message : 'Unknown error'}`,
103
+ flags: MessageFlags.Ephemeral | SILENT_MESSAGE_FLAGS,
104
+ })
105
+ }
106
+ }
@@ -0,0 +1,293 @@
1
+ // /tasks command — list all scheduled tasks sorted by next run time.
2
+ // Renders a markdown table that the CV2 pipeline auto-formats for Discord,
3
+ // including HTML-backed action buttons for cancellable tasks.
4
+
5
+ import {
6
+ ButtonInteraction,
7
+ ChatInputCommandInteraction,
8
+ ComponentType,
9
+ MessageFlags,
10
+ type APIMessageTopLevelComponent,
11
+ type APITextDisplayComponent,
12
+ type InteractionEditReplyOptions,
13
+ } from 'discord.js'
14
+ import {
15
+ cancelScheduledTask,
16
+ listScheduledTasks,
17
+ type ScheduledTask,
18
+ type ScheduledTaskStatus,
19
+ } from '../database.js'
20
+ import { splitTablesFromMarkdown } from '../format-tables.js'
21
+ import {
22
+ buildHtmlActionCustomId,
23
+ cancelHtmlActionsForOwner,
24
+ registerHtmlAction,
25
+ } from '../html-actions.js'
26
+ import { formatTimeAgo } from './worktrees.js'
27
+
28
+ function formatTimeUntil(date: Date): string {
29
+ const diffMs = date.getTime() - Date.now()
30
+ if (diffMs <= 0) {
31
+ return 'due now'
32
+ }
33
+ const totalSeconds = Math.floor(diffMs / 1000)
34
+ if (totalSeconds < 60) {
35
+ return `in ${totalSeconds}s`
36
+ }
37
+ const totalMinutes = Math.floor(totalSeconds / 60)
38
+ if (totalMinutes < 60) {
39
+ return `in ${totalMinutes}m`
40
+ }
41
+ const hours = Math.floor(totalMinutes / 60)
42
+ const minutes = totalMinutes % 60
43
+ if (hours < 24) {
44
+ return minutes > 0 ? `in ${hours}h ${minutes}m` : `in ${hours}h`
45
+ }
46
+ const days = Math.floor(hours / 24)
47
+ const remainingHours = hours % 24
48
+ return remainingHours > 0 ? `in ${days}d ${remainingHours}h` : `in ${days}d`
49
+ }
50
+
51
+ function scheduleLabel(task: ScheduledTask): string {
52
+ if (task.schedule_kind === 'cron') {
53
+ return task.cron_expr || 'cron'
54
+ }
55
+ return 'one-time'
56
+ }
57
+
58
+ function canCancelTask(task: ScheduledTask): boolean {
59
+ return task.status === 'planned' || task.status === 'running'
60
+ }
61
+
62
+ // Escape pipe chars and collapse whitespace so free-text fields don't break
63
+ // GFM table column alignment.
64
+ function sanitizeTableCell(value: string): string {
65
+ return value.replaceAll('|', '\\|').replace(/\s+/g, ' ').trim()
66
+ }
67
+
68
+ function buildCancelButtonHtml({ buttonId }: { buttonId: string }): string {
69
+ return `<button id="${buttonId}" variant="secondary">Delete</button>`
70
+ }
71
+
72
+ function buildActionCell(task: ScheduledTask): string {
73
+ if (!canCancelTask(task)) {
74
+ return '-'
75
+ }
76
+ return buildCancelButtonHtml({ buttonId: `cancel-task-${task.id}` })
77
+ }
78
+
79
+ // Cap rows to avoid exceeding Discord's 40-component CV2 limit.
80
+ // Each cancellable row renders as text + action row + button (~4 components),
81
+ // so 10 rows is a safe ceiling.
82
+ const MAX_TASK_ROWS = 10
83
+
84
+ function buildTaskTable({
85
+ tasks,
86
+ }: {
87
+ tasks: ScheduledTask[]
88
+ }): string {
89
+ const header = '| ID | Status | Prompt | Schedule | Next Run | Action |'
90
+ const separator = '|---|---|---|---|---|---|'
91
+ const rows = tasks.map((task) => {
92
+ const id = String(task.id)
93
+ const status = task.status
94
+ const prompt = sanitizeTableCell(
95
+ task.prompt_preview.length > 240
96
+ ? task.prompt_preview.slice(0, 237) + '...'
97
+ : task.prompt_preview,
98
+ )
99
+ const schedule = sanitizeTableCell(scheduleLabel(task))
100
+ const nextRun = (() => {
101
+ if (
102
+ task.status === 'completed' ||
103
+ task.status === 'cancelled' ||
104
+ task.status === 'failed'
105
+ ) {
106
+ return task.last_run_at ? formatTimeAgo(task.last_run_at) : '-'
107
+ }
108
+ return formatTimeUntil(task.next_run_at)
109
+ })()
110
+ const action = buildActionCell(task)
111
+ return `| ${id} | ${status} | ${prompt} | ${schedule} | ${nextRun} | ${action} |`
112
+ })
113
+ return [header, separator, ...rows].join('\n')
114
+ }
115
+
116
+ function getTasksActionOwnerKey({
117
+ userId,
118
+ channelId,
119
+ }: {
120
+ userId: string
121
+ channelId: string
122
+ }): string {
123
+ return `tasks:${userId}:${channelId}`
124
+ }
125
+
126
+ type TasksReplyTarget = {
127
+ guildId: string
128
+ userId: string
129
+ channelId: string
130
+ showAll: boolean
131
+ notice?: string
132
+ editReply: (
133
+ options: string | InteractionEditReplyOptions,
134
+ ) => Promise<unknown>
135
+ }
136
+
137
+ async function renderTasksReply({
138
+ guildId,
139
+ userId,
140
+ channelId,
141
+ showAll,
142
+ notice,
143
+ editReply,
144
+ }: TasksReplyTarget): Promise<void> {
145
+ const ownerKey = getTasksActionOwnerKey({ userId, channelId })
146
+ cancelHtmlActionsForOwner(ownerKey)
147
+
148
+ const statuses: ScheduledTaskStatus[] | undefined = showAll
149
+ ? undefined
150
+ : ['planned', 'running']
151
+ const allTasks = await listScheduledTasks({ statuses })
152
+ if (allTasks.length === 0) {
153
+ const message = notice
154
+ ? `${notice}\n\nNo scheduled tasks found.`
155
+ : 'No scheduled tasks found.'
156
+ const textDisplay: APITextDisplayComponent = {
157
+ type: ComponentType.TextDisplay,
158
+ content: message,
159
+ }
160
+ await editReply({
161
+ components: [textDisplay],
162
+ flags: MessageFlags.IsComponentsV2,
163
+ })
164
+ return
165
+ }
166
+
167
+ const tasks = allTasks.slice(0, MAX_TASK_ROWS)
168
+ const truncatedNotice =
169
+ allTasks.length > MAX_TASK_ROWS
170
+ ? `Showing ${MAX_TASK_ROWS}/${allTasks.length} tasks. Use \`kimaki task list\` for full list.`
171
+ : undefined
172
+ const combinedNotice = [notice, truncatedNotice].filter(Boolean).join('\n')
173
+
174
+ const cancellableTasksByButtonId = new Map<string, ScheduledTask>()
175
+ tasks.forEach((task) => {
176
+ if (!canCancelTask(task)) {
177
+ return
178
+ }
179
+ cancellableTasksByButtonId.set(`cancel-task-${task.id}`, task)
180
+ })
181
+
182
+ const tableMarkdown = buildTaskTable({ tasks })
183
+ const markdown = combinedNotice
184
+ ? `${combinedNotice}\n\n${tableMarkdown}`
185
+ : tableMarkdown
186
+ const segments = splitTablesFromMarkdown(markdown, {
187
+ resolveButtonCustomId: ({ button }) => {
188
+ const task = cancellableTasksByButtonId.get(button.id)
189
+ if (!task) {
190
+ return new Error(`No task registered for button ${button.id}`)
191
+ }
192
+
193
+ const actionId = registerHtmlAction({
194
+ ownerKey,
195
+ threadId: String(task.id),
196
+ run: async ({ interaction }) => {
197
+ await handleCancelTaskAction({
198
+ interaction,
199
+ taskId: task.id,
200
+ showAll,
201
+ })
202
+ },
203
+ })
204
+ return buildHtmlActionCustomId(actionId)
205
+ },
206
+ })
207
+
208
+ const components: APIMessageTopLevelComponent[] = segments.flatMap(
209
+ (segment) => {
210
+ if (segment.type === 'components') {
211
+ return segment.components
212
+ }
213
+ const textDisplay: APITextDisplayComponent = {
214
+ type: ComponentType.TextDisplay,
215
+ content: segment.text,
216
+ }
217
+ return [textDisplay]
218
+ },
219
+ )
220
+
221
+ await editReply({
222
+ components,
223
+ flags: MessageFlags.IsComponentsV2,
224
+ })
225
+ }
226
+
227
+ async function handleCancelTaskAction({
228
+ interaction,
229
+ taskId,
230
+ showAll,
231
+ }: {
232
+ interaction: ButtonInteraction
233
+ taskId: number
234
+ showAll: boolean
235
+ }): Promise<void> {
236
+ const guildId = interaction.guildId
237
+ if (!guildId) {
238
+ await interaction.editReply({
239
+ components: [
240
+ {
241
+ type: ComponentType.TextDisplay,
242
+ content: 'This action can only be used in a server.',
243
+ },
244
+ ],
245
+ flags: MessageFlags.IsComponentsV2,
246
+ })
247
+ return
248
+ }
249
+
250
+ const cancelled = await cancelScheduledTask(taskId)
251
+ const notice = cancelled
252
+ ? `Cancelled task #${taskId}.`
253
+ : `Task #${taskId} not found or already finalized.`
254
+
255
+ await renderTasksReply({
256
+ guildId,
257
+ userId: interaction.user.id,
258
+ channelId: interaction.channelId,
259
+ showAll,
260
+ notice,
261
+ editReply: (options) => {
262
+ return interaction.editReply(options)
263
+ },
264
+ })
265
+ }
266
+
267
+ export async function handleTasksCommand({
268
+ command,
269
+ }: {
270
+ command: ChatInputCommandInteraction
271
+ appId: string
272
+ }): Promise<void> {
273
+ const guildId = command.guildId
274
+ if (!guildId) {
275
+ await command.reply({
276
+ content: 'This command can only be used in a server.',
277
+ flags: MessageFlags.Ephemeral,
278
+ })
279
+ return
280
+ }
281
+
282
+ const showAll = command.options.getBoolean('all') ?? false
283
+ await command.deferReply({ flags: MessageFlags.Ephemeral })
284
+ await renderTasksReply({
285
+ guildId,
286
+ userId: command.user.id,
287
+ channelId: command.channelId,
288
+ showAll,
289
+ editReply: (options) => {
290
+ return command.editReply(options)
291
+ },
292
+ })
293
+ }
@@ -0,0 +1,25 @@
1
+ // Shared types for command handlers.
2
+
3
+ import type {
4
+ AutocompleteInteraction,
5
+ ChatInputCommandInteraction,
6
+ StringSelectMenuInteraction,
7
+ } from 'discord.js'
8
+
9
+ export type CommandContext = {
10
+ command: ChatInputCommandInteraction
11
+ appId: string
12
+ }
13
+
14
+ export type CommandHandler = (ctx: CommandContext) => Promise<void>
15
+
16
+ export type AutocompleteContext = {
17
+ interaction: AutocompleteInteraction
18
+ appId: string
19
+ }
20
+
21
+ export type AutocompleteHandler = (ctx: AutocompleteContext) => Promise<void>
22
+
23
+ export type SelectMenuHandler = (
24
+ interaction: StringSelectMenuInteraction,
25
+ ) => Promise<void>