@brianli/kimaki 0.4.72-brianli.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin.js +2 -0
- package/dist/ai-tool-to-genai.js +233 -0
- package/dist/ai-tool-to-genai.test.js +267 -0
- package/dist/ai-tool.js +6 -0
- package/dist/bin.js +87 -0
- package/dist/bot-token.js +121 -0
- package/dist/bot-token.test.js +134 -0
- package/dist/channel-management.js +101 -0
- package/dist/cli-parsing.test.js +89 -0
- package/dist/cli.js +2529 -0
- package/dist/commands/abort.js +82 -0
- package/dist/commands/action-buttons.js +257 -0
- package/dist/commands/add-project.js +114 -0
- package/dist/commands/agent.js +291 -0
- package/dist/commands/ask-question.js +223 -0
- package/dist/commands/compact.js +120 -0
- package/dist/commands/context-usage.js +140 -0
- package/dist/commands/create-new-project.js +118 -0
- package/dist/commands/diff.js +128 -0
- package/dist/commands/file-upload.js +275 -0
- package/dist/commands/fork.js +217 -0
- package/dist/commands/gemini-apikey.js +70 -0
- package/dist/commands/login.js +490 -0
- package/dist/commands/mention-mode.js +51 -0
- package/dist/commands/merge-worktree.js +124 -0
- package/dist/commands/model.js +694 -0
- package/dist/commands/permissions.js +163 -0
- package/dist/commands/queue.js +217 -0
- package/dist/commands/remove-project.js +115 -0
- package/dist/commands/restart-opencode-server.js +116 -0
- package/dist/commands/resume.js +159 -0
- package/dist/commands/run-command.js +79 -0
- package/dist/commands/session-id.js +78 -0
- package/dist/commands/session.js +192 -0
- package/dist/commands/share.js +80 -0
- package/dist/commands/types.js +2 -0
- package/dist/commands/undo-redo.js +159 -0
- package/dist/commands/unset-model.js +152 -0
- package/dist/commands/upgrade.js +42 -0
- package/dist/commands/user-command.js +148 -0
- package/dist/commands/verbosity.js +60 -0
- package/dist/commands/worktree-settings.js +50 -0
- package/dist/commands/worktree.js +299 -0
- package/dist/condense-memory.js +33 -0
- package/dist/config.js +110 -0
- package/dist/database.js +1050 -0
- package/dist/db.js +159 -0
- package/dist/db.test.js +49 -0
- package/dist/discord-api.js +28 -0
- package/dist/discord-auth.js +231 -0
- package/dist/discord-auth.test.js +80 -0
- package/dist/discord-bot.js +997 -0
- package/dist/discord-utils.js +560 -0
- package/dist/discord-utils.test.js +115 -0
- package/dist/errors.js +167 -0
- package/dist/escape-backticks.test.js +429 -0
- package/dist/format-tables.js +122 -0
- package/dist/format-tables.test.js +199 -0
- package/dist/forum-sync/config.js +79 -0
- package/dist/forum-sync/discord-operations.js +154 -0
- package/dist/forum-sync/index.js +5 -0
- package/dist/forum-sync/markdown.js +117 -0
- package/dist/forum-sync/sync-to-discord.js +417 -0
- package/dist/forum-sync/sync-to-files.js +190 -0
- package/dist/forum-sync/types.js +53 -0
- package/dist/forum-sync/watchers.js +307 -0
- package/dist/gateway-consumer.js +232 -0
- package/dist/gateway-consumer.test.js +18 -0
- package/dist/genai-worker-wrapper.js +111 -0
- package/dist/genai-worker.js +311 -0
- package/dist/genai.js +232 -0
- package/dist/generated/browser.js +17 -0
- package/dist/generated/client.js +35 -0
- package/dist/generated/commonInputTypes.js +10 -0
- package/dist/generated/enums.js +30 -0
- package/dist/generated/internal/class.js +41 -0
- package/dist/generated/internal/prismaNamespace.js +239 -0
- package/dist/generated/internal/prismaNamespaceBrowser.js +209 -0
- package/dist/generated/models/bot_api_keys.js +1 -0
- package/dist/generated/models/bot_tokens.js +1 -0
- package/dist/generated/models/channel_agents.js +1 -0
- package/dist/generated/models/channel_directories.js +1 -0
- package/dist/generated/models/channel_mention_mode.js +1 -0
- package/dist/generated/models/channel_models.js +1 -0
- package/dist/generated/models/channel_verbosity.js +1 -0
- package/dist/generated/models/channel_worktrees.js +1 -0
- package/dist/generated/models/forum_sync_configs.js +1 -0
- package/dist/generated/models/global_models.js +1 -0
- package/dist/generated/models/ipc_requests.js +1 -0
- package/dist/generated/models/part_messages.js +1 -0
- package/dist/generated/models/scheduled_tasks.js +1 -0
- package/dist/generated/models/session_agents.js +1 -0
- package/dist/generated/models/session_models.js +1 -0
- package/dist/generated/models/session_start_sources.js +1 -0
- package/dist/generated/models/thread_sessions.js +1 -0
- package/dist/generated/models/thread_worktrees.js +1 -0
- package/dist/generated/models.js +1 -0
- package/dist/heap-monitor.js +95 -0
- package/dist/hrana-server.js +416 -0
- package/dist/hrana-server.test.js +368 -0
- package/dist/image-utils.js +112 -0
- package/dist/interaction-handler.js +327 -0
- package/dist/ipc-polling.js +251 -0
- package/dist/kimaki-digital-twin.e2e.test.js +165 -0
- package/dist/limit-heading-depth.js +25 -0
- package/dist/limit-heading-depth.test.js +105 -0
- package/dist/logger.js +160 -0
- package/dist/markdown.js +342 -0
- package/dist/markdown.test.js +253 -0
- package/dist/message-formatting.js +433 -0
- package/dist/message-formatting.test.js +73 -0
- package/dist/openai-realtime.js +228 -0
- package/dist/opencode-plugin-loading.e2e.test.js +91 -0
- package/dist/opencode-plugin.js +536 -0
- package/dist/opencode-plugin.test.js +98 -0
- package/dist/opencode.js +409 -0
- package/dist/privacy-sanitizer.js +105 -0
- package/dist/runtime-mode.js +51 -0
- package/dist/runtime-mode.test.js +115 -0
- package/dist/sentry.js +127 -0
- package/dist/session-handler/state.js +151 -0
- package/dist/session-handler.js +1874 -0
- package/dist/session-search.js +100 -0
- package/dist/session-search.test.js +40 -0
- package/dist/startup-service.js +153 -0
- package/dist/system-message.js +499 -0
- package/dist/task-runner.js +282 -0
- package/dist/task-schedule.js +191 -0
- package/dist/task-schedule.test.js +71 -0
- package/dist/thinking-utils.js +35 -0
- package/dist/thread-message-queue.e2e.test.js +781 -0
- package/dist/tools.js +359 -0
- package/dist/unnest-code-blocks.js +136 -0
- package/dist/unnest-code-blocks.test.js +641 -0
- package/dist/upgrade.js +114 -0
- package/dist/utils.js +109 -0
- package/dist/voice-handler.js +606 -0
- package/dist/voice.js +304 -0
- package/dist/voice.test.js +187 -0
- package/dist/wait-session.js +94 -0
- package/dist/worker-types.js +4 -0
- package/dist/worktree-utils.js +727 -0
- package/dist/xml.js +92 -0
- package/dist/xml.test.js +32 -0
- package/package.json +82 -0
- package/schema.prisma +246 -0
- package/skills/batch/SKILL.md +87 -0
- package/skills/critique/SKILL.md +129 -0
- package/skills/errore/SKILL.md +589 -0
- package/skills/goke/.prettierrc +5 -0
- package/skills/goke/CHANGELOG.md +40 -0
- package/skills/goke/LICENSE +21 -0
- package/skills/goke/README.md +666 -0
- package/skills/goke/SKILL.md +458 -0
- package/skills/goke/package.json +43 -0
- package/skills/goke/src/__test__/coerce.test.ts +411 -0
- package/skills/goke/src/__test__/index.test.ts +1798 -0
- package/skills/goke/src/__test__/types.test-d.ts +111 -0
- package/skills/goke/src/coerce.ts +547 -0
- package/skills/goke/src/goke.ts +1362 -0
- package/skills/goke/src/index.ts +16 -0
- package/skills/goke/src/mri.ts +164 -0
- package/skills/goke/tsconfig.json +15 -0
- package/skills/jitter/EDITOR.md +219 -0
- package/skills/jitter/EXPORT-INTERNALS.md +309 -0
- package/skills/jitter/SKILL.md +158 -0
- package/skills/jitter/jitter-clipboard.json +1042 -0
- package/skills/jitter/package.json +14 -0
- package/skills/jitter/tsconfig.json +15 -0
- package/skills/jitter/utils/actions.ts +212 -0
- package/skills/jitter/utils/export.ts +114 -0
- package/skills/jitter/utils/index.ts +141 -0
- package/skills/jitter/utils/snapshot.ts +154 -0
- package/skills/jitter/utils/traverse.ts +246 -0
- package/skills/jitter/utils/types.ts +279 -0
- package/skills/jitter/utils/wait.ts +133 -0
- package/skills/playwriter/SKILL.md +31 -0
- package/skills/security-review/SKILL.md +208 -0
- package/skills/simplify/SKILL.md +58 -0
- package/skills/termcast/SKILL.md +945 -0
- package/skills/tuistory/SKILL.md +250 -0
- package/skills/zustand-centralized-state/SKILL.md +582 -0
- package/src/__snapshots__/compact-session-context-no-system.md +35 -0
- package/src/__snapshots__/compact-session-context.md +41 -0
- package/src/__snapshots__/first-session-no-info.md +17 -0
- package/src/__snapshots__/first-session-with-info.md +23 -0
- package/src/__snapshots__/session-1.md +17 -0
- package/src/__snapshots__/session-2.md +5871 -0
- package/src/__snapshots__/session-3.md +17 -0
- package/src/__snapshots__/session-with-tools.md +5871 -0
- package/src/ai-tool-to-genai.test.ts +296 -0
- package/src/ai-tool-to-genai.ts +282 -0
- package/src/ai-tool.ts +39 -0
- package/src/bin.ts +108 -0
- package/src/bot-token.test.ts +171 -0
- package/src/bot-token.ts +159 -0
- package/src/channel-management.ts +172 -0
- package/src/cli-parsing.test.ts +132 -0
- package/src/cli.ts +3605 -0
- package/src/commands/abort.ts +112 -0
- package/src/commands/action-buttons.ts +376 -0
- package/src/commands/add-project.ts +152 -0
- package/src/commands/agent.ts +404 -0
- package/src/commands/ask-question.ts +330 -0
- package/src/commands/compact.ts +157 -0
- package/src/commands/context-usage.ts +199 -0
- package/src/commands/create-new-project.ts +179 -0
- package/src/commands/diff.ts +165 -0
- package/src/commands/file-upload.ts +389 -0
- package/src/commands/fork.ts +320 -0
- package/src/commands/gemini-apikey.ts +104 -0
- package/src/commands/login.ts +634 -0
- package/src/commands/mention-mode.ts +77 -0
- package/src/commands/merge-worktree.ts +177 -0
- package/src/commands/model.ts +961 -0
- package/src/commands/permissions.ts +261 -0
- package/src/commands/queue.ts +296 -0
- package/src/commands/remove-project.ts +155 -0
- package/src/commands/restart-opencode-server.ts +162 -0
- package/src/commands/resume.ts +242 -0
- package/src/commands/run-command.ts +123 -0
- package/src/commands/session-id.ts +109 -0
- package/src/commands/session.ts +250 -0
- package/src/commands/share.ts +106 -0
- package/src/commands/types.ts +25 -0
- package/src/commands/undo-redo.ts +221 -0
- package/src/commands/unset-model.ts +189 -0
- package/src/commands/upgrade.ts +52 -0
- package/src/commands/user-command.ts +193 -0
- package/src/commands/verbosity.ts +88 -0
- package/src/commands/worktree-settings.ts +79 -0
- package/src/commands/worktree.ts +431 -0
- package/src/condense-memory.ts +36 -0
- package/src/config.ts +148 -0
- package/src/database.ts +1530 -0
- package/src/db.test.ts +60 -0
- package/src/db.ts +190 -0
- package/src/discord-api.ts +35 -0
- package/src/discord-bot.ts +1316 -0
- package/src/discord-utils.test.ts +132 -0
- package/src/discord-utils.ts +767 -0
- package/src/errors.ts +213 -0
- package/src/escape-backticks.test.ts +469 -0
- package/src/format-tables.test.ts +223 -0
- package/src/format-tables.ts +145 -0
- package/src/forum-sync/config.ts +92 -0
- package/src/forum-sync/discord-operations.ts +241 -0
- package/src/forum-sync/index.ts +9 -0
- package/src/forum-sync/markdown.ts +176 -0
- package/src/forum-sync/sync-to-discord.ts +595 -0
- package/src/forum-sync/sync-to-files.ts +294 -0
- package/src/forum-sync/types.ts +175 -0
- package/src/forum-sync/watchers.ts +454 -0
- package/src/genai-worker-wrapper.ts +164 -0
- package/src/genai-worker.ts +386 -0
- package/src/genai.ts +321 -0
- package/src/generated/browser.ts +109 -0
- package/src/generated/client.ts +131 -0
- package/src/generated/commonInputTypes.ts +512 -0
- package/src/generated/enums.ts +46 -0
- package/src/generated/internal/class.ts +362 -0
- package/src/generated/internal/prismaNamespace.ts +2251 -0
- package/src/generated/internal/prismaNamespaceBrowser.ts +308 -0
- package/src/generated/models/bot_api_keys.ts +1288 -0
- package/src/generated/models/bot_tokens.ts +1577 -0
- package/src/generated/models/channel_agents.ts +1256 -0
- package/src/generated/models/channel_directories.ts +2104 -0
- package/src/generated/models/channel_mention_mode.ts +1300 -0
- package/src/generated/models/channel_models.ts +1288 -0
- package/src/generated/models/channel_verbosity.ts +1224 -0
- package/src/generated/models/channel_worktrees.ts +1308 -0
- package/src/generated/models/forum_sync_configs.ts +1452 -0
- package/src/generated/models/global_models.ts +1288 -0
- package/src/generated/models/ipc_requests.ts +1485 -0
- package/src/generated/models/part_messages.ts +1302 -0
- package/src/generated/models/scheduled_tasks.ts +2320 -0
- package/src/generated/models/session_agents.ts +1086 -0
- package/src/generated/models/session_models.ts +1114 -0
- package/src/generated/models/session_start_sources.ts +1408 -0
- package/src/generated/models/thread_sessions.ts +1599 -0
- package/src/generated/models/thread_worktrees.ts +1352 -0
- package/src/generated/models.ts +29 -0
- package/src/heap-monitor.ts +121 -0
- package/src/hrana-server.test.ts +428 -0
- package/src/hrana-server.ts +547 -0
- package/src/image-utils.ts +149 -0
- package/src/interaction-handler.ts +461 -0
- package/src/ipc-polling.ts +325 -0
- package/src/kimaki-digital-twin.e2e.test.ts +201 -0
- package/src/limit-heading-depth.test.ts +116 -0
- package/src/limit-heading-depth.ts +26 -0
- package/src/logger.ts +203 -0
- package/src/markdown.test.ts +360 -0
- package/src/markdown.ts +410 -0
- package/src/message-formatting.test.ts +81 -0
- package/src/message-formatting.ts +549 -0
- package/src/openai-realtime.ts +362 -0
- package/src/opencode-plugin-loading.e2e.test.ts +112 -0
- package/src/opencode-plugin.test.ts +108 -0
- package/src/opencode-plugin.ts +652 -0
- package/src/opencode.ts +554 -0
- package/src/privacy-sanitizer.ts +142 -0
- package/src/schema.sql +158 -0
- package/src/sentry.ts +137 -0
- package/src/session-handler/state.ts +232 -0
- package/src/session-handler.ts +2668 -0
- package/src/session-search.test.ts +50 -0
- package/src/session-search.ts +148 -0
- package/src/startup-service.ts +200 -0
- package/src/system-message.ts +568 -0
- package/src/task-runner.ts +425 -0
- package/src/task-schedule.test.ts +84 -0
- package/src/task-schedule.ts +287 -0
- package/src/thinking-utils.ts +61 -0
- package/src/thread-message-queue.e2e.test.ts +997 -0
- package/src/tools.ts +432 -0
- package/src/unnest-code-blocks.test.ts +679 -0
- package/src/unnest-code-blocks.ts +168 -0
- package/src/upgrade.ts +127 -0
- package/src/utils.ts +145 -0
- package/src/voice-handler.ts +852 -0
- package/src/voice.test.ts +219 -0
- package/src/voice.ts +444 -0
- package/src/wait-session.ts +147 -0
- package/src/worker-types.ts +64 -0
- package/src/worktree-utils.ts +988 -0
- package/src/xml.test.ts +38 -0
- package/src/xml.ts +121 -0
package/src/schema.sql
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
-- This file is generated by pnpm generate:sql. Do not edit manually.
|
|
2
|
+
CREATE TABLE IF NOT EXISTS "thread_sessions" (
|
|
3
|
+
"thread_id" TEXT NOT NULL PRIMARY KEY,
|
|
4
|
+
"session_id" TEXT NOT NULL,
|
|
5
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
6
|
+
);
|
|
7
|
+
CREATE TABLE IF NOT EXISTS "part_messages" (
|
|
8
|
+
"part_id" TEXT NOT NULL PRIMARY KEY,
|
|
9
|
+
"message_id" TEXT NOT NULL,
|
|
10
|
+
"thread_id" TEXT NOT NULL,
|
|
11
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
12
|
+
CONSTRAINT "part_messages_thread_id_fkey" FOREIGN KEY ("thread_id") REFERENCES "thread_sessions" ("thread_id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
13
|
+
);
|
|
14
|
+
CREATE TABLE IF NOT EXISTS "bot_tokens" (
|
|
15
|
+
"app_id" TEXT NOT NULL PRIMARY KEY,
|
|
16
|
+
"token" TEXT NOT NULL,
|
|
17
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
18
|
+
);
|
|
19
|
+
CREATE TABLE IF NOT EXISTS "channel_directories" (
|
|
20
|
+
"channel_id" TEXT NOT NULL PRIMARY KEY,
|
|
21
|
+
"directory" TEXT NOT NULL,
|
|
22
|
+
"channel_type" TEXT NOT NULL,
|
|
23
|
+
"app_id" TEXT,
|
|
24
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
25
|
+
CONSTRAINT "channel_directories_app_id_fkey" FOREIGN KEY ("app_id") REFERENCES "bot_tokens" ("app_id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
26
|
+
);
|
|
27
|
+
CREATE TABLE IF NOT EXISTS "bot_api_keys" (
|
|
28
|
+
"app_id" TEXT NOT NULL PRIMARY KEY,
|
|
29
|
+
"gemini_api_key" TEXT,
|
|
30
|
+
"openai_api_key" TEXT,
|
|
31
|
+
"xai_api_key" TEXT,
|
|
32
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
33
|
+
CONSTRAINT "bot_api_keys_app_id_fkey" FOREIGN KEY ("app_id") REFERENCES "bot_tokens" ("app_id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
34
|
+
);
|
|
35
|
+
CREATE TABLE IF NOT EXISTS "thread_worktrees" (
|
|
36
|
+
"thread_id" TEXT NOT NULL PRIMARY KEY,
|
|
37
|
+
"worktree_name" TEXT NOT NULL,
|
|
38
|
+
"worktree_directory" TEXT,
|
|
39
|
+
"project_directory" TEXT NOT NULL,
|
|
40
|
+
"status" TEXT DEFAULT 'pending',
|
|
41
|
+
"error_message" TEXT,
|
|
42
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
43
|
+
CONSTRAINT "thread_worktrees_thread_id_fkey" FOREIGN KEY ("thread_id") REFERENCES "thread_sessions" ("thread_id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
44
|
+
);
|
|
45
|
+
CREATE TABLE IF NOT EXISTS "channel_models" (
|
|
46
|
+
"channel_id" TEXT NOT NULL PRIMARY KEY,
|
|
47
|
+
"model_id" TEXT NOT NULL,
|
|
48
|
+
"variant" TEXT,
|
|
49
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
50
|
+
"updated_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
51
|
+
CONSTRAINT "channel_models_channel_id_fkey" FOREIGN KEY ("channel_id") REFERENCES "channel_directories" ("channel_id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
52
|
+
);
|
|
53
|
+
CREATE TABLE IF NOT EXISTS "session_models" (
|
|
54
|
+
"session_id" TEXT NOT NULL PRIMARY KEY,
|
|
55
|
+
"model_id" TEXT NOT NULL,
|
|
56
|
+
"variant" TEXT,
|
|
57
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
58
|
+
);
|
|
59
|
+
CREATE TABLE IF NOT EXISTS "channel_agents" (
|
|
60
|
+
"channel_id" TEXT NOT NULL PRIMARY KEY,
|
|
61
|
+
"agent_name" TEXT NOT NULL,
|
|
62
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
63
|
+
"updated_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
64
|
+
CONSTRAINT "channel_agents_channel_id_fkey" FOREIGN KEY ("channel_id") REFERENCES "channel_directories" ("channel_id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
65
|
+
);
|
|
66
|
+
CREATE TABLE IF NOT EXISTS "session_agents" (
|
|
67
|
+
"session_id" TEXT NOT NULL PRIMARY KEY,
|
|
68
|
+
"agent_name" TEXT NOT NULL,
|
|
69
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
70
|
+
);
|
|
71
|
+
CREATE TABLE IF NOT EXISTS "channel_worktrees" (
|
|
72
|
+
"channel_id" TEXT NOT NULL PRIMARY KEY,
|
|
73
|
+
"enabled" INTEGER NOT NULL DEFAULT 0,
|
|
74
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
75
|
+
"updated_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
76
|
+
CONSTRAINT "channel_worktrees_channel_id_fkey" FOREIGN KEY ("channel_id") REFERENCES "channel_directories" ("channel_id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
77
|
+
);
|
|
78
|
+
CREATE TABLE IF NOT EXISTS "channel_verbosity" (
|
|
79
|
+
"channel_id" TEXT NOT NULL PRIMARY KEY,
|
|
80
|
+
"verbosity" TEXT NOT NULL DEFAULT 'tools-and-text',
|
|
81
|
+
"updated_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
82
|
+
CONSTRAINT "channel_verbosity_channel_id_fkey" FOREIGN KEY ("channel_id") REFERENCES "channel_directories" ("channel_id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
83
|
+
);
|
|
84
|
+
CREATE TABLE IF NOT EXISTS "channel_mention_mode" (
|
|
85
|
+
"channel_id" TEXT NOT NULL PRIMARY KEY,
|
|
86
|
+
"enabled" INTEGER NOT NULL DEFAULT 0,
|
|
87
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
88
|
+
"updated_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
89
|
+
CONSTRAINT "channel_mention_mode_channel_id_fkey" FOREIGN KEY ("channel_id") REFERENCES "channel_directories" ("channel_id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
90
|
+
);
|
|
91
|
+
CREATE TABLE IF NOT EXISTS "global_models" (
|
|
92
|
+
"app_id" TEXT NOT NULL PRIMARY KEY,
|
|
93
|
+
"model_id" TEXT NOT NULL,
|
|
94
|
+
"variant" TEXT,
|
|
95
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
96
|
+
"updated_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
97
|
+
CONSTRAINT "global_models_app_id_fkey" FOREIGN KEY ("app_id") REFERENCES "bot_tokens" ("app_id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
98
|
+
);
|
|
99
|
+
CREATE TABLE IF NOT EXISTS "scheduled_tasks" (
|
|
100
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
101
|
+
"status" TEXT NOT NULL DEFAULT 'planned',
|
|
102
|
+
"schedule_kind" TEXT NOT NULL,
|
|
103
|
+
"run_at" DATETIME,
|
|
104
|
+
"cron_expr" TEXT,
|
|
105
|
+
"timezone" TEXT,
|
|
106
|
+
"next_run_at" DATETIME NOT NULL,
|
|
107
|
+
"running_started_at" DATETIME,
|
|
108
|
+
"last_run_at" DATETIME,
|
|
109
|
+
"last_error" TEXT,
|
|
110
|
+
"attempts" INTEGER NOT NULL DEFAULT 0,
|
|
111
|
+
"payload_json" TEXT NOT NULL,
|
|
112
|
+
"prompt_preview" TEXT NOT NULL,
|
|
113
|
+
"channel_id" TEXT,
|
|
114
|
+
"thread_id" TEXT,
|
|
115
|
+
"session_id" TEXT,
|
|
116
|
+
"project_directory" TEXT,
|
|
117
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
118
|
+
"updated_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
119
|
+
CONSTRAINT "scheduled_tasks_channel_id_fkey" FOREIGN KEY ("channel_id") REFERENCES "channel_directories" ("channel_id") ON DELETE SET NULL ON UPDATE CASCADE,
|
|
120
|
+
CONSTRAINT "scheduled_tasks_thread_id_fkey" FOREIGN KEY ("thread_id") REFERENCES "thread_sessions" ("thread_id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
121
|
+
);
|
|
122
|
+
CREATE TABLE sqlite_sequence(name,seq);
|
|
123
|
+
CREATE TABLE IF NOT EXISTS "session_start_sources" (
|
|
124
|
+
"session_id" TEXT NOT NULL PRIMARY KEY,
|
|
125
|
+
"schedule_kind" TEXT NOT NULL,
|
|
126
|
+
"scheduled_task_id" INTEGER,
|
|
127
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
128
|
+
"updated_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
129
|
+
CONSTRAINT "session_start_sources_scheduled_task_id_fkey" FOREIGN KEY ("scheduled_task_id") REFERENCES "scheduled_tasks" ("id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
130
|
+
);
|
|
131
|
+
CREATE TABLE IF NOT EXISTS "forum_sync_configs" (
|
|
132
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
133
|
+
"app_id" TEXT NOT NULL,
|
|
134
|
+
"forum_channel_id" TEXT NOT NULL,
|
|
135
|
+
"output_dir" TEXT NOT NULL,
|
|
136
|
+
"direction" TEXT NOT NULL DEFAULT 'bidirectional',
|
|
137
|
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
138
|
+
"updated_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
139
|
+
CONSTRAINT "forum_sync_configs_app_id_fkey" FOREIGN KEY ("app_id") REFERENCES "bot_tokens" ("app_id") ON DELETE CASCADE ON UPDATE CASCADE
|
|
140
|
+
);
|
|
141
|
+
CREATE TABLE IF NOT EXISTS "ipc_requests" (
|
|
142
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
143
|
+
"type" TEXT NOT NULL,
|
|
144
|
+
"session_id" TEXT NOT NULL,
|
|
145
|
+
"thread_id" TEXT NOT NULL,
|
|
146
|
+
"payload" TEXT NOT NULL,
|
|
147
|
+
"response" TEXT,
|
|
148
|
+
"status" TEXT NOT NULL DEFAULT 'pending',
|
|
149
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
150
|
+
"updated_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
151
|
+
CONSTRAINT "ipc_requests_thread_id_fkey" FOREIGN KEY ("thread_id") REFERENCES "thread_sessions" ("thread_id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
152
|
+
);
|
|
153
|
+
CREATE INDEX "scheduled_tasks_status_next_run_at_idx" ON "scheduled_tasks"("status", "next_run_at");
|
|
154
|
+
CREATE INDEX "scheduled_tasks_channel_id_status_idx" ON "scheduled_tasks"("channel_id", "status");
|
|
155
|
+
CREATE INDEX "scheduled_tasks_thread_id_status_idx" ON "scheduled_tasks"("thread_id", "status");
|
|
156
|
+
CREATE INDEX "session_start_sources_scheduled_task_id_idx" ON "session_start_sources"("scheduled_task_id");
|
|
157
|
+
CREATE UNIQUE INDEX "forum_sync_configs_app_id_forum_channel_id_key" ON "forum_sync_configs"("app_id", "forum_channel_id");
|
|
158
|
+
CREATE INDEX "ipc_requests_status_created_at_idx" ON "ipc_requests"("status", "created_at");
|
package/src/sentry.ts
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// Sentry error tracking initialization and notifyError helper.
|
|
2
|
+
// Uses @sentry/node for the Node.js runtime (bot process, plugin process, worker threads).
|
|
3
|
+
// Must be initialized early in both the bot process (cli.ts) and plugin process
|
|
4
|
+
// (opencode-plugin.ts). The plugin process receives the DSN via KIMAKI_SENTRY_DSN env var.
|
|
5
|
+
|
|
6
|
+
import * as Sentry from '@sentry/node'
|
|
7
|
+
import * as errore from 'errore'
|
|
8
|
+
import { createRequire } from 'node:module'
|
|
9
|
+
import { sanitizeSensitiveText, sanitizeUnknownValue } from './privacy-sanitizer.js'
|
|
10
|
+
|
|
11
|
+
// DSN placeholder — replace with your Sentry project DSN.
|
|
12
|
+
// Users can also set KIMAKI_SENTRY_DSN env var.
|
|
13
|
+
const HARDCODED_DSN = 'https://3b87e21ac01cb9c66225719ea65111d2@o4510952031715328.ingest.us.sentry.io/4510952088469504'
|
|
14
|
+
|
|
15
|
+
function readKimakiVersion(): string {
|
|
16
|
+
try {
|
|
17
|
+
const require = createRequire(import.meta.url)
|
|
18
|
+
const pkg = require('../package.json') as { version?: string }
|
|
19
|
+
const version = pkg.version
|
|
20
|
+
if (!version) {
|
|
21
|
+
return 'unknown'
|
|
22
|
+
}
|
|
23
|
+
return version
|
|
24
|
+
} catch {
|
|
25
|
+
return 'unknown'
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const kimakiVersion = readKimakiVersion()
|
|
30
|
+
const kimakiRelease = `kimaki@${kimakiVersion}`
|
|
31
|
+
|
|
32
|
+
let initialized = false
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Initialize Sentry. Call once at process startup.
|
|
36
|
+
* No-op if DSN is empty or --no-sentry was passed.
|
|
37
|
+
*/
|
|
38
|
+
export function initSentry({ dsn }: { dsn?: string } = {}): void {
|
|
39
|
+
if (process.env.KIMAKI_SENTRY_DISABLED === '1') {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const resolvedDsn = dsn || process.env.KIMAKI_SENTRY_DSN || HARDCODED_DSN
|
|
44
|
+
if (!resolvedDsn || initialized) {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
Sentry.init({
|
|
49
|
+
dsn: resolvedDsn,
|
|
50
|
+
release: kimakiRelease,
|
|
51
|
+
integrations: [],
|
|
52
|
+
tracesSampleRate: 0,
|
|
53
|
+
sendDefaultPii: false,
|
|
54
|
+
profilesSampleRate: 0,
|
|
55
|
+
beforeSend(event, hint) {
|
|
56
|
+
// Skip in development — too noisy, errors appear in terminal
|
|
57
|
+
if (process.env.NODE_ENV === 'development') {
|
|
58
|
+
return null
|
|
59
|
+
}
|
|
60
|
+
// Skip abort errors — walks the cause chain so wrapped aborts are caught
|
|
61
|
+
if (errore.isAbortError(hint.originalException)) {
|
|
62
|
+
return null
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const sanitizedEvent = sanitizeUnknownValue(event, {
|
|
67
|
+
redactPaths: false,
|
|
68
|
+
})
|
|
69
|
+
if (sanitizedEvent && typeof sanitizedEvent === 'object') {
|
|
70
|
+
return sanitizedEvent as typeof event
|
|
71
|
+
}
|
|
72
|
+
} catch {
|
|
73
|
+
return event
|
|
74
|
+
}
|
|
75
|
+
return event
|
|
76
|
+
},
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
Sentry.setTag('kimaki_version', kimakiVersion)
|
|
80
|
+
|
|
81
|
+
initialized = true
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Report an unexpected error to Sentry.
|
|
86
|
+
* Safe to call even if Sentry is not initialized.
|
|
87
|
+
* Fire-and-forget only: use `void notifyError(error, msg)` and never await it.
|
|
88
|
+
* This helper must never throw.
|
|
89
|
+
* Use this at terminal error handlers — the "last catch" in a chain
|
|
90
|
+
* where the error would otherwise be invisible.
|
|
91
|
+
*/
|
|
92
|
+
export function notifyError(error: unknown, msg?: string): void {
|
|
93
|
+
try {
|
|
94
|
+
if (!initialized) {
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const safeMsg = (() => {
|
|
99
|
+
if (!msg) {
|
|
100
|
+
return undefined
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
return sanitizeSensitiveText(msg, { redactPaths: false })
|
|
104
|
+
} catch {
|
|
105
|
+
return msg
|
|
106
|
+
}
|
|
107
|
+
})()
|
|
108
|
+
const safeError = (() => {
|
|
109
|
+
try {
|
|
110
|
+
return sanitizeUnknownValue(error, { redactPaths: false })
|
|
111
|
+
} catch {
|
|
112
|
+
return error
|
|
113
|
+
}
|
|
114
|
+
})()
|
|
115
|
+
|
|
116
|
+
Sentry.captureException(error, {
|
|
117
|
+
tags: { kimaki_version: kimakiVersion },
|
|
118
|
+
extra: { msg: safeMsg, kimakiVersion, error: safeError },
|
|
119
|
+
})
|
|
120
|
+
void Sentry.flush(1000).catch(() => {
|
|
121
|
+
return
|
|
122
|
+
})
|
|
123
|
+
} catch {
|
|
124
|
+
return
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* User-readable error class. Messages from AppError instances
|
|
130
|
+
* are forwarded to the user as-is; regular Error messages may be obfuscated.
|
|
131
|
+
*/
|
|
132
|
+
export class AppError extends Error {
|
|
133
|
+
constructor(message: string) {
|
|
134
|
+
super(message)
|
|
135
|
+
this.name = 'AppError'
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// Session handler run-state store and transitions.
|
|
2
|
+
// Centralizes prompt/idle race state so interrupt handling stays consistent.
|
|
3
|
+
|
|
4
|
+
import { createStore, type StoreApi } from 'zustand/vanilla'
|
|
5
|
+
|
|
6
|
+
export type MainRunPhase =
|
|
7
|
+
| 'waiting-dispatch'
|
|
8
|
+
| 'collecting-baseline'
|
|
9
|
+
| 'dispatching'
|
|
10
|
+
| 'prompt-resolved'
|
|
11
|
+
| 'finished'
|
|
12
|
+
| 'aborted'
|
|
13
|
+
|
|
14
|
+
export type MainIdleState = 'none' | 'deferred'
|
|
15
|
+
|
|
16
|
+
export type MainRunState = {
|
|
17
|
+
phase: MainRunPhase
|
|
18
|
+
idleState: MainIdleState
|
|
19
|
+
baselineAssistantIds: Set<string>
|
|
20
|
+
currentAssistantMessageId: string | undefined
|
|
21
|
+
eventSeq: number
|
|
22
|
+
evidenceSeq: number | undefined
|
|
23
|
+
deferredIdleSeq: number | undefined
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type MainRunStore = StoreApi<MainRunState>
|
|
27
|
+
|
|
28
|
+
export type MainSessionIdleDecision =
|
|
29
|
+
| 'deferred'
|
|
30
|
+
| 'ignore-no-evidence'
|
|
31
|
+
| 'process'
|
|
32
|
+
|
|
33
|
+
export type DeferredIdleDecision =
|
|
34
|
+
| 'none'
|
|
35
|
+
| 'ignore-no-evidence'
|
|
36
|
+
| 'ignore-before-evidence'
|
|
37
|
+
| 'process'
|
|
38
|
+
|
|
39
|
+
function initialMainRunState(): MainRunState {
|
|
40
|
+
return {
|
|
41
|
+
phase: 'waiting-dispatch',
|
|
42
|
+
idleState: 'none',
|
|
43
|
+
baselineAssistantIds: new Set<string>(),
|
|
44
|
+
currentAssistantMessageId: undefined,
|
|
45
|
+
eventSeq: 0,
|
|
46
|
+
evidenceSeq: undefined,
|
|
47
|
+
deferredIdleSeq: undefined,
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function createMainRunStore(): MainRunStore {
|
|
52
|
+
return createStore<MainRunState>(() => {
|
|
53
|
+
return initialMainRunState()
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function beginPromptCycle({ store }: { store: MainRunStore }): void {
|
|
58
|
+
store.setState((state) => {
|
|
59
|
+
return {
|
|
60
|
+
...state,
|
|
61
|
+
phase: 'collecting-baseline',
|
|
62
|
+
idleState: 'none',
|
|
63
|
+
baselineAssistantIds: new Set<string>(),
|
|
64
|
+
currentAssistantMessageId: undefined,
|
|
65
|
+
eventSeq: 0,
|
|
66
|
+
evidenceSeq: undefined,
|
|
67
|
+
deferredIdleSeq: undefined,
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function setBaselineAssistantIds({
|
|
73
|
+
store,
|
|
74
|
+
messageIds,
|
|
75
|
+
}: {
|
|
76
|
+
store: MainRunStore
|
|
77
|
+
messageIds: Set<string>
|
|
78
|
+
}): void {
|
|
79
|
+
store.setState((state) => {
|
|
80
|
+
return {
|
|
81
|
+
...state,
|
|
82
|
+
baselineAssistantIds: new Set<string>(messageIds),
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function markDispatching({ store }: { store: MainRunStore }): void {
|
|
88
|
+
store.setState((state) => {
|
|
89
|
+
return {
|
|
90
|
+
...state,
|
|
91
|
+
phase: 'dispatching',
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function markCurrentPromptEvidence({
|
|
97
|
+
store,
|
|
98
|
+
messageId,
|
|
99
|
+
}: {
|
|
100
|
+
store: MainRunStore
|
|
101
|
+
messageId: string
|
|
102
|
+
}): void {
|
|
103
|
+
store.setState((state) => {
|
|
104
|
+
const eventSeq = state.eventSeq + 1
|
|
105
|
+
const canTrackCurrentPrompt =
|
|
106
|
+
state.phase === 'dispatching' || state.phase === 'prompt-resolved'
|
|
107
|
+
if (!canTrackCurrentPrompt) {
|
|
108
|
+
return {
|
|
109
|
+
...state,
|
|
110
|
+
eventSeq,
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (state.baselineAssistantIds.has(messageId)) {
|
|
114
|
+
return {
|
|
115
|
+
...state,
|
|
116
|
+
eventSeq,
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
...state,
|
|
121
|
+
eventSeq,
|
|
122
|
+
currentAssistantMessageId: messageId,
|
|
123
|
+
evidenceSeq: state.evidenceSeq ?? eventSeq,
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function handleMainSessionIdle({
|
|
129
|
+
store,
|
|
130
|
+
}: {
|
|
131
|
+
store: MainRunStore
|
|
132
|
+
}): MainSessionIdleDecision {
|
|
133
|
+
const state = store.getState()
|
|
134
|
+
const idleSeq = state.eventSeq + 1
|
|
135
|
+
|
|
136
|
+
if (state.phase !== 'prompt-resolved') {
|
|
137
|
+
store.setState((current) => {
|
|
138
|
+
return {
|
|
139
|
+
...current,
|
|
140
|
+
eventSeq: idleSeq,
|
|
141
|
+
idleState: 'deferred',
|
|
142
|
+
deferredIdleSeq: idleSeq,
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
|
+
return 'deferred'
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (!state.currentAssistantMessageId) {
|
|
149
|
+
store.setState((current) => {
|
|
150
|
+
return {
|
|
151
|
+
...current,
|
|
152
|
+
eventSeq: idleSeq,
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
return 'ignore-no-evidence'
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
store.setState((current) => {
|
|
159
|
+
return {
|
|
160
|
+
...current,
|
|
161
|
+
eventSeq: idleSeq,
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
return 'process'
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function markPromptResolvedAndConsumeDeferredIdle({
|
|
168
|
+
store,
|
|
169
|
+
}: {
|
|
170
|
+
store: MainRunStore
|
|
171
|
+
}): DeferredIdleDecision {
|
|
172
|
+
const state = store.getState()
|
|
173
|
+
|
|
174
|
+
const nextState: MainRunState = {
|
|
175
|
+
...state,
|
|
176
|
+
phase: 'prompt-resolved',
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (state.idleState !== 'deferred') {
|
|
180
|
+
store.setState(nextState)
|
|
181
|
+
return 'none'
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
nextState.idleState = 'none'
|
|
185
|
+
nextState.deferredIdleSeq = undefined
|
|
186
|
+
|
|
187
|
+
if (!state.currentAssistantMessageId) {
|
|
188
|
+
store.setState(nextState)
|
|
189
|
+
return 'ignore-no-evidence'
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (
|
|
193
|
+
typeof state.deferredIdleSeq === 'number' &&
|
|
194
|
+
typeof state.evidenceSeq === 'number' &&
|
|
195
|
+
state.deferredIdleSeq <= state.evidenceSeq
|
|
196
|
+
) {
|
|
197
|
+
store.setState(nextState)
|
|
198
|
+
return 'ignore-before-evidence'
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
store.setState(nextState)
|
|
202
|
+
return 'process'
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function markFinished({ store }: { store: MainRunStore }): void {
|
|
206
|
+
store.setState((state) => {
|
|
207
|
+
return {
|
|
208
|
+
...state,
|
|
209
|
+
phase: 'finished',
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function markAborted({ store }: { store: MainRunStore }): void {
|
|
215
|
+
store.setState((state) => {
|
|
216
|
+
if (state.phase === 'finished') {
|
|
217
|
+
return state
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
...state,
|
|
221
|
+
phase: 'aborted',
|
|
222
|
+
}
|
|
223
|
+
})
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export function hasCurrentPromptEvidence({
|
|
227
|
+
store,
|
|
228
|
+
}: {
|
|
229
|
+
store: MainRunStore
|
|
230
|
+
}): boolean {
|
|
231
|
+
return Boolean(store.getState().currentAssistantMessageId)
|
|
232
|
+
}
|