@askexenow/exe-os 0.8.80 → 0.8.82

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.
Files changed (110) hide show
  1. package/dist/bin/backfill-conversations.js +359 -267
  2. package/dist/bin/backfill-responses.js +357 -265
  3. package/dist/bin/backfill-vectors.js +339 -264
  4. package/dist/bin/cleanup-stale-review-tasks.js +315 -256
  5. package/dist/bin/cli.js +494 -240
  6. package/dist/bin/exe-agent.js +141 -46
  7. package/dist/bin/exe-assign.js +151 -63
  8. package/dist/bin/exe-boot.js +294 -115
  9. package/dist/bin/exe-call.js +76 -51
  10. package/dist/bin/exe-cloud.js +58 -45
  11. package/dist/bin/exe-dispatch.js +434 -277
  12. package/dist/bin/exe-doctor.js +317 -246
  13. package/dist/bin/exe-export-behaviors.js +328 -248
  14. package/dist/bin/exe-forget.js +314 -231
  15. package/dist/bin/exe-gateway.js +2676 -1402
  16. package/dist/bin/exe-heartbeat.js +329 -264
  17. package/dist/bin/exe-kill.js +324 -244
  18. package/dist/bin/exe-launch-agent.js +574 -463
  19. package/dist/bin/exe-link.js +1055 -95
  20. package/dist/bin/exe-new-employee.js +49 -54
  21. package/dist/bin/exe-pending-messages.js +310 -253
  22. package/dist/bin/exe-pending-notifications.js +299 -228
  23. package/dist/bin/exe-pending-reviews.js +314 -245
  24. package/dist/bin/exe-rename.js +259 -195
  25. package/dist/bin/exe-review.js +140 -64
  26. package/dist/bin/exe-search.js +543 -356
  27. package/dist/bin/exe-session-cleanup.js +463 -382
  28. package/dist/bin/exe-settings.js +129 -99
  29. package/dist/bin/exe-start.sh +6 -6
  30. package/dist/bin/exe-status.js +95 -36
  31. package/dist/bin/exe-team.js +116 -51
  32. package/dist/bin/git-sweep.js +482 -307
  33. package/dist/bin/graph-backfill.js +357 -245
  34. package/dist/bin/graph-export.js +324 -244
  35. package/dist/bin/install.js +33 -10
  36. package/dist/bin/scan-tasks.js +481 -307
  37. package/dist/bin/setup.js +1147 -140
  38. package/dist/bin/shard-migrate.js +321 -241
  39. package/dist/bin/update.js +1 -7
  40. package/dist/bin/wiki-sync.js +318 -238
  41. package/dist/gateway/index.js +2656 -1383
  42. package/dist/hooks/bug-report-worker.js +641 -472
  43. package/dist/hooks/commit-complete.js +482 -307
  44. package/dist/hooks/error-recall.js +363 -135
  45. package/dist/hooks/exe-heartbeat-hook.js +97 -27
  46. package/dist/hooks/ingest-worker.js +584 -397
  47. package/dist/hooks/ingest.js +123 -58
  48. package/dist/hooks/instructions-loaded.js +212 -82
  49. package/dist/hooks/notification.js +200 -70
  50. package/dist/hooks/post-compact.js +199 -81
  51. package/dist/hooks/pre-compact.js +352 -140
  52. package/dist/hooks/pre-tool-use.js +416 -278
  53. package/dist/hooks/prompt-ingest-worker.js +376 -299
  54. package/dist/hooks/prompt-submit.js +414 -188
  55. package/dist/hooks/response-ingest-worker.js +408 -338
  56. package/dist/hooks/session-end.js +209 -83
  57. package/dist/hooks/session-start.js +382 -158
  58. package/dist/hooks/stop.js +209 -83
  59. package/dist/hooks/subagent-stop.js +209 -85
  60. package/dist/hooks/summary-worker.js +606 -510
  61. package/dist/index.js +2133 -855
  62. package/dist/lib/cloud-sync.js +1175 -184
  63. package/dist/lib/config.js +1 -9
  64. package/dist/lib/consolidation.js +71 -34
  65. package/dist/lib/database.js +166 -14
  66. package/dist/lib/device-registry.js +189 -117
  67. package/dist/lib/embedder.js +6 -10
  68. package/dist/lib/employee-templates.js +134 -39
  69. package/dist/lib/employees.js +30 -7
  70. package/dist/lib/exe-daemon-client.js +5 -7
  71. package/dist/lib/exe-daemon.js +514 -152
  72. package/dist/lib/hybrid-search.js +543 -356
  73. package/dist/lib/identity-templates.js +15 -15
  74. package/dist/lib/identity.js +19 -15
  75. package/dist/lib/license.js +1 -7
  76. package/dist/lib/messaging.js +157 -135
  77. package/dist/lib/reminders.js +97 -0
  78. package/dist/lib/schedules.js +302 -231
  79. package/dist/lib/skill-learning.js +33 -27
  80. package/dist/lib/status-brief.js +11 -14
  81. package/dist/lib/store.js +326 -237
  82. package/dist/lib/task-router.js +105 -1
  83. package/dist/lib/tasks.js +233 -116
  84. package/dist/lib/tmux-routing.js +173 -56
  85. package/dist/lib/ws-client.js +13 -3
  86. package/dist/mcp/server.js +2009 -1015
  87. package/dist/mcp/tools/complete-reminder.js +97 -0
  88. package/dist/mcp/tools/create-reminder.js +97 -0
  89. package/dist/mcp/tools/create-task.js +426 -262
  90. package/dist/mcp/tools/deactivate-behavior.js +119 -44
  91. package/dist/mcp/tools/list-reminders.js +97 -0
  92. package/dist/mcp/tools/list-tasks.js +56 -57
  93. package/dist/mcp/tools/send-message.js +206 -143
  94. package/dist/mcp/tools/update-task.js +259 -85
  95. package/dist/runtime/index.js +495 -316
  96. package/dist/tui/App.js +1128 -919
  97. package/package.json +2 -10
  98. package/src/commands/exe/afk.md +8 -8
  99. package/src/commands/exe/assign.md +1 -1
  100. package/src/commands/exe/build-adv.md +1 -1
  101. package/src/commands/exe/call.md +10 -10
  102. package/src/commands/exe/employee-heartbeat.md +9 -6
  103. package/src/commands/exe/heartbeat.md +5 -5
  104. package/src/commands/exe/intercom.md +26 -15
  105. package/src/commands/exe/launch.md +2 -2
  106. package/src/commands/exe/new-employee.md +1 -1
  107. package/src/commands/exe/review.md +2 -2
  108. package/src/commands/exe/schedule.md +1 -1
  109. package/src/commands/exe/sessions.md +2 -2
  110. package/src/commands/exe.md +22 -20
@@ -23,7 +23,6 @@ var EXE_AI_DIR = resolveDataDir();
23
23
  var DB_PATH = path.join(EXE_AI_DIR, "memories.db");
24
24
  var MODELS_DIR = path.join(EXE_AI_DIR, "models");
25
25
  var CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
26
- var COO_AGENT_NAME = "exe";
27
26
  var LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
28
27
  var CURRENT_CONFIG_VERSION = 1;
29
28
  var DEFAULT_CONFIG = {
@@ -59,13 +58,7 @@ var DEFAULT_CONFIG = {
59
58
  wikiUrl: "",
60
59
  wikiApiKey: "",
61
60
  wikiSyncIntervalMs: 30 * 60 * 1e3,
62
- wikiWorkspaceMapping: {
63
- exe: "Executive",
64
- yoshi: "Engineering",
65
- mari: "Marketing",
66
- tom: "Engineering",
67
- sasha: "Production"
68
- },
61
+ wikiWorkspaceMapping: {},
69
62
  wikiAutoUpdate: true,
70
63
  wikiAutoUpdateThreshold: 0.5,
71
64
  wikiAutoUpdateCreateNew: true,
@@ -226,7 +219,6 @@ async function loadConfigFrom(configPath) {
226
219
  export {
227
220
  CONFIG_MIGRATIONS,
228
221
  CONFIG_PATH,
229
- COO_AGENT_NAME,
230
222
  CURRENT_CONFIG_VERSION,
231
223
  DB_PATH,
232
224
  EXE_AI_DIR,
@@ -10,26 +10,17 @@ var init_db_retry = __esm({
10
10
  }
11
11
  });
12
12
 
13
- // src/lib/database.ts
14
- import { createClient } from "@libsql/client";
15
- var init_database = __esm({
16
- "src/lib/database.ts"() {
17
- "use strict";
18
- init_db_retry();
19
- }
20
- });
21
-
22
13
  // src/lib/config.ts
23
- import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, chmod as chmod2 } from "fs/promises";
24
- import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
25
- import path2 from "path";
26
- import os2 from "os";
14
+ import { readFile, writeFile, mkdir, chmod } from "fs/promises";
15
+ import { readFileSync, existsSync, renameSync } from "fs";
16
+ import path from "path";
17
+ import os from "os";
27
18
  function resolveDataDir() {
28
19
  if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
29
20
  if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
30
- const newDir = path2.join(os2.homedir(), ".exe-os");
31
- const legacyDir = path2.join(os2.homedir(), ".exe-mem");
32
- if (!existsSync2(newDir) && existsSync2(legacyDir)) {
21
+ const newDir = path.join(os.homedir(), ".exe-os");
22
+ const legacyDir = path.join(os.homedir(), ".exe-mem");
23
+ if (!existsSync(newDir) && existsSync(legacyDir)) {
33
24
  try {
34
25
  renameSync(legacyDir, newDir);
35
26
  process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
@@ -45,10 +36,10 @@ var init_config = __esm({
45
36
  "src/lib/config.ts"() {
46
37
  "use strict";
47
38
  EXE_AI_DIR = resolveDataDir();
48
- DB_PATH = path2.join(EXE_AI_DIR, "memories.db");
49
- MODELS_DIR = path2.join(EXE_AI_DIR, "models");
50
- CONFIG_PATH = path2.join(EXE_AI_DIR, "config.json");
51
- LEGACY_LANCE_PATH = path2.join(EXE_AI_DIR, "local.lance");
39
+ DB_PATH = path.join(EXE_AI_DIR, "memories.db");
40
+ MODELS_DIR = path.join(EXE_AI_DIR, "models");
41
+ CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
42
+ LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
52
43
  CURRENT_CONFIG_VERSION = 1;
53
44
  DEFAULT_CONFIG = {
54
45
  config_version: CURRENT_CONFIG_VERSION,
@@ -83,13 +74,7 @@ var init_config = __esm({
83
74
  wikiUrl: "",
84
75
  wikiApiKey: "",
85
76
  wikiSyncIntervalMs: 30 * 60 * 1e3,
86
- wikiWorkspaceMapping: {
87
- exe: "Executive",
88
- yoshi: "Engineering",
89
- mari: "Marketing",
90
- tom: "Engineering",
91
- sasha: "Production"
92
- },
77
+ wikiWorkspaceMapping: {},
93
78
  wikiAutoUpdate: true,
94
79
  wikiAutoUpdateThreshold: 0.5,
95
80
  wikiAutoUpdateCreateNew: true,
@@ -116,6 +101,57 @@ var init_config = __esm({
116
101
  }
117
102
  });
118
103
 
104
+ // src/lib/employees.ts
105
+ import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
106
+ import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
107
+ import { execSync } from "child_process";
108
+ import path2 from "path";
109
+ import os2 from "os";
110
+ function normalizeRole(role) {
111
+ return (role ?? "").trim().toLowerCase();
112
+ }
113
+ function isCoordinatorRole(role) {
114
+ return normalizeRole(role) === normalizeRole(COORDINATOR_ROLE);
115
+ }
116
+ function getCoordinatorEmployee(employees) {
117
+ return employees.find((e) => isCoordinatorRole(e.role));
118
+ }
119
+ function getCoordinatorName(employees = loadEmployeesSync()) {
120
+ return getCoordinatorEmployee(employees)?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
121
+ }
122
+ function isCoordinatorName(agentName, employees = loadEmployeesSync()) {
123
+ if (!agentName) return false;
124
+ return agentName.toLowerCase() === getCoordinatorName(employees).toLowerCase();
125
+ }
126
+ function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
127
+ if (!existsSync2(employeesPath)) return [];
128
+ try {
129
+ return JSON.parse(readFileSync2(employeesPath, "utf-8"));
130
+ } catch {
131
+ return [];
132
+ }
133
+ }
134
+ var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE;
135
+ var init_employees = __esm({
136
+ "src/lib/employees.ts"() {
137
+ "use strict";
138
+ init_config();
139
+ EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
140
+ DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
141
+ COORDINATOR_ROLE = "COO";
142
+ }
143
+ });
144
+
145
+ // src/lib/database.ts
146
+ import { createClient } from "@libsql/client";
147
+ var init_database = __esm({
148
+ "src/lib/database.ts"() {
149
+ "use strict";
150
+ init_db_retry();
151
+ init_employees();
152
+ }
153
+ });
154
+
119
155
  // src/lib/consolidation.ts
120
156
  import { randomUUID } from "crypto";
121
157
 
@@ -123,10 +159,10 @@ import { randomUUID } from "crypto";
123
159
  init_database();
124
160
 
125
161
  // src/lib/keychain.ts
126
- import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
127
- import { existsSync } from "fs";
128
- import path from "path";
129
- import os from "os";
162
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
163
+ import { existsSync as existsSync3 } from "fs";
164
+ import path3 from "path";
165
+ import os3 from "os";
130
166
 
131
167
  // src/lib/store.ts
132
168
  init_config();
@@ -187,6 +223,7 @@ function vectorToBlob(vector) {
187
223
  }
188
224
 
189
225
  // src/lib/consolidation.ts
226
+ init_employees();
190
227
  async function selectUnconsolidated(client, limit = 200) {
191
228
  const result = await client.execute({
192
229
  sql: `SELECT id, agent_id, project_name, tool_name, raw_text, timestamp
@@ -423,8 +460,8 @@ async function runConsolidation(client, options) {
423
460
  if (clustersProcessed >= options.maxCalls) break;
424
461
  if (cluster.memories.length < 3) continue;
425
462
  try {
426
- const isExe = cluster.agentId === "exe";
427
- if (isExe) {
463
+ const isCoordinator = cluster.agentId === "exe" || isCoordinatorName(cluster.agentId);
464
+ if (isCoordinator) {
428
465
  const synthesis = await consolidateCluster(cluster, options.model);
429
466
  if (!synthesis.trim()) continue;
430
467
  const result = await storeConsolidation(client, cluster, synthesis, options.embedFn);
@@ -453,7 +490,7 @@ async function runConsolidation(client, options) {
453
490
  if (dedupCount === 0) continue;
454
491
  }
455
492
  clustersProcessed++;
456
- memoriesConsolidated += isExe ? cluster.memories.length : 0;
493
+ memoriesConsolidated += isCoordinator ? cluster.memories.length : 0;
457
494
  } catch (err) {
458
495
  process.stderr.write(
459
496
  `[consolidation] Cluster failed (${cluster.projectName}/${cluster.dateRange}): ${err instanceof Error ? err.message : String(err)}
@@ -43,13 +43,130 @@ function wrapWithRetry(client) {
43
43
  return (sql) => retryOnBusy(() => target.execute(sql), "execute");
44
44
  }
45
45
  if (prop === "batch") {
46
- return (stmts) => retryOnBusy(() => target.batch(stmts), "batch");
46
+ return (stmts, mode) => retryOnBusy(() => target.batch(stmts, mode), "batch");
47
47
  }
48
48
  return Reflect.get(target, prop, receiver);
49
49
  }
50
50
  });
51
51
  }
52
52
 
53
+ // src/lib/employees.ts
54
+ import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
55
+ import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
56
+ import { execSync } from "child_process";
57
+ import path2 from "path";
58
+ import os2 from "os";
59
+
60
+ // src/lib/config.ts
61
+ import { readFile, writeFile, mkdir, chmod } from "fs/promises";
62
+ import { readFileSync, existsSync, renameSync } from "fs";
63
+ import path from "path";
64
+ import os from "os";
65
+ function resolveDataDir() {
66
+ if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
67
+ if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
68
+ const newDir = path.join(os.homedir(), ".exe-os");
69
+ const legacyDir = path.join(os.homedir(), ".exe-mem");
70
+ if (!existsSync(newDir) && existsSync(legacyDir)) {
71
+ try {
72
+ renameSync(legacyDir, newDir);
73
+ process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
74
+ `);
75
+ } catch {
76
+ return legacyDir;
77
+ }
78
+ }
79
+ return newDir;
80
+ }
81
+ var EXE_AI_DIR = resolveDataDir();
82
+ var DB_PATH = path.join(EXE_AI_DIR, "memories.db");
83
+ var MODELS_DIR = path.join(EXE_AI_DIR, "models");
84
+ var CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
85
+ var LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
86
+ var CURRENT_CONFIG_VERSION = 1;
87
+ var DEFAULT_CONFIG = {
88
+ config_version: CURRENT_CONFIG_VERSION,
89
+ dbPath: DB_PATH,
90
+ modelFile: "jina-embeddings-v5-small-q4_k_m.gguf",
91
+ embeddingDim: 1024,
92
+ batchSize: 20,
93
+ flushIntervalMs: 1e4,
94
+ autoIngestion: true,
95
+ autoRetrieval: true,
96
+ searchMode: "hybrid",
97
+ hookSearchMode: "hybrid",
98
+ fileGrepEnabled: true,
99
+ splashEffect: true,
100
+ consolidationEnabled: true,
101
+ consolidationIntervalMs: 6 * 60 * 60 * 1e3,
102
+ consolidationModel: "claude-haiku-4-5-20251001",
103
+ consolidationMaxCallsPerRun: 20,
104
+ selfQueryRouter: true,
105
+ selfQueryModel: "claude-haiku-4-5-20251001",
106
+ rerankerEnabled: true,
107
+ scalingRoadmap: {
108
+ rerankerAutoTrigger: {
109
+ enabled: true,
110
+ broadQueryMinCardinality: 5e4,
111
+ fetchTopK: 150,
112
+ returnTopK: 5
113
+ }
114
+ },
115
+ graphRagEnabled: true,
116
+ wikiEnabled: false,
117
+ wikiUrl: "",
118
+ wikiApiKey: "",
119
+ wikiSyncIntervalMs: 30 * 60 * 1e3,
120
+ wikiWorkspaceMapping: {},
121
+ wikiAutoUpdate: true,
122
+ wikiAutoUpdateThreshold: 0.5,
123
+ wikiAutoUpdateCreateNew: true,
124
+ skillLearning: true,
125
+ skillThreshold: 3,
126
+ skillModel: "claude-haiku-4-5-20251001",
127
+ exeHeartbeat: {
128
+ enabled: true,
129
+ intervalSeconds: 60,
130
+ staleInProgressThresholdHours: 2
131
+ },
132
+ sessionLifecycle: {
133
+ idleKillEnabled: true,
134
+ idleKillTicksRequired: 3,
135
+ idleKillIntercomAckWindowMs: 1e4,
136
+ maxAutoInstances: 10
137
+ },
138
+ autoUpdate: {
139
+ checkOnBoot: true,
140
+ autoInstall: false,
141
+ checkIntervalMs: 24 * 60 * 60 * 1e3
142
+ }
143
+ };
144
+
145
+ // src/lib/employees.ts
146
+ var EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
147
+ var DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
148
+ var COORDINATOR_ROLE = "COO";
149
+ function normalizeRole(role) {
150
+ return (role ?? "").trim().toLowerCase();
151
+ }
152
+ function isCoordinatorRole(role) {
153
+ return normalizeRole(role) === normalizeRole(COORDINATOR_ROLE);
154
+ }
155
+ function getCoordinatorEmployee(employees) {
156
+ return employees.find((e) => isCoordinatorRole(e.role));
157
+ }
158
+ function getCoordinatorName(employees = loadEmployeesSync()) {
159
+ return getCoordinatorEmployee(employees)?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
160
+ }
161
+ function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
162
+ if (!existsSync2(employeesPath)) return [];
163
+ try {
164
+ return JSON.parse(readFileSync2(employeesPath, "utf-8"));
165
+ } catch {
166
+ return [];
167
+ }
168
+ }
169
+
53
170
  // src/lib/database.ts
54
171
  var _client = null;
55
172
  var _resilientClient = null;
@@ -188,22 +305,24 @@ async function ensureSchema() {
188
305
  ON behaviors(agent_id, active);
189
306
  `);
190
307
  try {
308
+ const coordinatorName = getCoordinatorName();
191
309
  const existing = await client.execute({
192
- sql: "SELECT COUNT(*) as cnt FROM behaviors WHERE agent_id = 'exe'",
193
- args: []
310
+ sql: "SELECT COUNT(*) as cnt FROM behaviors WHERE agent_id = ?",
311
+ args: [coordinatorName]
194
312
  });
195
313
  if (Number(existing.rows[0]?.cnt) === 0) {
196
- await client.executeMultiple(`
197
- INSERT INTO behaviors (id, agent_id, project_name, domain, content, active, created_at, updated_at)
198
- VALUES
199
- (hex(randomblob(16)), 'exe', NULL, 'workflow', 'Don''t ask "keep going?" \u2014 just keep executing phases/plans autonomously', 1, '2026-03-25T00:00:00Z', '2026-03-25T00:00:00Z');
200
- INSERT INTO behaviors (id, agent_id, project_name, domain, content, active, created_at, updated_at)
201
- VALUES
202
- (hex(randomblob(16)), 'exe', NULL, 'tool-use', 'Always use create_task MCP tool, never write .md files directly for task creation', 1, '2026-03-25T00:00:00Z', '2026-03-25T00:00:00Z');
203
- INSERT INTO behaviors (id, agent_id, project_name, domain, content, active, created_at, updated_at)
204
- VALUES
205
- (hex(randomblob(16)), 'exe', NULL, 'workflow', 'Auto-start reviewing when idle and reviews are pending \u2014 never ask founder for permission', 1, '2026-03-25T00:00:00Z', '2026-03-25T00:00:00Z');
206
- `);
314
+ const seededAt = "2026-03-25T00:00:00Z";
315
+ for (const [domain, content] of [
316
+ ["workflow", `Don't ask "keep going?" \u2014 just keep executing phases/plans autonomously`],
317
+ ["tool-use", "Always use create_task MCP tool, never write .md files directly for task creation"],
318
+ ["workflow", "Auto-start reviewing when idle and reviews are pending \u2014 never ask founder for permission"]
319
+ ]) {
320
+ await client.execute({
321
+ sql: `INSERT INTO behaviors (id, agent_id, project_name, domain, content, active, created_at, updated_at)
322
+ VALUES (hex(randomblob(16)), ?, NULL, ?, ?, 1, ?, ?)`,
323
+ args: [coordinatorName, domain, content, seededAt, seededAt]
324
+ });
325
+ }
207
326
  }
208
327
  } catch {
209
328
  }
@@ -895,6 +1014,39 @@ async function ensureSchema() {
895
1014
  } catch {
896
1015
  }
897
1016
  }
1017
+ try {
1018
+ await client.execute({
1019
+ sql: `ALTER TABLE memories ADD COLUMN draft INTEGER DEFAULT 0`,
1020
+ args: []
1021
+ });
1022
+ } catch {
1023
+ }
1024
+ try {
1025
+ await client.execute(
1026
+ `CREATE INDEX IF NOT EXISTS idx_memories_draft ON memories(draft) WHERE draft = 1`
1027
+ );
1028
+ } catch {
1029
+ }
1030
+ try {
1031
+ await client.execute({
1032
+ sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
1033
+ args: []
1034
+ });
1035
+ } catch {
1036
+ }
1037
+ try {
1038
+ await client.execute(
1039
+ `CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type)`
1040
+ );
1041
+ } catch {
1042
+ }
1043
+ try {
1044
+ await client.execute({
1045
+ sql: `ALTER TABLE memories ADD COLUMN trajectory TEXT`,
1046
+ args: []
1047
+ });
1048
+ } catch {
1049
+ }
898
1050
  }
899
1051
  var disposeTurso = disposeDatabase;
900
1052
  async function disposeDatabase() {