@brianli/kimaki 0.4.72-brianli.1

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 (328) hide show
  1. package/bin.js +2 -0
  2. package/dist/ai-tool-to-genai.js +233 -0
  3. package/dist/ai-tool-to-genai.test.js +267 -0
  4. package/dist/ai-tool.js +6 -0
  5. package/dist/bin.js +87 -0
  6. package/dist/bot-token.js +121 -0
  7. package/dist/bot-token.test.js +134 -0
  8. package/dist/channel-management.js +101 -0
  9. package/dist/cli-parsing.test.js +89 -0
  10. package/dist/cli.js +2529 -0
  11. package/dist/commands/abort.js +82 -0
  12. package/dist/commands/action-buttons.js +257 -0
  13. package/dist/commands/add-project.js +114 -0
  14. package/dist/commands/agent.js +291 -0
  15. package/dist/commands/ask-question.js +223 -0
  16. package/dist/commands/compact.js +120 -0
  17. package/dist/commands/context-usage.js +140 -0
  18. package/dist/commands/create-new-project.js +118 -0
  19. package/dist/commands/diff.js +128 -0
  20. package/dist/commands/file-upload.js +275 -0
  21. package/dist/commands/fork.js +217 -0
  22. package/dist/commands/gemini-apikey.js +70 -0
  23. package/dist/commands/login.js +490 -0
  24. package/dist/commands/mention-mode.js +51 -0
  25. package/dist/commands/merge-worktree.js +124 -0
  26. package/dist/commands/model.js +694 -0
  27. package/dist/commands/permissions.js +163 -0
  28. package/dist/commands/queue.js +217 -0
  29. package/dist/commands/remove-project.js +115 -0
  30. package/dist/commands/restart-opencode-server.js +116 -0
  31. package/dist/commands/resume.js +159 -0
  32. package/dist/commands/run-command.js +79 -0
  33. package/dist/commands/session-id.js +78 -0
  34. package/dist/commands/session.js +192 -0
  35. package/dist/commands/share.js +80 -0
  36. package/dist/commands/types.js +2 -0
  37. package/dist/commands/undo-redo.js +159 -0
  38. package/dist/commands/unset-model.js +152 -0
  39. package/dist/commands/upgrade.js +42 -0
  40. package/dist/commands/user-command.js +148 -0
  41. package/dist/commands/verbosity.js +60 -0
  42. package/dist/commands/worktree-settings.js +50 -0
  43. package/dist/commands/worktree.js +299 -0
  44. package/dist/condense-memory.js +33 -0
  45. package/dist/config.js +110 -0
  46. package/dist/database.js +1050 -0
  47. package/dist/db.js +159 -0
  48. package/dist/db.test.js +49 -0
  49. package/dist/discord-api.js +28 -0
  50. package/dist/discord-auth.js +231 -0
  51. package/dist/discord-auth.test.js +80 -0
  52. package/dist/discord-bot.js +997 -0
  53. package/dist/discord-utils.js +560 -0
  54. package/dist/discord-utils.test.js +115 -0
  55. package/dist/errors.js +167 -0
  56. package/dist/escape-backticks.test.js +429 -0
  57. package/dist/format-tables.js +122 -0
  58. package/dist/format-tables.test.js +199 -0
  59. package/dist/forum-sync/config.js +79 -0
  60. package/dist/forum-sync/discord-operations.js +154 -0
  61. package/dist/forum-sync/index.js +5 -0
  62. package/dist/forum-sync/markdown.js +117 -0
  63. package/dist/forum-sync/sync-to-discord.js +417 -0
  64. package/dist/forum-sync/sync-to-files.js +190 -0
  65. package/dist/forum-sync/types.js +53 -0
  66. package/dist/forum-sync/watchers.js +307 -0
  67. package/dist/gateway-consumer.js +232 -0
  68. package/dist/gateway-consumer.test.js +18 -0
  69. package/dist/genai-worker-wrapper.js +111 -0
  70. package/dist/genai-worker.js +311 -0
  71. package/dist/genai.js +232 -0
  72. package/dist/generated/browser.js +17 -0
  73. package/dist/generated/client.js +35 -0
  74. package/dist/generated/commonInputTypes.js +10 -0
  75. package/dist/generated/enums.js +30 -0
  76. package/dist/generated/internal/class.js +41 -0
  77. package/dist/generated/internal/prismaNamespace.js +239 -0
  78. package/dist/generated/internal/prismaNamespaceBrowser.js +209 -0
  79. package/dist/generated/models/bot_api_keys.js +1 -0
  80. package/dist/generated/models/bot_tokens.js +1 -0
  81. package/dist/generated/models/channel_agents.js +1 -0
  82. package/dist/generated/models/channel_directories.js +1 -0
  83. package/dist/generated/models/channel_mention_mode.js +1 -0
  84. package/dist/generated/models/channel_models.js +1 -0
  85. package/dist/generated/models/channel_verbosity.js +1 -0
  86. package/dist/generated/models/channel_worktrees.js +1 -0
  87. package/dist/generated/models/forum_sync_configs.js +1 -0
  88. package/dist/generated/models/global_models.js +1 -0
  89. package/dist/generated/models/ipc_requests.js +1 -0
  90. package/dist/generated/models/part_messages.js +1 -0
  91. package/dist/generated/models/scheduled_tasks.js +1 -0
  92. package/dist/generated/models/session_agents.js +1 -0
  93. package/dist/generated/models/session_models.js +1 -0
  94. package/dist/generated/models/session_start_sources.js +1 -0
  95. package/dist/generated/models/thread_sessions.js +1 -0
  96. package/dist/generated/models/thread_worktrees.js +1 -0
  97. package/dist/generated/models.js +1 -0
  98. package/dist/heap-monitor.js +95 -0
  99. package/dist/hrana-server.js +416 -0
  100. package/dist/hrana-server.test.js +368 -0
  101. package/dist/image-utils.js +112 -0
  102. package/dist/interaction-handler.js +327 -0
  103. package/dist/ipc-polling.js +251 -0
  104. package/dist/kimaki-digital-twin.e2e.test.js +165 -0
  105. package/dist/limit-heading-depth.js +25 -0
  106. package/dist/limit-heading-depth.test.js +105 -0
  107. package/dist/logger.js +160 -0
  108. package/dist/markdown.js +342 -0
  109. package/dist/markdown.test.js +253 -0
  110. package/dist/message-formatting.js +433 -0
  111. package/dist/message-formatting.test.js +73 -0
  112. package/dist/openai-realtime.js +228 -0
  113. package/dist/opencode-plugin-loading.e2e.test.js +91 -0
  114. package/dist/opencode-plugin.js +536 -0
  115. package/dist/opencode-plugin.test.js +98 -0
  116. package/dist/opencode.js +409 -0
  117. package/dist/privacy-sanitizer.js +105 -0
  118. package/dist/runtime-mode.js +51 -0
  119. package/dist/runtime-mode.test.js +115 -0
  120. package/dist/sentry.js +127 -0
  121. package/dist/session-handler/state.js +151 -0
  122. package/dist/session-handler.js +1874 -0
  123. package/dist/session-search.js +100 -0
  124. package/dist/session-search.test.js +40 -0
  125. package/dist/startup-service.js +153 -0
  126. package/dist/system-message.js +499 -0
  127. package/dist/task-runner.js +282 -0
  128. package/dist/task-schedule.js +191 -0
  129. package/dist/task-schedule.test.js +71 -0
  130. package/dist/thinking-utils.js +35 -0
  131. package/dist/thread-message-queue.e2e.test.js +781 -0
  132. package/dist/tools.js +359 -0
  133. package/dist/unnest-code-blocks.js +136 -0
  134. package/dist/unnest-code-blocks.test.js +641 -0
  135. package/dist/upgrade.js +114 -0
  136. package/dist/utils.js +109 -0
  137. package/dist/voice-handler.js +606 -0
  138. package/dist/voice.js +304 -0
  139. package/dist/voice.test.js +187 -0
  140. package/dist/wait-session.js +94 -0
  141. package/dist/worker-types.js +4 -0
  142. package/dist/worktree-utils.js +727 -0
  143. package/dist/xml.js +92 -0
  144. package/dist/xml.test.js +32 -0
  145. package/package.json +82 -0
  146. package/schema.prisma +246 -0
  147. package/skills/batch/SKILL.md +87 -0
  148. package/skills/critique/SKILL.md +129 -0
  149. package/skills/errore/SKILL.md +589 -0
  150. package/skills/goke/.prettierrc +5 -0
  151. package/skills/goke/CHANGELOG.md +40 -0
  152. package/skills/goke/LICENSE +21 -0
  153. package/skills/goke/README.md +666 -0
  154. package/skills/goke/SKILL.md +458 -0
  155. package/skills/goke/package.json +43 -0
  156. package/skills/goke/src/__test__/coerce.test.ts +411 -0
  157. package/skills/goke/src/__test__/index.test.ts +1798 -0
  158. package/skills/goke/src/__test__/types.test-d.ts +111 -0
  159. package/skills/goke/src/coerce.ts +547 -0
  160. package/skills/goke/src/goke.ts +1362 -0
  161. package/skills/goke/src/index.ts +16 -0
  162. package/skills/goke/src/mri.ts +164 -0
  163. package/skills/goke/tsconfig.json +15 -0
  164. package/skills/jitter/EDITOR.md +219 -0
  165. package/skills/jitter/EXPORT-INTERNALS.md +309 -0
  166. package/skills/jitter/SKILL.md +158 -0
  167. package/skills/jitter/jitter-clipboard.json +1042 -0
  168. package/skills/jitter/package.json +14 -0
  169. package/skills/jitter/tsconfig.json +15 -0
  170. package/skills/jitter/utils/actions.ts +212 -0
  171. package/skills/jitter/utils/export.ts +114 -0
  172. package/skills/jitter/utils/index.ts +141 -0
  173. package/skills/jitter/utils/snapshot.ts +154 -0
  174. package/skills/jitter/utils/traverse.ts +246 -0
  175. package/skills/jitter/utils/types.ts +279 -0
  176. package/skills/jitter/utils/wait.ts +133 -0
  177. package/skills/playwriter/SKILL.md +31 -0
  178. package/skills/security-review/SKILL.md +208 -0
  179. package/skills/simplify/SKILL.md +58 -0
  180. package/skills/termcast/SKILL.md +945 -0
  181. package/skills/tuistory/SKILL.md +250 -0
  182. package/skills/zustand-centralized-state/SKILL.md +582 -0
  183. package/src/__snapshots__/compact-session-context-no-system.md +35 -0
  184. package/src/__snapshots__/compact-session-context.md +41 -0
  185. package/src/__snapshots__/first-session-no-info.md +17 -0
  186. package/src/__snapshots__/first-session-with-info.md +23 -0
  187. package/src/__snapshots__/session-1.md +17 -0
  188. package/src/__snapshots__/session-2.md +5871 -0
  189. package/src/__snapshots__/session-3.md +17 -0
  190. package/src/__snapshots__/session-with-tools.md +5871 -0
  191. package/src/ai-tool-to-genai.test.ts +296 -0
  192. package/src/ai-tool-to-genai.ts +282 -0
  193. package/src/ai-tool.ts +39 -0
  194. package/src/bin.ts +108 -0
  195. package/src/bot-token.test.ts +171 -0
  196. package/src/bot-token.ts +159 -0
  197. package/src/channel-management.ts +172 -0
  198. package/src/cli-parsing.test.ts +132 -0
  199. package/src/cli.ts +3605 -0
  200. package/src/commands/abort.ts +112 -0
  201. package/src/commands/action-buttons.ts +376 -0
  202. package/src/commands/add-project.ts +152 -0
  203. package/src/commands/agent.ts +404 -0
  204. package/src/commands/ask-question.ts +330 -0
  205. package/src/commands/compact.ts +157 -0
  206. package/src/commands/context-usage.ts +199 -0
  207. package/src/commands/create-new-project.ts +179 -0
  208. package/src/commands/diff.ts +165 -0
  209. package/src/commands/file-upload.ts +389 -0
  210. package/src/commands/fork.ts +320 -0
  211. package/src/commands/gemini-apikey.ts +104 -0
  212. package/src/commands/login.ts +634 -0
  213. package/src/commands/mention-mode.ts +77 -0
  214. package/src/commands/merge-worktree.ts +177 -0
  215. package/src/commands/model.ts +961 -0
  216. package/src/commands/permissions.ts +261 -0
  217. package/src/commands/queue.ts +296 -0
  218. package/src/commands/remove-project.ts +155 -0
  219. package/src/commands/restart-opencode-server.ts +162 -0
  220. package/src/commands/resume.ts +242 -0
  221. package/src/commands/run-command.ts +123 -0
  222. package/src/commands/session-id.ts +109 -0
  223. package/src/commands/session.ts +250 -0
  224. package/src/commands/share.ts +106 -0
  225. package/src/commands/types.ts +25 -0
  226. package/src/commands/undo-redo.ts +221 -0
  227. package/src/commands/unset-model.ts +189 -0
  228. package/src/commands/upgrade.ts +52 -0
  229. package/src/commands/user-command.ts +193 -0
  230. package/src/commands/verbosity.ts +88 -0
  231. package/src/commands/worktree-settings.ts +79 -0
  232. package/src/commands/worktree.ts +431 -0
  233. package/src/condense-memory.ts +36 -0
  234. package/src/config.ts +148 -0
  235. package/src/database.ts +1530 -0
  236. package/src/db.test.ts +60 -0
  237. package/src/db.ts +190 -0
  238. package/src/discord-api.ts +35 -0
  239. package/src/discord-bot.ts +1316 -0
  240. package/src/discord-utils.test.ts +132 -0
  241. package/src/discord-utils.ts +767 -0
  242. package/src/errors.ts +213 -0
  243. package/src/escape-backticks.test.ts +469 -0
  244. package/src/format-tables.test.ts +223 -0
  245. package/src/format-tables.ts +145 -0
  246. package/src/forum-sync/config.ts +92 -0
  247. package/src/forum-sync/discord-operations.ts +241 -0
  248. package/src/forum-sync/index.ts +9 -0
  249. package/src/forum-sync/markdown.ts +176 -0
  250. package/src/forum-sync/sync-to-discord.ts +595 -0
  251. package/src/forum-sync/sync-to-files.ts +294 -0
  252. package/src/forum-sync/types.ts +175 -0
  253. package/src/forum-sync/watchers.ts +454 -0
  254. package/src/genai-worker-wrapper.ts +164 -0
  255. package/src/genai-worker.ts +386 -0
  256. package/src/genai.ts +321 -0
  257. package/src/generated/browser.ts +109 -0
  258. package/src/generated/client.ts +131 -0
  259. package/src/generated/commonInputTypes.ts +512 -0
  260. package/src/generated/enums.ts +46 -0
  261. package/src/generated/internal/class.ts +362 -0
  262. package/src/generated/internal/prismaNamespace.ts +2251 -0
  263. package/src/generated/internal/prismaNamespaceBrowser.ts +308 -0
  264. package/src/generated/models/bot_api_keys.ts +1288 -0
  265. package/src/generated/models/bot_tokens.ts +1577 -0
  266. package/src/generated/models/channel_agents.ts +1256 -0
  267. package/src/generated/models/channel_directories.ts +2104 -0
  268. package/src/generated/models/channel_mention_mode.ts +1300 -0
  269. package/src/generated/models/channel_models.ts +1288 -0
  270. package/src/generated/models/channel_verbosity.ts +1224 -0
  271. package/src/generated/models/channel_worktrees.ts +1308 -0
  272. package/src/generated/models/forum_sync_configs.ts +1452 -0
  273. package/src/generated/models/global_models.ts +1288 -0
  274. package/src/generated/models/ipc_requests.ts +1485 -0
  275. package/src/generated/models/part_messages.ts +1302 -0
  276. package/src/generated/models/scheduled_tasks.ts +2320 -0
  277. package/src/generated/models/session_agents.ts +1086 -0
  278. package/src/generated/models/session_models.ts +1114 -0
  279. package/src/generated/models/session_start_sources.ts +1408 -0
  280. package/src/generated/models/thread_sessions.ts +1599 -0
  281. package/src/generated/models/thread_worktrees.ts +1352 -0
  282. package/src/generated/models.ts +29 -0
  283. package/src/heap-monitor.ts +121 -0
  284. package/src/hrana-server.test.ts +428 -0
  285. package/src/hrana-server.ts +547 -0
  286. package/src/image-utils.ts +149 -0
  287. package/src/interaction-handler.ts +461 -0
  288. package/src/ipc-polling.ts +325 -0
  289. package/src/kimaki-digital-twin.e2e.test.ts +201 -0
  290. package/src/limit-heading-depth.test.ts +116 -0
  291. package/src/limit-heading-depth.ts +26 -0
  292. package/src/logger.ts +203 -0
  293. package/src/markdown.test.ts +360 -0
  294. package/src/markdown.ts +410 -0
  295. package/src/message-formatting.test.ts +81 -0
  296. package/src/message-formatting.ts +549 -0
  297. package/src/openai-realtime.ts +362 -0
  298. package/src/opencode-plugin-loading.e2e.test.ts +112 -0
  299. package/src/opencode-plugin.test.ts +108 -0
  300. package/src/opencode-plugin.ts +652 -0
  301. package/src/opencode.ts +554 -0
  302. package/src/privacy-sanitizer.ts +142 -0
  303. package/src/schema.sql +158 -0
  304. package/src/sentry.ts +137 -0
  305. package/src/session-handler/state.ts +232 -0
  306. package/src/session-handler.ts +2668 -0
  307. package/src/session-search.test.ts +50 -0
  308. package/src/session-search.ts +148 -0
  309. package/src/startup-service.ts +200 -0
  310. package/src/system-message.ts +568 -0
  311. package/src/task-runner.ts +425 -0
  312. package/src/task-schedule.test.ts +84 -0
  313. package/src/task-schedule.ts +287 -0
  314. package/src/thinking-utils.ts +61 -0
  315. package/src/thread-message-queue.e2e.test.ts +997 -0
  316. package/src/tools.ts +432 -0
  317. package/src/unnest-code-blocks.test.ts +679 -0
  318. package/src/unnest-code-blocks.ts +168 -0
  319. package/src/upgrade.ts +127 -0
  320. package/src/utils.ts +145 -0
  321. package/src/voice-handler.ts +852 -0
  322. package/src/voice.test.ts +219 -0
  323. package/src/voice.ts +444 -0
  324. package/src/wait-session.ts +147 -0
  325. package/src/worker-types.ts +64 -0
  326. package/src/worktree-utils.ts +988 -0
  327. package/src/xml.test.ts +38 -0
  328. package/src/xml.ts +121 -0
package/dist/xml.js ADDED
@@ -0,0 +1,92 @@
1
+ // XML/HTML tag content extractor.
2
+ // Parses XML-like tags from strings (e.g., channel topics) to extract
3
+ // Kimaki configuration like directory paths and app IDs.
4
+ import { DomHandler, Parser, ElementType } from 'htmlparser2';
5
+ import { createLogger, LogPrefix } from './logger.js';
6
+ const xmlLogger = createLogger(LogPrefix.XML);
7
+ export function extractTagsArrays({ xml, tags, }) {
8
+ const result = {
9
+ others: [],
10
+ };
11
+ // Initialize arrays for each tag
12
+ tags.forEach((tag) => {
13
+ result[tag] = [];
14
+ });
15
+ try {
16
+ const handler = new DomHandler((error, dom) => {
17
+ if (error) {
18
+ xmlLogger.error('Error parsing XML:', error);
19
+ }
20
+ else {
21
+ const findTags = (nodes, path = []) => {
22
+ nodes.forEach((node) => {
23
+ if (node.type === ElementType.Tag) {
24
+ const element = node;
25
+ const currentPath = [...path, element.name];
26
+ const pathString = currentPath.join('.');
27
+ // Extract content using original string positions
28
+ const extractContent = () => {
29
+ // Use element's own indices but exclude the tags
30
+ if (element.startIndex !== null &&
31
+ element.endIndex !== null) {
32
+ // Extract the full element including tags
33
+ const fullElement = xml.substring(element.startIndex, element.endIndex + 1);
34
+ // Find where content starts (after opening tag)
35
+ const contentStart = fullElement.indexOf('>') + 1;
36
+ // Find where content ends (before this element's closing tag)
37
+ const closingTag = `</${element.name}>`;
38
+ const contentEnd = fullElement.lastIndexOf(closingTag);
39
+ if (contentStart > 0 && contentEnd > contentStart) {
40
+ return fullElement.substring(contentStart, contentEnd);
41
+ }
42
+ return '';
43
+ }
44
+ return '';
45
+ };
46
+ // Check both single tag names and nested paths
47
+ if (tags.includes(element.name)) {
48
+ const content = extractContent();
49
+ result[element.name]?.push(content);
50
+ }
51
+ // Check for nested path matches
52
+ if (tags.includes(pathString)) {
53
+ const content = extractContent();
54
+ result[pathString]?.push(content);
55
+ }
56
+ if (element.children) {
57
+ findTags(element.children, currentPath);
58
+ }
59
+ }
60
+ else if (node.type === ElementType.Text &&
61
+ node.parent?.type === ElementType.Root) {
62
+ const textNode = node;
63
+ if (textNode.data.trim()) {
64
+ // console.log('node.parent',node.parent)
65
+ result.others?.push(textNode.data.trim());
66
+ }
67
+ }
68
+ });
69
+ };
70
+ findTags(dom);
71
+ }
72
+ }, {
73
+ withStartIndices: true,
74
+ withEndIndices: true,
75
+ xmlMode: true,
76
+ });
77
+ const parser = new Parser(handler, {
78
+ xmlMode: true,
79
+ decodeEntities: false,
80
+ });
81
+ parser.write(xml);
82
+ parser.end();
83
+ }
84
+ catch (error) {
85
+ xmlLogger.error('Unexpected error in extractTags:', error);
86
+ }
87
+ return result;
88
+ }
89
+ export function extractNonXmlContent(xml) {
90
+ const result = extractTagsArrays({ xml, tags: [] });
91
+ return result.others.join('\n');
92
+ }
@@ -0,0 +1,32 @@
1
+ import { describe, test, expect } from 'vitest';
2
+ import { extractNonXmlContent } from './xml.js';
3
+ describe('extractNonXmlContent', () => {
4
+ test('removes xml tags and returns only text content', () => {
5
+ const xml = 'Hello <tag>content</tag> world <nested><inner>deep</inner></nested> end';
6
+ expect(extractNonXmlContent(xml)).toMatchInlineSnapshot(`
7
+ "Hello
8
+ world
9
+ end"
10
+ `);
11
+ });
12
+ test('handles multiple text segments', () => {
13
+ const xml = 'Start <a>tag1</a> middle <b>tag2</b> finish';
14
+ expect(extractNonXmlContent(xml)).toMatchInlineSnapshot(`
15
+ "Start
16
+ middle
17
+ finish"
18
+ `);
19
+ });
20
+ test('handles only xml without text', () => {
21
+ const xml = '<root><child>content</child></root>';
22
+ expect(extractNonXmlContent(xml)).toMatchInlineSnapshot(`""`);
23
+ });
24
+ test('handles only text without xml', () => {
25
+ const xml = 'Just plain text';
26
+ expect(extractNonXmlContent(xml)).toMatchInlineSnapshot(`"Just plain text"`);
27
+ });
28
+ test('handles empty string', () => {
29
+ const xml = '';
30
+ expect(extractNonXmlContent(xml)).toMatchInlineSnapshot(`""`);
31
+ });
32
+ });
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "@brianli/kimaki",
3
+ "module": "index.ts",
4
+ "type": "module",
5
+ "version": "0.4.72-brianli.1",
6
+ "scripts": {
7
+ "dev": "tsx --env-file .env src/cli.ts",
8
+ "prepublishOnly": "pnpm generate && pnpm tsc",
9
+ "dev:bun": "DEBUG=1 bun --env-file .env src/cli.ts",
10
+ "watch": "tsx scripts/watch-session.ts",
11
+ "generate": "prisma generate && pnpm generate:sql",
12
+ "generate:sql": "rm -f dev.db && prisma db push --url 'file:dev.db' --accept-data-loss && echo '-- This file is generated by pnpm generate:sql. Do not edit manually.' > src/schema.sql && sqlite3 dev.db '.schema' >> src/schema.sql",
13
+ "pcm-to-mp3": "bun scripts/pcm-to-mp3",
14
+ "test": "vitest",
15
+ "test:send": "tsx send-test-message.ts",
16
+ "register-commands": "tsx scripts/register-commands.ts",
17
+ "format": "oxfmt src",
18
+ "sync-skills": "tsx scripts/sync-skills.ts"
19
+ },
20
+ "repository": "https://github.com/remorses/kimaki",
21
+ "bin": "bin.js",
22
+ "files": [
23
+ "dist",
24
+ "src",
25
+ "skills",
26
+ "schema.prisma",
27
+ "bin.js"
28
+ ],
29
+ "devDependencies": {
30
+ "@types/bun": "latest",
31
+ "@types/heic-convert": "^2.1.0",
32
+ "@types/js-yaml": "^4.0.9",
33
+ "@types/json-schema": "^7.0.15",
34
+ "@types/ms": "^2.1.0",
35
+ "@types/node": "^24.3.0",
36
+ "discord-digital-twin": "workspace:^",
37
+ "opencode-cached-provider": "workspace:^",
38
+ "opencode-deterministic-provider": "workspace:^",
39
+ "prisma": "7.3.0",
40
+ "tsx": "^4.20.5"
41
+ },
42
+ "dependencies": {
43
+ "@ai-sdk/google": "^3.0.30",
44
+ "@ai-sdk/openai": "^3.0.31",
45
+ "@ai-sdk/provider": "^3.0.8",
46
+ "@clack/prompts": "^1.0.0",
47
+ "@discordjs/voice": "^0.19.0",
48
+ "@google/genai": "^1.34.0",
49
+ "@libsql/client": "^0.15.15",
50
+ "@opencode-ai/plugin": "^1.1.53",
51
+ "@opencode-ai/sdk": "^1.1.53",
52
+ "@parcel/watcher": "^2.5.6",
53
+ "@prisma/adapter-libsql": "7.3.0",
54
+ "@prisma/client": "7.3.0",
55
+ "@purinton/resampler": "^1.0.4",
56
+ "@sentry/node": "^10.40.0",
57
+ "cron-parser": "^5.5.0",
58
+ "discord.js": "^14.25.1",
59
+ "domhandler": "^5.0.3",
60
+ "errore": "workspace:^",
61
+ "goke": "^6.1.2",
62
+ "htmlparser2": "^10.0.0",
63
+ "js-yaml": "^4.1.0",
64
+ "libsql": "^0.5.22",
65
+ "marked": "^16.3.0",
66
+ "mime": "^4.1.0",
67
+ "picocolors": "^1.1.1",
68
+ "pretty-ms": "^9.3.0",
69
+ "string-dedent": "^3.0.2",
70
+ "traforo": "workspace:^",
71
+ "undici": "^7.16.0",
72
+ "xdg-basedir": "^5.1.0",
73
+ "zod": "^4.3.6",
74
+ "zustand": "^5.0.11"
75
+ },
76
+ "optionalDependencies": {
77
+ "@discordjs/opus": "^0.10.0",
78
+ "heic-convert": "^2.1.0",
79
+ "prism-media": "^1.3.5",
80
+ "sharp": "^0.34.5"
81
+ }
82
+ }
package/schema.prisma ADDED
@@ -0,0 +1,246 @@
1
+ generator client {
2
+ provider = "prisma-client"
3
+ output = "./src/generated"
4
+ }
5
+
6
+ datasource db {
7
+ provider = "sqlite"
8
+ }
9
+
10
+ model thread_sessions {
11
+ thread_id String @id
12
+ session_id String
13
+ created_at DateTime? @default(now())
14
+
15
+ part_messages part_messages[]
16
+ scheduled_tasks scheduled_tasks[]
17
+ thread_worktree thread_worktrees?
18
+ ipc_requests ipc_requests[]
19
+ }
20
+
21
+ model part_messages {
22
+ part_id String @id
23
+ message_id String
24
+ thread_id String
25
+ created_at DateTime? @default(now())
26
+
27
+ thread thread_sessions @relation(fields: [thread_id], references: [thread_id])
28
+ }
29
+
30
+ model bot_tokens {
31
+ app_id String @id
32
+ token String
33
+ created_at DateTime? @default(now())
34
+
35
+ api_keys bot_api_keys?
36
+ channels channel_directories[]
37
+ forum_sync_configs forum_sync_configs[]
38
+ global_model global_models?
39
+ }
40
+
41
+ model channel_directories {
42
+ channel_id String @id
43
+ directory String
44
+ channel_type String
45
+ app_id String?
46
+ created_at DateTime? @default(now())
47
+
48
+ bot bot_tokens? @relation(fields: [app_id], references: [app_id])
49
+ channel_model channel_models?
50
+ channel_agent channel_agents?
51
+ channel_worktree channel_worktrees?
52
+ channel_verbosity channel_verbosity?
53
+ channel_mention_mode channel_mention_mode?
54
+ scheduled_tasks scheduled_tasks[]
55
+ }
56
+
57
+ model bot_api_keys {
58
+ app_id String @id
59
+ gemini_api_key String?
60
+ openai_api_key String?
61
+ xai_api_key String?
62
+ created_at DateTime? @default(now())
63
+
64
+ bot bot_tokens @relation(fields: [app_id], references: [app_id])
65
+ }
66
+
67
+ // status: 'pending' while creating, 'ready' when done, 'error' if failed
68
+ model thread_worktrees {
69
+ thread_id String @id
70
+ worktree_name String
71
+ worktree_directory String?
72
+ project_directory String
73
+ status String? @default("pending")
74
+ error_message String?
75
+ created_at DateTime? @default(now())
76
+
77
+ thread thread_sessions @relation(fields: [thread_id], references: [thread_id])
78
+ }
79
+
80
+ model channel_models {
81
+ channel_id String @id
82
+ model_id String
83
+ variant String?
84
+ created_at DateTime? @default(now())
85
+ updated_at DateTime? @default(now()) @updatedAt
86
+
87
+ channel channel_directories @relation(fields: [channel_id], references: [channel_id])
88
+ }
89
+
90
+ model session_models {
91
+ session_id String @id
92
+ model_id String
93
+ variant String?
94
+ created_at DateTime? @default(now())
95
+ }
96
+
97
+ model channel_agents {
98
+ channel_id String @id
99
+ agent_name String
100
+ created_at DateTime? @default(now())
101
+ updated_at DateTime? @default(now()) @updatedAt
102
+
103
+ channel channel_directories @relation(fields: [channel_id], references: [channel_id])
104
+ }
105
+
106
+ model session_agents {
107
+ session_id String @id
108
+ agent_name String
109
+ created_at DateTime? @default(now())
110
+ }
111
+
112
+ model channel_worktrees {
113
+ channel_id String @id
114
+ enabled Int @default(0)
115
+ created_at DateTime? @default(now())
116
+ updated_at DateTime? @default(now()) @updatedAt
117
+
118
+ channel channel_directories @relation(fields: [channel_id], references: [channel_id])
119
+ }
120
+
121
+ model channel_verbosity {
122
+ channel_id String @id
123
+ verbosity String @default("tools-and-text")
124
+ updated_at DateTime? @default(now()) @updatedAt
125
+
126
+ channel channel_directories @relation(fields: [channel_id], references: [channel_id])
127
+ }
128
+
129
+ model channel_mention_mode {
130
+ channel_id String @id
131
+ enabled Int @default(0)
132
+ created_at DateTime? @default(now())
133
+ updated_at DateTime? @default(now()) @updatedAt
134
+
135
+ channel channel_directories @relation(fields: [channel_id], references: [channel_id])
136
+ }
137
+
138
+ model global_models {
139
+ app_id String @id
140
+ model_id String
141
+ variant String?
142
+ created_at DateTime? @default(now())
143
+ updated_at DateTime? @default(now()) @updatedAt
144
+
145
+ bot bot_tokens @relation(fields: [app_id], references: [app_id])
146
+ }
147
+
148
+ enum task_status {
149
+ planned
150
+ running
151
+ completed
152
+ cancelled
153
+ failed
154
+ }
155
+
156
+ enum task_schedule_kind {
157
+ at
158
+ cron
159
+ }
160
+
161
+ model scheduled_tasks {
162
+ id Int @id @default(autoincrement())
163
+ status task_status @default(planned)
164
+ schedule_kind task_schedule_kind
165
+ run_at DateTime?
166
+ cron_expr String?
167
+ timezone String?
168
+ next_run_at DateTime
169
+ running_started_at DateTime?
170
+ last_run_at DateTime?
171
+ last_error String?
172
+ attempts Int @default(0)
173
+ payload_json String
174
+ prompt_preview String
175
+ channel_id String?
176
+ thread_id String?
177
+ session_id String?
178
+ project_directory String?
179
+ created_at DateTime? @default(now())
180
+ updated_at DateTime? @default(now()) @updatedAt
181
+
182
+ channel channel_directories? @relation(fields: [channel_id], references: [channel_id], onDelete: SetNull, onUpdate: Cascade)
183
+ thread thread_sessions? @relation(fields: [thread_id], references: [thread_id], onDelete: SetNull, onUpdate: Cascade)
184
+ session_start_sources session_start_sources[]
185
+
186
+ @@index([status, next_run_at])
187
+ @@index([channel_id, status])
188
+ @@index([thread_id, status])
189
+ }
190
+
191
+ model session_start_sources {
192
+ session_id String @id
193
+ schedule_kind task_schedule_kind
194
+ scheduled_task_id Int?
195
+ created_at DateTime? @default(now())
196
+ updated_at DateTime? @default(now()) @updatedAt
197
+
198
+ scheduled_task scheduled_tasks? @relation(fields: [scheduled_task_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
199
+
200
+ @@index([scheduled_task_id])
201
+ }
202
+
203
+ model forum_sync_configs {
204
+ id Int @id @default(autoincrement())
205
+ app_id String
206
+ forum_channel_id String
207
+ output_dir String
208
+ direction String @default("bidirectional")
209
+ created_at DateTime? @default(now())
210
+ updated_at DateTime? @default(now()) @updatedAt
211
+
212
+ bot bot_tokens @relation(fields: [app_id], references: [app_id], onDelete: Cascade, onUpdate: Cascade)
213
+
214
+ @@unique([app_id, forum_channel_id])
215
+ }
216
+
217
+ enum ipc_request_type {
218
+ file_upload
219
+ action_buttons
220
+ }
221
+
222
+ enum ipc_request_status {
223
+ pending
224
+ processing
225
+ completed
226
+ cancelled
227
+ }
228
+
229
+ // IPC bridge between the opencode plugin process and the Discord bot process.
230
+ // Replaces the old HTTP lock server for file-upload and action-buttons requests.
231
+ // Plugin inserts a pending row, bot polls and dispatches, then writes the response.
232
+ model ipc_requests {
233
+ id String @id @default(uuid())
234
+ type ipc_request_type
235
+ session_id String
236
+ thread_id String
237
+ payload String // JSON-encoded request data
238
+ response String? // JSON-encoded response, null while pending
239
+ status ipc_request_status @default(pending)
240
+ created_at DateTime @default(now())
241
+ updated_at DateTime @default(now()) @updatedAt
242
+
243
+ thread thread_sessions @relation(fields: [thread_id], references: [thread_id])
244
+
245
+ @@index([status, created_at])
246
+ }
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: batch
3
+ description: >
4
+ Research and plan a large-scale change, then execute it in parallel across
5
+ 5-30 isolated worktree agents that each open a PR. Use when the user wants
6
+ to make a sweeping, mechanical change across many files (migrations,
7
+ refactors, bulk renames) that can be decomposed into independent parallel
8
+ units.
9
+ argument-hint: "<instruction>"
10
+ source-path: cli.js (line 7359, function mGz)
11
+ source-package: "@anthropic-ai/claude-code@2.1.63"
12
+ source-date: 2026-02-28
13
+ ---
14
+
15
+ # Batch: Parallel Work Orchestration
16
+
17
+ You are orchestrating a large, parallelizable change across this codebase.
18
+
19
+ ## User Instruction
20
+
21
+ $instruction
22
+
23
+ ## Phase 1: Research and Plan (Plan Mode)
24
+
25
+ Enter plan mode, then:
26
+
27
+ 1. **Understand the scope.** Launch one or more Explore agents (in the foreground — you need their results) to deeply research what this instruction touches. Find all the files, patterns, and call sites that need to change. Understand the existing conventions so the migration is consistent.
28
+
29
+ 2. **Decompose into independent units.** Break the work into 5–30 self-contained units. Each unit must:
30
+ - Be independently implementable in an isolated git worktree (no shared state with sibling units)
31
+ - Be mergeable on its own without depending on another unit's PR landing first
32
+ - Be roughly uniform in size (split large units, merge trivial ones)
33
+
34
+ Scale the count to the actual work: few files → closer to 5; hundreds of files → closer to 30. Prefer per-directory or per-module slicing over arbitrary file lists.
35
+
36
+ 3. **Determine the e2e test recipe.** Figure out how a worker can verify its change actually works end-to-end — not just that unit tests pass. Look for:
37
+ - A browser-automation tool (for UI changes: click through the affected flow, screenshot the result)
38
+ - A tmux or CLI-verifier skill (for CLI changes: launch the app interactively, exercise the changed behavior)
39
+ - A dev-server + curl pattern (for API changes: start the server, hit the affected endpoints)
40
+ - An existing e2e/integration test suite the worker can run
41
+
42
+ If you cannot find a concrete e2e path, ask the user how to verify this change end-to-end. Offer 2–3 specific options based on what you found (e.g., "Screenshot via chrome extension", "Run `bun run dev` and curl the endpoint", "No e2e — unit tests are sufficient"). Do not skip this — the workers cannot ask the user themselves.
43
+
44
+ Write the recipe as a short, concrete set of steps that a worker can execute autonomously. Include any setup (start a dev server, build first) and the exact command/interaction to verify.
45
+
46
+ 4. **Write the plan.** In your plan file, include:
47
+ - A summary of what you found during research
48
+ - A numbered list of work units — for each: a short title, the list of files/directories it covers, and a one-line description of the change
49
+ - The e2e test recipe (or "skip e2e because …" if the user chose that)
50
+ - The exact worker instructions you will give each agent (the shared template)
51
+
52
+ 5. Present the plan for approval.
53
+
54
+ ## Phase 2: Spawn Workers (After Plan Approval)
55
+
56
+ Once the plan is approved, spawn one background agent per work unit using the Task tool. **All agents must use `isolation: "worktree"` and `run_in_background: true`.** Launch them all in a single message block so they run in parallel.
57
+
58
+ For each agent, the prompt must be fully self-contained. Include:
59
+ - The overall goal (the user's instruction)
60
+ - This unit's specific task (title, file list, change description — copied verbatim from your plan)
61
+ - Any codebase conventions you discovered that the worker needs to follow
62
+ - The e2e test recipe from your plan (or "skip e2e because …")
63
+ - The worker instructions below, copied verbatim:
64
+
65
+ ```
66
+ After you finish implementing the change:
67
+ 1. **Simplify** — Invoke the simplify skill to review and clean up your changes.
68
+ 2. **Run unit tests** — Run the project's test suite (check for package.json scripts, Makefile targets, or common commands like `npm test`, `bun test`, `pytest`, `go test`). If tests fail, fix them.
69
+ 3. **Test end-to-end** — Follow the e2e test recipe from the coordinator's prompt (below). If the recipe says to skip e2e for this unit, skip it.
70
+ 4. **Commit and push** — Commit all changes with a clear message, push the branch, and create a PR with `gh pr create`. Use a descriptive title. If `gh` is not available or the push fails, note it in your final message.
71
+ 5. **Report** — End with a single line: `PR: <url>` so the coordinator can track it. If no PR was created, end with `PR: none — <reason>`.
72
+ ```
73
+
74
+ Use `subagent_type: "general-purpose"` unless a more specific agent type fits.
75
+
76
+ ## Phase 3: Track Progress
77
+
78
+ After launching all workers, render an initial status table:
79
+
80
+ | # | Unit | Status | PR |
81
+ |---|------|--------|----|
82
+ | 1 | <title> | running | — |
83
+ | 2 | <title> | running | — |
84
+
85
+ As background-agent completion notifications arrive, parse the `PR: <url>` line from each agent's result and re-render the table with updated status (`done` / `failed`) and PR links. Keep a brief failure note for any agent that did not produce a PR.
86
+
87
+ When all agents have reported, render the final table and a one-line summary (e.g., "22/24 units landed as PRs").
@@ -0,0 +1,129 @@
1
+ ---
2
+ name: critique
3
+ description: >
4
+ Git diff viewer and AI reviewer. Renders diffs as web pages, images, and PDFs
5
+ with syntax highlighting. Also provides AI-powered diff reviews via
6
+ `critique review --web`. Use this skill when working with critique for showing
7
+ diffs, generating diff URLs, selective hunk staging, or AI code reviews.
8
+ ---
9
+
10
+ # critique
11
+
12
+ Git diff viewer that renders diffs as **web pages**, **images**, and **PDFs** with syntax highlighting.
13
+
14
+ Agents running in headless environments (kimaki on Discord, openclaw on Slack/Telegram) have no terminal to show diffs. critique uploads diffs to critique.work and returns a shareable URL you can paste into chat. Users click the link and see a syntax-highlighted split-view diff with mobile support and dark/light mode — no install needed.
15
+
16
+ **Always run `critique --help` first** to see the latest flags and commands. The help output is the source of truth.
17
+
18
+ ## Web — shareable diff URLs
19
+
20
+ Always pass a title to describe what the diff contains.
21
+
22
+ ```bash
23
+ # Working tree changes
24
+ critique --web "Add retry logic to database connections"
25
+
26
+ # Staged changes
27
+ critique --staged --web "Refactor auth middleware"
28
+
29
+ # Branch diff (three-dot: changes since diverging from base)
30
+ critique main...HEAD --web "Feature branch changes"
31
+ critique main...feature-branch --web "Compare branches"
32
+
33
+ # Last N commits
34
+ critique HEAD~3 --web "Recent changes"
35
+
36
+ # Specific commit
37
+ critique --commit HEAD --web "Latest commit"
38
+ critique --commit abc1234 --web "Fix race condition"
39
+
40
+ # Filter to specific files
41
+ critique --web "API changes" --filter "src/api.ts" --filter "src/utils.ts"
42
+
43
+ # JSON output for programmatic use (returns {url, id, files})
44
+ critique --web "Deploy changes" --json
45
+ ```
46
+
47
+ Share the returned URL with the user so they can see the diff.
48
+
49
+ ## PDF
50
+
51
+ ```bash
52
+ critique --pdf # working tree to PDF
53
+ critique --staged --pdf # staged changes
54
+ critique main...HEAD --pdf # branch diff
55
+ critique --commit HEAD --pdf # single commit
56
+ critique --pdf output.pdf # custom filename
57
+ critique --pdf --pdf-page-size a4-portrait # page size options
58
+ critique main...HEAD --pdf --open # open in viewer
59
+ ```
60
+
61
+ ## Image
62
+
63
+ ```bash
64
+ critique --image # renders to /tmp as WebP
65
+ critique main...HEAD --image # branch diff as images
66
+ ```
67
+
68
+ ## Selective hunk staging
69
+
70
+ When multiple agents work on the same repo, each agent should only commit its own changes. `critique hunks` lets you stage individual hunks instead of whole files — like a scriptable `git add -p`.
71
+
72
+ ```bash
73
+ # List hunks with stable IDs
74
+ critique hunks list
75
+ critique hunks list --filter "src/**/*.ts"
76
+
77
+ # Stage specific hunks by ID
78
+ critique hunks add 'src/main.ts:@-10,6+10,7'
79
+ critique hunks add 'src/main.ts:@-10,6+10,7' 'src/utils.ts:@-5,3+5,4'
80
+ ```
81
+
82
+ Hunk ID format: `file:@-oldStart,oldLines+newStart,newLines` — derived from the `@@` diff header, stable across runs.
83
+
84
+ **Typical workflow:**
85
+
86
+ ```bash
87
+ critique hunks list # see all unstaged hunks
88
+ critique hunks add 'file:@-10,6+10,7' # stage only your hunks
89
+ git commit -m "your changes" # commit separately
90
+ ```
91
+
92
+ ## AI-powered diff review
93
+
94
+ `critique review --web` spawns a separate opencode session that analyzes a diff, groups related
95
+ changes, and produces a structured review with explanations, diagrams, and suggestions. Uploads
96
+ the result as a shareable URL — much richer than a plain diff link.
97
+
98
+ **This command is very slow (up to 20 minutes for large diffs).** Only run when the user
99
+ explicitly asks for a code review or diff explanation. Warn the user it will take a while.
100
+ Set Bash tool timeout to at least 25 minutes (`timeout: 1_500_000`).
101
+
102
+ Always pass `--agent opencode` and `--session <current_session_id>` so the reviewer has context
103
+ about why the changes were made. If you know other session IDs that produced the diff, pass them
104
+ too with additional `--session` flags.
105
+
106
+ ```bash
107
+ # Review working tree changes
108
+ critique review --web --agent opencode --session <session_id>
109
+
110
+ # Review a specific commit
111
+ critique review --commit HEAD --web --agent opencode --session <session_id>
112
+
113
+ # Review branch changes compared to main
114
+ critique review main...HEAD --web --agent opencode --session <session_id>
115
+
116
+ # Review with multiple session contexts
117
+ critique review --commit abc1234 --web --agent opencode --session <session_id> --session <other_session_id>
118
+
119
+ # Review only specific files
120
+ critique review --web --agent opencode --session <session_id> --filter "src/**/*.ts"
121
+ ```
122
+
123
+ The command prints a preview URL when done — share that URL with the user.
124
+
125
+ ## Notes
126
+
127
+ - Requires **Bun** — use `bunx critique` or global `critique`
128
+ - Lock files and diffs >6000 lines are auto-hidden
129
+ - `--web` URLs expire after 7 days (content-hashed, same diff = same URL)