@askexenow/exe-os 0.9.60 → 0.9.62

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 (106) hide show
  1. package/deploy/stack-manifests/v0.9.json +62 -13
  2. package/dist/bin/backfill-conversations.js +282 -7
  3. package/dist/bin/backfill-responses.js +282 -7
  4. package/dist/bin/backfill-vectors.js +119 -7
  5. package/dist/bin/cc-doctor.js +376 -0
  6. package/dist/bin/cleanup-stale-review-tasks.js +282 -7
  7. package/dist/bin/cli.js +455 -77
  8. package/dist/bin/customer-readiness.js +33 -0
  9. package/dist/bin/exe-agent-config.js +2 -2
  10. package/dist/bin/exe-agent.js +3 -3
  11. package/dist/bin/exe-assign.js +282 -7
  12. package/dist/bin/exe-boot.js +125 -13
  13. package/dist/bin/exe-call.js +3 -3
  14. package/dist/bin/exe-cloud.js +2 -2
  15. package/dist/bin/exe-dispatch.js +282 -7
  16. package/dist/bin/exe-doctor.js +119 -7
  17. package/dist/bin/exe-export-behaviors.js +282 -7
  18. package/dist/bin/exe-forget.js +336 -7
  19. package/dist/bin/exe-gateway.js +282 -7
  20. package/dist/bin/exe-heartbeat.js +284 -9
  21. package/dist/bin/exe-kill.js +282 -7
  22. package/dist/bin/exe-launch-agent.js +282 -7
  23. package/dist/bin/exe-link.js +121 -9
  24. package/dist/bin/exe-new-employee.js +50 -21
  25. package/dist/bin/exe-pending-messages.js +282 -7
  26. package/dist/bin/exe-pending-notifications.js +282 -7
  27. package/dist/bin/exe-pending-reviews.js +282 -7
  28. package/dist/bin/exe-rename.js +282 -7
  29. package/dist/bin/exe-review.js +282 -7
  30. package/dist/bin/exe-search.js +306 -8
  31. package/dist/bin/exe-session-cleanup.js +282 -7
  32. package/dist/bin/exe-settings.js +2 -2
  33. package/dist/bin/exe-start-codex.js +326 -21
  34. package/dist/bin/exe-start-opencode.js +304 -10
  35. package/dist/bin/exe-status.js +282 -7
  36. package/dist/bin/exe-team.js +282 -7
  37. package/dist/bin/git-sweep.js +282 -7
  38. package/dist/bin/graph-backfill.js +282 -7
  39. package/dist/bin/graph-export.js +282 -7
  40. package/dist/bin/install.js +58 -33
  41. package/dist/bin/intercom-check.js +282 -7
  42. package/dist/bin/pre-build-guard.js +98 -0
  43. package/dist/bin/scan-tasks.js +282 -7
  44. package/dist/bin/setup.js +122 -10
  45. package/dist/bin/shard-migrate.js +282 -7
  46. package/dist/bin/stack-update.js +79 -11
  47. package/dist/bin/update.js +2 -2
  48. package/dist/gateway/index.js +288 -13
  49. package/dist/hooks/bug-report-worker.js +282 -7
  50. package/dist/hooks/codex-stop-task-finalizer.js +282 -7
  51. package/dist/hooks/commit-complete.js +282 -7
  52. package/dist/hooks/error-recall.js +306 -8
  53. package/dist/hooks/exe-heartbeat-hook.js +2 -2
  54. package/dist/hooks/ingest-worker.js +2 -2
  55. package/dist/hooks/ingest.js +282 -7
  56. package/dist/hooks/instructions-loaded.js +282 -7
  57. package/dist/hooks/notification.js +282 -7
  58. package/dist/hooks/post-compact.js +282 -7
  59. package/dist/hooks/post-tool-combined.js +306 -8
  60. package/dist/hooks/pre-compact.js +282 -7
  61. package/dist/hooks/pre-tool-use.js +282 -7
  62. package/dist/hooks/prompt-submit.js +306 -8
  63. package/dist/hooks/session-end.js +282 -7
  64. package/dist/hooks/session-start.js +308 -10
  65. package/dist/hooks/stop.js +282 -7
  66. package/dist/hooks/subagent-stop.js +282 -7
  67. package/dist/hooks/summary-worker.js +125 -13
  68. package/dist/index.js +288 -13
  69. package/dist/lib/agent-config.js +2 -2
  70. package/dist/lib/cloud-sync.js +121 -9
  71. package/dist/lib/config.js +2 -2
  72. package/dist/lib/consolidation.js +2 -2
  73. package/dist/lib/database.js +115 -3
  74. package/dist/lib/db-daemon-client.js +2 -2
  75. package/dist/lib/db.js +115 -3
  76. package/dist/lib/device-registry.js +115 -3
  77. package/dist/lib/embedder.js +2 -2
  78. package/dist/lib/employee-templates.js +3 -3
  79. package/dist/lib/employees.js +2 -2
  80. package/dist/lib/exe-daemon-client.js +2 -2
  81. package/dist/lib/exe-daemon.js +339 -31
  82. package/dist/lib/hybrid-search.js +306 -8
  83. package/dist/lib/identity.js +2 -2
  84. package/dist/lib/license.js +2 -2
  85. package/dist/lib/messaging.js +2 -2
  86. package/dist/lib/reminders.js +2 -2
  87. package/dist/lib/schedules.js +119 -7
  88. package/dist/lib/skill-learning.js +2 -2
  89. package/dist/lib/store.js +282 -7
  90. package/dist/lib/task-router.js +2 -2
  91. package/dist/lib/tasks.js +2 -2
  92. package/dist/lib/tmux-routing.js +2 -2
  93. package/dist/lib/token-spend.js +2 -2
  94. package/dist/mcp/server.js +339 -31
  95. package/dist/mcp/tools/complete-reminder.js +2 -2
  96. package/dist/mcp/tools/create-reminder.js +2 -2
  97. package/dist/mcp/tools/create-task.js +2 -2
  98. package/dist/mcp/tools/deactivate-behavior.js +2 -2
  99. package/dist/mcp/tools/list-reminders.js +2 -2
  100. package/dist/mcp/tools/list-tasks.js +2 -2
  101. package/dist/mcp/tools/send-message.js +2 -2
  102. package/dist/mcp/tools/update-task.js +2 -2
  103. package/dist/runtime/index.js +282 -7
  104. package/dist/tui/App.js +290 -15
  105. package/package.json +3 -2
  106. package/stack.release.json +23 -7
@@ -266,8 +266,8 @@ var init_config = __esm({
266
266
  rerankerAutoTrigger: {
267
267
  enabled: true,
268
268
  broadQueryMinCardinality: 5e4,
269
- fetchTopK: 150,
270
- returnTopK: 5
269
+ fetchTopK: 200,
270
+ returnTopK: 20
271
271
  }
272
272
  },
273
273
  graphRagEnabled: true,
@@ -2937,7 +2937,7 @@ async function ensureSchema() {
2937
2937
  ON session_kills(agent_id);
2938
2938
  `);
2939
2939
  await client.execute(`
2940
- CREATE TABLE IF NOT EXISTS global_procedures (
2940
+ CREATE TABLE IF NOT EXISTS company_procedures (
2941
2941
  id TEXT PRIMARY KEY,
2942
2942
  title TEXT NOT NULL,
2943
2943
  content TEXT NOT NULL,
@@ -2948,6 +2948,73 @@ async function ensureSchema() {
2948
2948
  updated_at TEXT NOT NULL
2949
2949
  )
2950
2950
  `);
2951
+ const legacyProcedureObject = await client.execute({
2952
+ sql: "SELECT type FROM sqlite_master WHERE name = 'global_procedures'",
2953
+ args: []
2954
+ });
2955
+ const legacyProcedureType = legacyProcedureObject.rows[0]?.type == null ? null : String(legacyProcedureObject.rows[0].type);
2956
+ if (legacyProcedureType === "table") {
2957
+ await client.execute(`
2958
+ INSERT OR IGNORE INTO company_procedures
2959
+ (id, title, content, priority, domain, active, created_at, updated_at)
2960
+ SELECT id, title, content, priority, domain, active, created_at, updated_at
2961
+ FROM global_procedures
2962
+ `);
2963
+ await client.executeMultiple(`
2964
+ CREATE TRIGGER IF NOT EXISTS global_procedures_mirror_insert
2965
+ AFTER INSERT ON global_procedures
2966
+ BEGIN
2967
+ INSERT OR IGNORE INTO company_procedures
2968
+ (id, title, content, priority, domain, active, created_at, updated_at)
2969
+ VALUES
2970
+ (NEW.id, NEW.title, NEW.content, NEW.priority, NEW.domain, NEW.active, NEW.created_at, NEW.updated_at);
2971
+ END;
2972
+
2973
+ CREATE TRIGGER IF NOT EXISTS global_procedures_mirror_update
2974
+ AFTER UPDATE ON global_procedures
2975
+ BEGIN
2976
+ UPDATE company_procedures
2977
+ SET title = NEW.title,
2978
+ content = NEW.content,
2979
+ priority = NEW.priority,
2980
+ domain = NEW.domain,
2981
+ active = NEW.active,
2982
+ created_at = NEW.created_at,
2983
+ updated_at = NEW.updated_at
2984
+ WHERE id = OLD.id;
2985
+ END;
2986
+ `);
2987
+ } else {
2988
+ await client.execute(`
2989
+ CREATE VIEW IF NOT EXISTS global_procedures AS
2990
+ SELECT id, title, content, priority, domain, active, created_at, updated_at
2991
+ FROM company_procedures
2992
+ `);
2993
+ await client.executeMultiple(`
2994
+ CREATE TRIGGER IF NOT EXISTS global_procedures_insert
2995
+ INSTEAD OF INSERT ON global_procedures
2996
+ BEGIN
2997
+ INSERT INTO company_procedures
2998
+ (id, title, content, priority, domain, active, created_at, updated_at)
2999
+ VALUES
3000
+ (NEW.id, NEW.title, NEW.content, NEW.priority, NEW.domain, NEW.active, NEW.created_at, NEW.updated_at);
3001
+ END;
3002
+
3003
+ CREATE TRIGGER IF NOT EXISTS global_procedures_update
3004
+ INSTEAD OF UPDATE ON global_procedures
3005
+ BEGIN
3006
+ UPDATE company_procedures
3007
+ SET title = NEW.title,
3008
+ content = NEW.content,
3009
+ priority = NEW.priority,
3010
+ domain = NEW.domain,
3011
+ active = NEW.active,
3012
+ created_at = NEW.created_at,
3013
+ updated_at = NEW.updated_at
3014
+ WHERE id = OLD.id;
3015
+ END;
3016
+ `);
3017
+ }
2951
3018
  await client.executeMultiple(`
2952
3019
  CREATE TABLE IF NOT EXISTS conversations (
2953
3020
  id TEXT PRIMARY KEY,
@@ -3087,6 +3154,51 @@ async function ensureSchema() {
3087
3154
  VALUES (new.rowid, new.content_text, new.sender_name, new.agent_response);
3088
3155
  END;
3089
3156
  `);
3157
+ await client.executeMultiple(`
3158
+ CREATE TABLE IF NOT EXISTS memory_cards (
3159
+ id TEXT PRIMARY KEY,
3160
+ memory_id TEXT NOT NULL,
3161
+ agent_id TEXT NOT NULL,
3162
+ session_id TEXT NOT NULL,
3163
+ project_name TEXT,
3164
+ timestamp TEXT NOT NULL,
3165
+ card_type TEXT NOT NULL,
3166
+ subject TEXT,
3167
+ predicate TEXT,
3168
+ object TEXT,
3169
+ content TEXT NOT NULL,
3170
+ source_ref TEXT,
3171
+ confidence REAL DEFAULT 0.6,
3172
+ active INTEGER DEFAULT 1,
3173
+ created_at TEXT NOT NULL
3174
+ );
3175
+
3176
+ CREATE INDEX IF NOT EXISTS idx_memory_cards_agent
3177
+ ON memory_cards(agent_id, active, timestamp);
3178
+
3179
+ CREATE INDEX IF NOT EXISTS idx_memory_cards_memory
3180
+ ON memory_cards(memory_id);
3181
+
3182
+ CREATE VIRTUAL TABLE IF NOT EXISTS memory_cards_fts
3183
+ USING fts5(content, subject, predicate, object, content='memory_cards', content_rowid='rowid');
3184
+
3185
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ai AFTER INSERT ON memory_cards BEGIN
3186
+ INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
3187
+ VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
3188
+ END;
3189
+
3190
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ad AFTER DELETE ON memory_cards BEGIN
3191
+ INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
3192
+ VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
3193
+ END;
3194
+
3195
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_au AFTER UPDATE ON memory_cards BEGIN
3196
+ INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
3197
+ VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
3198
+ INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
3199
+ VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
3200
+ END;
3201
+ `);
3090
3202
  try {
3091
3203
  await client.execute({
3092
3204
  sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
@@ -4394,7 +4506,7 @@ var init_platform_procedures = __esm({
4394
4506
  title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
4395
4507
  domain: "tool-use",
4396
4508
  priority: "p1",
4397
- 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."
4509
+ 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. company_procedure: manage customer-owned company procedures (Layer 0; actions: store, list, deactivate). Legacy aliases: global_procedure, store_global_procedure, list_global_procedures, deactivate_global_procedure."
4398
4510
  }
4399
4511
  ];
4400
4512
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -4415,7 +4527,7 @@ import { randomUUID as randomUUID2 } from "crypto";
4415
4527
  async function loadGlobalProcedures() {
4416
4528
  const client = getClient();
4417
4529
  const result = await client.execute({
4418
- sql: "SELECT * FROM global_procedures WHERE active = 1 ORDER BY priority ASC, created_at ASC",
4530
+ sql: "SELECT * FROM company_procedures WHERE active = 1 ORDER BY priority ASC, created_at ASC",
4419
4531
  args: []
4420
4532
  });
4421
4533
  const allRows = result.rows;
@@ -4444,7 +4556,7 @@ async function storeGlobalProcedure(input) {
4444
4556
  const now = (/* @__PURE__ */ new Date()).toISOString();
4445
4557
  const client = getClient();
4446
4558
  await client.execute({
4447
- sql: `INSERT INTO global_procedures (id, title, content, priority, domain, active, created_at, updated_at)
4559
+ sql: `INSERT INTO company_procedures (id, title, content, priority, domain, active, created_at, updated_at)
4448
4560
  VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
4449
4561
  args: [id, input.title, input.content, input.priority ?? "p0", input.domain ?? null, now, now]
4450
4562
  });
@@ -4455,7 +4567,7 @@ async function deactivateGlobalProcedure(id) {
4455
4567
  const now = (/* @__PURE__ */ new Date()).toISOString();
4456
4568
  const client = getClient();
4457
4569
  const result = await client.execute({
4458
- sql: "UPDATE global_procedures SET active = 0, updated_at = ? WHERE id = ?",
4570
+ sql: "UPDATE company_procedures SET active = 0, updated_at = ? WHERE id = ?",
4459
4571
  args: [now, id]
4460
4572
  });
4461
4573
  await loadGlobalProcedures();
@@ -4474,6 +4586,164 @@ ${p.content}`).join("\n\n");
4474
4586
  }
4475
4587
  });
4476
4588
 
4589
+ // src/lib/memory-cards.ts
4590
+ var memory_cards_exports = {};
4591
+ __export(memory_cards_exports, {
4592
+ extractMemoryCards: () => extractMemoryCards,
4593
+ insertMemoryCardsForBatch: () => insertMemoryCardsForBatch,
4594
+ searchMemoryCards: () => searchMemoryCards
4595
+ });
4596
+ import { createHash as createHash2 } from "crypto";
4597
+ function stableId(memoryId, type, content) {
4598
+ return createHash2("sha256").update(`${memoryId}:${type}:${content}`).digest("hex").slice(0, 32);
4599
+ }
4600
+ function cleanText(text3) {
4601
+ return text3.replace(/```[\s\S]*?```/g, " ").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
4602
+ }
4603
+ function splitSentences(text3) {
4604
+ return cleanText(text3).split(/(?<=[.!?])\s+|\n+/).map((s) => s.trim()).filter((s) => s.length >= 24 && s.length <= MAX_SENTENCE_CHARS);
4605
+ }
4606
+ function inferCardType(sentence, toolName) {
4607
+ const lower = sentence.toLowerCase();
4608
+ if (toolName === "store_decision" || /\b(decided|decision|adr|approved|rejected)\b/.test(lower)) return "decision";
4609
+ if (/\b(prefers|preference|likes|dislikes|wants|doesn't want|does not want)\b/.test(lower)) return "preference";
4610
+ if (/\b(changed|updated|replaced|now|no longer|instead|supersedes)\b/.test(lower)) return "belief_update";
4611
+ if (toolName && ["Read", "Write", "Edit", "Bash"].includes(toolName)) return "code";
4612
+ if (/\b(meeting|deadline|shipped|launched|completed|failed|blocked|assigned|created)\b/.test(lower)) return "event";
4613
+ return "fact";
4614
+ }
4615
+ function extractSubject(sentence, agentId) {
4616
+ const explicit = sentence.match(/\b([A-Z][a-zA-Z0-9_-]{2,}(?:\s+[A-Z][a-zA-Z0-9_-]{2,})?)\b/);
4617
+ return explicit?.[1] ?? agentId;
4618
+ }
4619
+ function predicateFor(type) {
4620
+ switch (type) {
4621
+ case "preference":
4622
+ return "prefers";
4623
+ case "belief_update":
4624
+ return "updated";
4625
+ case "decision":
4626
+ return "decided";
4627
+ case "event":
4628
+ return "happened";
4629
+ case "code":
4630
+ return "implemented";
4631
+ default:
4632
+ return "states";
4633
+ }
4634
+ }
4635
+ function extractMemoryCards(row) {
4636
+ const sentences = splitSentences(row.raw_text);
4637
+ const cards = [];
4638
+ for (const sentence of sentences) {
4639
+ const type = inferCardType(sentence, row.tool_name);
4640
+ const subject = extractSubject(sentence, row.agent_id);
4641
+ const content = sentence.length > MAX_SENTENCE_CHARS ? `${sentence.slice(0, MAX_SENTENCE_CHARS - 1)}\u2026` : sentence;
4642
+ cards.push({
4643
+ id: stableId(row.id, type, content),
4644
+ memory_id: row.id,
4645
+ agent_id: row.agent_id,
4646
+ session_id: row.session_id,
4647
+ project_name: row.project_name ?? null,
4648
+ timestamp: row.timestamp,
4649
+ card_type: type,
4650
+ subject,
4651
+ predicate: predicateFor(type),
4652
+ object: content,
4653
+ content,
4654
+ source_ref: row.id,
4655
+ confidence: type === "fact" ? 0.55 : 0.65
4656
+ });
4657
+ if (cards.length >= MAX_CARDS_PER_MEMORY) break;
4658
+ }
4659
+ return cards;
4660
+ }
4661
+ async function insertMemoryCardsForBatch(rows) {
4662
+ const cards = rows.flatMap(extractMemoryCards);
4663
+ if (cards.length === 0) return 0;
4664
+ const now = (/* @__PURE__ */ new Date()).toISOString();
4665
+ const client = getClient();
4666
+ const stmts = cards.map((card) => ({
4667
+ sql: `INSERT OR IGNORE INTO memory_cards
4668
+ (id, memory_id, agent_id, session_id, project_name, timestamp, card_type,
4669
+ subject, predicate, object, content, source_ref, confidence, active, created_at)
4670
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?)`,
4671
+ args: [
4672
+ card.id,
4673
+ card.memory_id,
4674
+ card.agent_id,
4675
+ card.session_id,
4676
+ card.project_name,
4677
+ card.timestamp,
4678
+ card.card_type,
4679
+ card.subject,
4680
+ card.predicate,
4681
+ card.object,
4682
+ card.content,
4683
+ card.source_ref,
4684
+ card.confidence,
4685
+ now
4686
+ ]
4687
+ }));
4688
+ await client.batch(stmts, "write");
4689
+ return cards.length;
4690
+ }
4691
+ function buildMatchExpr(queryText) {
4692
+ const terms = queryText.toLowerCase().split(/\s+/).filter((t) => t.length >= 3).map((t) => t.replace(/[^a-z0-9_]/g, "")).filter((t) => t.length >= 3).slice(0, 12);
4693
+ if (terms.length === 0) return null;
4694
+ return terms.map((t) => `${t}*`).join(terms.length >= 3 ? " AND " : " OR ");
4695
+ }
4696
+ async function searchMemoryCards(queryText, agentId, options) {
4697
+ const limit = options?.limit ?? 10;
4698
+ const matchExpr = buildMatchExpr(queryText);
4699
+ if (!matchExpr) return [];
4700
+ let sql = `SELECT c.id, c.memory_id, c.agent_id, c.session_id, c.project_name,
4701
+ c.timestamp, c.card_type, c.content, c.source_ref, c.confidence
4702
+ FROM memory_cards c
4703
+ JOIN memory_cards_fts fts ON c.rowid = fts.rowid
4704
+ WHERE memory_cards_fts MATCH ?
4705
+ AND c.agent_id = ?
4706
+ AND COALESCE(c.active, 1) = 1`;
4707
+ const args = [matchExpr, agentId];
4708
+ if (options?.projectName) {
4709
+ sql += ` AND c.project_name = ?`;
4710
+ args.push(options.projectName);
4711
+ }
4712
+ if (options?.since) {
4713
+ sql += ` AND c.timestamp >= ?`;
4714
+ args.push(options.since);
4715
+ }
4716
+ sql += ` ORDER BY rank LIMIT ?`;
4717
+ args.push(limit);
4718
+ const result = await getClient().execute({ sql, args });
4719
+ return result.rows.map((row) => ({
4720
+ id: `card:${String(row.id)}`,
4721
+ agent_id: String(row.agent_id),
4722
+ agent_role: "memory_card",
4723
+ session_id: String(row.session_id),
4724
+ timestamp: String(row.timestamp),
4725
+ tool_name: `memory_card:${String(row.card_type)}`,
4726
+ project_name: row.project_name == null ? "" : String(row.project_name),
4727
+ has_error: false,
4728
+ raw_text: `[${String(row.card_type)}] ${String(row.content)}
4729
+ Source memory: ${String(row.source_ref ?? row.memory_id)}`,
4730
+ vector: [],
4731
+ importance: 6,
4732
+ status: "active",
4733
+ confidence: Number(row.confidence ?? 0.6),
4734
+ last_accessed: String(row.timestamp)
4735
+ }));
4736
+ }
4737
+ var MAX_CARDS_PER_MEMORY, MAX_SENTENCE_CHARS;
4738
+ var init_memory_cards = __esm({
4739
+ "src/lib/memory-cards.ts"() {
4740
+ "use strict";
4741
+ init_database();
4742
+ MAX_CARDS_PER_MEMORY = 6;
4743
+ MAX_SENTENCE_CHARS = 360;
4744
+ }
4745
+ });
4746
+
4477
4747
  // src/lib/store.ts
4478
4748
  var store_exports = {};
4479
4749
  __export(store_exports, {
@@ -4812,6 +5082,11 @@ async function flushBatch() {
4812
5082
  const globalClient = getClient();
4813
5083
  const globalStmts = batch.map(buildStmt);
4814
5084
  await globalClient.batch(globalStmts, "write");
5085
+ try {
5086
+ const { insertMemoryCardsForBatch: insertMemoryCardsForBatch2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
5087
+ await insertMemoryCardsForBatch2(batch);
5088
+ } catch {
5089
+ }
4815
5090
  schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
4816
5091
  _pendingRecords.splice(0, batch.length);
4817
5092
  try {
@@ -6252,9 +6527,18 @@ async function hybridSearch(queryText, agentId, options) {
6252
6527
  } catch {
6253
6528
  }
6254
6529
  }
6255
- const [ftsResults, vectorResults, grepResults] = await Promise.all([
6530
+ const includeStructuredCards = effectiveIsBroad || effectiveOptions.includeStructuredCards === true;
6531
+ const [ftsResults, vectorResults, cardResults, grepResults] = await Promise.all([
6256
6532
  lightweightSearch(effectiveQuery, agentId, fetchOptions),
6257
6533
  queryVector ? searchMemories(queryVector, agentId, fetchOptions) : Promise.resolve([]),
6534
+ includeStructuredCards ? (async () => {
6535
+ try {
6536
+ const { searchMemoryCards: searchMemoryCards2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
6537
+ return await searchMemoryCards2(effectiveQuery, agentId, fetchOptions);
6538
+ } catch {
6539
+ return [];
6540
+ }
6541
+ })() : Promise.resolve([]),
6258
6542
  grepPromise
6259
6543
  ]);
6260
6544
  const lists = [];
@@ -6267,6 +6551,10 @@ async function hybridSearch(queryText, agentId, options) {
6267
6551
  lists.push(vectorResults);
6268
6552
  weights.push(1);
6269
6553
  }
6554
+ if (cardResults.length > 0) {
6555
+ lists.push(cardResults);
6556
+ weights.push(1.2);
6557
+ }
6270
6558
  if (grepResults.length > 0) {
6271
6559
  lists.push(grepResults);
6272
6560
  weights.push(0.5);
@@ -6335,6 +6623,7 @@ async function hybridSearch(queryText, agentId, options) {
6335
6623
  signals: {
6336
6624
  fts: ftsResults.length,
6337
6625
  vector: vectorResults.length,
6626
+ cards: cardResults.length,
6338
6627
  grep: grepResults.length,
6339
6628
  entityBoost: entityBoostRan,
6340
6629
  reranker: rerankedAndBlended !== null,
@@ -6484,6 +6773,15 @@ async function lightweightSearch(queryText, agentId, options) {
6484
6773
  if (options?.includeSource && results.length > 0) {
6485
6774
  await attachDocumentMetadata(results);
6486
6775
  }
6776
+ if (options?.includeStructuredCards !== true) return results;
6777
+ try {
6778
+ const { searchMemoryCards: searchMemoryCards2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
6779
+ const cardResults = await searchMemoryCards2(queryText, agentId, options);
6780
+ if (cardResults.length > 0) {
6781
+ return rrfMergeMulti([results, cardResults], limit, RRF_K, [1, 1.2]);
6782
+ }
6783
+ } catch {
6784
+ }
6487
6785
  return results;
6488
6786
  }
6489
6787
  async function ftsQuery(client, matchExpr, agentId, options, limit) {
@@ -11580,7 +11878,7 @@ __export(identity_exports, {
11580
11878
  import { existsSync as existsSync20, mkdirSync as mkdirSync10, readFileSync as readFileSync15, writeFileSync as writeFileSync12 } from "fs";
11581
11879
  import { readdirSync as readdirSync7 } from "fs";
11582
11880
  import path26 from "path";
11583
- import { createHash as createHash2 } from "crypto";
11881
+ import { createHash as createHash3 } from "crypto";
11584
11882
  function ensureDir2() {
11585
11883
  if (!existsSync20(IDENTITY_DIR2)) {
11586
11884
  mkdirSync10(IDENTITY_DIR2, { recursive: true });
@@ -11627,7 +11925,7 @@ function parseFrontmatter(raw) {
11627
11925
  };
11628
11926
  }
11629
11927
  function contentHash(content) {
11630
- return createHash2("sha256").update(content).digest("hex").slice(0, 16);
11928
+ return createHash3("sha256").update(content).digest("hex").slice(0, 16);
11631
11929
  }
11632
11930
  function getIdentity(agentId) {
11633
11931
  const filePath = identityPath(agentId);
@@ -19860,12 +20158,12 @@ async function cloudSync(config2) {
19860
20158
  try {
19861
20159
  await cloudPushGlobalProcedures(config2);
19862
20160
  } catch (err) {
19863
- logError(`[cloud-sync] Global procedures push: ${err instanceof Error ? err.message : String(err)}`);
20161
+ logError(`[cloud-sync] Company procedures push: ${err instanceof Error ? err.message : String(err)}`);
19864
20162
  }
19865
20163
  try {
19866
20164
  await cloudPullGlobalProcedures(config2);
19867
20165
  } catch (err) {
19868
- logError(`[cloud-sync] Global procedures pull: ${err instanceof Error ? err.message : String(err)}`);
20166
+ logError(`[cloud-sync] Company procedures pull: ${err instanceof Error ? err.message : String(err)}`);
19869
20167
  }
19870
20168
  const countRows = async (sql) => {
19871
20169
  try {
@@ -20264,12 +20562,12 @@ async function cloudPullBlob(route, config2) {
20264
20562
  }
20265
20563
  async function cloudPushGlobalProcedures(config2) {
20266
20564
  const client = getClient();
20267
- const result = await client.execute("SELECT * FROM global_procedures LIMIT 1000");
20565
+ const result = await client.execute("SELECT * FROM company_procedures LIMIT 1000");
20268
20566
  const rows = result.rows;
20269
20567
  const { ok } = await cloudPushBlob(
20270
20568
  "/sync/push-global-procedures",
20271
20569
  rows,
20272
- "last_global_procedures_push_version",
20570
+ "last_company_procedures_push_version",
20273
20571
  config2
20274
20572
  );
20275
20573
  return ok;
@@ -20282,7 +20580,7 @@ async function cloudPullGlobalProcedures(config2) {
20282
20580
  if (!remoteProcs || remoteProcs.length === 0) return { pulled: 0 };
20283
20581
  const client = getClient();
20284
20582
  const stmts = remoteProcs.map((p) => ({
20285
- sql: `INSERT INTO global_procedures
20583
+ sql: `INSERT INTO company_procedures
20286
20584
  (id, title, content, priority, domain, active, created_at, updated_at)
20287
20585
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)
20288
20586
  ON CONFLICT(id) DO UPDATE SET
@@ -20292,7 +20590,7 @@ async function cloudPullGlobalProcedures(config2) {
20292
20590
  domain = excluded.domain,
20293
20591
  active = excluded.active,
20294
20592
  updated_at = excluded.updated_at
20295
- WHERE excluded.updated_at > global_procedures.updated_at`,
20593
+ WHERE excluded.updated_at > company_procedures.updated_at`,
20296
20594
  args: [
20297
20595
  sqlSafe(p.id),
20298
20596
  sqlSafe(p.title),
@@ -22935,7 +23233,7 @@ async function insertProcedures(procedures, timestamp, options) {
22935
23233
  continue;
22936
23234
  }
22937
23235
  await client.execute({
22938
- sql: `INSERT INTO global_procedures (id, title, content, priority, domain, active, created_at, updated_at)
23236
+ sql: `INSERT INTO company_procedures (id, title, content, priority, domain, active, created_at, updated_at)
22939
23237
  VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
22940
23238
  args: [
22941
23239
  randomUUID8(),
@@ -23017,7 +23315,7 @@ async function importIdentities(identities, updatedBy) {
23017
23315
  async function getActiveProcedureTitles() {
23018
23316
  const client = getClient();
23019
23317
  const result = await client.execute({
23020
- sql: "SELECT title FROM global_procedures WHERE active = 1",
23318
+ sql: "SELECT title FROM company_procedures WHERE active = 1",
23021
23319
  args: []
23022
23320
  });
23023
23321
  return new Set(result.rows.map((row) => String(row.title)));
@@ -23040,7 +23338,7 @@ async function exportOrchestration(createdBy) {
23040
23338
  args: []
23041
23339
  });
23042
23340
  const procedureResult = await client.execute({
23043
- sql: "SELECT title, content, priority, domain FROM global_procedures WHERE active = 1",
23341
+ sql: "SELECT title, content, priority, domain FROM company_procedures WHERE active = 1",
23044
23342
  args: []
23045
23343
  });
23046
23344
  const behaviors = behaviorResult.rows.map((row) => ({
@@ -23237,9 +23535,9 @@ init_active_agent();
23237
23535
  init_database();
23238
23536
  init_employees();
23239
23537
  import { z as z71 } from "zod";
23240
- function registerGlobalProcedure(server2) {
23538
+ function registerCompanyProcedureTool(server2, toolName) {
23241
23539
  server2.registerTool(
23242
- "global_procedure",
23540
+ toolName,
23243
23541
  {
23244
23542
  title: "Company Procedure",
23245
23543
  description: "Manage company procedures (customer-owned Layer 0 rules) that supersede identity, expertise, and experience. Actions: store (create new, restricted), list (view all, open), deactivate (soft-delete, restricted).",
@@ -23249,7 +23547,7 @@ function registerGlobalProcedure(server2) {
23249
23547
  content: z71.string().max(500).optional().describe("The procedure content \u2014 clear, actionable instruction (store)"),
23250
23548
  priority: z71.enum(["p0", "p1", "p2"]).optional().describe("Priority tier. p0 = always (default). p1 = standard. p2 = nice-to-have."),
23251
23549
  domain: z71.string().optional().describe("Category: workflow, code-style, communication, architecture, testing, security"),
23252
- procedure_id: z71.string().optional().describe("UUID of the global procedure (deactivate)")
23550
+ procedure_id: z71.string().optional().describe("UUID of the company procedure (deactivate)")
23253
23551
  }
23254
23552
  },
23255
23553
  async ({ action, title, content, priority, domain, procedure_id }) => {
@@ -23260,7 +23558,7 @@ function registerGlobalProcedure(server2) {
23260
23558
  content: [{
23261
23559
  type: "text",
23262
23560
  text: `No custom company procedures. ${PLATFORM_PROCEDURES.length} platform procedures are active (shipped with exe-os, not editable).
23263
- Use global_procedure with action "store" to add company-specific rules.`
23561
+ Use company_procedure with action "store" to add company-specific rules.`
23264
23562
  }]
23265
23563
  };
23266
23564
  }
@@ -23326,7 +23624,7 @@ Domain: ${domain ?? "none"}`
23326
23624
  }
23327
23625
  const client = getClient();
23328
23626
  const result = await client.execute({
23329
- sql: "SELECT id, title, content, priority, domain FROM global_procedures WHERE id = ?",
23627
+ sql: "SELECT id, title, content, priority, domain FROM company_procedures WHERE id = ?",
23330
23628
  args: [procedure_id]
23331
23629
  });
23332
23630
  if (result.rows.length === 0) {
@@ -23344,7 +23642,7 @@ Domain: ${domain ?? "none"}`
23344
23642
  return {
23345
23643
  content: [{
23346
23644
  type: "text",
23347
- text: `Global procedure ${procedure_id} was already inactive.`
23645
+ text: `Company procedure ${procedure_id} was already inactive.`
23348
23646
  }]
23349
23647
  };
23350
23648
  }
@@ -23362,6 +23660,12 @@ Content: ${row.content}`
23362
23660
  }
23363
23661
  );
23364
23662
  }
23663
+ function registerCompanyProcedure(server2) {
23664
+ registerCompanyProcedureTool(server2, "company_procedure");
23665
+ }
23666
+ function registerGlobalProcedure(server2) {
23667
+ registerCompanyProcedureTool(server2, "global_procedure");
23668
+ }
23365
23669
 
23366
23670
  // src/mcp/tools/config.ts
23367
23671
  var ACTION_TO_TOOL2 = {
@@ -23388,6 +23692,7 @@ var ACTION_TO_TOOL2 = {
23388
23692
  load_skill: "load_skill",
23389
23693
  export_orchestration: "export_orchestration",
23390
23694
  import_orchestration: "import_orchestration",
23695
+ company_procedure: "company_procedure",
23391
23696
  global_procedure: "global_procedure"
23392
23697
  };
23393
23698
  function errorResult8(text3) {
@@ -23423,6 +23728,7 @@ function buildHandlers5() {
23423
23728
  registerLoadSkill(localServer);
23424
23729
  registerExportOrchestration(localServer);
23425
23730
  registerImportOrchestration(localServer);
23731
+ registerCompanyProcedure(localServer);
23426
23732
  registerGlobalProcedure(localServer);
23427
23733
  return tools;
23428
23734
  }
@@ -23463,7 +23769,7 @@ function registerConfig(server2) {
23463
23769
  priority: z72.enum(["p0", "p1", "p2"]).optional().describe("Procedure priority"),
23464
23770
  domain: z72.string().optional().describe("Procedure domain"),
23465
23771
  procedure_id: z72.string().optional().describe("Procedure id for deactivate"),
23466
- subaction: z72.enum(["store", "list", "deactivate"]).optional().describe("Nested action for global_procedure"),
23772
+ subaction: z72.enum(["store", "list", "deactivate"]).optional().describe("Nested action for company_procedure/global_procedure"),
23467
23773
  max_clusters: z72.coerce.number().optional().describe("Consolidation max clusters"),
23468
23774
  force: z72.boolean().optional().describe("Force operation where supported"),
23469
23775
  domain_name: z72.string().optional().describe("Client deployment domain")
@@ -23471,14 +23777,14 @@ function registerConfig(server2) {
23471
23777
  }, async (input, extra) => {
23472
23778
  const action = input.action;
23473
23779
  const { action: _action, subaction, ...args } = input;
23474
- if (action === "global_procedure") {
23780
+ if (action === "company_procedure" || action === "global_procedure") {
23475
23781
  args.action = subaction ?? "list";
23476
23782
  }
23477
23783
  if (action === "export_orchestration" && !args.output_path) return errorResult8('config action "export_orchestration" requires output_path');
23478
23784
  if (action === "import_orchestration" && !args.input_path) return errorResult8('config action "import_orchestration" requires input_path');
23479
23785
  if (action === "activate_license" && !args.license_key) return errorResult8('config action "activate_license" requires license_key');
23480
23786
  if (action === "create_trigger" && (!args.name || !args.event || !Array.isArray(args.actions))) return errorResult8('config action "create_trigger" requires name, event, and actions');
23481
- if (action === "global_procedure" && args.action === "store" && (!args.title || !args.content)) return errorResult8('config action "global_procedure" subaction=store requires title and content');
23787
+ if ((action === "company_procedure" || action === "global_procedure") && args.action === "store" && (!args.title || !args.content)) return errorResult8(`config action "${action}" subaction=store requires title and content`);
23482
23788
  const toolName = ACTION_TO_TOOL2[action];
23483
23789
  const tool = legacy.get(toolName);
23484
23790
  if (!tool) return errorResult8(`Legacy config handler not found for action "${action}" (${toolName})`);
@@ -24181,7 +24487,7 @@ function registerDeactivateGlobalProcedure(server2) {
24181
24487
  title: "Deactivate Company Procedure (use global_procedure instead)",
24182
24488
  description: "DEPRECATED \u2014 use global_procedure with action='deactivate'. Soft-delete a company procedure. RESTRICTED: only coordinator or founder sessions.",
24183
24489
  inputSchema: {
24184
- procedure_id: z79.string().describe("UUID of the global procedure to deactivate")
24490
+ procedure_id: z79.string().describe("UUID of the company procedure to deactivate")
24185
24491
  }
24186
24492
  },
24187
24493
  async ({ procedure_id }) => {
@@ -24198,7 +24504,7 @@ function registerDeactivateGlobalProcedure(server2) {
24198
24504
  }
24199
24505
  const client = getClient();
24200
24506
  const result = await client.execute({
24201
- sql: "SELECT id, title, content, priority, domain FROM global_procedures WHERE id = ?",
24507
+ sql: "SELECT id, title, content, priority, domain FROM company_procedures WHERE id = ?",
24202
24508
  args: [procedure_id]
24203
24509
  });
24204
24510
  if (result.rows.length === 0) {
@@ -24216,7 +24522,7 @@ function registerDeactivateGlobalProcedure(server2) {
24216
24522
  return {
24217
24523
  content: [{
24218
24524
  type: "text",
24219
- text: `Global procedure ${procedure_id} was already inactive.`
24525
+ text: `Company procedure ${procedure_id} was already inactive.`
24220
24526
  }]
24221
24527
  };
24222
24528
  }
@@ -25160,6 +25466,7 @@ var TOOL_CATEGORIES = {
25160
25466
  registerLoadSkill: "orchestration",
25161
25467
  registerExportOrchestration: "orchestration",
25162
25468
  registerImportOrchestration: "orchestration",
25469
+ registerCompanyProcedure: "orchestration",
25163
25470
  registerGlobalProcedure: "orchestration",
25164
25471
  registerStoreGlobalProcedure: "orchestration",
25165
25472
  registerListGlobalProcedures: "orchestration",
@@ -25316,6 +25623,7 @@ function registerAllTools(server2) {
25316
25623
  gate("registerConsolidateMemories", registerConsolidateMemories);
25317
25624
  }
25318
25625
  if (exposeLegacyConfig) {
25626
+ gate("registerCompanyProcedure", registerCompanyProcedure);
25319
25627
  gate("registerGlobalProcedure", registerGlobalProcedure);
25320
25628
  gate("registerStoreGlobalProcedure", registerStoreGlobalProcedure);
25321
25629
  gate("registerListGlobalProcedures", registerListGlobalProcedures);
@@ -68,8 +68,8 @@ var init_config = __esm({
68
68
  rerankerAutoTrigger: {
69
69
  enabled: true,
70
70
  broadQueryMinCardinality: 5e4,
71
- fetchTopK: 150,
72
- returnTopK: 5
71
+ fetchTopK: 200,
72
+ returnTopK: 20
73
73
  }
74
74
  },
75
75
  graphRagEnabled: true,
@@ -68,8 +68,8 @@ var init_config = __esm({
68
68
  rerankerAutoTrigger: {
69
69
  enabled: true,
70
70
  broadQueryMinCardinality: 5e4,
71
- fetchTopK: 150,
72
- returnTopK: 5
71
+ fetchTopK: 200,
72
+ returnTopK: 20
73
73
  }
74
74
  },
75
75
  graphRagEnabled: true,
@@ -264,8 +264,8 @@ var init_config = __esm({
264
264
  rerankerAutoTrigger: {
265
265
  enabled: true,
266
266
  broadQueryMinCardinality: 5e4,
267
- fetchTopK: 150,
268
- returnTopK: 5
267
+ fetchTopK: 200,
268
+ returnTopK: 20
269
269
  }
270
270
  },
271
271
  graphRagEnabled: true,