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
package/dist/database.js
DELETED
|
@@ -1,1074 +0,0 @@
|
|
|
1
|
-
// SQLite database manager for persistent bot state using Drizzle.
|
|
2
|
-
// Stores thread-session mappings, bot tokens, channel directories,
|
|
3
|
-
// API keys, and model preferences in <dataDir>/discord-sessions.db.
|
|
4
|
-
import crypto from 'node:crypto';
|
|
5
|
-
import fs from 'node:fs';
|
|
6
|
-
import path from 'node:path';
|
|
7
|
-
import * as errore from 'errore';
|
|
8
|
-
import * as orm from 'drizzle-orm';
|
|
9
|
-
import { getDb, closeDb } from './db.js';
|
|
10
|
-
import { createLogger, LogPrefix } from './logger.js';
|
|
11
|
-
import * as schema from './schema.js';
|
|
12
|
-
import { store } from './store.js';
|
|
13
|
-
const dbLogger = createLogger(LogPrefix.DB);
|
|
14
|
-
export { getDb, closeDb };
|
|
15
|
-
export async function initDatabase() {
|
|
16
|
-
const db = await getDb();
|
|
17
|
-
dbLogger.log('Database initialized');
|
|
18
|
-
return db;
|
|
19
|
-
}
|
|
20
|
-
export const closeDatabase = closeDb;
|
|
21
|
-
function countRows(rows) {
|
|
22
|
-
return rows.length;
|
|
23
|
-
}
|
|
24
|
-
export async function createScheduledTask({ scheduleKind, runAt, cronExpr, timezone, nextRunAt, payloadJson, promptPreview, channelId, threadId, sessionId, projectDirectory, }) {
|
|
25
|
-
const db = await getDb();
|
|
26
|
-
const [row] = await db.insert(schema.scheduled_tasks).values({
|
|
27
|
-
status: 'planned',
|
|
28
|
-
schedule_kind: scheduleKind,
|
|
29
|
-
run_at: runAt ?? null,
|
|
30
|
-
cron_expr: cronExpr ?? null,
|
|
31
|
-
timezone: timezone ?? null,
|
|
32
|
-
next_run_at: nextRunAt,
|
|
33
|
-
payload_json: payloadJson,
|
|
34
|
-
prompt_preview: promptPreview,
|
|
35
|
-
channel_id: channelId ?? null,
|
|
36
|
-
thread_id: threadId ?? null,
|
|
37
|
-
session_id: sessionId ?? null,
|
|
38
|
-
project_directory: projectDirectory ?? null,
|
|
39
|
-
}).returning({ id: schema.scheduled_tasks.id });
|
|
40
|
-
if (!row)
|
|
41
|
-
throw new Error('Failed to create scheduled task');
|
|
42
|
-
return row.id;
|
|
43
|
-
}
|
|
44
|
-
export async function listScheduledTasks({ statuses, } = {}) {
|
|
45
|
-
const db = await getDb();
|
|
46
|
-
return db.query.scheduled_tasks.findMany({
|
|
47
|
-
where: statuses && statuses.length > 0 ? { status: { in: statuses } } : undefined,
|
|
48
|
-
orderBy: { next_run_at: 'asc', id: 'asc' },
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
export async function getScheduledTask(taskId) {
|
|
52
|
-
const db = await getDb();
|
|
53
|
-
return await db.query.scheduled_tasks.findFirst({ where: { id: taskId } }) ?? null;
|
|
54
|
-
}
|
|
55
|
-
export async function updateScheduledTask({ taskId, payloadJson, promptPreview, scheduleKind, runAt, cronExpr, timezone, nextRunAt, }) {
|
|
56
|
-
const db = await getDb();
|
|
57
|
-
const data = {
|
|
58
|
-
payload_json: payloadJson,
|
|
59
|
-
prompt_preview: promptPreview,
|
|
60
|
-
};
|
|
61
|
-
if (scheduleKind !== undefined)
|
|
62
|
-
data.schedule_kind = scheduleKind;
|
|
63
|
-
if (runAt !== undefined)
|
|
64
|
-
data.run_at = runAt;
|
|
65
|
-
if (cronExpr !== undefined)
|
|
66
|
-
data.cron_expr = cronExpr;
|
|
67
|
-
if (timezone !== undefined)
|
|
68
|
-
data.timezone = timezone;
|
|
69
|
-
if (nextRunAt !== undefined)
|
|
70
|
-
data.next_run_at = nextRunAt;
|
|
71
|
-
const rows = await db.update(schema.scheduled_tasks)
|
|
72
|
-
.set(data)
|
|
73
|
-
.where(orm.and(orm.eq(schema.scheduled_tasks.id, taskId), orm.eq(schema.scheduled_tasks.status, 'planned')))
|
|
74
|
-
.returning({ id: schema.scheduled_tasks.id });
|
|
75
|
-
return countRows(rows) > 0;
|
|
76
|
-
}
|
|
77
|
-
export async function cancelScheduledTask(taskId) {
|
|
78
|
-
const db = await getDb();
|
|
79
|
-
const rows = await db.update(schema.scheduled_tasks)
|
|
80
|
-
.set({ status: 'cancelled', running_started_at: null })
|
|
81
|
-
.where(orm.and(orm.eq(schema.scheduled_tasks.id, taskId), orm.inArray(schema.scheduled_tasks.status, ['planned', 'running'])))
|
|
82
|
-
.returning({ id: schema.scheduled_tasks.id });
|
|
83
|
-
return countRows(rows) > 0;
|
|
84
|
-
}
|
|
85
|
-
export async function getDuePlannedScheduledTasks({ now, limit }) {
|
|
86
|
-
const db = await getDb();
|
|
87
|
-
return db.query.scheduled_tasks.findMany({
|
|
88
|
-
where: { status: 'planned', next_run_at: { lte: now } },
|
|
89
|
-
orderBy: { next_run_at: 'asc', id: 'asc' },
|
|
90
|
-
limit,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
export async function claimScheduledTaskRunning({ taskId, startedAt }) {
|
|
94
|
-
const db = await getDb();
|
|
95
|
-
const rows = await db.update(schema.scheduled_tasks)
|
|
96
|
-
.set({ status: 'running', running_started_at: startedAt })
|
|
97
|
-
.where(orm.and(orm.eq(schema.scheduled_tasks.id, taskId), orm.eq(schema.scheduled_tasks.status, 'planned')))
|
|
98
|
-
.returning({ id: schema.scheduled_tasks.id });
|
|
99
|
-
return countRows(rows) > 0;
|
|
100
|
-
}
|
|
101
|
-
export async function releaseScheduledTaskClaim(taskId) {
|
|
102
|
-
const db = await getDb();
|
|
103
|
-
await db.update(schema.scheduled_tasks)
|
|
104
|
-
.set({ status: 'planned', running_started_at: null })
|
|
105
|
-
.where(orm.and(orm.eq(schema.scheduled_tasks.id, taskId), orm.eq(schema.scheduled_tasks.status, 'running')));
|
|
106
|
-
}
|
|
107
|
-
export async function createScheduledTaskRun({ taskId, startedAt, }) {
|
|
108
|
-
const db = await getDb();
|
|
109
|
-
const [run] = await db.insert(schema.scheduled_task_runs)
|
|
110
|
-
.values({ scheduled_task_id: taskId, started_at: startedAt })
|
|
111
|
-
.returning({ id: schema.scheduled_task_runs.id });
|
|
112
|
-
if (!run)
|
|
113
|
-
throw new Error(`Failed to create run for scheduled task ${taskId}`);
|
|
114
|
-
return run.id;
|
|
115
|
-
}
|
|
116
|
-
export async function getActiveScheduledTaskRuns(taskId) {
|
|
117
|
-
const db = await getDb();
|
|
118
|
-
return db.query.scheduled_task_runs.findMany({
|
|
119
|
-
where: {
|
|
120
|
-
scheduled_task_id: taskId,
|
|
121
|
-
status: { in: ['pending', 'running'] },
|
|
122
|
-
},
|
|
123
|
-
orderBy: { started_at: 'desc' },
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
export async function setScheduledTaskRunThread({ runId, threadId, }) {
|
|
127
|
-
const db = await getDb();
|
|
128
|
-
await db.update(schema.scheduled_task_runs)
|
|
129
|
-
.set({ thread_id: threadId })
|
|
130
|
-
.where(orm.eq(schema.scheduled_task_runs.id, runId));
|
|
131
|
-
}
|
|
132
|
-
export async function startScheduledTaskRunSession({ runId, sessionId, projectDirectory, }) {
|
|
133
|
-
const db = await getDb();
|
|
134
|
-
await db.update(schema.scheduled_task_runs)
|
|
135
|
-
.set({ status: 'running', session_id: sessionId, project_directory: projectDirectory })
|
|
136
|
-
.where(orm.and(orm.eq(schema.scheduled_task_runs.id, runId), orm.eq(schema.scheduled_task_runs.status, 'pending')));
|
|
137
|
-
}
|
|
138
|
-
export async function completeScheduledTaskRunsForSession(sessionId) {
|
|
139
|
-
const db = await getDb();
|
|
140
|
-
const rows = await db.update(schema.scheduled_task_runs)
|
|
141
|
-
.set({ status: 'completed', completed_at: new Date() })
|
|
142
|
-
.where(orm.and(orm.eq(schema.scheduled_task_runs.session_id, sessionId), orm.inArray(schema.scheduled_task_runs.status, ['pending', 'running'])))
|
|
143
|
-
.returning({ id: schema.scheduled_task_runs.id });
|
|
144
|
-
return rows.length;
|
|
145
|
-
}
|
|
146
|
-
export async function failScheduledTaskRunsForSession({ sessionId, error, }) {
|
|
147
|
-
const db = await getDb();
|
|
148
|
-
const rows = await db.update(schema.scheduled_task_runs)
|
|
149
|
-
.set({ status: 'failed', completed_at: new Date(), error })
|
|
150
|
-
.where(orm.and(orm.eq(schema.scheduled_task_runs.session_id, sessionId), orm.inArray(schema.scheduled_task_runs.status, ['pending', 'running'])))
|
|
151
|
-
.returning({ id: schema.scheduled_task_runs.id });
|
|
152
|
-
return rows.length;
|
|
153
|
-
}
|
|
154
|
-
export async function failScheduledTaskRun({ runId, error, }) {
|
|
155
|
-
const db = await getDb();
|
|
156
|
-
await db.update(schema.scheduled_task_runs)
|
|
157
|
-
.set({ status: 'failed', completed_at: new Date(), error })
|
|
158
|
-
.where(orm.eq(schema.scheduled_task_runs.id, runId));
|
|
159
|
-
}
|
|
160
|
-
export async function finishScheduledTaskRun({ runId, status, }) {
|
|
161
|
-
const db = await getDb();
|
|
162
|
-
await db.update(schema.scheduled_task_runs)
|
|
163
|
-
.set({ status, completed_at: new Date() })
|
|
164
|
-
.where(orm.eq(schema.scheduled_task_runs.id, runId));
|
|
165
|
-
}
|
|
166
|
-
export async function recoverStaleRunningScheduledTasks({ staleBefore }) {
|
|
167
|
-
const db = await getDb();
|
|
168
|
-
const rows = await db.update(schema.scheduled_tasks)
|
|
169
|
-
.set({ status: 'planned', running_started_at: null })
|
|
170
|
-
.where(orm.and(orm.eq(schema.scheduled_tasks.status, 'running'), orm.lte(schema.scheduled_tasks.running_started_at, staleBefore)))
|
|
171
|
-
.returning({ id: schema.scheduled_tasks.id });
|
|
172
|
-
return countRows(rows);
|
|
173
|
-
}
|
|
174
|
-
export async function deleteScheduledTask(taskId) {
|
|
175
|
-
const db = await getDb();
|
|
176
|
-
await db.delete(schema.scheduled_tasks)
|
|
177
|
-
.where(orm.and(orm.eq(schema.scheduled_tasks.id, taskId), orm.eq(schema.scheduled_tasks.status, 'running')));
|
|
178
|
-
}
|
|
179
|
-
export async function markScheduledTaskCronRescheduled({ taskId, completedAt, nextRunAt }) {
|
|
180
|
-
const db = await getDb();
|
|
181
|
-
await db.update(schema.scheduled_tasks)
|
|
182
|
-
.set({ status: 'planned', last_run_at: completedAt, running_started_at: null, last_error: null, next_run_at: nextRunAt })
|
|
183
|
-
.where(orm.and(orm.eq(schema.scheduled_tasks.id, taskId), orm.eq(schema.scheduled_tasks.status, 'running')));
|
|
184
|
-
}
|
|
185
|
-
export async function markScheduledTaskFailed({ taskId, failedAt, errorMessage }) {
|
|
186
|
-
const db = await getDb();
|
|
187
|
-
await db.update(schema.scheduled_tasks)
|
|
188
|
-
.set({
|
|
189
|
-
status: 'failed',
|
|
190
|
-
last_run_at: failedAt,
|
|
191
|
-
running_started_at: null,
|
|
192
|
-
last_error: errorMessage,
|
|
193
|
-
attempts: orm.sql `${schema.scheduled_tasks.attempts} + 1`,
|
|
194
|
-
})
|
|
195
|
-
.where(orm.and(orm.eq(schema.scheduled_tasks.id, taskId), orm.eq(schema.scheduled_tasks.status, 'running')));
|
|
196
|
-
}
|
|
197
|
-
export async function markScheduledTaskCronRetry({ taskId, failedAt, errorMessage, nextRunAt }) {
|
|
198
|
-
const db = await getDb();
|
|
199
|
-
await db.update(schema.scheduled_tasks)
|
|
200
|
-
.set({
|
|
201
|
-
status: 'planned',
|
|
202
|
-
next_run_at: nextRunAt,
|
|
203
|
-
last_run_at: failedAt,
|
|
204
|
-
running_started_at: null,
|
|
205
|
-
last_error: errorMessage,
|
|
206
|
-
attempts: orm.sql `${schema.scheduled_tasks.attempts} + 1`,
|
|
207
|
-
})
|
|
208
|
-
.where(orm.and(orm.eq(schema.scheduled_tasks.id, taskId), orm.eq(schema.scheduled_tasks.status, 'running')));
|
|
209
|
-
}
|
|
210
|
-
export async function setSessionStartSource({ sessionId, scheduleKind, scheduledTaskId }) {
|
|
211
|
-
const db = await getDb();
|
|
212
|
-
await db.insert(schema.session_start_sources)
|
|
213
|
-
.values({ session_id: sessionId, schedule_kind: scheduleKind, scheduled_task_id: scheduledTaskId ?? null })
|
|
214
|
-
.onConflictDoUpdate({
|
|
215
|
-
target: schema.session_start_sources.session_id,
|
|
216
|
-
set: { schedule_kind: scheduleKind, scheduled_task_id: scheduledTaskId ?? null, updated_at: new Date() },
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
export async function upsertSessionSleep({ sessionId, wakeAt, reason, }) {
|
|
220
|
-
const db = await getDb();
|
|
221
|
-
// A new occurrence gets a fresh delivery_id, which invalidates any in-flight
|
|
222
|
-
// wake for the previous occurrence: every delivery write is guarded on it.
|
|
223
|
-
const deliveryId = crypto.randomUUID();
|
|
224
|
-
await db.insert(schema.session_sleeps)
|
|
225
|
-
.values({
|
|
226
|
-
session_id: sessionId,
|
|
227
|
-
wake_at: wakeAt,
|
|
228
|
-
reason: reason ?? null,
|
|
229
|
-
status: 'planned',
|
|
230
|
-
delivery_id: deliveryId,
|
|
231
|
-
})
|
|
232
|
-
.onConflictDoUpdate({
|
|
233
|
-
target: schema.session_sleeps.session_id,
|
|
234
|
-
set: {
|
|
235
|
-
wake_at: wakeAt,
|
|
236
|
-
reason: reason ?? null,
|
|
237
|
-
status: 'planned',
|
|
238
|
-
delivery_id: deliveryId,
|
|
239
|
-
attempts: 0,
|
|
240
|
-
last_attempt_at: null,
|
|
241
|
-
created_at: new Date(),
|
|
242
|
-
},
|
|
243
|
-
});
|
|
244
|
-
return deliveryId;
|
|
245
|
-
}
|
|
246
|
-
export async function getSessionSleep({ sessionId }) {
|
|
247
|
-
const db = await getDb();
|
|
248
|
-
return await db.query.session_sleeps.findFirst({
|
|
249
|
-
where: { session_id: sessionId },
|
|
250
|
-
}) ?? null;
|
|
251
|
-
}
|
|
252
|
-
/** Rows that are due and not attempted too recently. Status stays `planned`. */
|
|
253
|
-
export async function getDueSessionSleeps({ now, retryAfterMs, limit, }) {
|
|
254
|
-
const db = await getDb();
|
|
255
|
-
const retryBefore = new Date(now.getTime() - retryAfterMs);
|
|
256
|
-
return db.select()
|
|
257
|
-
.from(schema.session_sleeps)
|
|
258
|
-
.where(orm.and(orm.eq(schema.session_sleeps.status, 'planned'), orm.lte(schema.session_sleeps.wake_at, now), orm.or(orm.isNull(schema.session_sleeps.last_attempt_at), orm.lte(schema.session_sleeps.last_attempt_at, retryBefore))))
|
|
259
|
-
.orderBy(orm.asc(schema.session_sleeps.wake_at))
|
|
260
|
-
.limit(limit);
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Reserve one delivery attempt. The row never leaves `planned` here.
|
|
264
|
-
*
|
|
265
|
-
* Only `last_attempt_at` moves, which keeps concurrent ticks off the same row
|
|
266
|
-
* for retryAfterMs. Because posting does not change the status either, one
|
|
267
|
-
* retry path covers every loss: dying before the post, dying after it, or
|
|
268
|
-
* never receiving the gateway event for the message we posted.
|
|
269
|
-
*/
|
|
270
|
-
export async function claimSessionSleepAttempt({ sessionId, deliveryId, now, retryAfterMs, }) {
|
|
271
|
-
const db = await getDb();
|
|
272
|
-
const retryBefore = new Date(now.getTime() - retryAfterMs);
|
|
273
|
-
const rows = await db.update(schema.session_sleeps)
|
|
274
|
-
.set({ last_attempt_at: now, attempts: orm.sql `${schema.session_sleeps.attempts} + 1` })
|
|
275
|
-
.where(orm.and(orm.eq(schema.session_sleeps.session_id, sessionId), orm.eq(schema.session_sleeps.delivery_id, deliveryId), orm.eq(schema.session_sleeps.status, 'planned'), orm.lte(schema.session_sleeps.wake_at, now), orm.or(orm.isNull(schema.session_sleeps.last_attempt_at), orm.lte(schema.session_sleeps.last_attempt_at, retryBefore))))
|
|
276
|
-
.returning();
|
|
277
|
-
return rows[0] ?? null;
|
|
278
|
-
}
|
|
279
|
-
export async function markSessionSleepFailed({ sessionId, deliveryId, }) {
|
|
280
|
-
const db = await getDb();
|
|
281
|
-
const rows = await db.update(schema.session_sleeps)
|
|
282
|
-
.set({ status: 'failed' })
|
|
283
|
-
.where(orm.and(orm.eq(schema.session_sleeps.session_id, sessionId), orm.eq(schema.session_sleeps.delivery_id, deliveryId), orm.eq(schema.session_sleeps.status, 'planned')))
|
|
284
|
-
.returning({ session_id: schema.session_sleeps.session_id });
|
|
285
|
-
return countRows(rows) > 0;
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Ingress commit point. Marks the wake as delivered to the session.
|
|
289
|
-
*
|
|
290
|
-
* Returns false when the row is missing or no longer `planned`, which is how a
|
|
291
|
-
* wake that raced a user cancellation, or a duplicate of one already delivered,
|
|
292
|
-
* gets dropped instead of starting a turn.
|
|
293
|
-
*/
|
|
294
|
-
export async function consumeSessionSleepWake({ deliveryId }) {
|
|
295
|
-
const db = await getDb();
|
|
296
|
-
const rows = await db.update(schema.session_sleeps)
|
|
297
|
-
.set({ status: 'consumed' })
|
|
298
|
-
.where(orm.and(orm.eq(schema.session_sleeps.delivery_id, deliveryId), orm.eq(schema.session_sleeps.status, 'planned')))
|
|
299
|
-
.returning({ session_id: schema.session_sleeps.session_id });
|
|
300
|
-
return countRows(rows) > 0;
|
|
301
|
-
}
|
|
302
|
-
/**
|
|
303
|
-
* Cancel the pending sleep of the session currently bound to a thread.
|
|
304
|
-
*
|
|
305
|
-
* Runs on every ingress, so the binding is resolved with a correlated subquery
|
|
306
|
-
* rather than a second round trip. thread_id is the primary key of
|
|
307
|
-
* thread_sessions, so it yields at most one session.
|
|
308
|
-
*/
|
|
309
|
-
export async function cancelSessionSleepForThread({ threadId }) {
|
|
310
|
-
const db = await getDb();
|
|
311
|
-
const rows = await db.update(schema.session_sleeps)
|
|
312
|
-
.set({ status: 'cancelled' })
|
|
313
|
-
.where(orm.and(orm.eq(schema.session_sleeps.status, 'planned'), orm.eq(schema.session_sleeps.session_id, orm.sql `(SELECT ${schema.thread_sessions.session_id} FROM ${schema.thread_sessions} WHERE ${schema.thread_sessions.thread_id} = ${threadId})`)))
|
|
314
|
-
.returning({ session_id: schema.session_sleeps.session_id });
|
|
315
|
-
return countRows(rows) > 0;
|
|
316
|
-
}
|
|
317
|
-
export async function getSessionStartSourcesBySessionIds(sessionIds) {
|
|
318
|
-
if (sessionIds.length === 0)
|
|
319
|
-
return new Map();
|
|
320
|
-
const db = await getDb();
|
|
321
|
-
const chunkSize = 500;
|
|
322
|
-
const rows = [];
|
|
323
|
-
for (let index = 0; index < sessionIds.length; index += chunkSize) {
|
|
324
|
-
rows.push(...await db.query.session_start_sources.findMany({
|
|
325
|
-
where: { session_id: { in: sessionIds.slice(index, index + chunkSize) } },
|
|
326
|
-
}));
|
|
327
|
-
}
|
|
328
|
-
return new Map(rows.map((row) => [row.session_id, row]));
|
|
329
|
-
}
|
|
330
|
-
export async function getSessionStartSource({ sessionId }) {
|
|
331
|
-
const db = await getDb();
|
|
332
|
-
return await db.query.session_start_sources.findFirst({
|
|
333
|
-
where: { session_id: sessionId },
|
|
334
|
-
}) ?? null;
|
|
335
|
-
}
|
|
336
|
-
export async function getChannelModel(channelId) {
|
|
337
|
-
const db = await getDb();
|
|
338
|
-
const row = await db.query.channel_models.findFirst({ where: { channel_id: channelId } });
|
|
339
|
-
return row ? { modelId: row.model_id, variant: row.variant } : undefined;
|
|
340
|
-
}
|
|
341
|
-
export async function setChannelModel({ channelId, modelId, variant }) {
|
|
342
|
-
const db = await getDb();
|
|
343
|
-
await db.insert(schema.channel_models)
|
|
344
|
-
.values({ channel_id: channelId, model_id: modelId, variant: variant ?? null })
|
|
345
|
-
.onConflictDoUpdate({
|
|
346
|
-
target: schema.channel_models.channel_id,
|
|
347
|
-
set: { model_id: modelId, variant: variant ?? null, updated_at: new Date() },
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
export async function getGlobalModel(appId) {
|
|
351
|
-
const db = await getDb();
|
|
352
|
-
const row = await db.query.global_models.findFirst({ where: { app_id: appId } });
|
|
353
|
-
return row ? { modelId: row.model_id, variant: row.variant } : undefined;
|
|
354
|
-
}
|
|
355
|
-
export async function setGlobalModel({ appId, modelId, variant }) {
|
|
356
|
-
const db = await getDb();
|
|
357
|
-
await db.insert(schema.global_models)
|
|
358
|
-
.values({ app_id: appId, model_id: modelId, variant: variant ?? null })
|
|
359
|
-
.onConflictDoUpdate({
|
|
360
|
-
target: schema.global_models.app_id,
|
|
361
|
-
set: { model_id: modelId, variant: variant ?? null, updated_at: new Date() },
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
export async function getSessionModel(sessionId) {
|
|
365
|
-
const db = await getDb();
|
|
366
|
-
const row = await db.query.session_models.findFirst({ where: { session_id: sessionId } });
|
|
367
|
-
return row ? { modelId: row.model_id, variant: row.variant } : undefined;
|
|
368
|
-
}
|
|
369
|
-
export async function setSessionModel({ sessionId, modelId, variant }) {
|
|
370
|
-
const db = await getDb();
|
|
371
|
-
await db.insert(schema.session_models)
|
|
372
|
-
.values({ session_id: sessionId, model_id: modelId, variant: variant ?? null })
|
|
373
|
-
.onConflictDoUpdate({
|
|
374
|
-
target: schema.session_models.session_id,
|
|
375
|
-
set: { model_id: modelId, variant: variant ?? null },
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
export async function clearSessionModel(sessionId) {
|
|
379
|
-
const db = await getDb();
|
|
380
|
-
await db.delete(schema.session_models).where(orm.eq(schema.session_models.session_id, sessionId));
|
|
381
|
-
}
|
|
382
|
-
export async function getVariantCascade({ sessionId, channelId, appId }) {
|
|
383
|
-
if (sessionId) {
|
|
384
|
-
const session = await getSessionModel(sessionId);
|
|
385
|
-
if (session?.variant)
|
|
386
|
-
return session.variant;
|
|
387
|
-
}
|
|
388
|
-
if (channelId) {
|
|
389
|
-
const channel = await getChannelModel(channelId);
|
|
390
|
-
if (channel?.variant)
|
|
391
|
-
return channel.variant;
|
|
392
|
-
}
|
|
393
|
-
if (appId) {
|
|
394
|
-
const global = await getGlobalModel(appId);
|
|
395
|
-
if (global?.variant)
|
|
396
|
-
return global.variant;
|
|
397
|
-
}
|
|
398
|
-
return undefined;
|
|
399
|
-
}
|
|
400
|
-
export async function getChannelAgent(channelId) {
|
|
401
|
-
const db = await getDb();
|
|
402
|
-
return (await db.query.channel_agents.findFirst({ where: { channel_id: channelId } }))?.agent_name;
|
|
403
|
-
}
|
|
404
|
-
export async function setChannelAgent(channelId, agentName) {
|
|
405
|
-
const db = await getDb();
|
|
406
|
-
await db.insert(schema.channel_agents)
|
|
407
|
-
.values({ channel_id: channelId, agent_name: agentName })
|
|
408
|
-
.onConflictDoUpdate({ target: schema.channel_agents.channel_id, set: { agent_name: agentName, updated_at: new Date() } });
|
|
409
|
-
}
|
|
410
|
-
export async function getSessionAgent(sessionId) {
|
|
411
|
-
const db = await getDb();
|
|
412
|
-
return (await db.query.session_agents.findFirst({ where: { session_id: sessionId } }))?.agent_name;
|
|
413
|
-
}
|
|
414
|
-
export async function setSessionAgent(sessionId, agentName) {
|
|
415
|
-
const db = await getDb();
|
|
416
|
-
await db.insert(schema.session_agents)
|
|
417
|
-
.values({ session_id: sessionId, agent_name: agentName })
|
|
418
|
-
.onConflictDoUpdate({ target: schema.session_agents.session_id, set: { agent_name: agentName } });
|
|
419
|
-
}
|
|
420
|
-
export async function getThreadWorktree(threadId) {
|
|
421
|
-
const db = await getDb();
|
|
422
|
-
return await db.query.thread_worktrees.findFirst({ where: { thread_id: threadId } }) ?? undefined;
|
|
423
|
-
}
|
|
424
|
-
export async function createPendingWorktree({ threadId, worktreeName, projectDirectory }) {
|
|
425
|
-
const db = await getDb();
|
|
426
|
-
await db.batch([
|
|
427
|
-
db.insert(schema.thread_sessions)
|
|
428
|
-
.values({ thread_id: threadId, session_id: '' })
|
|
429
|
-
.onConflictDoNothing({ target: schema.thread_sessions.thread_id }),
|
|
430
|
-
db.insert(schema.thread_worktrees)
|
|
431
|
-
.values({ thread_id: threadId, worktree_name: worktreeName, project_directory: projectDirectory, status: 'pending' })
|
|
432
|
-
.onConflictDoUpdate({
|
|
433
|
-
target: schema.thread_worktrees.thread_id,
|
|
434
|
-
set: { worktree_name: worktreeName, project_directory: projectDirectory, status: 'pending', worktree_directory: null, error_message: null },
|
|
435
|
-
}),
|
|
436
|
-
]);
|
|
437
|
-
}
|
|
438
|
-
export async function setWorktreeReady({ threadId, worktreeDirectory }) {
|
|
439
|
-
const db = await getDb();
|
|
440
|
-
await db.update(schema.thread_worktrees).set({ worktree_directory: worktreeDirectory, status: 'ready' }).where(orm.eq(schema.thread_worktrees.thread_id, threadId));
|
|
441
|
-
}
|
|
442
|
-
export async function setWorktreeError({ threadId, errorMessage }) {
|
|
443
|
-
const db = await getDb();
|
|
444
|
-
await db.update(schema.thread_worktrees).set({ status: 'error', error_message: errorMessage }).where(orm.eq(schema.thread_worktrees.thread_id, threadId));
|
|
445
|
-
}
|
|
446
|
-
export async function deleteThreadWorktree(threadId) {
|
|
447
|
-
const db = await getDb();
|
|
448
|
-
await db.delete(schema.thread_worktrees).where(orm.eq(schema.thread_worktrees.thread_id, threadId));
|
|
449
|
-
}
|
|
450
|
-
export async function createPendingWorkspace({ threadId, workspaceType, workspaceName, projectDirectory, }) {
|
|
451
|
-
const db = await getDb();
|
|
452
|
-
await db.batch([
|
|
453
|
-
db.insert(schema.thread_sessions)
|
|
454
|
-
.values({ thread_id: threadId, session_id: '' })
|
|
455
|
-
.onConflictDoNothing({ target: schema.thread_sessions.thread_id }),
|
|
456
|
-
db.insert(schema.thread_workspaces)
|
|
457
|
-
.values({
|
|
458
|
-
thread_id: threadId,
|
|
459
|
-
workspace_type: workspaceType,
|
|
460
|
-
workspace_name: workspaceName,
|
|
461
|
-
project_directory: projectDirectory,
|
|
462
|
-
status: 'pending',
|
|
463
|
-
})
|
|
464
|
-
.onConflictDoUpdate({
|
|
465
|
-
target: schema.thread_workspaces.thread_id,
|
|
466
|
-
set: {
|
|
467
|
-
workspace_type: workspaceType,
|
|
468
|
-
workspace_name: workspaceName,
|
|
469
|
-
project_directory: projectDirectory,
|
|
470
|
-
status: 'pending',
|
|
471
|
-
workspace_id: null,
|
|
472
|
-
workspace_directory: null,
|
|
473
|
-
error_message: null,
|
|
474
|
-
},
|
|
475
|
-
}),
|
|
476
|
-
]);
|
|
477
|
-
}
|
|
478
|
-
export async function setWorkspaceReady({ threadId, workspaceId, workspaceDirectory, }) {
|
|
479
|
-
const db = await getDb();
|
|
480
|
-
await db.update(schema.thread_workspaces)
|
|
481
|
-
.set({
|
|
482
|
-
workspace_directory: workspaceDirectory,
|
|
483
|
-
workspace_id: workspaceId ?? null,
|
|
484
|
-
status: 'ready',
|
|
485
|
-
})
|
|
486
|
-
.where(orm.eq(schema.thread_workspaces.thread_id, threadId));
|
|
487
|
-
}
|
|
488
|
-
export async function setWorkspaceError({ threadId, errorMessage, }) {
|
|
489
|
-
const db = await getDb();
|
|
490
|
-
await db.update(schema.thread_workspaces)
|
|
491
|
-
.set({ status: 'error', error_message: errorMessage })
|
|
492
|
-
.where(orm.eq(schema.thread_workspaces.thread_id, threadId));
|
|
493
|
-
}
|
|
494
|
-
export async function getThreadWorkspace(threadId) {
|
|
495
|
-
const db = await getDb();
|
|
496
|
-
return await db.query.thread_workspaces.findFirst({ where: { thread_id: threadId } }) ?? undefined;
|
|
497
|
-
}
|
|
498
|
-
export async function deleteThreadWorkspace(threadId) {
|
|
499
|
-
const db = await getDb();
|
|
500
|
-
await db.delete(schema.thread_workspaces).where(orm.eq(schema.thread_workspaces.thread_id, threadId));
|
|
501
|
-
}
|
|
502
|
-
/** Alias for getThreadWorkspace — used throughout the codebase. */
|
|
503
|
-
export const getThreadWorktreeOrWorkspace = getThreadWorkspace;
|
|
504
|
-
export async function getChannelVerbosity(channelId) {
|
|
505
|
-
const db = await getDb();
|
|
506
|
-
const row = await db.query.channel_verbosity.findFirst({ where: { channel_id: channelId } });
|
|
507
|
-
return row?.verbosity ?? store.getState().defaultVerbosity;
|
|
508
|
-
}
|
|
509
|
-
export async function setChannelVerbosity(channelId, verbosity) {
|
|
510
|
-
const db = await getDb();
|
|
511
|
-
await db.insert(schema.channel_verbosity)
|
|
512
|
-
.values({ channel_id: channelId, verbosity })
|
|
513
|
-
.onConflictDoUpdate({ target: schema.channel_verbosity.channel_id, set: { verbosity, updated_at: new Date() } });
|
|
514
|
-
}
|
|
515
|
-
export async function getChannelMentionMode(channelId) {
|
|
516
|
-
const db = await getDb();
|
|
517
|
-
const row = await db.query.channel_mention_mode.findFirst({ where: { channel_id: channelId } });
|
|
518
|
-
return row ? row.enabled === 1 : store.getState().defaultMentionMode;
|
|
519
|
-
}
|
|
520
|
-
export async function setChannelMentionMode(channelId, enabled) {
|
|
521
|
-
const db = await getDb();
|
|
522
|
-
await db.insert(schema.channel_mention_mode)
|
|
523
|
-
.values({ channel_id: channelId, enabled: enabled ? 1 : 0 })
|
|
524
|
-
.onConflictDoUpdate({ target: schema.channel_mention_mode.channel_id, set: { enabled: enabled ? 1 : 0, updated_at: new Date() } });
|
|
525
|
-
}
|
|
526
|
-
export async function getChannelWorktreesEnabled(channelId) {
|
|
527
|
-
const db = await getDb();
|
|
528
|
-
return (await db.query.channel_worktrees.findFirst({ where: { channel_id: channelId } }))?.enabled === 1;
|
|
529
|
-
}
|
|
530
|
-
export async function setChannelWorktreesEnabled(channelId, enabled) {
|
|
531
|
-
const db = await getDb();
|
|
532
|
-
await db.insert(schema.channel_worktrees)
|
|
533
|
-
.values({ channel_id: channelId, enabled: enabled ? 1 : 0 })
|
|
534
|
-
.onConflictDoUpdate({ target: schema.channel_worktrees.channel_id, set: { enabled: enabled ? 1 : 0, updated_at: new Date() } });
|
|
535
|
-
}
|
|
536
|
-
export async function getChannelDirectory(channelId) {
|
|
537
|
-
const db = await getDb();
|
|
538
|
-
const row = await db.query.channel_directories.findFirst({ where: { channel_id: channelId } });
|
|
539
|
-
return row ? { directory: row.directory } : undefined;
|
|
540
|
-
}
|
|
541
|
-
export async function getThreadSession(threadId) {
|
|
542
|
-
const db = await getDb();
|
|
543
|
-
return (await db.query.thread_sessions.findFirst({ where: { thread_id: threadId } }))?.session_id;
|
|
544
|
-
}
|
|
545
|
-
export async function insertThreadQueueItem({ queueId, threadId, payloadJson, }) {
|
|
546
|
-
const db = await getDb();
|
|
547
|
-
await db.insert(schema.thread_queue_items).values({
|
|
548
|
-
queue_id: queueId,
|
|
549
|
-
thread_id: threadId,
|
|
550
|
-
payload_json: payloadJson,
|
|
551
|
-
});
|
|
552
|
-
}
|
|
553
|
-
export async function listThreadQueueItems(threadId) {
|
|
554
|
-
const db = await getDb();
|
|
555
|
-
return db.query.thread_queue_items.findMany({
|
|
556
|
-
where: { thread_id: threadId },
|
|
557
|
-
orderBy: { id: 'asc' },
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
export async function listAllThreadQueueItems() {
|
|
561
|
-
const db = await getDb();
|
|
562
|
-
return db.query.thread_queue_items.findMany({
|
|
563
|
-
orderBy: { id: 'asc' },
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
export async function deleteThreadQueueItem(queueId) {
|
|
567
|
-
const db = await getDb();
|
|
568
|
-
const rows = await db.delete(schema.thread_queue_items).where(orm.eq(schema.thread_queue_items.queue_id, queueId)).returning();
|
|
569
|
-
return rows[0];
|
|
570
|
-
}
|
|
571
|
-
export async function deleteThreadQueueItems(threadId) {
|
|
572
|
-
const db = await getDb();
|
|
573
|
-
await db.delete(schema.thread_queue_items).where(orm.eq(schema.thread_queue_items.thread_id, threadId));
|
|
574
|
-
}
|
|
575
|
-
export async function updateThreadQueueItemPayload({ queueId, payloadJson, }) {
|
|
576
|
-
const db = await getDb();
|
|
577
|
-
await db.update(schema.thread_queue_items)
|
|
578
|
-
.set({ payload_json: payloadJson })
|
|
579
|
-
.where(orm.eq(schema.thread_queue_items.queue_id, queueId));
|
|
580
|
-
}
|
|
581
|
-
export async function setThreadSession(threadId, sessionId) {
|
|
582
|
-
await upsertThreadSession({ threadId, sessionId, source: 'kimaki' });
|
|
583
|
-
}
|
|
584
|
-
export async function upsertThreadSession({ threadId, sessionId, source }) {
|
|
585
|
-
const db = await getDb();
|
|
586
|
-
// updated_at is written explicitly on BOTH paths, never left to the column's
|
|
587
|
-
// CURRENT_TIMESTAMP default. The default stores "YYYY-MM-DD HH:MM:SS" while
|
|
588
|
-
// Date values store ISO with a "T", and those two text formats do not sort
|
|
589
|
-
// against each other correctly. Writing ISO everywhere keeps the ordering in
|
|
590
|
-
// getThreadIdBySessionId honest and gives it millisecond resolution.
|
|
591
|
-
const boundAt = new Date();
|
|
592
|
-
await db.insert(schema.thread_sessions)
|
|
593
|
-
.values({ thread_id: threadId, session_id: sessionId, source, updated_at: boundAt })
|
|
594
|
-
.onConflictDoUpdate({
|
|
595
|
-
target: schema.thread_sessions.thread_id,
|
|
596
|
-
set: { session_id: sessionId, source, updated_at: boundAt },
|
|
597
|
-
});
|
|
598
|
-
}
|
|
599
|
-
export async function getThreadParentSessionId(threadId) {
|
|
600
|
-
const db = await getDb();
|
|
601
|
-
return (await db.query.thread_sessions.findFirst({
|
|
602
|
-
where: { thread_id: threadId },
|
|
603
|
-
columns: { parent_session_id: true },
|
|
604
|
-
}))?.parent_session_id ?? undefined;
|
|
605
|
-
}
|
|
606
|
-
export async function setThreadParentSessionId({ threadId, parentSessionId, }) {
|
|
607
|
-
const db = await getDb();
|
|
608
|
-
await db
|
|
609
|
-
.update(schema.thread_sessions)
|
|
610
|
-
.set({ parent_session_id: parentSessionId })
|
|
611
|
-
.where(orm.eq(schema.thread_sessions.thread_id, threadId));
|
|
612
|
-
}
|
|
613
|
-
export async function getThreadSessionSource(threadId) {
|
|
614
|
-
const db = await getDb();
|
|
615
|
-
return (await db.query.thread_sessions.findFirst({ where: { thread_id: threadId }, columns: { source: true } }))?.source;
|
|
616
|
-
}
|
|
617
|
-
/**
|
|
618
|
-
* Reverse lookup of the Discord thread that currently owns an OpenCode session.
|
|
619
|
-
*
|
|
620
|
-
* `thread_sessions.session_id` is NOT unique: /resume binds an existing session
|
|
621
|
-
* to a brand new thread without clearing the old row. An unordered findFirst
|
|
622
|
-
* therefore returns an arbitrary (often dead) thread, which made plugin tools
|
|
623
|
-
* post into the wrong conversation. Order by the most recent binding instead,
|
|
624
|
-
* falling back to created_at for rows written before updated_at existed.
|
|
625
|
-
*/
|
|
626
|
-
export async function getThreadIdBySessionId(sessionId) {
|
|
627
|
-
const db = await getDb();
|
|
628
|
-
const rows = await db.select({ thread_id: schema.thread_sessions.thread_id })
|
|
629
|
-
.from(schema.thread_sessions)
|
|
630
|
-
.where(orm.eq(schema.thread_sessions.session_id, sessionId))
|
|
631
|
-
.orderBy(orm.desc(orm.sql `COALESCE(${schema.thread_sessions.updated_at}, ${schema.thread_sessions.created_at})`))
|
|
632
|
-
.limit(1);
|
|
633
|
-
return rows[0]?.thread_id;
|
|
634
|
-
}
|
|
635
|
-
export async function getAllThreadSessionIds() {
|
|
636
|
-
const db = await getDb();
|
|
637
|
-
const rows = await db.query.thread_sessions.findMany({ columns: { session_id: true } });
|
|
638
|
-
return rows.map((row) => row.session_id).filter((id) => id !== '');
|
|
639
|
-
}
|
|
640
|
-
export async function appendSessionEventsSinceLastTimestamp({ sessionId, events }) {
|
|
641
|
-
if (events.length === 0)
|
|
642
|
-
return 0;
|
|
643
|
-
const db = await getDb();
|
|
644
|
-
const sortedEvents = [...events].sort((a, b) => {
|
|
645
|
-
if (a.timestamp !== b.timestamp)
|
|
646
|
-
return a.timestamp - b.timestamp;
|
|
647
|
-
return a.event_index - b.event_index;
|
|
648
|
-
});
|
|
649
|
-
const latestPersisted = await db.query.session_events.findFirst({
|
|
650
|
-
where: { session_id: sessionId },
|
|
651
|
-
orderBy: { timestamp: 'desc', event_index: 'desc', id: 'desc' },
|
|
652
|
-
columns: { timestamp: true, event_index: true },
|
|
653
|
-
});
|
|
654
|
-
const eventsToInsert = sortedEvents.filter((event) => {
|
|
655
|
-
if (!latestPersisted)
|
|
656
|
-
return true;
|
|
657
|
-
if (event.timestamp > latestPersisted.timestamp)
|
|
658
|
-
return true;
|
|
659
|
-
if (event.timestamp < latestPersisted.timestamp)
|
|
660
|
-
return false;
|
|
661
|
-
return event.event_index > latestPersisted.event_index;
|
|
662
|
-
});
|
|
663
|
-
if (eventsToInsert.length === 0)
|
|
664
|
-
return 0;
|
|
665
|
-
await db.insert(schema.session_events).values(eventsToInsert);
|
|
666
|
-
const staleRows = await db.query.session_events.findMany({
|
|
667
|
-
where: { session_id: sessionId },
|
|
668
|
-
orderBy: { timestamp: 'desc', event_index: 'desc', id: 'desc' },
|
|
669
|
-
limit: 1_000_000,
|
|
670
|
-
offset: 1000,
|
|
671
|
-
columns: { id: true },
|
|
672
|
-
});
|
|
673
|
-
if (staleRows.length > 0) {
|
|
674
|
-
await db.delete(schema.session_events).where(orm.inArray(schema.session_events.id, staleRows.map((row) => row.id)));
|
|
675
|
-
}
|
|
676
|
-
return eventsToInsert.length;
|
|
677
|
-
}
|
|
678
|
-
export async function getSessionEventSnapshot({ sessionId }) {
|
|
679
|
-
const db = await getDb();
|
|
680
|
-
return db.query.session_events.findMany({
|
|
681
|
-
where: { session_id: sessionId },
|
|
682
|
-
orderBy: { timestamp: 'asc', event_index: 'asc', id: 'asc' },
|
|
683
|
-
limit: 1000,
|
|
684
|
-
});
|
|
685
|
-
}
|
|
686
|
-
export async function getPartMessageIds(threadId) {
|
|
687
|
-
const db = await getDb();
|
|
688
|
-
const rows = await db.query.part_messages.findMany({ where: { thread_id: threadId }, columns: { part_id: true } });
|
|
689
|
-
return rows.map((row) => row.part_id);
|
|
690
|
-
}
|
|
691
|
-
export async function setPartMessage({ partId, messageId, threadId }) {
|
|
692
|
-
const db = await getDb();
|
|
693
|
-
await db.insert(schema.part_messages)
|
|
694
|
-
.values({ part_id: partId, message_id: messageId, thread_id: threadId })
|
|
695
|
-
.onConflictDoUpdate({ target: schema.part_messages.part_id, set: { message_id: messageId, thread_id: threadId } });
|
|
696
|
-
}
|
|
697
|
-
export async function setPartMessagesBatch(partMappings) {
|
|
698
|
-
if (partMappings.length === 0)
|
|
699
|
-
return;
|
|
700
|
-
const db = await getDb();
|
|
701
|
-
for (const { partId, messageId, threadId } of partMappings) {
|
|
702
|
-
await db.insert(schema.part_messages)
|
|
703
|
-
.values({ part_id: partId, message_id: messageId, thread_id: threadId })
|
|
704
|
-
.onConflictDoUpdate({ target: schema.part_messages.part_id, set: { message_id: messageId, thread_id: threadId } });
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
function splitServiceAuthToken({ token }) {
|
|
708
|
-
const separatorIndex = token.indexOf(':');
|
|
709
|
-
if (separatorIndex <= 0 || separatorIndex >= token.length - 1)
|
|
710
|
-
return null;
|
|
711
|
-
return { clientId: token.slice(0, separatorIndex), clientSecret: token.slice(separatorIndex + 1) };
|
|
712
|
-
}
|
|
713
|
-
function createServiceCredentials() {
|
|
714
|
-
return { clientId: crypto.randomUUID(), clientSecret: crypto.randomBytes(32).toString('hex') };
|
|
715
|
-
}
|
|
716
|
-
export async function getBotTokenWithMode() {
|
|
717
|
-
const db = await getDb();
|
|
718
|
-
const [row] = await db.query.bot_tokens.findMany({ orderBy: { last_used_at: 'desc', created_at: 'desc' }, limit: 1 });
|
|
719
|
-
if (!row)
|
|
720
|
-
return undefined;
|
|
721
|
-
const gatewayToken = await ensureServiceAuthToken({ appId: row.app_id });
|
|
722
|
-
const serviceParts = splitServiceAuthToken({ token: gatewayToken });
|
|
723
|
-
const mode = row.bot_mode === 'gateway' ? 'gateway' : 'self_hosted';
|
|
724
|
-
const token = mode === 'gateway' && serviceParts ? gatewayToken : row.token;
|
|
725
|
-
const discordBaseUrl = mode === 'gateway' && row.proxy_url ? row.proxy_url : 'https://discord.com';
|
|
726
|
-
store.setState({ discordBaseUrl, gatewayToken });
|
|
727
|
-
return {
|
|
728
|
-
appId: row.app_id,
|
|
729
|
-
token,
|
|
730
|
-
gatewayToken,
|
|
731
|
-
mode,
|
|
732
|
-
clientId: serviceParts?.clientId || row.client_id,
|
|
733
|
-
clientSecret: serviceParts?.clientSecret || row.client_secret,
|
|
734
|
-
proxyUrl: row.proxy_url,
|
|
735
|
-
};
|
|
736
|
-
}
|
|
737
|
-
export async function ensureServiceAuthToken({ appId, preferredGatewayToken }) {
|
|
738
|
-
const db = await getDb();
|
|
739
|
-
const row = await db.query.bot_tokens.findFirst({ where: { app_id: appId } });
|
|
740
|
-
if (!row)
|
|
741
|
-
throw new Error(`Bot token row not found for app_id ${appId}`);
|
|
742
|
-
const preferred = preferredGatewayToken ? splitServiceAuthToken({ token: preferredGatewayToken }) : null;
|
|
743
|
-
const existing = row.client_id && row.client_secret ? { clientId: row.client_id, clientSecret: row.client_secret } : null;
|
|
744
|
-
const fromStoredToken = splitServiceAuthToken({ token: row.token });
|
|
745
|
-
const resolved = preferred || existing || fromStoredToken || createServiceCredentials();
|
|
746
|
-
if (row.client_id !== resolved.clientId || row.client_secret !== resolved.clientSecret) {
|
|
747
|
-
await db.update(schema.bot_tokens)
|
|
748
|
-
.set({ client_id: resolved.clientId, client_secret: resolved.clientSecret })
|
|
749
|
-
.where(orm.eq(schema.bot_tokens.app_id, appId));
|
|
750
|
-
}
|
|
751
|
-
return `${resolved.clientId}:${resolved.clientSecret}`;
|
|
752
|
-
}
|
|
753
|
-
export async function setBotToken(appId, token) {
|
|
754
|
-
const db = await getDb();
|
|
755
|
-
const generated = createServiceCredentials();
|
|
756
|
-
await db.insert(schema.bot_tokens)
|
|
757
|
-
.values({ app_id: appId, token, client_id: generated.clientId, client_secret: generated.clientSecret })
|
|
758
|
-
.onConflictDoUpdate({ target: schema.bot_tokens.app_id, set: { token } });
|
|
759
|
-
await ensureServiceAuthToken({ appId });
|
|
760
|
-
}
|
|
761
|
-
export async function setBotMode({ appId, mode, clientId, clientSecret, proxyUrl }) {
|
|
762
|
-
const db = await getDb();
|
|
763
|
-
const token = clientId && clientSecret ? `${clientId}:${clientSecret}` : '';
|
|
764
|
-
const data = { bot_mode: mode, client_id: clientId ?? null, client_secret: clientSecret ?? null, proxy_url: proxyUrl ?? null };
|
|
765
|
-
await db.insert(schema.bot_tokens)
|
|
766
|
-
.values({ app_id: appId, token, ...data })
|
|
767
|
-
.onConflictDoUpdate({ target: schema.bot_tokens.app_id, set: data });
|
|
768
|
-
await ensureServiceAuthToken({ appId, preferredGatewayToken: token || undefined });
|
|
769
|
-
}
|
|
770
|
-
export async function getGeminiApiKey(appId) {
|
|
771
|
-
const db = await getDb();
|
|
772
|
-
return (await db.query.bot_api_keys.findFirst({ where: { app_id: appId } }))?.gemini_api_key ?? null;
|
|
773
|
-
}
|
|
774
|
-
export async function setGeminiApiKey(appId, apiKey) {
|
|
775
|
-
const db = await getDb();
|
|
776
|
-
await db.insert(schema.bot_api_keys)
|
|
777
|
-
.values({ app_id: appId, gemini_api_key: apiKey })
|
|
778
|
-
.onConflictDoUpdate({ target: schema.bot_api_keys.app_id, set: { gemini_api_key: apiKey } });
|
|
779
|
-
}
|
|
780
|
-
export async function getOpenAIApiKey(appId) {
|
|
781
|
-
const db = await getDb();
|
|
782
|
-
return (await db.query.bot_api_keys.findFirst({ where: { app_id: appId } }))?.openai_api_key ?? null;
|
|
783
|
-
}
|
|
784
|
-
export async function setOpenAIApiKey(appId, apiKey) {
|
|
785
|
-
const db = await getDb();
|
|
786
|
-
await db.insert(schema.bot_api_keys)
|
|
787
|
-
.values({ app_id: appId, openai_api_key: apiKey })
|
|
788
|
-
.onConflictDoUpdate({ target: schema.bot_api_keys.app_id, set: { openai_api_key: apiKey } });
|
|
789
|
-
}
|
|
790
|
-
export async function getTranscriptionApiKey(appId) {
|
|
791
|
-
const db = await getDb();
|
|
792
|
-
const row = await db.query.bot_api_keys.findFirst({ where: { app_id: appId } });
|
|
793
|
-
if (!row)
|
|
794
|
-
return null;
|
|
795
|
-
if (row.openai_api_key)
|
|
796
|
-
return { provider: 'openai', apiKey: row.openai_api_key };
|
|
797
|
-
if (row.gemini_api_key)
|
|
798
|
-
return { provider: 'gemini', apiKey: row.gemini_api_key };
|
|
799
|
-
return null;
|
|
800
|
-
}
|
|
801
|
-
/**
|
|
802
|
-
* Get any stored audio API key (OpenAI or Gemini) without requiring a specific appId.
|
|
803
|
-
* Used by the plugin process which doesn't have direct access to the bot's appId.
|
|
804
|
-
* Returns the first available key found, preferring OpenAI.
|
|
805
|
-
*/
|
|
806
|
-
export async function getAnyAudioApiKey() {
|
|
807
|
-
const db = await getDb();
|
|
808
|
-
const row = await db.query.bot_api_keys.findFirst();
|
|
809
|
-
if (!row)
|
|
810
|
-
return null;
|
|
811
|
-
if (row.openai_api_key)
|
|
812
|
-
return { provider: 'openai', apiKey: row.openai_api_key, appId: row.app_id };
|
|
813
|
-
if (row.gemini_api_key)
|
|
814
|
-
return { provider: 'gemini', apiKey: row.gemini_api_key, appId: row.app_id };
|
|
815
|
-
return null;
|
|
816
|
-
}
|
|
817
|
-
export async function setChannelDirectory({ channelId, directory, channelType, guildId, skipIfExists = false }) {
|
|
818
|
-
const db = await getDb();
|
|
819
|
-
if (skipIfExists) {
|
|
820
|
-
await db.insert(schema.channel_directories)
|
|
821
|
-
.values({ channel_id: channelId, directory, channel_type: channelType, guild_id: guildId })
|
|
822
|
-
.onConflictDoNothing({ target: schema.channel_directories.channel_id });
|
|
823
|
-
return;
|
|
824
|
-
}
|
|
825
|
-
await db.insert(schema.channel_directories)
|
|
826
|
-
.values({ channel_id: channelId, directory, channel_type: channelType, guild_id: guildId })
|
|
827
|
-
.onConflictDoUpdate({ target: schema.channel_directories.channel_id, set: { directory, channel_type: channelType, guild_id: guildId } });
|
|
828
|
-
}
|
|
829
|
-
export async function findChannelsByDirectory({ directory, channelType }) {
|
|
830
|
-
const db = await getDb();
|
|
831
|
-
const where = directory && channelType
|
|
832
|
-
? { directory, channel_type: channelType }
|
|
833
|
-
: directory
|
|
834
|
-
? { directory }
|
|
835
|
-
: channelType
|
|
836
|
-
? { channel_type: channelType }
|
|
837
|
-
: undefined;
|
|
838
|
-
return db.query.channel_directories.findMany({ where, columns: { channel_id: true, directory: true, channel_type: true, guild_id: true } });
|
|
839
|
-
}
|
|
840
|
-
function canonicalizeDirectory(directory) {
|
|
841
|
-
const resolved = path.resolve(directory);
|
|
842
|
-
const real = errore.try(() => fs.realpathSync(resolved), (e) => new Error('realpath failed', { cause: e }));
|
|
843
|
-
if (real instanceof Error)
|
|
844
|
-
return resolved;
|
|
845
|
-
return real;
|
|
846
|
-
}
|
|
847
|
-
export async function findRegisteredTextChannelForDirectory(directory) {
|
|
848
|
-
const wanted = canonicalizeDirectory(directory);
|
|
849
|
-
const channels = await findChannelsByDirectory({ channelType: 'text' });
|
|
850
|
-
return channels.find((ch) => canonicalizeDirectory(ch.directory) === wanted) ?? null;
|
|
851
|
-
}
|
|
852
|
-
export function formatProjectAlreadyRegisteredError({ channelId, directory, }) {
|
|
853
|
-
return [
|
|
854
|
-
`Channel already exists for this directory: ${directory}`,
|
|
855
|
-
`Channel ID: ${channelId}`,
|
|
856
|
-
`Remove the mapping first: kimaki project remove ${channelId}`,
|
|
857
|
-
].join('\n');
|
|
858
|
-
}
|
|
859
|
-
export async function getAllTextChannelDirectories() {
|
|
860
|
-
const db = await getDb();
|
|
861
|
-
const rows = await db.query.channel_directories.findMany({ where: { channel_type: 'text' }, columns: { directory: true } });
|
|
862
|
-
return [...new Set(rows.map((row) => row.directory))];
|
|
863
|
-
}
|
|
864
|
-
export async function listTrackedTextChannels() {
|
|
865
|
-
const db = await getDb();
|
|
866
|
-
return db.query.channel_directories.findMany({
|
|
867
|
-
where: { channel_type: 'text' },
|
|
868
|
-
orderBy: { created_at: 'asc', channel_id: 'asc' },
|
|
869
|
-
columns: { channel_id: true, directory: true, created_at: true },
|
|
870
|
-
});
|
|
871
|
-
}
|
|
872
|
-
export async function getGuildCategories(guildId) {
|
|
873
|
-
const db = await getDb();
|
|
874
|
-
const row = await db.query.guild_categories.findFirst({ where: { guild_id: guildId } });
|
|
875
|
-
if (!row)
|
|
876
|
-
return null;
|
|
877
|
-
return {
|
|
878
|
-
guild_id: row.guild_id,
|
|
879
|
-
category_id: row.category_id,
|
|
880
|
-
audio_category_id: row.audio_category_id,
|
|
881
|
-
};
|
|
882
|
-
}
|
|
883
|
-
export async function listGuildCategoryIds() {
|
|
884
|
-
const db = await getDb();
|
|
885
|
-
const rows = await db.query.guild_categories.findMany({
|
|
886
|
-
columns: { category_id: true, audio_category_id: true },
|
|
887
|
-
});
|
|
888
|
-
const ids = new Set();
|
|
889
|
-
for (const row of rows) {
|
|
890
|
-
if (row.category_id)
|
|
891
|
-
ids.add(row.category_id);
|
|
892
|
-
if (row.audio_category_id)
|
|
893
|
-
ids.add(row.audio_category_id);
|
|
894
|
-
}
|
|
895
|
-
return [...ids];
|
|
896
|
-
}
|
|
897
|
-
export async function setGuildCategoryId({ guildId, kind, categoryId, }) {
|
|
898
|
-
const db = await getDb();
|
|
899
|
-
const values = kind === 'audio'
|
|
900
|
-
? { guild_id: guildId, audio_category_id: categoryId }
|
|
901
|
-
: { guild_id: guildId, category_id: categoryId };
|
|
902
|
-
const set = kind === 'audio'
|
|
903
|
-
? { audio_category_id: categoryId }
|
|
904
|
-
: { category_id: categoryId };
|
|
905
|
-
await db.insert(schema.guild_categories)
|
|
906
|
-
.values(values)
|
|
907
|
-
.onConflictDoUpdate({
|
|
908
|
-
target: schema.guild_categories.guild_id,
|
|
909
|
-
set,
|
|
910
|
-
});
|
|
911
|
-
}
|
|
912
|
-
export async function deleteChannelDirectoriesByDirectory(directory) {
|
|
913
|
-
const db = await getDb();
|
|
914
|
-
await db.delete(schema.channel_directories).where(orm.eq(schema.channel_directories.directory, directory));
|
|
915
|
-
}
|
|
916
|
-
export async function deleteChannelDirectoryById(channelId, { preserveMapping = false } = {}) {
|
|
917
|
-
const db = await getDb();
|
|
918
|
-
await db.batch([
|
|
919
|
-
db.update(schema.scheduled_tasks)
|
|
920
|
-
.set({
|
|
921
|
-
status: 'cancelled',
|
|
922
|
-
running_started_at: null,
|
|
923
|
-
last_error: 'Discord channel was deleted',
|
|
924
|
-
})
|
|
925
|
-
.where(orm.and(orm.eq(schema.scheduled_tasks.channel_id, channelId), orm.inArray(schema.scheduled_tasks.status, ['planned', 'running']))),
|
|
926
|
-
db.delete(schema.channel_models).where(orm.eq(schema.channel_models.channel_id, channelId)),
|
|
927
|
-
db.delete(schema.channel_agents).where(orm.eq(schema.channel_agents.channel_id, channelId)),
|
|
928
|
-
db.delete(schema.channel_worktrees).where(orm.eq(schema.channel_worktrees.channel_id, channelId)),
|
|
929
|
-
db.delete(schema.channel_verbosity).where(orm.eq(schema.channel_verbosity.channel_id, channelId)),
|
|
930
|
-
db.delete(schema.channel_mention_mode).where(orm.eq(schema.channel_mention_mode.channel_id, channelId)),
|
|
931
|
-
]);
|
|
932
|
-
if (preserveMapping) {
|
|
933
|
-
return Boolean(await db.query.channel_directories.findFirst({
|
|
934
|
-
where: { channel_id: channelId },
|
|
935
|
-
columns: { channel_id: true },
|
|
936
|
-
}));
|
|
937
|
-
}
|
|
938
|
-
const rows = await db.delete(schema.channel_directories)
|
|
939
|
-
.where(orm.eq(schema.channel_directories.channel_id, channelId))
|
|
940
|
-
.returning({ channel_id: schema.channel_directories.channel_id });
|
|
941
|
-
return rows.length > 0;
|
|
942
|
-
}
|
|
943
|
-
export async function cleanupDeletedThread(threadId) {
|
|
944
|
-
const db = await getDb();
|
|
945
|
-
const binding = await db.query.thread_sessions.findFirst({
|
|
946
|
-
where: { thread_id: threadId },
|
|
947
|
-
columns: { session_id: true },
|
|
948
|
-
});
|
|
949
|
-
const currentThreadId = binding
|
|
950
|
-
? await getThreadIdBySessionId(binding.session_id)
|
|
951
|
-
: undefined;
|
|
952
|
-
const currentSessionId = currentThreadId === threadId
|
|
953
|
-
? binding?.session_id
|
|
954
|
-
: undefined;
|
|
955
|
-
await db.batch([
|
|
956
|
-
db.delete(schema.thread_queue_items)
|
|
957
|
-
.where(orm.eq(schema.thread_queue_items.thread_id, threadId)),
|
|
958
|
-
db.update(schema.session_sleeps)
|
|
959
|
-
.set({ status: 'cancelled' })
|
|
960
|
-
.where(orm.and(orm.eq(schema.session_sleeps.status, 'planned'), orm.eq(schema.session_sleeps.session_id, currentSessionId ?? ''))),
|
|
961
|
-
db.update(schema.scheduled_tasks)
|
|
962
|
-
.set({
|
|
963
|
-
status: 'cancelled',
|
|
964
|
-
running_started_at: null,
|
|
965
|
-
last_error: 'Discord thread was deleted',
|
|
966
|
-
})
|
|
967
|
-
.where(orm.and(orm.eq(schema.scheduled_tasks.thread_id, threadId), orm.inArray(schema.scheduled_tasks.status, ['planned', 'running']))),
|
|
968
|
-
db.update(schema.ipc_requests)
|
|
969
|
-
.set({
|
|
970
|
-
status: 'cancelled',
|
|
971
|
-
response: JSON.stringify({ error: 'Discord thread was deleted' }),
|
|
972
|
-
})
|
|
973
|
-
.where(orm.and(orm.eq(schema.ipc_requests.thread_id, threadId), orm.inArray(schema.ipc_requests.status, ['pending', 'processing']))),
|
|
974
|
-
]);
|
|
975
|
-
}
|
|
976
|
-
export async function isCurrentThreadSessionBinding(threadId) {
|
|
977
|
-
const db = await getDb();
|
|
978
|
-
const binding = await db.query.thread_sessions.findFirst({
|
|
979
|
-
where: { thread_id: threadId },
|
|
980
|
-
columns: { session_id: true },
|
|
981
|
-
});
|
|
982
|
-
if (!binding)
|
|
983
|
-
return false;
|
|
984
|
-
return await getThreadIdBySessionId(binding.session_id) === threadId;
|
|
985
|
-
}
|
|
986
|
-
export async function clearGuildCategoryByChannelId(channelId) {
|
|
987
|
-
const db = await getDb();
|
|
988
|
-
await db.batch([
|
|
989
|
-
db.update(schema.guild_categories)
|
|
990
|
-
.set({ category_id: null })
|
|
991
|
-
.where(orm.eq(schema.guild_categories.category_id, channelId)),
|
|
992
|
-
db.update(schema.guild_categories)
|
|
993
|
-
.set({ audio_category_id: null })
|
|
994
|
-
.where(orm.eq(schema.guild_categories.audio_category_id, channelId)),
|
|
995
|
-
]);
|
|
996
|
-
}
|
|
997
|
-
export async function getVoiceChannelDirectory(channelId) {
|
|
998
|
-
const db = await getDb();
|
|
999
|
-
return (await db.query.channel_directories.findFirst({ where: { channel_id: channelId, channel_type: 'voice' } }))?.directory;
|
|
1000
|
-
}
|
|
1001
|
-
export async function findTextChannelByVoiceChannel(voiceChannelId) {
|
|
1002
|
-
const db = await getDb();
|
|
1003
|
-
const voiceChannel = await db.query.channel_directories.findFirst({ where: { channel_id: voiceChannelId, channel_type: 'voice' } });
|
|
1004
|
-
if (!voiceChannel)
|
|
1005
|
-
return undefined;
|
|
1006
|
-
return (await db.query.channel_directories.findFirst({ where: { directory: voiceChannel.directory, channel_type: 'text' } }))?.channel_id;
|
|
1007
|
-
}
|
|
1008
|
-
export async function getForumSyncConfigs({ appId }) {
|
|
1009
|
-
const db = await getDb();
|
|
1010
|
-
const rows = await db.query.forum_sync_configs.findMany({ where: { app_id: appId } });
|
|
1011
|
-
return rows.map((row) => ({ appId: row.app_id, forumChannelId: row.forum_channel_id, outputDir: row.output_dir, direction: row.direction }));
|
|
1012
|
-
}
|
|
1013
|
-
export async function upsertForumSyncConfig({ appId, forumChannelId, outputDir, direction = 'bidirectional' }) {
|
|
1014
|
-
const db = await getDb();
|
|
1015
|
-
await db.insert(schema.forum_sync_configs)
|
|
1016
|
-
.values({ app_id: appId, forum_channel_id: forumChannelId, output_dir: outputDir, direction })
|
|
1017
|
-
.onConflictDoUpdate({ target: [schema.forum_sync_configs.app_id, schema.forum_sync_configs.forum_channel_id], set: { output_dir: outputDir, direction, updated_at: new Date() } });
|
|
1018
|
-
}
|
|
1019
|
-
export async function deleteForumSyncConfig({ appId, forumChannelId }) {
|
|
1020
|
-
const db = await getDb();
|
|
1021
|
-
await db.delete(schema.forum_sync_configs).where(orm.and(orm.eq(schema.forum_sync_configs.app_id, appId), orm.eq(schema.forum_sync_configs.forum_channel_id, forumChannelId)));
|
|
1022
|
-
}
|
|
1023
|
-
export async function deleteStaleForumSyncConfigs({ appId, forumChannelId, outputDir }) {
|
|
1024
|
-
const db = await getDb();
|
|
1025
|
-
await db.delete(schema.forum_sync_configs).where(orm.and(orm.eq(schema.forum_sync_configs.app_id, appId), orm.eq(schema.forum_sync_configs.output_dir, outputDir), orm.ne(schema.forum_sync_configs.forum_channel_id, forumChannelId)));
|
|
1026
|
-
}
|
|
1027
|
-
export async function createIpcRequest({ type, sessionId, threadId, payload }) {
|
|
1028
|
-
const db = await getDb();
|
|
1029
|
-
const [row] = await db.insert(schema.ipc_requests).values({ type, session_id: sessionId, thread_id: threadId, payload }).returning();
|
|
1030
|
-
if (!row)
|
|
1031
|
-
throw new Error('Failed to create IPC request');
|
|
1032
|
-
return row;
|
|
1033
|
-
}
|
|
1034
|
-
export async function claimPendingIpcRequests() {
|
|
1035
|
-
const db = await getDb();
|
|
1036
|
-
const pending = await db.query.ipc_requests.findMany({ where: { status: 'pending' }, orderBy: { created_at: 'asc' } });
|
|
1037
|
-
const claimed = [];
|
|
1038
|
-
for (const req of pending) {
|
|
1039
|
-
const rows = await db.update(schema.ipc_requests)
|
|
1040
|
-
.set({ status: 'processing' })
|
|
1041
|
-
.where(orm.and(orm.eq(schema.ipc_requests.id, req.id), orm.eq(schema.ipc_requests.status, 'pending')))
|
|
1042
|
-
.returning();
|
|
1043
|
-
if (rows.length > 0)
|
|
1044
|
-
claimed.push(req);
|
|
1045
|
-
}
|
|
1046
|
-
return claimed;
|
|
1047
|
-
}
|
|
1048
|
-
export async function completeIpcRequest({ id, response }) {
|
|
1049
|
-
const db = await getDb();
|
|
1050
|
-
const [row] = await db.update(schema.ipc_requests)
|
|
1051
|
-
.set({ response, status: 'completed' })
|
|
1052
|
-
.where(orm.and(orm.eq(schema.ipc_requests.id, id), orm.inArray(schema.ipc_requests.status, ['pending', 'processing'])))
|
|
1053
|
-
.returning();
|
|
1054
|
-
return row;
|
|
1055
|
-
}
|
|
1056
|
-
export async function getIpcRequestById({ id }) {
|
|
1057
|
-
const db = await getDb();
|
|
1058
|
-
return await db.query.ipc_requests.findFirst({ where: { id } }) ?? null;
|
|
1059
|
-
}
|
|
1060
|
-
export async function cancelStaleProcessingRequests({ ttlMs }) {
|
|
1061
|
-
const db = await getDb();
|
|
1062
|
-
const cutoff = new Date(Date.now() - ttlMs);
|
|
1063
|
-
const rows = await db.update(schema.ipc_requests)
|
|
1064
|
-
.set({ status: 'cancelled', response: JSON.stringify({ error: 'Request timed out' }) })
|
|
1065
|
-
.where(orm.and(orm.eq(schema.ipc_requests.status, 'processing'), orm.lt(schema.ipc_requests.updated_at, cutoff)))
|
|
1066
|
-
.returning({ id: schema.ipc_requests.id });
|
|
1067
|
-
return { count: rows.length };
|
|
1068
|
-
}
|
|
1069
|
-
export async function cancelAllPendingIpcRequests() {
|
|
1070
|
-
const db = await getDb();
|
|
1071
|
-
await db.update(schema.ipc_requests)
|
|
1072
|
-
.set({ status: 'cancelled', response: JSON.stringify({ error: 'Bot shutting down' }) })
|
|
1073
|
-
.where(orm.inArray(schema.ipc_requests.status, ['pending', 'processing']));
|
|
1074
|
-
}
|