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,178 @@
|
|
|
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
|
+
import { execFile, spawn } from 'node:child_process';
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import http from 'node:http';
|
|
9
|
+
import { createRequire } from 'node:module';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import { promisify } from 'node:util';
|
|
12
|
+
import { afterAll, beforeAll, expect, test } from 'vitest';
|
|
13
|
+
import { createApi } from "./project.js";
|
|
14
|
+
import { freePort, startOpencodeTestServer, startTwin, tempDataDir, TEST_USER_ID, textParts, waitFor, waitForFooter, warmUp, } from "./test/harness.js";
|
|
15
|
+
const execFileAsync = promisify(execFile);
|
|
16
|
+
let server;
|
|
17
|
+
let twin;
|
|
18
|
+
let website;
|
|
19
|
+
let websiteUrl;
|
|
20
|
+
let dataDir;
|
|
21
|
+
let child = null;
|
|
22
|
+
beforeAll(async () => {
|
|
23
|
+
dataDir = tempDataDir();
|
|
24
|
+
[server, twin] = await Promise.all([
|
|
25
|
+
startOpencodeTestServer({
|
|
26
|
+
matchers: [
|
|
27
|
+
{
|
|
28
|
+
id: 'onboarding-greeting',
|
|
29
|
+
priority: 50,
|
|
30
|
+
when: { latestUserTextIncludes: 'This is the Kimaki onboarding thread' },
|
|
31
|
+
then: { parts: textParts('Want channels for your projects?') },
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
}),
|
|
35
|
+
startTwin({ gateway: true }),
|
|
36
|
+
]);
|
|
37
|
+
await warmUp({ server });
|
|
38
|
+
// Fake kimaki.dev: the user "installs" the bot as soon as the CLI polls.
|
|
39
|
+
website = http.createServer((request, response) => {
|
|
40
|
+
const url = new URL(request.url ?? '/', 'http://localhost');
|
|
41
|
+
if (url.pathname !== '/api/onboarding/status') {
|
|
42
|
+
response.writeHead(404).end();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
twin.discord.authorizeGatewayClient({
|
|
46
|
+
token: `${url.searchParams.get('client_id')}:${url.searchParams.get('secret')}`,
|
|
47
|
+
guildIds: [twin.discord.guildId],
|
|
48
|
+
});
|
|
49
|
+
response.setHeader('content-type', 'application/json');
|
|
50
|
+
response.end(JSON.stringify({ guild_id: twin.discord.guildId, discord_user_id: TEST_USER_ID }));
|
|
51
|
+
});
|
|
52
|
+
const port = await freePort();
|
|
53
|
+
await new Promise((resolve) => website.listen(port, '127.0.0.1', resolve));
|
|
54
|
+
websiteUrl = `http://127.0.0.1:${port}`;
|
|
55
|
+
}, 60_000);
|
|
56
|
+
afterAll(async () => {
|
|
57
|
+
if (child && child.exitCode === null) {
|
|
58
|
+
const exited = new Promise((resolve) => child?.once('exit', resolve));
|
|
59
|
+
child.kill('SIGTERM');
|
|
60
|
+
await exited;
|
|
61
|
+
}
|
|
62
|
+
await new Promise((resolve) => website?.close(() => resolve()));
|
|
63
|
+
await twin?.stop();
|
|
64
|
+
await server?.stop();
|
|
65
|
+
fs.rmSync(dataDir, { recursive: true, force: true });
|
|
66
|
+
});
|
|
67
|
+
function sseEvents(stdout) {
|
|
68
|
+
return stdout
|
|
69
|
+
.split('\n\n')
|
|
70
|
+
.filter((chunk) => chunk.startsWith('data: '))
|
|
71
|
+
.map((chunk) => JSON.parse(chunk.slice('data: '.length)));
|
|
72
|
+
}
|
|
73
|
+
test('kimaki --gateway without a TTY installs, onboards and reports ready on stdout', async () => {
|
|
74
|
+
const require = createRequire(import.meta.url);
|
|
75
|
+
const proxy = new URL('/', twin.discord.restUrl).toString();
|
|
76
|
+
const lockPort = await freePort();
|
|
77
|
+
child = spawn(process.execPath, ['--import', require.resolve('tsx'), path.resolve('src/cli.ts'), '--data-dir', dataDir, '--gateway', '--machine-name', 'test-machine'], {
|
|
78
|
+
env: {
|
|
79
|
+
...process.env,
|
|
80
|
+
KIMAKI_WEBSITE_URL: websiteUrl,
|
|
81
|
+
KIMAKI_GATEWAY_PROXY_URL: proxy,
|
|
82
|
+
KIMAKI_LOCK_PORT: String(lockPort),
|
|
83
|
+
KIMAKI_OPENCODE_SERVICE_FILE: server.serviceFile,
|
|
84
|
+
OPENCODE_CONFIG_DIR: server.configDir,
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
const output = { stdout: '', stderr: '' };
|
|
88
|
+
child.stdout.on('data', (chunk) => (output.stdout += chunk.toString()));
|
|
89
|
+
child.stderr.on('data', (chunk) => (output.stderr += chunk.toString()));
|
|
90
|
+
await waitFor({
|
|
91
|
+
label: `ready event (stderr: ${output.stderr.slice(-500)})`,
|
|
92
|
+
timeout: 10_000,
|
|
93
|
+
check: async () => sseEvents(output.stdout).some((event) => event['type'] === 'ready'),
|
|
94
|
+
});
|
|
95
|
+
const token = (sseEvents(output.stdout)[0]?.['url']).match(/clientId=([^&]+)&clientSecret=([^&]+)/);
|
|
96
|
+
expect(sseEvents(output.stdout).map((event) => JSON.parse(JSON.stringify(event)
|
|
97
|
+
.replaceAll(websiteUrl, '<website>')
|
|
98
|
+
.replaceAll(token?.[1] ?? '-', '<clientId>')
|
|
99
|
+
.replaceAll(token?.[2] ?? '-', '<secret>')
|
|
100
|
+
.replaceAll(twin.discord.guildId, '<guild>')))).toMatchInlineSnapshot(`
|
|
101
|
+
[
|
|
102
|
+
{
|
|
103
|
+
"type": "install_url",
|
|
104
|
+
"url": "<website>/discord-install?clientId=<clientId>&clientSecret=<secret>",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"guild_id": "<guild>",
|
|
108
|
+
"type": "authorized",
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"app_id": "1477605701202481173",
|
|
112
|
+
"guild_ids": [
|
|
113
|
+
"<guild>",
|
|
114
|
+
],
|
|
115
|
+
"type": "ready",
|
|
116
|
+
},
|
|
117
|
+
]
|
|
118
|
+
`);
|
|
119
|
+
const channels = await createApi({ token: twin.discord.botToken, restUrl: twin.discord.restUrl }).guilds.getChannels(twin.discord.guildId);
|
|
120
|
+
const names = new Map(channels.map((channel) => [channel.id, channel.name]));
|
|
121
|
+
expect(channels.map((channel) => `${channel.name}${channel.parent_id ? ` (in ${names.get(channel.parent_id)})` : ''}`)).toMatchInlineSnapshot(`
|
|
122
|
+
[
|
|
123
|
+
"project",
|
|
124
|
+
"random",
|
|
125
|
+
"quiet",
|
|
126
|
+
"Kimaki test-machine",
|
|
127
|
+
"kimaki (in Kimaki test-machine)",
|
|
128
|
+
"Kimaki voice test-machine",
|
|
129
|
+
]
|
|
130
|
+
`);
|
|
131
|
+
const kimakiChannel = channels.find((channel) => channel.name === 'kimaki');
|
|
132
|
+
const thread = await twin.discord.channel(kimakiChannel.id).waitForThread({ timeout: 8_000 });
|
|
133
|
+
await waitForFooter({ discord: twin.discord, threadId: thread.id });
|
|
134
|
+
expect(await twin.discord.thread(thread.id).text()).toMatchInlineSnapshot(`
|
|
135
|
+
"--- from: assistant (TestBot)
|
|
136
|
+
**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.
|
|
137
|
+
Reply in the thread below to add channels for your projects. <@200000000000000001>
|
|
138
|
+
-# *using deterministic-provider/deterministic-v2 ⋅ build*
|
|
139
|
+
Want channels for your projects?
|
|
140
|
+
-# *kimaki ⋅ main ⋅ Ns ⋅ N% ⋅ deterministic-v2*"
|
|
141
|
+
`);
|
|
142
|
+
// `kimaki restart`: the supervisor starts a new bot process, which reports ready again.
|
|
143
|
+
const cli = (args) => execFileAsync(process.execPath, ['--import', require.resolve('tsx'), path.resolve('src/cli.ts'), ...args, '--data-dir', dataDir], {
|
|
144
|
+
env: { ...process.env, KIMAKI_LOCK_PORT: String(lockPort) },
|
|
145
|
+
});
|
|
146
|
+
const before = JSON.parse((await cli(['status', '--json'])).stdout);
|
|
147
|
+
await cli(['restart']);
|
|
148
|
+
await waitFor({
|
|
149
|
+
label: `second ready event (stderr: ${output.stderr.slice(-500)})`,
|
|
150
|
+
check: async () => sseEvents(output.stdout).filter((event) => event['type'] === 'ready').length === 2,
|
|
151
|
+
});
|
|
152
|
+
const after = JSON.parse((await cli(['status', '--json'])).stdout);
|
|
153
|
+
expect({ newPid: after.pid !== before.pid, supervisorAlive: child.exitCode === null }).toEqual({ newPid: true, supervisorAlive: true });
|
|
154
|
+
}, 40_000);
|
|
155
|
+
test('--install-url --gateway prints the install URL with the callback and exits', async () => {
|
|
156
|
+
const otherDataDir = tempDataDir();
|
|
157
|
+
const require = createRequire(import.meta.url);
|
|
158
|
+
const result = await new Promise((resolve) => {
|
|
159
|
+
const process_ = spawn(process.execPath, [
|
|
160
|
+
'--import', require.resolve('tsx'), path.resolve('src/cli.ts'),
|
|
161
|
+
'--data-dir', otherDataDir, '--install-url', '--gateway', '--gateway-callback-url', 'https://example.com/done',
|
|
162
|
+
], { env: { ...process.env, KIMAKI_WEBSITE_URL: 'https://kimaki.test' } });
|
|
163
|
+
const output = { stdout: '' };
|
|
164
|
+
process_.stdout.on('data', (chunk) => (output.stdout += chunk.toString()));
|
|
165
|
+
process_.once('exit', (code) => resolve({ code, stdout: output.stdout }));
|
|
166
|
+
});
|
|
167
|
+
fs.rmSync(otherDataDir, { recursive: true, force: true });
|
|
168
|
+
expect({
|
|
169
|
+
code: result.code,
|
|
170
|
+
url: result.stdout.trim().replace(/clientId=[^&]+&clientSecret=[^&]+/, 'clientId=<clientId>&clientSecret=<secret>'),
|
|
171
|
+
}).toMatchInlineSnapshot(`
|
|
172
|
+
{
|
|
173
|
+
"code": 0,
|
|
174
|
+
"url": "https://kimaki.test/discord-install?clientId=<clientId>&clientSecret=<secret>&kimakiCallbackUrl=https%3A%2F%2Fexample.com%2Fdone",
|
|
175
|
+
}
|
|
176
|
+
`);
|
|
177
|
+
});
|
|
178
|
+
//# sourceMappingURL=onboarding-cli.e2e.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboarding-cli.e2e.test.js","sourceRoot":"","sources":["../src/onboarding-cli.e2e.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Client, type Guild } from 'discord.js';
|
|
2
|
+
import { ConfigError, OpenCodeMissingError, type OpenCodeV1Error, type OpenCodeVersionError } from './errors.ts';
|
|
3
|
+
import type { Bot } from './bot.ts';
|
|
4
|
+
export declare function chooseGuild({ discord, guildId, installUrl, gateway, }: {
|
|
5
|
+
discord: Client;
|
|
6
|
+
guildId?: string;
|
|
7
|
+
installUrl: string;
|
|
8
|
+
gateway: boolean;
|
|
9
|
+
}): Promise<ConfigError | Guild>;
|
|
10
|
+
export declare function ensureOpencode({ serviceFile, }: {
|
|
11
|
+
serviceFile?: string;
|
|
12
|
+
}): Promise<OpenCodeMissingError | OpenCodeV1Error | OpenCodeVersionError | ConfigError | void>;
|
|
13
|
+
export declare function startCaffeinate(): void;
|
|
14
|
+
export declare function shellQuote(arg: string): string;
|
|
15
|
+
export declare function onboardingPrompt({ kimaki }: {
|
|
16
|
+
kimaki: string;
|
|
17
|
+
}): string;
|
|
18
|
+
export declare function kimakiShellCommand({ command }: {
|
|
19
|
+
command: readonly string[];
|
|
20
|
+
}): string;
|
|
21
|
+
export type OnboardingResult = {
|
|
22
|
+
guildId: string;
|
|
23
|
+
channelId: string;
|
|
24
|
+
threadId: string;
|
|
25
|
+
} | null;
|
|
26
|
+
export declare function runOnboarding({ bot, dataDir, guild, guildId, installUrl, kimaki, gateway, installerId, machine, }: {
|
|
27
|
+
bot: Bot;
|
|
28
|
+
dataDir: string;
|
|
29
|
+
guild?: Guild;
|
|
30
|
+
guildId?: string;
|
|
31
|
+
installUrl?: string;
|
|
32
|
+
kimaki: string;
|
|
33
|
+
gateway: boolean;
|
|
34
|
+
machine: string;
|
|
35
|
+
installerId?: string | null;
|
|
36
|
+
}): Promise<Error | OnboardingResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,148 @@
|
|
|
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
|
+
import { execFileSync } from 'node:child_process';
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import { createRequire } from 'node:module';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import { API } from '@discordjs/core/http-only';
|
|
11
|
+
import { ChannelType } from 'discord.js';
|
|
12
|
+
import { afterAll, beforeAll, expect, test } from 'vitest';
|
|
13
|
+
import { kimakiShellCommand, runOnboarding } from "./onboarding.js";
|
|
14
|
+
import { TEST_USER_ID, scriptedTurn, startOpencodeTestServer, startTestBot, startTwin, tempDataDir, textParts, waitFor, waitForFooter, warmUp, } from "./test/harness.js";
|
|
15
|
+
let server;
|
|
16
|
+
let twin;
|
|
17
|
+
let bot;
|
|
18
|
+
let dataDir;
|
|
19
|
+
let kimaki;
|
|
20
|
+
let otherProject;
|
|
21
|
+
beforeAll(async () => {
|
|
22
|
+
dataDir = tempDataDir();
|
|
23
|
+
twin = await startTwin({ gateway: true });
|
|
24
|
+
const require = createRequire(import.meta.url);
|
|
25
|
+
kimaki = kimakiShellCommand({
|
|
26
|
+
command: [process.execPath, require.resolve('tsx/cli'), path.join(import.meta.dirname, 'cli.ts')],
|
|
27
|
+
});
|
|
28
|
+
otherProject = path.join(dataDir, 'other-project');
|
|
29
|
+
fs.mkdirSync(otherProject);
|
|
30
|
+
execFileSync('git', ['init', '-q'], { cwd: otherProject });
|
|
31
|
+
server = await startOpencodeTestServer({
|
|
32
|
+
matchers: [
|
|
33
|
+
{
|
|
34
|
+
id: 'onboarding-greeting',
|
|
35
|
+
priority: 50,
|
|
36
|
+
when: { latestUserTextIncludes: 'This is the Kimaki onboarding thread' },
|
|
37
|
+
then: { parts: textParts('Want channels for your projects? I can search for git repositories.') },
|
|
38
|
+
},
|
|
39
|
+
...scriptedTurn({
|
|
40
|
+
marker: 'add-other-project',
|
|
41
|
+
steps: [
|
|
42
|
+
{
|
|
43
|
+
id: 'call-project-add',
|
|
44
|
+
tool: 'shell',
|
|
45
|
+
input: { command: `${kimaki} project add ${otherProject}`, description: 'add project channel' },
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
finalText: 'Added the channel for other-project.',
|
|
49
|
+
}),
|
|
50
|
+
],
|
|
51
|
+
});
|
|
52
|
+
await warmUp({ server });
|
|
53
|
+
bot = await startTestBot({ dataDir, twin, server });
|
|
54
|
+
}, 120_000);
|
|
55
|
+
afterAll(async () => {
|
|
56
|
+
await bot?.stop();
|
|
57
|
+
await twin?.stop();
|
|
58
|
+
await server?.stop();
|
|
59
|
+
fs.rmSync(dataDir, { recursive: true, force: true });
|
|
60
|
+
});
|
|
61
|
+
async function guildChannels() {
|
|
62
|
+
const channels = await new API(bot.discord.rest).guilds.getChannels(twin.discord.guildId);
|
|
63
|
+
const names = new Map(channels.map((channel) => [channel.id, channel.name]));
|
|
64
|
+
return channels.map((channel) => {
|
|
65
|
+
const parent = channel.parent_id ? names.get(channel.parent_id) : null;
|
|
66
|
+
return `${channel.name}${parent ? ` (in ${parent})` : ''}`;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
test('onboarding thread adds a project channel through the kimaki CLI, which answers at once', async () => {
|
|
70
|
+
const { discord } = twin;
|
|
71
|
+
const guild = bot.discord.guilds.cache.get(discord.guildId);
|
|
72
|
+
const onboarded = await runOnboarding({ bot, dataDir, guild, kimaki, gateway: true, installerId: TEST_USER_ID, machine: 'test-machine' });
|
|
73
|
+
if (!onboarded || onboarded instanceof Error)
|
|
74
|
+
throw new Error(`onboarding failed: ${onboarded?.message}`, { cause: onboarded });
|
|
75
|
+
await waitForFooter({ discord, threadId: onboarded.threadId });
|
|
76
|
+
await discord.thread(onboarded.threadId).user(TEST_USER_ID).sendMessage({ content: 'yes, add-other-project' });
|
|
77
|
+
await waitForFooter({ discord, threadId: onboarded.threadId, count: 2 });
|
|
78
|
+
expect(await discord.channel(onboarded.channelId).text()).toMatchInlineSnapshot(`
|
|
79
|
+
"--- from: assistant (TestBot)
|
|
80
|
+
**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.
|
|
81
|
+
Reply in the thread below to add channels for your projects. <@200000000000000001>"
|
|
82
|
+
`);
|
|
83
|
+
expect(await discord.thread(onboarded.threadId).text()).toMatchInlineSnapshot(`
|
|
84
|
+
"--- from: assistant (TestBot)
|
|
85
|
+
**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.
|
|
86
|
+
Reply in the thread below to add channels for your projects. <@200000000000000001>
|
|
87
|
+
-# *using deterministic-provider/deterministic-v2 ⋅ build*
|
|
88
|
+
Want channels for your projects? I can search for git repositories.
|
|
89
|
+
-# *kimaki ⋅ main ⋅ Ns ⋅ N% ⋅ deterministic-v2*
|
|
90
|
+
--- from: user (tommy)
|
|
91
|
+
yes, add-other-project
|
|
92
|
+
--- from: assistant (TestBot)
|
|
93
|
+
-# ┣ shell _add project channel_
|
|
94
|
+
|
|
95
|
+
Added the channel for other-project.
|
|
96
|
+
-# *kimaki ⋅ main ⋅ Ns ⋅ N% ⋅ deterministic-v2*"
|
|
97
|
+
`);
|
|
98
|
+
expect(await guildChannels()).toMatchInlineSnapshot(`
|
|
99
|
+
[
|
|
100
|
+
"project",
|
|
101
|
+
"random",
|
|
102
|
+
"quiet",
|
|
103
|
+
"Kimaki test-machine",
|
|
104
|
+
"kimaki (in Kimaki test-machine)",
|
|
105
|
+
"other-project (in Kimaki test-machine)",
|
|
106
|
+
]
|
|
107
|
+
`);
|
|
108
|
+
const rows = await bot.db.query.channel_directories.findMany({ orderBy: { created_at: 'asc' } });
|
|
109
|
+
expect(rows.map((row) => path.relative(dataDir, row.directory))).toMatchInlineSnapshot(`
|
|
110
|
+
[
|
|
111
|
+
"projects/kimaki",
|
|
112
|
+
"other-project",
|
|
113
|
+
]
|
|
114
|
+
`);
|
|
115
|
+
// The new channel answers without restarting the bot.
|
|
116
|
+
const added = rows.find((row) => row.directory === otherProject);
|
|
117
|
+
await discord.channel(added.channel_id).user(TEST_USER_ID).sendMessage({ content: 'hello new channel' });
|
|
118
|
+
const thread = await discord.channel(added.channel_id).waitForThread({ timeout: 8_000 });
|
|
119
|
+
await waitForFooter({ discord, threadId: thread.id });
|
|
120
|
+
// Second start: nothing is created again.
|
|
121
|
+
expect(await runOnboarding({ bot, dataDir, guild, kimaki, gateway: true, machine: 'test-machine' })).toBe(null);
|
|
122
|
+
await waitFor({ label: 'no extra channels', check: async () => (await guildChannels()).length === 6 });
|
|
123
|
+
// An empty default channel means an earlier onboarding failed: retry in the same channel.
|
|
124
|
+
const defaultChannel = rows.find((row) => row.directory !== otherProject);
|
|
125
|
+
const channel = await bot.discord.channels.fetch(defaultChannel.channel_id);
|
|
126
|
+
if (channel?.type !== ChannelType.GuildText)
|
|
127
|
+
throw new Error('default channel is not a text channel');
|
|
128
|
+
for (const message of (await channel.messages.fetch()).values())
|
|
129
|
+
await message.delete();
|
|
130
|
+
const retried = await runOnboarding({ bot, dataDir, guild, kimaki, gateway: true, installerId: TEST_USER_ID, machine: 'test-machine' });
|
|
131
|
+
if (retried instanceof Error || !retried)
|
|
132
|
+
throw new Error(`expected a retried onboarding, got ${retried}`);
|
|
133
|
+
expect(retried.channelId).toBe(defaultChannel.channel_id);
|
|
134
|
+
await waitForFooter({ discord, threadId: retried.threadId });
|
|
135
|
+
expect((await guildChannels()).length).toBe(6);
|
|
136
|
+
}, 30_000);
|
|
137
|
+
test('an upgraded setup with project mappings skips onboarding without selecting a server', async () => {
|
|
138
|
+
const before = await guildChannels();
|
|
139
|
+
expect(await runOnboarding({
|
|
140
|
+
bot,
|
|
141
|
+
dataDir: path.join(dataDir, 'upgraded-layout'),
|
|
142
|
+
kimaki,
|
|
143
|
+
gateway: true,
|
|
144
|
+
machine: 'test-machine',
|
|
145
|
+
})).toBe(null);
|
|
146
|
+
expect(await guildChannels()).toEqual(before);
|
|
147
|
+
});
|
|
148
|
+
//# sourceMappingURL=onboarding.e2e.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboarding.e2e.test.js","sourceRoot":"","sources":["../src/onboarding.e2e.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
// First-run onboarding. Kimaki does not ask which projects to add. It creates
|
|
2
|
+
// one default channel, backed by <dataDir>/projects/kimaki, posts a welcome
|
|
3
|
+
// message, and starts a session in a thread under it. That session asks the
|
|
4
|
+
// user which projects they want, searches for them, and adds channels with
|
|
5
|
+
// `kimaki project add` (see project.ts).
|
|
6
|
+
//
|
|
7
|
+
// credentials (credentials.ts) ─▶ bot ready ─▶ pick guild (gateway: the
|
|
8
|
+
// installed one) ─▶ "Kimaki <machine>" category + #kimaki channel ─▶ welcome message
|
|
9
|
+
// ─▶ "Kimaki onboarding" thread + session with ONBOARDING prompt
|
|
10
|
+
//
|
|
11
|
+
// Existing project mappings also mark an upgraded install as already configured.
|
|
12
|
+
import { execFile, spawn } from 'node:child_process';
|
|
13
|
+
import fs from 'node:fs';
|
|
14
|
+
import path from 'node:path';
|
|
15
|
+
import { promisify } from 'node:util';
|
|
16
|
+
import * as clack from '@clack/prompts';
|
|
17
|
+
import { ChannelType, Events } from 'discord.js';
|
|
18
|
+
import * as errore from 'errore';
|
|
19
|
+
import dedent from 'string-dedent';
|
|
20
|
+
import { API } from '@discordjs/core/http-only';
|
|
21
|
+
import { ConfigError, DbError, DiscordError, OpenCodeMissingError } from "./errors.js";
|
|
22
|
+
import { NOTIFY_MESSAGE_FLAGS } from "./format-parts.js";
|
|
23
|
+
import { createLogger } from "./logger.js";
|
|
24
|
+
import { checkOpencode, findOpencodeBinary, installedOpencodeBinary, OPENCODE_INSTALL_COMMAND } from "./opencode-server.js";
|
|
25
|
+
import { startSession } from "./sessions.js";
|
|
26
|
+
import { addProjectChannel, defaultChannelName, defaultProjectDirectory } from "./project.js";
|
|
27
|
+
const logger = createLogger('ONBOARD');
|
|
28
|
+
const execFileAsync = promisify(execFile);
|
|
29
|
+
const DEFAULT_CHANNEL_TOPIC = 'General channel for misc tasks with Kimaki. Not connected to a specific project or repository.';
|
|
30
|
+
// Waits until a self-hosted bot is in at least one server. A gateway client
|
|
31
|
+
// in no server cannot be fixed by waiting: the install URL must be opened
|
|
32
|
+
// again (V1 behavior), so that is an error with the URL.
|
|
33
|
+
async function waitForGuild({ discord, installUrl, gateway }) {
|
|
34
|
+
const first = discord.guilds.cache.first();
|
|
35
|
+
if (first)
|
|
36
|
+
return first;
|
|
37
|
+
if (gateway) {
|
|
38
|
+
return new ConfigError({ reason: `The Kimaki bot is in no Discord server. Open this URL to add it (do not share it, it contains your credentials), then run kimaki again: ${installUrl}` });
|
|
39
|
+
}
|
|
40
|
+
logger.log(`bot is in no server yet, install it: ${installUrl}`);
|
|
41
|
+
process.stderr.write(`\nAdd the bot to your Discord server:\n${installUrl}\n\nWaiting...\n`);
|
|
42
|
+
return new Promise((resolve) => discord.once(Events.GuildCreate, resolve));
|
|
43
|
+
}
|
|
44
|
+
// Many servers: --guild, else a prompt, else an error listing the choices.
|
|
45
|
+
export async function chooseGuild({ discord, guildId, installUrl, gateway, }) {
|
|
46
|
+
if (guildId) {
|
|
47
|
+
const guild = discord.guilds.cache.get(guildId);
|
|
48
|
+
return guild ?? new ConfigError({ reason: `The bot is not in server ${guildId}` });
|
|
49
|
+
}
|
|
50
|
+
const guilds = [...discord.guilds.cache.values()];
|
|
51
|
+
if (guilds.length <= 1)
|
|
52
|
+
return waitForGuild({ discord, installUrl, gateway });
|
|
53
|
+
if (!process.stdin.isTTY) {
|
|
54
|
+
const choices = guilds.map((guild) => `${guild.id} (${guild.name})`).join(', ');
|
|
55
|
+
return new ConfigError({ reason: `The bot is in several servers: ${choices}. Pass --guild <id>.` });
|
|
56
|
+
}
|
|
57
|
+
const picked = await clack.select({
|
|
58
|
+
message: 'Which server should Kimaki use?',
|
|
59
|
+
options: guilds.map((guild) => ({ value: guild.id, label: guild.name })),
|
|
60
|
+
});
|
|
61
|
+
if (clack.isCancel(picked))
|
|
62
|
+
return new ConfigError({ reason: 'Onboarding cancelled' });
|
|
63
|
+
return discord.guilds.cache.get(picked) ?? new ConfigError({ reason: `Unknown server ${picked}` });
|
|
64
|
+
}
|
|
65
|
+
// Before the Discord install: a running OpenCode service, or a V2 binary to
|
|
66
|
+
// start one. When OpenCode is missing it installs V2 with the official script,
|
|
67
|
+
// like V1 installed its tools (asks first in a terminal). An OpenCode 1 or an
|
|
68
|
+
// old V2 is never replaced: the error tells the user how to install V2.
|
|
69
|
+
export async function ensureOpencode({ serviceFile, }) {
|
|
70
|
+
const checked = await checkOpencode({ serviceFile });
|
|
71
|
+
if (checked instanceof Error)
|
|
72
|
+
return checked;
|
|
73
|
+
if (checked === 'ready')
|
|
74
|
+
return;
|
|
75
|
+
const missing = new OpenCodeMissingError({ install: OPENCODE_INSTALL_COMMAND });
|
|
76
|
+
// The script is bash-only; OPENCODE_PATH points at a binary the user chose.
|
|
77
|
+
if (process.platform === 'win32' || process.env['OPENCODE_PATH'])
|
|
78
|
+
return missing;
|
|
79
|
+
if (process.stdin.isTTY) {
|
|
80
|
+
const confirmed = await clack.confirm({ message: `Kimaki requires OpenCode 2. Install it now with \`${OPENCODE_INSTALL_COMMAND}\`?` });
|
|
81
|
+
if (clack.isCancel(confirmed) || !confirmed)
|
|
82
|
+
return missing;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
logger.log(`OpenCode 2 not found, installing: ${OPENCODE_INSTALL_COMMAND}`);
|
|
86
|
+
}
|
|
87
|
+
// Script output goes to stderr: stdout is for `data:` events (logging rules in AGENTS.md).
|
|
88
|
+
const exitCode = await new Promise((resolve) => {
|
|
89
|
+
const child = spawn('/bin/bash', ['-c', OPENCODE_INSTALL_COMMAND], { stdio: ['ignore', 2, 2], signal: AbortSignal.timeout(600_000) });
|
|
90
|
+
child.on('error', (cause) => resolve(new ConfigError({ reason: 'OpenCode install failed to run', cause })));
|
|
91
|
+
child.on('close', (code) => resolve(code ?? 1));
|
|
92
|
+
});
|
|
93
|
+
if (exitCode instanceof Error)
|
|
94
|
+
return exitCode;
|
|
95
|
+
if (exitCode !== 0)
|
|
96
|
+
return new ConfigError({ reason: `OpenCode install exited with code ${exitCode}. ${missing.message}` });
|
|
97
|
+
const installed = await findOpencodeBinary();
|
|
98
|
+
if (installed instanceof Error)
|
|
99
|
+
return installed;
|
|
100
|
+
if (installed === null)
|
|
101
|
+
return new ConfigError({ reason: `OpenCode install finished but ${installedOpencodeBinary()} does not run. ${missing.message}` });
|
|
102
|
+
logger.info(`installed OpenCode 2 at ${installed}`);
|
|
103
|
+
}
|
|
104
|
+
// macOS: keep the machine awake while the bot runs (-s also on lid close on
|
|
105
|
+
// AC power). -w exits caffeinate with this process, whatever ends it.
|
|
106
|
+
export function startCaffeinate() {
|
|
107
|
+
if (process.platform !== 'darwin')
|
|
108
|
+
return;
|
|
109
|
+
const child = errore.try(() => spawn('caffeinate', ['-s', '-w', String(process.pid)], { stdio: 'ignore' }), (e) => new ConfigError({ reason: 'caffeinate failed to start', cause: e }));
|
|
110
|
+
if (child instanceof Error) {
|
|
111
|
+
logger.warn(child);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
child.on('error', (error) => logger.warn(`caffeinate`, error));
|
|
115
|
+
child.unref();
|
|
116
|
+
}
|
|
117
|
+
export function shellQuote(arg) {
|
|
118
|
+
return /^[\w@%+=:,./-]+$/.test(arg) ? arg : `'${arg.replaceAll("'", `'\\''`)}'`;
|
|
119
|
+
}
|
|
120
|
+
export function onboardingPrompt({ kimaki }) {
|
|
121
|
+
return dedent `
|
|
122
|
+
This is the Kimaki onboarding thread. Kimaki maps Discord channels to project folders on this computer:
|
|
123
|
+
a message in a project channel starts a coding session in that folder.
|
|
124
|
+
|
|
125
|
+
Help the user add channels for their projects:
|
|
126
|
+
|
|
127
|
+
1. Greet the user in one short sentence and ask if they want channels for their projects. Suggest
|
|
128
|
+
searching for git repositories on this computer.
|
|
129
|
+
2. If they agree, search. Only list folders that exist, most recently changed first, at most 15:
|
|
130
|
+
\`find ~/Documents ~/Projects ~/projects ~/code ~/dev ~/src ~/repos ~/GitHub ~/github -maxdepth 3 -name .git -prune 2>/dev/null\`
|
|
131
|
+
Skip folders that already have a channel: \`${kimaki} project list\`
|
|
132
|
+
3. Show the folders as a numbered list and ask the user to reply with the numbers to add.
|
|
133
|
+
4. Add each chosen folder with its absolute path: \`${kimaki} project add <absolute-directory>\`
|
|
134
|
+
The command prints the new channel as a mention like <#123>. Reply with the list of new channels.
|
|
135
|
+
|
|
136
|
+
Never add a channel the user did not choose. Keep every message short.
|
|
137
|
+
`;
|
|
138
|
+
}
|
|
139
|
+
// The shell command the agent runs to call this Kimaki install.
|
|
140
|
+
// No --data-dir: agent shells get KIMAKI_DATA_DIR from the plugin, and not every command takes the flag.
|
|
141
|
+
export function kimakiShellCommand({ command }) {
|
|
142
|
+
return command.map(shellQuote).join(' ');
|
|
143
|
+
}
|
|
144
|
+
class GitInitError extends errore.createTaggedError({
|
|
145
|
+
name: 'GitInitError',
|
|
146
|
+
message: 'Could not create $directory',
|
|
147
|
+
}) {
|
|
148
|
+
}
|
|
149
|
+
async function createDefaultDirectory(directory) {
|
|
150
|
+
const created = errore.try(() => {
|
|
151
|
+
fs.mkdirSync(directory, { recursive: true });
|
|
152
|
+
const gitignore = path.join(directory, '.gitignore');
|
|
153
|
+
if (!fs.existsSync(gitignore))
|
|
154
|
+
fs.writeFileSync(gitignore, 'node_modules/\ntmp/\n*.log\n.DS_Store\n');
|
|
155
|
+
}, (e) => new GitInitError({ directory, cause: e }));
|
|
156
|
+
if (created instanceof Error)
|
|
157
|
+
return created;
|
|
158
|
+
if (fs.existsSync(path.join(directory, '.git')))
|
|
159
|
+
return;
|
|
160
|
+
// Without git the folder still works; only branch names in footers are missing.
|
|
161
|
+
const init = await execFileAsync('git', ['init', '-q'], { cwd: directory, timeout: 10_000 }).catch((e) => new GitInitError({ directory, cause: e }));
|
|
162
|
+
if (init instanceof Error)
|
|
163
|
+
logger.warn(`git init failed in ${directory}`, init);
|
|
164
|
+
}
|
|
165
|
+
export async function runOnboarding({ bot, dataDir, guild, guildId, installUrl, kimaki, gateway, installerId, machine, }) {
|
|
166
|
+
const { db } = bot;
|
|
167
|
+
const directory = defaultProjectDirectory({ dataDir });
|
|
168
|
+
const projects = await db.query.channel_directories
|
|
169
|
+
.findMany({ where: { channel_type: 'text' } })
|
|
170
|
+
.catch((e) => new DbError({ operation: 'read channel_directories', cause: e }));
|
|
171
|
+
if (projects instanceof Error)
|
|
172
|
+
return projects;
|
|
173
|
+
const mapped = projects.find((project) => project.directory === directory);
|
|
174
|
+
if (!mapped && projects.length > 0)
|
|
175
|
+
return null;
|
|
176
|
+
// Done once the default channel has a message (the welcome). An empty channel
|
|
177
|
+
// means an earlier onboarding failed: retry in it. A deleted one stays deleted.
|
|
178
|
+
if (mapped) {
|
|
179
|
+
const existing = await bot.discord.channels.fetch(mapped.channel_id).catch(() => null);
|
|
180
|
+
if (existing?.type !== ChannelType.GuildText)
|
|
181
|
+
return null;
|
|
182
|
+
const messages = await existing.messages
|
|
183
|
+
.fetch({ limit: 1 })
|
|
184
|
+
.catch((e) => new DiscordError({ operation: 'read default channel', cause: e }));
|
|
185
|
+
if (messages instanceof Error)
|
|
186
|
+
return messages;
|
|
187
|
+
if (messages.size > 0)
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
const selectedGuild = await (async () => {
|
|
191
|
+
if (guild)
|
|
192
|
+
return guild;
|
|
193
|
+
const saved = mapped?.guild_id ? bot.discord.guilds.cache.get(mapped.guild_id) : null;
|
|
194
|
+
if (saved)
|
|
195
|
+
return saved;
|
|
196
|
+
if (!installUrl)
|
|
197
|
+
return new ConfigError({ reason: 'No server configured for onboarding. Run kimaki --guild <id>.' });
|
|
198
|
+
return chooseGuild({ discord: bot.discord, guildId, installUrl, gateway });
|
|
199
|
+
})();
|
|
200
|
+
if (selectedGuild instanceof Error)
|
|
201
|
+
return selectedGuild;
|
|
202
|
+
const directoryReady = await createDefaultDirectory(directory);
|
|
203
|
+
if (directoryReady instanceof Error)
|
|
204
|
+
return directoryReady;
|
|
205
|
+
const botName = bot.discord.user?.username ?? 'kimaki';
|
|
206
|
+
const channel = await addProjectChannel({
|
|
207
|
+
api: new API(bot.discord.rest),
|
|
208
|
+
db,
|
|
209
|
+
guildId: selectedGuild.id,
|
|
210
|
+
directory,
|
|
211
|
+
name: defaultChannelName({ botName, gateway }),
|
|
212
|
+
topic: DEFAULT_CHANNEL_TOPIC,
|
|
213
|
+
machine,
|
|
214
|
+
});
|
|
215
|
+
if (channel instanceof Error)
|
|
216
|
+
return channel;
|
|
217
|
+
if (channel.created)
|
|
218
|
+
bot.analytics.track('project_registered', { project_kind: 'default', source: 'onboarding' });
|
|
219
|
+
const textChannel = await bot.discord.channels
|
|
220
|
+
.fetch(channel.channelId)
|
|
221
|
+
.catch((e) => new DiscordError({ operation: 'fetch default channel', cause: e }));
|
|
222
|
+
if (textChannel instanceof Error)
|
|
223
|
+
return textChannel;
|
|
224
|
+
if (textChannel?.type !== ChannelType.GuildText) {
|
|
225
|
+
return new DiscordError({ operation: `default channel ${channel.channelId} is not a text channel` });
|
|
226
|
+
}
|
|
227
|
+
const owner = await selectedGuild.members
|
|
228
|
+
.fetch(installerId ?? selectedGuild.ownerId)
|
|
229
|
+
.catch((e) => new DiscordError({ operation: 'fetch installer', cause: e }));
|
|
230
|
+
if (owner instanceof Error)
|
|
231
|
+
return owner;
|
|
232
|
+
const welcome = await textChannel
|
|
233
|
+
.send({
|
|
234
|
+
content: dedent `
|
|
235
|
+
**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.
|
|
236
|
+
Reply in the thread below to add channels for your projects. <@${owner.id}>
|
|
237
|
+
`,
|
|
238
|
+
allowedMentions: { users: [owner.id] },
|
|
239
|
+
flags: NOTIFY_MESSAGE_FLAGS,
|
|
240
|
+
})
|
|
241
|
+
.catch((e) => new DiscordError({ operation: 'send welcome message', cause: e }));
|
|
242
|
+
if (welcome instanceof Error)
|
|
243
|
+
return welcome;
|
|
244
|
+
const session = await startSession(bot, {
|
|
245
|
+
channelId: channel.channelId,
|
|
246
|
+
directory,
|
|
247
|
+
route: { kind: 'steer', text: onboardingPrompt({ kimaki }) },
|
|
248
|
+
author: { id: owner.id, username: owner.user.username },
|
|
249
|
+
messageId: welcome.id,
|
|
250
|
+
threadName: 'Kimaki onboarding',
|
|
251
|
+
worktree: false,
|
|
252
|
+
});
|
|
253
|
+
if (session instanceof Error) {
|
|
254
|
+
// Leaves the channel empty, so the next start onboards again.
|
|
255
|
+
await welcome.delete().catch((e) => logger.warn('delete welcome message', e));
|
|
256
|
+
return session;
|
|
257
|
+
}
|
|
258
|
+
logger.log(`onboarding thread ${session.threadId} in channel ${channel.channelId}`);
|
|
259
|
+
return { guildId: selectedGuild.id, channelId: channel.channelId, threadId: session.threadId };
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=onboarding.js.map
|