@askexenow/exe-os 0.9.37 → 0.9.39

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 (73) hide show
  1. package/deploy/stack-manifests/v0.9.json +55 -0
  2. package/dist/bin/backfill-conversations.js +36 -9
  3. package/dist/bin/backfill-responses.js +36 -9
  4. package/dist/bin/backfill-vectors.js +36 -9
  5. package/dist/bin/cleanup-stale-review-tasks.js +37 -10
  6. package/dist/bin/cli.js +624 -204
  7. package/dist/bin/exe-agent.js +13 -5
  8. package/dist/bin/exe-assign.js +36 -9
  9. package/dist/bin/exe-boot.js +50 -20
  10. package/dist/bin/exe-call.js +134 -342
  11. package/dist/bin/exe-dispatch.js +36 -9
  12. package/dist/bin/exe-doctor.js +39 -12
  13. package/dist/bin/exe-export-behaviors.js +38 -11
  14. package/dist/bin/exe-forget.js +36 -9
  15. package/dist/bin/exe-gateway.js +64 -15
  16. package/dist/bin/exe-heartbeat.js +37 -10
  17. package/dist/bin/exe-kill.js +36 -9
  18. package/dist/bin/exe-launch-agent.js +287 -1081
  19. package/dist/bin/exe-new-employee.js +100 -14
  20. package/dist/bin/exe-pending-messages.js +36 -9
  21. package/dist/bin/exe-pending-notifications.js +36 -9
  22. package/dist/bin/exe-pending-reviews.js +36 -9
  23. package/dist/bin/exe-rename.js +1780 -204
  24. package/dist/bin/exe-review.js +36 -9
  25. package/dist/bin/exe-search.js +38 -11
  26. package/dist/bin/exe-session-cleanup.js +38 -11
  27. package/dist/bin/exe-start-codex.js +38 -11
  28. package/dist/bin/exe-start-opencode.js +38 -11
  29. package/dist/bin/exe-status.js +37 -10
  30. package/dist/bin/exe-team.js +36 -9
  31. package/dist/bin/git-sweep.js +36 -9
  32. package/dist/bin/graph-backfill.js +36 -9
  33. package/dist/bin/graph-export.js +36 -9
  34. package/dist/bin/install.js +70 -3
  35. package/dist/bin/intercom-check.js +38 -11
  36. package/dist/bin/scan-tasks.js +36 -9
  37. package/dist/bin/setup.js +20 -19
  38. package/dist/bin/shard-migrate.js +36 -9
  39. package/dist/bin/stack-update.js +308 -0
  40. package/dist/gateway/index.js +62 -13
  41. package/dist/hooks/bug-report-worker.js +40 -12
  42. package/dist/hooks/codex-stop-task-finalizer.js +38 -11
  43. package/dist/hooks/commit-complete.js +36 -9
  44. package/dist/hooks/error-recall.js +38 -11
  45. package/dist/hooks/ingest.js +38 -10
  46. package/dist/hooks/instructions-loaded.js +44 -12
  47. package/dist/hooks/notification.js +36 -9
  48. package/dist/hooks/post-compact.js +36 -9
  49. package/dist/hooks/post-tool-combined.js +39 -12
  50. package/dist/hooks/pre-compact.js +37 -10
  51. package/dist/hooks/pre-tool-use.js +38 -10
  52. package/dist/hooks/prompt-submit.js +43 -15
  53. package/dist/hooks/session-end.js +37 -10
  54. package/dist/hooks/session-start.js +49 -16
  55. package/dist/hooks/stop.js +37 -10
  56. package/dist/hooks/subagent-stop.js +36 -9
  57. package/dist/hooks/summary-worker.js +45 -18
  58. package/dist/index.js +60 -11
  59. package/dist/lib/consolidation.js +2 -1
  60. package/dist/lib/employee-templates.js +4 -3
  61. package/dist/lib/employees.js +2 -1
  62. package/dist/lib/exe-daemon.js +11229 -10537
  63. package/dist/lib/hybrid-search.js +38 -11
  64. package/dist/lib/identity.js +8 -3
  65. package/dist/lib/schedules.js +36 -9
  66. package/dist/lib/store.js +36 -9
  67. package/dist/mcp/server.js +6873 -6249
  68. package/dist/mcp/tools/create-task.js +10 -4
  69. package/dist/runtime/index.js +36 -9
  70. package/dist/tui/App.js +42 -13
  71. package/package.json +4 -1
  72. package/stack.release.json +31 -0
  73. package/stack.release.schema.json +31 -0
@@ -3333,7 +3333,7 @@ __export(shard_manager_exports, {
3333
3333
  shardExists: () => shardExists
3334
3334
  });
3335
3335
  import path7 from "path";
3336
- import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync } from "fs";
3336
+ import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync, renameSync as renameSync3, statSync as statSync2 } from "fs";
3337
3337
  import { createClient as createClient2 } from "@libsql/client";
3338
3338
  function initShardManager(encryptionKey) {
3339
3339
  _encryptionKey = encryptionKey;
@@ -3355,7 +3355,7 @@ function getShardClient(projectName) {
3355
3355
  if (!_encryptionKey) {
3356
3356
  throw new Error("Shard manager not initialized. Call initShardManager() first.");
3357
3357
  }
3358
- const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3358
+ const safeName = safeShardName(projectName);
3359
3359
  if (!safeName || safeName === "unknown") {
3360
3360
  throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
3361
3361
  }
@@ -3377,9 +3377,12 @@ function getShardClient(projectName) {
3377
3377
  return client;
3378
3378
  }
3379
3379
  function shardExists(projectName) {
3380
- const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3380
+ const safeName = safeShardName(projectName);
3381
3381
  return existsSync7(path7.join(SHARDS_DIR, `${safeName}.db`));
3382
3382
  }
3383
+ function safeShardName(projectName) {
3384
+ return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3385
+ }
3383
3386
  function listShards() {
3384
3387
  if (!existsSync7(SHARDS_DIR)) return [];
3385
3388
  return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
@@ -3473,7 +3476,8 @@ async function ensureShardSchema(client) {
3473
3476
  "ALTER TABLE memories ADD COLUMN token_cost REAL",
3474
3477
  "ALTER TABLE memories ADD COLUMN audience TEXT",
3475
3478
  "ALTER TABLE memories ADD COLUMN language_type TEXT",
3476
- "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
3479
+ "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
3480
+ "ALTER TABLE memories ADD COLUMN deleted_at TEXT"
3477
3481
  ]) {
3478
3482
  try {
3479
3483
  await client.execute(col);
@@ -3569,9 +3573,32 @@ async function ensureShardSchema(client) {
3569
3573
  }
3570
3574
  }
3571
3575
  async function getReadyShardClient(projectName) {
3572
- const client = getShardClient(projectName);
3573
- await ensureShardSchema(client);
3574
- return client;
3576
+ const safeName = safeShardName(projectName);
3577
+ let client = getShardClient(projectName);
3578
+ try {
3579
+ await ensureShardSchema(client);
3580
+ return client;
3581
+ } catch (err) {
3582
+ const message = err instanceof Error ? err.message : String(err);
3583
+ if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
3584
+ client.close();
3585
+ _shards.delete(safeName);
3586
+ _shardLastAccess.delete(safeName);
3587
+ const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
3588
+ if (existsSync7(dbPath)) {
3589
+ const stat = statSync2(dbPath);
3590
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
3591
+ const archivedPath = path7.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
3592
+ renameSync3(dbPath, archivedPath);
3593
+ process.stderr.write(
3594
+ `[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
3595
+ `
3596
+ );
3597
+ }
3598
+ client = getShardClient(projectName);
3599
+ await ensureShardSchema(client);
3600
+ return client;
3601
+ }
3575
3602
  }
3576
3603
  function evictLRU() {
3577
3604
  let oldest = null;
@@ -3792,7 +3819,7 @@ var init_platform_procedures = __esm({
3792
3819
  title: "MCP tools \u2014 wiki, documents, and content",
3793
3820
  domain: "tool-use",
3794
3821
  priority: "p1",
3795
- content: "create_wiki_page: create a wiki page in exe-wiki. list_wiki_pages: browse wiki pages. get_wiki_page: read a wiki page. update_wiki_page: edit a wiki page. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
3822
+ content: "wiki: read/list wiki pages only. Direct wiki write tools are removed; wiki updates flow through raw-data ingestion/projection into the curated wiki store. Legacy aliases: list_wiki_pages/get_wiki_page. crm: read/list/get CRM records from exe-db. raw_data: read capped raw landing-pad events from exe-db with payload opt-in. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
3796
3823
  },
3797
3824
  {
3798
3825
  title: "MCP tools \u2014 system, operations, and admin",
@@ -3810,7 +3837,7 @@ var init_platform_procedures = __esm({
3810
3837
  title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
3811
3838
  domain: "tool-use",
3812
3839
  priority: "p1",
3813
- content: "create_trigger: set up a scheduled recurring agent job (cron). list_triggers: view active triggers. load_skill: load a slash-command skill dynamically. apply_starter_pack: import a pre-built behavior + identity pack for a role. export_orchestration: export full org state (tasks, behaviors, identities) as portable JSON. import_orchestration: import org state into a new instance. deploy_client: deploy a customer client instance. query_company_brain: unified RAG query across all company knowledge. create_reminder: set a text reminder (shown in boot brief). list_reminders: view pending reminders. complete_reminder: mark a reminder done. global_procedure: manage Layer 0 procedures (actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
3840
+ content: "create_trigger: set up a scheduled recurring agent job (cron). list_triggers: view active triggers. load_skill: load a slash-command skill dynamically. apply_starter_pack: import a pre-built behavior + identity pack for a role. export_orchestration: export full org state (tasks, behaviors, identities) as portable JSON. import_orchestration: import org state into a new instance. deploy_client: deploy a customer client instance. query_company_brain: unified RAG query across all company knowledge. create_reminder: set a text reminder (shown in boot brief). list_reminders: view pending reminders. complete_reminder: mark a reminder done. global_procedure: manage customer-owned company procedures (Layer 0; actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
3814
3841
  }
3815
3842
  ];
3816
3843
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -4799,7 +4826,7 @@ __export(intercom_queue_exports, {
4799
4826
  queueIntercom: () => queueIntercom,
4800
4827
  readQueue: () => readQueue
4801
4828
  });
4802
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync9, mkdirSync as mkdirSync3 } from "fs";
4829
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as renameSync4, existsSync as existsSync9, mkdirSync as mkdirSync3 } from "fs";
4803
4830
  import path10 from "path";
4804
4831
  import os7 from "os";
4805
4832
  function ensureDir() {
@@ -4818,7 +4845,7 @@ function writeQueue(queue) {
4818
4845
  ensureDir();
4819
4846
  const tmp = `${QUEUE_PATH}.tmp`;
4820
4847
  writeFileSync4(tmp, JSON.stringify(queue, null, 2));
4821
- renameSync3(tmp, QUEUE_PATH);
4848
+ renameSync4(tmp, QUEUE_PATH);
4822
4849
  }
4823
4850
  function queueIntercom(targetSession, reason) {
4824
4851
  const queue = readQueue();
@@ -6949,7 +6949,7 @@ __export(shard_manager_exports, {
6949
6949
  shardExists: () => shardExists
6950
6950
  });
6951
6951
  import path19 from "path";
6952
- import { existsSync as existsSync16, mkdirSync as mkdirSync7, readdirSync as readdirSync4 } from "fs";
6952
+ import { existsSync as existsSync16, mkdirSync as mkdirSync7, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync2 } from "fs";
6953
6953
  import { createClient as createClient2 } from "@libsql/client";
6954
6954
  function initShardManager(encryptionKey) {
6955
6955
  _encryptionKey = encryptionKey;
@@ -6971,7 +6971,7 @@ function getShardClient(projectName) {
6971
6971
  if (!_encryptionKey) {
6972
6972
  throw new Error("Shard manager not initialized. Call initShardManager() first.");
6973
6973
  }
6974
- const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
6974
+ const safeName = safeShardName(projectName);
6975
6975
  if (!safeName || safeName === "unknown") {
6976
6976
  throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
6977
6977
  }
@@ -6993,9 +6993,12 @@ function getShardClient(projectName) {
6993
6993
  return client;
6994
6994
  }
6995
6995
  function shardExists(projectName) {
6996
- const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
6996
+ const safeName = safeShardName(projectName);
6997
6997
  return existsSync16(path19.join(SHARDS_DIR, `${safeName}.db`));
6998
6998
  }
6999
+ function safeShardName(projectName) {
7000
+ return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
7001
+ }
6999
7002
  function listShards() {
7000
7003
  if (!existsSync16(SHARDS_DIR)) return [];
7001
7004
  return readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
@@ -7089,7 +7092,8 @@ async function ensureShardSchema(client) {
7089
7092
  "ALTER TABLE memories ADD COLUMN token_cost REAL",
7090
7093
  "ALTER TABLE memories ADD COLUMN audience TEXT",
7091
7094
  "ALTER TABLE memories ADD COLUMN language_type TEXT",
7092
- "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
7095
+ "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
7096
+ "ALTER TABLE memories ADD COLUMN deleted_at TEXT"
7093
7097
  ]) {
7094
7098
  try {
7095
7099
  await client.execute(col);
@@ -7185,9 +7189,32 @@ async function ensureShardSchema(client) {
7185
7189
  }
7186
7190
  }
7187
7191
  async function getReadyShardClient(projectName) {
7188
- const client = getShardClient(projectName);
7189
- await ensureShardSchema(client);
7190
- return client;
7192
+ const safeName = safeShardName(projectName);
7193
+ let client = getShardClient(projectName);
7194
+ try {
7195
+ await ensureShardSchema(client);
7196
+ return client;
7197
+ } catch (err) {
7198
+ const message = err instanceof Error ? err.message : String(err);
7199
+ if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
7200
+ client.close();
7201
+ _shards.delete(safeName);
7202
+ _shardLastAccess.delete(safeName);
7203
+ const dbPath = path19.join(SHARDS_DIR, `${safeName}.db`);
7204
+ if (existsSync16(dbPath)) {
7205
+ const stat = statSync2(dbPath);
7206
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
7207
+ const archivedPath = path19.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
7208
+ renameSync4(dbPath, archivedPath);
7209
+ process.stderr.write(
7210
+ `[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
7211
+ `
7212
+ );
7213
+ }
7214
+ client = getShardClient(projectName);
7215
+ await ensureShardSchema(client);
7216
+ return client;
7217
+ }
7191
7218
  }
7192
7219
  function evictLRU() {
7193
7220
  let oldest = null;
@@ -7408,7 +7435,7 @@ var init_platform_procedures = __esm({
7408
7435
  title: "MCP tools \u2014 wiki, documents, and content",
7409
7436
  domain: "tool-use",
7410
7437
  priority: "p1",
7411
- content: "create_wiki_page: create a wiki page in exe-wiki. list_wiki_pages: browse wiki pages. get_wiki_page: read a wiki page. update_wiki_page: edit a wiki page. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
7438
+ content: "wiki: read/list wiki pages only. Direct wiki write tools are removed; wiki updates flow through raw-data ingestion/projection into the curated wiki store. Legacy aliases: list_wiki_pages/get_wiki_page. crm: read/list/get CRM records from exe-db. raw_data: read capped raw landing-pad events from exe-db with payload opt-in. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
7412
7439
  },
7413
7440
  {
7414
7441
  title: "MCP tools \u2014 system, operations, and admin",
@@ -7426,7 +7453,7 @@ var init_platform_procedures = __esm({
7426
7453
  title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
7427
7454
  domain: "tool-use",
7428
7455
  priority: "p1",
7429
- content: "create_trigger: set up a scheduled recurring agent job (cron). list_triggers: view active triggers. load_skill: load a slash-command skill dynamically. apply_starter_pack: import a pre-built behavior + identity pack for a role. export_orchestration: export full org state (tasks, behaviors, identities) as portable JSON. import_orchestration: import org state into a new instance. deploy_client: deploy a customer client instance. query_company_brain: unified RAG query across all company knowledge. create_reminder: set a text reminder (shown in boot brief). list_reminders: view pending reminders. complete_reminder: mark a reminder done. global_procedure: manage Layer 0 procedures (actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
7456
+ content: "create_trigger: set up a scheduled recurring agent job (cron). list_triggers: view active triggers. load_skill: load a slash-command skill dynamically. apply_starter_pack: import a pre-built behavior + identity pack for a role. export_orchestration: export full org state (tasks, behaviors, identities) as portable JSON. import_orchestration: import org state into a new instance. deploy_client: deploy a customer client instance. query_company_brain: unified RAG query across all company knowledge. create_reminder: set a text reminder (shown in boot brief). list_reminders: view pending reminders. complete_reminder: mark a reminder done. global_procedure: manage customer-owned company procedures (Layer 0; actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
7430
7457
  }
7431
7458
  ];
7432
7459
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -3241,7 +3241,7 @@ __export(shard_manager_exports, {
3241
3241
  shardExists: () => shardExists
3242
3242
  });
3243
3243
  import path7 from "path";
3244
- import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync } from "fs";
3244
+ import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync, renameSync as renameSync3, statSync as statSync2 } from "fs";
3245
3245
  import { createClient as createClient2 } from "@libsql/client";
3246
3246
  function initShardManager(encryptionKey) {
3247
3247
  _encryptionKey = encryptionKey;
@@ -3263,7 +3263,7 @@ function getShardClient(projectName) {
3263
3263
  if (!_encryptionKey) {
3264
3264
  throw new Error("Shard manager not initialized. Call initShardManager() first.");
3265
3265
  }
3266
- const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3266
+ const safeName = safeShardName(projectName);
3267
3267
  if (!safeName || safeName === "unknown") {
3268
3268
  throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
3269
3269
  }
@@ -3285,9 +3285,12 @@ function getShardClient(projectName) {
3285
3285
  return client;
3286
3286
  }
3287
3287
  function shardExists(projectName) {
3288
- const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3288
+ const safeName = safeShardName(projectName);
3289
3289
  return existsSync7(path7.join(SHARDS_DIR, `${safeName}.db`));
3290
3290
  }
3291
+ function safeShardName(projectName) {
3292
+ return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3293
+ }
3291
3294
  function listShards() {
3292
3295
  if (!existsSync7(SHARDS_DIR)) return [];
3293
3296
  return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
@@ -3381,7 +3384,8 @@ async function ensureShardSchema(client) {
3381
3384
  "ALTER TABLE memories ADD COLUMN token_cost REAL",
3382
3385
  "ALTER TABLE memories ADD COLUMN audience TEXT",
3383
3386
  "ALTER TABLE memories ADD COLUMN language_type TEXT",
3384
- "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
3387
+ "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
3388
+ "ALTER TABLE memories ADD COLUMN deleted_at TEXT"
3385
3389
  ]) {
3386
3390
  try {
3387
3391
  await client.execute(col);
@@ -3477,9 +3481,32 @@ async function ensureShardSchema(client) {
3477
3481
  }
3478
3482
  }
3479
3483
  async function getReadyShardClient(projectName) {
3480
- const client = getShardClient(projectName);
3481
- await ensureShardSchema(client);
3482
- return client;
3484
+ const safeName = safeShardName(projectName);
3485
+ let client = getShardClient(projectName);
3486
+ try {
3487
+ await ensureShardSchema(client);
3488
+ return client;
3489
+ } catch (err) {
3490
+ const message = err instanceof Error ? err.message : String(err);
3491
+ if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
3492
+ client.close();
3493
+ _shards.delete(safeName);
3494
+ _shardLastAccess.delete(safeName);
3495
+ const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
3496
+ if (existsSync7(dbPath)) {
3497
+ const stat = statSync2(dbPath);
3498
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
3499
+ const archivedPath = path7.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
3500
+ renameSync3(dbPath, archivedPath);
3501
+ process.stderr.write(
3502
+ `[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
3503
+ `
3504
+ );
3505
+ }
3506
+ client = getShardClient(projectName);
3507
+ await ensureShardSchema(client);
3508
+ return client;
3509
+ }
3483
3510
  }
3484
3511
  function evictLRU() {
3485
3512
  let oldest = null;
@@ -3700,7 +3727,7 @@ var init_platform_procedures = __esm({
3700
3727
  title: "MCP tools \u2014 wiki, documents, and content",
3701
3728
  domain: "tool-use",
3702
3729
  priority: "p1",
3703
- content: "create_wiki_page: create a wiki page in exe-wiki. list_wiki_pages: browse wiki pages. get_wiki_page: read a wiki page. update_wiki_page: edit a wiki page. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
3730
+ content: "wiki: read/list wiki pages only. Direct wiki write tools are removed; wiki updates flow through raw-data ingestion/projection into the curated wiki store. Legacy aliases: list_wiki_pages/get_wiki_page. crm: read/list/get CRM records from exe-db. raw_data: read capped raw landing-pad events from exe-db with payload opt-in. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
3704
3731
  },
3705
3732
  {
3706
3733
  title: "MCP tools \u2014 system, operations, and admin",
@@ -3718,7 +3745,7 @@ var init_platform_procedures = __esm({
3718
3745
  title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
3719
3746
  domain: "tool-use",
3720
3747
  priority: "p1",
3721
- content: "create_trigger: set up a scheduled recurring agent job (cron). list_triggers: view active triggers. load_skill: load a slash-command skill dynamically. apply_starter_pack: import a pre-built behavior + identity pack for a role. export_orchestration: export full org state (tasks, behaviors, identities) as portable JSON. import_orchestration: import org state into a new instance. deploy_client: deploy a customer client instance. query_company_brain: unified RAG query across all company knowledge. create_reminder: set a text reminder (shown in boot brief). list_reminders: view pending reminders. complete_reminder: mark a reminder done. global_procedure: manage Layer 0 procedures (actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
3748
+ content: "create_trigger: set up a scheduled recurring agent job (cron). list_triggers: view active triggers. load_skill: load a slash-command skill dynamically. apply_starter_pack: import a pre-built behavior + identity pack for a role. export_orchestration: export full org state (tasks, behaviors, identities) as portable JSON. import_orchestration: import org state into a new instance. deploy_client: deploy a customer client instance. query_company_brain: unified RAG query across all company knowledge. create_reminder: set a text reminder (shown in boot brief). list_reminders: view pending reminders. complete_reminder: mark a reminder done. global_procedure: manage customer-owned company procedures (Layer 0; actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
3722
3749
  }
3723
3750
  ];
3724
3751
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -4754,7 +4781,7 @@ __export(file_grep_exports, {
4754
4781
  grepProjectFiles: () => grepProjectFiles
4755
4782
  });
4756
4783
  import { execSync as execSync4 } from "child_process";
4757
- import { readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as statSync2, existsSync as existsSync9 } from "fs";
4784
+ import { readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as statSync3, existsSync as existsSync9 } from "fs";
4758
4785
  import path10 from "path";
4759
4786
  import crypto3 from "crypto";
4760
4787
  function hasRipgrep() {
@@ -4871,7 +4898,7 @@ function grepWithNodeFs(pattern, projectRoot, patterns) {
4871
4898
  for (const filePath of files.slice(0, MAX_FILES)) {
4872
4899
  const absPath = path10.join(projectRoot, filePath);
4873
4900
  try {
4874
- const stat = statSync2(absPath);
4901
+ const stat = statSync3(absPath);
4875
4902
  if (stat.size > MAX_FILE_SIZE) continue;
4876
4903
  const content = readFileSync5(absPath, "utf8");
4877
4904
  const lines = content.split("\n");
@@ -492,7 +492,8 @@ function isMultiInstance(agentName, employees) {
492
492
  return MULTI_INSTANCE_ROLES.has(emp.role.toLowerCase());
493
493
  }
494
494
  function addEmployee(employees, employee) {
495
- const normalized = { ...employee, name: employee.name.toLowerCase() };
495
+ const { systemPrompt: _legacyPrompt, ...rest } = employee;
496
+ const normalized = { ...rest, name: employee.name.toLowerCase() };
496
497
  if (employees.some((e) => e.name.toLowerCase() === normalized.name)) {
497
498
  throw new Error(`Employee '${normalized.name}' already exists`);
498
499
  }
@@ -3417,7 +3418,7 @@ __export(shard_manager_exports, {
3417
3418
  shardExists: () => shardExists
3418
3419
  });
3419
3420
  import path11 from "path";
3420
- import { existsSync as existsSync10, mkdirSync as mkdirSync5, readdirSync as readdirSync3 } from "fs";
3421
+ import { existsSync as existsSync10, mkdirSync as mkdirSync5, readdirSync as readdirSync3, renameSync as renameSync3, statSync as statSync2 } from "fs";
3421
3422
  import { createClient as createClient2 } from "@libsql/client";
3422
3423
  function initShardManager(encryptionKey) {
3423
3424
  _encryptionKey = encryptionKey;
@@ -3439,7 +3440,7 @@ function getShardClient(projectName) {
3439
3440
  if (!_encryptionKey) {
3440
3441
  throw new Error("Shard manager not initialized. Call initShardManager() first.");
3441
3442
  }
3442
- const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3443
+ const safeName = safeShardName(projectName);
3443
3444
  if (!safeName || safeName === "unknown") {
3444
3445
  throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
3445
3446
  }
@@ -3461,9 +3462,12 @@ function getShardClient(projectName) {
3461
3462
  return client;
3462
3463
  }
3463
3464
  function shardExists(projectName) {
3464
- const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3465
+ const safeName = safeShardName(projectName);
3465
3466
  return existsSync10(path11.join(SHARDS_DIR, `${safeName}.db`));
3466
3467
  }
3468
+ function safeShardName(projectName) {
3469
+ return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3470
+ }
3467
3471
  function listShards() {
3468
3472
  if (!existsSync10(SHARDS_DIR)) return [];
3469
3473
  return readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
@@ -3557,7 +3561,8 @@ async function ensureShardSchema(client) {
3557
3561
  "ALTER TABLE memories ADD COLUMN token_cost REAL",
3558
3562
  "ALTER TABLE memories ADD COLUMN audience TEXT",
3559
3563
  "ALTER TABLE memories ADD COLUMN language_type TEXT",
3560
- "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
3564
+ "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
3565
+ "ALTER TABLE memories ADD COLUMN deleted_at TEXT"
3561
3566
  ]) {
3562
3567
  try {
3563
3568
  await client.execute(col);
@@ -3653,9 +3658,32 @@ async function ensureShardSchema(client) {
3653
3658
  }
3654
3659
  }
3655
3660
  async function getReadyShardClient(projectName) {
3656
- const client = getShardClient(projectName);
3657
- await ensureShardSchema(client);
3658
- return client;
3661
+ const safeName = safeShardName(projectName);
3662
+ let client = getShardClient(projectName);
3663
+ try {
3664
+ await ensureShardSchema(client);
3665
+ return client;
3666
+ } catch (err) {
3667
+ const message = err instanceof Error ? err.message : String(err);
3668
+ if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
3669
+ client.close();
3670
+ _shards.delete(safeName);
3671
+ _shardLastAccess.delete(safeName);
3672
+ const dbPath = path11.join(SHARDS_DIR, `${safeName}.db`);
3673
+ if (existsSync10(dbPath)) {
3674
+ const stat = statSync2(dbPath);
3675
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
3676
+ const archivedPath = path11.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
3677
+ renameSync3(dbPath, archivedPath);
3678
+ process.stderr.write(
3679
+ `[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
3680
+ `
3681
+ );
3682
+ }
3683
+ client = getShardClient(projectName);
3684
+ await ensureShardSchema(client);
3685
+ return client;
3686
+ }
3659
3687
  }
3660
3688
  function evictLRU() {
3661
3689
  let oldest = null;
@@ -3876,7 +3904,7 @@ var init_platform_procedures = __esm({
3876
3904
  title: "MCP tools \u2014 wiki, documents, and content",
3877
3905
  domain: "tool-use",
3878
3906
  priority: "p1",
3879
- content: "create_wiki_page: create a wiki page in exe-wiki. list_wiki_pages: browse wiki pages. get_wiki_page: read a wiki page. update_wiki_page: edit a wiki page. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
3907
+ content: "wiki: read/list wiki pages only. Direct wiki write tools are removed; wiki updates flow through raw-data ingestion/projection into the curated wiki store. Legacy aliases: list_wiki_pages/get_wiki_page. crm: read/list/get CRM records from exe-db. raw_data: read capped raw landing-pad events from exe-db with payload opt-in. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
3880
3908
  },
3881
3909
  {
3882
3910
  title: "MCP tools \u2014 system, operations, and admin",
@@ -3894,7 +3922,7 @@ var init_platform_procedures = __esm({
3894
3922
  title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
3895
3923
  domain: "tool-use",
3896
3924
  priority: "p1",
3897
- content: "create_trigger: set up a scheduled recurring agent job (cron). list_triggers: view active triggers. load_skill: load a slash-command skill dynamically. apply_starter_pack: import a pre-built behavior + identity pack for a role. export_orchestration: export full org state (tasks, behaviors, identities) as portable JSON. import_orchestration: import org state into a new instance. deploy_client: deploy a customer client instance. query_company_brain: unified RAG query across all company knowledge. create_reminder: set a text reminder (shown in boot brief). list_reminders: view pending reminders. complete_reminder: mark a reminder done. global_procedure: manage Layer 0 procedures (actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
3925
+ content: "create_trigger: set up a scheduled recurring agent job (cron). list_triggers: view active triggers. load_skill: load a slash-command skill dynamically. apply_starter_pack: import a pre-built behavior + identity pack for a role. export_orchestration: export full org state (tasks, behaviors, identities) as portable JSON. import_orchestration: import org state into a new instance. deploy_client: deploy a customer client instance. query_company_brain: unified RAG query across all company knowledge. create_reminder: set a text reminder (shown in boot brief). list_reminders: view pending reminders. complete_reminder: mark a reminder done. global_procedure: manage customer-owned company procedures (Layer 0; actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
3898
3926
  }
3899
3927
  ];
3900
3928
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -3252,7 +3252,7 @@ __export(shard_manager_exports, {
3252
3252
  shardExists: () => shardExists
3253
3253
  });
3254
3254
  import path9 from "path";
3255
- import { existsSync as existsSync8, mkdirSync as mkdirSync4, readdirSync as readdirSync3 } from "fs";
3255
+ import { existsSync as existsSync8, mkdirSync as mkdirSync4, readdirSync as readdirSync3, renameSync as renameSync3, statSync as statSync2 } from "fs";
3256
3256
  import { createClient as createClient2 } from "@libsql/client";
3257
3257
  function initShardManager(encryptionKey) {
3258
3258
  _encryptionKey = encryptionKey;
@@ -3274,7 +3274,7 @@ function getShardClient(projectName) {
3274
3274
  if (!_encryptionKey) {
3275
3275
  throw new Error("Shard manager not initialized. Call initShardManager() first.");
3276
3276
  }
3277
- const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3277
+ const safeName = safeShardName(projectName);
3278
3278
  if (!safeName || safeName === "unknown") {
3279
3279
  throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
3280
3280
  }
@@ -3296,9 +3296,12 @@ function getShardClient(projectName) {
3296
3296
  return client;
3297
3297
  }
3298
3298
  function shardExists(projectName) {
3299
- const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3299
+ const safeName = safeShardName(projectName);
3300
3300
  return existsSync8(path9.join(SHARDS_DIR, `${safeName}.db`));
3301
3301
  }
3302
+ function safeShardName(projectName) {
3303
+ return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3304
+ }
3302
3305
  function listShards() {
3303
3306
  if (!existsSync8(SHARDS_DIR)) return [];
3304
3307
  return readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
@@ -3392,7 +3395,8 @@ async function ensureShardSchema(client) {
3392
3395
  "ALTER TABLE memories ADD COLUMN token_cost REAL",
3393
3396
  "ALTER TABLE memories ADD COLUMN audience TEXT",
3394
3397
  "ALTER TABLE memories ADD COLUMN language_type TEXT",
3395
- "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
3398
+ "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
3399
+ "ALTER TABLE memories ADD COLUMN deleted_at TEXT"
3396
3400
  ]) {
3397
3401
  try {
3398
3402
  await client.execute(col);
@@ -3488,9 +3492,32 @@ async function ensureShardSchema(client) {
3488
3492
  }
3489
3493
  }
3490
3494
  async function getReadyShardClient(projectName) {
3491
- const client = getShardClient(projectName);
3492
- await ensureShardSchema(client);
3493
- return client;
3495
+ const safeName = safeShardName(projectName);
3496
+ let client = getShardClient(projectName);
3497
+ try {
3498
+ await ensureShardSchema(client);
3499
+ return client;
3500
+ } catch (err) {
3501
+ const message = err instanceof Error ? err.message : String(err);
3502
+ if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
3503
+ client.close();
3504
+ _shards.delete(safeName);
3505
+ _shardLastAccess.delete(safeName);
3506
+ const dbPath = path9.join(SHARDS_DIR, `${safeName}.db`);
3507
+ if (existsSync8(dbPath)) {
3508
+ const stat = statSync2(dbPath);
3509
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
3510
+ const archivedPath = path9.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
3511
+ renameSync3(dbPath, archivedPath);
3512
+ process.stderr.write(
3513
+ `[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
3514
+ `
3515
+ );
3516
+ }
3517
+ client = getShardClient(projectName);
3518
+ await ensureShardSchema(client);
3519
+ return client;
3520
+ }
3494
3521
  }
3495
3522
  function evictLRU() {
3496
3523
  let oldest = null;
@@ -3711,7 +3738,7 @@ var init_platform_procedures = __esm({
3711
3738
  title: "MCP tools \u2014 wiki, documents, and content",
3712
3739
  domain: "tool-use",
3713
3740
  priority: "p1",
3714
- content: "create_wiki_page: create a wiki page in exe-wiki. list_wiki_pages: browse wiki pages. get_wiki_page: read a wiki page. update_wiki_page: edit a wiki page. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
3741
+ content: "wiki: read/list wiki pages only. Direct wiki write tools are removed; wiki updates flow through raw-data ingestion/projection into the curated wiki store. Legacy aliases: list_wiki_pages/get_wiki_page. crm: read/list/get CRM records from exe-db. raw_data: read capped raw landing-pad events from exe-db with payload opt-in. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
3715
3742
  },
3716
3743
  {
3717
3744
  title: "MCP tools \u2014 system, operations, and admin",
@@ -3729,7 +3756,7 @@ var init_platform_procedures = __esm({
3729
3756
  title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
3730
3757
  domain: "tool-use",
3731
3758
  priority: "p1",
3732
- content: "create_trigger: set up a scheduled recurring agent job (cron). list_triggers: view active triggers. load_skill: load a slash-command skill dynamically. apply_starter_pack: import a pre-built behavior + identity pack for a role. export_orchestration: export full org state (tasks, behaviors, identities) as portable JSON. import_orchestration: import org state into a new instance. deploy_client: deploy a customer client instance. query_company_brain: unified RAG query across all company knowledge. create_reminder: set a text reminder (shown in boot brief). list_reminders: view pending reminders. complete_reminder: mark a reminder done. global_procedure: manage Layer 0 procedures (actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
3759
+ content: "create_trigger: set up a scheduled recurring agent job (cron). list_triggers: view active triggers. load_skill: load a slash-command skill dynamically. apply_starter_pack: import a pre-built behavior + identity pack for a role. export_orchestration: export full org state (tasks, behaviors, identities) as portable JSON. import_orchestration: import org state into a new instance. deploy_client: deploy a customer client instance. query_company_brain: unified RAG query across all company knowledge. create_reminder: set a text reminder (shown in boot brief). list_reminders: view pending reminders. complete_reminder: mark a reminder done. global_procedure: manage customer-owned company procedures (Layer 0; actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
3733
3760
  }
3734
3761
  ];
3735
3762
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -4679,6 +4706,9 @@ function ensureDir() {
4679
4706
  function identityPath(agentId) {
4680
4707
  return path7.join(IDENTITY_DIR2, `${agentId}.md`);
4681
4708
  }
4709
+ function sanitizeIdentityBody(body) {
4710
+ return body.replace(/<!--[\s\S]*?-->/g, "").trim();
4711
+ }
4682
4712
  function parseFrontmatter(raw) {
4683
4713
  const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
4684
4714
  if (!match) {
@@ -4691,11 +4721,11 @@ function parseFrontmatter(raw) {
4691
4721
  created_by: "system",
4692
4722
  updated_at: (/* @__PURE__ */ new Date()).toISOString()
4693
4723
  },
4694
- body: raw
4724
+ body: sanitizeIdentityBody(raw)
4695
4725
  };
4696
4726
  }
4697
4727
  const yamlStr = match[1];
4698
- const body = match[2].trim();
4728
+ const body = sanitizeIdentityBody(match[2]);
4699
4729
  const fm = {};
4700
4730
  for (const line of yamlStr.split("\n")) {
4701
4731
  const kv = line.match(/^(\w+):\s*(.+)$/);
@@ -4741,7 +4771,9 @@ function listIdentities() {
4741
4771
  const summary = lines[0]?.trim().slice(0, 120) ?? identity.frontmatter.title;
4742
4772
  results.push({
4743
4773
  agentId,
4744
- title: `${identity.frontmatter.title} (${identity.frontmatter.role.toUpperCase()})`,
4774
+ // User-facing/team-facing title only. `frontmatter.role` is internal
4775
+ // routing metadata and must not leak as an external title.
4776
+ title: identity.frontmatter.title,
4745
4777
  summary
4746
4778
  });
4747
4779
  }