beecork 1.7.0 → 2.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/README.md +52 -111
- package/dist/index.js +1394 -581
- package/package.json +26 -54
- package/dist/capabilities/index.d.ts +0 -3
- package/dist/capabilities/index.js +0 -2
- package/dist/capabilities/manager.d.ts +0 -13
- package/dist/capabilities/manager.js +0 -115
- package/dist/capabilities/packs.d.ts +0 -2
- package/dist/capabilities/packs.js +0 -54
- package/dist/capabilities/types.d.ts +0 -21
- package/dist/capabilities/types.js +0 -1
- package/dist/channels/admin.d.ts +0 -10
- package/dist/channels/admin.js +0 -20
- package/dist/channels/command-handler.d.ts +0 -19
- package/dist/channels/command-handler.js +0 -235
- package/dist/channels/discord.d.ts +0 -17
- package/dist/channels/discord.js +0 -266
- package/dist/channels/index.d.ts +0 -7
- package/dist/channels/index.js +0 -6
- package/dist/channels/loader.d.ts +0 -7
- package/dist/channels/loader.js +0 -87
- package/dist/channels/pipeline.d.ts +0 -50
- package/dist/channels/pipeline.js +0 -92
- package/dist/channels/registry.d.ts +0 -36
- package/dist/channels/registry.js +0 -80
- package/dist/channels/send-helpers.d.ts +0 -19
- package/dist/channels/send-helpers.js +0 -21
- package/dist/channels/telegram.d.ts +0 -47
- package/dist/channels/telegram.js +0 -649
- package/dist/channels/types.d.ts +0 -41
- package/dist/channels/types.js +0 -1
- package/dist/channels/voice-state.d.ts +0 -29
- package/dist/channels/voice-state.js +0 -45
- package/dist/channels/webhook.d.ts +0 -16
- package/dist/channels/webhook.js +0 -222
- package/dist/channels/whatsapp.d.ts +0 -28
- package/dist/channels/whatsapp.js +0 -323
- package/dist/cli/capabilities.d.ts +0 -3
- package/dist/cli/capabilities.js +0 -72
- package/dist/cli/channel.d.ts +0 -3
- package/dist/cli/channel.js +0 -202
- package/dist/cli/commands.d.ts +0 -15
- package/dist/cli/commands.js +0 -279
- package/dist/cli/doctor.d.ts +0 -1
- package/dist/cli/doctor.js +0 -208
- package/dist/cli/handoff.d.ts +0 -8
- package/dist/cli/handoff.js +0 -33
- package/dist/cli/helpers.d.ts +0 -2
- package/dist/cli/helpers.js +0 -21
- package/dist/cli/mcp.d.ts +0 -3
- package/dist/cli/mcp.js +0 -47
- package/dist/cli/media.d.ts +0 -2
- package/dist/cli/media.js +0 -125
- package/dist/cli/setup.d.ts +0 -1
- package/dist/cli/setup.js +0 -239
- package/dist/cli/store.d.ts +0 -3
- package/dist/cli/store.js +0 -108
- package/dist/config.d.ts +0 -11
- package/dist/config.js +0 -115
- package/dist/daemon.d.ts +0 -1
- package/dist/daemon.js +0 -345
- package/dist/dashboard/html.d.ts +0 -1
- package/dist/dashboard/html.js +0 -849
- package/dist/dashboard/routes.d.ts +0 -17
- package/dist/dashboard/routes.js +0 -623
- package/dist/dashboard/server.d.ts +0 -1
- package/dist/dashboard/server.js +0 -104
- package/dist/db/connection.d.ts +0 -29
- package/dist/db/connection.js +0 -37
- package/dist/db/index.d.ts +0 -14
- package/dist/db/index.js +0 -127
- package/dist/db/migrations.d.ts +0 -2
- package/dist/db/migrations.js +0 -384
- package/dist/delegation/manager.d.ts +0 -18
- package/dist/delegation/manager.js +0 -89
- package/dist/index.d.ts +0 -2
- package/dist/knowledge/index.d.ts +0 -2
- package/dist/knowledge/index.js +0 -1
- package/dist/knowledge/manager.d.ts +0 -17
- package/dist/knowledge/manager.js +0 -160
- package/dist/knowledge/types.d.ts +0 -7
- package/dist/knowledge/types.js +0 -1
- package/dist/mcp/handlers.d.ts +0 -37
- package/dist/mcp/handlers.js +0 -520
- package/dist/mcp/server.d.ts +0 -2
- package/dist/mcp/server.js +0 -86
- package/dist/mcp/tool-definitions.d.ts +0 -1225
- package/dist/mcp/tool-definitions.js +0 -412
- package/dist/mcp/validate.d.ts +0 -23
- package/dist/mcp/validate.js +0 -65
- package/dist/media/factory.d.ts +0 -6
- package/dist/media/factory.js +0 -36
- package/dist/media/generators/dall-e.d.ts +0 -10
- package/dist/media/generators/dall-e.js +0 -41
- package/dist/media/generators/elevenlabs-music.d.ts +0 -9
- package/dist/media/generators/elevenlabs-music.js +0 -34
- package/dist/media/generators/elevenlabs-sfx.d.ts +0 -9
- package/dist/media/generators/elevenlabs-sfx.js +0 -33
- package/dist/media/generators/kling.d.ts +0 -9
- package/dist/media/generators/kling.js +0 -47
- package/dist/media/generators/lyria.d.ts +0 -10
- package/dist/media/generators/lyria.js +0 -41
- package/dist/media/generators/nano-banana.d.ts +0 -10
- package/dist/media/generators/nano-banana.js +0 -45
- package/dist/media/generators/poll-util.d.ts +0 -12
- package/dist/media/generators/poll-util.js +0 -22
- package/dist/media/generators/recraft.d.ts +0 -9
- package/dist/media/generators/recraft.js +0 -52
- package/dist/media/generators/runway.d.ts +0 -9
- package/dist/media/generators/runway.js +0 -49
- package/dist/media/generators/stable-diffusion.d.ts +0 -9
- package/dist/media/generators/stable-diffusion.js +0 -35
- package/dist/media/generators/veo.d.ts +0 -9
- package/dist/media/generators/veo.js +0 -32
- package/dist/media/index.d.ts +0 -6
- package/dist/media/index.js +0 -8
- package/dist/media/store.d.ts +0 -17
- package/dist/media/store.js +0 -69
- package/dist/media/types.d.ts +0 -43
- package/dist/media/types.js +0 -1
- package/dist/notifications/index.d.ts +0 -4
- package/dist/notifications/index.js +0 -21
- package/dist/notifications/ntfy.d.ts +0 -9
- package/dist/notifications/ntfy.js +0 -25
- package/dist/notifications/pushover.d.ts +0 -9
- package/dist/notifications/pushover.js +0 -26
- package/dist/notifications/types.d.ts +0 -5
- package/dist/notifications/types.js +0 -1
- package/dist/notifications/webhook-provider.d.ts +0 -9
- package/dist/notifications/webhook-provider.js +0 -24
- package/dist/observability/analytics.d.ts +0 -30
- package/dist/observability/analytics.js +0 -118
- package/dist/projects/index.d.ts +0 -4
- package/dist/projects/index.js +0 -2
- package/dist/projects/manager.d.ts +0 -13
- package/dist/projects/manager.js +0 -166
- package/dist/projects/router.d.ts +0 -17
- package/dist/projects/router.js +0 -246
- package/dist/projects/types.d.ts +0 -19
- package/dist/projects/types.js +0 -1
- package/dist/service/install.d.ts +0 -4
- package/dist/service/install.js +0 -146
- package/dist/service/templates.d.ts +0 -4
- package/dist/service/templates.js +0 -52
- package/dist/service/windows.d.ts +0 -8
- package/dist/service/windows.js +0 -59
- package/dist/session/budget-guard.d.ts +0 -20
- package/dist/session/budget-guard.js +0 -31
- package/dist/session/circuit-breaker.d.ts +0 -19
- package/dist/session/circuit-breaker.js +0 -91
- package/dist/session/context-compactor.d.ts +0 -32
- package/dist/session/context-compactor.js +0 -45
- package/dist/session/context-monitor.d.ts +0 -15
- package/dist/session/context-monitor.js +0 -44
- package/dist/session/handoff.d.ts +0 -21
- package/dist/session/handoff.js +0 -50
- package/dist/session/manager.d.ts +0 -60
- package/dist/session/manager.js +0 -379
- package/dist/session/memory-store.d.ts +0 -29
- package/dist/session/memory-store.js +0 -45
- package/dist/session/message-queue.d.ts +0 -28
- package/dist/session/message-queue.js +0 -52
- package/dist/session/pending-dispatcher.d.ts +0 -31
- package/dist/session/pending-dispatcher.js +0 -120
- package/dist/session/pending-store.d.ts +0 -60
- package/dist/session/pending-store.js +0 -118
- package/dist/session/stale-session.d.ts +0 -31
- package/dist/session/stale-session.js +0 -45
- package/dist/session/subprocess.d.ts +0 -25
- package/dist/session/subprocess.js +0 -189
- package/dist/session/tab-store.d.ts +0 -28
- package/dist/session/tab-store.js +0 -78
- package/dist/tasks/scheduler.d.ts +0 -45
- package/dist/tasks/scheduler.js +0 -329
- package/dist/tasks/store.d.ts +0 -11
- package/dist/tasks/store.js +0 -103
- package/dist/timeline/index.d.ts +0 -3
- package/dist/timeline/index.js +0 -2
- package/dist/timeline/logger.d.ts +0 -8
- package/dist/timeline/logger.js +0 -11
- package/dist/timeline/query.d.ts +0 -11
- package/dist/timeline/query.js +0 -67
- package/dist/timeline/types.d.ts +0 -12
- package/dist/timeline/types.js +0 -1
- package/dist/types.d.ts +0 -216
- package/dist/types.js +0 -3
- package/dist/util/auto-heal.d.ts +0 -43
- package/dist/util/auto-heal.js +0 -107
- package/dist/util/install-info.d.ts +0 -37
- package/dist/util/install-info.js +0 -80
- package/dist/util/logger.d.ts +0 -18
- package/dist/util/logger.js +0 -118
- package/dist/util/paths.d.ts +0 -13
- package/dist/util/paths.js +0 -55
- package/dist/util/platform.d.ts +0 -2
- package/dist/util/platform.js +0 -11
- package/dist/util/progress.d.ts +0 -34
- package/dist/util/progress.js +0 -133
- package/dist/util/rate-limiter.d.ts +0 -14
- package/dist/util/rate-limiter.js +0 -50
- package/dist/util/retry.d.ts +0 -2
- package/dist/util/retry.js +0 -18
- package/dist/util/text.d.ts +0 -32
- package/dist/util/text.js +0 -101
- package/dist/version.d.ts +0 -1
- package/dist/version.js +0 -4
- package/dist/voice/index.d.ts +0 -17
- package/dist/voice/index.js +0 -42
- package/dist/voice/stt.d.ts +0 -16
- package/dist/voice/stt.js +0 -57
- package/dist/voice/tts.d.ts +0 -23
- package/dist/voice/tts.js +0 -84
- package/dist/watchers/evaluator.d.ts +0 -5
- package/dist/watchers/evaluator.js +0 -45
- package/dist/watchers/index.d.ts +0 -4
- package/dist/watchers/index.js +0 -3
- package/dist/watchers/scheduler.d.ts +0 -20
- package/dist/watchers/scheduler.js +0 -183
- package/dist/watchers/store.d.ts +0 -10
- package/dist/watchers/store.js +0 -56
- package/dist/watchers/types.d.ts +0 -15
- package/dist/watchers/types.js +0 -1
- package/scripts/postinstall.mjs +0 -50
package/dist/db/migrations.js
DELETED
|
@@ -1,384 +0,0 @@
|
|
|
1
|
-
import { logger } from '../util/logger.js';
|
|
2
|
-
/*
|
|
3
|
-
* Migration authoring conventions:
|
|
4
|
-
*
|
|
5
|
-
* - Every migration runs inside a single transaction so partial failures are
|
|
6
|
-
* atomically rolled back. Idempotency checks for ALTER TABLE ADD/DROP COLUMN
|
|
7
|
-
* are performed inline below.
|
|
8
|
-
*
|
|
9
|
-
* - For destructive reshapes (column type change, rename, etc.) follow the
|
|
10
|
-
* SQLite-recommended pattern, all in one migration so the transaction wraps
|
|
11
|
-
* it cleanly:
|
|
12
|
-
*
|
|
13
|
-
* CREATE TABLE new_X (...);
|
|
14
|
-
* INSERT INTO new_X (a, b, c) SELECT a, b, c FROM X;
|
|
15
|
-
* DROP TABLE X;
|
|
16
|
-
* ALTER TABLE new_X RENAME TO X;
|
|
17
|
-
*
|
|
18
|
-
* AVOID `DROP TABLE X; CREATE TABLE X (...)` without a copy step — migration
|
|
19
|
-
* v13 did this and silently nuked user-created rows. The audit history flags
|
|
20
|
-
* that as a one-off; do not repeat it.
|
|
21
|
-
*/
|
|
22
|
-
const MIGRATIONS = [
|
|
23
|
-
{
|
|
24
|
-
version: 2,
|
|
25
|
-
description: 'Add user_id column for multi-user support',
|
|
26
|
-
up: `
|
|
27
|
-
ALTER TABLE tabs ADD COLUMN user_id TEXT NOT NULL DEFAULT 'local';
|
|
28
|
-
ALTER TABLE memories ADD COLUMN user_id TEXT NOT NULL DEFAULT 'local';
|
|
29
|
-
`,
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
version: 3,
|
|
33
|
-
description: 'Add schema_version table',
|
|
34
|
-
up: '', // Already handled by bootstrap
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
version: 4,
|
|
38
|
-
description: 'Add cron_jobs table in SQLite',
|
|
39
|
-
up: `
|
|
40
|
-
CREATE TABLE IF NOT EXISTS cron_jobs (
|
|
41
|
-
id TEXT PRIMARY KEY,
|
|
42
|
-
name TEXT NOT NULL,
|
|
43
|
-
schedule_type TEXT NOT NULL,
|
|
44
|
-
schedule TEXT NOT NULL,
|
|
45
|
-
tab_name TEXT NOT NULL DEFAULT 'default',
|
|
46
|
-
message TEXT NOT NULL,
|
|
47
|
-
enabled INTEGER NOT NULL DEFAULT 1,
|
|
48
|
-
user_id TEXT NOT NULL DEFAULT 'local',
|
|
49
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
50
|
-
last_run_at TEXT,
|
|
51
|
-
next_run_at TEXT
|
|
52
|
-
);
|
|
53
|
-
CREATE INDEX IF NOT EXISTS idx_cron_jobs_user ON cron_jobs(user_id, enabled);
|
|
54
|
-
`,
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
version: 5,
|
|
58
|
-
description: 'Add type column to pending_messages for notifications',
|
|
59
|
-
up: `
|
|
60
|
-
ALTER TABLE pending_messages ADD COLUMN type TEXT NOT NULL DEFAULT 'message';
|
|
61
|
-
ALTER TABLE pending_messages ADD COLUMN user_id TEXT NOT NULL DEFAULT 'local';
|
|
62
|
-
`,
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
version: 6,
|
|
66
|
-
description: 'Add pipe intelligence tables (projects, preferences, permissions, routing)',
|
|
67
|
-
up: `
|
|
68
|
-
CREATE TABLE IF NOT EXISTS projects (
|
|
69
|
-
id TEXT PRIMARY KEY,
|
|
70
|
-
name TEXT NOT NULL,
|
|
71
|
-
path TEXT UNIQUE NOT NULL,
|
|
72
|
-
description TEXT DEFAULT '',
|
|
73
|
-
languages TEXT DEFAULT '[]',
|
|
74
|
-
last_used TEXT,
|
|
75
|
-
tab_name TEXT,
|
|
76
|
-
discovered_via TEXT DEFAULT 'scan',
|
|
77
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
78
|
-
updated_at TEXT DEFAULT (datetime('now'))
|
|
79
|
-
);
|
|
80
|
-
CREATE INDEX IF NOT EXISTS idx_projects_path ON projects(path);
|
|
81
|
-
CREATE INDEX IF NOT EXISTS idx_projects_name ON projects(name);
|
|
82
|
-
|
|
83
|
-
CREATE TABLE IF NOT EXISTS preferences (
|
|
84
|
-
key TEXT PRIMARY KEY,
|
|
85
|
-
value TEXT NOT NULL,
|
|
86
|
-
updated_at TEXT DEFAULT (datetime('now'))
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
CREATE TABLE IF NOT EXISTS permission_history (
|
|
90
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
91
|
-
tool_name TEXT NOT NULL,
|
|
92
|
-
tool_args_pattern TEXT NOT NULL,
|
|
93
|
-
decision TEXT NOT NULL,
|
|
94
|
-
confidence REAL DEFAULT 1.0,
|
|
95
|
-
context TEXT,
|
|
96
|
-
tab_name TEXT,
|
|
97
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
98
|
-
);
|
|
99
|
-
CREATE INDEX IF NOT EXISTS idx_permissions_tool ON permission_history(tool_name, created_at);
|
|
100
|
-
|
|
101
|
-
CREATE TABLE IF NOT EXISTS routing_history (
|
|
102
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
103
|
-
message_preview TEXT NOT NULL,
|
|
104
|
-
tab_name TEXT NOT NULL,
|
|
105
|
-
project_path TEXT,
|
|
106
|
-
confidence REAL NOT NULL,
|
|
107
|
-
was_correct INTEGER,
|
|
108
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
109
|
-
);
|
|
110
|
-
CREATE INDEX IF NOT EXISTS idx_routing_tab ON routing_history(tab_name, created_at);
|
|
111
|
-
`,
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
version: 7,
|
|
115
|
-
description: 'Add delivery tracking columns to messages',
|
|
116
|
-
up: `ALTER TABLE messages ADD COLUMN delivery_status TEXT DEFAULT 'sent';
|
|
117
|
-
ALTER TABLE messages ADD COLUMN retry_count INTEGER DEFAULT 0;`,
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
version: 8,
|
|
121
|
-
description: 'Add system_prompt column to tabs',
|
|
122
|
-
up: 'ALTER TABLE tabs ADD COLUMN system_prompt TEXT DEFAULT NULL',
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
version: 9,
|
|
126
|
-
description: 'Add users table',
|
|
127
|
-
up: `CREATE TABLE IF NOT EXISTS users (
|
|
128
|
-
id TEXT PRIMARY KEY,
|
|
129
|
-
name TEXT NOT NULL,
|
|
130
|
-
role TEXT NOT NULL DEFAULT 'user',
|
|
131
|
-
budget_usd REAL,
|
|
132
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
133
|
-
)`,
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
version: 10,
|
|
137
|
-
description: 'Add identities table for cross-channel identity',
|
|
138
|
-
up: `CREATE TABLE IF NOT EXISTS identities (
|
|
139
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
140
|
-
user_id TEXT NOT NULL REFERENCES users(id),
|
|
141
|
-
channel_id TEXT NOT NULL,
|
|
142
|
-
peer_id TEXT NOT NULL,
|
|
143
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
144
|
-
UNIQUE(channel_id, peer_id)
|
|
145
|
-
)`,
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
version: 11,
|
|
149
|
-
description: 'Add delegations table for multi-agent orchestration',
|
|
150
|
-
up: `CREATE TABLE IF NOT EXISTS delegations (
|
|
151
|
-
id TEXT PRIMARY KEY,
|
|
152
|
-
source_tab TEXT NOT NULL,
|
|
153
|
-
target_tab TEXT NOT NULL,
|
|
154
|
-
message TEXT NOT NULL,
|
|
155
|
-
return_to_tab TEXT,
|
|
156
|
-
status TEXT NOT NULL DEFAULT 'pending',
|
|
157
|
-
result TEXT,
|
|
158
|
-
depth INTEGER NOT NULL DEFAULT 0,
|
|
159
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
160
|
-
completed_at TEXT
|
|
161
|
-
)`,
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
version: 12,
|
|
165
|
-
description: 'Removed machines table (retired multi-machine scaffolding)',
|
|
166
|
-
up: '',
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
// NOTE: this migration is destructive — any user-created project rows from
|
|
170
|
-
// before v13 are lost. discoverProjects() repopulates the table on next
|
|
171
|
-
// daemon start, so in practice only manually-created projects are affected.
|
|
172
|
-
// Future destructive migrations should copy data into the new shape instead.
|
|
173
|
-
version: 13,
|
|
174
|
-
description: 'Recreate projects table with new schema (DESTRUCTIVE — see comment)',
|
|
175
|
-
up: `DROP TABLE IF EXISTS projects;
|
|
176
|
-
CREATE TABLE IF NOT EXISTS projects (
|
|
177
|
-
id TEXT PRIMARY KEY,
|
|
178
|
-
name TEXT UNIQUE NOT NULL,
|
|
179
|
-
path TEXT NOT NULL,
|
|
180
|
-
type TEXT NOT NULL DEFAULT 'user-project',
|
|
181
|
-
last_used_at TEXT DEFAULT (datetime('now')),
|
|
182
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
183
|
-
)`,
|
|
184
|
-
},
|
|
185
|
-
{
|
|
186
|
-
version: 14,
|
|
187
|
-
description: 'Add routing_preferences table',
|
|
188
|
-
up: `CREATE TABLE IF NOT EXISTS routing_preferences (
|
|
189
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
190
|
-
pattern TEXT NOT NULL,
|
|
191
|
-
project_name TEXT NOT NULL,
|
|
192
|
-
confidence REAL DEFAULT 1.0,
|
|
193
|
-
hit_count INTEGER DEFAULT 1,
|
|
194
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
195
|
-
)`,
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
version: 15,
|
|
199
|
-
description: 'Add project_id to tabs',
|
|
200
|
-
up: 'ALTER TABLE tabs ADD COLUMN project_id TEXT DEFAULT NULL',
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
version: 16,
|
|
204
|
-
description: 'Add payload_type to cron_jobs + routing pattern index',
|
|
205
|
-
up: `ALTER TABLE cron_jobs ADD COLUMN payload_type TEXT DEFAULT 'agentTurn';
|
|
206
|
-
CREATE UNIQUE INDEX IF NOT EXISTS idx_routing_pattern ON routing_preferences(pattern, project_name);`,
|
|
207
|
-
},
|
|
208
|
-
{
|
|
209
|
-
version: 17,
|
|
210
|
-
description: 'Add index on messages.created_at for date-range cost queries',
|
|
211
|
-
up: 'CREATE INDEX IF NOT EXISTS idx_messages_created_at ON messages(created_at)',
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
version: 18,
|
|
215
|
-
description: 'Rename cron_jobs table to tasks',
|
|
216
|
-
up: 'ALTER TABLE cron_jobs RENAME TO tasks',
|
|
217
|
-
},
|
|
218
|
-
{
|
|
219
|
-
version: 19,
|
|
220
|
-
description: 'Add watchers table',
|
|
221
|
-
up: `CREATE TABLE IF NOT EXISTS watchers (
|
|
222
|
-
id TEXT PRIMARY KEY,
|
|
223
|
-
name TEXT NOT NULL,
|
|
224
|
-
description TEXT,
|
|
225
|
-
check_command TEXT NOT NULL,
|
|
226
|
-
condition TEXT NOT NULL,
|
|
227
|
-
action TEXT NOT NULL DEFAULT 'notify',
|
|
228
|
-
action_details TEXT,
|
|
229
|
-
schedule TEXT NOT NULL,
|
|
230
|
-
last_check_at TEXT,
|
|
231
|
-
last_triggered_at TEXT,
|
|
232
|
-
trigger_count INTEGER DEFAULT 0,
|
|
233
|
-
enabled INTEGER DEFAULT 1,
|
|
234
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
235
|
-
)`,
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
version: 20,
|
|
239
|
-
description: 'Add activity_log table for timeline',
|
|
240
|
-
up: `CREATE TABLE IF NOT EXISTS activity_log (
|
|
241
|
-
id TEXT PRIMARY KEY,
|
|
242
|
-
event_type TEXT NOT NULL,
|
|
243
|
-
project_name TEXT,
|
|
244
|
-
tab_name TEXT,
|
|
245
|
-
summary TEXT NOT NULL,
|
|
246
|
-
details TEXT,
|
|
247
|
-
duration_ms INTEGER,
|
|
248
|
-
cost_usd REAL,
|
|
249
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
250
|
-
)`,
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
version: 21,
|
|
254
|
-
description: 'Add index on activity_log.created_at',
|
|
255
|
-
up: 'CREATE INDEX IF NOT EXISTS idx_activity_log_created ON activity_log(created_at)',
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
version: 22,
|
|
259
|
-
description: 'Add indices on memories for dedup lookups and tab-scoped reads',
|
|
260
|
-
up: `
|
|
261
|
-
CREATE INDEX IF NOT EXISTS idx_memories_content ON memories(content);
|
|
262
|
-
CREATE INDEX IF NOT EXISTS idx_memories_tab_name ON memories(tab_name, created_at);
|
|
263
|
-
`,
|
|
264
|
-
},
|
|
265
|
-
{
|
|
266
|
-
version: 23,
|
|
267
|
-
description: 'Index routing_preferences.hit_count for fast WHERE/ORDER BY in routing hot path',
|
|
268
|
-
up: 'CREATE INDEX IF NOT EXISTS idx_routing_prefs_hits ON routing_preferences(hit_count DESC)',
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
version: 24,
|
|
272
|
-
description: 'Rip out multi-user scaffolding (never enforced; everything was hardcoded user_id="local")',
|
|
273
|
-
up: `
|
|
274
|
-
DROP TABLE IF EXISTS identities;
|
|
275
|
-
DROP TABLE IF EXISTS users;
|
|
276
|
-
DROP INDEX IF EXISTS idx_cron_jobs_user;
|
|
277
|
-
ALTER TABLE tabs DROP COLUMN user_id;
|
|
278
|
-
ALTER TABLE memories DROP COLUMN user_id;
|
|
279
|
-
ALTER TABLE tasks DROP COLUMN user_id;
|
|
280
|
-
ALTER TABLE pending_messages DROP COLUMN user_id;
|
|
281
|
-
`,
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
version: 25,
|
|
285
|
-
description: 'Drop idx_memories_content — leading-wildcard LIKE cannot use a B-tree index',
|
|
286
|
-
up: 'DROP INDEX IF EXISTS idx_memories_content',
|
|
287
|
-
},
|
|
288
|
-
{
|
|
289
|
-
version: 26,
|
|
290
|
-
description: 'Add status column to pending_messages for 3-state lifecycle (pending → processing → done|failed); allow nullable tab_name for notifications',
|
|
291
|
-
up: `
|
|
292
|
-
ALTER TABLE pending_messages ADD COLUMN status TEXT NOT NULL DEFAULT 'pending';
|
|
293
|
-
UPDATE pending_messages SET status = 'done' WHERE processed = 1;
|
|
294
|
-
UPDATE pending_messages SET status = 'pending' WHERE processed = 0;
|
|
295
|
-
CREATE INDEX IF NOT EXISTS idx_pending_status_created ON pending_messages(status, created_at);
|
|
296
|
-
`,
|
|
297
|
-
},
|
|
298
|
-
{
|
|
299
|
-
version: 27,
|
|
300
|
-
description: 'Add indexes for delegations (source_tab, target_tab) to prevent scans on completion lookup',
|
|
301
|
-
up: `
|
|
302
|
-
CREATE INDEX IF NOT EXISTS idx_delegations_source ON delegations(source_tab, status);
|
|
303
|
-
CREATE INDEX IF NOT EXISTS idx_delegations_target ON delegations(target_tab, status, created_at);
|
|
304
|
-
`,
|
|
305
|
-
},
|
|
306
|
-
{
|
|
307
|
-
version: 28,
|
|
308
|
-
description: 'Add idx_tabs_working_dir for the per-message routing query that finds tabs by project path',
|
|
309
|
-
up: 'CREATE INDEX IF NOT EXISTS idx_tabs_working_dir ON tabs(working_dir, last_activity_at)',
|
|
310
|
-
},
|
|
311
|
-
];
|
|
312
|
-
export function runMigrations(db) {
|
|
313
|
-
// Ensure schema_version table exists
|
|
314
|
-
db.exec(`
|
|
315
|
-
CREATE TABLE IF NOT EXISTS schema_version (
|
|
316
|
-
version INTEGER NOT NULL DEFAULT 1
|
|
317
|
-
);
|
|
318
|
-
`);
|
|
319
|
-
// Get current version
|
|
320
|
-
let row = db.prepare('SELECT version FROM schema_version').get();
|
|
321
|
-
if (!row) {
|
|
322
|
-
db.prepare('INSERT INTO schema_version (version) VALUES (?)').run(1);
|
|
323
|
-
row = { version: 1 };
|
|
324
|
-
}
|
|
325
|
-
const currentVersion = row.version;
|
|
326
|
-
// Apply pending migrations
|
|
327
|
-
for (const migration of MIGRATIONS) {
|
|
328
|
-
if (migration.version <= currentVersion)
|
|
329
|
-
continue;
|
|
330
|
-
if (!migration.up) {
|
|
331
|
-
db.prepare('UPDATE schema_version SET version = ?').run(migration.version);
|
|
332
|
-
continue;
|
|
333
|
-
}
|
|
334
|
-
logger.info(`DB migration v${migration.version}: ${migration.description}`);
|
|
335
|
-
// Split multi-statement migrations and apply each safely
|
|
336
|
-
// (handles partial failures from previous runs where some statements succeeded)
|
|
337
|
-
const statements = migration.up
|
|
338
|
-
.split(';')
|
|
339
|
-
.map((s) => s.trim())
|
|
340
|
-
.filter((s) => s.length > 0);
|
|
341
|
-
// Wrap the whole migration in a transaction so a mid-statement failure
|
|
342
|
-
// rolls back to the pre-migration state. The schema_version bump is the
|
|
343
|
-
// final statement inside the transaction, so an aborted migration won't
|
|
344
|
-
// leave the DB in a half-applied state with the version already bumped.
|
|
345
|
-
const applyMigration = db.transaction(() => {
|
|
346
|
-
for (const stmt of statements) {
|
|
347
|
-
try {
|
|
348
|
-
// For ALTER TABLE ADD COLUMN, check if column already exists first
|
|
349
|
-
const addMatch = stmt.match(/ALTER\s+TABLE\s+(\S+)\s+ADD\s+COLUMN\s+(\S+)/i);
|
|
350
|
-
if (addMatch) {
|
|
351
|
-
const columns = db.pragma(`table_info(${addMatch[1]})`);
|
|
352
|
-
if (columns.some((c) => c.name === addMatch[2])) {
|
|
353
|
-
logger.debug(`Migration v${migration.version}: column ${addMatch[1]}.${addMatch[2]} already exists, skipping`);
|
|
354
|
-
continue;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
// For ALTER TABLE DROP COLUMN, skip if column already gone
|
|
358
|
-
const dropMatch = stmt.match(/ALTER\s+TABLE\s+(\S+)\s+DROP\s+COLUMN\s+(\S+)/i);
|
|
359
|
-
if (dropMatch) {
|
|
360
|
-
const columns = db.pragma(`table_info(${dropMatch[1]})`);
|
|
361
|
-
if (!columns.some((c) => c.name === dropMatch[2])) {
|
|
362
|
-
logger.debug(`Migration v${migration.version}: column ${dropMatch[1]}.${dropMatch[2]} already absent, skipping`);
|
|
363
|
-
continue;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
db.exec(stmt);
|
|
367
|
-
}
|
|
368
|
-
catch (err) {
|
|
369
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
370
|
-
if (msg.includes('already exists') ||
|
|
371
|
-
msg.includes('no such column') ||
|
|
372
|
-
msg.includes('no such table') ||
|
|
373
|
-
msg.includes('no such index')) {
|
|
374
|
-
logger.debug(`Migration v${migration.version}: object already in target state, skipping statement`);
|
|
375
|
-
continue;
|
|
376
|
-
}
|
|
377
|
-
throw err;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
db.prepare('UPDATE schema_version SET version = ?').run(migration.version);
|
|
381
|
-
});
|
|
382
|
-
applyMigration();
|
|
383
|
-
}
|
|
384
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export interface Delegation {
|
|
2
|
-
id: string;
|
|
3
|
-
sourceTab: string;
|
|
4
|
-
targetTab: string;
|
|
5
|
-
message: string;
|
|
6
|
-
returnToTab: string | null;
|
|
7
|
-
status: 'pending' | 'running' | 'completed' | 'failed';
|
|
8
|
-
result: string | null;
|
|
9
|
-
depth: number;
|
|
10
|
-
createdAt: string;
|
|
11
|
-
completedAt: string | null;
|
|
12
|
-
}
|
|
13
|
-
/** Create a new delegation */
|
|
14
|
-
export declare function createDelegation(sourceTab: string, targetTab: string, message: string, returnToTab?: string): Delegation;
|
|
15
|
-
/** Complete a delegation with a result */
|
|
16
|
-
export declare function completeDelegation(targetTab: string, result: string): Delegation | null;
|
|
17
|
-
/** Get pending delegations for a tab */
|
|
18
|
-
export declare function getPendingDelegations(tabName?: string): Delegation[];
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
-
import { getDb } from '../db/index.js';
|
|
3
|
-
import { logger } from '../util/logger.js';
|
|
4
|
-
const MAX_DELEGATION_DEPTH = 3;
|
|
5
|
-
const MAX_PENDING_PER_TAB = 5;
|
|
6
|
-
/** Create a new delegation */
|
|
7
|
-
export function createDelegation(sourceTab, targetTab, message, returnToTab) {
|
|
8
|
-
const db = getDb();
|
|
9
|
-
// Check depth limit
|
|
10
|
-
const sourceDepth = getCurrentDepth(sourceTab);
|
|
11
|
-
if (sourceDepth >= MAX_DELEGATION_DEPTH) {
|
|
12
|
-
throw new Error(`Delegation depth limit reached (max ${MAX_DELEGATION_DEPTH}). Tab "${sourceTab}" cannot delegate further.`);
|
|
13
|
-
}
|
|
14
|
-
// Check pending limit
|
|
15
|
-
const pending = db
|
|
16
|
-
.prepare("SELECT COUNT(*) as c FROM delegations WHERE source_tab = ? AND status IN ('pending', 'running')")
|
|
17
|
-
.get(sourceTab).c;
|
|
18
|
-
if (pending >= MAX_PENDING_PER_TAB) {
|
|
19
|
-
throw new Error(`Too many pending delegations for tab "${sourceTab}" (max ${MAX_PENDING_PER_TAB}).`);
|
|
20
|
-
}
|
|
21
|
-
const id = uuidv4();
|
|
22
|
-
const delegation = {
|
|
23
|
-
id,
|
|
24
|
-
sourceTab,
|
|
25
|
-
targetTab,
|
|
26
|
-
message,
|
|
27
|
-
returnToTab: returnToTab || sourceTab,
|
|
28
|
-
status: 'pending',
|
|
29
|
-
result: null,
|
|
30
|
-
depth: sourceDepth + 1,
|
|
31
|
-
createdAt: new Date().toISOString(),
|
|
32
|
-
completedAt: null,
|
|
33
|
-
};
|
|
34
|
-
db.prepare('INSERT INTO delegations (id, source_tab, target_tab, message, return_to_tab, status, depth) VALUES (?, ?, ?, ?, ?, ?, ?)').run(id, sourceTab, targetTab, message, delegation.returnToTab, 'pending', delegation.depth);
|
|
35
|
-
logger.info(`Delegation created: ${sourceTab} → ${targetTab} (depth ${delegation.depth})`);
|
|
36
|
-
return delegation;
|
|
37
|
-
}
|
|
38
|
-
/** Complete a delegation with a result */
|
|
39
|
-
export function completeDelegation(targetTab, result) {
|
|
40
|
-
const db = getDb();
|
|
41
|
-
// Find the most recent pending/running delegation to this tab
|
|
42
|
-
const row = db
|
|
43
|
-
.prepare("SELECT * FROM delegations WHERE target_tab = ? AND status IN ('pending', 'running') ORDER BY created_at DESC LIMIT 1")
|
|
44
|
-
.get(targetTab);
|
|
45
|
-
if (!row)
|
|
46
|
-
return null;
|
|
47
|
-
db.prepare("UPDATE delegations SET status = 'completed', result = ?, completed_at = datetime('now') WHERE id = ?").run(result.slice(0, 50000), row.id); // Cap result at 50KB
|
|
48
|
-
logger.info(`Delegation completed: ${row.source_tab} → ${row.target_tab}`);
|
|
49
|
-
return {
|
|
50
|
-
id: row.id,
|
|
51
|
-
sourceTab: row.source_tab,
|
|
52
|
-
targetTab: row.target_tab,
|
|
53
|
-
message: row.message,
|
|
54
|
-
returnToTab: row.return_to_tab,
|
|
55
|
-
status: 'completed',
|
|
56
|
-
result,
|
|
57
|
-
depth: row.depth,
|
|
58
|
-
createdAt: row.created_at,
|
|
59
|
-
completedAt: new Date().toISOString(),
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
/** Get pending delegations for a tab */
|
|
63
|
-
export function getPendingDelegations(tabName) {
|
|
64
|
-
const db = getDb();
|
|
65
|
-
const query = tabName
|
|
66
|
-
? "SELECT * FROM delegations WHERE source_tab = ? AND status IN ('pending', 'running') ORDER BY created_at"
|
|
67
|
-
: "SELECT * FROM delegations WHERE status IN ('pending', 'running') ORDER BY created_at";
|
|
68
|
-
const rows = tabName ? db.prepare(query).all(tabName) : db.prepare(query).all();
|
|
69
|
-
return rows.map((r) => ({
|
|
70
|
-
id: r.id,
|
|
71
|
-
sourceTab: r.source_tab,
|
|
72
|
-
targetTab: r.target_tab,
|
|
73
|
-
message: r.message,
|
|
74
|
-
returnToTab: r.return_to_tab,
|
|
75
|
-
status: r.status,
|
|
76
|
-
result: r.result,
|
|
77
|
-
depth: r.depth,
|
|
78
|
-
createdAt: r.created_at,
|
|
79
|
-
completedAt: r.completed_at,
|
|
80
|
-
}));
|
|
81
|
-
}
|
|
82
|
-
/** Get current delegation depth for a tab */
|
|
83
|
-
function getCurrentDepth(tabName) {
|
|
84
|
-
const db = getDb();
|
|
85
|
-
const row = db
|
|
86
|
-
.prepare("SELECT MAX(depth) as d FROM delegations WHERE source_tab = ? AND status IN ('pending', 'running')")
|
|
87
|
-
.get(tabName);
|
|
88
|
-
return row.d ?? 0;
|
|
89
|
-
}
|
package/dist/index.d.ts
DELETED
package/dist/knowledge/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { getGlobalKnowledge, addGlobalKnowledge, getProjectKnowledge, addProjectKnowledge, getTabKnowledge, getAllKnowledge, formatKnowledgeForContext, addKnowledge, searchKnowledge, } from './manager.js';
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { KnowledgeEntry, KnowledgeScope } from './types.js';
|
|
2
|
-
export declare function getGlobalKnowledge(): KnowledgeEntry[];
|
|
3
|
-
export declare function addGlobalKnowledge(content: string, category?: string): void;
|
|
4
|
-
export declare function getProjectKnowledge(projectPath: string): KnowledgeEntry[];
|
|
5
|
-
export declare function addProjectKnowledge(projectPath: string, content: string): void;
|
|
6
|
-
export declare function getTabKnowledge(tabName: string): KnowledgeEntry[];
|
|
7
|
-
export declare function getAllKnowledge(projectPath?: string, tabName?: string): KnowledgeEntry[];
|
|
8
|
-
/** Format knowledge for injection into Claude's context */
|
|
9
|
-
export declare function formatKnowledgeForContext(entries: KnowledgeEntry[]): string;
|
|
10
|
-
/** Add knowledge to the right scope */
|
|
11
|
-
export declare function addKnowledge(content: string, scope: KnowledgeScope, options?: {
|
|
12
|
-
projectPath?: string;
|
|
13
|
-
tabName?: string;
|
|
14
|
-
category?: string;
|
|
15
|
-
}): void;
|
|
16
|
-
/** Search knowledge across all layers */
|
|
17
|
-
export declare function searchKnowledge(query: string, projectPath?: string, tabName?: string): KnowledgeEntry[];
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { getDb } from '../db/index.js';
|
|
4
|
-
import { getBeecorkHome } from '../util/paths.js';
|
|
5
|
-
import { logger } from '../util/logger.js';
|
|
6
|
-
const GLOBAL_KNOWLEDGE_DIR = path.join(getBeecorkHome(), 'knowledge');
|
|
7
|
-
const GLOBAL_CATEGORIES = ['people', 'preferences', 'routines', 'general'];
|
|
8
|
-
/** Ensure global knowledge directory exists */
|
|
9
|
-
function ensureGlobalDir() {
|
|
10
|
-
fs.mkdirSync(GLOBAL_KNOWLEDGE_DIR, { recursive: true, mode: 0o700 });
|
|
11
|
-
}
|
|
12
|
-
const knowledgeCache = new Map();
|
|
13
|
-
/** Read a knowledge file with mtime-based caching, return content or empty string */
|
|
14
|
-
function readKnowledgeCached(filePath) {
|
|
15
|
-
// Skip the existsSync precheck — fs.statSync throws ENOENT on missing files,
|
|
16
|
-
// catching that gets us the same fall-through. This halves the syscall count
|
|
17
|
-
// on every Claude message that triggers knowledge injection.
|
|
18
|
-
try {
|
|
19
|
-
const stat = fs.statSync(filePath);
|
|
20
|
-
const cached = knowledgeCache.get(filePath);
|
|
21
|
-
if (cached && cached.mtime === stat.mtimeMs)
|
|
22
|
-
return cached.content;
|
|
23
|
-
const content = fs.readFileSync(filePath, 'utf-8');
|
|
24
|
-
knowledgeCache.set(filePath, { content, mtime: stat.mtimeMs });
|
|
25
|
-
return content;
|
|
26
|
-
}
|
|
27
|
-
catch (err) {
|
|
28
|
-
if (err?.code === 'ENOENT')
|
|
29
|
-
return '';
|
|
30
|
-
logger.warn(`Failed to read knowledge file ${filePath}:`, err);
|
|
31
|
-
return '';
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
/** Append to a knowledge file */
|
|
35
|
-
function appendToFile(filePath, content) {
|
|
36
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o700 });
|
|
37
|
-
const existing = readKnowledgeCached(filePath);
|
|
38
|
-
const separator = existing.endsWith('\n') || existing === '' ? '' : '\n';
|
|
39
|
-
fs.writeFileSync(filePath, existing + separator + content + '\n', { mode: 0o600 });
|
|
40
|
-
try {
|
|
41
|
-
fs.chmodSync(filePath, 0o600);
|
|
42
|
-
}
|
|
43
|
-
catch {
|
|
44
|
-
/* not fatal */
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
// ─── Layer 1: Global Knowledge ───
|
|
48
|
-
export function getGlobalKnowledge() {
|
|
49
|
-
ensureGlobalDir();
|
|
50
|
-
const entries = [];
|
|
51
|
-
for (const category of GLOBAL_CATEGORIES) {
|
|
52
|
-
const filePath = path.join(GLOBAL_KNOWLEDGE_DIR, `${category}.md`);
|
|
53
|
-
const content = readKnowledgeCached(filePath);
|
|
54
|
-
if (content.trim()) {
|
|
55
|
-
entries.push({ content, scope: 'global', source: `${category}.md`, category });
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return entries;
|
|
59
|
-
}
|
|
60
|
-
export function addGlobalKnowledge(content, category = 'general') {
|
|
61
|
-
ensureGlobalDir();
|
|
62
|
-
const validCategory = GLOBAL_CATEGORIES.includes(category) ? category : 'general';
|
|
63
|
-
const filePath = path.join(GLOBAL_KNOWLEDGE_DIR, `${validCategory}.md`);
|
|
64
|
-
appendToFile(filePath, content);
|
|
65
|
-
logger.info(`Global knowledge added to ${validCategory}.md`);
|
|
66
|
-
}
|
|
67
|
-
// ─── Layer 2: Project Knowledge ───
|
|
68
|
-
export function getProjectKnowledge(projectPath) {
|
|
69
|
-
const filePath = path.join(projectPath, '.beecork', 'knowledge.md');
|
|
70
|
-
const content = readKnowledgeCached(filePath);
|
|
71
|
-
if (!content.trim())
|
|
72
|
-
return [];
|
|
73
|
-
return [{ content, scope: 'project', source: filePath }];
|
|
74
|
-
}
|
|
75
|
-
export function addProjectKnowledge(projectPath, content) {
|
|
76
|
-
const filePath = path.join(projectPath, '.beecork', 'knowledge.md');
|
|
77
|
-
appendToFile(filePath, content);
|
|
78
|
-
logger.info(`Project knowledge added to ${filePath}`);
|
|
79
|
-
}
|
|
80
|
-
// ─── Layer 3: Tab Knowledge (database) ───
|
|
81
|
-
export function getTabKnowledge(tabName) {
|
|
82
|
-
const db = getDb();
|
|
83
|
-
const rows = db
|
|
84
|
-
.prepare('SELECT content FROM memories WHERE tab_name = ? ORDER BY created_at DESC LIMIT 50')
|
|
85
|
-
.all(tabName);
|
|
86
|
-
return rows.map((r) => ({ content: r.content, scope: 'tab', source: tabName }));
|
|
87
|
-
}
|
|
88
|
-
// ─── Combined Knowledge ───
|
|
89
|
-
export function getAllKnowledge(projectPath, tabName) {
|
|
90
|
-
const entries = [];
|
|
91
|
-
// Layer 1: Global
|
|
92
|
-
entries.push(...getGlobalKnowledge());
|
|
93
|
-
// Layer 2: Project (if provided)
|
|
94
|
-
if (projectPath) {
|
|
95
|
-
entries.push(...getProjectKnowledge(projectPath));
|
|
96
|
-
}
|
|
97
|
-
// Layer 3: Tab (if provided)
|
|
98
|
-
if (tabName) {
|
|
99
|
-
entries.push(...getTabKnowledge(tabName));
|
|
100
|
-
}
|
|
101
|
-
return entries;
|
|
102
|
-
}
|
|
103
|
-
/** Format knowledge for injection into Claude's context */
|
|
104
|
-
export function formatKnowledgeForContext(entries) {
|
|
105
|
-
if (entries.length === 0)
|
|
106
|
-
return '';
|
|
107
|
-
const sections = [];
|
|
108
|
-
const global = entries.filter((e) => e.scope === 'global');
|
|
109
|
-
if (global.length > 0) {
|
|
110
|
-
sections.push('[Your knowledge (global)]');
|
|
111
|
-
for (const entry of global) {
|
|
112
|
-
if (entry.category)
|
|
113
|
-
sections.push(`[${entry.category}]`);
|
|
114
|
-
sections.push(entry.content);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
const project = entries.filter((e) => e.scope === 'project');
|
|
118
|
-
if (project.length > 0) {
|
|
119
|
-
sections.push('\n[Project knowledge]');
|
|
120
|
-
for (const entry of project) {
|
|
121
|
-
sections.push(entry.content);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
const tab = entries.filter((e) => e.scope === 'tab');
|
|
125
|
-
if (tab.length > 0) {
|
|
126
|
-
sections.push('\n[Context from memory]');
|
|
127
|
-
for (const entry of tab) {
|
|
128
|
-
sections.push(`- ${entry.content}`);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return sections.join('\n');
|
|
132
|
-
}
|
|
133
|
-
/** Add knowledge to the right scope */
|
|
134
|
-
export function addKnowledge(content, scope, options) {
|
|
135
|
-
switch (scope) {
|
|
136
|
-
case 'global':
|
|
137
|
-
addGlobalKnowledge(content, options?.category);
|
|
138
|
-
break;
|
|
139
|
-
case 'project':
|
|
140
|
-
if (!options?.projectPath)
|
|
141
|
-
throw new Error('projectPath required for project scope');
|
|
142
|
-
addProjectKnowledge(options.projectPath, content);
|
|
143
|
-
break;
|
|
144
|
-
case 'tab': {
|
|
145
|
-
// Use existing memory system. Inline INSERT here (rather than the
|
|
146
|
-
// MemoryStore wrapper) because knowledge → session would invert the
|
|
147
|
-
// module dep direction; the schema duplication is one column list and
|
|
148
|
-
// the shape is stable.
|
|
149
|
-
const db = getDb();
|
|
150
|
-
db.prepare('INSERT INTO memories (content, tab_name, source) VALUES (?, ?, ?)').run(content, options?.tabName || null, 'tool');
|
|
151
|
-
break;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
/** Search knowledge across all layers */
|
|
156
|
-
export function searchKnowledge(query, projectPath, tabName) {
|
|
157
|
-
const all = getAllKnowledge(projectPath, tabName);
|
|
158
|
-
const lower = query.toLowerCase();
|
|
159
|
-
return all.filter((e) => e.content.toLowerCase().includes(lower));
|
|
160
|
-
}
|