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
@@ -13,8 +13,10 @@
13
13
  // Uses opencode-deterministic-provider (no real LLM calls).
14
14
  // Poll timeouts: 4s max, 100ms interval.
15
15
  import { describe, test, expect } from 'vitest';
16
+ import fs from 'node:fs';
17
+ import path from 'node:path';
16
18
  import { setupQueueAdvancedSuite, TEST_USER_ID, } from './queue-advanced-e2e-setup.js';
17
- import { waitForFooterMessage } from './test-utils.js';
19
+ import { waitForBotMessageContaining, waitForFooterMessage, } from './test-utils.js';
18
20
  import { getThreadSession } from './database.js';
19
21
  import { initializeOpencodeForDirectory } from './opencode.js';
20
22
  const TEXT_CHANNEL_ID = '200000000000001200';
@@ -27,27 +29,28 @@ e2eTest('/undo sets revert state and cleans up on next prompt', () => {
27
29
  username: 'undo-tester',
28
30
  });
29
31
  test('undo sets revert state, next message cleans up reverted messages', async () => {
32
+ const markerPath = path.join(ctx.directories.projectDirectory, 'tmp', 'undo-marker.txt');
30
33
  // 1. Send a message and wait for complete session (footer)
31
34
  await ctx.discord
32
35
  .channel(TEXT_CHANNEL_ID)
33
36
  .user(TEST_USER_ID)
34
37
  .sendMessage({
35
- content: 'Reply with exactly: undo-test-message',
38
+ content: 'UNDO_FILE_MARKER',
36
39
  });
37
40
  const thread = await ctx.discord
38
41
  .channel(TEXT_CHANNEL_ID)
39
42
  .waitForThread({
40
- timeout: 4_000,
43
+ timeout: 8_000,
41
44
  predicate: (t) => {
42
- return t.name === 'Reply with exactly: undo-test-message';
45
+ return t.name === 'UNDO_FILE_MARKER';
43
46
  },
44
47
  });
45
48
  const th = ctx.discord.thread(thread.id);
46
- await th.waitForBotReply({ timeout: 4_000 });
49
+ await th.waitForBotReply({ timeout: 8_000 });
47
50
  await waitForFooterMessage({
48
51
  discord: ctx.discord,
49
52
  threadId: thread.id,
50
- timeout: 4_000,
53
+ timeout: 8_000,
51
54
  });
52
55
  // 2. Get session ID and verify it has messages
53
56
  const sessionId = await getThreadSession(thread.id);
@@ -70,6 +73,7 @@ e2eTest('/undo sets revert state and cleans up on next prompt', () => {
70
73
  });
71
74
  expect(beforeUserMessages.length).toBeGreaterThan(0);
72
75
  expect(beforeAssistantMessages.length).toBeGreaterThan(0);
76
+ expect(fs.existsSync(markerPath)).toBe(true);
73
77
  // Verify no revert state yet
74
78
  const beforeSession = await getClient().session.get({
75
79
  sessionID: sessionId,
@@ -84,22 +88,12 @@ e2eTest('/undo sets revert state and cleans up on next prompt', () => {
84
88
  timeout: 4_000,
85
89
  });
86
90
  expect(undoAck).toBeDefined();
87
- // Wait for the undo reply to appear (deferred reply gets edited)
88
- if (undoAck.messageId) {
89
- const start = Date.now();
90
- while (Date.now() - start < 4_000) {
91
- const messages = await th.getMessages();
92
- const undoMessage = messages.find((m) => {
93
- return m.id === undoAck.messageId;
94
- });
95
- if (undoMessage && undoMessage.content.length > 0) {
96
- break;
97
- }
98
- await new Promise((r) => {
99
- setTimeout(r, 100);
100
- });
101
- }
102
- }
91
+ await waitForBotMessageContaining({
92
+ discord: ctx.discord,
93
+ threadId: thread.id,
94
+ text: 'Undone - reverted last assistant message',
95
+ timeout: 8_000,
96
+ });
103
97
  // 4. Verify session now has revert state set
104
98
  const afterSession = await getClient().session.get({
105
99
  sessionID: sessionId,
@@ -120,7 +114,7 @@ e2eTest('/undo sets revert state and cleans up on next prompt', () => {
120
114
  await waitForFooterMessage({
121
115
  discord: ctx.discord,
122
116
  threadId: thread.id,
123
- timeout: 4_000,
117
+ timeout: 8_000,
124
118
  afterMessageIncludes: 'after-undo-message',
125
119
  });
126
120
  // 6. Verify reverted messages were cleaned up
@@ -151,9 +145,10 @@ e2eTest('/undo sets revert state and cleans up on next prompt', () => {
151
145
  // 7. Snapshot the Discord thread
152
146
  expect(await th.text()).toMatchInlineSnapshot(`
153
147
  "--- from: user (undo-tester)
154
- Reply with exactly: undo-test-message
148
+ UNDO_FILE_MARKER
155
149
  --- from: assistant (TestBot)
156
- ok
150
+ creating undo file
151
+ ⬥ undo file created
157
152
  *project ⋅ main ⋅ Ns ⋅ N% ⋅ deterministic-v2*
158
153
  Undone - reverted last assistant message
159
154
  --- from: user (undo-tester)
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "kimaki",
3
3
  "module": "index.ts",
4
4
  "type": "module",
5
- "version": "0.4.82",
5
+ "version": "0.4.84",
6
6
  "repository": "https://github.com/remorses/kimaki",
7
7
  "bin": "bin.js",
8
8
  "files": [
@@ -24,18 +24,18 @@
24
24
  "lintcn": "^0.3.0",
25
25
  "prisma": "7.4.2",
26
26
  "tsx": "^4.20.5",
27
+ "discord-digital-twin": "^0.1.0",
27
28
  "opencode-cached-provider": "^0.0.1",
28
- "db": "^0.0.0",
29
29
  "opencode-deterministic-provider": "^0.0.1",
30
- "discord-digital-twin": "^0.1.0"
30
+ "db": "^0.0.0"
31
31
  },
32
32
  "dependencies": {
33
- "@ai-sdk/google": "^3.0.30",
33
+ "@ai-sdk/google": "^3.0.53",
34
34
  "@ai-sdk/openai": "^3.0.31",
35
35
  "@ai-sdk/provider": "^3.0.8",
36
36
  "@clack/prompts": "^1.0.0",
37
37
  "@discordjs/voice": "^0.19.0",
38
- "@google/genai": "^1.34.0",
38
+ "@google/genai": "^1.46.0",
39
39
  "@libsql/client": "^0.15.15",
40
40
  "@openauthjs/openauth": "^0.4.3",
41
41
  "@opencode-ai/plugin": "^1.2.27",
@@ -52,9 +52,11 @@
52
52
  "goke": "^6.3.0",
53
53
  "htmlparser2": "^10.0.0",
54
54
  "js-yaml": "^4.1.0",
55
+ "kitty-graphics-agent": "^0.0.5",
55
56
  "libsql": "^0.5.22",
56
57
  "marked": "^16.3.0",
57
58
  "mime": "^4.1.0",
59
+ "opusscript": "^0.1.1",
58
60
  "picocolors": "^1.1.1",
59
61
  "pretty-ms": "^9.3.0",
60
62
  "proper-lockfile": "^4.1.2",
@@ -65,7 +67,8 @@
65
67
  "zod": "^4.3.6",
66
68
  "zustand": "^5.0.11",
67
69
  "errore": "^0.14.1",
68
- "traforo": "^0.1.0"
70
+ "libsqlproxy": "^0.1.0",
71
+ "traforo": "^0.2.0"
69
72
  },
70
73
  "optionalDependencies": {
71
74
  "@discordjs/opus": "^0.10.0",
@@ -76,6 +79,7 @@
76
79
  },
77
80
  "scripts": {
78
81
  "dev": "tsx src/cli.ts",
82
+ "build": "pnpm generate && pnpm tsc",
79
83
  "dev:bun": "DEBUG=1 bun --env-file .env src/cli.ts",
80
84
  "watch": "tsx scripts/watch-session.ts",
81
85
  "generate": "prisma generate && pnpm generate:sql",
package/schema.prisma CHANGED
@@ -14,6 +14,7 @@ datasource db {
14
14
  model thread_sessions {
15
15
  thread_id String @id
16
16
  session_id String
17
+ source ThreadSessionSource @default(kimaki)
17
18
  created_at DateTime? @default(now())
18
19
 
19
20
  part_messages part_messages[]
@@ -23,6 +24,11 @@ model thread_sessions {
23
24
  ipc_requests ipc_requests[]
24
25
  }
25
26
 
27
+ enum ThreadSessionSource {
28
+ kimaki
29
+ external_poll
30
+ }
31
+
26
32
  model session_events {
27
33
  id Int @id @default(autoincrement())
28
34
  session_id String
@@ -432,11 +432,11 @@ return res.status(response.status).json(response.body)
432
432
 
433
433
  > `matchError` routes by `_tag` and requires an `Error` fallback for plain Error instances. Use `matchErrorPartial` when you only need to handle some cases.
434
434
 
435
- ### Resource Cleanup (defer)
435
+ ### Resource Cleanup (defer) — Replacing try/finally with `using`
436
436
 
437
- errore ships `DisposableStack` and `AsyncDisposableStack` polyfills that work in every runtime. Use them with TypeScript's `using` / `await using` for Go-like `defer` cleanup.
437
+ `try/finally` has a structural problem: **every resource adds a nesting level**. Two resources = two levels of indentation. The business logic gets buried deeper with each resource, and cleanup is split across `finally` blocks far from where the resource was acquired. `await using` + `DisposableStack` keeps the function flat — one `cleanup.defer()` per resource, same indentation whether you have one resource or ten. Cleanup runs automatically in reverse order on every exit path.
438
438
 
439
- **tsconfig requirement:** add `"ESNext.Disposable"` to `lib` so TypeScript knows about `Disposable`, `AsyncDisposable`, `using`, and `await using`:
439
+ **tsconfig requirement:** add `"ESNext.Disposable"` to `lib`:
440
440
 
441
441
  ```jsonc
442
442
  {
@@ -446,28 +446,51 @@ errore ships `DisposableStack` and `AsyncDisposableStack` polyfills that work in
446
446
  }
447
447
  ```
448
448
 
449
- Without this, `using`/`await using` declarations and `Symbol.dispose`/`Symbol.asyncDispose` will produce type errors. The errore polyfill handles the runtime side this setting handles the type side.
449
+ **Beforenested try/finally:**
450
450
 
451
451
  ```ts
452
- import * as errore from 'errore'
452
+ async function importData(url: string, dbUrl: string) {
453
+ const db = await connectDb(dbUrl)
454
+ try {
455
+ const tmpFile = await createTempFile()
456
+ try {
457
+ const data = await (await fetch(url)).text()
458
+ await tmpFile.write(data)
459
+ await db.import(tmpFile.path)
460
+ return { rows: await db.count() }
461
+ } finally {
462
+ await tmpFile.delete()
463
+ }
464
+ } finally {
465
+ await db.close()
466
+ }
467
+ }
468
+ ```
469
+
470
+ **After — flat with `await using`:**
453
471
 
454
- async function processRequest(id: string): Promise<DbError | Result> {
472
+ ```ts
473
+ async function importData(url: string, dbUrl: string): Promise<ImportError | { rows: number }> {
455
474
  await using cleanup = new errore.AsyncDisposableStack()
456
475
 
457
- const db = await connectDb().catch((e) => new DbError({ cause: e }))
476
+ const db = await connectDb(dbUrl).catch((e) => new ImportError({ reason: 'db connect', cause: e }))
458
477
  if (db instanceof Error) return db
459
478
  cleanup.defer(() => db.close())
460
479
 
461
- const cache = await openCache().catch((e) => new CacheError({ cause: e }))
462
- if (cache instanceof Error) return cache
463
- cleanup.defer(() => cache.flush())
480
+ const tmpFile = await createTempFile()
481
+ cleanup.defer(() => tmpFile.delete())
482
+
483
+ const response = await fetch(url).catch((e) => new ImportError({ reason: 'fetch', cause: e }))
484
+ if (response instanceof Error) return response
464
485
 
465
- return result
466
- // cleanup runs in LIFO order: cache.flush(), then db.close()
486
+ await tmpFile.write(await response.text())
487
+ await db.import(tmpFile.path)
488
+ return { rows: await db.count() }
489
+ // cleanup: tmpFile.delete() → db.close()
467
490
  }
468
491
  ```
469
492
 
470
- > `await using` guarantees cleanup runs when the scope exits whether by return, early error return, or thrown exception. Resources are released in reverse order (LIFO), just like Go's `defer`. No `try/finally` nesting.
493
+ > `await using` guarantees cleanup on every exit pathnormal return, early error return, or exception. Resources release in LIFO order. Adding a resource is one line (`cleanup.defer()`), not another nesting level. The errore polyfill handles the runtime; the tsconfig `lib` entry handles the types.
471
494
 
472
495
  ### Fallback Values
473
496
 
@@ -608,6 +631,10 @@ for (const item of items) {
608
631
 
609
632
  > Place `signal.aborted` checks **before** expensive operations (network, db writes, file I/O). Check `isAbortError` **after** async calls that received the signal. Both keep the function responsive to cancellation.
610
633
 
634
+ ## Linting
635
+
636
+ If the project uses [lintcn](https://github.com/remorses/lintcn), read `docs/lintcn.md` for the `no-unhandled-error` rule that catches discarded `Error | T` return values.
637
+
611
638
  ## Pitfalls
612
639
 
613
640
  ### CustomError | Error is ambiguous when CustomError extends Error
@@ -602,6 +602,18 @@ cli.version('1.0.0')
602
602
  cli.parse()
603
603
  ```
604
604
 
605
+ ## `openInBrowser(url)`
606
+
607
+ Opens a URL in the default browser. In non-TTY environments (CI, piped output, agents), prints the URL to stdout instead of opening a browser.
608
+
609
+ ```ts
610
+ import { openInBrowser } from 'goke'
611
+
612
+ openInBrowser('https://example.com/dashboard')
613
+ ```
614
+
615
+ Use this after generating URLs (OAuth callbacks, dashboards, docs links) so interactive users get a browser tab and non-interactive environments get a printable URL.
616
+
605
617
  ## Exposing your CLI as a skill
606
618
 
607
619
  When you build a CLI with goke, the optimal way to create a skill for it is a minimal SKILL.md that tells agents to run `--help` before using the CLI. This way descriptions, examples, and usage patterns live in the CLI code (collocated with the implementation) instead of a separate markdown file that can go stale.