kimaki 0.31.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-ui.d.ts +33 -0
- package/dist/agent-ui.e2e.test.d.ts +1 -0
- package/dist/agent-ui.e2e.test.js +140 -0
- package/dist/agent-ui.e2e.test.js.map +1 -0
- package/dist/agent-ui.js +199 -0
- package/dist/agent-ui.js.map +1 -0
- package/dist/analytics.d.ts +42 -0
- package/dist/analytics.e2e.test.d.ts +1 -0
- package/dist/analytics.e2e.test.js +112 -0
- package/dist/analytics.e2e.test.js.map +1 -0
- package/dist/analytics.js +162 -223
- package/dist/analytics.js.map +1 -0
- package/dist/analytics.test.d.ts +1 -0
- package/dist/analytics.test.js +121 -157
- package/dist/analytics.test.js.map +1 -0
- package/dist/autostart.d.ts +7 -0
- package/dist/autostart.js +75 -0
- package/dist/autostart.js.map +1 -0
- package/dist/bot.d.ts +90 -0
- package/dist/bot.js +120 -0
- package/dist/bot.js.map +1 -0
- package/dist/btw.e2e.test.d.ts +1 -0
- package/dist/btw.e2e.test.js +102 -0
- package/dist/btw.e2e.test.js.map +1 -0
- package/dist/catalog-refresh.e2e.test.d.ts +1 -0
- package/dist/catalog-refresh.e2e.test.js +90 -0
- package/dist/catalog-refresh.e2e.test.js.map +1 -0
- package/dist/cli/bot.d.ts +5 -0
- package/dist/cli/bot.js +427 -0
- package/dist/cli/bot.js.map +1 -0
- package/dist/cli/discord.d.ts +3 -0
- package/dist/cli/discord.js +118 -0
- package/dist/cli/discord.js.map +1 -0
- package/dist/cli/project.d.ts +5 -0
- package/dist/cli/project.js +143 -0
- package/dist/cli/project.js.map +1 -0
- package/dist/cli/schedule.d.ts +3 -0
- package/dist/cli/schedule.js +156 -0
- package/dist/cli/schedule.js.map +1 -0
- package/dist/cli/session.d.ts +4 -0
- package/dist/cli/session.js +281 -0
- package/dist/cli/session.js.map +1 -0
- package/dist/cli/shared.d.ts +55 -0
- package/dist/cli/shared.js +138 -0
- package/dist/cli/shared.js.map +1 -0
- package/dist/cli-discord.e2e.test.d.ts +1 -0
- package/dist/cli-discord.e2e.test.js +64 -0
- package/dist/cli-discord.e2e.test.js.map +1 -0
- package/dist/cli-lock.e2e.test.d.ts +1 -0
- package/dist/cli-lock.e2e.test.js +520 -0
- package/dist/cli-lock.e2e.test.js.map +1 -0
- package/dist/cli-read.e2e.test.d.ts +1 -0
- package/dist/cli-read.e2e.test.js +81 -0
- package/dist/cli-read.e2e.test.js.map +1 -0
- package/dist/cli-sessions.e2e.test.d.ts +1 -0
- package/dist/cli-sessions.e2e.test.js +116 -0
- package/dist/cli-sessions.e2e.test.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +34 -263
- package/dist/cli.js.map +1 -0
- package/dist/commands/login-commands.d.ts +59 -0
- package/dist/commands/login-commands.js +341 -0
- package/dist/commands/login-commands.js.map +1 -0
- package/dist/commands/preference-commands.d.ts +44 -0
- package/dist/commands/preference-commands.js +551 -0
- package/dist/commands/preference-commands.js.map +1 -0
- package/dist/commands/session-commands.d.ts +8 -0
- package/dist/commands/session-commands.js +267 -0
- package/dist/commands/session-commands.js.map +1 -0
- package/dist/commands/thread-commands.d.ts +16 -0
- package/dist/commands/thread-commands.js +285 -0
- package/dist/commands/thread-commands.js.map +1 -0
- package/dist/commands/worktree-commands.d.ts +41 -0
- package/dist/commands/worktree-commands.js +279 -0
- package/dist/commands/worktree-commands.js.map +1 -0
- package/dist/commands.e2e.test.d.ts +1 -0
- package/dist/commands.e2e.test.js +255 -0
- package/dist/commands.e2e.test.js.map +1 -0
- package/dist/credentials.d.ts +84 -0
- package/dist/credentials.js +320 -0
- package/dist/credentials.js.map +1 -0
- package/dist/db.d.ts +1532 -0
- package/dist/db.js +57 -245
- package/dist/db.js.map +1 -0
- package/dist/db.test.d.ts +1 -0
- package/dist/db.test.js +351 -682
- package/dist/db.test.js.map +1 -0
- package/dist/duration.d.ts +2 -0
- package/dist/duration.js +18 -0
- package/dist/duration.js.map +1 -0
- package/dist/effects.d.ts +15 -0
- package/dist/effects.js +291 -0
- package/dist/effects.js.map +1 -0
- package/dist/errors.d.ts +38 -0
- package/dist/errors.js +40 -175
- package/dist/errors.js.map +1 -0
- package/dist/event-loop.d.ts +40 -0
- package/dist/event-loop.js +414 -0
- package/dist/event-loop.js.map +1 -0
- package/dist/file-edit-log.d.ts +41 -0
- package/dist/file-edit-log.js +122 -164
- package/dist/file-edit-log.js.map +1 -0
- package/dist/file-edit-log.test.d.ts +1 -0
- package/dist/file-edit-log.test.js +68 -244
- package/dist/file-edit-log.test.js.map +1 -0
- package/dist/format-parts.d.ts +137 -0
- package/dist/format-parts.js +300 -0
- package/dist/format-parts.js.map +1 -0
- package/dist/format-parts.test.d.ts +1 -0
- package/dist/format-parts.test.js +144 -0
- package/dist/format-parts.test.js.map +1 -0
- package/dist/gateway-replay.e2e.test.d.ts +1 -0
- package/dist/gateway-replay.e2e.test.js +95 -0
- package/dist/gateway-replay.e2e.test.js.map +1 -0
- package/dist/harness.e2e.test.d.ts +1 -0
- package/dist/harness.e2e.test.js +107 -0
- package/dist/harness.e2e.test.js.map +1 -0
- package/dist/hello-thread.e2e.test.d.ts +1 -0
- package/dist/hello-thread.e2e.test.js +194 -0
- package/dist/hello-thread.e2e.test.js.map +1 -0
- package/dist/ingress.d.ts +7 -0
- package/dist/ingress.js +337 -0
- package/dist/ingress.js.map +1 -0
- package/dist/interaction-context.d.ts +45 -0
- package/dist/interaction-context.js +77 -0
- package/dist/interaction-context.js.map +1 -0
- package/dist/interrupt.e2e.test.d.ts +1 -0
- package/dist/interrupt.e2e.test.js +124 -0
- package/dist/interrupt.e2e.test.js.map +1 -0
- package/dist/legacy.e2e.test.d.ts +1 -0
- package/dist/legacy.e2e.test.js +85 -0
- package/dist/legacy.e2e.test.js.map +1 -0
- package/dist/live-call.d.ts +51 -0
- package/dist/live-call.js +207 -0
- package/dist/live-call.js.map +1 -0
- package/dist/lock-routes.d.ts +812 -0
- package/dist/lock-routes.js +635 -0
- package/dist/lock-routes.js.map +1 -0
- package/dist/lock-server.d.ts +36 -0
- package/dist/lock-server.js +223 -0
- package/dist/lock-server.js.map +1 -0
- package/dist/logger.d.ts +13 -0
- package/dist/logger.js +112 -162
- package/dist/logger.js.map +1 -0
- package/dist/login.e2e.test.d.ts +1 -0
- package/dist/login.e2e.test.js +83 -0
- package/dist/login.e2e.test.js.map +1 -0
- package/dist/main.d.ts +32 -0
- package/dist/main.js +190 -0
- package/dist/main.js.map +1 -0
- package/dist/markdown/components.d.ts +10 -0
- package/dist/markdown/components.js +77 -0
- package/dist/markdown/components.js.map +1 -0
- package/dist/markdown/markdown.test.d.ts +1 -0
- package/dist/markdown/markdown.test.js +393 -0
- package/dist/markdown/markdown.test.js.map +1 -0
- package/dist/markdown/render-markdown.d.ts +30 -0
- package/dist/markdown/render-markdown.js +265 -0
- package/dist/markdown/render-markdown.js.map +1 -0
- package/dist/message-tool.e2e.test.d.ts +1 -0
- package/dist/message-tool.e2e.test.js +39 -0
- package/dist/message-tool.e2e.test.js.map +1 -0
- package/dist/migrations.d.ts +8 -0
- package/dist/migrations.js +187 -0
- package/dist/migrations.js.map +1 -0
- package/dist/onboarding-cli.e2e.test.d.ts +1 -0
- package/dist/onboarding-cli.e2e.test.js +178 -0
- package/dist/onboarding-cli.e2e.test.js.map +1 -0
- package/dist/onboarding.d.ts +36 -0
- package/dist/onboarding.e2e.test.d.ts +1 -0
- package/dist/onboarding.e2e.test.js +148 -0
- package/dist/onboarding.e2e.test.js.map +1 -0
- package/dist/onboarding.js +261 -0
- package/dist/onboarding.js.map +1 -0
- package/dist/opencode-server.d.ts +54 -0
- package/dist/opencode-server.js +413 -0
- package/dist/opencode-server.js.map +1 -0
- package/dist/opencode-server.test.d.ts +1 -0
- package/dist/opencode-server.test.js +21 -0
- package/dist/opencode-server.test.js.map +1 -0
- package/dist/permissions.d.ts +31 -0
- package/dist/permissions.e2e.test.d.ts +1 -0
- package/dist/permissions.e2e.test.js +166 -0
- package/dist/permissions.e2e.test.js.map +1 -0
- package/dist/permissions.js +95 -0
- package/dist/permissions.js.map +1 -0
- package/dist/plugin/anthropic/index.d.ts +13 -0
- package/dist/plugin/anthropic/index.js +201 -0
- package/dist/plugin/anthropic/index.js.map +1 -0
- package/dist/plugin/anthropic/index.test.d.ts +1 -0
- package/dist/plugin/anthropic/index.test.js +39 -0
- package/dist/plugin/anthropic/index.test.js.map +1 -0
- package/dist/plugin/index.d.ts +3 -0
- package/dist/plugin/index.js +106 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/session-id/index.d.ts +3 -0
- package/dist/plugin/session-id/index.js +18 -0
- package/dist/plugin/session-id/index.js.map +1 -0
- package/dist/plugin.e2e.test.d.ts +1 -0
- package/dist/plugin.e2e.test.js +87 -0
- package/dist/plugin.e2e.test.js.map +1 -0
- package/dist/preference-commands.e2e.test.d.ts +1 -0
- package/dist/preference-commands.e2e.test.js +555 -0
- package/dist/preference-commands.e2e.test.js.map +1 -0
- package/dist/probe-live.tmp.d.ts +1 -0
- package/dist/probe-live.tmp.js +82 -0
- package/dist/probe-live.tmp.js.map +1 -0
- package/dist/project.d.ts +58 -0
- package/dist/project.js +169 -0
- package/dist/project.js.map +1 -0
- package/dist/prompt.d.ts +112 -0
- package/dist/prompt.js +578 -0
- package/dist/prompt.js.map +1 -0
- package/dist/questions.d.ts +59 -0
- package/dist/questions.e2e.test.d.ts +1 -0
- package/dist/questions.e2e.test.js +290 -0
- package/dist/questions.e2e.test.js.map +1 -0
- package/dist/questions.js +231 -0
- package/dist/questions.js.map +1 -0
- package/dist/queue.d.ts +45 -0
- package/dist/queue.e2e.test.d.ts +1 -0
- package/dist/queue.e2e.test.js +220 -0
- package/dist/queue.e2e.test.js.map +1 -0
- package/dist/queue.js +132 -0
- package/dist/queue.js.map +1 -0
- package/dist/remote-send.d.ts +32 -0
- package/dist/remote-send.e2e.test.d.ts +1 -0
- package/dist/remote-send.e2e.test.js +89 -0
- package/dist/remote-send.e2e.test.js.map +1 -0
- package/dist/remote-send.js +105 -0
- package/dist/remote-send.js.map +1 -0
- package/dist/renderer.e2e.test.d.ts +1 -0
- package/dist/renderer.e2e.test.js +357 -0
- package/dist/renderer.e2e.test.js.map +1 -0
- package/dist/restart.e2e.test.d.ts +1 -0
- package/dist/restart.e2e.test.js +68 -0
- package/dist/restart.e2e.test.js.map +1 -0
- package/dist/routes.d.ts +24 -0
- package/dist/routes.js +42 -0
- package/dist/routes.js.map +1 -0
- package/dist/routes.test.d.ts +1 -0
- package/dist/routes.test.js +79 -0
- package/dist/routes.test.js.map +1 -0
- package/dist/routines.e2e.test.d.ts +1 -0
- package/dist/routines.e2e.test.js +188 -0
- package/dist/routines.e2e.test.js.map +1 -0
- package/dist/scheduler.d.ts +116 -0
- package/dist/scheduler.e2e.test.d.ts +1 -0
- package/dist/scheduler.e2e.test.js +163 -0
- package/dist/scheduler.e2e.test.js.map +1 -0
- package/dist/scheduler.js +602 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/scheduler.test.d.ts +1 -0
- package/dist/scheduler.test.js +180 -0
- package/dist/scheduler.test.js.map +1 -0
- package/dist/schema-sql.d.ts +1 -0
- package/dist/schema-sql.js +3 -0
- package/dist/schema-sql.js.map +1 -0
- package/dist/schema.d.ts +2968 -0
- package/dist/schema.js +95 -252
- package/dist/schema.js.map +1 -0
- package/dist/session-commands.e2e.test.d.ts +1 -0
- package/dist/session-commands.e2e.test.js +285 -0
- package/dist/session-commands.e2e.test.js.map +1 -0
- package/dist/session-events.d.ts +55 -0
- package/dist/session-events.js +190 -0
- package/dist/session-events.js.map +1 -0
- package/dist/session-ops.e2e.test.d.ts +1 -0
- package/dist/session-ops.e2e.test.js +114 -0
- package/dist/session-ops.e2e.test.js.map +1 -0
- package/dist/sessions.d.ts +121 -0
- package/dist/sessions.js +662 -0
- package/dist/sessions.js.map +1 -0
- package/dist/shell.e2e.test.d.ts +1 -0
- package/dist/shell.e2e.test.js +147 -0
- package/dist/shell.e2e.test.js.map +1 -0
- package/dist/slash-commands.d.ts +62 -0
- package/dist/slash-commands.js +475 -0
- package/dist/slash-commands.js.map +1 -0
- package/dist/slash-commands.test.d.ts +1 -0
- package/dist/slash-commands.test.js +87 -0
- package/dist/slash-commands.test.js.map +1 -0
- package/dist/sleep.e2e.test.d.ts +1 -0
- package/dist/sleep.e2e.test.js +115 -487
- package/dist/sleep.e2e.test.js.map +1 -0
- package/dist/sleeps.d.ts +37 -0
- package/dist/sleeps.js +220 -0
- package/dist/sleeps.js.map +1 -0
- package/dist/store.d.ts +10 -0
- package/dist/store.js +8 -28
- package/dist/store.js.map +1 -0
- package/dist/system-prompt.d.ts +65 -0
- package/dist/system-prompt.js +875 -0
- package/dist/system-prompt.js.map +1 -0
- package/dist/tasks.e2e.test.d.ts +1 -0
- package/dist/tasks.e2e.test.js +173 -0
- package/dist/tasks.e2e.test.js.map +1 -0
- package/dist/test/auth-plugin/index.d.ts +3 -0
- package/dist/test/auth-plugin/index.js +18 -0
- package/dist/test/auth-plugin/index.js.map +1 -0
- package/dist/test/fake-mcp-server.d.ts +1 -0
- package/dist/test/fake-mcp-server.js +45 -0
- package/dist/test/fake-mcp-server.js.map +1 -0
- package/dist/test/harness.d.ts +246 -0
- package/dist/test/harness.js +704 -0
- package/dist/test/harness.js.map +1 -0
- package/dist/test/replay.d.ts +14 -0
- package/dist/test/replay.js +75 -0
- package/dist/test/replay.js.map +1 -0
- package/dist/thread-reducer.d.ts +172 -0
- package/dist/thread-reducer.fixtures.test.d.ts +1 -0
- package/dist/thread-reducer.fixtures.test.js +360 -0
- package/dist/thread-reducer.fixtures.test.js.map +1 -0
- package/dist/thread-reducer.js +497 -0
- package/dist/thread-reducer.js.map +1 -0
- package/dist/thread-reducer.test.d.ts +1 -0
- package/dist/thread-reducer.test.js +369 -0
- package/dist/thread-reducer.test.js.map +1 -0
- package/dist/tts.test.d.ts +1 -0
- package/dist/tts.test.js +147 -0
- package/dist/tts.test.js.map +1 -0
- package/dist/voice-agent.d.ts +33 -0
- package/dist/voice-agent.js +159 -0
- package/dist/voice-agent.js.map +1 -0
- package/dist/voice-attachments.e2e.test.d.ts +1 -0
- package/dist/voice-attachments.e2e.test.js +253 -0
- package/dist/voice-attachments.e2e.test.js.map +1 -0
- package/dist/voice-call.d.ts +59 -0
- package/dist/voice-call.e2e.test.d.ts +1 -0
- package/dist/voice-call.e2e.test.js +259 -0
- package/dist/voice-call.e2e.test.js.map +1 -0
- package/dist/voice-call.js +760 -0
- package/dist/voice-call.js.map +1 -0
- package/dist/voice-openai.e2e.test.d.ts +1 -0
- package/dist/voice-openai.e2e.test.js +161 -0
- package/dist/voice-openai.e2e.test.js.map +1 -0
- package/dist/voice.d.ts +116 -0
- package/dist/voice.js +619 -717
- package/dist/voice.js.map +1 -0
- package/dist/working-directory.e2e.test.d.ts +1 -0
- package/dist/working-directory.e2e.test.js +231 -0
- package/dist/working-directory.e2e.test.js.map +1 -0
- package/dist/worktrees.d.ts +54 -0
- package/dist/worktrees.js +247 -709
- package/dist/worktrees.js.map +1 -0
- package/dist/worktrees.test.d.ts +1 -0
- package/dist/worktrees.test.js +97 -952
- package/dist/worktrees.test.js.map +1 -0
- package/package.json +38 -74
- package/src/agent-ui.e2e.test.ts +134 -0
- package/src/agent-ui.ts +216 -0
- package/src/analytics.e2e.test.ts +138 -0
- package/src/analytics.test.ts +122 -182
- package/src/analytics.ts +206 -258
- package/src/autostart.ts +78 -0
- package/src/bot.ts +194 -0
- package/src/btw.e2e.test.ts +130 -0
- package/src/catalog-refresh.e2e.test.ts +112 -0
- package/src/cli/bot.ts +419 -0
- package/src/cli/discord.ts +116 -0
- package/src/cli/project.ts +147 -0
- package/src/cli/schedule.ts +151 -0
- package/src/cli/session.ts +285 -0
- package/src/cli/shared.ts +139 -0
- package/src/cli-discord.e2e.test.ts +62 -0
- package/src/cli-lock.e2e.test.ts +530 -0
- package/src/cli-read.e2e.test.ts +78 -0
- package/src/cli-sessions.e2e.test.ts +122 -0
- package/src/cli.ts +35 -418
- package/src/commands/login-commands.ts +360 -0
- package/src/commands/preference-commands.ts +586 -0
- package/src/commands/session-commands.ts +289 -0
- package/src/commands/thread-commands.ts +324 -0
- package/src/commands/worktree-commands.ts +288 -0
- package/src/commands.e2e.test.ts +290 -0
- package/src/credentials.ts +425 -0
- package/src/db.test.ts +344 -759
- package/src/db.ts +66 -284
- package/src/duration.ts +18 -0
- package/src/effects.ts +303 -0
- package/src/errors.ts +39 -228
- package/src/event-loop.ts +462 -0
- package/src/file-edit-log.test.ts +68 -272
- package/src/file-edit-log.ts +108 -231
- package/src/fixtures/v1-schema.sql +241 -0
- package/src/fixtures/voice.ogg +0 -0
- package/src/format-parts.test.ts +150 -0
- package/src/format-parts.ts +405 -0
- package/src/gateway-replay.e2e.test.ts +116 -0
- package/src/harness.e2e.test.ts +124 -0
- package/src/hello-thread.e2e.test.ts +223 -0
- package/src/ingress.ts +334 -0
- package/src/interaction-context.ts +131 -0
- package/src/interrupt.e2e.test.ts +151 -0
- package/src/legacy.e2e.test.ts +105 -0
- package/src/live-call.ts +249 -0
- package/src/lock-routes.ts +625 -0
- package/src/lock-server.ts +233 -0
- package/src/logger.ts +120 -207
- package/src/login.e2e.test.ts +86 -0
- package/src/main.ts +230 -0
- package/src/markdown/components.ts +102 -0
- package/src/markdown/markdown.test.ts +414 -0
- package/src/markdown/render-markdown.ts +288 -0
- package/src/migrations.ts +198 -0
- package/src/onboarding-cli.e2e.test.ts +215 -0
- package/src/onboarding.e2e.test.ts +171 -0
- package/src/onboarding.ts +297 -0
- package/src/opencode-server.test.ts +24 -0
- package/src/opencode-server.ts +461 -0
- package/src/permissions.e2e.test.ts +191 -0
- package/src/permissions.ts +121 -0
- package/src/plugin/anthropic/index.test.ts +39 -0
- package/src/plugin/anthropic/index.ts +213 -0
- package/src/plugin/index.ts +93 -0
- package/src/plugin/session-id/index.ts +19 -0
- package/src/plugin.e2e.test.ts +112 -0
- package/src/preference-commands.e2e.test.ts +597 -0
- package/src/project.ts +216 -0
- package/src/prompt.ts +664 -0
- package/src/questions.e2e.test.ts +328 -0
- package/src/questions.ts +322 -0
- package/src/queue.e2e.test.ts +253 -0
- package/src/queue.ts +158 -0
- package/src/remote-send.e2e.test.ts +91 -0
- package/src/remote-send.ts +110 -0
- package/src/renderer.e2e.test.ts +390 -0
- package/src/restart.e2e.test.ts +90 -0
- package/src/routes.test.ts +81 -0
- package/src/routes.ts +48 -0
- package/src/routines.e2e.test.ts +210 -0
- package/src/scheduler.e2e.test.ts +182 -0
- package/src/scheduler.test.ts +183 -0
- package/src/scheduler.ts +648 -0
- package/src/schema-sql.ts +3 -0
- package/src/schema.ts +95 -271
- package/src/session-commands.e2e.test.ts +326 -0
- package/src/session-events.ts +218 -0
- package/src/session-ops.e2e.test.ts +141 -0
- package/src/sessions.ts +803 -0
- package/src/shell.e2e.test.ts +173 -0
- package/src/slash-commands.test.ts +89 -0
- package/src/slash-commands.ts +539 -0
- package/src/sleep.e2e.test.ts +135 -552
- package/src/sleeps.ts +230 -0
- package/src/store.ts +19 -217
- package/src/system-prompt.ts +944 -0
- package/src/test/auth-plugin/index.ts +17 -0
- package/src/test/fake-mcp-server.ts +49 -0
- package/src/test/harness.ts +957 -0
- package/src/test/replay.ts +90 -0
- package/src/thread-reducer.fixtures.test.ts +374 -0
- package/src/thread-reducer.test.ts +380 -0
- package/src/thread-reducer.ts +671 -0
- package/src/tts.test.ts +150 -0
- package/src/voice-agent.ts +196 -0
- package/src/voice-attachments.e2e.test.ts +298 -0
- package/src/voice-call.e2e.test.ts +293 -0
- package/src/voice-call.ts +764 -0
- package/src/voice-openai.e2e.test.ts +191 -0
- package/src/voice.ts +668 -988
- package/src/working-directory.e2e.test.ts +226 -0
- package/src/worktrees.test.ts +89 -1115
- package/src/worktrees.ts +195 -957
- package/bin.js +0 -2
- package/dist/agent-model.e2e.test.js +0 -1223
- package/dist/ai-tool-to-genai.js +0 -233
- package/dist/ai-tool-to-genai.test.js +0 -267
- package/dist/ai-tool.js +0 -6
- package/dist/anthropic-account-identity.js +0 -70
- package/dist/anthropic-account-identity.test.js +0 -38
- package/dist/anthropic-auth-plugin.js +0 -958
- package/dist/anthropic-auth-plugin.test.js +0 -115
- package/dist/anthropic-auth-state.js +0 -186
- package/dist/anthropic-auth-state.test.js +0 -203
- package/dist/bash-tool-schema-plugin.js +0 -50
- package/dist/bash-tool-schema-plugin.test.js +0 -68
- package/dist/bin.js +0 -151
- package/dist/bot-lifecycle.test.js +0 -206
- package/dist/btw-prefix-detection.js +0 -24
- package/dist/btw-prefix-detection.test.js +0 -130
- package/dist/cache-drift-plugin.js +0 -183
- package/dist/cache-rewrite.js +0 -39
- package/dist/cache-rewrite.test.js +0 -41
- package/dist/channel-management.js +0 -347
- package/dist/cli-commands/bot.js +0 -254
- package/dist/cli-commands/maintenance.js +0 -171
- package/dist/cli-commands/misc.js +0 -153
- package/dist/cli-commands/project.js +0 -510
- package/dist/cli-commands/send.js +0 -659
- package/dist/cli-commands/session.js +0 -889
- package/dist/cli-commands/task.js +0 -277
- package/dist/cli-commands/thread.js +0 -63
- package/dist/cli-commands/user.js +0 -145
- package/dist/cli-parsing.test.js +0 -226
- package/dist/cli-runner.js +0 -1591
- package/dist/cli-runner.test.js +0 -119
- package/dist/cli-send-thread.e2e.test.js +0 -470
- package/dist/cloudflare-transcription.js +0 -56
- package/dist/commands/abort.js +0 -84
- package/dist/commands/action-buttons.js +0 -248
- package/dist/commands/add-project.js +0 -111
- package/dist/commands/agent.js +0 -658
- package/dist/commands/ask-question.js +0 -371
- package/dist/commands/ask-question.test.js +0 -150
- package/dist/commands/btw.js +0 -275
- package/dist/commands/compact.js +0 -117
- package/dist/commands/context-usage.js +0 -194
- package/dist/commands/context-usage.test.js +0 -49
- package/dist/commands/create-new-project.js +0 -138
- package/dist/commands/diff.js +0 -63
- package/dist/commands/file-upload.js +0 -280
- package/dist/commands/fork-subagent.js +0 -175
- package/dist/commands/fork.js +0 -291
- package/dist/commands/gemini-apikey.js +0 -123
- package/dist/commands/last-sessions.js +0 -129
- package/dist/commands/login.js +0 -893
- package/dist/commands/mcp.js +0 -239
- package/dist/commands/memory-snapshot.js +0 -24
- package/dist/commands/mention-mode.js +0 -42
- package/dist/commands/merge-worktree.js +0 -205
- package/dist/commands/model-variant.js +0 -390
- package/dist/commands/model.js +0 -1012
- package/dist/commands/multioauth.js +0 -425
- package/dist/commands/new-worktree.js +0 -625
- package/dist/commands/paginated-select.js +0 -57
- package/dist/commands/permissions.js +0 -327
- package/dist/commands/queue.js +0 -347
- package/dist/commands/queue.test.js +0 -15
- package/dist/commands/remove-project.js +0 -111
- package/dist/commands/restart-opencode-server.js +0 -133
- package/dist/commands/resume.js +0 -148
- package/dist/commands/run-command.js +0 -79
- package/dist/commands/screenshare.js +0 -307
- package/dist/commands/screenshare.test.js +0 -20
- package/dist/commands/session-id.js +0 -78
- package/dist/commands/session.js +0 -248
- package/dist/commands/share.js +0 -80
- package/dist/commands/tasks.js +0 -296
- package/dist/commands/types.js +0 -2
- package/dist/commands/undo-redo.js +0 -313
- package/dist/commands/unset-model.js +0 -116
- package/dist/commands/upgrade.js +0 -41
- package/dist/commands/user-command.js +0 -196
- package/dist/commands/verbosity.js +0 -124
- package/dist/commands/vscode.js +0 -295
- package/dist/commands/worktrees.js +0 -548
- package/dist/condense-memory.js +0 -33
- package/dist/config.js +0 -126
- package/dist/context-awareness-plugin.js +0 -357
- package/dist/context-awareness-plugin.test.js +0 -126
- package/dist/cpu-profiler.js +0 -211
- package/dist/cpu-profiler.test.js +0 -160
- package/dist/critique-utils.js +0 -95
- package/dist/database.js +0 -1074
- package/dist/debounce-timeout.js +0 -28
- package/dist/debounced-process-flush.js +0 -77
- package/dist/default-channel-provisioning.test.js +0 -149
- package/dist/discord-bot.js +0 -1432
- package/dist/discord-command-registration.js +0 -519
- package/dist/discord-command-registration.test.js +0 -17
- package/dist/discord-urls.js +0 -81
- package/dist/discord-utils.js +0 -789
- package/dist/discord-utils.test.js +0 -400
- package/dist/escape-backticks.test.js +0 -429
- package/dist/event-stream-real-capture.e2e.test.js +0 -533
- package/dist/eventsource-parser.test.js +0 -327
- package/dist/exec-async.js +0 -38
- package/dist/external-directory-permissions.e2e.test.js +0 -86
- package/dist/external-directory-project-deny.e2e.test.js +0 -70
- package/dist/external-opencode-sync.js +0 -620
- package/dist/external-opencode-sync.test.js +0 -206
- package/dist/extract-sdk-error-message.test.js +0 -13
- package/dist/format-tables.js +0 -728
- package/dist/format-tables.test.js +0 -915
- package/dist/forum-sync/config.js +0 -79
- package/dist/forum-sync/discord-operations.js +0 -157
- package/dist/forum-sync/index.js +0 -5
- package/dist/forum-sync/markdown.js +0 -110
- package/dist/forum-sync/sync-to-discord.js +0 -417
- package/dist/forum-sync/sync-to-files.js +0 -190
- package/dist/forum-sync/types.js +0 -53
- package/dist/forum-sync/watchers.js +0 -322
- package/dist/gateway-proxy-reconnect.e2e.test.js +0 -414
- package/dist/gateway-proxy.e2e.test.js +0 -488
- package/dist/genai-worker-wrapper.js +0 -111
- package/dist/genai-worker.js +0 -309
- package/dist/genai.js +0 -232
- package/dist/git-worktree-core.js +0 -461
- package/dist/guild-categories.test.js +0 -225
- package/dist/heap-monitor.js +0 -122
- package/dist/hrana-server.js +0 -322
- package/dist/hrana-server.test.js +0 -99
- package/dist/html-actions.js +0 -123
- package/dist/html-actions.test.js +0 -70
- package/dist/html-components.js +0 -115
- package/dist/html-components.test.js +0 -34
- package/dist/image-optimizer-plugin.js +0 -153
- package/dist/image-utils.js +0 -112
- package/dist/interaction-handler.js +0 -578
- package/dist/ipc-polling.js +0 -245
- package/dist/ipc-tools-plugin.js +0 -251
- package/dist/kimaki-digital-twin.e2e.test.js +0 -161
- package/dist/kimaki-opencode-plugin-loading.e2e.test.js +0 -158
- package/dist/kimaki-opencode-plugin.js +0 -33
- package/dist/kimaki-opencode-plugin.test.js +0 -126
- package/dist/kimaki-workspace-adaptor.js +0 -118
- package/dist/limit-heading-depth.js +0 -25
- package/dist/limit-heading-depth.test.js +0 -105
- package/dist/list-channel-threads.js +0 -163
- package/dist/list-channel-threads.test.js +0 -80
- package/dist/markdown.js +0 -455
- package/dist/markdown.test.js +0 -411
- package/dist/memory-overview-plugin.js +0 -123
- package/dist/message-formatting.js +0 -788
- package/dist/message-formatting.test.js +0 -1132
- package/dist/message-preprocessing.js +0 -419
- package/dist/oauth-rotation-shared.js +0 -253
- package/dist/onboarding-tutorial.js +0 -163
- package/dist/onboarding-welcome.js +0 -37
- package/dist/openai-auth-plugin.js +0 -125
- package/dist/openai-auth-state.js +0 -237
- package/dist/openai-realtime.js +0 -224
- package/dist/opencode-command-detection.js +0 -65
- package/dist/opencode-command-detection.test.js +0 -240
- package/dist/opencode-command.js +0 -181
- package/dist/opencode-command.test.js +0 -218
- package/dist/opencode-interrupt-plugin.js +0 -253
- package/dist/opencode-interrupt-plugin.test.js +0 -293
- package/dist/opencode.js +0 -1217
- package/dist/parse-permission-rules.test.js +0 -117
- package/dist/patch-text-parser.js +0 -97
- package/dist/plugin-logger.js +0 -105
- package/dist/plugin-opencode-client.js +0 -54
- package/dist/privacy-sanitizer.js +0 -105
- package/dist/project-add.test.js +0 -62
- package/dist/question-abort-clears-dropdown.e2e.test.js +0 -89
- package/dist/question-abort-resume.e2e.test.js +0 -100
- package/dist/question-abort-retry-text-before-dropdown.e2e.test.js +0 -150
- package/dist/question-text-before-dropdown.e2e.test.js +0 -52
- package/dist/queue-advanced-abort.e2e.test.js +0 -348
- package/dist/queue-advanced-action-buttons.e2e.test.js +0 -209
- package/dist/queue-advanced-e2e-setup.js +0 -1043
- package/dist/queue-advanced-footer.e2e.test.js +0 -286
- package/dist/queue-advanced-model-switch.e2e.test.js +0 -297
- package/dist/queue-advanced-permissions-typing.e2e.test.js +0 -189
- package/dist/queue-advanced-question.e2e.test.js +0 -266
- package/dist/queue-advanced-typing-interrupt.e2e.test.js +0 -113
- package/dist/queue-advanced-typing.e2e.test.js +0 -151
- package/dist/queue-delete-message.e2e.test.js +0 -216
- package/dist/queue-drain-after-interactive-ui.e2e.test.js +0 -120
- package/dist/queue-interrupt-drain.e2e.test.js +0 -256
- package/dist/queue-question-select-drain.e2e.test.js +0 -162
- package/dist/runtime-idle-sweeper.js +0 -52
- package/dist/runtime-lifecycle.e2e.test.js +0 -570
- package/dist/sentry.js +0 -23
- package/dist/session-handler/agent-utils.js +0 -65
- package/dist/session-handler/event-stream-state.js +0 -1225
- package/dist/session-handler/event-stream-state.test.js +0 -3160
- package/dist/session-handler/global-event-listener.js +0 -212
- package/dist/session-handler/model-utils.js +0 -311
- package/dist/session-handler/model-utils.test.js +0 -445
- package/dist/session-handler/opencode-session-event-log.js +0 -121
- package/dist/session-handler/thread-ingress.test.js +0 -41
- package/dist/session-handler/thread-runtime-state.js +0 -209
- package/dist/session-handler/thread-session-runtime-summary.test.js +0 -121
- package/dist/session-handler/thread-session-runtime.js +0 -4320
- package/dist/session-handler.js +0 -9
- package/dist/session-search.js +0 -219
- package/dist/session-search.test.js +0 -287
- package/dist/session-sleep.test.js +0 -224
- package/dist/session-title-rename.test.js +0 -128
- package/dist/skill-filter.js +0 -43
- package/dist/skill-filter.test.js +0 -86
- package/dist/startup-service.js +0 -153
- package/dist/startup-time.e2e.test.js +0 -297
- package/dist/system-message.js +0 -806
- package/dist/system-message.test.js +0 -917
- package/dist/task-id-plugin.js +0 -16
- package/dist/task-runner.js +0 -554
- package/dist/task-schedule.js +0 -298
- package/dist/task-schedule.test.js +0 -366
- package/dist/test-utils.js +0 -385
- package/dist/thinking-utils.js +0 -45
- package/dist/thinking-utils.test.js +0 -35
- package/dist/thread-message-queue.e2e.test.js +0 -1227
- package/dist/tools.js +0 -357
- package/dist/undo-redo.e2e.test.js +0 -171
- package/dist/unnest-code-blocks.js +0 -146
- package/dist/unnest-code-blocks.test.js +0 -673
- package/dist/upgrade.js +0 -114
- package/dist/utils.js +0 -148
- package/dist/voice-attachment.js +0 -56
- package/dist/voice-handler.js +0 -727
- package/dist/voice-message.e2e.test.js +0 -1254
- package/dist/voice-routing-input.e2e.test.js +0 -195
- package/dist/voice-routing-question.e2e.test.js +0 -182
- package/dist/voice.test.js +0 -500
- package/dist/wait-session.js +0 -193
- package/dist/websockify.js +0 -69
- package/dist/worker-types.js +0 -4
- package/dist/worktree-clone-isolation.e2e.test.js +0 -188
- package/dist/worktree-lifecycle.e2e.test.js +0 -735
- package/dist/worktree-utils.js +0 -3
- package/dist/xai-auth-plugin.js +0 -238
- package/dist/xai-auth-state.js +0 -234
- package/dist/xai-auth-state.test.js +0 -183
- package/dist/xml.js +0 -92
- package/dist/xml.test.js +0 -32
- package/skills/bump-holocron-consumers/SKILL.md +0 -137
- package/skills/critique/SKILL.md +0 -116
- package/skills/egaki/SKILL.md +0 -86
- package/skills/errore/SKILL.md +0 -501
- package/skills/goke/SKILL.md +0 -695
- package/skills/holocron/SKILL.md +0 -942
- package/skills/lintcn/SKILL.md +0 -873
- package/skills/new-skill/SKILL.md +0 -339
- package/skills/npm-package/SKILL.md +0 -692
- package/skills/opensrc/SKILL.md +0 -102
- package/skills/playwriter/SKILL.md +0 -35
- package/skills/profano/SKILL.md +0 -33
- package/skills/readme.md +0 -20
- package/skills/sigillo/SKILL.md +0 -370
- package/skills/spiceflow/SKILL.md +0 -80
- package/skills/strada/SKILL.md +0 -104
- package/skills/termcast/SKILL.md +0 -133
- package/skills/tuistory/SKILL.md +0 -237
- package/skills/usecomputer/SKILL.md +0 -264
- package/skills/zele/SKILL.md +0 -81
- package/src/agent-model.e2e.test.ts +0 -1557
- package/src/ai-tool-to-genai.test.ts +0 -296
- package/src/ai-tool-to-genai.ts +0 -283
- package/src/ai-tool.ts +0 -39
- package/src/anthropic-account-identity.test.ts +0 -52
- package/src/anthropic-account-identity.ts +0 -96
- package/src/anthropic-auth-plugin.test.ts +0 -135
- package/src/anthropic-auth-plugin.ts +0 -1180
- package/src/anthropic-auth-state.test.ts +0 -259
- package/src/anthropic-auth-state.ts +0 -272
- package/src/bash-tool-schema-plugin.test.ts +0 -84
- package/src/bash-tool-schema-plugin.ts +0 -77
- package/src/bin.ts +0 -173
- package/src/bot-lifecycle.test.ts +0 -252
- package/src/btw-prefix-detection.test.ts +0 -142
- package/src/btw-prefix-detection.ts +0 -30
- package/src/cache-drift-plugin.ts +0 -249
- package/src/cache-rewrite.test.ts +0 -49
- package/src/cache-rewrite.ts +0 -96
- package/src/channel-management.ts +0 -494
- package/src/cli-commands/bot.ts +0 -374
- package/src/cli-commands/maintenance.ts +0 -237
- package/src/cli-commands/misc.ts +0 -208
- package/src/cli-commands/project.ts +0 -680
- package/src/cli-commands/send.ts +0 -885
- package/src/cli-commands/session.ts +0 -1181
- package/src/cli-commands/task.ts +0 -358
- package/src/cli-commands/thread.ts +0 -86
- package/src/cli-commands/user.ts +0 -195
- package/src/cli-parsing.test.ts +0 -305
- package/src/cli-runner.test.ts +0 -166
- package/src/cli-runner.ts +0 -2157
- package/src/cli-send-thread.e2e.test.ts +0 -609
- package/src/cloudflare-transcription.ts +0 -76
- package/src/commands/abort.ts +0 -113
- package/src/commands/action-buttons.ts +0 -371
- package/src/commands/add-project.ts +0 -146
- package/src/commands/agent.ts +0 -911
- package/src/commands/ask-question.test.ts +0 -177
- package/src/commands/ask-question.ts +0 -532
- package/src/commands/btw.ts +0 -356
- package/src/commands/compact.ts +0 -154
- package/src/commands/context-usage.test.ts +0 -57
- package/src/commands/context-usage.ts +0 -267
- package/src/commands/create-new-project.ts +0 -203
- package/src/commands/diff.ts +0 -91
- package/src/commands/file-upload.ts +0 -398
- package/src/commands/fork-subagent.ts +0 -262
- package/src/commands/fork.ts +0 -421
- package/src/commands/gemini-apikey.ts +0 -205
- package/src/commands/last-sessions.ts +0 -176
- package/src/commands/login.ts +0 -1182
- package/src/commands/mcp.ts +0 -307
- package/src/commands/memory-snapshot.ts +0 -30
- package/src/commands/mention-mode.ts +0 -66
- package/src/commands/merge-worktree.ts +0 -282
- package/src/commands/model-variant.ts +0 -522
- package/src/commands/model.ts +0 -1377
- package/src/commands/multioauth.ts +0 -508
- package/src/commands/new-worktree.ts +0 -835
- package/src/commands/paginated-select.ts +0 -81
- package/src/commands/permissions.ts +0 -458
- package/src/commands/queue.test.ts +0 -19
- package/src/commands/queue.ts +0 -471
- package/src/commands/remove-project.ts +0 -152
- package/src/commands/restart-opencode-server.ts +0 -173
- package/src/commands/resume.ts +0 -229
- package/src/commands/run-command.ts +0 -123
- package/src/commands/screenshare.test.ts +0 -30
- package/src/commands/screenshare.ts +0 -388
- package/src/commands/session-id.ts +0 -109
- package/src/commands/session.ts +0 -319
- package/src/commands/share.ts +0 -106
- package/src/commands/tasks.ts +0 -399
- package/src/commands/types.ts +0 -25
- package/src/commands/undo-redo.ts +0 -394
- package/src/commands/unset-model.ts +0 -152
- package/src/commands/upgrade.ts +0 -51
- package/src/commands/user-command.ts +0 -260
- package/src/commands/verbosity.ts +0 -172
- package/src/commands/vscode.ts +0 -378
- package/src/commands/worktrees.ts +0 -762
- package/src/condense-memory.ts +0 -36
- package/src/config.ts +0 -147
- package/src/context-awareness-plugin.test.ts +0 -144
- package/src/context-awareness-plugin.ts +0 -508
- package/src/cpu-profiler.test.ts +0 -183
- package/src/cpu-profiler.ts +0 -293
- package/src/critique-utils.ts +0 -139
- package/src/database.ts +0 -1484
- package/src/debounce-timeout.ts +0 -43
- package/src/debounced-process-flush.ts +0 -104
- package/src/default-channel-provisioning.test.ts +0 -156
- package/src/discord-bot.ts +0 -1852
- package/src/discord-command-registration.test.ts +0 -20
- package/src/discord-command-registration.ts +0 -704
- package/src/discord-urls.ts +0 -88
- package/src/discord-utils.test.ts +0 -470
- package/src/discord-utils.ts +0 -1079
- package/src/escape-backticks.test.ts +0 -469
- package/src/event-stream-real-capture.e2e.test.ts +0 -692
- package/src/eventsource-parser.test.ts +0 -351
- package/src/exec-async.ts +0 -44
- package/src/external-directory-permissions.e2e.test.ts +0 -103
- package/src/external-directory-project-deny.e2e.test.ts +0 -84
- package/src/external-opencode-sync.test.ts +0 -248
- package/src/external-opencode-sync.ts +0 -867
- package/src/extract-sdk-error-message.test.ts +0 -18
- package/src/format-tables.test.ts +0 -988
- package/src/format-tables.ts +0 -1031
- package/src/forum-sync/config.ts +0 -92
- package/src/forum-sync/discord-operations.ts +0 -245
- package/src/forum-sync/index.ts +0 -9
- package/src/forum-sync/markdown.ts +0 -172
- package/src/forum-sync/sync-to-discord.ts +0 -595
- package/src/forum-sync/sync-to-files.ts +0 -294
- package/src/forum-sync/types.ts +0 -175
- package/src/forum-sync/watchers.ts +0 -474
- package/src/gateway-proxy-reconnect.e2e.test.ts +0 -553
- package/src/gateway-proxy.e2e.test.ts +0 -648
- package/src/genai-worker-wrapper.ts +0 -164
- package/src/genai-worker.ts +0 -385
- package/src/genai.ts +0 -318
- package/src/git-worktree-core.ts +0 -616
- package/src/guild-categories.test.ts +0 -260
- package/src/heap-monitor.ts +0 -152
- package/src/hrana-server.test.ts +0 -130
- package/src/hrana-server.ts +0 -399
- package/src/html-actions.test.ts +0 -87
- package/src/html-actions.ts +0 -174
- package/src/html-components.test.ts +0 -38
- package/src/html-components.ts +0 -177
- package/src/image-optimizer-plugin.ts +0 -194
- package/src/image-utils.ts +0 -150
- package/src/interaction-handler.ts +0 -775
- package/src/ipc-polling.ts +0 -325
- package/src/ipc-tools-plugin.ts +0 -306
- package/src/kimaki-digital-twin.e2e.test.ts +0 -199
- package/src/kimaki-opencode-plugin-loading.e2e.test.ts +0 -208
- package/src/kimaki-opencode-plugin.test.ts +0 -142
- package/src/kimaki-opencode-plugin.ts +0 -34
- package/src/kimaki-workspace-adaptor.ts +0 -144
- package/src/limit-heading-depth.test.ts +0 -116
- package/src/limit-heading-depth.ts +0 -26
- package/src/list-channel-threads.test.ts +0 -90
- package/src/list-channel-threads.ts +0 -252
- package/src/markdown.test.ts +0 -498
- package/src/markdown.ts +0 -577
- package/src/memory-overview-plugin.ts +0 -159
- package/src/message-formatting.test.ts +0 -1401
- package/src/message-formatting.ts +0 -999
- package/src/message-preprocessing.ts +0 -557
- package/src/oauth-rotation-shared.ts +0 -332
- package/src/onboarding-tutorial.ts +0 -167
- package/src/onboarding-welcome.ts +0 -49
- package/src/openai-auth-plugin.ts +0 -158
- package/src/openai-auth-state.ts +0 -297
- package/src/openai-realtime.ts +0 -358
- package/src/opencode-command-detection.test.ts +0 -307
- package/src/opencode-command-detection.ts +0 -76
- package/src/opencode-command.test.ts +0 -290
- package/src/opencode-command.ts +0 -251
- package/src/opencode-interrupt-plugin.test.ts +0 -419
- package/src/opencode-interrupt-plugin.ts +0 -306
- package/src/opencode.ts +0 -1590
- package/src/parse-permission-rules.test.ts +0 -127
- package/src/patch-text-parser.ts +0 -107
- package/src/plugin-logger.ts +0 -139
- package/src/plugin-opencode-client.ts +0 -71
- package/src/privacy-sanitizer.ts +0 -142
- package/src/project-add.test.ts +0 -80
- package/src/question-abort-clears-dropdown.e2e.test.ts +0 -109
- package/src/question-abort-resume.e2e.test.ts +0 -121
- package/src/question-abort-retry-text-before-dropdown.e2e.test.ts +0 -172
- package/src/question-text-before-dropdown.e2e.test.ts +0 -67
- package/src/queue-advanced-abort.e2e.test.ts +0 -449
- package/src/queue-advanced-action-buttons.e2e.test.ts +0 -271
- package/src/queue-advanced-e2e-setup.ts +0 -1164
- package/src/queue-advanced-footer.e2e.test.ts +0 -357
- package/src/queue-advanced-model-switch.e2e.test.ts +0 -382
- package/src/queue-advanced-permissions-typing.e2e.test.ts +0 -256
- package/src/queue-advanced-question.e2e.test.ts +0 -322
- package/src/queue-advanced-typing-interrupt.e2e.test.ts +0 -147
- package/src/queue-advanced-typing.e2e.test.ts +0 -199
- package/src/queue-delete-message.e2e.test.ts +0 -262
- package/src/queue-drain-after-interactive-ui.e2e.test.ts +0 -152
- package/src/queue-interrupt-drain.e2e.test.ts +0 -299
- package/src/queue-question-select-drain.e2e.test.ts +0 -209
- package/src/runtime-idle-sweeper.ts +0 -76
- package/src/runtime-lifecycle.e2e.test.ts +0 -714
- package/src/schema.sql +0 -251
- package/src/sentry.ts +0 -26
- package/src/session-handler/agent-utils.ts +0 -104
- package/src/session-handler/event-stream-fixtures/real-session-action-buttons.jsonl +0 -45
- package/src/session-handler/event-stream-fixtures/real-session-footer-suppressed-on-pre-idle-interrupt.jsonl +0 -40
- package/src/session-handler/event-stream-fixtures/real-session-permission-external-file.jsonl +0 -23
- package/src/session-handler/event-stream-fixtures/real-session-task-normal.jsonl +0 -22
- package/src/session-handler/event-stream-fixtures/real-session-task-three-parallel-sleeps.jsonl +0 -277
- package/src/session-handler/event-stream-fixtures/real-session-task-user-interruption.jsonl +0 -46
- package/src/session-handler/event-stream-fixtures/session-abort-after-idle-race.jsonl +0 -21
- package/src/session-handler/event-stream-fixtures/session-concurrent-messages-serialized.jsonl +0 -56
- package/src/session-handler/event-stream-fixtures/session-explicit-abort.jsonl +0 -44
- package/src/session-handler/event-stream-fixtures/session-normal-completion.jsonl +0 -29
- package/src/session-handler/event-stream-fixtures/session-tool-call-noisy-stream.jsonl +0 -29
- package/src/session-handler/event-stream-fixtures/session-two-completions-same-session.jsonl +0 -50
- package/src/session-handler/event-stream-fixtures/session-user-interruption.jsonl +0 -59
- package/src/session-handler/event-stream-fixtures/session-voice-queued-followup.jsonl +0 -52
- package/src/session-handler/event-stream-state.test.ts +0 -3431
- package/src/session-handler/event-stream-state.ts +0 -1792
- package/src/session-handler/global-event-listener.ts +0 -258
- package/src/session-handler/model-utils.test.ts +0 -537
- package/src/session-handler/model-utils.ts +0 -489
- package/src/session-handler/opencode-session-event-log.ts +0 -159
- package/src/session-handler/thread-ingress.test.ts +0 -54
- package/src/session-handler/thread-runtime-state.ts +0 -358
- package/src/session-handler/thread-session-runtime-summary.test.ts +0 -169
- package/src/session-handler/thread-session-runtime.ts +0 -5696
- package/src/session-handler.ts +0 -15
- package/src/session-search.test.ts +0 -331
- package/src/session-search.ts +0 -382
- package/src/session-sleep.test.ts +0 -294
- package/src/session-title-rename.test.ts +0 -186
- package/src/skill-filter.test.ts +0 -110
- package/src/skill-filter.ts +0 -63
- package/src/startup-service.ts +0 -200
- package/src/startup-time.e2e.test.ts +0 -377
- package/src/system-message.test.ts +0 -1013
- package/src/system-message.ts +0 -1043
- package/src/task-id-plugin.ts +0 -17
- package/src/task-runner.ts +0 -768
- package/src/task-schedule.test.ts +0 -424
- package/src/task-schedule.ts +0 -470
- package/src/test-utils.ts +0 -549
- package/src/thinking-utils.test.ts +0 -46
- package/src/thinking-utils.ts +0 -82
- package/src/thread-message-queue.e2e.test.ts +0 -1468
- package/src/tools.ts +0 -430
- package/src/undici.d.ts +0 -12
- package/src/undo-redo.e2e.test.ts +0 -219
- package/src/unnest-code-blocks.test.ts +0 -713
- package/src/unnest-code-blocks.ts +0 -185
- package/src/upgrade.ts +0 -127
- package/src/utils.ts +0 -216
- package/src/voice-attachment.ts +0 -79
- package/src/voice-handler.ts +0 -1000
- package/src/voice-message.e2e.test.ts +0 -1513
- package/src/voice-routing-input.e2e.test.ts +0 -203
- package/src/voice-routing-question.e2e.test.ts +0 -188
- package/src/voice.test.ts +0 -565
- package/src/wait-session.ts +0 -291
- package/src/websockify.ts +0 -101
- package/src/worker-types.ts +0 -64
- package/src/worktree-clone-isolation.e2e.test.ts +0 -213
- package/src/worktree-lifecycle.e2e.test.ts +0 -900
- package/src/worktree-utils.ts +0 -4
- package/src/xai-auth-plugin.ts +0 -303
- package/src/xai-auth-state.test.ts +0 -224
- package/src/xai-auth-state.ts +0 -294
- package/src/xml.test.ts +0 -38
- package/src/xml.ts +0 -121
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// Every SQLite migration of kimaki, in one place. Only the bot start runs it
|
|
2
|
+
// (openDb({ migrate: true })); subcommands never migrate.
|
|
3
|
+
//
|
|
4
|
+
// <dataDir>/kimaki.db present without the DB_VERSION marker, next to a V1 file?
|
|
5
|
+
// └─ not made by kimaki: rename it to kimaki.db.unknown-<time> (never deleted)
|
|
6
|
+
// <dataDir>/kimaki.db missing?
|
|
7
|
+
// └─ <dataDir>/discord-sessions.db (V1) present?
|
|
8
|
+
// yes ─▶ build kimaki.db.import from schema.sql + the V1 rows of the
|
|
9
|
+
// tables kimaki uses, then rename it to kimaki.db (atomic: a
|
|
10
|
+
// crash leaves no half-imported kimaki.db, the next start retries)
|
|
11
|
+
// no ─▶ empty kimaki.db
|
|
12
|
+
// then: schema.sql (CREATE ... IF NOT EXISTS) + the marker on kimaki.db
|
|
13
|
+
//
|
|
14
|
+
// The V1 file is opened read-only and never changed or deleted, so V1 keeps
|
|
15
|
+
// working on its own data. There is no downgrade: changes made by kimaki stay in
|
|
16
|
+
// kimaki.db. Future schema changes (ALTER TABLE ... ADD COLUMN) go in
|
|
17
|
+
// migrateSchema() below.
|
|
18
|
+
|
|
19
|
+
import fs from 'node:fs'
|
|
20
|
+
import path from 'node:path'
|
|
21
|
+
import { createClient, type Client } from '@libsql/client'
|
|
22
|
+
import * as errore from 'errore'
|
|
23
|
+
|
|
24
|
+
import { DbError } from './errors.ts'
|
|
25
|
+
import { createLogger } from './logger.ts'
|
|
26
|
+
import { SCHEMA_SQL } from './schema-sql.ts'
|
|
27
|
+
|
|
28
|
+
const logger = createLogger('DB')
|
|
29
|
+
|
|
30
|
+
export const DB_FILE = 'kimaki.db'
|
|
31
|
+
export const LEGACY_DB_FILE = 'discord-sessions.db'
|
|
32
|
+
|
|
33
|
+
// PRAGMA user_version of every kimaki.db written by migrateSchema(). A stray
|
|
34
|
+
// kimaki.db without it (an empty file from another tool, a pre-marker dev
|
|
35
|
+
// build) must not block the V1 import: then the user gets onboarding again.
|
|
36
|
+
export const DB_VERSION = 1
|
|
37
|
+
|
|
38
|
+
// Parents first, so imported rows satisfy the foreign keys.
|
|
39
|
+
const IMPORTED_TABLES = [
|
|
40
|
+
'bot_tokens',
|
|
41
|
+
'bot_api_keys',
|
|
42
|
+
'guild_categories',
|
|
43
|
+
'channel_directories',
|
|
44
|
+
'channel_models',
|
|
45
|
+
'global_models',
|
|
46
|
+
'channel_agents',
|
|
47
|
+
'channel_worktrees',
|
|
48
|
+
'channel_verbosity',
|
|
49
|
+
'channel_mention_mode',
|
|
50
|
+
'thread_sessions',
|
|
51
|
+
'scheduled_tasks',
|
|
52
|
+
'session_sleeps',
|
|
53
|
+
] as const
|
|
54
|
+
|
|
55
|
+
// V1 values kimaki reads differently. Old V1 rows can carry the DDL default
|
|
56
|
+
// 'self-hosted' (hyphen) or NULL; kimaki only knows 'self_hosted' | 'gateway'.
|
|
57
|
+
const IMPORT_EXPRESSIONS: Partial<Record<(typeof IMPORTED_TABLES)[number], Record<string, string>>> = {
|
|
58
|
+
bot_tokens: { bot_mode: `CASE WHEN bot_mode = 'gateway' THEN 'gateway' ELSE 'self_hosted' END` },
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function schemaStatements(): string[] {
|
|
62
|
+
return SCHEMA_SQL.split(';')
|
|
63
|
+
.map((statement) => {
|
|
64
|
+
return statement
|
|
65
|
+
.split('\n')
|
|
66
|
+
.filter((line) => !line.trimStart().startsWith('--'))
|
|
67
|
+
.join('\n')
|
|
68
|
+
.trim()
|
|
69
|
+
})
|
|
70
|
+
.filter((statement) => statement.length > 0)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function columnsOf({ client, schema, table }: { client: Client; schema: 'main' | 'legacy'; table: string }) {
|
|
74
|
+
const rows = await client.execute(`PRAGMA ${schema}.table_info("${table}")`)
|
|
75
|
+
return rows.rows.map((row) => ({ name: String(row.name), notNull: Number(row.notnull) === 1 || Number(row.pk) > 0 }))
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// One entry per FK column: the schema has only single-column foreign keys
|
|
79
|
+
// with an explicit parent column. A composite FK would need grouping by `id`.
|
|
80
|
+
async function foreignKeysOf({ client, table }: { client: Client; table: string }) {
|
|
81
|
+
const rows = await client.execute(`PRAGMA main.foreign_key_list("${table}")`)
|
|
82
|
+
return rows.rows.map((row) => ({ column: String(row.from), parent: String(row.table), parentColumn: String(row.to) }))
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Copies the V1 rows into `client` (an empty file with schema.sql applied).
|
|
86
|
+
// Most V1 tables have no foreign keys, so real installs hold rows that point
|
|
87
|
+
// at deleted channels or threads: a required reference skips the row, an
|
|
88
|
+
// optional one becomes NULL (like ON DELETE SET NULL).
|
|
89
|
+
async function copyLegacyRows({ client, legacyFile }: { client: Client; legacyFile: string }): Promise<void> {
|
|
90
|
+
await client.execute({ sql: 'ATTACH DATABASE ? AS legacy', args: [`file:${legacyFile}?mode=ro`] })
|
|
91
|
+
for (const table of IMPORTED_TABLES) {
|
|
92
|
+
const legacyColumns = (await columnsOf({ client, schema: 'legacy', table })).map((column) => column.name)
|
|
93
|
+
if (legacyColumns.length === 0) {
|
|
94
|
+
logger.log(`import ${table}: not in ${LEGACY_DB_FILE}, skipped`)
|
|
95
|
+
continue
|
|
96
|
+
}
|
|
97
|
+
// Columns an older V1 file lacks get the kimaki default.
|
|
98
|
+
const columns = (await columnsOf({ client, schema: 'main', table })).filter((column) => legacyColumns.includes(column.name))
|
|
99
|
+
const foreignKeys = (await foreignKeysOf({ client, table })).filter((key) => legacyColumns.includes(key.column))
|
|
100
|
+
const existsIn = (key: (typeof foreignKeys)[number]) => `"${key.column}" IN (SELECT "${key.parentColumn}" FROM main."${key.parent}")`
|
|
101
|
+
const expressions = columns.map((column) => {
|
|
102
|
+
const custom = IMPORT_EXPRESSIONS[table]?.[column.name]
|
|
103
|
+
if (custom) return custom
|
|
104
|
+
const key = foreignKeys.find((candidate) => candidate.column === column.name)
|
|
105
|
+
if (key && !column.notNull) return `CASE WHEN ${existsIn(key)} THEN "${column.name}" END`
|
|
106
|
+
return `"${column.name}"`
|
|
107
|
+
})
|
|
108
|
+
const required = foreignKeys.filter((key) => columns.some((column) => column.name === key.column && column.notNull))
|
|
109
|
+
const where = required.length > 0 ? ` WHERE ${required.map(existsIn).join(' AND ')}` : ''
|
|
110
|
+
const inserted = await client.execute(
|
|
111
|
+
`INSERT INTO main."${table}" (${columns.map((column) => `"${column.name}"`).join(', ')}) SELECT ${expressions.join(', ')} FROM legacy."${table}"${where}`,
|
|
112
|
+
)
|
|
113
|
+
const total = await client.execute(`SELECT count(*) FROM legacy."${table}"`)
|
|
114
|
+
const skipped = Number(total.rows[0]?.[0] ?? 0) - inserted.rowsAffected
|
|
115
|
+
logger.log(`import ${table}: ${inserted.rowsAffected} rows${skipped > 0 ? `, ${skipped} skipped (missing parent row)` : ''}`)
|
|
116
|
+
}
|
|
117
|
+
await client.execute('DETACH DATABASE legacy')
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function readDbVersion({ file }: { file: string }): Promise<DbError | number> {
|
|
121
|
+
const client = createClient({ url: `file:${file}` })
|
|
122
|
+
const version = await client
|
|
123
|
+
.execute('PRAGMA user_version')
|
|
124
|
+
.then((result) => Number(result.rows[0]?.[0] ?? 0))
|
|
125
|
+
// Not an SQLite file at all: unmarked too, so it is set aside like any stray file.
|
|
126
|
+
.catch((e) => (Reflect.get(e, 'code') === 'SQLITE_NOTADB' ? 0 : new DbError({ operation: `read version of ${file}`, cause: e })))
|
|
127
|
+
client.close()
|
|
128
|
+
return version
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Renames file and its WAL files. The WAL files go first and keep their
|
|
132
|
+
// suffix, so a crash never leaves a foreign -wal next to a new kimaki.db.
|
|
133
|
+
function setAside({ file }: { file: string }): DbError | string {
|
|
134
|
+
const target = `${file}.unknown-${new Date().toISOString().replace(/[:.]/g, '-')}`
|
|
135
|
+
return errore.try(
|
|
136
|
+
() => {
|
|
137
|
+
for (const suffix of ['-wal', '-shm', '']) {
|
|
138
|
+
if (fs.existsSync(`${file}${suffix}`)) fs.renameSync(`${file}${suffix}`, `${target}${suffix}`)
|
|
139
|
+
}
|
|
140
|
+
return target
|
|
141
|
+
},
|
|
142
|
+
(e) => new DbError({ operation: `rename ${file}`, cause: e }),
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Picks or creates the database file. Returns its path.
|
|
147
|
+
async function prepareDbFile({ dataDir }: { dataDir: string }): Promise<DbError | string> {
|
|
148
|
+
const file = path.join(dataDir, DB_FILE)
|
|
149
|
+
const legacyFile = path.join(dataDir, LEGACY_DB_FILE)
|
|
150
|
+
const hasLegacy = fs.existsSync(legacyFile)
|
|
151
|
+
if (fs.existsSync(file)) {
|
|
152
|
+
// Without a V1 file there is nothing to import: keep it, migrateSchema() marks it.
|
|
153
|
+
if (!hasLegacy) return file
|
|
154
|
+
const version = await readDbVersion({ file })
|
|
155
|
+
if (version instanceof Error) return version
|
|
156
|
+
if (version >= DB_VERSION) return file
|
|
157
|
+
const moved = setAside({ file })
|
|
158
|
+
if (moved instanceof Error) return moved
|
|
159
|
+
logger.warn(`${file} was not made by kimaki (no version marker), moved it to ${moved}`)
|
|
160
|
+
}
|
|
161
|
+
if (!hasLegacy) return file
|
|
162
|
+
logger.log(`first start of this version: importing ${legacyFile} into ${file}`)
|
|
163
|
+
const target = `${file}.import`
|
|
164
|
+
fs.rmSync(target, { force: true })
|
|
165
|
+
const client = createClient({ url: `file:${target}` })
|
|
166
|
+
const imported = await migrateSchema({ client })
|
|
167
|
+
.then(() => copyLegacyRows({ client, legacyFile }))
|
|
168
|
+
.catch((e) => new DbError({ operation: `import ${legacyFile}`, cause: e }))
|
|
169
|
+
client.close()
|
|
170
|
+
if (imported instanceof Error) {
|
|
171
|
+
fs.rmSync(target, { force: true })
|
|
172
|
+
return imported
|
|
173
|
+
}
|
|
174
|
+
const renamed = errore.try(
|
|
175
|
+
() => fs.renameSync(target, file),
|
|
176
|
+
(e) => new DbError({ operation: `rename ${target}`, cause: e }),
|
|
177
|
+
)
|
|
178
|
+
if (renamed instanceof Error) return renamed
|
|
179
|
+
logger.log(`import done, ${legacyFile} is kept unchanged`)
|
|
180
|
+
return file
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Schema of an open kimaki.db: schema.sql is idempotent. Add future
|
|
184
|
+
// ALTER TABLE migrations here, before schema.sql when a new index needs them.
|
|
185
|
+
async function migrateSchema({ client }: { client: Client }): Promise<void> {
|
|
186
|
+
for (const statement of schemaStatements()) await client.execute(statement)
|
|
187
|
+
await client.execute(`PRAGMA user_version = ${DB_VERSION}`)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export async function migrateDb({ dataDir }: { dataDir: string }): Promise<DbError | string> {
|
|
191
|
+
const file = await prepareDbFile({ dataDir })
|
|
192
|
+
if (file instanceof Error) return file
|
|
193
|
+
const client = createClient({ url: `file:${file}` })
|
|
194
|
+
const migrated = await migrateSchema({ client }).catch((e) => new DbError({ operation: 'migrate schema', cause: e }))
|
|
195
|
+
client.close()
|
|
196
|
+
if (migrated instanceof Error) return migrated
|
|
197
|
+
return file
|
|
198
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// Non-interactive gateway onboarding through the real CLI process, like a
|
|
2
|
+
// cloud sandbox: stdout carries SSE events (install_url, authorized, ready).
|
|
3
|
+
// A local fake kimaki.dev answers /api/onboarding/status and, like the real
|
|
4
|
+
// OAuth callback, authorizes the new client in the twin, which plays
|
|
5
|
+
// gateway-proxy (REST scope rules enforced).
|
|
6
|
+
|
|
7
|
+
import { execFile, spawn, type ChildProcessWithoutNullStreams } from 'node:child_process'
|
|
8
|
+
import fs from 'node:fs'
|
|
9
|
+
import http from 'node:http'
|
|
10
|
+
import { createRequire } from 'node:module'
|
|
11
|
+
import path from 'node:path'
|
|
12
|
+
import { promisify } from 'node:util'
|
|
13
|
+
import { afterAll, beforeAll, expect, test } from 'vitest'
|
|
14
|
+
|
|
15
|
+
import { createApi } from './project.ts'
|
|
16
|
+
import {
|
|
17
|
+
freePort,
|
|
18
|
+
startOpencodeTestServer,
|
|
19
|
+
startTwin,
|
|
20
|
+
tempDataDir,
|
|
21
|
+
TEST_USER_ID,
|
|
22
|
+
textParts,
|
|
23
|
+
waitFor,
|
|
24
|
+
waitForFooter,
|
|
25
|
+
warmUp,
|
|
26
|
+
type OpencodeTestServer,
|
|
27
|
+
type TestTwin,
|
|
28
|
+
} from './test/harness.ts'
|
|
29
|
+
|
|
30
|
+
const execFileAsync = promisify(execFile)
|
|
31
|
+
let server: OpencodeTestServer
|
|
32
|
+
let twin: TestTwin
|
|
33
|
+
let website: http.Server
|
|
34
|
+
let websiteUrl: string
|
|
35
|
+
let dataDir: string
|
|
36
|
+
let child: ChildProcessWithoutNullStreams | null = null
|
|
37
|
+
|
|
38
|
+
beforeAll(async () => {
|
|
39
|
+
dataDir = tempDataDir()
|
|
40
|
+
;[server, twin] = await Promise.all([
|
|
41
|
+
startOpencodeTestServer({
|
|
42
|
+
matchers: [
|
|
43
|
+
{
|
|
44
|
+
id: 'onboarding-greeting',
|
|
45
|
+
priority: 50,
|
|
46
|
+
when: { latestUserTextIncludes: 'This is the Kimaki onboarding thread' },
|
|
47
|
+
then: { parts: textParts('Want channels for your projects?') },
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
}),
|
|
51
|
+
startTwin({ gateway: true }),
|
|
52
|
+
])
|
|
53
|
+
await warmUp({ server })
|
|
54
|
+
// Fake kimaki.dev: the user "installs" the bot as soon as the CLI polls.
|
|
55
|
+
website = http.createServer((request, response) => {
|
|
56
|
+
const url = new URL(request.url ?? '/', 'http://localhost')
|
|
57
|
+
if (url.pathname !== '/api/onboarding/status') {
|
|
58
|
+
response.writeHead(404).end()
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
twin.discord.authorizeGatewayClient({
|
|
62
|
+
token: `${url.searchParams.get('client_id')}:${url.searchParams.get('secret')}`,
|
|
63
|
+
guildIds: [twin.discord.guildId],
|
|
64
|
+
})
|
|
65
|
+
response.setHeader('content-type', 'application/json')
|
|
66
|
+
response.end(JSON.stringify({ guild_id: twin.discord.guildId, discord_user_id: TEST_USER_ID }))
|
|
67
|
+
})
|
|
68
|
+
const port = await freePort()
|
|
69
|
+
await new Promise<void>((resolve) => website.listen(port, '127.0.0.1', resolve))
|
|
70
|
+
websiteUrl = `http://127.0.0.1:${port}`
|
|
71
|
+
}, 60_000)
|
|
72
|
+
|
|
73
|
+
afterAll(async () => {
|
|
74
|
+
if (child && child.exitCode === null) {
|
|
75
|
+
const exited = new Promise((resolve) => child?.once('exit', resolve))
|
|
76
|
+
child.kill('SIGTERM')
|
|
77
|
+
await exited
|
|
78
|
+
}
|
|
79
|
+
await new Promise<void>((resolve) => website?.close(() => resolve()))
|
|
80
|
+
await twin?.stop()
|
|
81
|
+
await server?.stop()
|
|
82
|
+
fs.rmSync(dataDir, { recursive: true, force: true })
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
function sseEvents(stdout: string): Array<Record<string, unknown>> {
|
|
86
|
+
return stdout
|
|
87
|
+
.split('\n\n')
|
|
88
|
+
.filter((chunk) => chunk.startsWith('data: '))
|
|
89
|
+
.map((chunk) => JSON.parse(chunk.slice('data: '.length)) as Record<string, unknown>)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
test('kimaki --gateway without a TTY installs, onboards and reports ready on stdout', async () => {
|
|
93
|
+
const require = createRequire(import.meta.url)
|
|
94
|
+
const proxy = new URL('/', twin.discord.restUrl).toString()
|
|
95
|
+
const lockPort = await freePort()
|
|
96
|
+
child = spawn(
|
|
97
|
+
process.execPath,
|
|
98
|
+
['--import', require.resolve('tsx'), path.resolve('src/cli.ts'), '--data-dir', dataDir, '--gateway', '--machine-name', 'test-machine'],
|
|
99
|
+
{
|
|
100
|
+
env: {
|
|
101
|
+
...process.env,
|
|
102
|
+
KIMAKI_WEBSITE_URL: websiteUrl,
|
|
103
|
+
KIMAKI_GATEWAY_PROXY_URL: proxy,
|
|
104
|
+
KIMAKI_LOCK_PORT: String(lockPort),
|
|
105
|
+
KIMAKI_OPENCODE_SERVICE_FILE: server.serviceFile,
|
|
106
|
+
OPENCODE_CONFIG_DIR: server.configDir,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
)
|
|
110
|
+
const output = { stdout: '', stderr: '' }
|
|
111
|
+
child.stdout.on('data', (chunk: Buffer) => (output.stdout += chunk.toString()))
|
|
112
|
+
child.stderr.on('data', (chunk: Buffer) => (output.stderr += chunk.toString()))
|
|
113
|
+
await waitFor({
|
|
114
|
+
label: `ready event (stderr: ${output.stderr.slice(-500)})`,
|
|
115
|
+
timeout: 10_000,
|
|
116
|
+
check: async () => sseEvents(output.stdout).some((event) => event['type'] === 'ready'),
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
const token = (sseEvents(output.stdout)[0]?.['url'] as string).match(/clientId=([^&]+)&clientSecret=([^&]+)/)
|
|
120
|
+
expect(
|
|
121
|
+
sseEvents(output.stdout).map((event) =>
|
|
122
|
+
JSON.parse(
|
|
123
|
+
JSON.stringify(event)
|
|
124
|
+
.replaceAll(websiteUrl, '<website>')
|
|
125
|
+
.replaceAll(token?.[1] ?? '-', '<clientId>')
|
|
126
|
+
.replaceAll(token?.[2] ?? '-', '<secret>')
|
|
127
|
+
.replaceAll(twin.discord.guildId, '<guild>'),
|
|
128
|
+
),
|
|
129
|
+
),
|
|
130
|
+
).toMatchInlineSnapshot(`
|
|
131
|
+
[
|
|
132
|
+
{
|
|
133
|
+
"type": "install_url",
|
|
134
|
+
"url": "<website>/discord-install?clientId=<clientId>&clientSecret=<secret>",
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"guild_id": "<guild>",
|
|
138
|
+
"type": "authorized",
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"app_id": "1477605701202481173",
|
|
142
|
+
"guild_ids": [
|
|
143
|
+
"<guild>",
|
|
144
|
+
],
|
|
145
|
+
"type": "ready",
|
|
146
|
+
},
|
|
147
|
+
]
|
|
148
|
+
`)
|
|
149
|
+
|
|
150
|
+
const channels = await createApi({ token: twin.discord.botToken, restUrl: twin.discord.restUrl }).guilds.getChannels(twin.discord.guildId)
|
|
151
|
+
const names = new Map(channels.map((channel) => [channel.id, channel.name]))
|
|
152
|
+
expect(channels.map((channel) => `${channel.name}${channel.parent_id ? ` (in ${names.get(channel.parent_id)})` : ''}`)).toMatchInlineSnapshot(`
|
|
153
|
+
[
|
|
154
|
+
"project",
|
|
155
|
+
"random",
|
|
156
|
+
"quiet",
|
|
157
|
+
"Kimaki test-machine",
|
|
158
|
+
"kimaki (in Kimaki test-machine)",
|
|
159
|
+
"Kimaki voice test-machine",
|
|
160
|
+
]
|
|
161
|
+
`)
|
|
162
|
+
|
|
163
|
+
const kimakiChannel = channels.find((channel) => channel.name === 'kimaki')!
|
|
164
|
+
const thread = await twin.discord.channel(kimakiChannel.id).waitForThread({ timeout: 8_000 })
|
|
165
|
+
await waitForFooter({ discord: twin.discord, threadId: thread.id })
|
|
166
|
+
expect(await twin.discord.thread(thread.id).text()).toMatchInlineSnapshot(`
|
|
167
|
+
"--- from: assistant (TestBot)
|
|
168
|
+
**Kimaki** lets you code from Discord. Each project channel is linked to a folder on your computer. A message there starts an AI coding session in that folder.
|
|
169
|
+
Reply in the thread below to add channels for your projects. <@200000000000000001>
|
|
170
|
+
-# *using deterministic-provider/deterministic-v2 ⋅ build*
|
|
171
|
+
Want channels for your projects?
|
|
172
|
+
-# *kimaki ⋅ main ⋅ Ns ⋅ N% ⋅ deterministic-v2*"
|
|
173
|
+
`)
|
|
174
|
+
|
|
175
|
+
// `kimaki restart`: the supervisor starts a new bot process, which reports ready again.
|
|
176
|
+
const cli = (args: string[]) => execFileAsync(process.execPath, ['--import', require.resolve('tsx'), path.resolve('src/cli.ts'), ...args, '--data-dir', dataDir], {
|
|
177
|
+
env: { ...process.env, KIMAKI_LOCK_PORT: String(lockPort) },
|
|
178
|
+
})
|
|
179
|
+
const before = JSON.parse((await cli(['status', '--json'])).stdout) as { pid: number }
|
|
180
|
+
await cli(['restart'])
|
|
181
|
+
await waitFor({
|
|
182
|
+
label: `second ready event (stderr: ${output.stderr.slice(-500)})`,
|
|
183
|
+
check: async () => sseEvents(output.stdout).filter((event) => event['type'] === 'ready').length === 2,
|
|
184
|
+
})
|
|
185
|
+
const after = JSON.parse((await cli(['status', '--json'])).stdout) as { pid: number }
|
|
186
|
+
expect({ newPid: after.pid !== before.pid, supervisorAlive: child.exitCode === null }).toEqual({ newPid: true, supervisorAlive: true })
|
|
187
|
+
}, 40_000)
|
|
188
|
+
|
|
189
|
+
test('--install-url --gateway prints the install URL with the callback and exits', async () => {
|
|
190
|
+
const otherDataDir = tempDataDir()
|
|
191
|
+
const require = createRequire(import.meta.url)
|
|
192
|
+
const result = await new Promise<{ code: number | null; stdout: string }>((resolve) => {
|
|
193
|
+
const process_ = spawn(
|
|
194
|
+
process.execPath,
|
|
195
|
+
[
|
|
196
|
+
'--import', require.resolve('tsx'), path.resolve('src/cli.ts'),
|
|
197
|
+
'--data-dir', otherDataDir, '--install-url', '--gateway', '--gateway-callback-url', 'https://example.com/done',
|
|
198
|
+
],
|
|
199
|
+
{ env: { ...process.env, KIMAKI_WEBSITE_URL: 'https://kimaki.test' } },
|
|
200
|
+
)
|
|
201
|
+
const output = { stdout: '' }
|
|
202
|
+
process_.stdout.on('data', (chunk: Buffer) => (output.stdout += chunk.toString()))
|
|
203
|
+
process_.once('exit', (code) => resolve({ code, stdout: output.stdout }))
|
|
204
|
+
})
|
|
205
|
+
fs.rmSync(otherDataDir, { recursive: true, force: true })
|
|
206
|
+
expect({
|
|
207
|
+
code: result.code,
|
|
208
|
+
url: result.stdout.trim().replace(/clientId=[^&]+&clientSecret=[^&]+/, 'clientId=<clientId>&clientSecret=<secret>'),
|
|
209
|
+
}).toMatchInlineSnapshot(`
|
|
210
|
+
{
|
|
211
|
+
"code": 0,
|
|
212
|
+
"url": "https://kimaki.test/discord-install?clientId=<clientId>&clientSecret=<secret>&kimakiCallbackUrl=https%3A%2F%2Fexample.com%2Fdone",
|
|
213
|
+
}
|
|
214
|
+
`)
|
|
215
|
+
})
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// First start in gateway mode (the twin plays gateway-proxy): the bot creates
|
|
2
|
+
// the default channel with an onboarding thread, the onboarding session adds a
|
|
3
|
+
// project channel with `kimaki project add` (real CLI process, run by the
|
|
4
|
+
// agent's shell tool, reading the saved gateway credentials), and the new
|
|
5
|
+
// channel answers without a bot restart.
|
|
6
|
+
|
|
7
|
+
import { execFileSync } from 'node:child_process'
|
|
8
|
+
import fs from 'node:fs'
|
|
9
|
+
import { createRequire } from 'node:module'
|
|
10
|
+
import path from 'node:path'
|
|
11
|
+
import { API } from '@discordjs/core/http-only'
|
|
12
|
+
import { ChannelType } from 'discord.js'
|
|
13
|
+
import { afterAll, beforeAll, expect, test } from 'vitest'
|
|
14
|
+
|
|
15
|
+
import type { BotHandle } from './main.ts'
|
|
16
|
+
import { kimakiShellCommand, runOnboarding } from './onboarding.ts'
|
|
17
|
+
import {
|
|
18
|
+
TEST_USER_ID,
|
|
19
|
+
scriptedTurn,
|
|
20
|
+
startOpencodeTestServer,
|
|
21
|
+
startTestBot,
|
|
22
|
+
startTwin,
|
|
23
|
+
tempDataDir,
|
|
24
|
+
textParts,
|
|
25
|
+
waitFor,
|
|
26
|
+
waitForFooter,
|
|
27
|
+
warmUp,
|
|
28
|
+
type OpencodeTestServer,
|
|
29
|
+
type TestTwin,
|
|
30
|
+
} from './test/harness.ts'
|
|
31
|
+
|
|
32
|
+
let server: OpencodeTestServer
|
|
33
|
+
let twin: TestTwin
|
|
34
|
+
let bot: BotHandle
|
|
35
|
+
let dataDir: string
|
|
36
|
+
let kimaki: string
|
|
37
|
+
let otherProject: string
|
|
38
|
+
|
|
39
|
+
beforeAll(async () => {
|
|
40
|
+
dataDir = tempDataDir()
|
|
41
|
+
twin = await startTwin({ gateway: true })
|
|
42
|
+
const require = createRequire(import.meta.url)
|
|
43
|
+
kimaki = kimakiShellCommand({
|
|
44
|
+
command: [process.execPath, require.resolve('tsx/cli'), path.join(import.meta.dirname, 'cli.ts')],
|
|
45
|
+
})
|
|
46
|
+
otherProject = path.join(dataDir, 'other-project')
|
|
47
|
+
fs.mkdirSync(otherProject)
|
|
48
|
+
execFileSync('git', ['init', '-q'], { cwd: otherProject })
|
|
49
|
+
server = await startOpencodeTestServer({
|
|
50
|
+
matchers: [
|
|
51
|
+
{
|
|
52
|
+
id: 'onboarding-greeting',
|
|
53
|
+
priority: 50,
|
|
54
|
+
when: { latestUserTextIncludes: 'This is the Kimaki onboarding thread' },
|
|
55
|
+
then: { parts: textParts('Want channels for your projects? I can search for git repositories.') },
|
|
56
|
+
},
|
|
57
|
+
...scriptedTurn({
|
|
58
|
+
marker: 'add-other-project',
|
|
59
|
+
steps: [
|
|
60
|
+
{
|
|
61
|
+
id: 'call-project-add',
|
|
62
|
+
tool: 'shell',
|
|
63
|
+
input: { command: `${kimaki} project add ${otherProject}`, description: 'add project channel' },
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
finalText: 'Added the channel for other-project.',
|
|
67
|
+
}),
|
|
68
|
+
],
|
|
69
|
+
})
|
|
70
|
+
await warmUp({ server })
|
|
71
|
+
bot = await startTestBot({ dataDir, twin, server })
|
|
72
|
+
}, 120_000)
|
|
73
|
+
|
|
74
|
+
afterAll(async () => {
|
|
75
|
+
await bot?.stop()
|
|
76
|
+
await twin?.stop()
|
|
77
|
+
await server?.stop()
|
|
78
|
+
fs.rmSync(dataDir, { recursive: true, force: true })
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
async function guildChannels() {
|
|
82
|
+
const channels = await new API(bot.discord.rest).guilds.getChannels(twin.discord.guildId)
|
|
83
|
+
const names = new Map(channels.map((channel) => [channel.id, channel.name]))
|
|
84
|
+
return channels.map((channel) => {
|
|
85
|
+
const parent = channel.parent_id ? names.get(channel.parent_id) : null
|
|
86
|
+
return `${channel.name}${parent ? ` (in ${parent})` : ''}`
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
test('onboarding thread adds a project channel through the kimaki CLI, which answers at once', async () => {
|
|
91
|
+
const { discord } = twin
|
|
92
|
+
const guild = bot.discord.guilds.cache.get(discord.guildId)!
|
|
93
|
+
const onboarded = await runOnboarding({ bot, dataDir, guild, kimaki, gateway: true, installerId: TEST_USER_ID, machine: 'test-machine' })
|
|
94
|
+
if (!onboarded || onboarded instanceof Error) throw new Error(`onboarding failed: ${onboarded?.message}`, { cause: onboarded })
|
|
95
|
+
await waitForFooter({ discord, threadId: onboarded.threadId })
|
|
96
|
+
|
|
97
|
+
await discord.thread(onboarded.threadId).user(TEST_USER_ID).sendMessage({ content: 'yes, add-other-project' })
|
|
98
|
+
await waitForFooter({ discord, threadId: onboarded.threadId, count: 2 })
|
|
99
|
+
|
|
100
|
+
expect(await discord.channel(onboarded.channelId).text()).toMatchInlineSnapshot(`
|
|
101
|
+
"--- from: assistant (TestBot)
|
|
102
|
+
**Kimaki** lets you code from Discord. Each project channel is linked to a folder on your computer. A message there starts an AI coding session in that folder.
|
|
103
|
+
Reply in the thread below to add channels for your projects. <@200000000000000001>"
|
|
104
|
+
`)
|
|
105
|
+
expect(await discord.thread(onboarded.threadId).text()).toMatchInlineSnapshot(`
|
|
106
|
+
"--- from: assistant (TestBot)
|
|
107
|
+
**Kimaki** lets you code from Discord. Each project channel is linked to a folder on your computer. A message there starts an AI coding session in that folder.
|
|
108
|
+
Reply in the thread below to add channels for your projects. <@200000000000000001>
|
|
109
|
+
-# *using deterministic-provider/deterministic-v2 ⋅ build*
|
|
110
|
+
Want channels for your projects? I can search for git repositories.
|
|
111
|
+
-# *kimaki ⋅ main ⋅ Ns ⋅ N% ⋅ deterministic-v2*
|
|
112
|
+
--- from: user (tommy)
|
|
113
|
+
yes, add-other-project
|
|
114
|
+
--- from: assistant (TestBot)
|
|
115
|
+
-# ┣ shell _add project channel_
|
|
116
|
+
|
|
117
|
+
Added the channel for other-project.
|
|
118
|
+
-# *kimaki ⋅ main ⋅ Ns ⋅ N% ⋅ deterministic-v2*"
|
|
119
|
+
`)
|
|
120
|
+
expect(await guildChannels()).toMatchInlineSnapshot(`
|
|
121
|
+
[
|
|
122
|
+
"project",
|
|
123
|
+
"random",
|
|
124
|
+
"quiet",
|
|
125
|
+
"Kimaki test-machine",
|
|
126
|
+
"kimaki (in Kimaki test-machine)",
|
|
127
|
+
"other-project (in Kimaki test-machine)",
|
|
128
|
+
]
|
|
129
|
+
`)
|
|
130
|
+
|
|
131
|
+
const rows = await bot.db.query.channel_directories.findMany({ orderBy: { created_at: 'asc' } })
|
|
132
|
+
expect(rows.map((row) => path.relative(dataDir, row.directory))).toMatchInlineSnapshot(`
|
|
133
|
+
[
|
|
134
|
+
"projects/kimaki",
|
|
135
|
+
"other-project",
|
|
136
|
+
]
|
|
137
|
+
`)
|
|
138
|
+
|
|
139
|
+
// The new channel answers without restarting the bot.
|
|
140
|
+
const added = rows.find((row) => row.directory === otherProject)!
|
|
141
|
+
await discord.channel(added.channel_id).user(TEST_USER_ID).sendMessage({ content: 'hello new channel' })
|
|
142
|
+
const thread = await discord.channel(added.channel_id).waitForThread({ timeout: 8_000 })
|
|
143
|
+
await waitForFooter({ discord, threadId: thread.id })
|
|
144
|
+
|
|
145
|
+
// Second start: nothing is created again.
|
|
146
|
+
expect(await runOnboarding({ bot, dataDir, guild, kimaki, gateway: true, machine: 'test-machine' })).toBe(null)
|
|
147
|
+
await waitFor({ label: 'no extra channels', check: async () => (await guildChannels()).length === 6 })
|
|
148
|
+
|
|
149
|
+
// An empty default channel means an earlier onboarding failed: retry in the same channel.
|
|
150
|
+
const defaultChannel = rows.find((row) => row.directory !== otherProject)!
|
|
151
|
+
const channel = await bot.discord.channels.fetch(defaultChannel.channel_id)
|
|
152
|
+
if (channel?.type !== ChannelType.GuildText) throw new Error('default channel is not a text channel')
|
|
153
|
+
for (const message of (await channel.messages.fetch()).values()) await message.delete()
|
|
154
|
+
const retried = await runOnboarding({ bot, dataDir, guild, kimaki, gateway: true, installerId: TEST_USER_ID, machine: 'test-machine' })
|
|
155
|
+
if (retried instanceof Error || !retried) throw new Error(`expected a retried onboarding, got ${retried}`)
|
|
156
|
+
expect(retried.channelId).toBe(defaultChannel.channel_id)
|
|
157
|
+
await waitForFooter({ discord, threadId: retried.threadId })
|
|
158
|
+
expect((await guildChannels()).length).toBe(6)
|
|
159
|
+
}, 30_000)
|
|
160
|
+
|
|
161
|
+
test('an upgraded setup with project mappings skips onboarding without selecting a server', async () => {
|
|
162
|
+
const before = await guildChannels()
|
|
163
|
+
expect(await runOnboarding({
|
|
164
|
+
bot,
|
|
165
|
+
dataDir: path.join(dataDir, 'upgraded-layout'),
|
|
166
|
+
kimaki,
|
|
167
|
+
gateway: true,
|
|
168
|
+
machine: 'test-machine',
|
|
169
|
+
})).toBe(null)
|
|
170
|
+
expect(await guildChannels()).toEqual(before)
|
|
171
|
+
})
|