@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
@@ -3232,7 +3232,7 @@ __export(shard_manager_exports, {
3232
3232
  shardExists: () => shardExists
3233
3233
  });
3234
3234
  import path7 from "path";
3235
- import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync } from "fs";
3235
+ import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync, renameSync as renameSync3, statSync as statSync2 } from "fs";
3236
3236
  import { createClient as createClient2 } from "@libsql/client";
3237
3237
  function initShardManager(encryptionKey) {
3238
3238
  _encryptionKey = encryptionKey;
@@ -3254,7 +3254,7 @@ function getShardClient(projectName) {
3254
3254
  if (!_encryptionKey) {
3255
3255
  throw new Error("Shard manager not initialized. Call initShardManager() first.");
3256
3256
  }
3257
- const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3257
+ const safeName = safeShardName(projectName);
3258
3258
  if (!safeName || safeName === "unknown") {
3259
3259
  throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
3260
3260
  }
@@ -3276,9 +3276,12 @@ function getShardClient(projectName) {
3276
3276
  return client;
3277
3277
  }
3278
3278
  function shardExists(projectName) {
3279
- const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3279
+ const safeName = safeShardName(projectName);
3280
3280
  return existsSync7(path7.join(SHARDS_DIR, `${safeName}.db`));
3281
3281
  }
3282
+ function safeShardName(projectName) {
3283
+ return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3284
+ }
3282
3285
  function listShards() {
3283
3286
  if (!existsSync7(SHARDS_DIR)) return [];
3284
3287
  return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
@@ -3372,7 +3375,8 @@ async function ensureShardSchema(client) {
3372
3375
  "ALTER TABLE memories ADD COLUMN token_cost REAL",
3373
3376
  "ALTER TABLE memories ADD COLUMN audience TEXT",
3374
3377
  "ALTER TABLE memories ADD COLUMN language_type TEXT",
3375
- "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
3378
+ "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
3379
+ "ALTER TABLE memories ADD COLUMN deleted_at TEXT"
3376
3380
  ]) {
3377
3381
  try {
3378
3382
  await client.execute(col);
@@ -3468,9 +3472,32 @@ async function ensureShardSchema(client) {
3468
3472
  }
3469
3473
  }
3470
3474
  async function getReadyShardClient(projectName) {
3471
- const client = getShardClient(projectName);
3472
- await ensureShardSchema(client);
3473
- return client;
3475
+ const safeName = safeShardName(projectName);
3476
+ let client = getShardClient(projectName);
3477
+ try {
3478
+ await ensureShardSchema(client);
3479
+ return client;
3480
+ } catch (err) {
3481
+ const message = err instanceof Error ? err.message : String(err);
3482
+ if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
3483
+ client.close();
3484
+ _shards.delete(safeName);
3485
+ _shardLastAccess.delete(safeName);
3486
+ const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
3487
+ if (existsSync7(dbPath)) {
3488
+ const stat = statSync2(dbPath);
3489
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
3490
+ const archivedPath = path7.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
3491
+ renameSync3(dbPath, archivedPath);
3492
+ process.stderr.write(
3493
+ `[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
3494
+ `
3495
+ );
3496
+ }
3497
+ client = getShardClient(projectName);
3498
+ await ensureShardSchema(client);
3499
+ return client;
3500
+ }
3474
3501
  }
3475
3502
  function evictLRU() {
3476
3503
  let oldest = null;
@@ -3691,7 +3718,7 @@ var init_platform_procedures = __esm({
3691
3718
  title: "MCP tools \u2014 wiki, documents, and content",
3692
3719
  domain: "tool-use",
3693
3720
  priority: "p1",
3694
- 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."
3721
+ 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."
3695
3722
  },
3696
3723
  {
3697
3724
  title: "MCP tools \u2014 system, operations, and admin",
@@ -3709,7 +3736,7 @@ var init_platform_procedures = __esm({
3709
3736
  title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
3710
3737
  domain: "tool-use",
3711
3738
  priority: "p1",
3712
- 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."
3739
+ 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."
3713
3740
  }
3714
3741
  ];
3715
3742
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -4060,7 +4087,7 @@ var init_agent_config = __esm({
4060
4087
  });
4061
4088
 
4062
4089
  // src/lib/intercom-queue.ts
4063
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync9, mkdirSync as mkdirSync3 } from "fs";
4090
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as renameSync4, existsSync as existsSync9, mkdirSync as mkdirSync3 } from "fs";
4064
4091
  import path10 from "path";
4065
4092
  import os7 from "os";
4066
4093
  var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
@@ -4334,8 +4361,8 @@ async function validateLicense(apiKey, deviceId) {
4334
4361
  }
4335
4362
  function getCacheAgeMs() {
4336
4363
  try {
4337
- const { statSync: statSync5 } = __require("fs");
4338
- const s = statSync5(CACHE_PATH);
4364
+ const { statSync: statSync6 } = __require("fs");
4365
+ const s = statSync6(CACHE_PATH);
4339
4366
  return Date.now() - s.mtimeMs;
4340
4367
  } catch {
4341
4368
  return Infinity;
@@ -5294,7 +5321,7 @@ __export(db_backup_exports, {
5294
5321
  listBackups: () => listBackups,
5295
5322
  rotateBackups: () => rotateBackups
5296
5323
  });
5297
- import { copyFileSync, existsSync as existsSync17, mkdirSync as mkdirSync8, readdirSync as readdirSync5, unlinkSync as unlinkSync7, statSync as statSync3 } from "fs";
5324
+ import { copyFileSync, existsSync as existsSync17, mkdirSync as mkdirSync8, readdirSync as readdirSync5, unlinkSync as unlinkSync7, statSync as statSync4 } from "fs";
5298
5325
  import path18 from "path";
5299
5326
  function findActiveDb() {
5300
5327
  for (const name of DB_NAMES) {
@@ -5338,7 +5365,7 @@ function rotateBackups(keepDays = DEFAULT_KEEP_DAYS) {
5338
5365
  if (!file.endsWith(".db") && !file.endsWith(".db-wal") && !file.endsWith(".db-shm")) continue;
5339
5366
  const filePath = path18.join(BACKUP_DIR, file);
5340
5367
  try {
5341
- const stat = statSync3(filePath);
5368
+ const stat = statSync4(filePath);
5342
5369
  if (stat.mtimeMs < cutoff) {
5343
5370
  unlinkSync7(filePath);
5344
5371
  deleted++;
@@ -5356,7 +5383,7 @@ function listBackups() {
5356
5383
  const files = readdirSync5(BACKUP_DIR).filter((f) => f.endsWith(".db") && !f.endsWith("-wal") && !f.endsWith("-shm"));
5357
5384
  return files.map((name) => {
5358
5385
  const p = path18.join(BACKUP_DIR, name);
5359
- const stat = statSync3(p);
5386
+ const stat = statSync4(p);
5360
5387
  return { path: p, name, size: stat.size, date: stat.mtime };
5361
5388
  }).sort((a, b) => b.date.getTime() - a.date.getTime());
5362
5389
  } catch {
@@ -5415,7 +5442,7 @@ __export(cloud_sync_exports, {
5415
5442
  pushToPostgres: () => pushToPostgres,
5416
5443
  recordRosterDeletion: () => recordRosterDeletion
5417
5444
  });
5418
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, existsSync as existsSync18, readdirSync as readdirSync6, mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, unlinkSync as unlinkSync8, openSync as openSync2, closeSync as closeSync2, statSync as statSync4 } from "fs";
5445
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, existsSync as existsSync18, readdirSync as readdirSync6, mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, unlinkSync as unlinkSync8, openSync as openSync2, closeSync as closeSync2, statSync as statSync5 } from "fs";
5419
5446
  import crypto4 from "crypto";
5420
5447
  import path19 from "path";
5421
5448
  import { homedir as homedir2 } from "os";
@@ -5907,7 +5934,7 @@ async function cloudSync(config) {
5907
5934
  const { getLatestBackup: getLatestBackup2 } = await Promise.resolve().then(() => (init_db_backup(), db_backup_exports));
5908
5935
  const latestBackup = getLatestBackup2();
5909
5936
  if (latestBackup) {
5910
- const backupSize = statSync4(latestBackup).size;
5937
+ const backupSize = statSync5(latestBackup).size;
5911
5938
  const MAX_CLOUD_BACKUP_BYTES = 50 * 1024 * 1024;
5912
5939
  if (backupSize <= MAX_CLOUD_BACKUP_BYTES) {
5913
5940
  const backupData = readFileSync13(latestBackup);
@@ -6709,7 +6736,7 @@ init_exe_daemon_client();
6709
6736
 
6710
6737
  // src/lib/memory-queue.ts
6711
6738
  init_config();
6712
- import { appendFileSync as appendFileSync2, readFileSync as readFileSync11, renameSync as renameSync4, unlinkSync as unlinkSync4, existsSync as existsSync14, statSync as statSync2 } from "fs";
6739
+ import { appendFileSync as appendFileSync2, readFileSync as readFileSync11, renameSync as renameSync5, unlinkSync as unlinkSync4, existsSync as existsSync14, statSync as statSync3 } from "fs";
6713
6740
  import path15 from "path";
6714
6741
  var QUEUE_PATH2 = path15.join(EXE_AI_DIR, "memory-queue.jsonl");
6715
6742
  var PROCESSING_PATH = QUEUE_PATH2 + ".processing";
package/dist/index.js CHANGED
@@ -539,7 +539,8 @@ function isMultiInstance(agentName, employees) {
539
539
  return MULTI_INSTANCE_ROLES.has(emp.role.toLowerCase());
540
540
  }
541
541
  function addEmployee(employees, employee) {
542
- const normalized = { ...employee, name: employee.name.toLowerCase() };
542
+ const { systemPrompt: _legacyPrompt, ...rest } = employee;
543
+ const normalized = { ...rest, name: employee.name.toLowerCase() };
543
544
  if (employees.some((e) => e.name.toLowerCase() === normalized.name)) {
544
545
  throw new Error(`Employee '${normalized.name}' already exists`);
545
546
  }
@@ -7223,7 +7224,7 @@ __export(shard_manager_exports, {
7223
7224
  shardExists: () => shardExists
7224
7225
  });
7225
7226
  import path20 from "path";
7226
- import { existsSync as existsSync16, mkdirSync as mkdirSync7, readdirSync as readdirSync4 } from "fs";
7227
+ import { existsSync as existsSync16, mkdirSync as mkdirSync7, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync2 } from "fs";
7227
7228
  import { createClient as createClient2 } from "@libsql/client";
7228
7229
  function initShardManager(encryptionKey) {
7229
7230
  _encryptionKey = encryptionKey;
@@ -7245,7 +7246,7 @@ function getShardClient(projectName) {
7245
7246
  if (!_encryptionKey) {
7246
7247
  throw new Error("Shard manager not initialized. Call initShardManager() first.");
7247
7248
  }
7248
- const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
7249
+ const safeName = safeShardName(projectName);
7249
7250
  if (!safeName || safeName === "unknown") {
7250
7251
  throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
7251
7252
  }
@@ -7267,9 +7268,12 @@ function getShardClient(projectName) {
7267
7268
  return client;
7268
7269
  }
7269
7270
  function shardExists(projectName) {
7270
- const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
7271
+ const safeName = safeShardName(projectName);
7271
7272
  return existsSync16(path20.join(SHARDS_DIR, `${safeName}.db`));
7272
7273
  }
7274
+ function safeShardName(projectName) {
7275
+ return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
7276
+ }
7273
7277
  function listShards() {
7274
7278
  if (!existsSync16(SHARDS_DIR)) return [];
7275
7279
  return readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
@@ -7363,7 +7367,8 @@ async function ensureShardSchema(client) {
7363
7367
  "ALTER TABLE memories ADD COLUMN token_cost REAL",
7364
7368
  "ALTER TABLE memories ADD COLUMN audience TEXT",
7365
7369
  "ALTER TABLE memories ADD COLUMN language_type TEXT",
7366
- "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
7370
+ "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
7371
+ "ALTER TABLE memories ADD COLUMN deleted_at TEXT"
7367
7372
  ]) {
7368
7373
  try {
7369
7374
  await client.execute(col);
@@ -7459,9 +7464,32 @@ async function ensureShardSchema(client) {
7459
7464
  }
7460
7465
  }
7461
7466
  async function getReadyShardClient(projectName) {
7462
- const client = getShardClient(projectName);
7463
- await ensureShardSchema(client);
7464
- return client;
7467
+ const safeName = safeShardName(projectName);
7468
+ let client = getShardClient(projectName);
7469
+ try {
7470
+ await ensureShardSchema(client);
7471
+ return client;
7472
+ } catch (err) {
7473
+ const message = err instanceof Error ? err.message : String(err);
7474
+ if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
7475
+ client.close();
7476
+ _shards.delete(safeName);
7477
+ _shardLastAccess.delete(safeName);
7478
+ const dbPath = path20.join(SHARDS_DIR, `${safeName}.db`);
7479
+ if (existsSync16(dbPath)) {
7480
+ const stat = statSync2(dbPath);
7481
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
7482
+ const archivedPath = path20.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
7483
+ renameSync4(dbPath, archivedPath);
7484
+ process.stderr.write(
7485
+ `[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
7486
+ `
7487
+ );
7488
+ }
7489
+ client = getShardClient(projectName);
7490
+ await ensureShardSchema(client);
7491
+ return client;
7492
+ }
7465
7493
  }
7466
7494
  function evictLRU() {
7467
7495
  let oldest = null;
@@ -7682,7 +7710,7 @@ var init_platform_procedures = __esm({
7682
7710
  title: "MCP tools \u2014 wiki, documents, and content",
7683
7711
  domain: "tool-use",
7684
7712
  priority: "p1",
7685
- 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."
7713
+ 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."
7686
7714
  },
7687
7715
  {
7688
7716
  title: "MCP tools \u2014 system, operations, and admin",
@@ -7700,7 +7728,7 @@ var init_platform_procedures = __esm({
7700
7728
  title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
7701
7729
  domain: "tool-use",
7702
7730
  priority: "p1",
7703
- 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."
7731
+ 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."
7704
7732
  }
7705
7733
  ];
7706
7734
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -14291,6 +14319,24 @@ var MAX_BACKOFF_MS = 3e5;
14291
14319
  var BACKOFF_MULTIPLIER = 2;
14292
14320
  var JITTER_FACTOR = 0.25;
14293
14321
  var AUTH_DIR = join(homedir(), ".exe-os", "whatsapp-auth");
14322
+ function createBaileysLogger(accountName) {
14323
+ const prefix = accountName ? `[whatsapp:${accountName}]` : "[whatsapp]";
14324
+ let logger;
14325
+ logger = {
14326
+ level: "warn",
14327
+ trace: () => {
14328
+ },
14329
+ debug: () => {
14330
+ },
14331
+ info: () => {
14332
+ },
14333
+ warn: (...args) => console.warn(prefix, ...args),
14334
+ error: (...args) => console.error(prefix, ...args),
14335
+ fatal: (...args) => console.error(prefix, ...args),
14336
+ child: () => logger
14337
+ };
14338
+ return logger;
14339
+ }
14294
14340
  function calculateBackoff(retryCount) {
14295
14341
  const base = Math.min(
14296
14342
  INITIAL_BACKOFF_MS * BACKOFF_MULTIPLIER ** retryCount,
@@ -14306,6 +14352,7 @@ var WhatsAppAdapter = class {
14306
14352
  connected = false;
14307
14353
  abortController = null;
14308
14354
  authDir = AUTH_DIR;
14355
+ baileysLogger = createBaileysLogger();
14309
14356
  // Resilience state
14310
14357
  retryCount = 0;
14311
14358
  disconnectedAt = 0;
@@ -14316,6 +14363,7 @@ var WhatsAppAdapter = class {
14316
14363
  const { makeWASocket, useMultiFileAuthState, fetchLatestBaileysVersion, DisconnectReason, makeCacheableSignalKeyStore } = baileys;
14317
14364
  const { state, saveCreds } = await useMultiFileAuthState(this.authDir);
14318
14365
  const { version } = await fetchLatestBaileysVersion();
14366
+ this.baileysLogger = createBaileysLogger();
14319
14367
  this.abortController = new AbortController();
14320
14368
  let agent;
14321
14369
  const socksProxy = config2.credentials.socksProxy;
@@ -14334,8 +14382,9 @@ var WhatsAppAdapter = class {
14334
14382
  const sock = makeWASocket({
14335
14383
  auth: {
14336
14384
  creds: state.creds,
14337
- keys: makeCacheableSignalKeyStore(state.keys, void 0)
14385
+ keys: makeCacheableSignalKeyStore(state.keys, this.baileysLogger)
14338
14386
  },
14387
+ logger: this.baileysLogger,
14339
14388
  version,
14340
14389
  printQRInTerminal: true,
14341
14390
  browser: ["exe-os", "cli", "1.0"],
@@ -375,7 +375,8 @@ function isMultiInstance(agentName, employees) {
375
375
  return MULTI_INSTANCE_ROLES.has(emp.role.toLowerCase());
376
376
  }
377
377
  function addEmployee(employees, employee) {
378
- const normalized = { ...employee, name: employee.name.toLowerCase() };
378
+ const { systemPrompt: _legacyPrompt, ...rest } = employee;
379
+ const normalized = { ...rest, name: employee.name.toLowerCase() };
379
380
  if (employees.some((e) => e.name.toLowerCase() === normalized.name)) {
380
381
  throw new Error(`Employee '${normalized.name}' already exists`);
381
382
  }
@@ -282,7 +282,7 @@ var PLATFORM_PROCEDURES = [
282
282
  title: "MCP tools \u2014 wiki, documents, and content",
283
283
  domain: "tool-use",
284
284
  priority: "p1",
285
- 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."
285
+ 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."
286
286
  },
287
287
  {
288
288
  title: "MCP tools \u2014 system, operations, and admin",
@@ -300,7 +300,7 @@ var PLATFORM_PROCEDURES = [
300
300
  title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
301
301
  domain: "tool-use",
302
302
  priority: "p1",
303
- 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."
303
+ 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."
304
304
  }
305
305
  ];
306
306
  var PLATFORM_PROCEDURE_TITLES = new Set(
@@ -472,7 +472,8 @@ var TEMPLATE_VERSION = 1;
472
472
  var PROCEDURES_MARKER = "EXE OS \u2014 VISION AND NON-NEGOTIABLE PRINCIPLES";
473
473
  function getSessionPrompt(storedPrompt) {
474
474
  const markerIndex = storedPrompt.indexOf(PROCEDURES_MARKER);
475
- const rolePrompt = markerIndex >= 0 ? storedPrompt.slice(0, markerIndex).trimEnd() : storedPrompt;
475
+ const withoutProcedures = markerIndex >= 0 ? storedPrompt.slice(0, markerIndex).trimEnd() : storedPrompt;
476
+ const rolePrompt = withoutProcedures.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, "").replace(/<!--[\s\S]*?-->/g, "").trimStart();
476
477
  const globalBlock = getGlobalProceduresBlock();
477
478
  return `${globalBlock}${rolePrompt}
478
479
  ${BASE_OPERATING_PROCEDURES}`;
@@ -340,7 +340,8 @@ function isMultiInstance(agentName, employees) {
340
340
  return MULTI_INSTANCE_ROLES.has(emp.role.toLowerCase());
341
341
  }
342
342
  function addEmployee(employees, employee) {
343
- const normalized = { ...employee, name: employee.name.toLowerCase() };
343
+ const { systemPrompt: _legacyPrompt, ...rest } = employee;
344
+ const normalized = { ...rest, name: employee.name.toLowerCase() };
344
345
  if (employees.some((e) => e.name.toLowerCase() === normalized.name)) {
345
346
  throw new Error(`Employee '${normalized.name}' already exists`);
346
347
  }