@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
@@ -0,0 +1,461 @@
1
+ // Discord slash command and interaction handler.
2
+ // Processes all slash commands (/session, /resume, /fork, /model, /abort, etc.)
3
+ // and manages autocomplete, select menu interactions for the bot.
4
+
5
+ import {
6
+ Events,
7
+ MessageFlags,
8
+ type Client,
9
+ type Interaction,
10
+ } from 'discord.js'
11
+ import {
12
+ handleSessionCommand,
13
+ handleSessionAutocomplete,
14
+ } from './commands/session.js'
15
+ import { handleNewWorktreeCommand } from './commands/worktree.js'
16
+ import { handleMergeWorktreeCommand } from './commands/merge-worktree.js'
17
+ import { handleToggleWorktreesCommand } from './commands/worktree-settings.js'
18
+ import { handleToggleMentionModeCommand } from './commands/mention-mode.js'
19
+ import {
20
+ handleResumeCommand,
21
+ handleResumeAutocomplete,
22
+ } from './commands/resume.js'
23
+ import {
24
+ handleAddProjectCommand,
25
+ handleAddProjectAutocomplete,
26
+ } from './commands/add-project.js'
27
+ import {
28
+ handleRemoveProjectCommand,
29
+ handleRemoveProjectAutocomplete,
30
+ } from './commands/remove-project.js'
31
+ import { handleCreateNewProjectCommand } from './commands/create-new-project.js'
32
+ import { handlePermissionButton } from './commands/permissions.js'
33
+ import { handleAbortCommand } from './commands/abort.js'
34
+ import { handleCompactCommand } from './commands/compact.js'
35
+ import { handleShareCommand } from './commands/share.js'
36
+ import { handleDiffCommand } from './commands/diff.js'
37
+ import { handleForkCommand, handleForkSelectMenu } from './commands/fork.js'
38
+ import {
39
+ handleModelCommand,
40
+ handleProviderSelectMenu,
41
+ handleModelSelectMenu,
42
+ handleModelScopeSelectMenu,
43
+ } from './commands/model.js'
44
+ import { handleUnsetModelCommand } from './commands/unset-model.js'
45
+ import {
46
+ handleLoginCommand,
47
+ handleLoginProviderSelectMenu,
48
+ handleLoginMethodSelectMenu,
49
+ handleApiKeyModalSubmit,
50
+ } from './commands/login.js'
51
+ import {
52
+ handleTranscriptionApiKeyButton,
53
+ handleTranscriptionApiKeyCommand,
54
+ handleTranscriptionApiKeyModalSubmit,
55
+ } from './commands/gemini-apikey.js'
56
+ import {
57
+ handleAgentCommand,
58
+ handleAgentSelectMenu,
59
+ handleQuickAgentCommand,
60
+ } from './commands/agent.js'
61
+ import { handleAskQuestionSelectMenu } from './commands/ask-question.js'
62
+ import {
63
+ handleFileUploadButton,
64
+ handleFileUploadModalSubmit,
65
+ } from './commands/file-upload.js'
66
+ import { handleActionButton } from './commands/action-buttons.js'
67
+ import {
68
+ handleQueueCommand,
69
+ handleClearQueueCommand,
70
+ handleQueueCommandCommand,
71
+ handleQueueCommandAutocomplete,
72
+ } from './commands/queue.js'
73
+ import { handleUndoCommand, handleRedoCommand } from './commands/undo-redo.js'
74
+ import { handleUserCommand } from './commands/user-command.js'
75
+ import { handleVerbosityCommand } from './commands/verbosity.js'
76
+ import { handleRestartOpencodeServerCommand } from './commands/restart-opencode-server.js'
77
+ import { handleRunCommand } from './commands/run-command.js'
78
+ import { handleContextUsageCommand } from './commands/context-usage.js'
79
+ import { handleSessionIdCommand } from './commands/session-id.js'
80
+ import { handleUpgradeAndRestartCommand } from './commands/upgrade.js'
81
+ import { handleModelVariantSelectMenu } from './commands/model.js'
82
+ import { hasKimakiBotPermission, isGuildAllowed } from './discord-utils.js'
83
+ import { createLogger, LogPrefix } from './logger.js'
84
+ import { notifyError } from './sentry.js'
85
+
86
+ const interactionLogger = createLogger(LogPrefix.INTERACTION)
87
+
88
+ export function registerInteractionHandler({
89
+ discordClient,
90
+ appId,
91
+ }: {
92
+ discordClient: Client
93
+ appId: string
94
+ }) {
95
+ interactionLogger.log('[REGISTER] Interaction handler registered')
96
+
97
+ discordClient.on(
98
+ Events.InteractionCreate,
99
+ async (interaction: Interaction) => {
100
+ try {
101
+ if (!isGuildAllowed({ guildId: interaction.guildId })) {
102
+ return
103
+ }
104
+ interactionLogger.log(
105
+ `[INTERACTION] Received: ${interaction.type} - ${
106
+ interaction.isChatInputCommand()
107
+ ? interaction.commandName
108
+ : interaction.isAutocomplete()
109
+ ? `autocomplete:${interaction.commandName}`
110
+ : 'other'
111
+ }`,
112
+ )
113
+
114
+ if (interaction.isAutocomplete()) {
115
+ switch (interaction.commandName) {
116
+ case 'new-session':
117
+ await handleSessionAutocomplete({ interaction, appId })
118
+ return
119
+
120
+ case 'resume':
121
+ await handleResumeAutocomplete({ interaction, appId })
122
+ return
123
+
124
+ case 'add-project':
125
+ await handleAddProjectAutocomplete({ interaction, appId })
126
+ return
127
+
128
+ case 'remove-project':
129
+ await handleRemoveProjectAutocomplete({ interaction, appId })
130
+ return
131
+
132
+ case 'queue-command':
133
+ await handleQueueCommandAutocomplete({ interaction, appId })
134
+ return
135
+
136
+ default:
137
+ await interaction.respond([])
138
+ return
139
+ }
140
+ }
141
+
142
+ if (interaction.isChatInputCommand()) {
143
+ interactionLogger.log(
144
+ `[COMMAND] Processing: ${interaction.commandName}`,
145
+ )
146
+
147
+ if (!hasKimakiBotPermission(interaction.member, interaction.guild)) {
148
+ await interaction.reply({
149
+ content: `You don't have permission to use this command.\nTo use Kimaki, ask a server admin to give you the **Kimaki** role.`,
150
+ flags: MessageFlags.Ephemeral,
151
+ })
152
+ return
153
+ }
154
+
155
+ switch (interaction.commandName) {
156
+ case 'new-session':
157
+ await handleSessionCommand({ command: interaction, appId })
158
+ return
159
+
160
+ case 'new-worktree':
161
+ await handleNewWorktreeCommand({ command: interaction, appId })
162
+ return
163
+
164
+ case 'merge-worktree':
165
+ await handleMergeWorktreeCommand({ command: interaction, appId })
166
+ return
167
+
168
+ case 'toggle-worktrees':
169
+ await handleToggleWorktreesCommand({
170
+ command: interaction,
171
+ appId,
172
+ })
173
+ return
174
+
175
+ case 'toggle-mention-mode':
176
+ await handleToggleMentionModeCommand({
177
+ command: interaction,
178
+ appId,
179
+ })
180
+ return
181
+
182
+ case 'resume':
183
+ await handleResumeCommand({ command: interaction, appId })
184
+ return
185
+
186
+ case 'add-project':
187
+ await handleAddProjectCommand({ command: interaction, appId })
188
+ return
189
+
190
+ case 'remove-project':
191
+ await handleRemoveProjectCommand({ command: interaction, appId })
192
+ return
193
+
194
+ case 'create-new-project':
195
+ await handleCreateNewProjectCommand({
196
+ command: interaction,
197
+ appId,
198
+ })
199
+ return
200
+
201
+ case 'abort':
202
+ case 'stop':
203
+ await handleAbortCommand({ command: interaction, appId })
204
+ return
205
+
206
+ case 'compact':
207
+ await handleCompactCommand({ command: interaction, appId })
208
+ return
209
+
210
+ case 'share':
211
+ await handleShareCommand({ command: interaction, appId })
212
+ return
213
+
214
+ case 'diff':
215
+ await handleDiffCommand({ command: interaction, appId })
216
+ return
217
+
218
+ case 'fork':
219
+ await handleForkCommand(interaction)
220
+ return
221
+
222
+ case 'model':
223
+ await handleModelCommand({ interaction, appId })
224
+ return
225
+
226
+ case 'unset-model-override':
227
+ await handleUnsetModelCommand({ interaction, appId })
228
+ return
229
+
230
+ case 'login':
231
+ await handleLoginCommand({ interaction, appId })
232
+ return
233
+
234
+ case 'agent':
235
+ await handleAgentCommand({ interaction, appId })
236
+ return
237
+
238
+ case 'queue':
239
+ await handleQueueCommand({ command: interaction, appId })
240
+ return
241
+
242
+ case 'clear-queue':
243
+ await handleClearQueueCommand({ command: interaction, appId })
244
+ return
245
+
246
+ case 'queue-command':
247
+ await handleQueueCommandCommand({ command: interaction, appId })
248
+ return
249
+
250
+ case 'undo':
251
+ await handleUndoCommand({ command: interaction, appId })
252
+ return
253
+
254
+ case 'redo':
255
+ await handleRedoCommand({ command: interaction, appId })
256
+ return
257
+
258
+ case 'verbosity':
259
+ await handleVerbosityCommand({ command: interaction, appId })
260
+ return
261
+
262
+ case 'restart-opencode-server':
263
+ await handleRestartOpencodeServerCommand({
264
+ command: interaction,
265
+ appId,
266
+ })
267
+ return
268
+
269
+ case 'run-shell-command':
270
+ await handleRunCommand({ command: interaction, appId })
271
+ return
272
+
273
+ case 'context-usage':
274
+ await handleContextUsageCommand({ command: interaction, appId })
275
+ return
276
+
277
+ case 'session-id':
278
+ await handleSessionIdCommand({ command: interaction, appId })
279
+ return
280
+
281
+ case 'upgrade-and-restart':
282
+ await handleUpgradeAndRestartCommand({
283
+ command: interaction,
284
+ appId,
285
+ })
286
+ return
287
+
288
+ case 'transcription-key':
289
+ await handleTranscriptionApiKeyCommand({
290
+ interaction,
291
+ appId,
292
+ })
293
+ return
294
+ }
295
+
296
+ // Handle quick agent commands (ending with -agent suffix, but not the base /agent command)
297
+ if (
298
+ interaction.commandName.endsWith('-agent') &&
299
+ interaction.commandName !== 'agent'
300
+ ) {
301
+ await handleQuickAgentCommand({ command: interaction, appId })
302
+ return
303
+ }
304
+
305
+ // Handle user-defined commands (ending with -cmd suffix)
306
+ if (interaction.commandName.endsWith('-cmd')) {
307
+ await handleUserCommand({ command: interaction, appId })
308
+ return
309
+ }
310
+ return
311
+ }
312
+
313
+ if (interaction.isButton()) {
314
+ if (!hasKimakiBotPermission(interaction.member, interaction.guild)) {
315
+ await interaction.reply({
316
+ content: `You don't have permission to use this.\nTo use Kimaki, ask a server admin to give you the **Kimaki** role.`,
317
+ flags: MessageFlags.Ephemeral,
318
+ })
319
+ return
320
+ }
321
+
322
+ const customId = interaction.customId
323
+
324
+ if (customId.startsWith('transcription_apikey:')) {
325
+ await handleTranscriptionApiKeyButton(interaction)
326
+ return
327
+ }
328
+
329
+ if (
330
+ customId.startsWith('permission_once:') ||
331
+ customId.startsWith('permission_always:') ||
332
+ customId.startsWith('permission_reject:')
333
+ ) {
334
+ await handlePermissionButton(interaction)
335
+ return
336
+ }
337
+
338
+ if (customId.startsWith('file_upload_btn:')) {
339
+ await handleFileUploadButton(interaction)
340
+ return
341
+ }
342
+
343
+ if (customId.startsWith('action_button:')) {
344
+ await handleActionButton(interaction)
345
+ return
346
+ }
347
+ return
348
+ }
349
+
350
+ if (interaction.isStringSelectMenu()) {
351
+ if (!hasKimakiBotPermission(interaction.member, interaction.guild)) {
352
+ await interaction.reply({
353
+ content: `You don't have permission to use this.\nTo use Kimaki, ask a server admin to give you the **Kimaki** role.`,
354
+ flags: MessageFlags.Ephemeral,
355
+ })
356
+ return
357
+ }
358
+
359
+ const customId = interaction.customId
360
+
361
+ if (customId.startsWith('fork_select:')) {
362
+ await handleForkSelectMenu(interaction)
363
+ return
364
+ }
365
+
366
+ if (customId.startsWith('model_provider:')) {
367
+ await handleProviderSelectMenu(interaction)
368
+ return
369
+ }
370
+
371
+ if (customId.startsWith('model_select:')) {
372
+ await handleModelSelectMenu(interaction)
373
+ return
374
+ }
375
+
376
+ if (customId.startsWith('model_scope:')) {
377
+ await handleModelScopeSelectMenu(interaction)
378
+ return
379
+ }
380
+
381
+ if (customId.startsWith('model_variant:')) {
382
+ await handleModelVariantSelectMenu(interaction)
383
+ return
384
+ }
385
+
386
+ if (customId.startsWith('agent_select:')) {
387
+ await handleAgentSelectMenu(interaction)
388
+ return
389
+ }
390
+
391
+ if (customId.startsWith('ask_question:')) {
392
+ await handleAskQuestionSelectMenu(interaction)
393
+ return
394
+ }
395
+
396
+ if (customId.startsWith('login_provider:')) {
397
+ await handleLoginProviderSelectMenu(interaction)
398
+ return
399
+ }
400
+
401
+ if (customId.startsWith('login_method:')) {
402
+ await handleLoginMethodSelectMenu(interaction)
403
+ return
404
+ }
405
+ return
406
+ }
407
+
408
+ if (interaction.isModalSubmit()) {
409
+ if (!hasKimakiBotPermission(interaction.member, interaction.guild)) {
410
+ await interaction.reply({
411
+ content: `You don't have permission to use this.\nTo use Kimaki, ask a server admin to give you the **Kimaki** role.`,
412
+ flags: MessageFlags.Ephemeral,
413
+ })
414
+ return
415
+ }
416
+
417
+ const customId = interaction.customId
418
+
419
+ if (customId.startsWith('login_apikey:')) {
420
+ await handleApiKeyModalSubmit(interaction)
421
+ return
422
+ }
423
+
424
+ if (customId.startsWith('transcription_apikey_modal:')) {
425
+ await handleTranscriptionApiKeyModalSubmit(interaction)
426
+ return
427
+ }
428
+
429
+ if (customId.startsWith('file_upload_modal:')) {
430
+ await handleFileUploadModalSubmit(interaction)
431
+ return
432
+ }
433
+ return
434
+ }
435
+ } catch (error) {
436
+ interactionLogger.error(
437
+ '[INTERACTION] Error handling interaction:',
438
+ error,
439
+ )
440
+ void notifyError(error, 'Interaction handler error')
441
+ try {
442
+ if (
443
+ interaction.isRepliable() &&
444
+ !interaction.replied &&
445
+ !interaction.deferred
446
+ ) {
447
+ await interaction.reply({
448
+ content: 'An error occurred processing this command.',
449
+ flags: MessageFlags.Ephemeral,
450
+ })
451
+ }
452
+ } catch (replyError) {
453
+ interactionLogger.error(
454
+ '[INTERACTION] Failed to send error reply:',
455
+ replyError,
456
+ )
457
+ }
458
+ }
459
+ },
460
+ )
461
+ }