@otto-assistant/otto 0.1.1 → 0.7.15

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 (637) 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-account-identity.js +62 -0
  7. package/dist/anthropic-account-identity.test.js +38 -0
  8. package/dist/anthropic-auth-plugin.js +917 -0
  9. package/dist/anthropic-auth-state.js +303 -0
  10. package/dist/anthropic-auth-state.test.js +150 -0
  11. package/dist/bin.js +152 -0
  12. package/dist/btw-prefix-detection.js +17 -0
  13. package/dist/btw-prefix-detection.test.js +63 -0
  14. package/dist/channel-management.js +259 -0
  15. package/dist/cli-parsing.test.js +142 -0
  16. package/dist/cli-send-thread.e2e.test.js +353 -0
  17. package/dist/cli-telegram-options.test.js +99 -0
  18. package/dist/cli.js +4210 -568
  19. package/dist/commands/abort.js +65 -0
  20. package/dist/commands/action-buttons.js +245 -0
  21. package/dist/commands/add-dir.js +124 -0
  22. package/dist/commands/add-dir.test.js +126 -0
  23. package/dist/commands/add-project.js +113 -0
  24. package/dist/commands/agent.js +355 -0
  25. package/dist/commands/ask-question.js +320 -0
  26. package/dist/commands/ask-question.test.js +92 -0
  27. package/dist/commands/btw.js +121 -0
  28. package/dist/commands/cli-commands-group-a.test.js +728 -0
  29. package/dist/commands/cli-commands-group-b.test.js +695 -0
  30. package/dist/commands/compact.js +120 -0
  31. package/dist/commands/context-usage.js +140 -0
  32. package/dist/commands/create-new-project.js +130 -0
  33. package/dist/commands/diff.js +63 -0
  34. package/dist/commands/discord-commands-group-a.test.js +621 -0
  35. package/dist/commands/discord-commands-group-b.test.js +595 -0
  36. package/dist/commands/discord-commands-group-c.test.js +739 -0
  37. package/dist/commands/file-upload.js +275 -0
  38. package/dist/commands/fork-subagent.js +177 -0
  39. package/dist/commands/fork.js +262 -0
  40. package/dist/commands/gemini-apikey.js +70 -0
  41. package/dist/commands/login.js +887 -0
  42. package/dist/commands/mcp.js +239 -0
  43. package/dist/commands/memory-snapshot.js +24 -0
  44. package/dist/commands/mention-mode.js +44 -0
  45. package/dist/commands/merge-worktree.js +162 -0
  46. package/dist/commands/model-variant.js +366 -0
  47. package/dist/commands/model.js +794 -0
  48. package/dist/commands/new-worktree.js +465 -0
  49. package/dist/commands/paginated-select.js +57 -0
  50. package/dist/commands/permissions.js +274 -0
  51. package/dist/commands/queue.js +223 -0
  52. package/dist/commands/remove-project.js +115 -0
  53. package/dist/commands/restart-opencode-server.js +127 -0
  54. package/dist/commands/resume.js +149 -0
  55. package/dist/commands/run-command.js +79 -0
  56. package/dist/commands/screenshare.js +303 -0
  57. package/dist/commands/screenshare.test.js +20 -0
  58. package/dist/commands/session-id.js +78 -0
  59. package/dist/commands/session.js +176 -0
  60. package/dist/commands/share.js +80 -0
  61. package/dist/commands/tasks.js +205 -0
  62. package/dist/commands/thread-deletion-sync.js +50 -0
  63. package/dist/commands/types.js +2 -0
  64. package/dist/commands/undo-redo.js +305 -0
  65. package/dist/commands/unset-model.js +139 -0
  66. package/dist/commands/upgrade.js +48 -0
  67. package/dist/commands/user-command.js +155 -0
  68. package/dist/commands/verbosity.js +125 -0
  69. package/dist/commands/vscode.js +269 -0
  70. package/dist/commands/worktree-settings.js +43 -0
  71. package/dist/commands/worktrees.js +468 -0
  72. package/dist/condense-memory.js +33 -0
  73. package/dist/config.js +100 -255
  74. package/dist/context-awareness-plugin.js +340 -0
  75. package/dist/context-awareness-plugin.test.js +126 -0
  76. package/dist/critique-utils.js +95 -0
  77. package/dist/database.js +1355 -0
  78. package/dist/db.js +260 -0
  79. package/dist/db.test.js +138 -0
  80. package/dist/debounce-timeout.js +28 -0
  81. package/dist/debounced-process-flush.js +77 -0
  82. package/dist/discord-bot.js +1124 -0
  83. package/dist/discord-command-registration.js +567 -0
  84. package/dist/discord-urls.js +82 -0
  85. package/dist/discord-utils.js +616 -0
  86. package/dist/discord-utils.test.js +134 -0
  87. package/dist/errors.js +157 -0
  88. package/dist/escape-backticks.test.js +429 -0
  89. package/dist/event-stream-real-capture.e2e.test.js +533 -0
  90. package/dist/eventsource-parser.test.js +327 -0
  91. package/dist/exec-async.js +26 -0
  92. package/dist/external-opencode-sync.js +480 -0
  93. package/dist/format-tables.js +491 -0
  94. package/dist/format-tables.test.js +478 -0
  95. package/dist/forum-sync/config.js +79 -0
  96. package/dist/forum-sync/discord-operations.js +154 -0
  97. package/dist/forum-sync/index.js +5 -0
  98. package/dist/forum-sync/markdown.js +113 -0
  99. package/dist/forum-sync/sync-to-discord.js +417 -0
  100. package/dist/forum-sync/sync-to-files.js +190 -0
  101. package/dist/forum-sync/types.js +53 -0
  102. package/dist/forum-sync/watchers.js +307 -0
  103. package/dist/gateway-proxy-reconnect.e2e.test.js +394 -0
  104. package/dist/gateway-proxy.e2e.test.js +485 -0
  105. package/dist/genai-worker-wrapper.js +111 -0
  106. package/dist/genai-worker.js +311 -0
  107. package/dist/genai.js +232 -0
  108. package/dist/generated/browser.js +17 -0
  109. package/dist/generated/client.js +37 -0
  110. package/dist/generated/commonInputTypes.js +10 -0
  111. package/dist/generated/enums.js +58 -0
  112. package/dist/generated/internal/class.js +49 -0
  113. package/dist/generated/internal/prismaNamespace.js +254 -0
  114. package/dist/generated/internal/prismaNamespaceBrowser.js +224 -0
  115. package/dist/generated/models/bot_api_keys.js +1 -0
  116. package/dist/generated/models/bot_tokens.js +1 -0
  117. package/dist/generated/models/channel_agents.js +1 -0
  118. package/dist/generated/models/channel_directories.js +1 -0
  119. package/dist/generated/models/channel_mention_mode.js +1 -0
  120. package/dist/generated/models/channel_models.js +1 -0
  121. package/dist/generated/models/channel_verbosity.js +1 -0
  122. package/dist/generated/models/channel_worktrees.js +1 -0
  123. package/dist/generated/models/forum_sync_configs.js +1 -0
  124. package/dist/generated/models/global_models.js +1 -0
  125. package/dist/generated/models/ipc_requests.js +1 -0
  126. package/dist/generated/models/part_messages.js +1 -0
  127. package/dist/generated/models/scheduled_tasks.js +1 -0
  128. package/dist/generated/models/session_agents.js +1 -0
  129. package/dist/generated/models/session_events.js +1 -0
  130. package/dist/generated/models/session_models.js +1 -0
  131. package/dist/generated/models/session_start_sources.js +1 -0
  132. package/dist/generated/models/thread_sessions.js +1 -0
  133. package/dist/generated/models/thread_worktrees.js +1 -0
  134. package/dist/generated/models.js +1 -0
  135. package/dist/heap-monitor.js +122 -0
  136. package/dist/hrana-server.js +251 -0
  137. package/dist/hrana-server.test.js +370 -0
  138. package/dist/html-actions.js +123 -0
  139. package/dist/html-actions.test.js +70 -0
  140. package/dist/html-components.js +117 -0
  141. package/dist/html-components.test.js +34 -0
  142. package/dist/image-optimizer-plugin.js +153 -0
  143. package/dist/image-utils.js +112 -0
  144. package/dist/interaction-handler.js +420 -0
  145. package/dist/ipc-polling.js +327 -0
  146. package/dist/ipc-tools-plugin.js +193 -0
  147. package/dist/ipc-utils.js +18 -0
  148. package/dist/limit-heading-depth.js +25 -0
  149. package/dist/limit-heading-depth.test.js +105 -0
  150. package/dist/logger.js +171 -0
  151. package/dist/markdown.js +342 -0
  152. package/dist/markdown.test.js +264 -0
  153. package/dist/memory-overview-plugin.js +128 -0
  154. package/dist/message-finish-field.e2e.test.js +168 -0
  155. package/dist/message-formatting.js +415 -0
  156. package/dist/message-formatting.test.js +115 -0
  157. package/dist/message-preprocessing.js +359 -0
  158. package/dist/onboarding-tutorial.js +163 -0
  159. package/dist/onboarding-welcome.js +37 -0
  160. package/dist/openai-realtime.js +224 -0
  161. package/dist/opencode-command-detection.js +65 -0
  162. package/dist/opencode-command-detection.test.js +240 -0
  163. package/dist/opencode-command.js +131 -0
  164. package/dist/opencode-command.test.js +48 -0
  165. package/dist/opencode-interrupt-plugin.js +388 -0
  166. package/dist/opencode-interrupt-plugin.test.js +463 -0
  167. package/dist/opencode.js +1117 -0
  168. package/dist/otto/branding.js +22 -0
  169. package/dist/otto/index.js +21 -0
  170. package/dist/otto-digital-twin.e2e.test.js +161 -0
  171. package/dist/otto-opencode-plugin-loading.e2e.test.js +94 -0
  172. package/dist/otto-opencode-plugin.js +21 -0
  173. package/dist/otto-opencode-plugin.test.js +98 -0
  174. package/dist/parse-permission-rules.test.js +117 -0
  175. package/dist/patch-text-parser.js +97 -0
  176. package/dist/plugin-logger.js +68 -0
  177. package/dist/privacy-sanitizer.js +105 -0
  178. package/dist/queue-advanced-abort.e2e.test.js +293 -0
  179. package/dist/queue-advanced-action-buttons.e2e.test.js +206 -0
  180. package/dist/queue-advanced-e2e-setup.js +790 -0
  181. package/dist/queue-advanced-footer.e2e.test.js +481 -0
  182. package/dist/queue-advanced-model-switch.e2e.test.js +299 -0
  183. package/dist/queue-advanced-permissions-typing.e2e.test.js +179 -0
  184. package/dist/queue-advanced-question.e2e.test.js +261 -0
  185. package/dist/queue-advanced-typing-interrupt.e2e.test.js +114 -0
  186. package/dist/queue-advanced-typing.e2e.test.js +153 -0
  187. package/dist/queue-drain-after-interactive-ui.e2e.test.js +119 -0
  188. package/dist/queue-interrupt-drain.e2e.test.js +135 -0
  189. package/dist/queue-question-select-drain.e2e.test.js +256 -0
  190. package/dist/runtime-idle-sweeper.js +52 -0
  191. package/dist/runtime-lifecycle.e2e.test.js +514 -0
  192. package/dist/sentry.js +23 -0
  193. package/dist/session-handler/agent-utils.js +67 -0
  194. package/dist/session-handler/event-stream-state.js +475 -0
  195. package/dist/session-handler/event-stream-state.test.js +632 -0
  196. package/dist/session-handler/model-utils.js +147 -0
  197. package/dist/session-handler/opencode-session-event-log.js +94 -0
  198. package/dist/session-handler/thread-runtime-state.js +131 -0
  199. package/dist/session-handler/thread-session-runtime.js +3390 -0
  200. package/dist/session-handler.js +9 -0
  201. package/dist/session-search.js +100 -0
  202. package/dist/session-search.test.js +40 -0
  203. package/dist/session-title-rename.test.js +92 -0
  204. package/dist/skill-filter.js +31 -0
  205. package/dist/skill-filter.test.js +65 -0
  206. package/dist/startup-service.js +153 -0
  207. package/dist/startup-time.e2e.test.js +296 -0
  208. package/dist/store.js +19 -0
  209. package/dist/subagent-rate-limit-plugin.js +175 -0
  210. package/dist/system-message.js +702 -0
  211. package/dist/system-message.test.js +697 -0
  212. package/dist/task-runner.js +530 -0
  213. package/dist/task-schedule.js +213 -0
  214. package/dist/task-schedule.test.js +71 -0
  215. package/dist/test-utils.js +313 -0
  216. package/dist/thinking-utils.js +35 -0
  217. package/dist/thread-message-queue.e2e.test.js +1111 -0
  218. package/dist/tools.js +357 -0
  219. package/dist/undo-redo.e2e.test.js +161 -0
  220. package/dist/unnest-code-blocks.js +146 -0
  221. package/dist/unnest-code-blocks.test.js +673 -0
  222. package/dist/upgrade.js +156 -0
  223. package/dist/utils.js +172 -0
  224. package/dist/utils.test.js +130 -0
  225. package/dist/voice-attachment.js +34 -0
  226. package/dist/voice-handler.js +646 -0
  227. package/dist/voice-message.e2e.test.js +1021 -0
  228. package/dist/voice.js +456 -0
  229. package/dist/voice.test.js +235 -0
  230. package/dist/wait-session.js +171 -0
  231. package/dist/websockify.js +69 -0
  232. package/dist/worker-types.js +4 -0
  233. package/dist/worktree-lifecycle.e2e.test.js +311 -0
  234. package/dist/worktree-utils.js +3 -0
  235. package/dist/worktrees.js +991 -0
  236. package/dist/worktrees.test.js +415 -0
  237. package/dist/xml.js +92 -0
  238. package/dist/xml.test.js +32 -0
  239. package/package.json +90 -38
  240. package/schema.prisma +303 -0
  241. package/skills/batch/SKILL.md +87 -0
  242. package/skills/critique/SKILL.md +112 -0
  243. package/skills/egaki/SKILL.md +100 -0
  244. package/skills/errore/SKILL.md +647 -0
  245. package/skills/event-sourcing-state/SKILL.md +252 -0
  246. package/skills/goke/SKILL.md +38 -0
  247. package/skills/jitter/EDITOR.md +219 -0
  248. package/skills/jitter/EXPORT-INTERNALS.md +309 -0
  249. package/skills/jitter/SKILL.md +158 -0
  250. package/skills/jitter/jitter-clipboard.json +1042 -0
  251. package/skills/jitter/package.json +14 -0
  252. package/skills/jitter/tsconfig.json +15 -0
  253. package/skills/jitter/utils/actions.ts +212 -0
  254. package/skills/jitter/utils/export.ts +114 -0
  255. package/skills/jitter/utils/index.ts +141 -0
  256. package/skills/jitter/utils/snapshot.ts +154 -0
  257. package/skills/jitter/utils/traverse.ts +246 -0
  258. package/skills/jitter/utils/types.ts +279 -0
  259. package/skills/jitter/utils/wait.ts +133 -0
  260. package/skills/lintcn/SKILL.md +873 -0
  261. package/skills/manual-kimaki-upstream-adapt/SKILL.md +114 -0
  262. package/skills/new-skill/SKILL.md +237 -0
  263. package/skills/npm-package/SKILL.md +617 -0
  264. package/skills/opensrc/SKILL.md +78 -0
  265. package/skills/otto-publish/SKILL.md +61 -0
  266. package/skills/playwriter/SKILL.md +35 -0
  267. package/skills/profano/SKILL.md +16 -0
  268. package/skills/proxyman/SKILL.md +215 -0
  269. package/skills/security-review/SKILL.md +208 -0
  270. package/skills/sigillo/SKILL.md +101 -0
  271. package/skills/simplify/SKILL.md +58 -0
  272. package/skills/spiceflow/SKILL.md +28 -0
  273. package/skills/termcast/SKILL.md +945 -0
  274. package/skills/tuistory/SKILL.md +98 -0
  275. package/skills/usecomputer/SKILL.md +264 -0
  276. package/skills/x-articles/SKILL.md +554 -0
  277. package/skills/zele/SKILL.md +49 -0
  278. package/skills/zustand-centralized-state/SKILL.md +1004 -0
  279. package/src/agent-model.e2e.test.ts +979 -0
  280. package/src/ai-tool-to-genai.test.ts +296 -0
  281. package/src/ai-tool-to-genai.ts +283 -0
  282. package/src/ai-tool.ts +39 -0
  283. package/src/anthropic-account-identity.test.ts +52 -0
  284. package/src/anthropic-account-identity.ts +77 -0
  285. package/src/anthropic-auth-plugin.ts +1139 -0
  286. package/src/anthropic-auth-state.test.ts +187 -0
  287. package/src/anthropic-auth-state.ts +386 -0
  288. package/src/bin.ts +182 -0
  289. package/src/btw-prefix-detection.test.ts +73 -0
  290. package/src/btw-prefix-detection.ts +23 -0
  291. package/src/channel-management.ts +376 -0
  292. package/src/cli-parsing.test.ts +197 -0
  293. package/src/cli-send-thread.e2e.test.ts +463 -0
  294. package/src/cli-telegram-options.test.ts +114 -0
  295. package/src/cli.ts +5718 -580
  296. package/src/commands/abort.ts +89 -0
  297. package/src/commands/action-buttons.ts +364 -0
  298. package/src/commands/add-dir.test.ts +154 -0
  299. package/src/commands/add-dir.ts +175 -0
  300. package/src/commands/add-project.ts +149 -0
  301. package/src/commands/agent.ts +496 -0
  302. package/src/commands/ask-question.test.ts +111 -0
  303. package/src/commands/ask-question.ts +455 -0
  304. package/src/commands/btw.ts +184 -0
  305. package/src/commands/cli-commands-group-a.test.ts +837 -0
  306. package/src/commands/cli-commands-group-b.test.ts +800 -0
  307. package/src/commands/compact.ts +157 -0
  308. package/src/commands/context-usage.ts +199 -0
  309. package/src/commands/create-new-project.ts +190 -0
  310. package/src/commands/diff.ts +91 -0
  311. package/src/commands/discord-commands-group-a.test.ts +751 -0
  312. package/src/commands/discord-commands-group-b.test.ts +648 -0
  313. package/src/commands/discord-commands-group-c.test.ts +882 -0
  314. package/src/commands/file-upload.ts +389 -0
  315. package/src/commands/fork-subagent.ts +263 -0
  316. package/src/commands/fork.ts +386 -0
  317. package/src/commands/gemini-apikey.ts +104 -0
  318. package/src/commands/login.ts +1175 -0
  319. package/src/commands/mcp.ts +307 -0
  320. package/src/commands/memory-snapshot.ts +30 -0
  321. package/src/commands/mention-mode.ts +68 -0
  322. package/src/commands/merge-worktree.ts +226 -0
  323. package/src/commands/model-variant.ts +485 -0
  324. package/src/commands/model.ts +1078 -0
  325. package/src/commands/new-worktree.ts +645 -0
  326. package/src/commands/paginated-select.ts +81 -0
  327. package/src/commands/permissions.ts +397 -0
  328. package/src/commands/queue.ts +293 -0
  329. package/src/commands/remove-project.ts +155 -0
  330. package/src/commands/restart-opencode-server.ts +162 -0
  331. package/src/commands/resume.ts +230 -0
  332. package/src/commands/run-command.ts +123 -0
  333. package/src/commands/screenshare.test.ts +30 -0
  334. package/src/commands/screenshare.ts +366 -0
  335. package/src/commands/session-id.ts +109 -0
  336. package/src/commands/session.ts +227 -0
  337. package/src/commands/share.ts +106 -0
  338. package/src/commands/tasks.ts +293 -0
  339. package/src/commands/thread-deletion-sync.ts +80 -0
  340. package/src/commands/types.ts +25 -0
  341. package/src/commands/undo-redo.ts +386 -0
  342. package/src/commands/unset-model.ts +174 -0
  343. package/src/commands/upgrade.ts +59 -0
  344. package/src/commands/user-command.ts +198 -0
  345. package/src/commands/verbosity.ts +173 -0
  346. package/src/commands/vscode.ts +342 -0
  347. package/src/commands/worktree-settings.ts +70 -0
  348. package/src/commands/worktrees.ts +645 -0
  349. package/src/condense-memory.ts +36 -0
  350. package/src/config.ts +103 -339
  351. package/src/context-awareness-plugin.test.ts +144 -0
  352. package/src/context-awareness-plugin.ts +469 -0
  353. package/src/critique-utils.ts +139 -0
  354. package/src/database.ts +1949 -0
  355. package/src/db.test.ts +162 -0
  356. package/src/db.ts +295 -0
  357. package/src/debounce-timeout.ts +43 -0
  358. package/src/debounced-process-flush.ts +104 -0
  359. package/src/discord-bot.ts +1505 -0
  360. package/src/discord-command-registration.ts +752 -0
  361. package/src/discord-urls.ts +89 -0
  362. package/src/discord-utils.test.ts +153 -0
  363. package/src/discord-utils.ts +846 -0
  364. package/src/errors.ts +201 -0
  365. package/src/escape-backticks.test.ts +469 -0
  366. package/src/event-stream-real-capture.e2e.test.ts +692 -0
  367. package/src/eventsource-parser.test.ts +351 -0
  368. package/src/exec-async.ts +35 -0
  369. package/src/external-opencode-sync.ts +685 -0
  370. package/src/format-tables.test.ts +515 -0
  371. package/src/format-tables.ts +718 -0
  372. package/src/forum-sync/config.ts +92 -0
  373. package/src/forum-sync/discord-operations.ts +241 -0
  374. package/src/forum-sync/index.ts +9 -0
  375. package/src/forum-sync/markdown.ts +172 -0
  376. package/src/forum-sync/sync-to-discord.ts +595 -0
  377. package/src/forum-sync/sync-to-files.ts +294 -0
  378. package/src/forum-sync/types.ts +175 -0
  379. package/src/forum-sync/watchers.ts +454 -0
  380. package/src/gateway-proxy-reconnect.e2e.test.ts +523 -0
  381. package/src/gateway-proxy.e2e.test.ts +644 -0
  382. package/src/genai-worker-wrapper.ts +164 -0
  383. package/src/genai-worker.ts +386 -0
  384. package/src/genai.ts +321 -0
  385. package/src/generated/browser.ts +114 -0
  386. package/src/generated/client.ts +138 -0
  387. package/src/generated/commonInputTypes.ts +770 -0
  388. package/src/generated/enums.ts +98 -0
  389. package/src/generated/internal/class.ts +384 -0
  390. package/src/generated/internal/prismaNamespace.ts +2394 -0
  391. package/src/generated/internal/prismaNamespaceBrowser.ts +327 -0
  392. package/src/generated/models/bot_api_keys.ts +1288 -0
  393. package/src/generated/models/bot_tokens.ts +1700 -0
  394. package/src/generated/models/channel_agents.ts +1256 -0
  395. package/src/generated/models/channel_directories.ts +1859 -0
  396. package/src/generated/models/channel_mention_mode.ts +1300 -0
  397. package/src/generated/models/channel_models.ts +1288 -0
  398. package/src/generated/models/channel_verbosity.ts +1228 -0
  399. package/src/generated/models/channel_worktrees.ts +1300 -0
  400. package/src/generated/models/forum_sync_configs.ts +1452 -0
  401. package/src/generated/models/global_models.ts +1288 -0
  402. package/src/generated/models/ipc_requests.ts +1485 -0
  403. package/src/generated/models/part_messages.ts +1302 -0
  404. package/src/generated/models/scheduled_tasks.ts +2320 -0
  405. package/src/generated/models/session_agents.ts +1086 -0
  406. package/src/generated/models/session_events.ts +1439 -0
  407. package/src/generated/models/session_models.ts +1114 -0
  408. package/src/generated/models/session_start_sources.ts +1408 -0
  409. package/src/generated/models/thread_sessions.ts +1781 -0
  410. package/src/generated/models/thread_worktrees.ts +1356 -0
  411. package/src/generated/models.ts +30 -0
  412. package/src/heap-monitor.ts +152 -0
  413. package/src/hrana-server.test.ts +434 -0
  414. package/src/hrana-server.ts +299 -0
  415. package/src/html-actions.test.ts +87 -0
  416. package/src/html-actions.ts +174 -0
  417. package/src/html-components.test.ts +38 -0
  418. package/src/html-components.ts +181 -0
  419. package/src/image-optimizer-plugin.ts +194 -0
  420. package/src/image-utils.ts +149 -0
  421. package/src/interaction-handler.ts +610 -0
  422. package/src/ipc-polling.ts +427 -0
  423. package/src/ipc-tools-plugin.ts +236 -0
  424. package/src/ipc-utils.ts +29 -0
  425. package/src/limit-heading-depth.test.ts +116 -0
  426. package/src/limit-heading-depth.ts +26 -0
  427. package/src/logger.ts +215 -0
  428. package/src/markdown.test.ts +315 -0
  429. package/src/markdown.ts +410 -0
  430. package/src/memory-overview-plugin.ts +163 -0
  431. package/src/message-finish-field.e2e.test.ts +195 -0
  432. package/src/message-formatting.test.ts +126 -0
  433. package/src/message-formatting.ts +535 -0
  434. package/src/message-preprocessing.ts +488 -0
  435. package/src/onboarding-tutorial.ts +167 -0
  436. package/src/onboarding-welcome.ts +49 -0
  437. package/src/openai-realtime.ts +358 -0
  438. package/src/opencode-command-detection.test.ts +307 -0
  439. package/src/opencode-command-detection.ts +76 -0
  440. package/src/opencode-command.test.ts +70 -0
  441. package/src/opencode-command.ts +191 -0
  442. package/src/opencode-interrupt-plugin.test.ts +682 -0
  443. package/src/opencode-interrupt-plugin.ts +507 -0
  444. package/src/opencode.ts +1453 -0
  445. package/src/otto/branding.ts +23 -0
  446. package/src/otto/index.ts +22 -0
  447. package/src/otto-digital-twin.e2e.test.ts +199 -0
  448. package/src/otto-opencode-plugin-loading.e2e.test.ts +117 -0
  449. package/src/otto-opencode-plugin.test.ts +108 -0
  450. package/src/otto-opencode-plugin.ts +22 -0
  451. package/src/parse-permission-rules.test.ts +127 -0
  452. package/src/patch-text-parser.ts +107 -0
  453. package/src/plugin-logger.ts +84 -0
  454. package/src/privacy-sanitizer.ts +142 -0
  455. package/src/queue-advanced-abort.e2e.test.ts +382 -0
  456. package/src/queue-advanced-action-buttons.e2e.test.ts +268 -0
  457. package/src/queue-advanced-e2e-setup.ts +877 -0
  458. package/src/queue-advanced-footer.e2e.test.ts +591 -0
  459. package/src/queue-advanced-model-switch.e2e.test.ts +383 -0
  460. package/src/queue-advanced-permissions-typing.e2e.test.ts +246 -0
  461. package/src/queue-advanced-question.e2e.test.ts +316 -0
  462. package/src/queue-advanced-typing-interrupt.e2e.test.ts +146 -0
  463. package/src/queue-advanced-typing.e2e.test.ts +199 -0
  464. package/src/queue-drain-after-interactive-ui.e2e.test.ts +151 -0
  465. package/src/queue-interrupt-drain.e2e.test.ts +166 -0
  466. package/src/queue-question-select-drain.e2e.test.ts +327 -0
  467. package/src/runtime-idle-sweeper.ts +76 -0
  468. package/src/runtime-lifecycle.e2e.test.ts +651 -0
  469. package/src/schema.sql +174 -0
  470. package/src/sentry.ts +26 -0
  471. package/src/session-handler/agent-utils.ts +99 -0
  472. package/src/session-handler/event-stream-fixtures/real-session-action-buttons.jsonl +45 -0
  473. package/src/session-handler/event-stream-fixtures/real-session-footer-suppressed-on-pre-idle-interrupt.jsonl +40 -0
  474. package/src/session-handler/event-stream-fixtures/real-session-permission-external-file.jsonl +23 -0
  475. package/src/session-handler/event-stream-fixtures/real-session-task-normal.jsonl +22 -0
  476. package/src/session-handler/event-stream-fixtures/real-session-task-three-parallel-sleeps.jsonl +277 -0
  477. package/src/session-handler/event-stream-fixtures/real-session-task-user-interruption.jsonl +46 -0
  478. package/src/session-handler/event-stream-fixtures/session-abort-after-idle-race.jsonl +21 -0
  479. package/src/session-handler/event-stream-fixtures/session-concurrent-messages-serialized.jsonl +56 -0
  480. package/src/session-handler/event-stream-fixtures/session-explicit-abort.jsonl +44 -0
  481. package/src/session-handler/event-stream-fixtures/session-normal-completion.jsonl +29 -0
  482. package/src/session-handler/event-stream-fixtures/session-tool-call-noisy-stream.jsonl +29 -0
  483. package/src/session-handler/event-stream-fixtures/session-two-completions-same-session.jsonl +50 -0
  484. package/src/session-handler/event-stream-fixtures/session-user-interruption.jsonl +59 -0
  485. package/src/session-handler/event-stream-fixtures/session-voice-queued-followup.jsonl +52 -0
  486. package/src/session-handler/event-stream-state.test.ts +717 -0
  487. package/src/session-handler/event-stream-state.ts +706 -0
  488. package/src/session-handler/model-utils.ts +217 -0
  489. package/src/session-handler/opencode-session-event-log.ts +130 -0
  490. package/src/session-handler/thread-runtime-state.ts +247 -0
  491. package/src/session-handler/thread-session-runtime.ts +4440 -0
  492. package/src/session-handler.ts +15 -0
  493. package/src/session-search.test.ts +50 -0
  494. package/src/session-search.ts +148 -0
  495. package/src/session-title-rename.test.ts +130 -0
  496. package/src/skill-filter.test.ts +83 -0
  497. package/src/skill-filter.ts +42 -0
  498. package/src/startup-service.ts +200 -0
  499. package/src/startup-time.e2e.test.ts +373 -0
  500. package/src/store.ts +139 -0
  501. package/src/subagent-rate-limit-plugin.ts +218 -0
  502. package/src/system-message.test.ts +710 -0
  503. package/src/system-message.ts +814 -0
  504. package/src/task-runner.ts +725 -0
  505. package/src/task-schedule.test.ts +84 -0
  506. package/src/task-schedule.ts +317 -0
  507. package/src/test-utils.ts +451 -0
  508. package/src/thinking-utils.ts +61 -0
  509. package/src/thread-message-queue.e2e.test.ts +1350 -0
  510. package/src/tools.ts +430 -0
  511. package/src/undici.d.ts +12 -0
  512. package/src/undo-redo.e2e.test.ts +209 -0
  513. package/src/unnest-code-blocks.test.ts +713 -0
  514. package/src/unnest-code-blocks.ts +185 -0
  515. package/src/upgrade.ts +185 -0
  516. package/src/utils.test.ts +155 -0
  517. package/src/utils.ts +265 -0
  518. package/src/voice-attachment.ts +51 -0
  519. package/src/voice-handler.ts +908 -0
  520. package/src/voice-message.e2e.test.ts +1255 -0
  521. package/src/voice.test.ts +281 -0
  522. package/src/voice.ts +638 -0
  523. package/src/wait-session.ts +273 -0
  524. package/src/websockify.ts +101 -0
  525. package/src/worker-types.ts +64 -0
  526. package/src/worktree-lifecycle.e2e.test.ts +396 -0
  527. package/src/worktree-utils.ts +4 -0
  528. package/src/worktrees.test.ts +489 -0
  529. package/src/worktrees.ts +1370 -0
  530. package/src/xml.test.ts +38 -0
  531. package/src/xml.ts +121 -0
  532. package/dist/cli.d.ts +0 -3
  533. package/dist/cli.d.ts.map +0 -1
  534. package/dist/cli.js.map +0 -1
  535. package/dist/config.d.ts +0 -39
  536. package/dist/config.d.ts.map +0 -1
  537. package/dist/config.js.map +0 -1
  538. package/dist/config.test.d.ts +0 -2
  539. package/dist/config.test.d.ts.map +0 -1
  540. package/dist/config.test.js +0 -202
  541. package/dist/config.test.js.map +0 -1
  542. package/dist/detect.d.ts +0 -9
  543. package/dist/detect.d.ts.map +0 -1
  544. package/dist/detect.js +0 -40
  545. package/dist/detect.js.map +0 -1
  546. package/dist/detect.test.d.ts +0 -2
  547. package/dist/detect.test.d.ts.map +0 -1
  548. package/dist/detect.test.js +0 -26
  549. package/dist/detect.test.js.map +0 -1
  550. package/dist/docker.d.ts +0 -7
  551. package/dist/docker.d.ts.map +0 -1
  552. package/dist/docker.js +0 -17
  553. package/dist/docker.js.map +0 -1
  554. package/dist/docker.test.d.ts +0 -2
  555. package/dist/docker.test.d.ts.map +0 -1
  556. package/dist/docker.test.js +0 -12
  557. package/dist/docker.test.js.map +0 -1
  558. package/dist/health.d.ts +0 -31
  559. package/dist/health.d.ts.map +0 -1
  560. package/dist/health.js +0 -117
  561. package/dist/health.js.map +0 -1
  562. package/dist/health.test.d.ts +0 -2
  563. package/dist/health.test.d.ts.map +0 -1
  564. package/dist/health.test.js +0 -52
  565. package/dist/health.test.js.map +0 -1
  566. package/dist/index.d.ts +0 -20
  567. package/dist/index.d.ts.map +0 -1
  568. package/dist/index.js +0 -15
  569. package/dist/index.js.map +0 -1
  570. package/dist/index.test.d.ts +0 -2
  571. package/dist/index.test.d.ts.map +0 -1
  572. package/dist/index.test.js +0 -8
  573. package/dist/index.test.js.map +0 -1
  574. package/dist/installer.d.ts +0 -10
  575. package/dist/installer.d.ts.map +0 -1
  576. package/dist/installer.js +0 -50
  577. package/dist/installer.js.map +0 -1
  578. package/dist/installer.test.d.ts +0 -2
  579. package/dist/installer.test.d.ts.map +0 -1
  580. package/dist/installer.test.js +0 -43
  581. package/dist/installer.test.js.map +0 -1
  582. package/dist/lifecycle.d.ts +0 -10
  583. package/dist/lifecycle.d.ts.map +0 -1
  584. package/dist/lifecycle.js +0 -45
  585. package/dist/lifecycle.js.map +0 -1
  586. package/dist/lifecycle.test.d.ts +0 -2
  587. package/dist/lifecycle.test.d.ts.map +0 -1
  588. package/dist/lifecycle.test.js +0 -20
  589. package/dist/lifecycle.test.js.map +0 -1
  590. package/dist/manifest.d.ts +0 -18
  591. package/dist/manifest.d.ts.map +0 -1
  592. package/dist/manifest.js +0 -30
  593. package/dist/manifest.js.map +0 -1
  594. package/dist/skills-baseline.d.ts +0 -7
  595. package/dist/skills-baseline.d.ts.map +0 -1
  596. package/dist/skills-baseline.js +0 -9
  597. package/dist/skills-baseline.js.map +0 -1
  598. package/dist/skills.d.ts +0 -110
  599. package/dist/skills.d.ts.map +0 -1
  600. package/dist/skills.js +0 -429
  601. package/dist/skills.js.map +0 -1
  602. package/dist/skills.test.d.ts +0 -2
  603. package/dist/skills.test.d.ts.map +0 -1
  604. package/dist/skills.test.js +0 -416
  605. package/dist/skills.test.js.map +0 -1
  606. package/dist/sync.d.ts +0 -10
  607. package/dist/sync.d.ts.map +0 -1
  608. package/dist/sync.js +0 -39
  609. package/dist/sync.js.map +0 -1
  610. package/dist/tenant.d.ts +0 -13
  611. package/dist/tenant.d.ts.map +0 -1
  612. package/dist/tenant.js +0 -105
  613. package/dist/tenant.js.map +0 -1
  614. package/dist/tenant.test.d.ts +0 -2
  615. package/dist/tenant.test.d.ts.map +0 -1
  616. package/dist/tenant.test.js +0 -37
  617. package/dist/tenant.test.js.map +0 -1
  618. package/src/config.test.ts +0 -237
  619. package/src/detect.test.ts +0 -29
  620. package/src/detect.ts +0 -52
  621. package/src/docker.test.ts +0 -12
  622. package/src/docker.ts +0 -23
  623. package/src/health.test.ts +0 -61
  624. package/src/health.ts +0 -158
  625. package/src/index.test.ts +0 -8
  626. package/src/index.ts +0 -62
  627. package/src/installer.test.ts +0 -52
  628. package/src/installer.ts +0 -62
  629. package/src/lifecycle.test.ts +0 -23
  630. package/src/lifecycle.ts +0 -49
  631. package/src/manifest.ts +0 -42
  632. package/src/skills-baseline.ts +0 -14
  633. package/src/skills.test.ts +0 -503
  634. package/src/skills.ts +0 -512
  635. package/src/sync.ts +0 -53
  636. package/src/tenant.test.ts +0 -49
  637. package/src/tenant.ts +0 -120
package/package.json CHANGED
@@ -1,51 +1,103 @@
1
1
  {
2
2
  "name": "@otto-assistant/otto",
3
- "version": "0.1.1",
4
- "description": "Otto — terminal UI distribution wrapper for opencode + kimaki + mempalace",
3
+ "repository": "https://github.com/otto-assistant/bridge",
4
+ "publishConfig": {
5
+ "access": "public",
6
+ "registry": "https://registry.npmjs.org"
7
+ },
8
+ "module": "index.ts",
5
9
  "type": "module",
6
- "bin": {
7
- "otto": "./dist/cli.js"
10
+ "version": "0.7.15",
11
+ "scripts": {
12
+ "dev": "tsx src/bin.ts",
13
+ "prepublishOnly": "pnpm build",
14
+ "build": "pnpm prepare-skills && pnpm generate && pnpm tsc",
15
+ "dev:bun": "DEBUG=1 bun --env-file .env src/bin.ts",
16
+ "watch": "tsx scripts/watch-session.ts",
17
+ "generate": "prisma generate && pnpm generate:sql",
18
+ "generate:sql": "rm -f dev.db && prisma db push --url 'file:dev.db' --accept-data-loss && echo '-- This file is generated by pnpm generate:sql. Do not edit manually.' > src/schema.sql && sqlite3 dev.db '.schema' >> src/schema.sql",
19
+ "pcm-to-mp3": "bun scripts/pcm-to-mp3",
20
+ "test": "vitest",
21
+ "validate-typing-indicator": "doppler run -- tsx scripts/validate-typing-indicator.ts",
22
+ "test:send": "tsx send-test-message.ts",
23
+ "register-commands": "tsx scripts/register-commands.ts",
24
+ "lint": "lintcn lint",
25
+ "format": "oxfmt src",
26
+ "prepare-skills": "rm -rf skills && mkdir -p skills && cp -R ../skills/. skills",
27
+ "sync-skills": "tsx scripts/sync-skills.ts"
8
28
  },
9
- "main": "./dist/index.js",
10
- "types": "./dist/index.d.ts",
11
- "exports": {
12
- "./package.json": "./package.json",
13
- ".": {
14
- "types": "./dist/index.d.ts",
15
- "default": "./dist/index.js"
16
- }
29
+ "bin": {
30
+ "otto": "bin.js"
17
31
  },
18
32
  "files": [
33
+ "dist",
19
34
  "src",
20
- "dist"
21
- ],
22
- "keywords": [
23
- "otto",
24
- "opencode",
25
- "kimaki",
26
- "ai-agent",
27
- "distribution"
35
+ "skills",
36
+ "schema.prisma",
37
+ "bin.js"
28
38
  ],
29
- "license": "MIT",
30
- "repository": {
31
- "type": "git",
32
- "url": "git+https://github.com/otto-assistant/otto.git"
33
- },
34
- "scripts": {
35
- "build": "rm -rf dist *.tsbuildinfo && tsc && chmod +x dist/cli.js",
36
- "dev": "tsc --watch",
37
- "build:artifacts": "./scripts/build-local-artifacts.sh",
38
- "prepublishOnly": "pnpm build",
39
- "test": "vitest run",
40
- "test:watch": "vitest"
39
+ "devDependencies": {
40
+ "@types/bun": "latest",
41
+ "@types/heic-convert": "^2.1.0",
42
+ "@types/json-schema": "^7.0.15",
43
+ "@types/ms": "^2.1.0",
44
+ "@types/node": "^24.3.0",
45
+ "@types/proper-lockfile": "^4.1.4",
46
+ "@types/ws": "^8.18.1",
47
+ "db": "workspace:^",
48
+ "discord-digital-twin": "workspace:^",
49
+ "discord-telegram-bridge": "workspace:^",
50
+ "eventsource-parser": "^3.0.6",
51
+ "lintcn": "^0.7.1",
52
+ "opencode-cached-provider": "workspace:^",
53
+ "opencode-deterministic-provider": "workspace:^",
54
+ "prisma": "7.4.2",
55
+ "tsx": "^4.20.5",
56
+ "undici": "^8.0.2"
41
57
  },
42
58
  "dependencies": {
43
- "@clack/prompts": "^0.9.1",
44
- "picocolors": "^1.1.1"
59
+ "@ai-sdk/google": "^3.0.53",
60
+ "@ai-sdk/openai": "^3.0.31",
61
+ "@ai-sdk/provider": "^3.0.8",
62
+ "@clack/prompts": "^1.0.0",
63
+ "@discordjs/voice": "^0.19.0",
64
+ "@google/genai": "^1.46.0",
65
+ "@libsql/client": "^0.17.2",
66
+ "@opencode-ai/plugin": "^1.4.6",
67
+ "@opencode-ai/sdk": "^1.4.6",
68
+ "@parcel/watcher": "^2.5.6",
69
+ "@prisma/adapter-libsql": "7.4.2",
70
+ "@prisma/client": "7.4.2",
71
+ "@purinton/resampler": "^1.0.4",
72
+ "cron-parser": "^5.5.0",
73
+ "diff": "^8.0.4",
74
+ "discord.js": "^14.25.1",
75
+ "domhandler": "^6.0.1",
76
+ "errore": "^0.14.1",
77
+ "goke": "^6.8.0",
78
+ "htmlparser2": "^12.0.0",
79
+ "kitty-graphics-agent": "^0.0.5",
80
+ "libsql": "^0.5.22",
81
+ "libsqlproxy": "^0.1.0",
82
+ "marked": "^17.0.5",
83
+ "mime": "^4.1.0",
84
+ "opencode-injection-guard": "^0.2.1",
85
+ "opusscript": "^0.0.8",
86
+ "picocolors": "^1.1.1",
87
+ "pretty-ms": "^9.3.0",
88
+ "proper-lockfile": "^4.1.2",
89
+ "string-dedent": "^3.0.2",
90
+ "traforo": "^0.4.0",
91
+ "ws": "^8.19.0",
92
+ "xdg-basedir": "^5.1.0",
93
+ "yaml": "^2.8.3",
94
+ "zod": "^4.3.6",
95
+ "zustand": "^5.0.11"
45
96
  },
46
- "devDependencies": {
47
- "@types/node": "^22.19.17",
48
- "typescript": "^5.7.3",
49
- "vitest": "^3.2.0"
97
+ "optionalDependencies": {
98
+ "@snazzah/davey": "^0.1.10",
99
+ "heic-convert": "^2.1.0",
100
+ "prism-media": "^1.3.5",
101
+ "sharp": "^0.34.5"
50
102
  }
51
103
  }
package/schema.prisma ADDED
@@ -0,0 +1,303 @@
1
+ // schema.prisma for the otto local db
2
+ // prefer using enum for strings with few known options so it is type safe in typescript code. sqlite does not have enum. this is a prisma only concept
3
+ // these enums will be also exported as types by prisma and we can reuse them in our code
4
+
5
+ generator client {
6
+ provider = "prisma-client"
7
+ output = "./src/generated"
8
+ }
9
+
10
+ datasource db {
11
+ provider = "sqlite"
12
+ }
13
+
14
+ model thread_sessions {
15
+ thread_id String @id
16
+ session_id String
17
+ source ThreadSessionSource @default(otto)
18
+ created_at DateTime? @default(now())
19
+
20
+ part_messages part_messages[]
21
+ session_events session_events[]
22
+ scheduled_tasks scheduled_tasks[]
23
+ thread_worktree thread_worktrees?
24
+ ipc_requests ipc_requests[]
25
+ }
26
+
27
+ enum ThreadSessionSource {
28
+ otto
29
+ kimaki
30
+ external_poll
31
+ }
32
+
33
+ model session_events {
34
+ id Int @id @default(autoincrement())
35
+ session_id String
36
+ thread_id String
37
+ timestamp BigInt // milliseconds since Unix epoch
38
+ event_index Int // stable in-memory insertion order within a session
39
+ event_json String
40
+
41
+ thread thread_sessions @relation(fields: [thread_id], references: [thread_id], onDelete: Cascade, onUpdate: Cascade)
42
+
43
+ @@index([session_id, timestamp, event_index, id])
44
+ @@index([thread_id, timestamp, event_index, id])
45
+ }
46
+
47
+ model part_messages {
48
+ part_id String @id
49
+ message_id String
50
+ thread_id String
51
+ created_at DateTime? @default(now())
52
+
53
+ thread thread_sessions @relation(fields: [thread_id], references: [thread_id])
54
+ }
55
+
56
+ model bot_tokens {
57
+ app_id String @id
58
+ token String
59
+ bot_mode BotMode @default(self_hosted)
60
+ thread_deletion_sync_mode ThreadDeletionSyncMode?
61
+ client_id String?
62
+ client_secret String?
63
+ proxy_url String?
64
+ created_at DateTime? @default(now())
65
+ last_used_at DateTime?
66
+
67
+ api_keys bot_api_keys?
68
+ forum_sync_configs forum_sync_configs[]
69
+ global_model global_models?
70
+ }
71
+
72
+ enum BotMode {
73
+ self_hosted
74
+ gateway
75
+ }
76
+
77
+ enum ThreadDeletionSyncMode {
78
+ soft
79
+ hard
80
+ }
81
+
82
+ model channel_directories {
83
+ channel_id String @id
84
+ directory String
85
+ channel_type ChannelType
86
+ // app_id String? // no longer used: channel ownership is no longer scoped per bot app
87
+ created_at DateTime? @default(now())
88
+
89
+ channel_model channel_models?
90
+ channel_agent channel_agents?
91
+ channel_worktree channel_worktrees?
92
+ channel_verbosity channel_verbosity?
93
+ channel_mention_mode channel_mention_mode?
94
+ scheduled_tasks scheduled_tasks[]
95
+ }
96
+
97
+ enum ChannelType {
98
+ text
99
+ voice
100
+ }
101
+
102
+ model bot_api_keys {
103
+ app_id String @id
104
+ gemini_api_key String?
105
+ openai_api_key String?
106
+ xai_api_key String?
107
+ created_at DateTime? @default(now())
108
+
109
+ bot bot_tokens @relation(fields: [app_id], references: [app_id])
110
+ }
111
+
112
+ model thread_worktrees {
113
+ thread_id String @id
114
+ worktree_name String
115
+ worktree_directory String?
116
+ project_directory String
117
+ status WorktreeStatus @default(pending)
118
+ error_message String?
119
+ created_at DateTime? @default(now())
120
+
121
+ thread thread_sessions @relation(fields: [thread_id], references: [thread_id])
122
+ }
123
+
124
+ enum WorktreeStatus {
125
+ pending
126
+ ready
127
+ error
128
+ }
129
+
130
+ model channel_models {
131
+ channel_id String @id
132
+ model_id String
133
+ variant String?
134
+ created_at DateTime? @default(now())
135
+ updated_at DateTime? @default(now()) @updatedAt
136
+
137
+ channel channel_directories @relation(fields: [channel_id], references: [channel_id])
138
+ }
139
+
140
+ model session_models {
141
+ session_id String @id
142
+ model_id String
143
+ variant String?
144
+ created_at DateTime? @default(now())
145
+ }
146
+
147
+ model channel_agents {
148
+ channel_id String @id
149
+ agent_name String
150
+ created_at DateTime? @default(now())
151
+ updated_at DateTime? @default(now()) @updatedAt
152
+
153
+ channel channel_directories @relation(fields: [channel_id], references: [channel_id])
154
+ }
155
+
156
+ model session_agents {
157
+ session_id String @id
158
+ agent_name String
159
+ created_at DateTime? @default(now())
160
+ }
161
+
162
+ model channel_worktrees {
163
+ channel_id String @id
164
+ enabled Int @default(0)
165
+ created_at DateTime? @default(now())
166
+ updated_at DateTime? @default(now()) @updatedAt
167
+
168
+ channel channel_directories @relation(fields: [channel_id], references: [channel_id])
169
+ }
170
+
171
+ model channel_verbosity {
172
+ channel_id String @id
173
+ verbosity VerbosityLevel @default(tools_and_text)
174
+ updated_at DateTime? @default(now()) @updatedAt
175
+
176
+ channel channel_directories @relation(fields: [channel_id], references: [channel_id])
177
+ }
178
+
179
+ enum VerbosityLevel {
180
+ tools_and_text
181
+ text_and_essential_tools
182
+ text_only
183
+ }
184
+
185
+ model channel_mention_mode {
186
+ channel_id String @id
187
+ enabled Int @default(0)
188
+ created_at DateTime? @default(now())
189
+ updated_at DateTime? @default(now()) @updatedAt
190
+
191
+ channel channel_directories @relation(fields: [channel_id], references: [channel_id])
192
+ }
193
+
194
+ model global_models {
195
+ app_id String @id
196
+ model_id String
197
+ variant String?
198
+ created_at DateTime? @default(now())
199
+ updated_at DateTime? @default(now()) @updatedAt
200
+
201
+ bot bot_tokens @relation(fields: [app_id], references: [app_id])
202
+ }
203
+
204
+ enum task_status {
205
+ planned
206
+ running
207
+ completed
208
+ cancelled
209
+ failed
210
+ }
211
+
212
+ enum task_schedule_kind {
213
+ at
214
+ cron
215
+ }
216
+
217
+ model scheduled_tasks {
218
+ id Int @id @default(autoincrement())
219
+ status task_status @default(planned)
220
+ schedule_kind task_schedule_kind
221
+ run_at DateTime?
222
+ cron_expr String?
223
+ timezone String?
224
+ next_run_at DateTime
225
+ running_started_at DateTime?
226
+ last_run_at DateTime?
227
+ last_error String?
228
+ attempts Int @default(0)
229
+ payload_json String
230
+ prompt_preview String
231
+ channel_id String?
232
+ thread_id String?
233
+ session_id String?
234
+ project_directory String?
235
+ created_at DateTime? @default(now())
236
+ updated_at DateTime? @default(now()) @updatedAt
237
+
238
+ channel channel_directories? @relation(fields: [channel_id], references: [channel_id], onDelete: SetNull, onUpdate: Cascade)
239
+ thread thread_sessions? @relation(fields: [thread_id], references: [thread_id], onDelete: SetNull, onUpdate: Cascade)
240
+ session_start_sources session_start_sources[]
241
+
242
+ @@index([status, next_run_at])
243
+ @@index([channel_id, status])
244
+ @@index([thread_id, status])
245
+ }
246
+
247
+ model session_start_sources {
248
+ session_id String @id
249
+ schedule_kind task_schedule_kind
250
+ scheduled_task_id Int?
251
+ created_at DateTime? @default(now())
252
+ updated_at DateTime? @default(now()) @updatedAt
253
+
254
+ scheduled_task scheduled_tasks? @relation(fields: [scheduled_task_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
255
+
256
+ @@index([scheduled_task_id])
257
+ }
258
+
259
+ model forum_sync_configs {
260
+ id Int @id @default(autoincrement())
261
+ app_id String
262
+ forum_channel_id String
263
+ output_dir String
264
+ direction String @default("bidirectional")
265
+ created_at DateTime? @default(now())
266
+ updated_at DateTime? @default(now()) @updatedAt
267
+
268
+ bot bot_tokens @relation(fields: [app_id], references: [app_id], onDelete: Cascade, onUpdate: Cascade)
269
+
270
+ @@unique([app_id, forum_channel_id])
271
+ }
272
+
273
+ enum ipc_request_type {
274
+ file_upload
275
+ action_buttons
276
+ start_thread_listener
277
+ }
278
+
279
+ enum ipc_request_status {
280
+ pending
281
+ processing
282
+ completed
283
+ cancelled
284
+ }
285
+
286
+ // IPC bridge between the opencode plugin process and the Discord bot process.
287
+ // Replaces the old HTTP lock server for file-upload and action-buttons requests.
288
+ // Plugin inserts a pending row, bot polls and dispatches, then writes the response.
289
+ model ipc_requests {
290
+ id String @id @default(uuid())
291
+ type ipc_request_type
292
+ session_id String
293
+ thread_id String
294
+ payload String // JSON-encoded request data
295
+ response String? // JSON-encoded response, null while pending
296
+ status ipc_request_status @default(pending)
297
+ created_at DateTime @default(now())
298
+ updated_at DateTime @default(now()) @updatedAt
299
+
300
+ thread thread_sessions @relation(fields: [thread_id], references: [thread_id])
301
+
302
+ @@index([status, created_at])
303
+ }
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: batch
3
+ description: >
4
+ Research and plan a large-scale change, then execute it in parallel across
5
+ 5-30 isolated worktree agents that each open a PR. Use when the user wants
6
+ to make a sweeping, mechanical change across many files (migrations,
7
+ refactors, bulk renames) that can be decomposed into independent parallel
8
+ units.
9
+ argument-hint: "<instruction>"
10
+ source-path: cli.js (line 7359, function mGz)
11
+ source-package: "@anthropic-ai/claude-code@2.1.63"
12
+ source-date: 2026-02-28
13
+ ---
14
+
15
+ # Batch: Parallel Work Orchestration
16
+
17
+ You are orchestrating a large, parallelizable change across this codebase.
18
+
19
+ ## User Instruction
20
+
21
+ $instruction
22
+
23
+ ## Phase 1: Research and Plan (Plan Mode)
24
+
25
+ Enter plan mode, then:
26
+
27
+ 1. **Understand the scope.** Launch one or more Explore agents (in the foreground — you need their results) to deeply research what this instruction touches. Find all the files, patterns, and call sites that need to change. Understand the existing conventions so the migration is consistent.
28
+
29
+ 2. **Decompose into independent units.** Break the work into 5–30 self-contained units. Each unit must:
30
+ - Be independently implementable in an isolated git worktree (no shared state with sibling units)
31
+ - Be mergeable on its own without depending on another unit's PR landing first
32
+ - Be roughly uniform in size (split large units, merge trivial ones)
33
+
34
+ Scale the count to the actual work: few files → closer to 5; hundreds of files → closer to 30. Prefer per-directory or per-module slicing over arbitrary file lists.
35
+
36
+ 3. **Determine the e2e test recipe.** Figure out how a worker can verify its change actually works end-to-end — not just that unit tests pass. Look for:
37
+ - A browser-automation tool (for UI changes: click through the affected flow, screenshot the result)
38
+ - A tuistory or CLI-verifier skill (for CLI changes: launch the app interactively, exercise the changed behavior)
39
+ - A dev-server + curl pattern (for API changes: start the server, hit the affected endpoints)
40
+ - An existing e2e/integration test suite the worker can run
41
+
42
+ If you cannot find a concrete e2e path, ask the user how to verify this change end-to-end. Offer 2–3 specific options based on what you found (e.g., "Screenshot via chrome extension", "Run `bun run dev` and curl the endpoint", "No e2e — unit tests are sufficient"). Do not skip this — the workers cannot ask the user themselves.
43
+
44
+ Write the recipe as a short, concrete set of steps that a worker can execute autonomously. Include any setup (start a dev server, build first) and the exact command/interaction to verify.
45
+
46
+ 4. **Write the plan.** In your plan file, include:
47
+ - A summary of what you found during research
48
+ - A numbered list of work units — for each: a short title, the list of files/directories it covers, and a one-line description of the change
49
+ - The e2e test recipe (or "skip e2e because …" if the user chose that)
50
+ - The exact worker instructions you will give each agent (the shared template)
51
+
52
+ 5. Present the plan for approval.
53
+
54
+ ## Phase 2: Spawn Workers (After Plan Approval)
55
+
56
+ Once the plan is approved, spawn one background agent per work unit using the Task tool. **All agents must use `isolation: "worktree"` and `run_in_background: true`.** Launch them all in a single message block so they run in parallel.
57
+
58
+ For each agent, the prompt must be fully self-contained. Include:
59
+ - The overall goal (the user's instruction)
60
+ - This unit's specific task (title, file list, change description — copied verbatim from your plan)
61
+ - Any codebase conventions you discovered that the worker needs to follow
62
+ - The e2e test recipe from your plan (or "skip e2e because …")
63
+ - The worker instructions below, copied verbatim:
64
+
65
+ ```
66
+ After you finish implementing the change:
67
+ 1. **Simplify** — Invoke the simplify skill to review and clean up your changes.
68
+ 2. **Run unit tests** — Run the project's test suite (check for package.json scripts, Makefile targets, or common commands like `npm test`, `bun test`, `pytest`, `go test`). If tests fail, fix them.
69
+ 3. **Test end-to-end** — Follow the e2e test recipe from the coordinator's prompt (below). If the recipe says to skip e2e for this unit, skip it.
70
+ 4. **Commit and push** — Commit all changes with a clear message, push the branch, and create a PR with `gh pr create`. Use a descriptive title. If `gh` is not available or the push fails, note it in your final message.
71
+ 5. **Report** — End with a single line: `PR: <url>` so the coordinator can track it. If no PR was created, end with `PR: none — <reason>`.
72
+ ```
73
+
74
+ Use `subagent_type: "general-purpose"` unless a more specific agent type fits.
75
+
76
+ ## Phase 3: Track Progress
77
+
78
+ After launching all workers, render an initial status table:
79
+
80
+ | # | Unit | Status | PR |
81
+ |---|------|--------|----|
82
+ | 1 | <title> | running | — |
83
+ | 2 | <title> | running | — |
84
+
85
+ As background-agent completion notifications arrive, parse the `PR: <url>` line from each agent's result and re-render the table with updated status (`done` / `failed`) and PR links. Keep a brief failure note for any agent that did not produce a PR.
86
+
87
+ When all agents have reported, render the final table and a one-line summary (e.g., "22/24 units landed as PRs").
@@ -0,0 +1,112 @@
1
+ ---
2
+ name: critique
3
+ description: >
4
+ Git diff viewer. Renders diffs as web pages, images, and PDFs
5
+ with syntax highlighting. Use this skill when working with critique for showing
6
+ diffs, generating diff URLs, or selective hunk staging.
7
+ ---
8
+
9
+ # critique
10
+
11
+ Git diff viewer that renders diffs as **web pages**, **images**, and **PDFs** with syntax highlighting.
12
+
13
+ Agents running in headless environments (otto on Discord, openclaw on Slack/Telegram) have no terminal to show diffs. critique uploads diffs to critique.work and returns a shareable URL you can paste into chat. Users click the link and see a syntax-highlighted split-view diff with mobile support and dark/light mode — no install needed.
14
+
15
+ **Always run `critique --help` first** to see the latest flags and commands. The help output is the source of truth.
16
+
17
+ ## Web — shareable diff URLs
18
+
19
+ Always pass a title to describe what the diff contains.
20
+
21
+ ```bash
22
+ # Working tree changes
23
+ critique --web "Add retry logic to database connections"
24
+
25
+ # Staged changes
26
+ critique --staged --web "Refactor auth middleware"
27
+
28
+ # Branch diff (three-dot: changes since diverging from base)
29
+ critique main...HEAD --web "Feature branch changes"
30
+ critique main...feature-branch --web "Compare branches"
31
+
32
+ # Last N commits
33
+ critique HEAD~3 --web "Recent changes"
34
+
35
+ # Specific commit
36
+ critique --commit HEAD --web "Latest commit"
37
+ critique --commit abc1234 --web "Fix race condition"
38
+
39
+ # Filter to specific files
40
+ critique --web "API changes" --filter "src/api.ts" --filter "src/utils.ts"
41
+
42
+ # JSON output for programmatic use (returns {url, id, files})
43
+ critique --web "Deploy changes" --json
44
+ ```
45
+
46
+ Share the returned URL with the user so they can see the diff.
47
+
48
+ ## PDF
49
+
50
+ ```bash
51
+ critique --pdf # working tree to PDF
52
+ critique --staged --pdf # staged changes
53
+ critique main...HEAD --pdf # branch diff
54
+ critique --commit HEAD --pdf # single commit
55
+ critique --pdf output.pdf # custom filename
56
+ critique --pdf --pdf-page-size a4-portrait # page size options
57
+ critique main...HEAD --pdf --open # open in viewer
58
+ ```
59
+
60
+ ## Image
61
+
62
+ ```bash
63
+ critique --image # renders to /tmp as WebP
64
+ critique main...HEAD --image # branch diff as images
65
+ ```
66
+
67
+ ## Selective hunk staging
68
+
69
+ When multiple agents work on the same repo, each agent should only commit its own changes. `critique hunks` lets you stage individual hunks instead of whole files — like a scriptable `git add -p`.
70
+
71
+ ```bash
72
+ # List hunks with stable IDs
73
+ critique hunks list
74
+ critique hunks list --filter "src/**/*.ts"
75
+
76
+ # Stage specific hunks by ID
77
+ critique hunks add 'src/main.ts:@-10,6+10,7'
78
+ critique hunks add 'src/main.ts:@-10,6+10,7' 'src/utils.ts:@-5,3+5,4'
79
+ ```
80
+
81
+ Hunk ID format: `file:@-oldStart,oldLines+newStart,newLines` — derived from the `@@` diff header, stable across runs.
82
+
83
+ **Typical workflow:**
84
+
85
+ ```bash
86
+ critique hunks list # see all unstaged hunks
87
+ critique hunks add 'file:@-10,6+10,7' # stage only your hunks
88
+ git commit -m "your changes" # commit separately
89
+ ```
90
+
91
+ ## Raw patch access
92
+
93
+ Every `--web` upload also stores the raw unified diff. Append `.patch` to any critique URL to get it:
94
+
95
+ ```bash
96
+ # View the raw patch
97
+ curl https://critique.work/v/<id>.patch
98
+
99
+ # Apply the patch to current repo
100
+ curl -s https://critique.work/v/<id>.patch | git apply
101
+
102
+ # Reverse the patch (undo the changes)
103
+ curl -s https://critique.work/v/<id>.patch | git apply --reverse
104
+ ```
105
+
106
+ Useful when an agent shares a critique URL and you want to programmatically apply or revert those changes.
107
+
108
+ ## Notes
109
+
110
+ - Requires **Bun** — use `bunx critique` or global `critique`
111
+ - Lock files and diffs >6000 lines are auto-hidden
112
+ - `--web` URLs expire after 7 days (content-hashed, same diff = same URL)