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,102 @@
|
|
|
1
|
+
// `. btw` and /btw fork the session into a new "btw:" thread that answers a
|
|
2
|
+
// side question while the source session keeps running.
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import { afterAll, beforeAll, expect, test } from 'vitest';
|
|
5
|
+
import { TEST_USER_ID, seedProjectChannel, slowTextMatcher, startOpencodeTestServer, startTestBot, startTwin, tempDataDir, textParts, waitForBotMessageContaining, waitForFooter, warmUp, } from "./test/harness.js";
|
|
6
|
+
const matchers = [
|
|
7
|
+
slowTextMatcher({ marker: 'slow-marker', text: 'slow-done', delayMs: 2_000 }),
|
|
8
|
+
{ id: 'side', priority: 50, when: { latestUserTextIncludes: 'side-marker' }, then: { parts: textParts('side answer') } },
|
|
9
|
+
{ id: 'slash', priority: 50, when: { latestUserTextIncludes: 'slash-marker' }, then: { parts: textParts('slash answer') } },
|
|
10
|
+
];
|
|
11
|
+
let server;
|
|
12
|
+
let twin;
|
|
13
|
+
let bot;
|
|
14
|
+
let dataDir;
|
|
15
|
+
beforeAll(async () => {
|
|
16
|
+
dataDir = tempDataDir();
|
|
17
|
+
[server, twin] = await Promise.all([startOpencodeTestServer({ matchers }), startTwin()]);
|
|
18
|
+
await seedProjectChannel({
|
|
19
|
+
dataDir,
|
|
20
|
+
channelId: twin.channelId,
|
|
21
|
+
guildId: twin.discord.guildId,
|
|
22
|
+
directory: server.projectDirectory,
|
|
23
|
+
});
|
|
24
|
+
await warmUp({ server });
|
|
25
|
+
bot = await startTestBot({ dataDir, twin, server });
|
|
26
|
+
});
|
|
27
|
+
afterAll(async () => {
|
|
28
|
+
await bot?.stop();
|
|
29
|
+
await twin?.stop();
|
|
30
|
+
await server?.stop();
|
|
31
|
+
fs.rmSync(dataDir, { recursive: true, force: true });
|
|
32
|
+
});
|
|
33
|
+
function hideIds(text) {
|
|
34
|
+
return text.replace(/<#\d+>/g, '<#THREAD>').replace(/ses_\w+/g, 'ses_ID');
|
|
35
|
+
}
|
|
36
|
+
async function waitForBtwThread(existing) {
|
|
37
|
+
return twin.discord.channel(twin.channelId).waitForThread({
|
|
38
|
+
timeout: 8_000,
|
|
39
|
+
predicate: (thread) => !existing.has(thread.id) && (thread.name?.startsWith('btw:') ?? false),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
test('. btw forks into a side thread while the source run continues', async () => {
|
|
43
|
+
const { discord, channelId } = twin;
|
|
44
|
+
await discord.channel(channelId).user(TEST_USER_ID).sendMessage({ content: 'Long task slow-marker' });
|
|
45
|
+
const source = await discord.channel(channelId).waitForThread({ timeout: 8_000 });
|
|
46
|
+
await waitForBotMessageContaining({ discord, threadId: source.id, text: '*using ' });
|
|
47
|
+
const existing = new Set((await discord.channel(channelId).getThreads()).map((thread) => thread.id));
|
|
48
|
+
await discord.thread(source.id).user(TEST_USER_ID).sendMessage({ content: 'What is 2+2 side-marker. btw' });
|
|
49
|
+
const fork = await waitForBtwThread(existing);
|
|
50
|
+
await waitForFooter({ discord, threadId: fork.id });
|
|
51
|
+
await waitForFooter({ discord, threadId: source.id });
|
|
52
|
+
expect(fork.name).toBe('btw: What is 2+2 side-marker');
|
|
53
|
+
expect(hideIds(await discord.thread(source.id).text())).toMatchInlineSnapshot(`
|
|
54
|
+
"--- from: user (tommy)
|
|
55
|
+
Long task slow-marker
|
|
56
|
+
--- from: assistant (TestBot)
|
|
57
|
+
-# *using deterministic-provider/deterministic-v2 ⋅ build*
|
|
58
|
+
--- from: user (tommy)
|
|
59
|
+
What is 2+2 side-marker. btw
|
|
60
|
+
--- from: assistant (TestBot)
|
|
61
|
+
Session forked! Continue in <#THREAD>
|
|
62
|
+
slow-done
|
|
63
|
+
-# *project ⋅ main ⋅ Ns ⋅ N% ⋅ deterministic-v2*"
|
|
64
|
+
`);
|
|
65
|
+
expect(hideIds(await discord.thread(fork.id).text())).toMatchInlineSnapshot(`
|
|
66
|
+
"--- from: assistant (TestBot)
|
|
67
|
+
Reusing context from <#THREAD> to answer prompt...
|
|
68
|
+
What is 2+2 side-marker
|
|
69
|
+
side answer
|
|
70
|
+
-# *project ⋅ main ⋅ Ns ⋅ N% ⋅ deterministic-v2*"
|
|
71
|
+
`);
|
|
72
|
+
const rows = await bot.db.query.thread_sessions.findMany({ where: { thread_id: fork.id } });
|
|
73
|
+
expect(rows.length).toBe(1);
|
|
74
|
+
// The plugin only exports KIMAKI_TOOL_CALL to shells when the marker has the CLI context,
|
|
75
|
+
// so `kimaki buttons` failed on the first turn of every fork.
|
|
76
|
+
const info = await (await server.client()).session.get({ sessionID: rows[0].session_id });
|
|
77
|
+
expect(info.metadata?.['kimaki']).toMatchObject({ threadId: fork.id, dataDir, lockPort: expect.any(Number) });
|
|
78
|
+
});
|
|
79
|
+
test('/btw forks from a thread with an idle session', async () => {
|
|
80
|
+
const { discord, channelId } = twin;
|
|
81
|
+
await discord.channel(channelId).user(TEST_USER_ID).sendMessage({ content: 'Short task' });
|
|
82
|
+
const source = await discord.channel(channelId).waitForThread({
|
|
83
|
+
timeout: 8_000,
|
|
84
|
+
predicate: (thread) => thread.name === 'Short task',
|
|
85
|
+
});
|
|
86
|
+
await waitForFooter({ discord, threadId: source.id });
|
|
87
|
+
const existing = new Set((await discord.channel(channelId).getThreads()).map((thread) => thread.id));
|
|
88
|
+
await discord.thread(source.id).user(TEST_USER_ID).runSlashCommand({
|
|
89
|
+
name: 'btw',
|
|
90
|
+
options: [{ name: 'prompt', type: 3, value: 'Side slash-marker' }],
|
|
91
|
+
});
|
|
92
|
+
const fork = await waitForBtwThread(existing);
|
|
93
|
+
await waitForFooter({ discord, threadId: fork.id });
|
|
94
|
+
expect(hideIds(await discord.thread(fork.id).text())).toMatchInlineSnapshot(`
|
|
95
|
+
"--- from: assistant (TestBot)
|
|
96
|
+
Reusing context from <#THREAD> to answer prompt...
|
|
97
|
+
Side slash-marker
|
|
98
|
+
slash answer
|
|
99
|
+
-# *project ⋅ main ⋅ Ns ⋅ N% ⋅ deterministic-v2*"
|
|
100
|
+
`);
|
|
101
|
+
});
|
|
102
|
+
//# sourceMappingURL=btw.e2e.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"btw.e2e.test.js","sourceRoot":"","sources":["../src/btw.e2e.test.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,wDAAwD;AAExD,OAAO,EAAE,MAAM,SAAS,CAAA;AAExB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAG1D,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,uBAAuB,EACvB,YAAY,EACZ,SAAS,EACT,WAAW,EACX,SAAS,EACT,2BAA2B,EAC3B,aAAa,EACb,MAAM,GAGP,MAAM,mBAAmB,CAAA;AAE1B,MAAM,QAAQ,GAA2B;IACvC,eAAe,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC7E,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,sBAAsB,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,aAAa,CAAC,EAAE,EAAE;IACxH,EAAE,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,sBAAsB,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,cAAc,CAAC,EAAE,EAAE;CAC5H,CAAA;AAED,IAAI,MAA0B,CAAA;AAC9B,IAAI,IAAc,CAAA;AAClB,IAAI,GAAc,CAAA;AAClB,IAAI,OAAe,CAAA;AAEnB,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,OAAO,GAAG,WAAW,EAAE,CACtB;IAAA,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,uBAAuB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAA;IACzF,MAAM,kBAAkB,CAAC;QACvB,OAAO;QACP,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;QAC7B,SAAS,EAAE,MAAM,CAAC,gBAAgB;KACnC,CAAC,CAAA;IACF,MAAM,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAA;IACxB,GAAG,GAAG,MAAM,YAAY,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;AACrD,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,KAAK,IAAI,EAAE;IAClB,MAAM,GAAG,EAAE,IAAI,EAAE,CAAA;IACjB,MAAM,IAAI,EAAE,IAAI,EAAE,CAAA;IAClB,MAAM,MAAM,EAAE,IAAI,EAAE,CAAA;IACpB,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;AACtD,CAAC,CAAC,CAAA;AAEF,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;AAC3E,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,QAAqB;IACnD,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC;QACxD,OAAO,EAAE,KAAK;QACd,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC;KAC9F,CAAC,CAAA;AACJ,CAAC;AAED,IAAI,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;IAC/E,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IACnC,MAAM,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC,CAAA;IACrG,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;IACjF,MAAM,2BAA2B,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAA;IACpF,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;IAEpG,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC,CAAA;IAC3G,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,QAAQ,CAAC,CAAA;IAC7C,MAAM,aAAa,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;IACnD,MAAM,aAAa,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;IAErD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;IACtD,MAAM,CAAC,OAAO,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;GAW7E,CAAC,CAAA;IACF,MAAM,CAAC,OAAO,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;GAM3E,CAAC,CAAA;IACF,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IAC3F,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC3B,0FAA0F;IAC1F,8DAA8D;IAC9D,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAE,CAAC,UAAU,EAAE,CAAC,CAAA;IAC1F,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AAC/G,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;IAC/D,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IACnC,MAAM,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAA;IAC1F,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC;QAC5D,OAAO,EAAE,KAAK;QACd,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY;KACpD,CAAC,CAAA;IACF,MAAM,aAAa,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;IACrD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;IAEpG,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,eAAe,CAAC;QACjE,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;KACnE,CAAC,CAAA;IACF,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,QAAQ,CAAC,CAAA;IAC7C,MAAM,aAAa,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;IACnD,MAAM,CAAC,OAAO,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;GAM3E,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// OpenCode loads agents lazily: user agents missing at startup get their
|
|
2
|
+
// /<agent>-agent command when agent.updated arrives.
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { Routes } from 'discord.js';
|
|
6
|
+
import { afterAll, beforeAll, expect, test } from 'vitest';
|
|
7
|
+
import { TEST_USER_ID, seedProjectChannel, startOpencodeTestServer, startTestBot, startTwin, tempDataDir, textParts, waitForFooter, } from "./test/harness.js";
|
|
8
|
+
const matchers = [
|
|
9
|
+
{ id: 'late', priority: 500, when: { latestUserTextIncludes: 'late-marker' }, then: { parts: textParts('late reply') } },
|
|
10
|
+
];
|
|
11
|
+
let server;
|
|
12
|
+
let twin;
|
|
13
|
+
let bot;
|
|
14
|
+
let dataDir;
|
|
15
|
+
beforeAll(async () => {
|
|
16
|
+
dataDir = tempDataDir();
|
|
17
|
+
[server, twin] = await Promise.all([startOpencodeTestServer({ matchers, agents: { late: { description: 'Late agent', mode: 'primary' } } }), startTwin()]);
|
|
18
|
+
await seedProjectChannel({ dataDir, channelId: twin.channelId, guildId: twin.discord.guildId, directory: server.projectDirectory });
|
|
19
|
+
bot = await startTestBot({ dataDir, twin, server });
|
|
20
|
+
});
|
|
21
|
+
afterAll(async () => {
|
|
22
|
+
await bot?.stop();
|
|
23
|
+
await twin?.stop();
|
|
24
|
+
await server?.stop();
|
|
25
|
+
fs.rmSync(dataDir, { recursive: true, force: true });
|
|
26
|
+
});
|
|
27
|
+
async function registeredNames() {
|
|
28
|
+
const commands = await twin.discord.getRegisteredCommands();
|
|
29
|
+
return commands.map((command) => command.name);
|
|
30
|
+
}
|
|
31
|
+
test('agents loaded after startup get their slash commands', async () => {
|
|
32
|
+
// A cold OpenCode has no user agents when the bot first registers commands;
|
|
33
|
+
// agent.updated fires when the catalog finishes loading; the refresh follows it.
|
|
34
|
+
const deadline = Date.now() + 8_000;
|
|
35
|
+
while (Date.now() < deadline && !(await registeredNames()).includes('late-agent')) {
|
|
36
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
37
|
+
}
|
|
38
|
+
expect(await registeredNames()).toContain('late-agent');
|
|
39
|
+
const { discord, channelId } = twin;
|
|
40
|
+
const before = new Set((await discord.channel(channelId).getThreads()).map((thread) => thread.id));
|
|
41
|
+
await discord
|
|
42
|
+
.channel(channelId)
|
|
43
|
+
.user(TEST_USER_ID)
|
|
44
|
+
.runSlashCommand({ name: 'late-agent', options: [{ name: 'prompt', type: 3, value: 'Go late-marker' }] });
|
|
45
|
+
const thread = await discord.channel(channelId).waitForThread({ timeout: 8_000, predicate: (found) => !before.has(found.id) });
|
|
46
|
+
await waitForFooter({ discord, threadId: thread.id });
|
|
47
|
+
expect(await discord.thread(thread.id).text()).toMatchInlineSnapshot(`
|
|
48
|
+
"--- from: assistant (TestBot)
|
|
49
|
+
» **tommy:** Go late-marker
|
|
50
|
+
-# *using deterministic-provider/deterministic-v2 ⋅ late*
|
|
51
|
+
late reply
|
|
52
|
+
-# *project ⋅ main ⋅ Ns ⋅ N% ⋅ deterministic-v2 ⋅ late*"
|
|
53
|
+
`);
|
|
54
|
+
});
|
|
55
|
+
test('a skill change adds its command; catalog events with the same catalog write nothing to Discord', async () => {
|
|
56
|
+
const skillFile = path.join(server.skillsDirectory, 'demo', 'SKILL.md');
|
|
57
|
+
const skillText = '---\nname: demo\ndescription: Demo skill\n---\nDemo.\n';
|
|
58
|
+
const nextCatalogEvent = () => new Promise((resolve) => {
|
|
59
|
+
const stop = bot.opencode.subscribe((event) => {
|
|
60
|
+
if (event.type !== 'skill.updated')
|
|
61
|
+
return;
|
|
62
|
+
stop();
|
|
63
|
+
resolve();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
const waitForCommand = async () => {
|
|
67
|
+
const deadline = Date.now() + 8_000;
|
|
68
|
+
while (Date.now() < deadline && !(await registeredNames()).includes('demo-skill')) {
|
|
69
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
fs.mkdirSync(path.dirname(skillFile), { recursive: true });
|
|
73
|
+
fs.writeFileSync(skillFile, skillText);
|
|
74
|
+
await waitForCommand();
|
|
75
|
+
expect(await registeredNames()).toContain('demo-skill');
|
|
76
|
+
// Same file content again: OpenCode rescans and publishes skill.updated, the commands stay the same.
|
|
77
|
+
const bulkWrites = [];
|
|
78
|
+
const commandsRoute = Routes.applicationGuildCommands(bot.discord.user.id, twin.discord.guildId);
|
|
79
|
+
bot.discord.rest.on('response', (request) => {
|
|
80
|
+
if (request.method === 'PUT' && request.path === commandsRoute)
|
|
81
|
+
bulkWrites.push(request.path);
|
|
82
|
+
});
|
|
83
|
+
const event = nextCatalogEvent();
|
|
84
|
+
fs.writeFileSync(skillFile, skillText);
|
|
85
|
+
await event;
|
|
86
|
+
// Let the pass that the event started finish.
|
|
87
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
88
|
+
expect(bulkWrites).toEqual([]);
|
|
89
|
+
});
|
|
90
|
+
//# sourceMappingURL=catalog-refresh.e2e.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-refresh.e2e.test.js","sourceRoot":"","sources":["../src/catalog-refresh.e2e.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Goke } from 'goke';
|
|
2
|
+
export declare function registerStartCommand(cli: Goke): void;
|
|
3
|
+
export declare function registerLoginCommands(cli: Goke): void;
|
|
4
|
+
export declare function registerToolCommands(cli: Goke): void;
|
|
5
|
+
export declare function registerBotCommands(cli: Goke): void;
|
package/dist/cli/bot.js
ADDED
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
// Bot lifecycle and setup: the root command (start + onboarding), provider
|
|
2
|
+
// login, tools (tunnel, tts), and bot status, logs, credentials and keys.
|
|
3
|
+
// main.ts, onboarding.ts, traforo, SQLite and voice are loaded only by the
|
|
4
|
+
// commands that run them (see the note in shared.ts).
|
|
5
|
+
import { spawn } from 'node:child_process';
|
|
6
|
+
import fs from 'node:fs';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { setTimeout as sleep } from 'node:timers/promises';
|
|
9
|
+
import dedent from 'string-dedent';
|
|
10
|
+
import { distCliEntry, writeAutostartScript } from "../autostart.js";
|
|
11
|
+
import { callBot, DEFAULT_LOCK_PORT, RESTART_EXIT_CODE, startLockServer } from "../lock-server.js";
|
|
12
|
+
import { parseDuration } from "../duration.js";
|
|
13
|
+
import { createLogger, setLogFile } from "../logger.js";
|
|
14
|
+
import { action, DATA_DIR_HELP, dataDirOrDefault, discordApi, fail, openCliDb, printJson } from "./shared.js";
|
|
15
|
+
const logger = createLogger('CLI');
|
|
16
|
+
// null when the file vanished meanwhile (bot restart).
|
|
17
|
+
async function readRange({ file, start, end }) {
|
|
18
|
+
const handle = await fs.promises.open(file, 'r').catch(() => null);
|
|
19
|
+
if (!handle)
|
|
20
|
+
return null;
|
|
21
|
+
const buffer = Buffer.alloc(end - start);
|
|
22
|
+
const read = await handle.read(buffer, 0, buffer.length, start).catch(() => null);
|
|
23
|
+
await handle.close().catch(() => undefined);
|
|
24
|
+
return read ? buffer.subarray(0, read.bytesRead) : null;
|
|
25
|
+
}
|
|
26
|
+
// tail -f that survives the bot truncating the file on restart.
|
|
27
|
+
async function followFile(file) {
|
|
28
|
+
const position = { offset: 0 };
|
|
29
|
+
while (true) {
|
|
30
|
+
const size = await fs.promises.stat(file).then((stat) => stat.size).catch(() => 0);
|
|
31
|
+
if (size < position.offset)
|
|
32
|
+
position.offset = 0;
|
|
33
|
+
if (size > position.offset) {
|
|
34
|
+
const chunk = await readRange({ file, start: position.offset, end: size });
|
|
35
|
+
if (chunk)
|
|
36
|
+
process.stdout.write(chunk);
|
|
37
|
+
position.offset = size;
|
|
38
|
+
}
|
|
39
|
+
await sleep(300);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// The root command runs the bot in a child process and starts it again when it
|
|
43
|
+
// exits with RESTART_EXIT_CODE (`kimaki restart`), so a restart loads new code:
|
|
44
|
+
//
|
|
45
|
+
// kimaki (supervisor) ──spawn, same argv, KIMAKI_SUPERVISED=1──▶ bot
|
|
46
|
+
// ▲ │
|
|
47
|
+
// └──────────── exit 75: spawn again; other code: exit ─────┘
|
|
48
|
+
//
|
|
49
|
+
// The child shares the terminal (stdio inherit), so onboarding prompts work.
|
|
50
|
+
// The IPC channel only exists so the child sees `disconnect` if the supervisor dies.
|
|
51
|
+
async function supervise() {
|
|
52
|
+
const state = { child: null };
|
|
53
|
+
// Ctrl+C reaches both processes; `kill <supervisor pid>` reaches only this one.
|
|
54
|
+
for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
|
|
55
|
+
process.on(signal, () => state.child?.kill('SIGTERM'));
|
|
56
|
+
}
|
|
57
|
+
while (true) {
|
|
58
|
+
const child = spawn(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
|
|
59
|
+
stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
|
|
60
|
+
env: { ...process.env, KIMAKI_SUPERVISED: '1' },
|
|
61
|
+
});
|
|
62
|
+
state.child = child;
|
|
63
|
+
const code = await new Promise((resolve) => {
|
|
64
|
+
child.once('error', (error) => {
|
|
65
|
+
process.stderr.write(`Cannot start the kimaki bot process: ${error.message}\n`);
|
|
66
|
+
resolve(1);
|
|
67
|
+
});
|
|
68
|
+
child.once('exit', (exitCode, signal) => resolve(exitCode ?? (signal ? 1 : 0)));
|
|
69
|
+
});
|
|
70
|
+
if (code !== RESTART_EXIT_CODE)
|
|
71
|
+
process.exit(code);
|
|
72
|
+
process.stderr.write('Restarting kimaki...\n');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// `kimaki` with no subcommand.
|
|
76
|
+
export function registerStartCommand(cli) {
|
|
77
|
+
cli.command('', 'Start the bot. Runs onboarding on first start')
|
|
78
|
+
.option('--data-dir <path>', DATA_DIR_HELP)
|
|
79
|
+
.option('-g, --guild <guildId>', 'Server to onboard when the bot is in several')
|
|
80
|
+
.option('--gateway', 'Use the shared Kimaki bot, no Discord app needed')
|
|
81
|
+
.option('--gateway-callback-url <url>', 'Redirect here after the gateway install (appends ?guild_id=<id>)')
|
|
82
|
+
.option('--install-url', 'Print the install URL and exit (non-interactive onboarding)')
|
|
83
|
+
.option('--machine-name <name>', 'Name in this machine\'s category "Kimaki <name>" (default: hostname)')
|
|
84
|
+
.option('--restart-onboarding', 'Choose credentials again')
|
|
85
|
+
.option('--worktrees', 'Use a fresh Git worktree for new sessions unless the channel overrides it')
|
|
86
|
+
.option('--voice <name>', 'Voice of voice calls, saved for later starts (e.g. cove, juniper, sol). "default" resets it')
|
|
87
|
+
.option('--no-analytics', 'Disable anonymous usage analytics (same as KIMAKI_STRADA_ENABLED=0)')
|
|
88
|
+
.option('--if-not-running', 'Start only if no bot runs; never stop the running one (used by autostart)')
|
|
89
|
+
.action(async (options) => {
|
|
90
|
+
// The IPC check ignores a KIMAKI_SUPERVISED leaked into a shell by an older bot.
|
|
91
|
+
if (process.env['KIMAKI_SUPERVISED'] !== '1' || !process.connected)
|
|
92
|
+
return supervise();
|
|
93
|
+
// OpenCode and agent shells inherit process.env: a bot started from a
|
|
94
|
+
// session (tests) would otherwise think it is supervised and SIGTERM itself on restart.
|
|
95
|
+
delete process.env['KIMAKI_SUPERVISED'];
|
|
96
|
+
// Bot code loads only here: the other subcommands start without it.
|
|
97
|
+
const [{ startBot }, { ensureOpencode, kimakiShellCommand, runOnboarding, startCaffeinate }, { emitEvent, gatewayCredentials, gatewayUrlsFromEnv, installUrlFor, readSavedCredentials, resolveCredentials, restApiUrl }, { openDb }, { createAnalytics }, { opencodeConfigDir, opencodeDbFile }, { defaultMachineName }, { ensureVoiceChannels, parseRealtimeVoice, saveVoiceCallVoice },] = await Promise.all([
|
|
98
|
+
import("../main.js"),
|
|
99
|
+
import("../onboarding.js"),
|
|
100
|
+
import("../credentials.js"),
|
|
101
|
+
import("../db.js"),
|
|
102
|
+
import("../analytics.js"),
|
|
103
|
+
import("../opencode-server.js"),
|
|
104
|
+
import("../project.js"),
|
|
105
|
+
import("../voice-call.js"),
|
|
106
|
+
]);
|
|
107
|
+
// Non-TTY hosts get the failure as an `error` event too (programmatic onboarding).
|
|
108
|
+
// Explicit type: TS narrows after a `never` call only for annotated consts.
|
|
109
|
+
const failStartup = (error, installUrl) => {
|
|
110
|
+
if (!process.stdin.isTTY)
|
|
111
|
+
emitEvent({ type: 'error', message: error.message, ...(installUrl && { install_url: installUrl }) });
|
|
112
|
+
fail(error);
|
|
113
|
+
};
|
|
114
|
+
const dataDir = dataDirOrDefault(options.dataDir);
|
|
115
|
+
const urls = gatewayUrlsFromEnv();
|
|
116
|
+
const machine = options.machineName ?? defaultMachineName();
|
|
117
|
+
// Validated before the lock, so a typo never stops the running bot. null: reset to the default.
|
|
118
|
+
const voice = (() => {
|
|
119
|
+
if (!options.voice)
|
|
120
|
+
return undefined;
|
|
121
|
+
if (options.voice.trim().toLowerCase() === 'default')
|
|
122
|
+
return null;
|
|
123
|
+
const parsed = parseRealtimeVoice(options.voice);
|
|
124
|
+
if (parsed instanceof Error)
|
|
125
|
+
fail(parsed);
|
|
126
|
+
return parsed.voice;
|
|
127
|
+
})();
|
|
128
|
+
if (options.installUrl) {
|
|
129
|
+
const opened = await openDb({ dataDir, migrate: true });
|
|
130
|
+
if (opened instanceof Error)
|
|
131
|
+
fail(opened);
|
|
132
|
+
const credentials = options.gateway
|
|
133
|
+
? await gatewayCredentials({ db: opened.db, urls })
|
|
134
|
+
: await readSavedCredentials({ db: opened.db });
|
|
135
|
+
opened.close();
|
|
136
|
+
if (credentials instanceof Error)
|
|
137
|
+
fail(credentials);
|
|
138
|
+
if (!credentials)
|
|
139
|
+
fail(new Error('No bot configured yet. Run kimaki first, or pass --gateway.'));
|
|
140
|
+
process.stdout.write(`${installUrlFor({ credentials, website: urls.website, callbackUrl: options.gatewayCallbackUrl })}\n`);
|
|
141
|
+
if (credentials.mode === 'gateway')
|
|
142
|
+
process.stderr.write('This URL contains your client credentials. Do not share it.\n');
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
// Stops a running bot of this port (V1 or V2) before the migration and
|
|
146
|
+
// onboarding, which must not run while it still writes. Before the log
|
|
147
|
+
// reset, so the stopped bot (or the one --if-not-running leaves running) keeps its kimaki.log.
|
|
148
|
+
const lock = await startLockServer({ port: Number(process.env['KIMAKI_LOCK_PORT'] || DEFAULT_LOCK_PORT), dataDir, supervised: true, evict: !options.ifNotRunning });
|
|
149
|
+
if (lock instanceof Error) {
|
|
150
|
+
// Another bot won the race after the plugin's health check.
|
|
151
|
+
if (options.ifNotRunning && lock.cause instanceof Error && Reflect.get(lock.cause, 'code') === 'EADDRINUSE') {
|
|
152
|
+
process.stderr.write(`Kimaki already runs on port ${lock.port}. Nothing to start.\n`);
|
|
153
|
+
process.exit(0);
|
|
154
|
+
}
|
|
155
|
+
failStartup(lock);
|
|
156
|
+
}
|
|
157
|
+
const logFile = setLogFile({ dataDir });
|
|
158
|
+
if (logFile instanceof Error)
|
|
159
|
+
failStartup(logFile);
|
|
160
|
+
// A crash goes to kimaki.log too (Node still prints it and exits).
|
|
161
|
+
process.on('uncaughtExceptionMonitor', (error, origin) => logger.error(`crash (${origin})`, error));
|
|
162
|
+
const opened = await openDb({ dataDir, migrate: true });
|
|
163
|
+
if (opened instanceof Error)
|
|
164
|
+
failStartup(opened);
|
|
165
|
+
// Before onboarding: without OpenCode the bot cannot start, so fail (or install it) before the Discord install.
|
|
166
|
+
const opencodeCheck = await ensureOpencode({ serviceFile: process.env['KIMAKI_OPENCODE_SERVICE_FILE'] });
|
|
167
|
+
if (opencodeCheck instanceof Error) {
|
|
168
|
+
opened.close();
|
|
169
|
+
failStartup(opencodeCheck);
|
|
170
|
+
}
|
|
171
|
+
startCaffeinate();
|
|
172
|
+
const resolved = await resolveCredentials({
|
|
173
|
+
db: opened.db,
|
|
174
|
+
gateway: Boolean(options.gateway),
|
|
175
|
+
restartOnboarding: Boolean(options.restartOnboarding),
|
|
176
|
+
urls,
|
|
177
|
+
callbackUrl: options.gatewayCallbackUrl,
|
|
178
|
+
});
|
|
179
|
+
// Saved in SQLite, so restarts, crashes and autostart keep it without the flag.
|
|
180
|
+
const savedVoice = resolved instanceof Error || voice === undefined ? undefined : await saveVoiceCallVoice({ db: opened.db, appId: resolved.credentials.appId, voice });
|
|
181
|
+
opened.close();
|
|
182
|
+
if (resolved instanceof Error)
|
|
183
|
+
failStartup(resolved);
|
|
184
|
+
if (savedVoice instanceof Error)
|
|
185
|
+
failStartup(savedVoice);
|
|
186
|
+
if (voice !== undefined)
|
|
187
|
+
logger.log(`voice calls use ${voice === null ? 'the default voice' : `the voice ${voice}`}`);
|
|
188
|
+
const { credentials, install } = resolved;
|
|
189
|
+
const installUrl = installUrlFor({ credentials, website: urls.website, callbackUrl: options.gatewayCallbackUrl });
|
|
190
|
+
// The agent calls this same install. Prefer the built dist entry, so agent
|
|
191
|
+
// commands skip the tsx loader also when the bot runs from src.
|
|
192
|
+
const distCli = distCliEntry();
|
|
193
|
+
const kimaki = kimakiShellCommand({
|
|
194
|
+
command: fs.existsSync(distCli)
|
|
195
|
+
? [process.execPath, distCli]
|
|
196
|
+
: [process.execPath, ...process.execArgv, process.argv[1] ?? 'kimaki'],
|
|
197
|
+
});
|
|
198
|
+
const bot = await startBot({
|
|
199
|
+
kimakiCommand: kimaki,
|
|
200
|
+
dataDir,
|
|
201
|
+
token: credentials.token,
|
|
202
|
+
appId: credentials.appId,
|
|
203
|
+
discordRestUrl: restApiUrl(credentials),
|
|
204
|
+
lock,
|
|
205
|
+
opencodeServiceFile: process.env['KIMAKI_OPENCODE_SERVICE_FILE'],
|
|
206
|
+
ensureOpencode: true,
|
|
207
|
+
opencodeConfigDir: opencodeConfigDir(),
|
|
208
|
+
opencodeDbFile: opencodeDbFile(),
|
|
209
|
+
analytics: createAnalytics({ dataDir, botMode: credentials.mode, enabled: !options.noAnalytics }),
|
|
210
|
+
autoWorktrees: Boolean(options.worktrees),
|
|
211
|
+
});
|
|
212
|
+
if (bot instanceof Error)
|
|
213
|
+
failStartup(bot);
|
|
214
|
+
// exit() keeps process.exitCode: the restart route sets RESTART_EXIT_CODE before its SIGTERM.
|
|
215
|
+
const shutdown = () => {
|
|
216
|
+
void bot.stop().then(() => process.exit());
|
|
217
|
+
};
|
|
218
|
+
process.once('SIGTERM', shutdown);
|
|
219
|
+
process.once('SIGINT', shutdown);
|
|
220
|
+
// The supervisor died (SIGKILL, crash): nobody owns this bot anymore.
|
|
221
|
+
process.once('disconnect', shutdown);
|
|
222
|
+
const gateway = credentials.mode === 'gateway';
|
|
223
|
+
const onboarded = await runOnboarding({ bot, dataDir, guildId: options.guild ?? install?.guildId, installUrl, kimaki, gateway, installerId: install?.installerId, machine });
|
|
224
|
+
// The bot keeps running; the next start retries onboarding.
|
|
225
|
+
if (onboarded instanceof Error) {
|
|
226
|
+
logger.error(`onboarding failed`, onboarded);
|
|
227
|
+
if (!process.stdin.isTTY)
|
|
228
|
+
emitEvent({ type: 'error', message: `Onboarding failed: ${onboarded.message}. The bot is running; restart kimaki to retry.` });
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (onboarded)
|
|
232
|
+
process.stderr.write(`Onboarding thread: https://discord.com/channels/${onboarded.guildId}/${onboarded.threadId}\n`);
|
|
233
|
+
const voiceChannels = await ensureVoiceChannels(bot, { machine });
|
|
234
|
+
if (voiceChannels instanceof Error)
|
|
235
|
+
logger.warn('cannot create the Kimaki voice channel', voiceChannels);
|
|
236
|
+
// Only the default port: the plugin checks that one. Runtime flags only;
|
|
237
|
+
// credentials, onboarding and --voice are saved in SQLite.
|
|
238
|
+
if (lock.port === DEFAULT_LOCK_PORT) {
|
|
239
|
+
const autostart = await writeAutostartScript({ dataDir, args: [
|
|
240
|
+
...(options.worktrees ? ['--worktrees'] : []),
|
|
241
|
+
...(options.noAnalytics ? ['--no-analytics'] : []),
|
|
242
|
+
...(options.machineName ? ['--machine-name', options.machineName] : []),
|
|
243
|
+
] });
|
|
244
|
+
if (autostart instanceof Error)
|
|
245
|
+
logger.warn('cannot write the autostart script', autostart);
|
|
246
|
+
}
|
|
247
|
+
if (!process.stdin.isTTY)
|
|
248
|
+
emitEvent({ type: 'ready', app_id: credentials.appId, guild_ids: [...bot.discord.guilds.cache.keys()] });
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
// login, login credential: OpenCode provider credentials through the bot.
|
|
252
|
+
export function registerLoginCommands(cli) {
|
|
253
|
+
cli.command('login <provider>', 'Connect a provider using OpenCode integration credentials')
|
|
254
|
+
.option('--data-dir <path>', DATA_DIR_HELP)
|
|
255
|
+
.option('--key <key>', 'API key to store in OpenCode')
|
|
256
|
+
.option('--method <id>', 'OAuth method ID; without flags, list login methods')
|
|
257
|
+
.option('--attempt <id>', 'Check or complete this native OAuth attempt')
|
|
258
|
+
.option('--code <code>', 'Authorization code for the attempt')
|
|
259
|
+
.option('--cancel', 'Cancel the native OAuth attempt')
|
|
260
|
+
.action(async (provider, options) => {
|
|
261
|
+
await action({ route: 'login', dataDir: options.dataDir, input: {
|
|
262
|
+
provider, key: options.key, method: options.method, attempt: options.attempt, code: options.code, ...(options.cancel && { operation: 'cancel' }),
|
|
263
|
+
} });
|
|
264
|
+
});
|
|
265
|
+
cli.command('login credential <id>', 'Activate, remove, or label an OpenCode credential')
|
|
266
|
+
.option('--data-dir <path>', DATA_DIR_HELP)
|
|
267
|
+
.option('--operation <name>', 'activate | remove | label')
|
|
268
|
+
.option('--label <text>', 'Credential label')
|
|
269
|
+
.action(async (id, options) => {
|
|
270
|
+
await action({ route: 'credential', dataDir: options.dataDir, input: { id, operation: options.operation ?? 'activate', label: options.label } });
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
// tunnel, tts
|
|
274
|
+
export function registerToolCommands(cli) {
|
|
275
|
+
cli.command('tunnel', 'Run a command and expose its local port with a public URL. The child gets TRAFORO_URL')
|
|
276
|
+
.option('-p, --port <port>', 'Local port (default: read from the command output)')
|
|
277
|
+
.option('-t, --tunnel-id <id>', 'Fixed tunnel ID (default: random). Only for public-safe services')
|
|
278
|
+
.option('--host <host>', 'Local host (default: localhost)')
|
|
279
|
+
.option('-k, --kill', 'Kill the process on --port first')
|
|
280
|
+
.example('kimaki tunnel -- pnpm dev')
|
|
281
|
+
.action(async (options) => {
|
|
282
|
+
const command = options['--'] ?? [];
|
|
283
|
+
const port = options.port ? Number(options.port) : undefined;
|
|
284
|
+
if (port !== undefined && (!Number.isInteger(port) || port < 1 || port > 65_535))
|
|
285
|
+
fail(new Error(`Invalid --port ${options.port}`));
|
|
286
|
+
if (!port && command.length === 0)
|
|
287
|
+
fail(new Error('Pass a command after --, or --port <port>. Example: kimaki tunnel -- pnpm dev'));
|
|
288
|
+
const { runTunnel } = await import('traforo/run-tunnel');
|
|
289
|
+
await runTunnel({ port, command: command.length > 0 ? command : undefined, tunnelId: options.tunnelId, localHost: options.host, baseDomain: 'kimaki.dev', kill: options.kill });
|
|
290
|
+
});
|
|
291
|
+
cli.command('tts [text]', 'Text to speech with OpenAI or Gemini. Reads stdin if no text is given')
|
|
292
|
+
.option('--data-dir <path>', DATA_DIR_HELP)
|
|
293
|
+
.option('-o, --output <path>', 'Output file (default: speech.mp3 or speech.wav)')
|
|
294
|
+
.option('-p, --provider <name>', 'openai | gemini (default: from the stored key)')
|
|
295
|
+
.option('-v, --voice <voice>', 'Voice ID (default: alloy for OpenAI, Kore for Gemini)')
|
|
296
|
+
.option('-i, --instructions <text>', 'Style instructions (OpenAI only)')
|
|
297
|
+
.option('--speed <n>', '0.25 to 4.0 (OpenAI only, default: 1.25)')
|
|
298
|
+
.action(async (text, options) => {
|
|
299
|
+
const chunks = [];
|
|
300
|
+
if (!text && !process.stdin.isTTY)
|
|
301
|
+
for await (const chunk of process.stdin)
|
|
302
|
+
chunks.push(Buffer.from(chunk));
|
|
303
|
+
const input = text ?? Buffer.concat(chunks).toString('utf8').trim();
|
|
304
|
+
if (!input)
|
|
305
|
+
fail(new Error('Pass the text as an argument or pipe it via stdin'));
|
|
306
|
+
if (options.provider && options.provider !== 'openai' && options.provider !== 'gemini')
|
|
307
|
+
fail(new Error('--provider must be openai or gemini'));
|
|
308
|
+
const speed = options.speed ? Number(options.speed) : 1.25;
|
|
309
|
+
if (!(speed >= 0.25 && speed <= 4))
|
|
310
|
+
fail(new Error('--speed must be between 0.25 and 4'));
|
|
311
|
+
const [{ openDb }, { audioKeyCandidates, generateSpeech }] = await Promise.all([import("../db.js"), import("../voice.js")]);
|
|
312
|
+
// Any stored bot_api_keys row (imported from V1 /transcription-key); a missing database only skips it.
|
|
313
|
+
const opened = await openDb({ dataDir: dataDirOrDefault(options.dataDir), migrate: false });
|
|
314
|
+
const stored = opened instanceof Error ? null : await opened.db.query.bot_api_keys.findFirst().catch(() => null);
|
|
315
|
+
if (!(opened instanceof Error))
|
|
316
|
+
opened.close();
|
|
317
|
+
const key = audioKeyCandidates(stored).find((candidate) => !options.provider || candidate.provider === options.provider);
|
|
318
|
+
if (!key)
|
|
319
|
+
fail(new Error('No OpenAI or Gemini key. Set OPENAI_API_KEY or GEMINI_API_KEY'));
|
|
320
|
+
const result = await generateSpeech({ text: input, apiKey: key.apiKey, provider: key.provider, voice: options.voice, instructions: options.instructions, speed });
|
|
321
|
+
if (result instanceof Error)
|
|
322
|
+
fail(result);
|
|
323
|
+
const output = path.resolve(options.output ?? `speech.${result.mediaType === 'audio/mp3' ? 'mp3' : 'wav'}`);
|
|
324
|
+
await fs.promises.writeFile(output, result.audio);
|
|
325
|
+
process.stdout.write(`${output}\n`);
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
// status, logs, bot token / keys set / install-url
|
|
329
|
+
export function registerBotCommands(cli) {
|
|
330
|
+
cli.command('status', 'Bot health: running, pid, uptime, OpenCode URL and version, guilds')
|
|
331
|
+
.option('--data-dir <path>', DATA_DIR_HELP)
|
|
332
|
+
.option('--json', 'Output as JSON')
|
|
333
|
+
.action(async (options) => {
|
|
334
|
+
const result = await callBot({ dataDir: dataDirOrDefault(options.dataDir), route: 'status', input: {} });
|
|
335
|
+
if (result instanceof Error) {
|
|
336
|
+
process.stdout.write(options.json ? `${JSON.stringify({ running: false, reason: result.message })}\n` : `not running: ${result.message}\n`);
|
|
337
|
+
process.exitCode = 1;
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
const status = { running: true, ...result.data };
|
|
341
|
+
if (options.json)
|
|
342
|
+
return printJson(status);
|
|
343
|
+
process.stdout.write(dedent `
|
|
344
|
+
running: pid ${status.pid}, up ${status.uptimeSec}s, mode ${JSON.stringify(status.mode)}
|
|
345
|
+
opencode: ${JSON.stringify(status.opencode)}
|
|
346
|
+
guilds: ${JSON.stringify(status.guilds)}
|
|
347
|
+
data dir: ${JSON.stringify(status.dataDir)}
|
|
348
|
+
` + '\n');
|
|
349
|
+
});
|
|
350
|
+
cli.command('logs', 'Print the log file path. The bot resets the file on every start')
|
|
351
|
+
.option('--data-dir <path>', DATA_DIR_HELP)
|
|
352
|
+
.option('-f, --follow', 'Print the log and keep printing new lines')
|
|
353
|
+
.action(async (options) => {
|
|
354
|
+
const file = path.join(dataDirOrDefault(options.dataDir), 'kimaki.log');
|
|
355
|
+
if (!options.follow) {
|
|
356
|
+
process.stdout.write(`${file}\n`);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
await followFile(file);
|
|
360
|
+
});
|
|
361
|
+
cli.command('restart', 'Restart the running bot with the code on disk. Sessions keep running in OpenCode')
|
|
362
|
+
.option('--data-dir <path>', DATA_DIR_HELP)
|
|
363
|
+
.action(async (options) => {
|
|
364
|
+
const result = await callBot({ dataDir: dataDirOrDefault(options.dataDir), route: 'restart', input: {} });
|
|
365
|
+
if (result instanceof Error)
|
|
366
|
+
fail(result);
|
|
367
|
+
process.stdout.write(`Restarting bot (pid ${result.data.pid})\n`);
|
|
368
|
+
});
|
|
369
|
+
cli.command('profile cpu', 'Record a CPU profile of the running bot and print the .cpuprofile path')
|
|
370
|
+
.option('--data-dir <path>', DATA_DIR_HELP)
|
|
371
|
+
.option('-d, --duration <duration>', 'How long to record, e.g. 20s or 2m (default: 20s)')
|
|
372
|
+
.example('kimaki profile cpu --duration 30s')
|
|
373
|
+
.action(async (options) => {
|
|
374
|
+
const durationMs = parseDuration(options.duration ?? '20s', '--duration');
|
|
375
|
+
if (durationMs instanceof Error)
|
|
376
|
+
fail(durationMs);
|
|
377
|
+
// Ctrl+C stops the recording early; the bot still writes the profile.
|
|
378
|
+
const controller = new AbortController();
|
|
379
|
+
process.once('SIGINT', () => controller.abort());
|
|
380
|
+
const signal = AbortSignal.any([controller.signal, AbortSignal.timeout(durationMs + 30_000)]);
|
|
381
|
+
process.stderr.write(`Recording for ${options.duration ?? '20s'}. Press Ctrl+C to stop early.\n`);
|
|
382
|
+
const result = await callBot({ dataDir: dataDirOrDefault(options.dataDir), route: 'profile.cpu', input: { durationMs }, signal });
|
|
383
|
+
if (result instanceof Error)
|
|
384
|
+
fail(controller.signal.aborted ? new Error('Stopped early. The bot writes the profile to <data dir>/profiles/') : result);
|
|
385
|
+
process.stdout.write(`${result.data.path}\n`);
|
|
386
|
+
});
|
|
387
|
+
cli.command('profile heap', 'Write a heap snapshot of the running bot and print the .heapsnapshot path')
|
|
388
|
+
.option('--data-dir <path>', DATA_DIR_HELP)
|
|
389
|
+
.action(async (options) => {
|
|
390
|
+
const result = await callBot({ dataDir: dataDirOrDefault(options.dataDir), route: 'profile.heap', input: {}, signal: AbortSignal.timeout(300_000) });
|
|
391
|
+
if (result instanceof Error)
|
|
392
|
+
fail(result);
|
|
393
|
+
process.stdout.write(`${result.data.path}\n`);
|
|
394
|
+
});
|
|
395
|
+
cli.command('bot token', 'Print saved bot credentials for automation')
|
|
396
|
+
.option('--data-dir <path>', DATA_DIR_HELP)
|
|
397
|
+
.action(async (options) => process.stdout.write(`${(await discordApi(options.dataDir)).credentials.token}\n`));
|
|
398
|
+
cli.command('bot keys set', 'Store OpenAI or Gemini API keys for voice transcription and kimaki tts')
|
|
399
|
+
.option('--data-dir <path>', DATA_DIR_HELP)
|
|
400
|
+
.option('--openai <key>', 'OpenAI API key')
|
|
401
|
+
.option('--gemini <key>', 'Gemini API key')
|
|
402
|
+
.action(async (options) => {
|
|
403
|
+
const [{ readSavedCredentials }, { saveAudioKeys }] = await Promise.all([import("../credentials.js"), import("../voice.js")]);
|
|
404
|
+
const opened = await openCliDb(options.dataDir);
|
|
405
|
+
const result = await (async () => {
|
|
406
|
+
const credentials = await readSavedCredentials({ db: opened.db });
|
|
407
|
+
if (credentials instanceof Error)
|
|
408
|
+
return credentials;
|
|
409
|
+
if (!credentials)
|
|
410
|
+
return new Error('No saved bot credentials. Start kimaki once to onboard.');
|
|
411
|
+
return saveAudioKeys({ db: opened.db, token: credentials.token, openai: options.openai, gemini: options.gemini });
|
|
412
|
+
})();
|
|
413
|
+
opened.close();
|
|
414
|
+
if (result instanceof Error)
|
|
415
|
+
fail(result);
|
|
416
|
+
process.stdout.write(`Saved ${[options.openai && 'OpenAI', options.gemini && 'Gemini'].filter(Boolean).join(' and ')} API key\n`);
|
|
417
|
+
});
|
|
418
|
+
cli.command('bot install-url', 'Print the Discord bot install URL')
|
|
419
|
+
.option('--data-dir <path>', DATA_DIR_HELP)
|
|
420
|
+
.option('--gateway-callback-url <url>', 'Gateway only: redirect here after the install')
|
|
421
|
+
.action(async (options) => {
|
|
422
|
+
const { installUrlFor, gatewayUrlsFromEnv } = await import("../credentials.js");
|
|
423
|
+
const { credentials } = await discordApi(options.dataDir);
|
|
424
|
+
process.stdout.write(`${installUrlFor({ credentials, website: gatewayUrlsFromEnv().website, callbackUrl: options.gatewayCallbackUrl })}\n`);
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
//# sourceMappingURL=bot.js.map
|