kimaki 0.4.82 → 0.4.84

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 (264) hide show
  1. package/LICENSE +21 -0
  2. package/dist/anthropic-auth-plugin.js +7 -0
  3. package/dist/cli.js +51 -7
  4. package/dist/commands/abort.js +5 -16
  5. package/dist/commands/action-buttons.js +3 -3
  6. package/dist/commands/add-project.js +1 -1
  7. package/dist/commands/ask-question.js +3 -3
  8. package/dist/commands/context-usage.js +1 -1
  9. package/dist/commands/create-new-project.js +1 -1
  10. package/dist/commands/fork.js +11 -8
  11. package/dist/commands/merge-worktree.js +1 -1
  12. package/dist/commands/new-worktree.js +63 -44
  13. package/dist/commands/remove-project.js +1 -1
  14. package/dist/commands/resume.js +11 -8
  15. package/dist/commands/screenshare.js +14 -6
  16. package/dist/commands/screenshare.test.js +20 -0
  17. package/dist/commands/session.js +1 -1
  18. package/dist/commands/undo-redo.js +91 -7
  19. package/dist/commands/user-command.js +1 -1
  20. package/dist/config.js +16 -1
  21. package/dist/database.js +53 -2
  22. package/dist/db.js +6 -0
  23. package/dist/discord-bot.js +48 -85
  24. package/dist/discord-command-registration.js +1 -1
  25. package/dist/external-opencode-sync.js +515 -0
  26. package/dist/external-opencode-sync.test.js +151 -0
  27. package/dist/gateway-proxy.e2e.test.js +8 -5
  28. package/dist/genai.js +1 -1
  29. package/dist/generated/enums.js +4 -0
  30. package/dist/generated/internal/class.js +4 -4
  31. package/dist/generated/internal/prismaNamespace.js +1 -0
  32. package/dist/generated/internal/prismaNamespaceBrowser.js +1 -0
  33. package/dist/generated/models/external_session_pending_prompts.js +1 -0
  34. package/dist/hrana-server.js +14 -285
  35. package/dist/hrana-server.test.js +4 -2
  36. package/dist/kimaki-opencode-plugin-loading.e2e.test.js +7 -0
  37. package/dist/kimaki-opencode-plugin.js +2 -0
  38. package/dist/kitty-graphics-parser.js +3 -0
  39. package/dist/kitty-graphics-parser.test.js +276 -0
  40. package/dist/kitty-graphics-plugin.js +3 -0
  41. package/dist/markdown.js +4 -4
  42. package/dist/markdown.test.js +1 -1
  43. package/dist/message-formatting.js +54 -15
  44. package/dist/onboarding-tutorial.js +1 -1
  45. package/dist/openai-realtime.js +9 -13
  46. package/dist/opencode.js +28 -5
  47. package/dist/queue-advanced-e2e-setup.js +89 -0
  48. package/dist/queue-advanced-permissions-typing.e2e.test.js +5 -5
  49. package/dist/queue-advanced-typing.e2e.test.js +9 -22
  50. package/dist/queue-question-select-drain.e2e.test.js +117 -0
  51. package/dist/session-handler/event-stream-state.js +101 -7
  52. package/dist/session-handler/event-stream-state.test.js +7 -3
  53. package/dist/session-handler/thread-session-runtime.js +120 -9
  54. package/dist/store.js +1 -0
  55. package/dist/system-message.js +22 -4
  56. package/dist/system-message.test.js +19 -0
  57. package/dist/task-runner.js +1 -1
  58. package/dist/thread-message-queue.e2e.test.js +8 -14
  59. package/dist/tools.js +1 -1
  60. package/dist/undo-redo.e2e.test.js +20 -25
  61. package/package.json +10 -6
  62. package/schema.prisma +6 -0
  63. package/skills/errore/SKILL.md +40 -13
  64. package/skills/goke/SKILL.md +12 -0
  65. package/skills/lintcn/SKILL.md +868 -0
  66. package/skills/npm-package/SKILL.md +1 -0
  67. package/skills/proxyman/SKILL.md +215 -0
  68. package/skills/spiceflow/SKILL.md +1 -1
  69. package/skills/usecomputer/SKILL.md +339 -0
  70. package/src/ai-tool-to-genai.ts +1 -0
  71. package/src/anthropic-auth-plugin.ts +7 -0
  72. package/src/cli.ts +59 -6
  73. package/src/commands/abort.ts +6 -16
  74. package/src/commands/action-buttons.ts +5 -1
  75. package/src/commands/add-project.ts +1 -1
  76. package/src/commands/ask-question.ts +5 -2
  77. package/src/commands/context-usage.ts +1 -1
  78. package/src/commands/create-new-project.ts +1 -1
  79. package/src/commands/fork.ts +12 -11
  80. package/src/commands/merge-worktree.ts +1 -1
  81. package/src/commands/new-worktree.ts +74 -55
  82. package/src/commands/remove-project.ts +1 -1
  83. package/src/commands/resume.ts +12 -10
  84. package/src/commands/screenshare.test.ts +30 -0
  85. package/src/commands/screenshare.ts +18 -6
  86. package/src/commands/session.ts +1 -1
  87. package/src/commands/undo-redo.ts +108 -10
  88. package/src/commands/user-command.ts +1 -1
  89. package/src/config.ts +19 -1
  90. package/src/database.ts +72 -3
  91. package/src/db.ts +8 -0
  92. package/src/discord-bot.ts +58 -93
  93. package/src/discord-command-registration.ts +1 -1
  94. package/src/external-opencode-sync.ts +729 -0
  95. package/src/gateway-proxy.e2e.test.ts +9 -5
  96. package/src/genai.ts +3 -3
  97. package/src/generated/commonInputTypes.ts +34 -0
  98. package/src/generated/enums.ts +8 -0
  99. package/src/generated/internal/class.ts +4 -4
  100. package/src/generated/internal/prismaNamespace.ts +8 -0
  101. package/src/generated/internal/prismaNamespaceBrowser.ts +1 -0
  102. package/src/generated/models/thread_sessions.ts +53 -1
  103. package/src/hrana-server.test.ts +8 -2
  104. package/src/hrana-server.ts +18 -390
  105. package/src/kimaki-opencode-plugin-loading.e2e.test.ts +7 -0
  106. package/src/kimaki-opencode-plugin.ts +2 -0
  107. package/src/markdown.test.ts +1 -1
  108. package/src/markdown.ts +4 -4
  109. package/src/message-formatting.ts +66 -17
  110. package/src/onboarding-tutorial.ts +1 -1
  111. package/src/openai-realtime.ts +6 -10
  112. package/src/opencode.ts +31 -7
  113. package/src/queue-advanced-e2e-setup.ts +92 -0
  114. package/src/queue-advanced-permissions-typing.e2e.test.ts +5 -5
  115. package/src/queue-advanced-typing.e2e.test.ts +9 -22
  116. package/src/queue-question-select-drain.e2e.test.ts +149 -0
  117. package/src/schema.sql +1 -0
  118. package/src/session-handler/event-stream-state.test.ts +7 -2
  119. package/src/session-handler/event-stream-state.ts +128 -7
  120. package/src/session-handler/thread-runtime-state.ts +5 -0
  121. package/src/session-handler/thread-session-runtime.ts +153 -11
  122. package/src/store.ts +8 -0
  123. package/src/system-message.ts +27 -4
  124. package/src/task-runner.ts +1 -1
  125. package/src/thread-message-queue.e2e.test.ts +8 -14
  126. package/src/tools.ts +1 -1
  127. package/src/undo-redo.e2e.test.ts +28 -26
  128. package/skills/jitter/node_modules/.bin/esbuild +0 -21
  129. package/skills/jitter/node_modules/.bin/tsc +0 -21
  130. package/skills/jitter/node_modules/.bin/tsserver +0 -21
  131. package/skills/jitter/node_modules/typescript/LICENSE.txt +0 -55
  132. package/skills/jitter/node_modules/typescript/README.md +0 -50
  133. package/skills/jitter/node_modules/typescript/SECURITY.md +0 -41
  134. package/skills/jitter/node_modules/typescript/ThirdPartyNoticeText.txt +0 -193
  135. package/skills/jitter/node_modules/typescript/bin/tsc +0 -2
  136. package/skills/jitter/node_modules/typescript/bin/tsserver +0 -2
  137. package/skills/jitter/node_modules/typescript/lib/_tsc.js +0 -133792
  138. package/skills/jitter/node_modules/typescript/lib/_tsserver.js +0 -659
  139. package/skills/jitter/node_modules/typescript/lib/_typingsInstaller.js +0 -222
  140. package/skills/jitter/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +0 -2122
  141. package/skills/jitter/node_modules/typescript/lib/de/diagnosticMessages.generated.json +0 -2122
  142. package/skills/jitter/node_modules/typescript/lib/es/diagnosticMessages.generated.json +0 -2122
  143. package/skills/jitter/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +0 -2122
  144. package/skills/jitter/node_modules/typescript/lib/it/diagnosticMessages.generated.json +0 -2122
  145. package/skills/jitter/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +0 -2122
  146. package/skills/jitter/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +0 -2122
  147. package/skills/jitter/node_modules/typescript/lib/lib.d.ts +0 -22
  148. package/skills/jitter/node_modules/typescript/lib/lib.decorators.d.ts +0 -384
  149. package/skills/jitter/node_modules/typescript/lib/lib.decorators.legacy.d.ts +0 -22
  150. package/skills/jitter/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +0 -41
  151. package/skills/jitter/node_modules/typescript/lib/lib.dom.d.ts +0 -39429
  152. package/skills/jitter/node_modules/typescript/lib/lib.dom.iterable.d.ts +0 -571
  153. package/skills/jitter/node_modules/typescript/lib/lib.es2015.collection.d.ts +0 -147
  154. package/skills/jitter/node_modules/typescript/lib/lib.es2015.core.d.ts +0 -597
  155. package/skills/jitter/node_modules/typescript/lib/lib.es2015.d.ts +0 -28
  156. package/skills/jitter/node_modules/typescript/lib/lib.es2015.generator.d.ts +0 -77
  157. package/skills/jitter/node_modules/typescript/lib/lib.es2015.iterable.d.ts +0 -605
  158. package/skills/jitter/node_modules/typescript/lib/lib.es2015.promise.d.ts +0 -81
  159. package/skills/jitter/node_modules/typescript/lib/lib.es2015.proxy.d.ts +0 -128
  160. package/skills/jitter/node_modules/typescript/lib/lib.es2015.reflect.d.ts +0 -144
  161. package/skills/jitter/node_modules/typescript/lib/lib.es2015.symbol.d.ts +0 -46
  162. package/skills/jitter/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +0 -326
  163. package/skills/jitter/node_modules/typescript/lib/lib.es2016.array.include.d.ts +0 -116
  164. package/skills/jitter/node_modules/typescript/lib/lib.es2016.d.ts +0 -21
  165. package/skills/jitter/node_modules/typescript/lib/lib.es2016.full.d.ts +0 -23
  166. package/skills/jitter/node_modules/typescript/lib/lib.es2016.intl.d.ts +0 -31
  167. package/skills/jitter/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +0 -21
  168. package/skills/jitter/node_modules/typescript/lib/lib.es2017.d.ts +0 -26
  169. package/skills/jitter/node_modules/typescript/lib/lib.es2017.date.d.ts +0 -31
  170. package/skills/jitter/node_modules/typescript/lib/lib.es2017.full.d.ts +0 -23
  171. package/skills/jitter/node_modules/typescript/lib/lib.es2017.intl.d.ts +0 -44
  172. package/skills/jitter/node_modules/typescript/lib/lib.es2017.object.d.ts +0 -49
  173. package/skills/jitter/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +0 -135
  174. package/skills/jitter/node_modules/typescript/lib/lib.es2017.string.d.ts +0 -45
  175. package/skills/jitter/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +0 -53
  176. package/skills/jitter/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +0 -77
  177. package/skills/jitter/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +0 -53
  178. package/skills/jitter/node_modules/typescript/lib/lib.es2018.d.ts +0 -24
  179. package/skills/jitter/node_modules/typescript/lib/lib.es2018.full.d.ts +0 -24
  180. package/skills/jitter/node_modules/typescript/lib/lib.es2018.intl.d.ts +0 -83
  181. package/skills/jitter/node_modules/typescript/lib/lib.es2018.promise.d.ts +0 -30
  182. package/skills/jitter/node_modules/typescript/lib/lib.es2018.regexp.d.ts +0 -37
  183. package/skills/jitter/node_modules/typescript/lib/lib.es2019.array.d.ts +0 -79
  184. package/skills/jitter/node_modules/typescript/lib/lib.es2019.d.ts +0 -24
  185. package/skills/jitter/node_modules/typescript/lib/lib.es2019.full.d.ts +0 -24
  186. package/skills/jitter/node_modules/typescript/lib/lib.es2019.intl.d.ts +0 -23
  187. package/skills/jitter/node_modules/typescript/lib/lib.es2019.object.d.ts +0 -33
  188. package/skills/jitter/node_modules/typescript/lib/lib.es2019.string.d.ts +0 -37
  189. package/skills/jitter/node_modules/typescript/lib/lib.es2019.symbol.d.ts +0 -24
  190. package/skills/jitter/node_modules/typescript/lib/lib.es2020.bigint.d.ts +0 -765
  191. package/skills/jitter/node_modules/typescript/lib/lib.es2020.d.ts +0 -27
  192. package/skills/jitter/node_modules/typescript/lib/lib.es2020.date.d.ts +0 -42
  193. package/skills/jitter/node_modules/typescript/lib/lib.es2020.full.d.ts +0 -24
  194. package/skills/jitter/node_modules/typescript/lib/lib.es2020.intl.d.ts +0 -474
  195. package/skills/jitter/node_modules/typescript/lib/lib.es2020.number.d.ts +0 -28
  196. package/skills/jitter/node_modules/typescript/lib/lib.es2020.promise.d.ts +0 -47
  197. package/skills/jitter/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +0 -99
  198. package/skills/jitter/node_modules/typescript/lib/lib.es2020.string.d.ts +0 -44
  199. package/skills/jitter/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +0 -41
  200. package/skills/jitter/node_modules/typescript/lib/lib.es2021.d.ts +0 -23
  201. package/skills/jitter/node_modules/typescript/lib/lib.es2021.full.d.ts +0 -24
  202. package/skills/jitter/node_modules/typescript/lib/lib.es2021.intl.d.ts +0 -166
  203. package/skills/jitter/node_modules/typescript/lib/lib.es2021.promise.d.ts +0 -48
  204. package/skills/jitter/node_modules/typescript/lib/lib.es2021.string.d.ts +0 -33
  205. package/skills/jitter/node_modules/typescript/lib/lib.es2021.weakref.d.ts +0 -78
  206. package/skills/jitter/node_modules/typescript/lib/lib.es2022.array.d.ts +0 -121
  207. package/skills/jitter/node_modules/typescript/lib/lib.es2022.d.ts +0 -25
  208. package/skills/jitter/node_modules/typescript/lib/lib.es2022.error.d.ts +0 -75
  209. package/skills/jitter/node_modules/typescript/lib/lib.es2022.full.d.ts +0 -24
  210. package/skills/jitter/node_modules/typescript/lib/lib.es2022.intl.d.ts +0 -145
  211. package/skills/jitter/node_modules/typescript/lib/lib.es2022.object.d.ts +0 -26
  212. package/skills/jitter/node_modules/typescript/lib/lib.es2022.regexp.d.ts +0 -39
  213. package/skills/jitter/node_modules/typescript/lib/lib.es2022.string.d.ts +0 -25
  214. package/skills/jitter/node_modules/typescript/lib/lib.es2023.array.d.ts +0 -924
  215. package/skills/jitter/node_modules/typescript/lib/lib.es2023.collection.d.ts +0 -21
  216. package/skills/jitter/node_modules/typescript/lib/lib.es2023.d.ts +0 -22
  217. package/skills/jitter/node_modules/typescript/lib/lib.es2023.full.d.ts +0 -24
  218. package/skills/jitter/node_modules/typescript/lib/lib.es2023.intl.d.ts +0 -56
  219. package/skills/jitter/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +0 -65
  220. package/skills/jitter/node_modules/typescript/lib/lib.es2024.collection.d.ts +0 -29
  221. package/skills/jitter/node_modules/typescript/lib/lib.es2024.d.ts +0 -26
  222. package/skills/jitter/node_modules/typescript/lib/lib.es2024.full.d.ts +0 -24
  223. package/skills/jitter/node_modules/typescript/lib/lib.es2024.object.d.ts +0 -29
  224. package/skills/jitter/node_modules/typescript/lib/lib.es2024.promise.d.ts +0 -35
  225. package/skills/jitter/node_modules/typescript/lib/lib.es2024.regexp.d.ts +0 -25
  226. package/skills/jitter/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +0 -68
  227. package/skills/jitter/node_modules/typescript/lib/lib.es2024.string.d.ts +0 -29
  228. package/skills/jitter/node_modules/typescript/lib/lib.es5.d.ts +0 -4601
  229. package/skills/jitter/node_modules/typescript/lib/lib.es6.d.ts +0 -23
  230. package/skills/jitter/node_modules/typescript/lib/lib.esnext.array.d.ts +0 -35
  231. package/skills/jitter/node_modules/typescript/lib/lib.esnext.collection.d.ts +0 -96
  232. package/skills/jitter/node_modules/typescript/lib/lib.esnext.d.ts +0 -29
  233. package/skills/jitter/node_modules/typescript/lib/lib.esnext.decorators.d.ts +0 -28
  234. package/skills/jitter/node_modules/typescript/lib/lib.esnext.disposable.d.ts +0 -193
  235. package/skills/jitter/node_modules/typescript/lib/lib.esnext.error.d.ts +0 -24
  236. package/skills/jitter/node_modules/typescript/lib/lib.esnext.float16.d.ts +0 -443
  237. package/skills/jitter/node_modules/typescript/lib/lib.esnext.full.d.ts +0 -24
  238. package/skills/jitter/node_modules/typescript/lib/lib.esnext.intl.d.ts +0 -21
  239. package/skills/jitter/node_modules/typescript/lib/lib.esnext.iterator.d.ts +0 -148
  240. package/skills/jitter/node_modules/typescript/lib/lib.esnext.promise.d.ts +0 -34
  241. package/skills/jitter/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +0 -25
  242. package/skills/jitter/node_modules/typescript/lib/lib.scripthost.d.ts +0 -322
  243. package/skills/jitter/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +0 -41
  244. package/skills/jitter/node_modules/typescript/lib/lib.webworker.d.ts +0 -13150
  245. package/skills/jitter/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +0 -23
  246. package/skills/jitter/node_modules/typescript/lib/lib.webworker.iterable.d.ts +0 -340
  247. package/skills/jitter/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +0 -2122
  248. package/skills/jitter/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +0 -2122
  249. package/skills/jitter/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +0 -2122
  250. package/skills/jitter/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +0 -2122
  251. package/skills/jitter/node_modules/typescript/lib/tsc.js +0 -8
  252. package/skills/jitter/node_modules/typescript/lib/tsserver.js +0 -8
  253. package/skills/jitter/node_modules/typescript/lib/tsserverlibrary.d.ts +0 -17
  254. package/skills/jitter/node_modules/typescript/lib/tsserverlibrary.js +0 -21
  255. package/skills/jitter/node_modules/typescript/lib/typesMap.json +0 -497
  256. package/skills/jitter/node_modules/typescript/lib/typescript.d.ts +0 -11438
  257. package/skills/jitter/node_modules/typescript/lib/typescript.js +0 -200253
  258. package/skills/jitter/node_modules/typescript/lib/typingsInstaller.js +0 -8
  259. package/skills/jitter/node_modules/typescript/lib/watchGuard.js +0 -53
  260. package/skills/jitter/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +0 -2122
  261. package/skills/jitter/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +0 -2122
  262. package/skills/jitter/node_modules/typescript/node_modules/.bin/tsc +0 -21
  263. package/skills/jitter/node_modules/typescript/node_modules/.bin/tsserver +0 -21
  264. package/skills/jitter/node_modules/typescript/package.json +0 -120
@@ -7,21 +7,18 @@ import {
7
7
  closeDatabase,
8
8
  getThreadWorktree,
9
9
  getThreadSession,
10
- createPendingWorktree,
11
- setWorktreeReady,
12
- setWorktreeError,
13
10
  getChannelWorktreesEnabled,
14
11
  getChannelMentionMode,
15
12
  getChannelDirectory,
16
13
  getPrisma,
17
14
  cancelAllPendingIpcRequests,
15
+ deleteChannelDirectoryById,
18
16
  } from './database.js'
19
17
  import {
20
18
  stopOpencodeServer,
21
19
  } from './opencode.js'
22
- import { formatWorktreeName } from './commands/new-worktree.js'
20
+ import { formatWorktreeName, createWorktreeInBackground, worktreeCreatingMessage } from './commands/new-worktree.js'
23
21
  import { WORKTREE_PREFIX } from './commands/merge-worktree.js'
24
- import { createWorktreeWithSubmodules } from './worktrees.js'
25
22
  import {
26
23
  escapeBackticksInCodeBlocks,
27
24
  splitMarkdownForDiscord,
@@ -35,6 +32,7 @@ import {
35
32
  } from './discord-utils.js'
36
33
  import {
37
34
  getOpencodeSystemMessage,
35
+ isInjectedPromptMarker,
38
36
  type ThreadStartMarker,
39
37
  } from './system-message.js'
40
38
  import yaml from 'js-yaml'
@@ -78,6 +76,10 @@ import { markDiscordGatewayReady, stopHranaServer } from './hrana-server.js'
78
76
  import { notifyError } from './sentry.js'
79
77
  import { flushDebouncedProcessCallbacks } from './debounced-process-flush.js'
80
78
  import { startRuntimeIdleSweeper } from './runtime-idle-sweeper.js'
79
+ import {
80
+ startExternalOpencodeSessionSync,
81
+ stopExternalOpencodeSessionSync,
82
+ } from './external-opencode-sync.js'
81
83
 
82
84
  export {
83
85
  initDatabase,
@@ -283,6 +285,7 @@ export async function startDiscordBot({
283
285
 
284
286
  registerInteractionHandler({ discordClient: c, appId: currentAppId })
285
287
  registerVoiceStateHandler({ discordClient: c, appId: currentAppId })
288
+ startExternalOpencodeSessionSync({ discordClient: c })
286
289
 
287
290
  // Channel logging is informational only; do it in background so startup stays responsive.
288
291
  void (async () => {
@@ -396,7 +399,7 @@ export async function startDiscordBot({
396
399
  footer: message.embeds[0]?.footer?.text,
397
400
  })
398
401
  const isCliInjectedPrompt = Boolean(
399
- isSelfBotMessage && promptMarker?.cliThreadPrompt,
402
+ isSelfBotMessage && isInjectedPromptMarker({ marker: promptMarker }),
400
403
  )
401
404
  const sessionStartSource = isCliInjectedPrompt
402
405
  ? parseSessionStartSourceFromMarker(promptMarker)
@@ -604,8 +607,8 @@ export async function startDiscordBot({
604
607
  return
605
608
  }
606
609
 
607
- // Capture narrowed non-undefined value for use in the preprocess closure
608
610
  const resolvedProjectDir = projectDirectory
611
+
609
612
  const sdkDir =
610
613
  worktreeInfo?.status === 'ready' &&
611
614
  worktreeInfo.worktree_directory
@@ -629,7 +632,9 @@ export async function startDiscordBot({
629
632
  cancelHtmlActionsForThread(thread.id)
630
633
  const dismissedPermission = await cancelPendingPermission(thread.id)
631
634
  if (dismissedPermission) {
632
- runtime.abortActiveRun('user sent a new message while permission was pending')
635
+ await runtime.abortActiveRunAndWait({
636
+ reason: 'user sent a new message while permission was pending',
637
+ })
633
638
  }
634
639
  const questionResult = await cancelPendingQuestion(thread.id, message.content)
635
640
  void cancelPendingFileUpload(thread.id)
@@ -649,6 +654,8 @@ export async function startDiscordBot({
649
654
  cliInjectedUsername ||
650
655
  message.member?.displayName ||
651
656
  message.author.displayName,
657
+ sourceMessageId: message.id,
658
+ sourceThreadId: thread.id,
652
659
  appId: currentAppId,
653
660
  agent: cliInjectedAgent,
654
661
  model: cliInjectedModel,
@@ -777,45 +784,23 @@ export async function startDiscordBot({
777
784
  )
778
785
  discordLogger.log(`[WORKTREE] Creating worktree: ${worktreeName}`)
779
786
 
780
- // Store pending worktree immediately so bot knows about it
781
- await createPendingWorktree({
782
- threadId: thread.id,
787
+ const worktreeStatusMessage = await thread
788
+ .send({
789
+ content: worktreeCreatingMessage(worktreeName),
790
+ flags: SILENT_MESSAGE_FLAGS,
791
+ })
792
+ .catch(() => undefined)
793
+
794
+ const result = await createWorktreeInBackground({
795
+ thread,
796
+ starterMessage: worktreeStatusMessage,
783
797
  worktreeName,
784
798
  projectDirectory,
799
+ rest: discordClient.rest,
785
800
  })
786
801
 
787
- const worktreeResult = await createWorktreeWithSubmodules({
788
- directory: projectDirectory,
789
- name: worktreeName,
790
- })
791
-
792
- if (worktreeResult instanceof Error) {
793
- const errMsg = worktreeResult.message
794
- discordLogger.error(`[WORKTREE] Creation failed: ${errMsg}`)
795
- await setWorktreeError({
796
- threadId: thread.id,
797
- errorMessage: errMsg,
798
- })
799
- await thread.send({
800
- content: `āš ļø Failed to create worktree: ${errMsg}\nUsing main project directory instead.`,
801
- flags: NOTIFY_MESSAGE_FLAGS,
802
- })
803
- } else {
804
- await setWorktreeReady({
805
- threadId: thread.id,
806
- worktreeDirectory: worktreeResult.directory,
807
- })
808
- sessionDirectory = worktreeResult.directory
809
- discordLogger.log(
810
- `[WORKTREE] Created: ${worktreeResult.directory} (branch: ${worktreeResult.branch})`,
811
- )
812
- // React with tree emoji to mark as worktree thread
813
- await reactToThread({
814
- rest: discordClient.rest,
815
- threadId: thread.id,
816
- channelId: thread.parentId || undefined,
817
- emoji: '🌳',
818
- })
802
+ if (!(result instanceof Error)) {
803
+ sessionDirectory = result
819
804
  }
820
805
  }
821
806
 
@@ -832,6 +817,8 @@ export async function startDiscordBot({
832
817
  userId: message.author.id,
833
818
  username:
834
819
  message.member?.displayName || message.author.displayName,
820
+ sourceMessageId: message.id,
821
+ sourceThreadId: thread.id,
835
822
  appId: currentAppId,
836
823
  preprocess: () => {
837
824
  return preprocessNewThreadMessage({
@@ -961,66 +948,24 @@ export async function startDiscordBot({
961
948
 
962
949
  const worktreeStatusMessage = await thread
963
950
  .send({
964
- content: `🌳 Creating worktree: ${marker.worktree}\nā³ Setting up (this can take a bit)...`,
951
+ content: worktreeCreatingMessage(marker.worktree),
965
952
  flags: SILENT_MESSAGE_FLAGS,
966
953
  })
967
- .catch(() => {
968
- return null
969
- })
954
+ .catch(() => undefined)
970
955
 
971
- await createPendingWorktree({
972
- threadId: thread.id,
956
+ const result = await createWorktreeInBackground({
957
+ thread,
958
+ starterMessage: worktreeStatusMessage,
973
959
  worktreeName: marker.worktree,
974
960
  projectDirectory,
961
+ rest: discordClient.rest,
975
962
  })
976
963
 
977
- const worktreeResult = await createWorktreeWithSubmodules({
978
- directory: projectDirectory,
979
- name: marker.worktree,
980
- })
981
-
982
- if (errore.isError(worktreeResult)) {
983
- discordLogger.error(
984
- `[BOT_SESSION] Worktree creation failed: ${worktreeResult.message}`,
985
- )
986
- await setWorktreeError({
987
- threadId: thread.id,
988
- errorMessage: worktreeResult.message,
989
- })
990
- await (worktreeStatusMessage?.edit({
991
- content: `āš ļø Failed to create worktree: ${worktreeResult.message}\nUsing main project directory instead.`,
992
- flags: NOTIFY_MESSAGE_FLAGS,
993
- }) ||
994
- thread.send({
995
- content: `āš ļø Failed to create worktree: ${worktreeResult.message}\nUsing main project directory instead.`,
996
- flags: NOTIFY_MESSAGE_FLAGS,
997
- }))
964
+ if (result instanceof Error) {
998
965
  return projectDirectory
999
966
  }
1000
967
 
1001
- await setWorktreeReady({
1002
- threadId: thread.id,
1003
- worktreeDirectory: worktreeResult.directory,
1004
- })
1005
- discordLogger.log(
1006
- `[BOT_SESSION] Worktree created: ${worktreeResult.directory}`,
1007
- )
1008
- // React with tree emoji to mark as worktree thread
1009
- await reactToThread({
1010
- rest: discordClient.rest,
1011
- threadId: thread.id,
1012
- channelId: thread.parentId || undefined,
1013
- emoji: '🌳',
1014
- })
1015
- await (worktreeStatusMessage?.edit({
1016
- content: `🌳 **Worktree ready: ${marker.worktree}**\nšŸ“ \`${worktreeResult.directory}\`\n🌿 Branch: \`${worktreeResult.branch}\``,
1017
- flags: SILENT_MESSAGE_FLAGS,
1018
- }) ||
1019
- thread.send({
1020
- content: `🌳 **Worktree ready: ${marker.worktree}**\nšŸ“ \`${worktreeResult.directory}\`\n🌿 Branch: \`${worktreeResult.branch}\``,
1021
- flags: SILENT_MESSAGE_FLAGS,
1022
- }))
1023
- return worktreeResult.directory
968
+ return result
1024
969
  })()
1025
970
 
1026
971
  discordLogger.log(
@@ -1082,6 +1027,25 @@ export async function startDiscordBot({
1082
1027
  disposeRuntime(thread.id)
1083
1028
  })
1084
1029
 
1030
+ // Clean up SQLite when a Discord channel is deleted so project list
1031
+ // doesn't show stale ghost entries. Thread runtimes inside the deleted
1032
+ // channel are disposed by their own ThreadDelete events from Discord.
1033
+ discordClient.on(Events.ChannelDelete, async (channel) => {
1034
+ try {
1035
+ const deleted = await deleteChannelDirectoryById(channel.id)
1036
+ if (deleted) {
1037
+ discordLogger.log(
1038
+ `Cleaned up channel_directories for deleted channel ${channel.id}`,
1039
+ )
1040
+ }
1041
+ } catch (error) {
1042
+ notifyError(
1043
+ error instanceof Error ? error : new Error(String(error)),
1044
+ `Failed to clean up channel_directories for deleted channel ${channel.id}`,
1045
+ )
1046
+ }
1047
+ })
1048
+
1085
1049
  // Skip login if the caller already connected the client (e.g. cli.ts logs in
1086
1050
  // before calling startDiscordBot). Calling login() again destroys the existing
1087
1051
  // WebSocket (close code 1000) and triggers a spurious ShardReconnecting event.
@@ -1138,6 +1102,7 @@ export async function startDiscordBot({
1138
1102
  }
1139
1103
 
1140
1104
  voiceLogger.log('[SHUTDOWN] Stopping OpenCode server')
1105
+ stopExternalOpencodeSessionSync()
1141
1106
  await stopOpencodeServer()
1142
1107
 
1143
1108
  discordLogger.log('Closing database...')
@@ -484,7 +484,7 @@ export async function registerCommands({
484
484
  .toJSON(),
485
485
  new SlashCommandBuilder()
486
486
  .setName('screenshare')
487
- .setDescription(truncateCommandDescription('Start screen sharing via VNC tunnel (auto-stops after 1 hour)'))
487
+ .setDescription(truncateCommandDescription('Start screen sharing via VNC tunnel (auto-stops after 30 minutes)'))
488
488
  .setDMPermission(false)
489
489
  .toJSON(),
490
490
  new SlashCommandBuilder()