kimaki 0.31.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (989) hide show
  1. package/dist/agent-ui.d.ts +33 -0
  2. package/dist/agent-ui.e2e.test.d.ts +1 -0
  3. package/dist/agent-ui.e2e.test.js +140 -0
  4. package/dist/agent-ui.e2e.test.js.map +1 -0
  5. package/dist/agent-ui.js +199 -0
  6. package/dist/agent-ui.js.map +1 -0
  7. package/dist/analytics.d.ts +42 -0
  8. package/dist/analytics.e2e.test.d.ts +1 -0
  9. package/dist/analytics.e2e.test.js +112 -0
  10. package/dist/analytics.e2e.test.js.map +1 -0
  11. package/dist/analytics.js +162 -223
  12. package/dist/analytics.js.map +1 -0
  13. package/dist/analytics.test.d.ts +1 -0
  14. package/dist/analytics.test.js +121 -157
  15. package/dist/analytics.test.js.map +1 -0
  16. package/dist/autostart.d.ts +7 -0
  17. package/dist/autostart.js +75 -0
  18. package/dist/autostart.js.map +1 -0
  19. package/dist/bot.d.ts +90 -0
  20. package/dist/bot.js +120 -0
  21. package/dist/bot.js.map +1 -0
  22. package/dist/btw.e2e.test.d.ts +1 -0
  23. package/dist/btw.e2e.test.js +102 -0
  24. package/dist/btw.e2e.test.js.map +1 -0
  25. package/dist/catalog-refresh.e2e.test.d.ts +1 -0
  26. package/dist/catalog-refresh.e2e.test.js +90 -0
  27. package/dist/catalog-refresh.e2e.test.js.map +1 -0
  28. package/dist/cli/bot.d.ts +5 -0
  29. package/dist/cli/bot.js +427 -0
  30. package/dist/cli/bot.js.map +1 -0
  31. package/dist/cli/discord.d.ts +3 -0
  32. package/dist/cli/discord.js +118 -0
  33. package/dist/cli/discord.js.map +1 -0
  34. package/dist/cli/project.d.ts +5 -0
  35. package/dist/cli/project.js +143 -0
  36. package/dist/cli/project.js.map +1 -0
  37. package/dist/cli/schedule.d.ts +3 -0
  38. package/dist/cli/schedule.js +156 -0
  39. package/dist/cli/schedule.js.map +1 -0
  40. package/dist/cli/session.d.ts +4 -0
  41. package/dist/cli/session.js +281 -0
  42. package/dist/cli/session.js.map +1 -0
  43. package/dist/cli/shared.d.ts +55 -0
  44. package/dist/cli/shared.js +138 -0
  45. package/dist/cli/shared.js.map +1 -0
  46. package/dist/cli-discord.e2e.test.d.ts +1 -0
  47. package/dist/cli-discord.e2e.test.js +64 -0
  48. package/dist/cli-discord.e2e.test.js.map +1 -0
  49. package/dist/cli-lock.e2e.test.d.ts +1 -0
  50. package/dist/cli-lock.e2e.test.js +520 -0
  51. package/dist/cli-lock.e2e.test.js.map +1 -0
  52. package/dist/cli-read.e2e.test.d.ts +1 -0
  53. package/dist/cli-read.e2e.test.js +81 -0
  54. package/dist/cli-read.e2e.test.js.map +1 -0
  55. package/dist/cli-sessions.e2e.test.d.ts +1 -0
  56. package/dist/cli-sessions.e2e.test.js +116 -0
  57. package/dist/cli-sessions.e2e.test.js.map +1 -0
  58. package/dist/cli.d.ts +2 -0
  59. package/dist/cli.js +34 -263
  60. package/dist/cli.js.map +1 -0
  61. package/dist/commands/login-commands.d.ts +59 -0
  62. package/dist/commands/login-commands.js +341 -0
  63. package/dist/commands/login-commands.js.map +1 -0
  64. package/dist/commands/preference-commands.d.ts +44 -0
  65. package/dist/commands/preference-commands.js +551 -0
  66. package/dist/commands/preference-commands.js.map +1 -0
  67. package/dist/commands/session-commands.d.ts +8 -0
  68. package/dist/commands/session-commands.js +267 -0
  69. package/dist/commands/session-commands.js.map +1 -0
  70. package/dist/commands/thread-commands.d.ts +16 -0
  71. package/dist/commands/thread-commands.js +285 -0
  72. package/dist/commands/thread-commands.js.map +1 -0
  73. package/dist/commands/worktree-commands.d.ts +41 -0
  74. package/dist/commands/worktree-commands.js +279 -0
  75. package/dist/commands/worktree-commands.js.map +1 -0
  76. package/dist/commands.e2e.test.d.ts +1 -0
  77. package/dist/commands.e2e.test.js +255 -0
  78. package/dist/commands.e2e.test.js.map +1 -0
  79. package/dist/credentials.d.ts +84 -0
  80. package/dist/credentials.js +320 -0
  81. package/dist/credentials.js.map +1 -0
  82. package/dist/db.d.ts +1532 -0
  83. package/dist/db.js +57 -245
  84. package/dist/db.js.map +1 -0
  85. package/dist/db.test.d.ts +1 -0
  86. package/dist/db.test.js +351 -682
  87. package/dist/db.test.js.map +1 -0
  88. package/dist/duration.d.ts +2 -0
  89. package/dist/duration.js +18 -0
  90. package/dist/duration.js.map +1 -0
  91. package/dist/effects.d.ts +15 -0
  92. package/dist/effects.js +291 -0
  93. package/dist/effects.js.map +1 -0
  94. package/dist/errors.d.ts +38 -0
  95. package/dist/errors.js +40 -175
  96. package/dist/errors.js.map +1 -0
  97. package/dist/event-loop.d.ts +40 -0
  98. package/dist/event-loop.js +414 -0
  99. package/dist/event-loop.js.map +1 -0
  100. package/dist/file-edit-log.d.ts +41 -0
  101. package/dist/file-edit-log.js +122 -164
  102. package/dist/file-edit-log.js.map +1 -0
  103. package/dist/file-edit-log.test.d.ts +1 -0
  104. package/dist/file-edit-log.test.js +68 -244
  105. package/dist/file-edit-log.test.js.map +1 -0
  106. package/dist/format-parts.d.ts +137 -0
  107. package/dist/format-parts.js +300 -0
  108. package/dist/format-parts.js.map +1 -0
  109. package/dist/format-parts.test.d.ts +1 -0
  110. package/dist/format-parts.test.js +144 -0
  111. package/dist/format-parts.test.js.map +1 -0
  112. package/dist/gateway-replay.e2e.test.d.ts +1 -0
  113. package/dist/gateway-replay.e2e.test.js +95 -0
  114. package/dist/gateway-replay.e2e.test.js.map +1 -0
  115. package/dist/harness.e2e.test.d.ts +1 -0
  116. package/dist/harness.e2e.test.js +107 -0
  117. package/dist/harness.e2e.test.js.map +1 -0
  118. package/dist/hello-thread.e2e.test.d.ts +1 -0
  119. package/dist/hello-thread.e2e.test.js +194 -0
  120. package/dist/hello-thread.e2e.test.js.map +1 -0
  121. package/dist/ingress.d.ts +7 -0
  122. package/dist/ingress.js +337 -0
  123. package/dist/ingress.js.map +1 -0
  124. package/dist/interaction-context.d.ts +45 -0
  125. package/dist/interaction-context.js +77 -0
  126. package/dist/interaction-context.js.map +1 -0
  127. package/dist/interrupt.e2e.test.d.ts +1 -0
  128. package/dist/interrupt.e2e.test.js +124 -0
  129. package/dist/interrupt.e2e.test.js.map +1 -0
  130. package/dist/legacy.e2e.test.d.ts +1 -0
  131. package/dist/legacy.e2e.test.js +85 -0
  132. package/dist/legacy.e2e.test.js.map +1 -0
  133. package/dist/live-call.d.ts +51 -0
  134. package/dist/live-call.js +207 -0
  135. package/dist/live-call.js.map +1 -0
  136. package/dist/lock-routes.d.ts +812 -0
  137. package/dist/lock-routes.js +635 -0
  138. package/dist/lock-routes.js.map +1 -0
  139. package/dist/lock-server.d.ts +36 -0
  140. package/dist/lock-server.js +223 -0
  141. package/dist/lock-server.js.map +1 -0
  142. package/dist/logger.d.ts +13 -0
  143. package/dist/logger.js +112 -162
  144. package/dist/logger.js.map +1 -0
  145. package/dist/login.e2e.test.d.ts +1 -0
  146. package/dist/login.e2e.test.js +83 -0
  147. package/dist/login.e2e.test.js.map +1 -0
  148. package/dist/main.d.ts +32 -0
  149. package/dist/main.js +190 -0
  150. package/dist/main.js.map +1 -0
  151. package/dist/markdown/components.d.ts +10 -0
  152. package/dist/markdown/components.js +77 -0
  153. package/dist/markdown/components.js.map +1 -0
  154. package/dist/markdown/markdown.test.d.ts +1 -0
  155. package/dist/markdown/markdown.test.js +393 -0
  156. package/dist/markdown/markdown.test.js.map +1 -0
  157. package/dist/markdown/render-markdown.d.ts +30 -0
  158. package/dist/markdown/render-markdown.js +265 -0
  159. package/dist/markdown/render-markdown.js.map +1 -0
  160. package/dist/message-tool.e2e.test.d.ts +1 -0
  161. package/dist/message-tool.e2e.test.js +39 -0
  162. package/dist/message-tool.e2e.test.js.map +1 -0
  163. package/dist/migrations.d.ts +8 -0
  164. package/dist/migrations.js +187 -0
  165. package/dist/migrations.js.map +1 -0
  166. package/dist/onboarding-cli.e2e.test.d.ts +1 -0
  167. package/dist/onboarding-cli.e2e.test.js +178 -0
  168. package/dist/onboarding-cli.e2e.test.js.map +1 -0
  169. package/dist/onboarding.d.ts +36 -0
  170. package/dist/onboarding.e2e.test.d.ts +1 -0
  171. package/dist/onboarding.e2e.test.js +148 -0
  172. package/dist/onboarding.e2e.test.js.map +1 -0
  173. package/dist/onboarding.js +261 -0
  174. package/dist/onboarding.js.map +1 -0
  175. package/dist/opencode-server.d.ts +54 -0
  176. package/dist/opencode-server.js +413 -0
  177. package/dist/opencode-server.js.map +1 -0
  178. package/dist/opencode-server.test.d.ts +1 -0
  179. package/dist/opencode-server.test.js +21 -0
  180. package/dist/opencode-server.test.js.map +1 -0
  181. package/dist/permissions.d.ts +31 -0
  182. package/dist/permissions.e2e.test.d.ts +1 -0
  183. package/dist/permissions.e2e.test.js +166 -0
  184. package/dist/permissions.e2e.test.js.map +1 -0
  185. package/dist/permissions.js +95 -0
  186. package/dist/permissions.js.map +1 -0
  187. package/dist/plugin/anthropic/index.d.ts +13 -0
  188. package/dist/plugin/anthropic/index.js +201 -0
  189. package/dist/plugin/anthropic/index.js.map +1 -0
  190. package/dist/plugin/anthropic/index.test.d.ts +1 -0
  191. package/dist/plugin/anthropic/index.test.js +39 -0
  192. package/dist/plugin/anthropic/index.test.js.map +1 -0
  193. package/dist/plugin/index.d.ts +3 -0
  194. package/dist/plugin/index.js +106 -0
  195. package/dist/plugin/index.js.map +1 -0
  196. package/dist/plugin/session-id/index.d.ts +3 -0
  197. package/dist/plugin/session-id/index.js +18 -0
  198. package/dist/plugin/session-id/index.js.map +1 -0
  199. package/dist/plugin.e2e.test.d.ts +1 -0
  200. package/dist/plugin.e2e.test.js +87 -0
  201. package/dist/plugin.e2e.test.js.map +1 -0
  202. package/dist/preference-commands.e2e.test.d.ts +1 -0
  203. package/dist/preference-commands.e2e.test.js +555 -0
  204. package/dist/preference-commands.e2e.test.js.map +1 -0
  205. package/dist/probe-live.tmp.d.ts +1 -0
  206. package/dist/probe-live.tmp.js +82 -0
  207. package/dist/probe-live.tmp.js.map +1 -0
  208. package/dist/project.d.ts +58 -0
  209. package/dist/project.js +169 -0
  210. package/dist/project.js.map +1 -0
  211. package/dist/prompt.d.ts +112 -0
  212. package/dist/prompt.js +578 -0
  213. package/dist/prompt.js.map +1 -0
  214. package/dist/questions.d.ts +59 -0
  215. package/dist/questions.e2e.test.d.ts +1 -0
  216. package/dist/questions.e2e.test.js +290 -0
  217. package/dist/questions.e2e.test.js.map +1 -0
  218. package/dist/questions.js +231 -0
  219. package/dist/questions.js.map +1 -0
  220. package/dist/queue.d.ts +45 -0
  221. package/dist/queue.e2e.test.d.ts +1 -0
  222. package/dist/queue.e2e.test.js +220 -0
  223. package/dist/queue.e2e.test.js.map +1 -0
  224. package/dist/queue.js +132 -0
  225. package/dist/queue.js.map +1 -0
  226. package/dist/remote-send.d.ts +32 -0
  227. package/dist/remote-send.e2e.test.d.ts +1 -0
  228. package/dist/remote-send.e2e.test.js +89 -0
  229. package/dist/remote-send.e2e.test.js.map +1 -0
  230. package/dist/remote-send.js +105 -0
  231. package/dist/remote-send.js.map +1 -0
  232. package/dist/renderer.e2e.test.d.ts +1 -0
  233. package/dist/renderer.e2e.test.js +357 -0
  234. package/dist/renderer.e2e.test.js.map +1 -0
  235. package/dist/restart.e2e.test.d.ts +1 -0
  236. package/dist/restart.e2e.test.js +68 -0
  237. package/dist/restart.e2e.test.js.map +1 -0
  238. package/dist/routes.d.ts +24 -0
  239. package/dist/routes.js +42 -0
  240. package/dist/routes.js.map +1 -0
  241. package/dist/routes.test.d.ts +1 -0
  242. package/dist/routes.test.js +79 -0
  243. package/dist/routes.test.js.map +1 -0
  244. package/dist/routines.e2e.test.d.ts +1 -0
  245. package/dist/routines.e2e.test.js +188 -0
  246. package/dist/routines.e2e.test.js.map +1 -0
  247. package/dist/scheduler.d.ts +116 -0
  248. package/dist/scheduler.e2e.test.d.ts +1 -0
  249. package/dist/scheduler.e2e.test.js +163 -0
  250. package/dist/scheduler.e2e.test.js.map +1 -0
  251. package/dist/scheduler.js +602 -0
  252. package/dist/scheduler.js.map +1 -0
  253. package/dist/scheduler.test.d.ts +1 -0
  254. package/dist/scheduler.test.js +180 -0
  255. package/dist/scheduler.test.js.map +1 -0
  256. package/dist/schema-sql.d.ts +1 -0
  257. package/dist/schema-sql.js +3 -0
  258. package/dist/schema-sql.js.map +1 -0
  259. package/dist/schema.d.ts +2968 -0
  260. package/dist/schema.js +95 -252
  261. package/dist/schema.js.map +1 -0
  262. package/dist/session-commands.e2e.test.d.ts +1 -0
  263. package/dist/session-commands.e2e.test.js +285 -0
  264. package/dist/session-commands.e2e.test.js.map +1 -0
  265. package/dist/session-events.d.ts +55 -0
  266. package/dist/session-events.js +190 -0
  267. package/dist/session-events.js.map +1 -0
  268. package/dist/session-ops.e2e.test.d.ts +1 -0
  269. package/dist/session-ops.e2e.test.js +114 -0
  270. package/dist/session-ops.e2e.test.js.map +1 -0
  271. package/dist/sessions.d.ts +121 -0
  272. package/dist/sessions.js +662 -0
  273. package/dist/sessions.js.map +1 -0
  274. package/dist/shell.e2e.test.d.ts +1 -0
  275. package/dist/shell.e2e.test.js +147 -0
  276. package/dist/shell.e2e.test.js.map +1 -0
  277. package/dist/slash-commands.d.ts +62 -0
  278. package/dist/slash-commands.js +475 -0
  279. package/dist/slash-commands.js.map +1 -0
  280. package/dist/slash-commands.test.d.ts +1 -0
  281. package/dist/slash-commands.test.js +87 -0
  282. package/dist/slash-commands.test.js.map +1 -0
  283. package/dist/sleep.e2e.test.d.ts +1 -0
  284. package/dist/sleep.e2e.test.js +115 -487
  285. package/dist/sleep.e2e.test.js.map +1 -0
  286. package/dist/sleeps.d.ts +37 -0
  287. package/dist/sleeps.js +220 -0
  288. package/dist/sleeps.js.map +1 -0
  289. package/dist/store.d.ts +10 -0
  290. package/dist/store.js +8 -28
  291. package/dist/store.js.map +1 -0
  292. package/dist/system-prompt.d.ts +65 -0
  293. package/dist/system-prompt.js +875 -0
  294. package/dist/system-prompt.js.map +1 -0
  295. package/dist/tasks.e2e.test.d.ts +1 -0
  296. package/dist/tasks.e2e.test.js +173 -0
  297. package/dist/tasks.e2e.test.js.map +1 -0
  298. package/dist/test/auth-plugin/index.d.ts +3 -0
  299. package/dist/test/auth-plugin/index.js +18 -0
  300. package/dist/test/auth-plugin/index.js.map +1 -0
  301. package/dist/test/fake-mcp-server.d.ts +1 -0
  302. package/dist/test/fake-mcp-server.js +45 -0
  303. package/dist/test/fake-mcp-server.js.map +1 -0
  304. package/dist/test/harness.d.ts +246 -0
  305. package/dist/test/harness.js +704 -0
  306. package/dist/test/harness.js.map +1 -0
  307. package/dist/test/replay.d.ts +14 -0
  308. package/dist/test/replay.js +75 -0
  309. package/dist/test/replay.js.map +1 -0
  310. package/dist/thread-reducer.d.ts +172 -0
  311. package/dist/thread-reducer.fixtures.test.d.ts +1 -0
  312. package/dist/thread-reducer.fixtures.test.js +360 -0
  313. package/dist/thread-reducer.fixtures.test.js.map +1 -0
  314. package/dist/thread-reducer.js +497 -0
  315. package/dist/thread-reducer.js.map +1 -0
  316. package/dist/thread-reducer.test.d.ts +1 -0
  317. package/dist/thread-reducer.test.js +369 -0
  318. package/dist/thread-reducer.test.js.map +1 -0
  319. package/dist/tts.test.d.ts +1 -0
  320. package/dist/tts.test.js +147 -0
  321. package/dist/tts.test.js.map +1 -0
  322. package/dist/voice-agent.d.ts +33 -0
  323. package/dist/voice-agent.js +159 -0
  324. package/dist/voice-agent.js.map +1 -0
  325. package/dist/voice-attachments.e2e.test.d.ts +1 -0
  326. package/dist/voice-attachments.e2e.test.js +253 -0
  327. package/dist/voice-attachments.e2e.test.js.map +1 -0
  328. package/dist/voice-call.d.ts +59 -0
  329. package/dist/voice-call.e2e.test.d.ts +1 -0
  330. package/dist/voice-call.e2e.test.js +259 -0
  331. package/dist/voice-call.e2e.test.js.map +1 -0
  332. package/dist/voice-call.js +760 -0
  333. package/dist/voice-call.js.map +1 -0
  334. package/dist/voice-openai.e2e.test.d.ts +1 -0
  335. package/dist/voice-openai.e2e.test.js +161 -0
  336. package/dist/voice-openai.e2e.test.js.map +1 -0
  337. package/dist/voice.d.ts +116 -0
  338. package/dist/voice.js +619 -717
  339. package/dist/voice.js.map +1 -0
  340. package/dist/working-directory.e2e.test.d.ts +1 -0
  341. package/dist/working-directory.e2e.test.js +231 -0
  342. package/dist/working-directory.e2e.test.js.map +1 -0
  343. package/dist/worktrees.d.ts +54 -0
  344. package/dist/worktrees.js +247 -709
  345. package/dist/worktrees.js.map +1 -0
  346. package/dist/worktrees.test.d.ts +1 -0
  347. package/dist/worktrees.test.js +97 -952
  348. package/dist/worktrees.test.js.map +1 -0
  349. package/package.json +38 -74
  350. package/src/agent-ui.e2e.test.ts +134 -0
  351. package/src/agent-ui.ts +216 -0
  352. package/src/analytics.e2e.test.ts +138 -0
  353. package/src/analytics.test.ts +122 -182
  354. package/src/analytics.ts +206 -258
  355. package/src/autostart.ts +78 -0
  356. package/src/bot.ts +194 -0
  357. package/src/btw.e2e.test.ts +130 -0
  358. package/src/catalog-refresh.e2e.test.ts +112 -0
  359. package/src/cli/bot.ts +419 -0
  360. package/src/cli/discord.ts +116 -0
  361. package/src/cli/project.ts +147 -0
  362. package/src/cli/schedule.ts +151 -0
  363. package/src/cli/session.ts +285 -0
  364. package/src/cli/shared.ts +139 -0
  365. package/src/cli-discord.e2e.test.ts +62 -0
  366. package/src/cli-lock.e2e.test.ts +530 -0
  367. package/src/cli-read.e2e.test.ts +78 -0
  368. package/src/cli-sessions.e2e.test.ts +122 -0
  369. package/src/cli.ts +35 -418
  370. package/src/commands/login-commands.ts +360 -0
  371. package/src/commands/preference-commands.ts +586 -0
  372. package/src/commands/session-commands.ts +289 -0
  373. package/src/commands/thread-commands.ts +324 -0
  374. package/src/commands/worktree-commands.ts +288 -0
  375. package/src/commands.e2e.test.ts +290 -0
  376. package/src/credentials.ts +425 -0
  377. package/src/db.test.ts +344 -759
  378. package/src/db.ts +66 -284
  379. package/src/duration.ts +18 -0
  380. package/src/effects.ts +303 -0
  381. package/src/errors.ts +39 -228
  382. package/src/event-loop.ts +462 -0
  383. package/src/file-edit-log.test.ts +68 -272
  384. package/src/file-edit-log.ts +108 -231
  385. package/src/fixtures/v1-schema.sql +241 -0
  386. package/src/fixtures/voice.ogg +0 -0
  387. package/src/format-parts.test.ts +150 -0
  388. package/src/format-parts.ts +405 -0
  389. package/src/gateway-replay.e2e.test.ts +116 -0
  390. package/src/harness.e2e.test.ts +124 -0
  391. package/src/hello-thread.e2e.test.ts +223 -0
  392. package/src/ingress.ts +334 -0
  393. package/src/interaction-context.ts +131 -0
  394. package/src/interrupt.e2e.test.ts +151 -0
  395. package/src/legacy.e2e.test.ts +105 -0
  396. package/src/live-call.ts +249 -0
  397. package/src/lock-routes.ts +625 -0
  398. package/src/lock-server.ts +233 -0
  399. package/src/logger.ts +120 -207
  400. package/src/login.e2e.test.ts +86 -0
  401. package/src/main.ts +230 -0
  402. package/src/markdown/components.ts +102 -0
  403. package/src/markdown/markdown.test.ts +414 -0
  404. package/src/markdown/render-markdown.ts +288 -0
  405. package/src/migrations.ts +198 -0
  406. package/src/onboarding-cli.e2e.test.ts +215 -0
  407. package/src/onboarding.e2e.test.ts +171 -0
  408. package/src/onboarding.ts +297 -0
  409. package/src/opencode-server.test.ts +24 -0
  410. package/src/opencode-server.ts +461 -0
  411. package/src/permissions.e2e.test.ts +191 -0
  412. package/src/permissions.ts +121 -0
  413. package/src/plugin/anthropic/index.test.ts +39 -0
  414. package/src/plugin/anthropic/index.ts +213 -0
  415. package/src/plugin/index.ts +93 -0
  416. package/src/plugin/session-id/index.ts +19 -0
  417. package/src/plugin.e2e.test.ts +112 -0
  418. package/src/preference-commands.e2e.test.ts +597 -0
  419. package/src/project.ts +216 -0
  420. package/src/prompt.ts +664 -0
  421. package/src/questions.e2e.test.ts +328 -0
  422. package/src/questions.ts +322 -0
  423. package/src/queue.e2e.test.ts +253 -0
  424. package/src/queue.ts +158 -0
  425. package/src/remote-send.e2e.test.ts +91 -0
  426. package/src/remote-send.ts +110 -0
  427. package/src/renderer.e2e.test.ts +390 -0
  428. package/src/restart.e2e.test.ts +90 -0
  429. package/src/routes.test.ts +81 -0
  430. package/src/routes.ts +48 -0
  431. package/src/routines.e2e.test.ts +210 -0
  432. package/src/scheduler.e2e.test.ts +182 -0
  433. package/src/scheduler.test.ts +183 -0
  434. package/src/scheduler.ts +648 -0
  435. package/src/schema-sql.ts +3 -0
  436. package/src/schema.ts +95 -271
  437. package/src/session-commands.e2e.test.ts +326 -0
  438. package/src/session-events.ts +218 -0
  439. package/src/session-ops.e2e.test.ts +141 -0
  440. package/src/sessions.ts +803 -0
  441. package/src/shell.e2e.test.ts +173 -0
  442. package/src/slash-commands.test.ts +89 -0
  443. package/src/slash-commands.ts +539 -0
  444. package/src/sleep.e2e.test.ts +135 -552
  445. package/src/sleeps.ts +230 -0
  446. package/src/store.ts +19 -217
  447. package/src/system-prompt.ts +944 -0
  448. package/src/test/auth-plugin/index.ts +17 -0
  449. package/src/test/fake-mcp-server.ts +49 -0
  450. package/src/test/harness.ts +957 -0
  451. package/src/test/replay.ts +90 -0
  452. package/src/thread-reducer.fixtures.test.ts +374 -0
  453. package/src/thread-reducer.test.ts +380 -0
  454. package/src/thread-reducer.ts +671 -0
  455. package/src/tts.test.ts +150 -0
  456. package/src/voice-agent.ts +196 -0
  457. package/src/voice-attachments.e2e.test.ts +298 -0
  458. package/src/voice-call.e2e.test.ts +293 -0
  459. package/src/voice-call.ts +764 -0
  460. package/src/voice-openai.e2e.test.ts +191 -0
  461. package/src/voice.ts +668 -988
  462. package/src/working-directory.e2e.test.ts +226 -0
  463. package/src/worktrees.test.ts +89 -1115
  464. package/src/worktrees.ts +195 -957
  465. package/bin.js +0 -2
  466. package/dist/agent-model.e2e.test.js +0 -1223
  467. package/dist/ai-tool-to-genai.js +0 -233
  468. package/dist/ai-tool-to-genai.test.js +0 -267
  469. package/dist/ai-tool.js +0 -6
  470. package/dist/anthropic-account-identity.js +0 -70
  471. package/dist/anthropic-account-identity.test.js +0 -38
  472. package/dist/anthropic-auth-plugin.js +0 -958
  473. package/dist/anthropic-auth-plugin.test.js +0 -115
  474. package/dist/anthropic-auth-state.js +0 -186
  475. package/dist/anthropic-auth-state.test.js +0 -203
  476. package/dist/bash-tool-schema-plugin.js +0 -50
  477. package/dist/bash-tool-schema-plugin.test.js +0 -68
  478. package/dist/bin.js +0 -151
  479. package/dist/bot-lifecycle.test.js +0 -206
  480. package/dist/btw-prefix-detection.js +0 -24
  481. package/dist/btw-prefix-detection.test.js +0 -130
  482. package/dist/cache-drift-plugin.js +0 -183
  483. package/dist/cache-rewrite.js +0 -39
  484. package/dist/cache-rewrite.test.js +0 -41
  485. package/dist/channel-management.js +0 -347
  486. package/dist/cli-commands/bot.js +0 -254
  487. package/dist/cli-commands/maintenance.js +0 -171
  488. package/dist/cli-commands/misc.js +0 -153
  489. package/dist/cli-commands/project.js +0 -510
  490. package/dist/cli-commands/send.js +0 -659
  491. package/dist/cli-commands/session.js +0 -889
  492. package/dist/cli-commands/task.js +0 -277
  493. package/dist/cli-commands/thread.js +0 -63
  494. package/dist/cli-commands/user.js +0 -145
  495. package/dist/cli-parsing.test.js +0 -226
  496. package/dist/cli-runner.js +0 -1591
  497. package/dist/cli-runner.test.js +0 -119
  498. package/dist/cli-send-thread.e2e.test.js +0 -470
  499. package/dist/cloudflare-transcription.js +0 -56
  500. package/dist/commands/abort.js +0 -84
  501. package/dist/commands/action-buttons.js +0 -248
  502. package/dist/commands/add-project.js +0 -111
  503. package/dist/commands/agent.js +0 -658
  504. package/dist/commands/ask-question.js +0 -371
  505. package/dist/commands/ask-question.test.js +0 -150
  506. package/dist/commands/btw.js +0 -275
  507. package/dist/commands/compact.js +0 -117
  508. package/dist/commands/context-usage.js +0 -194
  509. package/dist/commands/context-usage.test.js +0 -49
  510. package/dist/commands/create-new-project.js +0 -138
  511. package/dist/commands/diff.js +0 -63
  512. package/dist/commands/file-upload.js +0 -280
  513. package/dist/commands/fork-subagent.js +0 -175
  514. package/dist/commands/fork.js +0 -291
  515. package/dist/commands/gemini-apikey.js +0 -123
  516. package/dist/commands/last-sessions.js +0 -129
  517. package/dist/commands/login.js +0 -893
  518. package/dist/commands/mcp.js +0 -239
  519. package/dist/commands/memory-snapshot.js +0 -24
  520. package/dist/commands/mention-mode.js +0 -42
  521. package/dist/commands/merge-worktree.js +0 -205
  522. package/dist/commands/model-variant.js +0 -390
  523. package/dist/commands/model.js +0 -1012
  524. package/dist/commands/multioauth.js +0 -425
  525. package/dist/commands/new-worktree.js +0 -625
  526. package/dist/commands/paginated-select.js +0 -57
  527. package/dist/commands/permissions.js +0 -327
  528. package/dist/commands/queue.js +0 -347
  529. package/dist/commands/queue.test.js +0 -15
  530. package/dist/commands/remove-project.js +0 -111
  531. package/dist/commands/restart-opencode-server.js +0 -133
  532. package/dist/commands/resume.js +0 -148
  533. package/dist/commands/run-command.js +0 -79
  534. package/dist/commands/screenshare.js +0 -307
  535. package/dist/commands/screenshare.test.js +0 -20
  536. package/dist/commands/session-id.js +0 -78
  537. package/dist/commands/session.js +0 -248
  538. package/dist/commands/share.js +0 -80
  539. package/dist/commands/tasks.js +0 -296
  540. package/dist/commands/types.js +0 -2
  541. package/dist/commands/undo-redo.js +0 -313
  542. package/dist/commands/unset-model.js +0 -116
  543. package/dist/commands/upgrade.js +0 -41
  544. package/dist/commands/user-command.js +0 -196
  545. package/dist/commands/verbosity.js +0 -124
  546. package/dist/commands/vscode.js +0 -295
  547. package/dist/commands/worktrees.js +0 -548
  548. package/dist/condense-memory.js +0 -33
  549. package/dist/config.js +0 -126
  550. package/dist/context-awareness-plugin.js +0 -357
  551. package/dist/context-awareness-plugin.test.js +0 -126
  552. package/dist/cpu-profiler.js +0 -211
  553. package/dist/cpu-profiler.test.js +0 -160
  554. package/dist/critique-utils.js +0 -95
  555. package/dist/database.js +0 -1074
  556. package/dist/debounce-timeout.js +0 -28
  557. package/dist/debounced-process-flush.js +0 -77
  558. package/dist/default-channel-provisioning.test.js +0 -149
  559. package/dist/discord-bot.js +0 -1432
  560. package/dist/discord-command-registration.js +0 -519
  561. package/dist/discord-command-registration.test.js +0 -17
  562. package/dist/discord-urls.js +0 -81
  563. package/dist/discord-utils.js +0 -789
  564. package/dist/discord-utils.test.js +0 -400
  565. package/dist/escape-backticks.test.js +0 -429
  566. package/dist/event-stream-real-capture.e2e.test.js +0 -533
  567. package/dist/eventsource-parser.test.js +0 -327
  568. package/dist/exec-async.js +0 -38
  569. package/dist/external-directory-permissions.e2e.test.js +0 -86
  570. package/dist/external-directory-project-deny.e2e.test.js +0 -70
  571. package/dist/external-opencode-sync.js +0 -620
  572. package/dist/external-opencode-sync.test.js +0 -206
  573. package/dist/extract-sdk-error-message.test.js +0 -13
  574. package/dist/format-tables.js +0 -728
  575. package/dist/format-tables.test.js +0 -915
  576. package/dist/forum-sync/config.js +0 -79
  577. package/dist/forum-sync/discord-operations.js +0 -157
  578. package/dist/forum-sync/index.js +0 -5
  579. package/dist/forum-sync/markdown.js +0 -110
  580. package/dist/forum-sync/sync-to-discord.js +0 -417
  581. package/dist/forum-sync/sync-to-files.js +0 -190
  582. package/dist/forum-sync/types.js +0 -53
  583. package/dist/forum-sync/watchers.js +0 -322
  584. package/dist/gateway-proxy-reconnect.e2e.test.js +0 -414
  585. package/dist/gateway-proxy.e2e.test.js +0 -488
  586. package/dist/genai-worker-wrapper.js +0 -111
  587. package/dist/genai-worker.js +0 -309
  588. package/dist/genai.js +0 -232
  589. package/dist/git-worktree-core.js +0 -461
  590. package/dist/guild-categories.test.js +0 -225
  591. package/dist/heap-monitor.js +0 -122
  592. package/dist/hrana-server.js +0 -322
  593. package/dist/hrana-server.test.js +0 -99
  594. package/dist/html-actions.js +0 -123
  595. package/dist/html-actions.test.js +0 -70
  596. package/dist/html-components.js +0 -115
  597. package/dist/html-components.test.js +0 -34
  598. package/dist/image-optimizer-plugin.js +0 -153
  599. package/dist/image-utils.js +0 -112
  600. package/dist/interaction-handler.js +0 -578
  601. package/dist/ipc-polling.js +0 -245
  602. package/dist/ipc-tools-plugin.js +0 -251
  603. package/dist/kimaki-digital-twin.e2e.test.js +0 -161
  604. package/dist/kimaki-opencode-plugin-loading.e2e.test.js +0 -158
  605. package/dist/kimaki-opencode-plugin.js +0 -33
  606. package/dist/kimaki-opencode-plugin.test.js +0 -126
  607. package/dist/kimaki-workspace-adaptor.js +0 -118
  608. package/dist/limit-heading-depth.js +0 -25
  609. package/dist/limit-heading-depth.test.js +0 -105
  610. package/dist/list-channel-threads.js +0 -163
  611. package/dist/list-channel-threads.test.js +0 -80
  612. package/dist/markdown.js +0 -455
  613. package/dist/markdown.test.js +0 -411
  614. package/dist/memory-overview-plugin.js +0 -123
  615. package/dist/message-formatting.js +0 -788
  616. package/dist/message-formatting.test.js +0 -1132
  617. package/dist/message-preprocessing.js +0 -419
  618. package/dist/oauth-rotation-shared.js +0 -253
  619. package/dist/onboarding-tutorial.js +0 -163
  620. package/dist/onboarding-welcome.js +0 -37
  621. package/dist/openai-auth-plugin.js +0 -125
  622. package/dist/openai-auth-state.js +0 -237
  623. package/dist/openai-realtime.js +0 -224
  624. package/dist/opencode-command-detection.js +0 -65
  625. package/dist/opencode-command-detection.test.js +0 -240
  626. package/dist/opencode-command.js +0 -181
  627. package/dist/opencode-command.test.js +0 -218
  628. package/dist/opencode-interrupt-plugin.js +0 -253
  629. package/dist/opencode-interrupt-plugin.test.js +0 -293
  630. package/dist/opencode.js +0 -1217
  631. package/dist/parse-permission-rules.test.js +0 -117
  632. package/dist/patch-text-parser.js +0 -97
  633. package/dist/plugin-logger.js +0 -105
  634. package/dist/plugin-opencode-client.js +0 -54
  635. package/dist/privacy-sanitizer.js +0 -105
  636. package/dist/project-add.test.js +0 -62
  637. package/dist/question-abort-clears-dropdown.e2e.test.js +0 -89
  638. package/dist/question-abort-resume.e2e.test.js +0 -100
  639. package/dist/question-abort-retry-text-before-dropdown.e2e.test.js +0 -150
  640. package/dist/question-text-before-dropdown.e2e.test.js +0 -52
  641. package/dist/queue-advanced-abort.e2e.test.js +0 -348
  642. package/dist/queue-advanced-action-buttons.e2e.test.js +0 -209
  643. package/dist/queue-advanced-e2e-setup.js +0 -1043
  644. package/dist/queue-advanced-footer.e2e.test.js +0 -286
  645. package/dist/queue-advanced-model-switch.e2e.test.js +0 -297
  646. package/dist/queue-advanced-permissions-typing.e2e.test.js +0 -189
  647. package/dist/queue-advanced-question.e2e.test.js +0 -266
  648. package/dist/queue-advanced-typing-interrupt.e2e.test.js +0 -113
  649. package/dist/queue-advanced-typing.e2e.test.js +0 -151
  650. package/dist/queue-delete-message.e2e.test.js +0 -216
  651. package/dist/queue-drain-after-interactive-ui.e2e.test.js +0 -120
  652. package/dist/queue-interrupt-drain.e2e.test.js +0 -256
  653. package/dist/queue-question-select-drain.e2e.test.js +0 -162
  654. package/dist/runtime-idle-sweeper.js +0 -52
  655. package/dist/runtime-lifecycle.e2e.test.js +0 -570
  656. package/dist/sentry.js +0 -23
  657. package/dist/session-handler/agent-utils.js +0 -65
  658. package/dist/session-handler/event-stream-state.js +0 -1225
  659. package/dist/session-handler/event-stream-state.test.js +0 -3160
  660. package/dist/session-handler/global-event-listener.js +0 -212
  661. package/dist/session-handler/model-utils.js +0 -311
  662. package/dist/session-handler/model-utils.test.js +0 -445
  663. package/dist/session-handler/opencode-session-event-log.js +0 -121
  664. package/dist/session-handler/thread-ingress.test.js +0 -41
  665. package/dist/session-handler/thread-runtime-state.js +0 -209
  666. package/dist/session-handler/thread-session-runtime-summary.test.js +0 -121
  667. package/dist/session-handler/thread-session-runtime.js +0 -4320
  668. package/dist/session-handler.js +0 -9
  669. package/dist/session-search.js +0 -219
  670. package/dist/session-search.test.js +0 -287
  671. package/dist/session-sleep.test.js +0 -224
  672. package/dist/session-title-rename.test.js +0 -128
  673. package/dist/skill-filter.js +0 -43
  674. package/dist/skill-filter.test.js +0 -86
  675. package/dist/startup-service.js +0 -153
  676. package/dist/startup-time.e2e.test.js +0 -297
  677. package/dist/system-message.js +0 -806
  678. package/dist/system-message.test.js +0 -917
  679. package/dist/task-id-plugin.js +0 -16
  680. package/dist/task-runner.js +0 -554
  681. package/dist/task-schedule.js +0 -298
  682. package/dist/task-schedule.test.js +0 -366
  683. package/dist/test-utils.js +0 -385
  684. package/dist/thinking-utils.js +0 -45
  685. package/dist/thinking-utils.test.js +0 -35
  686. package/dist/thread-message-queue.e2e.test.js +0 -1227
  687. package/dist/tools.js +0 -357
  688. package/dist/undo-redo.e2e.test.js +0 -171
  689. package/dist/unnest-code-blocks.js +0 -146
  690. package/dist/unnest-code-blocks.test.js +0 -673
  691. package/dist/upgrade.js +0 -114
  692. package/dist/utils.js +0 -148
  693. package/dist/voice-attachment.js +0 -56
  694. package/dist/voice-handler.js +0 -727
  695. package/dist/voice-message.e2e.test.js +0 -1254
  696. package/dist/voice-routing-input.e2e.test.js +0 -195
  697. package/dist/voice-routing-question.e2e.test.js +0 -182
  698. package/dist/voice.test.js +0 -500
  699. package/dist/wait-session.js +0 -193
  700. package/dist/websockify.js +0 -69
  701. package/dist/worker-types.js +0 -4
  702. package/dist/worktree-clone-isolation.e2e.test.js +0 -188
  703. package/dist/worktree-lifecycle.e2e.test.js +0 -735
  704. package/dist/worktree-utils.js +0 -3
  705. package/dist/xai-auth-plugin.js +0 -238
  706. package/dist/xai-auth-state.js +0 -234
  707. package/dist/xai-auth-state.test.js +0 -183
  708. package/dist/xml.js +0 -92
  709. package/dist/xml.test.js +0 -32
  710. package/skills/bump-holocron-consumers/SKILL.md +0 -137
  711. package/skills/critique/SKILL.md +0 -116
  712. package/skills/egaki/SKILL.md +0 -86
  713. package/skills/errore/SKILL.md +0 -501
  714. package/skills/goke/SKILL.md +0 -695
  715. package/skills/holocron/SKILL.md +0 -942
  716. package/skills/lintcn/SKILL.md +0 -873
  717. package/skills/new-skill/SKILL.md +0 -339
  718. package/skills/npm-package/SKILL.md +0 -692
  719. package/skills/opensrc/SKILL.md +0 -102
  720. package/skills/playwriter/SKILL.md +0 -35
  721. package/skills/profano/SKILL.md +0 -33
  722. package/skills/readme.md +0 -20
  723. package/skills/sigillo/SKILL.md +0 -370
  724. package/skills/spiceflow/SKILL.md +0 -80
  725. package/skills/strada/SKILL.md +0 -104
  726. package/skills/termcast/SKILL.md +0 -133
  727. package/skills/tuistory/SKILL.md +0 -237
  728. package/skills/usecomputer/SKILL.md +0 -264
  729. package/skills/zele/SKILL.md +0 -81
  730. package/src/agent-model.e2e.test.ts +0 -1557
  731. package/src/ai-tool-to-genai.test.ts +0 -296
  732. package/src/ai-tool-to-genai.ts +0 -283
  733. package/src/ai-tool.ts +0 -39
  734. package/src/anthropic-account-identity.test.ts +0 -52
  735. package/src/anthropic-account-identity.ts +0 -96
  736. package/src/anthropic-auth-plugin.test.ts +0 -135
  737. package/src/anthropic-auth-plugin.ts +0 -1180
  738. package/src/anthropic-auth-state.test.ts +0 -259
  739. package/src/anthropic-auth-state.ts +0 -272
  740. package/src/bash-tool-schema-plugin.test.ts +0 -84
  741. package/src/bash-tool-schema-plugin.ts +0 -77
  742. package/src/bin.ts +0 -173
  743. package/src/bot-lifecycle.test.ts +0 -252
  744. package/src/btw-prefix-detection.test.ts +0 -142
  745. package/src/btw-prefix-detection.ts +0 -30
  746. package/src/cache-drift-plugin.ts +0 -249
  747. package/src/cache-rewrite.test.ts +0 -49
  748. package/src/cache-rewrite.ts +0 -96
  749. package/src/channel-management.ts +0 -494
  750. package/src/cli-commands/bot.ts +0 -374
  751. package/src/cli-commands/maintenance.ts +0 -237
  752. package/src/cli-commands/misc.ts +0 -208
  753. package/src/cli-commands/project.ts +0 -680
  754. package/src/cli-commands/send.ts +0 -885
  755. package/src/cli-commands/session.ts +0 -1181
  756. package/src/cli-commands/task.ts +0 -358
  757. package/src/cli-commands/thread.ts +0 -86
  758. package/src/cli-commands/user.ts +0 -195
  759. package/src/cli-parsing.test.ts +0 -305
  760. package/src/cli-runner.test.ts +0 -166
  761. package/src/cli-runner.ts +0 -2157
  762. package/src/cli-send-thread.e2e.test.ts +0 -609
  763. package/src/cloudflare-transcription.ts +0 -76
  764. package/src/commands/abort.ts +0 -113
  765. package/src/commands/action-buttons.ts +0 -371
  766. package/src/commands/add-project.ts +0 -146
  767. package/src/commands/agent.ts +0 -911
  768. package/src/commands/ask-question.test.ts +0 -177
  769. package/src/commands/ask-question.ts +0 -532
  770. package/src/commands/btw.ts +0 -356
  771. package/src/commands/compact.ts +0 -154
  772. package/src/commands/context-usage.test.ts +0 -57
  773. package/src/commands/context-usage.ts +0 -267
  774. package/src/commands/create-new-project.ts +0 -203
  775. package/src/commands/diff.ts +0 -91
  776. package/src/commands/file-upload.ts +0 -398
  777. package/src/commands/fork-subagent.ts +0 -262
  778. package/src/commands/fork.ts +0 -421
  779. package/src/commands/gemini-apikey.ts +0 -205
  780. package/src/commands/last-sessions.ts +0 -176
  781. package/src/commands/login.ts +0 -1182
  782. package/src/commands/mcp.ts +0 -307
  783. package/src/commands/memory-snapshot.ts +0 -30
  784. package/src/commands/mention-mode.ts +0 -66
  785. package/src/commands/merge-worktree.ts +0 -282
  786. package/src/commands/model-variant.ts +0 -522
  787. package/src/commands/model.ts +0 -1377
  788. package/src/commands/multioauth.ts +0 -508
  789. package/src/commands/new-worktree.ts +0 -835
  790. package/src/commands/paginated-select.ts +0 -81
  791. package/src/commands/permissions.ts +0 -458
  792. package/src/commands/queue.test.ts +0 -19
  793. package/src/commands/queue.ts +0 -471
  794. package/src/commands/remove-project.ts +0 -152
  795. package/src/commands/restart-opencode-server.ts +0 -173
  796. package/src/commands/resume.ts +0 -229
  797. package/src/commands/run-command.ts +0 -123
  798. package/src/commands/screenshare.test.ts +0 -30
  799. package/src/commands/screenshare.ts +0 -388
  800. package/src/commands/session-id.ts +0 -109
  801. package/src/commands/session.ts +0 -319
  802. package/src/commands/share.ts +0 -106
  803. package/src/commands/tasks.ts +0 -399
  804. package/src/commands/types.ts +0 -25
  805. package/src/commands/undo-redo.ts +0 -394
  806. package/src/commands/unset-model.ts +0 -152
  807. package/src/commands/upgrade.ts +0 -51
  808. package/src/commands/user-command.ts +0 -260
  809. package/src/commands/verbosity.ts +0 -172
  810. package/src/commands/vscode.ts +0 -378
  811. package/src/commands/worktrees.ts +0 -762
  812. package/src/condense-memory.ts +0 -36
  813. package/src/config.ts +0 -147
  814. package/src/context-awareness-plugin.test.ts +0 -144
  815. package/src/context-awareness-plugin.ts +0 -508
  816. package/src/cpu-profiler.test.ts +0 -183
  817. package/src/cpu-profiler.ts +0 -293
  818. package/src/critique-utils.ts +0 -139
  819. package/src/database.ts +0 -1484
  820. package/src/debounce-timeout.ts +0 -43
  821. package/src/debounced-process-flush.ts +0 -104
  822. package/src/default-channel-provisioning.test.ts +0 -156
  823. package/src/discord-bot.ts +0 -1852
  824. package/src/discord-command-registration.test.ts +0 -20
  825. package/src/discord-command-registration.ts +0 -704
  826. package/src/discord-urls.ts +0 -88
  827. package/src/discord-utils.test.ts +0 -470
  828. package/src/discord-utils.ts +0 -1079
  829. package/src/escape-backticks.test.ts +0 -469
  830. package/src/event-stream-real-capture.e2e.test.ts +0 -692
  831. package/src/eventsource-parser.test.ts +0 -351
  832. package/src/exec-async.ts +0 -44
  833. package/src/external-directory-permissions.e2e.test.ts +0 -103
  834. package/src/external-directory-project-deny.e2e.test.ts +0 -84
  835. package/src/external-opencode-sync.test.ts +0 -248
  836. package/src/external-opencode-sync.ts +0 -867
  837. package/src/extract-sdk-error-message.test.ts +0 -18
  838. package/src/format-tables.test.ts +0 -988
  839. package/src/format-tables.ts +0 -1031
  840. package/src/forum-sync/config.ts +0 -92
  841. package/src/forum-sync/discord-operations.ts +0 -245
  842. package/src/forum-sync/index.ts +0 -9
  843. package/src/forum-sync/markdown.ts +0 -172
  844. package/src/forum-sync/sync-to-discord.ts +0 -595
  845. package/src/forum-sync/sync-to-files.ts +0 -294
  846. package/src/forum-sync/types.ts +0 -175
  847. package/src/forum-sync/watchers.ts +0 -474
  848. package/src/gateway-proxy-reconnect.e2e.test.ts +0 -553
  849. package/src/gateway-proxy.e2e.test.ts +0 -648
  850. package/src/genai-worker-wrapper.ts +0 -164
  851. package/src/genai-worker.ts +0 -385
  852. package/src/genai.ts +0 -318
  853. package/src/git-worktree-core.ts +0 -616
  854. package/src/guild-categories.test.ts +0 -260
  855. package/src/heap-monitor.ts +0 -152
  856. package/src/hrana-server.test.ts +0 -130
  857. package/src/hrana-server.ts +0 -399
  858. package/src/html-actions.test.ts +0 -87
  859. package/src/html-actions.ts +0 -174
  860. package/src/html-components.test.ts +0 -38
  861. package/src/html-components.ts +0 -177
  862. package/src/image-optimizer-plugin.ts +0 -194
  863. package/src/image-utils.ts +0 -150
  864. package/src/interaction-handler.ts +0 -775
  865. package/src/ipc-polling.ts +0 -325
  866. package/src/ipc-tools-plugin.ts +0 -306
  867. package/src/kimaki-digital-twin.e2e.test.ts +0 -199
  868. package/src/kimaki-opencode-plugin-loading.e2e.test.ts +0 -208
  869. package/src/kimaki-opencode-plugin.test.ts +0 -142
  870. package/src/kimaki-opencode-plugin.ts +0 -34
  871. package/src/kimaki-workspace-adaptor.ts +0 -144
  872. package/src/limit-heading-depth.test.ts +0 -116
  873. package/src/limit-heading-depth.ts +0 -26
  874. package/src/list-channel-threads.test.ts +0 -90
  875. package/src/list-channel-threads.ts +0 -252
  876. package/src/markdown.test.ts +0 -498
  877. package/src/markdown.ts +0 -577
  878. package/src/memory-overview-plugin.ts +0 -159
  879. package/src/message-formatting.test.ts +0 -1401
  880. package/src/message-formatting.ts +0 -999
  881. package/src/message-preprocessing.ts +0 -557
  882. package/src/oauth-rotation-shared.ts +0 -332
  883. package/src/onboarding-tutorial.ts +0 -167
  884. package/src/onboarding-welcome.ts +0 -49
  885. package/src/openai-auth-plugin.ts +0 -158
  886. package/src/openai-auth-state.ts +0 -297
  887. package/src/openai-realtime.ts +0 -358
  888. package/src/opencode-command-detection.test.ts +0 -307
  889. package/src/opencode-command-detection.ts +0 -76
  890. package/src/opencode-command.test.ts +0 -290
  891. package/src/opencode-command.ts +0 -251
  892. package/src/opencode-interrupt-plugin.test.ts +0 -419
  893. package/src/opencode-interrupt-plugin.ts +0 -306
  894. package/src/opencode.ts +0 -1590
  895. package/src/parse-permission-rules.test.ts +0 -127
  896. package/src/patch-text-parser.ts +0 -107
  897. package/src/plugin-logger.ts +0 -139
  898. package/src/plugin-opencode-client.ts +0 -71
  899. package/src/privacy-sanitizer.ts +0 -142
  900. package/src/project-add.test.ts +0 -80
  901. package/src/question-abort-clears-dropdown.e2e.test.ts +0 -109
  902. package/src/question-abort-resume.e2e.test.ts +0 -121
  903. package/src/question-abort-retry-text-before-dropdown.e2e.test.ts +0 -172
  904. package/src/question-text-before-dropdown.e2e.test.ts +0 -67
  905. package/src/queue-advanced-abort.e2e.test.ts +0 -449
  906. package/src/queue-advanced-action-buttons.e2e.test.ts +0 -271
  907. package/src/queue-advanced-e2e-setup.ts +0 -1164
  908. package/src/queue-advanced-footer.e2e.test.ts +0 -357
  909. package/src/queue-advanced-model-switch.e2e.test.ts +0 -382
  910. package/src/queue-advanced-permissions-typing.e2e.test.ts +0 -256
  911. package/src/queue-advanced-question.e2e.test.ts +0 -322
  912. package/src/queue-advanced-typing-interrupt.e2e.test.ts +0 -147
  913. package/src/queue-advanced-typing.e2e.test.ts +0 -199
  914. package/src/queue-delete-message.e2e.test.ts +0 -262
  915. package/src/queue-drain-after-interactive-ui.e2e.test.ts +0 -152
  916. package/src/queue-interrupt-drain.e2e.test.ts +0 -299
  917. package/src/queue-question-select-drain.e2e.test.ts +0 -209
  918. package/src/runtime-idle-sweeper.ts +0 -76
  919. package/src/runtime-lifecycle.e2e.test.ts +0 -714
  920. package/src/schema.sql +0 -251
  921. package/src/sentry.ts +0 -26
  922. package/src/session-handler/agent-utils.ts +0 -104
  923. package/src/session-handler/event-stream-fixtures/real-session-action-buttons.jsonl +0 -45
  924. package/src/session-handler/event-stream-fixtures/real-session-footer-suppressed-on-pre-idle-interrupt.jsonl +0 -40
  925. package/src/session-handler/event-stream-fixtures/real-session-permission-external-file.jsonl +0 -23
  926. package/src/session-handler/event-stream-fixtures/real-session-task-normal.jsonl +0 -22
  927. package/src/session-handler/event-stream-fixtures/real-session-task-three-parallel-sleeps.jsonl +0 -277
  928. package/src/session-handler/event-stream-fixtures/real-session-task-user-interruption.jsonl +0 -46
  929. package/src/session-handler/event-stream-fixtures/session-abort-after-idle-race.jsonl +0 -21
  930. package/src/session-handler/event-stream-fixtures/session-concurrent-messages-serialized.jsonl +0 -56
  931. package/src/session-handler/event-stream-fixtures/session-explicit-abort.jsonl +0 -44
  932. package/src/session-handler/event-stream-fixtures/session-normal-completion.jsonl +0 -29
  933. package/src/session-handler/event-stream-fixtures/session-tool-call-noisy-stream.jsonl +0 -29
  934. package/src/session-handler/event-stream-fixtures/session-two-completions-same-session.jsonl +0 -50
  935. package/src/session-handler/event-stream-fixtures/session-user-interruption.jsonl +0 -59
  936. package/src/session-handler/event-stream-fixtures/session-voice-queued-followup.jsonl +0 -52
  937. package/src/session-handler/event-stream-state.test.ts +0 -3431
  938. package/src/session-handler/event-stream-state.ts +0 -1792
  939. package/src/session-handler/global-event-listener.ts +0 -258
  940. package/src/session-handler/model-utils.test.ts +0 -537
  941. package/src/session-handler/model-utils.ts +0 -489
  942. package/src/session-handler/opencode-session-event-log.ts +0 -159
  943. package/src/session-handler/thread-ingress.test.ts +0 -54
  944. package/src/session-handler/thread-runtime-state.ts +0 -358
  945. package/src/session-handler/thread-session-runtime-summary.test.ts +0 -169
  946. package/src/session-handler/thread-session-runtime.ts +0 -5696
  947. package/src/session-handler.ts +0 -15
  948. package/src/session-search.test.ts +0 -331
  949. package/src/session-search.ts +0 -382
  950. package/src/session-sleep.test.ts +0 -294
  951. package/src/session-title-rename.test.ts +0 -186
  952. package/src/skill-filter.test.ts +0 -110
  953. package/src/skill-filter.ts +0 -63
  954. package/src/startup-service.ts +0 -200
  955. package/src/startup-time.e2e.test.ts +0 -377
  956. package/src/system-message.test.ts +0 -1013
  957. package/src/system-message.ts +0 -1043
  958. package/src/task-id-plugin.ts +0 -17
  959. package/src/task-runner.ts +0 -768
  960. package/src/task-schedule.test.ts +0 -424
  961. package/src/task-schedule.ts +0 -470
  962. package/src/test-utils.ts +0 -549
  963. package/src/thinking-utils.test.ts +0 -46
  964. package/src/thinking-utils.ts +0 -82
  965. package/src/thread-message-queue.e2e.test.ts +0 -1468
  966. package/src/tools.ts +0 -430
  967. package/src/undici.d.ts +0 -12
  968. package/src/undo-redo.e2e.test.ts +0 -219
  969. package/src/unnest-code-blocks.test.ts +0 -713
  970. package/src/unnest-code-blocks.ts +0 -185
  971. package/src/upgrade.ts +0 -127
  972. package/src/utils.ts +0 -216
  973. package/src/voice-attachment.ts +0 -79
  974. package/src/voice-handler.ts +0 -1000
  975. package/src/voice-message.e2e.test.ts +0 -1513
  976. package/src/voice-routing-input.e2e.test.ts +0 -203
  977. package/src/voice-routing-question.e2e.test.ts +0 -188
  978. package/src/voice.test.ts +0 -565
  979. package/src/wait-session.ts +0 -291
  980. package/src/websockify.ts +0 -101
  981. package/src/worker-types.ts +0 -64
  982. package/src/worktree-clone-isolation.e2e.test.ts +0 -213
  983. package/src/worktree-lifecycle.e2e.test.ts +0 -900
  984. package/src/worktree-utils.ts +0 -4
  985. package/src/xai-auth-plugin.ts +0 -303
  986. package/src/xai-auth-state.test.ts +0 -224
  987. package/src/xai-auth-state.ts +0 -294
  988. package/src/xml.test.ts +0 -38
  989. package/src/xml.ts +0 -121
@@ -0,0 +1,944 @@
1
+ // Text Kimaki adds to the model context: one durable instruction entry per
2
+ // session (spec 5.4, section 26 #3) and a short per-turn <discord-user> block
3
+ // the plugin adds to every Kimaki prompt from its metadata (turnContext()).
4
+
5
+ import dedent from 'string-dedent'
6
+ import { z } from 'zod'
7
+
8
+ export const INSTRUCTION_KEY = 'kimaki'
9
+
10
+ export type InstructionAgent = { name: string; description: string }
11
+
12
+ // The routine that started a session (scheduler.ts). Set once at
13
+ // session.create, so the instruction entry stays stable across turns.
14
+ export type ScheduledRun = { id: number; cronExpr: string | null; timezone: string | null }
15
+
16
+ const PARENT_SESSION_LINE = 'Your parent OpenCode session ID is: '
17
+
18
+ // Every system-level instruction of Kimaki is built in this file. Sections
19
+ // are joined in order; each is one dedent block.
20
+ export function baseInstructions({
21
+ sessionId,
22
+ threadId,
23
+ channelId,
24
+ guildId,
25
+ userId,
26
+ dataDir,
27
+ channelTopic,
28
+ agents,
29
+ parentSessionId,
30
+ scheduledTask = null,
31
+ }: {
32
+ sessionId: string
33
+ threadId: string
34
+ channelId: string
35
+ guildId: string
36
+ // The Discord user that starts the session; default for `--user`.
37
+ userId: string
38
+ dataDir: string
39
+ channelTopic: string | null
40
+ agents: readonly InstructionAgent[]
41
+ // Only from an explicit `kimaki send --parent-session`.
42
+ parentSessionId: string | null
43
+ scheduledTask?: ScheduledRun | null
44
+ }): string {
45
+ const userArg = ` --user '${userId}'`
46
+ const parentArg = ` --parent-session ${sessionId}`
47
+ const topic = channelTopic?.trim()
48
+ const agentList = agents.map((agent) => `- \`${agent.name}\`${agent.description ? `: ${agent.description}` : ''}`).join('\n')
49
+ const sections = [
50
+ dedent`
51
+ The user is reading your messages from inside Discord, via kimaki.dev.
52
+
53
+ ## Discord output
54
+
55
+ Be concise. Do not narrate between tool calls. Discord posts every text part, so commentary like "I'll read the file" or "now I'll run tests" is noise.
56
+ Do not restart the bot unless the user explicitly asks you to.
57
+ Do not output text until you are ready to give the user the final answer for this turn. Tool calls can run with no preceding text.
58
+ Exceptions: when a command or tool needs user-visible text first (\`kimaki buttons\`, \`kimaki upload-request\`, \`kimaki sleep\`), write that required text, then call it.
59
+
60
+ ## shell tool
61
+
62
+ When calling the shell tool, always include these extra fields alongside \`command\`:
63
+
64
+ \`\`\`ts
65
+ interface ShellToolInput {
66
+ command: string
67
+ /** Short 5-10 word summary of what this command does */
68
+ description: string
69
+ /** true if the user should see this command in Discord. false hides it */
70
+ hasSideEffect: boolean
71
+ workdir?: string
72
+ timeout?: number
73
+ }
74
+ \`\`\`
75
+
76
+ \`description\` is shown in Discord when the shell command is longer than 50 characters.
77
+ \`hasSideEffect\` only decides if Discord shows the shell call. Set it to \`true\` for every command the user should be aware of, for example commands that change state or that the user asked you to run (the user says "run sleep 100", so \`sleep 100\` gets \`true\`). Set \`false\` only for routine commands the user does not need to see.
78
+ The shell environment provides the \`kimaki\` command and OPENCODE_SESSION_ID. Do not pass stale IDs copied from another session.
79
+ `,
80
+ dedent`
81
+ Discord channel ID: ${channelId}
82
+ Discord thread ID: ${threadId}
83
+ Discord guild ID: ${guildId}
84
+ ${parentSessionId ? `${PARENT_SESSION_LINE}${parentSessionId}\nYou can send a message back to the parent session with:\nkimaki send --session ${parentSessionId} --prompt 'your update here' --agent <current_agent>\nDo NOT message the parent session unless the user explicitly asks you to.` : ''}
85
+
86
+ Per-turn Discord metadata like the current user and the Discord thread title is delivered in a \`<discord-user ... />\` line at the end of each user message.
87
+
88
+ ## commit messages
89
+
90
+ When you commit, end the commit message with the Discord link of the thread that made the change, so anyone can open the conversation (and \`kimaki session read <link>\` works on the machine that ran it):
91
+
92
+ \`\`\`
93
+ Discord: https://discord.com/channels/${guildId}/${threadId}
94
+ \`\`\`
95
+
96
+ Links have the form \`https://discord.com/channels/<guild_id>/<thread_id>\`. For changes made by another session, use that session's link (see "who edited a file").
97
+ `,
98
+ dedent`
99
+ ## permissions
100
+
101
+ Only users with these Discord permissions can send messages to the bot:
102
+ - Server Owner
103
+ - Administrator permission
104
+ - Manage Server permission
105
+ - "Kimaki" role (case-insensitive)
106
+
107
+ Other Discord bots are ignored by default. To allow another bot to trigger sessions (for multi-agent orchestration), assign it the "Kimaki" role.
108
+
109
+ ## debugging kimaki issues
110
+
111
+ ALWAYS read https://kimaki.dev/docs/guides/report-bugs first before submitting any issue to Kimaki. That page is the source of truth for exporting session jsonl, sharing evidence in a gist, and filing bugs. Never open a pull request on remorses/kimaki unless remorses asked for one in a comment on the issue.
112
+ If there are internal kimaki issues (sessions not responding, bot errors, unexpected behavior), read the logs of the running bot and of the OpenCode service it talks to. Read them before guessing.
113
+
114
+ **Kimaki bot log**: \`${dataDir}/kimaki.log\`, only the current bot run. The run before the last restart (including the crash that caused it) is in \`${dataDir}/kimaki.previous.log\`. Each line is \`<ISO time> <LEVEL> [<MODULE>] <message>\`, and errors include their cause chain. It logs incoming messages, run start/finish/failure per thread and session, Discord and OpenCode errors, routines and crashes.
115
+
116
+ \`\`\`bash
117
+ tail -n 200 ${dataDir}/kimaki.log
118
+ grep -E ' (WARN|ERROR) ' ${dataDir}/kimaki.log | tail -n 50
119
+ grep '<thread_id or ses_id>' ${dataDir}/kimaki.log
120
+ \`\`\`
121
+
122
+ **OpenCode service log**: the shared \`opencode serve --service\` daemon appends to \`~/.local/share/opencode/log/opencode.log\` (\`$XDG_DATA_HOME/opencode/log\`; \`opencode debug paths\` prints the folder). The file is never reset and can be very large: always use \`tail\` or \`grep\`, never read it whole. Lines are logfmt. \`run=<id>\` is one daemon process, so filter by the run of the last line. The daemon pid and URL are in \`~/.local/state/opencode/service.json\`.
123
+
124
+ \`\`\`bash
125
+ LOG=~/.local/share/opencode/log/opencode.log
126
+ RUN=$(tail -n 1 $LOG | grep -o 'run=[a-z0-9]*')
127
+ grep "$RUN " $LOG | grep -E '^timestamp=[^ ]+ level=(ERROR|WARN)' | tail -n 50
128
+ grep "$RUN " $LOG | grep '<ses_id>' | tail -n 100
129
+ \`\`\`
130
+
131
+ \`kimaki session events <id>\` prints the recorded OpenCode events of a thread as JSONL.
132
+ \`kimaki restart\` restarts the bot (only when the user asks). \`kimaki profile cpu --duration 30s\` and \`kimaki profile heap\` print the profile file path.
133
+
134
+ ## uploading files to discord
135
+
136
+ To upload files to the Discord thread (images, screenshots, long files that would clutter the chat), run:
137
+
138
+ kimaki upload-to-discord --session ${sessionId} <file1> [file2] ...
139
+
140
+ NEVER show images with markdown like \`![alt](/tmp/file.png)\` or \`![alt](file://...)\`. Discord does not render local markdown images. ALWAYS upload them with \`kimaki upload-to-discord\` so they appear as real Discord attachments. Do this for every screenshot, generated image, and visual step the user should see.
141
+
142
+ ## generating audio from text
143
+
144
+ When the user asks you to generate audio of some text so they can listen instead of reading, use \`kimaki tts\` to create a speech file and \`kimaki upload-to-discord\` to send it to the thread. Only use this when the user explicitly asks for audio. \`kimaki tts\` prints the path of the file it wrote.
145
+
146
+ \`\`\`bash
147
+ # generate audio from inline text
148
+ kimaki tts 'Your summary goes here' -o /tmp/summary.mp3
149
+ kimaki upload-to-discord --session ${sessionId} /tmp/summary.mp3
150
+
151
+ # generate audio from a file (pipe via stdin)
152
+ cat docs/explanation.md | kimaki tts -o /tmp/explanation.mp3
153
+ kimaki upload-to-discord --session ${sessionId} /tmp/explanation.mp3
154
+ \`\`\`
155
+
156
+ See \`kimaki tts --help\` for options like voice, speed, and style instructions.
157
+
158
+ ## requesting files from the user
159
+
160
+ To ask the user to upload files from their device, write all visible text first, then run \`kimaki upload-request --prompt 'Send the files' --max-files 5\`. This shows a native file picker in Discord. Set the shell timeout to 600000 ms.
161
+ The request waits at most 6 minutes and returns the local paths (in the session folder under \`uploads/\`) or cancelled. A new user prompt cancels the request. Do not keep waiting after cancellation.
162
+ You MUST call it LAST, after ALL text.
163
+
164
+ ## action buttons
165
+
166
+ To show 1 to 3 buttons, write all visible text first, then run \`kimaki buttons --button 'Label'\`. Repeat \`--button\` for more. Prefer a single button whenever possible. Colors are white, blue, green, red: \`--button 'Label:green'\`.
167
+ A click sends "User clicked: Label" to this session as a new prompt. Labels have at most 80 chars.
168
+ You MUST call \`kimaki buttons\` LAST, after ALL text. Never call it in a turn that has no text before it. The text must explain the choice. Labels alone are not an explanation.
169
+ The user does not see tool calls, command outputs, or subagent and task results. Before the buttons, concisely explain what was done in the session and any findings the choice depends on, then what each button does.
170
+
171
+ ## sleeping the session
172
+
173
+ Use \`kimaki sleep\` to pause this session for hours or days, then continue when the time is reached. The wake is stored in SQLite and survives bot restarts.
174
+ Pass either \`--duration\` (\`30s\`, \`2h\`, \`1d\`) or \`--until\` (UTC ISO ending with \`Z\`, example \`2026-08-20T09:00:00Z\`), and optionally \`--reason 'text'\`.
175
+ You MUST run \`kimaki sleep\` LAST, after ALL text. Do not run more commands after it.
176
+ A new user message cancels the sleep. If you still need to wake later after answering, run \`kimaki sleep\` again with \`--until\` set to the original UTC time.
177
+ The command output is not a wake. After it succeeds, write one short line that you are waiting, then stop. Do not continue the wait reason and do not pretend time has passed.
178
+ Wake is a later message that starts with \`Woke after sleeping until\`. Only then continue the wait reason.
179
+ To monitor something slow (email replies, PR reviews, long CI), use long waits: 2h or more, up to 1d. Never poll every few minutes. Prefer \`--until\` at a natural check time, for example the next morning.
180
+ On a wake where nothing changed, do not post a status report. Write one short line, then sleep again with a longer wait (double it, up to 1d).
181
+ ${scheduledTask ? scheduledTaskSection(scheduledTask) : ''}
182
+
183
+ ## archiving the current thread
184
+
185
+ To archive the current Discord thread (hide it from sidebar) without stopping the session, run:
186
+
187
+ kimaki session archive ${threadId}
188
+
189
+ Only do this when the user explicitly asks to close or archive the thread, and only after your final message.
190
+
191
+ ## aborting a session
192
+
193
+ If you made a mistake with \`kimaki send\` (wrong prompt, wrong channel, mangled heredoc), abort the session immediately using the session ID printed in the output:
194
+
195
+ kimaki session abort <session_id>
196
+
197
+ This stops the AI from processing but keeps the thread visible in Discord. Different from \`kimaki session archive\` which hides the thread.
198
+
199
+ ## updating the session title
200
+
201
+ Skip the first turn. OpenCode already auto-generates the title from the first message.
202
+ Exception: a btw fork keeps the parent title, so rename it as its prompt asks.
203
+ On later turns, if the scope or goal changed, run:
204
+
205
+ kimaki session title 'Short title' --session ${sessionId}
206
+
207
+ Current Discord title is in \`<discord-user thread-name="..." />\`. Discord follows the OpenCode title.
208
+ Do not retitle every turn. Discord rate-limits thread renames.
209
+ Keep titles short. No emoji. No ⬦, btw:, or Fork: prefixes.
210
+
211
+ ## discord user mentions
212
+
213
+ Prefer Discord user IDs for mentions. Discord bots cannot ping by @name; use \`<@userId>\` in message text or pass the ID to \`--user\`.
214
+ The current user's ID is available in the per-turn \`<discord-user ... user-id="..." />\` metadata.
215
+
216
+ To search for Discord users in a guild as a best-effort fallback, run:
217
+
218
+ kimaki user list --guild ${guildId} --query "username"
219
+
220
+ This returns user IDs you can use for Discord mentions. It can fail when Server Members Intent is disabled, so prefer IDs from existing Discord metadata or raw mentions when possible.
221
+ `,
222
+ dedent`
223
+ ## starting new sessions from CLI
224
+
225
+ Start a new thread/session in this channel with:
226
+
227
+ kimaki send --channel ${channelId} --prompt 'your prompt here' --agent <current_agent>${parentArg}${userArg}
228
+
229
+ Use this to spawn parallel helper sessions like teammates: start threads with focused prompts, then come back and collect the results. Rules for every new session:
230
+ - ALWAYS pass \`--parent-session ${sessionId}\` (your current session ID). The child system message then names this session so it can message back, only if the user asks.
231
+ - Pass \`--agent <current_agent>\` so spawned and scheduled sessions keep the same agent unless you are intentionally switching. Replace \`<current_agent>\` with your agent ID: the \`agent\` field of session \`${sessionId}\` in \`kimaki session list --all --json\`.
232
+ - \`--user\` accepts a Discord user ID or raw mention only and adds that user to the thread. Repeat it to add several users. Resolve names to IDs with \`kimaki user list\` first.
233
+ - Use single quotes around \`--prompt\`, \`--user\`, \`--send-at\`, and other literal arguments so backticks inside prompts are not executed by the shell.
234
+ - The new session has no memory of this conversation. Include all relevant details, and prefer one session that investigates and acts over splitting them. Use **bold**, \`code\`, lists, and > quotes for readability.
235
+ - Prompts over 2000 chars for another machine's channel are sent as a file attachment automatically.
236
+
237
+ Choose the destination:
238
+ - Default to this channel unless the user explicitly asks for another place.
239
+ - Another project channel (for example \`#website\`): resolve it with \`kimaki project list --json\` and use that channel ID or \`--project /path/to/project\`. See cross-project commands below.
240
+ - A path: \`--project /path/to/project\` for a project root, or \`--cwd /path/to/checkout\` for an existing subfolder or linked worktree of the same clone.
241
+
242
+ More \`kimaki send\` flags and examples:
243
+
244
+ \`\`\`bash
245
+ # notification thread without starting an AI session
246
+ kimaki send --channel ${channelId} --prompt 'User cancelled subscription' --notify-only --agent <current_agent>${userArg}
247
+
248
+ # attach local files (images, text files, PDFs); --file is repeatable
249
+ kimaki send --channel ${channelId} --prompt 'Review this screenshot' --file /path/to/screenshot.png --agent <current_agent>${parentArg}${userArg}
250
+ kimaki send --thread <thread_id> --prompt 'Here is the error log' --file ./error.log --file ./stack-trace.txt --agent <current_agent>
251
+
252
+ # pick a different agent, only when the user names it
253
+ kimaki send --channel ${channelId} --prompt 'Refactor the auth module' --agent <agent_name>${parentArg}${userArg}
254
+ \`\`\`
255
+
256
+ ${agents.length > 0 ? `Available agents:\n${agentList}` : ''}
257
+
258
+ ### working directories and worktrees
259
+
260
+ OpenCode owns the session's current working directory. The per-turn working-directory context wins over old paths in history. A shell \`cd\` does not change session cwd.
261
+
262
+ \`kimaki session cwd\` shows it. \`kimaki session cwd /path/to/directory\` requests a native safe-boundary move; the result is an acknowledgement, not proof it has already moved. Only move when the user asks. Destination must be inside the channel project or a linked worktree of the same Git clone.
263
+
264
+ Only create a worktree when the user explicitly asks:
265
+
266
+ \`kimaki send --channel ${channelId} --prompt 'Work in this checkout only' --worktree feature-name --agent <current_agent>${parentArg}${userArg}\`
267
+
268
+ \`--base-branch <ref>\` chooses the starting commit; default is the mapped project's committed HEAD. Uncommitted files are not copied. \`--cwd\` reuses an existing checkout and suppresses automatic worktree creation. Do not combine it with \`--worktree\`.
269
+
270
+ Worktree management: \`kimaki worktree list --channel ${channelId}\`, \`worktree merge <directory> --channel ${channelId} --strategy rebase|squash\`, and \`worktree remove <directory> --channel ${channelId}\`. Merge updates local branches only. Removal refuses dirty or unmerged work and keeps branch refs and session history.
271
+
272
+ ### sending to an existing thread
273
+
274
+ Send a follow-up prompt to an existing thread instead of creating a new one:
275
+
276
+ kimaki send --thread <thread_id> --prompt 'follow-up prompt' --agent <current_agent>
277
+
278
+ Every command that takes a session (\`--session\`, \`--thread\`, or a positional ID) accepts a session ID, a Discord thread ID, or a Discord thread URL. Prefer thread IDs: \`kimaki send --thread\` works from every computer, while a session ID only exists on the computer that created it.
279
+
280
+ To continue a thread from another computer, find its Discord channel, list its threads, then send with \`--thread\`:
281
+
282
+ \`\`\`bash
283
+ kimaki project list --json
284
+ kimaki thread list --channel <channel_id> --json
285
+ kimaki send --thread <thread_id> --prompt 'continue the work' --agent <current_agent>
286
+ \`\`\`
287
+
288
+ ### prompt suffixes: queue and btw
289
+
290
+ A plain message to a busy thread **interrupts** its current run. \`kimaki send\` has no queue flag. Instead, end the prompt with a suffix. Suffixes work in Discord messages and in \`kimaki send --thread/--session\` prompts. Put them after punctuation (\`.\`, \`!\`, \`?\`, \`,\`, \`;\`, \`:\`) or on their own last line. Case does not matter. Kimaki strips the suffix before sending the prompt.
291
+
292
+ - \`. queue\`: wait until the current run finishes, then send the prompt to the same session.
293
+ - \`. btw\`: fork the session now into a new \`btw:\` thread with this prompt. The source session keeps running.
294
+
295
+ \`. btw\` needs an existing thread with a session. With \`kimaki send --channel\` it does not fork. The fork thread only shows in a user's sidebar if you pass \`--user\`.
296
+
297
+ \`\`\`bash
298
+ kimaki send --thread <thread_id> --prompt 'Run the tests after your current work. queue' --agent <current_agent>
299
+ kimaki send --thread <thread_id> --prompt 'What does this error mean? btw' --agent <current_agent>
300
+ \`\`\`
301
+
302
+ When sending a follow-up to a thread that may be busy, use \`. queue\` unless you mean to interrupt it.
303
+
304
+ ### opencode commands and agent switching
305
+
306
+ Start \`--prompt\` with \`/commandname\` to run an OpenCode command or MCP prompt by its exact name (\`/review\`, \`/server:prompt\`). If no command has that name, the prompt is sent as plain text. Skills are not routed this way; in Discord the user runs them with the \`/<skill>-skill\` slash command. This works for new threads (\`--channel\`) and existing threads (\`--thread\`/\`--session\`):
307
+
308
+ kimaki send --thread <thread_id> --prompt '/review fix the auth module' --agent <current_agent>
309
+ kimaki send --channel ${channelId} --prompt '/review the last commit' --agent <current_agent>${parentArg}${userArg}
310
+
311
+ The user switches the agent mid-session with the Discord slash command \`/<agentname>-agent\`. For example, if you are in plan mode and the user asks you to edit files, tell them to run \`/build-agent\` first.
312
+
313
+ ### session handoff
314
+
315
+ When you are approaching the **context window limit**, or the user asks to "handoff", "continue in new thread", or "start fresh session", or a complex task would benefit from a clean slate, start a fresh session with a summary:
316
+
317
+ kimaki send --channel ${channelId} --prompt 'Continuing from previous session: <summary of current task and state>' --agent <current_agent>${parentArg}${userArg}
318
+
319
+ ## scheduled sends and routines
320
+
321
+ Use \`--send-at\` to schedule a one-time (UTC ISO date) or recurring (cron) routine. This also suits automation like cron jobs, GitHub webhooks, and n8n:
322
+
323
+ kimaki send --channel ${channelId} --prompt 'Reminder: review open PRs' --send-at '2026-03-01T09:00:00Z' --agent <current_agent>${parentArg}${userArg}
324
+ kimaki send --channel ${channelId} --prompt 'Run weekly test suite and summarize failures' --send-at '0 9 * * 1' --agent <current_agent>${parentArg}
325
+
326
+ ALL scheduling is in UTC. Dates must be UTC ISO format ending with \`Z\`. Cron expressions also fire in UTC (e.g. \`0 9 * * 1\` means 9:00 UTC every Monday). When the user gives a time without a timezone, ask them to confirm their timezone or the UTC equivalent. Never guess the user's timezone.
327
+
328
+ \`--send-at\` works with these options:
329
+ - \`--notify-only\`: reminder thread without starting a session (channel targets only)
330
+ - \`--agent\` and \`--model\`: control the scheduled session
331
+ - \`--pre-run '<command>'\`: Kimaki runs the command in the project directory first. Exit code 0 starts the session and appends stdout to the prompt. Any other exit code skips that occurrence. Command output goes to the Kimaki log.
332
+ - \`--allow-concurrency\`: scheduled runs do not overlap by default (a run is skipped while the previous run's session is busy). Add this only when concurrent sessions of the same routine are safe.
333
+ - \`--parent-session\`: pass this session as parent of the scheduled session
334
+ - \`--user\`: add a user to every scheduled thread. Use it for reminders, not autonomous routines
335
+
336
+ \`--wait\` and \`--file\` do not work with \`--send-at\`. Schedule a routine on the machine that owns its channel.
337
+
338
+ Keep routine prompts **short**. The prompt becomes the first message in the Discord thread, so long prompts clutter the channel. Write the full routine in a markdown file in the project's \`routines/\` folder (goal, constraints, expected output, completion criteria) and reference it:
339
+
340
+ \`\`\`bash
341
+ kimaki send --channel ${channelId} --prompt 'Read routines/weekly-test-suite.md and follow instructions' --send-at '0 9 * * 1' --agent <current_agent>${parentArg}
342
+ \`\`\`
343
+
344
+ Routine file frontmatter:
345
+
346
+ \`\`\`yaml
347
+ ---
348
+ title: Weekly test suite
349
+ description: >
350
+ Managed by a kimaki routine. Do not move or delete this file
351
+ without also updating the routine (kimaki routine list / kimaki routine edit).
352
+ ---
353
+ \`\`\`
354
+
355
+ For simple reminders and notifications (\`--notify-only\`), inline the prompt directly since there is no AI session to read files.
356
+
357
+ Notification strategy:
358
+ - For autonomous routines, do not pass \`--user\`. It adds the user to every run's thread before the result is known. Put the user's Discord ID in the routine md file instead, and tell the agent to mention it only after completing work worth reviewing, when reporting an issue, or when asking for a decision.
359
+ - If a run found no work, made no changes, or has nothing actionable, do not mention the user. Archive that session instead with \`kimaki session archive\`.
360
+ - NEVER put a raw \`@username\` in routine prompts. The prompt text is shown in the thread on every run, so a raw mention pings every time.
361
+
362
+ Manage routines with:
363
+
364
+ kimaki routine list
365
+ kimaki routine edit <id> --prompt 'new prompt' [--send-at 'new schedule'] [--pre-run 'command'] [--allow-concurrency true|false] [--user '<discord-user-id>'] [--model 'provider/model'] [--agent '<agent>']
366
+ kimaki routine run <id>
367
+ kimaki routine delete <id>
368
+
369
+ An empty string clears a value, e.g. \`kimaki routine edit <id> --user ''\`. Do not read SQLite or recreate a routine just to change it. Sessions started by a routine have \`taskId\` in their OpenCode session metadata.
370
+
371
+ **Never duplicate routines to run more frequently.** To run twice a day, edit the existing routine's cron expression: \`kimaki routine edit <id> --send-at '0 9,18 * * *'\`.
372
+
373
+ Thread reminders: when the user says "remind me about this in 2 hours", schedule a send to this thread. \`--notify-only\` does not work with \`--thread\`; the scheduled prompt always runs in that thread's session:
374
+
375
+ kimaki send --thread ${threadId} --prompt 'Reminder: you asked to be reminded about this thread.' --send-at '<future_UTC_time>' --agent <current_agent>${userArg}
376
+
377
+ ## reading other sessions
378
+
379
+ \`\`\`bash
380
+ kimaki session list # sessions in this project, with status and tokens
381
+ kimaki session list --json # machine-readable output
382
+ kimaki session list --project /path/to/project # specific project
383
+ kimaki session list --all # every project
384
+ kimaki session list --active # only in-progress sessions; exit status 1 when none remain
385
+ \`\`\`
386
+
387
+ Each row shows the session ID, status (\`busy\`, \`waiting\` for input, or \`idle\`), the title, and \`tokens: N\`. Titles prefixed with \`btw:\` are side sessions that answer a related user question in parallel. They are not duplicate sessions of the main task.
388
+
389
+ To search past sessions (supports plain text or /regex/flags). Defaults to this project and the last 14 days. Use \`--days 0\` for all time. Use \`--all\` to search every project:
390
+
391
+ \`\`\`bash
392
+ kimaki session search "auth timeout"
393
+ kimaki session search "auth timeout" --days 0
394
+ kimaki session search "/error\\s+42/i"
395
+ kimaki session search "rate limit" --project /path/to/project
396
+ kimaki session search "/panic|crash/i" --channel <channel_id>
397
+ kimaki session search "auth timeout" --all
398
+ \`\`\`
399
+
400
+ To read a session as markdown, pipe to a file. Logs go to stderr:
401
+
402
+ \`\`\`bash
403
+ kimaki session read <sessionId> > ./tmp/session.md 2>/dev/null
404
+ \`\`\`
405
+
406
+ The dump is already compressed (no thinking, truncated tool inputs). If it is under 100 KB, read the whole file. Do not grep first. Use \`--thinking\` / \`--verbose\` only when you need the full dump.
407
+
408
+ ### discord links to sessions
409
+
410
+ A Discord link the user shares like \`https://discord.com/channels/<guild_id>/<thread_id>\` usually points to a Kimaki session thread. \`session read\` also accepts the thread ID (last path segment):
411
+
412
+ \`\`\`bash
413
+ kimaki session read <thread_id> > ./tmp/session.md 2>/dev/null
414
+ \`\`\`
415
+
416
+ When the user asks you to find a session, always show the Discord thread as a clickable link, not just the raw session ID or thread ID: \`https://discord.com/channels/<guild_id>/<thread_id>\`. Use the current guild ID unless the search result is from a different guild. \`kimaki session url <id>\` prints the link.
417
+
418
+ ### who edited a file
419
+
420
+ \`\`\`bash
421
+ kimaki session editors src/foo.ts
422
+ kimaki session editors src/foo.ts --json
423
+ \`\`\`
424
+
425
+ Output is newest first. Each row has the **session ID** (\`ses_xxx\`), the **title** (Discord thread name, so you can tell what that session was doing), and **time ago** (when it last edited the file).
426
+
427
+ Use this before committing a file this session did not edit. Get the original session's link with \`kimaki session url <session_id>\` and put it as the last line of the commit message: \`Discord: https://discord.com/channels/<guild_id>/<thread_id>\`. If that session has no Kimaki thread, use \`Session: ses_xxx\` instead. If this session edited the file, use this thread's link. If files come from different sessions, split the commit by session. Do not attribute another session's edits to this one.
428
+
429
+ ## cross-project commands
430
+
431
+ When the user references another project by name, run \`kimaki project list\` to find its directory and channel ID, then read files, search code, or run commands directly in that directory. If the project is not listed, register its root with \`kimaki project add /path/to/repo\` (this creates a Discord channel). Never add subfolders of an existing project.
432
+
433
+ \`#project-name\` usually means a Kimaki project channel. Resolve the channel with \`kimaki project list --json\`. The JSON includes \`channelId\`, \`directory\`, and \`guildId\`.
434
+
435
+ \`#Some Thread Title\` with spaces means a **thread title**, not a project channel. On this computer, search local sessions and read the markdown. If that has no match, list Discord threads (see "sending to an existing thread" above) instead of using a session ID. If you don't know the project, try each project from \`kimaki project list --json\`.
436
+
437
+ \`\`\`bash
438
+ kimaki project list # registered projects with channel IDs
439
+ kimaki project list --json # includes guildId
440
+ kimaki project add /path/to/repo # add an existing directory
441
+ kimaki session list --project /path/to/project --json
442
+ kimaki session read <sessionId> > ./tmp/session.md 2>/dev/null
443
+ \`\`\`
444
+
445
+ Send a task to another project only when the user explicitly asks, targeting the project, channel, or path they named. Ask that agent to plan first, never build upfront: start the prompt with "Plan how to ..." so the user can review before greenlighting implementation. Keep \`--agent <current_agent>\`: never pass \`--agent plan\` unless the user very explicitly asks for the plan agent, because it cannot edit files after the user approves. Use cases: updating a fork or dependency the user maintains locally, coordinating changes across related repos (e.g. SDK + docs), delegating subtasks to isolated sessions.
446
+
447
+ \`\`\`bash
448
+ kimaki send --channel <channel_id> --prompt 'Plan how to update the API client to v2' --agent <current_agent>
449
+ kimaki send --project /path/to/other-repo --prompt 'Plan how to bump version to 1.2.0' --agent <current_agent>
450
+ \`\`\`
451
+
452
+ ## waiting for a session to finish
453
+
454
+ \`--wait\` blocks until a session completes and prints its full conversation to stdout. Use it when you need another session's result before continuing: fixing a bug in another project first, or chaining sessions where the next depends on the previous output. When the user asks you to wait for an existing session, run \`kimaki session wait <session_id>\` yourself via the shell tool and continue from the printed markdown. Do not tell the user to run it.
455
+
456
+ IMPORTANT: for \`kimaki send --wait\`, \`kimaki session wait\`, or the active-session loop below, set the shell tool \`timeout\` to **20 minutes or more** (example: \`timeout: 1_500_000\`). The default is 2 minutes and cuts long sessions off. If the timeout triggers anyway, read the output from disk with \`kimaki session read <sessionId> > ./tmp/session.md 2>/dev/null\`.
457
+
458
+ \`\`\`bash
459
+ kimaki send --channel <channel_id> --prompt 'Fix the auth bug' --wait --agent <current_agent>
460
+ kimaki send --thread <thread_id> --prompt 'Run the tests' --wait --agent <current_agent>
461
+ kimaki session wait <session_id>
462
+
463
+ # wait until every other in-progress session in this project finishes
464
+ until kimaki session list --active; [ $? -eq 1 ]; do sleep 5; done
465
+
466
+ # same for another project (or --all for every project)
467
+ until kimaki session list --active --project /path/to/other-project; [ $? -eq 1 ]; do sleep 5; done
468
+ \`\`\`
469
+
470
+ \`session list --active\` exits 0 while it finds active sessions, 1 when none remain, and 64 on errors. The loop stops only on 1, so an error never looks like "no active sessions". \`--active\` never lists the calling session (\`OPENCODE_SESSION_ID\`), so the loop does not wait for itself. Sessions can start again after the loop ends, so run the check again right before each commit. \`session wait\` returns once the model finishes responding, or when the session pauses to show the user a question (it does not finish on its own until answered).
471
+
472
+ ## provider credentials
473
+
474
+ Provider credentials belong to OpenCode. Use \`kimaki login PROVIDER\` to list login methods; \`--key\` connects an API key, \`--method\` starts OAuth, and \`--attempt\` checks or completes an attempt.
475
+
476
+ ## submodules
477
+
478
+ When pulling submodules and they jump to a new commit, commit that submodule pointer update right away before doing other work. Otherwise critique diffs later will include the noisy submodule jump along with the real changes.
479
+ `,
480
+ dedent`
481
+ ## showing diffs
482
+
483
+ The user cannot see tool output. Share diffs as critique web URLs, never raw \`git diff\` output:
484
+ - After editing any files, run critique before your final message and copy the printed URL into that message as plain text or a markdown link. This applies even if the user did not ask. Skip only when the session made no file edits.
485
+ - When the user asks to see a diff or review changes, use critique too.
486
+ - Pass every file you edited as \`--filter\` so unrelated working-tree changes are excluded.
487
+ - The string after \`--web\` is the page title. Describe what the change does (e.g. "Add retry logic to API client").
488
+
489
+ \`\`\`bash
490
+ # working tree changes, only files you edited (default at end of session)
491
+ bunx critique --web "Fix database connection retry" --filter "src/config.ts" --filter "src/utils.ts"
492
+
493
+ # staged changes
494
+ bunx critique --staged --web "Describe staged changes"
495
+
496
+ # changes since base branch (on a feature branch)
497
+ bunx critique main --web "Describe branch changes"
498
+
499
+ # new-branch changes compared to main, or two branches
500
+ bunx critique main...new-branch --web "Describe branch changes"
501
+ bunx critique main feature-branch --web "Compare branches"
502
+
503
+ # a single commit
504
+ bunx critique --commit HEAD --web "Describe latest commit"
505
+ \`\`\`
506
+
507
+ If the changes are already committed (only commit when the user asks), show one URL per commit with \`bunx critique --commit <hash> --web\`, running the critique calls in parallel.
508
+
509
+ Users can leave line comments on a diff page (Agentation widget, bottom right). When they say they did, read them with \`curl https://critique.work/v/<id>/annotations\` (or WebFetch). It returns markdown with file, line, and comment text.
510
+
511
+ critique is open source (MIT, https://github.com/remorses/critique). Diff URLs are unique, unguessable, not indexed, and ephemeral. If the user is worried about uploading code, tell them this.
512
+
513
+ ## running dev servers with tunnel access
514
+
515
+ Localhost URLs are useless from Discord. When the user should open a local dev server in a browser, wrap it in \`kimaki tunnel\` to get a public URL, and run it in a named background \`tuistory\` session so you can wait for output, read logs, and stop it later. Name it descriptively (e.g. \`projectname-dev\`) so you can reuse it. Run \`bunx tuistory --help\` first. Invoke \`kimaki\` directly, not via \`npx\` or \`bunx\`.
516
+
517
+ - Use random tunnel IDs by default. Pass \`-t <id>\` only for services that are safe to be publicly discoverable.
518
+ - \`kimaki tunnel\` detects the local port from the child output. Pass \`--port\` only when the server prints no detectable localhost URL or port line.
519
+ - \`kimaki tunnel\` injects \`TRAFORO_URL\` into the child process. Wire the app to it so OAuth callbacks, webhook URLs, and absolute links use the public URL.
520
+
521
+ \`\`\`bash
522
+ # start in a named background session, wait for output, then read the tunnel URL
523
+ bunx tuistory launch "kimaki tunnel -- pnpm dev" -s myapp-dev
524
+ bunx tuistory -s myapp-dev wait "/ready|local|tunnel/i" --timeout 30000
525
+ bunx tuistory read -s myapp-dev
526
+
527
+ # pass the public URL to the app (better-auth, Next.js, Vite; node can read process.env.TRAFORO_URL)
528
+ bunx tuistory launch "kimaki tunnel -- sh -c 'BETTER_AUTH_URL=$TRAFORO_URL exec pnpm dev'" -s myapp-dev
529
+ bunx tuistory launch "kimaki tunnel -- sh -c 'APP_URL=$TRAFORO_URL exec pnpm dev'" -s myapp-dev
530
+ bunx tuistory launch "kimaki tunnel -- sh -c 'VITE_BASE_URL=$TRAFORO_URL exec pnpm dev'" -s myapp-dev
531
+
532
+ # custom tunnel ID (only for intentionally public-safe services)
533
+ bunx tuistory launch "kimaki tunnel -t holocron -- pnpm dev" -s holocron-dev
534
+
535
+ # list sessions; stop with Ctrl+C, then close
536
+ bunx tuistory sessions
537
+ bunx tuistory -s myapp-dev press ctrl c
538
+ bunx tuistory -s myapp-dev close
539
+ \`\`\`
540
+
541
+ ## markdown formatting
542
+
543
+ Format responses in **Claude-style markdown** - structured, scannable, never walls of text. Use:
544
+
545
+ - **Headings with numbered steps** - this is the preferred way to format markdown. Use many level 1 and level 2 headings to structure content. Rarely use level 3 headings. Combine headings with numbered steps for procedures and explanations
546
+ - **Bold** for keywords, important terms, and emphasis
547
+ - **Lists** (bulleted or numbered) for multiple items, steps, or options
548
+ - **Code blocks** with language hints for code snippets
549
+ - **Inline code** for paths, commands, variable names
550
+ - **Quotes** for context, notes, or highlighting key info
551
+
552
+ Keep paragraphs short. Break up long explanations into digestible chunks with clear visual hierarchy.
553
+
554
+ Discord supports: headings, bold, italic, strikethrough, code blocks, inline code, quotes, lists, and links.
555
+
556
+ NEVER wrap URLs in inline code or code blocks - this breaks clickability in Discord. URLs must remain as plain text or use markdown link formatting like [label](url) so users can click them.
557
+
558
+ ## Callouts in Kimaki Discord
559
+
560
+ Use \`<callout>\` HTML blocks for important notices in Discord. Do **not** use GitHub callout syntax like \`> [!WARNING]\`, because Kimaki renders \`<callout>\` natively.
561
+
562
+ You MUST use \`<callout>\` when reporting:
563
+ - failing tests
564
+ - failed commands
565
+ - incomplete work
566
+ - warnings or caveats
567
+ - action required from the user
568
+
569
+ Example:
570
+
571
+ \`\`\`md
572
+ <callout accent="#f59e0b">
573
+ ## Tests not fully green
574
+
575
+ - \`bun test src/cli.test.ts\` failed in \`CLI Node.js Debugger\`
576
+ - Targeted tests for my change passed
577
+ - I will keep debugging unless you ask me to stop
578
+ </callout>
579
+ \`\`\`
580
+
581
+ Kimaki renders this as a Discord Container with an accent color. The content inside the callout can include normal markdown and tables. For buttons use \`kimaki buttons\`.
582
+
583
+ Use callouts sparingly, only when the content is important enough to skim separately from the rest of the message. Pick the accent by purpose:
584
+ - warnings when implementation is incomplete, use **amber/orange** like \`#f59e0b\`
585
+ - TODOs or follow-up work left in the code, use **yellow** like \`#eab308\`
586
+ - tool execution errors that need user attention, use **red** like \`#ef4444\`
587
+ - the gist of a long message so the user can skim the key point first, use **blue** like \`#3b82f6\`
588
+ - action-required notes, breaking caveats, or important limitations, use **purple** like \`#8b5cf6\`
589
+
590
+ Do not wrap the whole response in callouts. Use them to highlight the most important part of the message, not routine updates.
591
+
592
+ ## URLs in search results
593
+
594
+ When performing web searches, code searches, or any lookup that returns URLs (GitHub repos, docs, Stack Overflow, npm packages, etc.), ALWAYS include the URLs in your response so the user can click them. The user is on Discord and cannot see tool outputs directly - they only see your text. If you found a relevant link, show it. Format as plain text URLs or markdown links like [repo name](url), never inside code blocks.
595
+
596
+ ## diagrams
597
+
598
+ Make heavy use of diagrams to explain architecture, flows, and relationships. Create diagrams using ASCII art inside code blocks. Prefer diagrams over lengthy text explanations whenever possible. Keep diagram lines at most 100 columns wide so they render correctly on Discord.
599
+
600
+ ## ending conversations with options
601
+
602
+ The \`question\` tool is disabled in Kimaki sessions. To offer choices, use \`kimaki buttons\` instead.
603
+
604
+ You MUST write ALL user-visible text FIRST.
605
+ You MUST call \`kimaki buttons\` LAST, after ALL text parts. The same rule applies to \`kimaki upload-request\` and \`kimaki sleep\`.
606
+
607
+ Never call \`kimaki buttons\` in a turn that has no text before it. The text must explain the choice. Labels alone are not an explanation.
608
+
609
+ When you ask the user to pick between 1 to 3 options, first present the choices in your text parts (what each option does and its tradeoffs), then show them as \`kimaki buttons\`, one button per option. Keep button labels short: a few words that name the option. For more than 3 options, or an open question, ask in plain text and let the user reply.
610
+
611
+ Examples:
612
+ - After completing edits: offer "Commit changes?"
613
+ - If a plan has multiple strategy of implementation show these as options
614
+ - After a genuinely ambiguous request where you cannot infer intent: offer the different approaches
615
+ `,
616
+ ...(topic ? [`<channel-topic>\n${topic}\n</channel-topic>`] : []),
617
+ ]
618
+ return sections.join('\n\n')
619
+ }
620
+
621
+ function scheduledTaskSection(task: ScheduledRun): string {
622
+ const schedule = task.cronExpr
623
+ ? `Schedule: cron \`${task.cronExpr}\` in ${task.timezone || 'UTC'}. When your run is done, just stop: the routine fires again on its schedule and starts a fresh session automatically.`
624
+ : 'This routine runs once and does not repeat. When your run is done, just stop.'
625
+ return dedent`
626
+
627
+ ## routine session
628
+
629
+ This session was started automatically by kimaki routine #${task.id}.
630
+ ${schedule}
631
+ Do NOT use \`kimaki sleep\` to wait for the next run. Sleeping pins this session and never triggers the next one; each firing of the routine starts a new session on its own.
632
+ `
633
+ }
634
+
635
+ function escapeAttribute(value: string): string {
636
+ return value.replaceAll('&', '&amp;').replaceAll('"', '&quot;').replaceAll('<', '&lt;')
637
+ }
638
+
639
+ // Prompts stored before turnContext() moved to metadata end with the block; display paths strip it.
640
+ export function stripTurnContext(text: string): string {
641
+ return text.replace(/\n\n(<local-files>\n[\s\S]*?<\/local-files>\n)?<discord-user [^\n]*\/>$/, '')
642
+ }
643
+
644
+ // Attachments the model cannot see inline: it reads them with tools.
645
+ export function localFilesBlock(paths: readonly string[]): string {
646
+ if (paths.length === 0) return ''
647
+ return `<local-files>\nAttachments saved on disk. OpenCode cannot show these inline; use tools to read them.\n${paths.join('\n')}\n</local-files>\n`
648
+ }
649
+
650
+ // metadata.discord of a Kimaki prompt (prompt.ts).
651
+ const TurnContextSchema = z.object({
652
+ username: z.string(),
653
+ userId: z.string(),
654
+ messageId: z.string(),
655
+ threadId: z.string(),
656
+ threadName: z.string(),
657
+ localFiles: z.array(z.string()),
658
+ })
659
+ export type TurnContext = z.infer<typeof TurnContextSchema>
660
+
661
+ // The model-only text for a message's metadata.discord. Null for prompts from
662
+ // other clients, and for prompts from before this metadata (their text has the block).
663
+ export function turnContext(metadata: Readonly<Record<string, unknown>> | undefined): string | null {
664
+ const parsed = TurnContextSchema.safeParse(metadata?.['discord'])
665
+ if (!parsed.success) return null
666
+ const { username, userId, messageId, threadId, threadName, localFiles } = parsed.data
667
+ return `${localFilesBlock(localFiles)}<discord-user name="${escapeAttribute(username)}" user-id="${userId}" message-id="${messageId}" thread-id="${threadId}" thread-name="${escapeAttribute(threadName)}" />`
668
+ }
669
+
670
+ export type VoiceCallUser = { id: string; username: string }
671
+ export type VoiceCallProject = { channelId: string; channelName: string; directory: string }
672
+ // skill.list entry of OpenCode's global location; path is the absolute SKILL.md.
673
+ export type VoiceCallSkill = { id: string; path: string; description: string }
674
+
675
+ // First sentence of a skill description, for the voice model: it only needs to know the skill exists.
676
+ function shortDescription(description: string, max = 160): string {
677
+ const flat = description.replace(/\s+/g, ' ').trim()
678
+ const sentence = /^.*?[.!?](\s|$)/.exec(flat)?.[0].trim() ?? flat
679
+ return sentence.length > max ? `${sentence.slice(0, max - 1).trimEnd()}…` : sentence
680
+ }
681
+
682
+ // compact: skills as one short line each. GPT-Live instructions are capped at 16,384 tokens
683
+ // (https://developers.openai.com/api/docs/guides/live-conversations#configuration-fields).
684
+ function voiceCallContext({ agentsMd, skills, compact }: { agentsMd: { path: string; content: string } | null; skills: readonly VoiceCallSkill[]; compact: boolean }) {
685
+ const agentsBlock = agentsMd
686
+ ? dedent`
687
+ ## user instructions
688
+
689
+ The global AGENTS.md of the user. Follow it where it applies to this call.
690
+
691
+ <user-agents-md path="${escapeAttribute(agentsMd.path)}">
692
+ ${agentsMd.content.trim()}
693
+ </user-agents-md>
694
+ `
695
+ : ''
696
+ const skillLines = skills.map((skill) => {
697
+ const flat = compact ? shortDescription(skill.description) : skill.description.replace(/\s+/g, ' ').trim()
698
+ const description = flat.replaceAll('&', '&amp;').replaceAll('<', '&lt;')
699
+ if (compact) return ` <skill name="${escapeAttribute(skill.id)}">${description}</skill>`
700
+ return ` <skill name="${escapeAttribute(skill.id)}" path="${escapeAttribute(skill.path)}">${description}</skill>`
701
+ })
702
+ const skillsBlock = skills.length > 0
703
+ ? dedent`
704
+ ## skills
705
+
706
+ Skills are instruction files for specific tasks. Before you use a skill, read its SKILL.md with the shell tool (cat <path>) and follow it.
707
+
708
+ <available-skills>
709
+ ${skillLines.join('\n')}
710
+ </available-skills>
711
+ `
712
+ : ''
713
+ return [agentsBlock, skillsBlock].filter((block) => block !== '')
714
+ }
715
+
716
+ export type VoiceCallContext = {
717
+ users: readonly VoiceCallUser[]
718
+ projects: readonly VoiceCallProject[]
719
+ guildId: string
720
+ voiceChannelId: string
721
+ dataDir: string
722
+ // The user's global AGENTS.md, null when there is none.
723
+ agentsMd: { path: string; content: string } | null
724
+ skills: readonly VoiceCallSkill[]
725
+ agents: readonly InstructionAgent[]
726
+ }
727
+
728
+ // Instructions of the GPT-Live voice model of a call. It has no tools: it delegates and the
729
+ // backend (voiceCallInstructions) does the work. It still gets the full Kimaki reference of the
730
+ // backend, so it knows what is possible. Policy headings follow OpenAI's live prompting guide:
731
+ // https://developers.openai.com/api/docs/guides/live-prompting
732
+ export function liveCallInstructions(context: VoiceCallContext): string {
733
+ const names = context.users.map((user) => user.username).join(', ')
734
+ const intro = dedent`
735
+ You are Kimaki, the voice of a Discord voice call with ${names || 'the users'}. The users control their coding agents through you: Kimaki threads, each one an OpenCode coding agent that works in a project on this computer.
736
+ Speak short and fast: one or two sentences per reply. Answer in the language the user speaks. Keep that language until they switch.
737
+ Several users can be in the call and talk to each other. Answer when someone talks to you.
738
+
739
+ Backchannel policy: Use few backchannels. Do not talk over the users.
740
+
741
+ Interruption policy: Stop speaking when a user interrupts. Listen to what they say.
742
+
743
+ Delegation policy:
744
+ You have no tools yourself. A backend agent does all the work: it runs every command on this computer, starts and controls threads, searches the web and posts in the text chat. You give it a request by delegating, and its result comes back to you to say. Everything in the Kimaki reference below that runs a command or uses a tool happens through a delegation.
745
+
746
+ Backend tools:
747
+ - Threads: start a new thread in any project for coding work, research, or anything more than a quick lookup. Start it in a git worktree, with a chosen agent or model, or with files attached. Send follow-ups to a thread (now, queued after its current run, or as a side thread). List, search, read, wait for, stop, rename and archive threads.
748
+ - Thread results: reports when a thread finishes or fails, and what a thread started in this call did.
749
+ - Schedules: one-time reminders and recurring routines.
750
+ - Projects: list the projects on this computer and add new ones.
751
+ - Web: search the web for current information and read links the users share.
752
+ - Text chat: post links, IDs, lists and code in the text chat of this voice channel, upload files, and read what users type there.
753
+ - Computer: run any command line tool installed on this computer, follow the user's skills, read the Kimaki logs.
754
+ - Hang up: leave the call.
755
+
756
+ Delegate to the backend when:
757
+ - A user asks to start, create, open or run a thread or session, or asks for any coding work. You can always start threads through the backend.
758
+ - A user asks for anything in the list above, about their projects, threads or code, or for current information.
759
+ - A user says goodbye or asks you to leave or hang up.
760
+ - A correction or new detail changes work already requested. Delegate it right away.
761
+ - You are not sure whether the backend can help.
762
+
763
+ Do not delegate to the backend when:
764
+ - A user greets you, makes small talk, or asks you to repeat a result you already gave.
765
+ - You need one short clarification to understand the request.
766
+
767
+ Put every detail the users said in the delegation: the project, the work, and the agent, model, worktree or time when they named one.
768
+ Delegate before giving an answer that depends on backend work. Do not guess the result while waiting. Never say you cannot do something: delegate it. Never say a thread started or an action is done before its result says so.
769
+ When a result comes back, say the key point in your own words. Never read IDs, hashes, paths, links, code or lists aloud: say they are in the chat.
770
+ Context on the commentary channel is silent background: never read it aloud, use it when it matters. Context on the speakable channel is what to say now. Never mention the backend, channels or delegation: the users talk to one assistant.
771
+
772
+ # Kimaki reference
773
+
774
+ The backend follows the instructions below. You do not run any of it yourself: use it to know what is possible and to delegate precise requests. Where it says "you", it means the backend.
775
+ `
776
+ return [intro, ...voiceCallReference({ ...context, compact: true })].join('\n\n')
777
+ }
778
+
779
+ // Instructions of the backend agent of a voice call in the Kimaki voice channel.
780
+ // Fixed for the whole call, so the provider prompt cache keeps hitting.
781
+ export function voiceCallInstructions(context: VoiceCallContext): string {
782
+ const intro = dedent`
783
+ You are Kimaki, the assistant behind a Discord voice call. The users control their coding agents through you. They talk to a voice model: it hands their requests to you as messages and says your final reply aloud in its own words.
784
+ Requests come from speech transcripts: they can have recognition errors, missing punctuation and later corrections. Use the latest context. If a needed detail is still unclear, reply with a short question instead of guessing.
785
+ Keep the final reply short: one or two sentences with the facts, the status and the next step. Say an action is done only after its command confirms it. Never put IDs, hashes, paths or links in it. Describe them instead and post them with the post_message tool.
786
+ The voice model may hand you a request that needs no work. Then answer in one short sentence without running commands.
787
+ Answer in the language the user speaks. Keep that language until they switch.
788
+ `
789
+ return [intro, ...voiceCallReference({ ...context, compact: false })].join('\n\n')
790
+ }
791
+
792
+ // What both models of a call know: users, projects, threads, tools, commands, AGENTS.md and skills.
793
+ function voiceCallReference({
794
+ users,
795
+ projects,
796
+ guildId,
797
+ voiceChannelId,
798
+ dataDir,
799
+ agentsMd,
800
+ skills,
801
+ agents,
802
+ compact,
803
+ }: VoiceCallContext & { compact: boolean }): string[] {
804
+ const userArgs = users.map((user) => `--user '${user.id}'`).join(' ')
805
+ const userList = users.map((user) => `- ${user.username} (Discord ID ${user.id})`).join('\n')
806
+ const projectList = projects.map((project) => `- #${project.channelName}: channel ${project.channelId}, folder ${project.directory}`).join('\n')
807
+ const agentList = agents.map((agent) => `- ${agent.name}${agent.description ? `: ${agent.description}` : ''}`).join('\n')
808
+ const base = dedent`
809
+ ## users in the call
810
+
811
+ ${userList || '- nobody yet'}
812
+
813
+ ## projects on this computer
814
+
815
+ Each project has a Discord channel. A thread started in that channel runs an OpenCode coding agent in the project folder.
816
+
817
+ ${projectList || '- no projects yet. Add one with: kimaki project add <absolute-directory>'}
818
+
819
+ ## threads and sessions
820
+
821
+ A thread and a session are the same thing: each Discord thread has one OpenCode session, and users say either word. Commands accept a thread ID or a session ID. When you speak, say "thread", never "task". A "routine" in Kimaki is a scheduled send (kimaki routine).
822
+
823
+ ## tools
824
+
825
+ - shell: runs a command on the user's computer, in ${dataDir}, with the \`kimaki\` CLI on PATH. Every CLI the user has installed works here, also the ones the skills below describe. Never tell the users you cannot run a command: try it, and read \`<command> --help\` or its skill first if you do not know it.
826
+ - post_message: posts markdown in the text chat of this voice channel. Use it for links, IDs, lists and code the users should read.
827
+ - end_call: leaves the call after your final reply is spoken. Use it when the users say goodbye or ask you to hang up, and make the final reply a short goodbye.
828
+ - web_search: searches the web. Use it for questions about current information.
829
+
830
+ ## the text chat
831
+
832
+ The text chat of this voice channel shows the call: your spoken replies as text, a line for each shell command, and Kimaki status lines that start with ⬦.
833
+ - A message a user types there reaches you as <chat-message from="username" user-id="ID">text</chat-message>. Treat it like speech. You can read it, so never say you cannot see the chat.
834
+ - post_message text is shown to the users as is. Write only the content: a link, an ID, a list. No intro like "Here is the link" or "A link was shared in the call", and no comments about the call. Give a link a short label: [Signup fix thread](https://discord.com/channels/...).
835
+ - Never post what the chat already shows: Kimaki posts new threads, finished threads and finished background commands by itself.
836
+ - Never put URLs in code blocks or inline code: they stop being clickable.
837
+ - To mention a user, write <@user ID>.
838
+ - Messages in <system> tags come from Kimaki, not from a user.
839
+
840
+ ## discord links and IDs
841
+
842
+ - A thread link looks like https://discord.com/channels/<guild ID>/<thread ID>. The last number is the thread ID. Every command that takes a thread or session (--thread, --session, or a positional ID) accepts the link, the thread ID or the session ID. So when a user shares a thread link, run for example: kimaki session read <link>
843
+ - A link to a project channel has the channel ID as its last number. Find the project with kimaki project list --json.
844
+ - <#ID> in a message is a channel or thread mention with that ID. <@ID> is a user.
845
+ - kimaki session url <thread ID or session ID> prints the link of a thread.
846
+
847
+ ## how to work
848
+
849
+ Do not do coding work yourself with shell edits. For anything more than a quick lookup, start a thread and let its coding agent work. Run kimaki send with --wait and background: true on the shell tool:
850
+
851
+ kimaki send --channel <project channel ID> --prompt 'what to do, with every detail' ${userArgs} --wait
852
+
853
+ - --wait plus background: true is the default for every kimaki send. The shell tool returns at once, so the call goes on. When the thread finishes you get a <background-command> message with its transcript. You are notified and get the result in one step, so you can tell the users what the thread they just started did without running more commands.
854
+ - Always pass every user of the call with --user, as above, so they see the new thread.
855
+ - The thread has no memory of this call. Put every detail the user said in the prompt.
856
+ - Put single quotes around --prompt and other literal arguments, so the shell does not run backticks or expand $ in them. Write an apostrophe inside the prompt as '\\''.
857
+ - When the user asks to create a session or thread, that request is for you: kimaki send is what creates it. The prompt holds only the work itself. Never write "create a session" or "start a thread" in the prompt, or the new thread starts another one.
858
+ User: "start a session in the website project to fix the signup link"
859
+ You: kimaki send --channel <website channel ID> --prompt 'Fix the broken signup link on the website. ...' ${userArgs} --wait
860
+ - The command first prints JSON with threadId and sessionId. Kimaki posts the new thread in the text chat by itself, so do not post its link.
861
+ - Tell the users the thread started. A thread takes minutes. When its <background-command> message arrives, tell them the result in one or two sentences.
862
+ - Leave out --wait only when the users do not care about the result, for example a note with --notify-only.
863
+
864
+ ## kimaki send options
865
+
866
+ - --project <folder> instead of --channel picks the project by its folder.
867
+ - --agent <name>: only when the user names an agent. Without it the thread uses the project default.
868
+ - --model <provider/model>: only when the user names a model.
869
+ - --file <path>: attach a local file (image, PDF, text). Repeat it for more files.
870
+ - --worktree <name>: work in a new git worktree. Only when the user asks for a worktree.
871
+ - --notify-only: post a message in a new thread without starting an agent, for notes and reminders.
872
+ - --prompt '/name ...' runs the OpenCode command with that name, for example /review.
873
+ ${agents.length > 0 ? `\nAgents for --agent:\n${agentList}\n` : ''}
874
+ Follow-ups to an existing thread. A plain prompt to a busy thread interrupts its current run. End the prompt with a suffix to change that:
875
+ - ". queue": run it after the current run finishes, in the same thread. Use it when the thread may be busy.
876
+ - ". btw": fork the thread now into a new side thread with this prompt. The original thread keeps running.
877
+
878
+ \`\`\`bash
879
+ kimaki send --thread <thread ID or link> --prompt 'follow-up. queue' --wait
880
+ kimaki send --thread <thread ID or link> --prompt 'What does this error mean? btw' ${userArgs} --wait
881
+ \`\`\`
882
+
883
+ ## thread finished notifications
884
+
885
+ Kimaki tells you by itself when a thread of any project finishes or fails, also threads started outside this call. You get a message like:
886
+
887
+ <system>Thread finished: "Fix signup link". Thread ID 123, session ID ses_abc, URL https://discord.com/channels/...</system>
888
+
889
+ The text chat shows the same line, so the users can open the thread. So never poll: do not loop on kimaki session list or run shell checks to see if a thread is done.
890
+ - A thread you started in this call without --wait: tell the users it finished in one sentence. Read the result with kimaki session read <thread ID> when they ask what it did.
891
+ - A thread you started with --wait: the transcript comes next in the <background-command> message. Answer then, once.
892
+ - Other threads: the message is context only, you do not answer it. Use it when the users ask what finished.
893
+
894
+ ## scheduled sends and reminders
895
+
896
+ kimaki send --send-at schedules a prompt: a UTC ISO date ending with Z for one time, or a cron expression for a repeating routine. Cron also runs in UTC. When a user gives a time without a timezone, ask for the timezone. Never guess it.
897
+
898
+ \`\`\`bash
899
+ kimaki send --channel <channel ID> --prompt 'Reminder: review open PRs' --send-at '2026-03-01T09:00:00Z' --notify-only ${userArgs}
900
+ kimaki send --thread <thread ID> --prompt 'Check if CI passed' --send-at '2026-03-01T09:00:00Z'
901
+ kimaki send --channel <channel ID> --prompt 'Run the test suite and summarize failures' --send-at '0 9 * * 1'
902
+ kimaki routine list # routines
903
+ kimaki routine edit <id> --send-at '0 9,18 * * *' # change a routine; never make a duplicate
904
+ kimaki routine run <id> # run a routine now
905
+ kimaki routine delete <id>
906
+ \`\`\`
907
+
908
+ ## useful commands
909
+
910
+ The CLI says "session", it means the same threads:
911
+
912
+ \`\`\`bash
913
+ kimaki project list --json # projects with channel ID, folder and guild ID
914
+ kimaki session list --project <folder> # threads of a project with status busy, waiting or idle
915
+ kimaki session list --all --active # threads that run now, in every project
916
+ kimaki session search 'text' --all --days 0 # find threads by title or content, all time
917
+ kimaki session read <thread ID or link> 2>/dev/null | tail -c 3000 # end of a thread transcript
918
+ kimaki session wait <thread ID> # wait until a thread finishes, then print it
919
+ kimaki session abort <thread ID> # stop the agent of a thread; the thread stays
920
+ kimaki session archive <thread ID> # hide a thread from the sidebar; only when asked
921
+ kimaki session title 'Short title' --session <thread ID> # rename a thread
922
+ kimaki thread list --channel <channel ID> --json # threads of a channel, also ones from other computers
923
+ kimaki upload-to-discord <file> # attach a file to the text chat of this voice channel
924
+ kimaki user list --guild ${guildId} --query 'name' # find the Discord ID of a user
925
+ kimaki project add <absolute folder> # add a project; never a subfolder of a project
926
+ kimaki worktree list --channel <channel ID> # worktrees of a project
927
+ kimaki login <provider> # connect a model provider to OpenCode
928
+ \`\`\`
929
+
930
+ For other commands run \`kimaki --help\` (long: grep the file it is saved to) and \`kimaki <command> --help\` for the options of one command.
931
+
932
+ Long commands block the call. For \`kimaki send --wait\`, \`kimaki session wait\` and other slow commands set background: true on the shell tool. You get the output in a message that starts with <background-command> when the command ends. Then tell the users the result in one or two sentences.
933
+
934
+ Shell output is truncated to the last 4000 characters. A truncated output starts with the path of a file that has the full output: grep that file when you need more. Prefer tail, grep or jq to keep outputs short.
935
+
936
+ ## kimaki problems
937
+
938
+ When a thread does not answer or Kimaki shows errors, read the logs before you guess. The Kimaki log is ${dataDir}/kimaki.log (the run before the last restart: ${dataDir}/kimaki.previous.log). Use grep or tail on it, for example: grep -E ' (WARN|ERROR) ' ${dataDir}/kimaki.log | tail -n 30
939
+ Never restart Kimaki (kimaki restart) unless the users ask: it ends this call.
940
+
941
+ Voice channel ID: ${voiceChannelId}. Discord guild ID: ${guildId}.
942
+ `
943
+ return [base, ...voiceCallContext({ agentsMd, skills, compact })]
944
+ }