@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
package/dist/index.js CHANGED
@@ -257,8 +257,8 @@ var init_config = __esm({
257
257
  rerankerAutoTrigger: {
258
258
  enabled: true,
259
259
  broadQueryMinCardinality: 5e4,
260
- fetchTopK: 150,
261
- returnTopK: 5
260
+ fetchTopK: 200,
261
+ returnTopK: 20
262
262
  }
263
263
  },
264
264
  graphRagEnabled: true,
@@ -3303,7 +3303,7 @@ async function ensureSchema() {
3303
3303
  ON session_kills(agent_id);
3304
3304
  `);
3305
3305
  await client.execute(`
3306
- CREATE TABLE IF NOT EXISTS global_procedures (
3306
+ CREATE TABLE IF NOT EXISTS company_procedures (
3307
3307
  id TEXT PRIMARY KEY,
3308
3308
  title TEXT NOT NULL,
3309
3309
  content TEXT NOT NULL,
@@ -3314,6 +3314,73 @@ async function ensureSchema() {
3314
3314
  updated_at TEXT NOT NULL
3315
3315
  )
3316
3316
  `);
3317
+ const legacyProcedureObject = await client.execute({
3318
+ sql: "SELECT type FROM sqlite_master WHERE name = 'global_procedures'",
3319
+ args: []
3320
+ });
3321
+ const legacyProcedureType = legacyProcedureObject.rows[0]?.type == null ? null : String(legacyProcedureObject.rows[0].type);
3322
+ if (legacyProcedureType === "table") {
3323
+ await client.execute(`
3324
+ INSERT OR IGNORE INTO company_procedures
3325
+ (id, title, content, priority, domain, active, created_at, updated_at)
3326
+ SELECT id, title, content, priority, domain, active, created_at, updated_at
3327
+ FROM global_procedures
3328
+ `);
3329
+ await client.executeMultiple(`
3330
+ CREATE TRIGGER IF NOT EXISTS global_procedures_mirror_insert
3331
+ AFTER INSERT ON global_procedures
3332
+ BEGIN
3333
+ INSERT OR IGNORE INTO company_procedures
3334
+ (id, title, content, priority, domain, active, created_at, updated_at)
3335
+ VALUES
3336
+ (NEW.id, NEW.title, NEW.content, NEW.priority, NEW.domain, NEW.active, NEW.created_at, NEW.updated_at);
3337
+ END;
3338
+
3339
+ CREATE TRIGGER IF NOT EXISTS global_procedures_mirror_update
3340
+ AFTER UPDATE ON global_procedures
3341
+ BEGIN
3342
+ UPDATE company_procedures
3343
+ SET title = NEW.title,
3344
+ content = NEW.content,
3345
+ priority = NEW.priority,
3346
+ domain = NEW.domain,
3347
+ active = NEW.active,
3348
+ created_at = NEW.created_at,
3349
+ updated_at = NEW.updated_at
3350
+ WHERE id = OLD.id;
3351
+ END;
3352
+ `);
3353
+ } else {
3354
+ await client.execute(`
3355
+ CREATE VIEW IF NOT EXISTS global_procedures AS
3356
+ SELECT id, title, content, priority, domain, active, created_at, updated_at
3357
+ FROM company_procedures
3358
+ `);
3359
+ await client.executeMultiple(`
3360
+ CREATE TRIGGER IF NOT EXISTS global_procedures_insert
3361
+ INSTEAD OF INSERT ON global_procedures
3362
+ BEGIN
3363
+ INSERT INTO company_procedures
3364
+ (id, title, content, priority, domain, active, created_at, updated_at)
3365
+ VALUES
3366
+ (NEW.id, NEW.title, NEW.content, NEW.priority, NEW.domain, NEW.active, NEW.created_at, NEW.updated_at);
3367
+ END;
3368
+
3369
+ CREATE TRIGGER IF NOT EXISTS global_procedures_update
3370
+ INSTEAD OF UPDATE ON global_procedures
3371
+ BEGIN
3372
+ UPDATE company_procedures
3373
+ SET title = NEW.title,
3374
+ content = NEW.content,
3375
+ priority = NEW.priority,
3376
+ domain = NEW.domain,
3377
+ active = NEW.active,
3378
+ created_at = NEW.created_at,
3379
+ updated_at = NEW.updated_at
3380
+ WHERE id = OLD.id;
3381
+ END;
3382
+ `);
3383
+ }
3317
3384
  await client.executeMultiple(`
3318
3385
  CREATE TABLE IF NOT EXISTS conversations (
3319
3386
  id TEXT PRIMARY KEY,
@@ -3453,6 +3520,51 @@ async function ensureSchema() {
3453
3520
  VALUES (new.rowid, new.content_text, new.sender_name, new.agent_response);
3454
3521
  END;
3455
3522
  `);
3523
+ await client.executeMultiple(`
3524
+ CREATE TABLE IF NOT EXISTS memory_cards (
3525
+ id TEXT PRIMARY KEY,
3526
+ memory_id TEXT NOT NULL,
3527
+ agent_id TEXT NOT NULL,
3528
+ session_id TEXT NOT NULL,
3529
+ project_name TEXT,
3530
+ timestamp TEXT NOT NULL,
3531
+ card_type TEXT NOT NULL,
3532
+ subject TEXT,
3533
+ predicate TEXT,
3534
+ object TEXT,
3535
+ content TEXT NOT NULL,
3536
+ source_ref TEXT,
3537
+ confidence REAL DEFAULT 0.6,
3538
+ active INTEGER DEFAULT 1,
3539
+ created_at TEXT NOT NULL
3540
+ );
3541
+
3542
+ CREATE INDEX IF NOT EXISTS idx_memory_cards_agent
3543
+ ON memory_cards(agent_id, active, timestamp);
3544
+
3545
+ CREATE INDEX IF NOT EXISTS idx_memory_cards_memory
3546
+ ON memory_cards(memory_id);
3547
+
3548
+ CREATE VIRTUAL TABLE IF NOT EXISTS memory_cards_fts
3549
+ USING fts5(content, subject, predicate, object, content='memory_cards', content_rowid='rowid');
3550
+
3551
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ai AFTER INSERT ON memory_cards BEGIN
3552
+ INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
3553
+ VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
3554
+ END;
3555
+
3556
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ad AFTER DELETE ON memory_cards BEGIN
3557
+ INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
3558
+ VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
3559
+ END;
3560
+
3561
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_au AFTER UPDATE ON memory_cards BEGIN
3562
+ INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
3563
+ VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
3564
+ INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
3565
+ VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
3566
+ END;
3567
+ `);
3456
3568
  try {
3457
3569
  await client.execute({
3458
3570
  sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
@@ -7916,7 +8028,7 @@ var init_platform_procedures = __esm({
7916
8028
  title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
7917
8029
  domain: "tool-use",
7918
8030
  priority: "p1",
7919
- 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."
8031
+ 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."
7920
8032
  }
7921
8033
  ];
7922
8034
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -7937,7 +8049,7 @@ import { randomUUID as randomUUID4 } from "crypto";
7937
8049
  async function loadGlobalProcedures() {
7938
8050
  const client = getClient();
7939
8051
  const result = await client.execute({
7940
- sql: "SELECT * FROM global_procedures WHERE active = 1 ORDER BY priority ASC, created_at ASC",
8052
+ sql: "SELECT * FROM company_procedures WHERE active = 1 ORDER BY priority ASC, created_at ASC",
7941
8053
  args: []
7942
8054
  });
7943
8055
  const allRows = result.rows;
@@ -7966,7 +8078,7 @@ async function storeGlobalProcedure(input) {
7966
8078
  const now = (/* @__PURE__ */ new Date()).toISOString();
7967
8079
  const client = getClient();
7968
8080
  await client.execute({
7969
- sql: `INSERT INTO global_procedures (id, title, content, priority, domain, active, created_at, updated_at)
8081
+ sql: `INSERT INTO company_procedures (id, title, content, priority, domain, active, created_at, updated_at)
7970
8082
  VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
7971
8083
  args: [id, input.title, input.content, input.priority ?? "p0", input.domain ?? null, now, now]
7972
8084
  });
@@ -7977,7 +8089,7 @@ async function deactivateGlobalProcedure(id) {
7977
8089
  const now = (/* @__PURE__ */ new Date()).toISOString();
7978
8090
  const client = getClient();
7979
8091
  const result = await client.execute({
7980
- sql: "UPDATE global_procedures SET active = 0, updated_at = ? WHERE id = ?",
8092
+ sql: "UPDATE company_procedures SET active = 0, updated_at = ? WHERE id = ?",
7981
8093
  args: [now, id]
7982
8094
  });
7983
8095
  await loadGlobalProcedures();
@@ -7996,6 +8108,164 @@ ${p.content}`).join("\n\n");
7996
8108
  }
7997
8109
  });
7998
8110
 
8111
+ // src/lib/memory-cards.ts
8112
+ var memory_cards_exports = {};
8113
+ __export(memory_cards_exports, {
8114
+ extractMemoryCards: () => extractMemoryCards,
8115
+ insertMemoryCardsForBatch: () => insertMemoryCardsForBatch,
8116
+ searchMemoryCards: () => searchMemoryCards
8117
+ });
8118
+ import { createHash as createHash2 } from "crypto";
8119
+ function stableId(memoryId, type, content) {
8120
+ return createHash2("sha256").update(`${memoryId}:${type}:${content}`).digest("hex").slice(0, 32);
8121
+ }
8122
+ function cleanText(text) {
8123
+ return text.replace(/```[\s\S]*?```/g, " ").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
8124
+ }
8125
+ function splitSentences(text) {
8126
+ return cleanText(text).split(/(?<=[.!?])\s+|\n+/).map((s) => s.trim()).filter((s) => s.length >= 24 && s.length <= MAX_SENTENCE_CHARS);
8127
+ }
8128
+ function inferCardType(sentence, toolName) {
8129
+ const lower = sentence.toLowerCase();
8130
+ if (toolName === "store_decision" || /\b(decided|decision|adr|approved|rejected)\b/.test(lower)) return "decision";
8131
+ if (/\b(prefers|preference|likes|dislikes|wants|doesn't want|does not want)\b/.test(lower)) return "preference";
8132
+ if (/\b(changed|updated|replaced|now|no longer|instead|supersedes)\b/.test(lower)) return "belief_update";
8133
+ if (toolName && ["Read", "Write", "Edit", "Bash"].includes(toolName)) return "code";
8134
+ if (/\b(meeting|deadline|shipped|launched|completed|failed|blocked|assigned|created)\b/.test(lower)) return "event";
8135
+ return "fact";
8136
+ }
8137
+ function extractSubject(sentence, agentId) {
8138
+ const explicit = sentence.match(/\b([A-Z][a-zA-Z0-9_-]{2,}(?:\s+[A-Z][a-zA-Z0-9_-]{2,})?)\b/);
8139
+ return explicit?.[1] ?? agentId;
8140
+ }
8141
+ function predicateFor(type) {
8142
+ switch (type) {
8143
+ case "preference":
8144
+ return "prefers";
8145
+ case "belief_update":
8146
+ return "updated";
8147
+ case "decision":
8148
+ return "decided";
8149
+ case "event":
8150
+ return "happened";
8151
+ case "code":
8152
+ return "implemented";
8153
+ default:
8154
+ return "states";
8155
+ }
8156
+ }
8157
+ function extractMemoryCards(row) {
8158
+ const sentences = splitSentences(row.raw_text);
8159
+ const cards = [];
8160
+ for (const sentence of sentences) {
8161
+ const type = inferCardType(sentence, row.tool_name);
8162
+ const subject = extractSubject(sentence, row.agent_id);
8163
+ const content = sentence.length > MAX_SENTENCE_CHARS ? `${sentence.slice(0, MAX_SENTENCE_CHARS - 1)}\u2026` : sentence;
8164
+ cards.push({
8165
+ id: stableId(row.id, type, content),
8166
+ memory_id: row.id,
8167
+ agent_id: row.agent_id,
8168
+ session_id: row.session_id,
8169
+ project_name: row.project_name ?? null,
8170
+ timestamp: row.timestamp,
8171
+ card_type: type,
8172
+ subject,
8173
+ predicate: predicateFor(type),
8174
+ object: content,
8175
+ content,
8176
+ source_ref: row.id,
8177
+ confidence: type === "fact" ? 0.55 : 0.65
8178
+ });
8179
+ if (cards.length >= MAX_CARDS_PER_MEMORY) break;
8180
+ }
8181
+ return cards;
8182
+ }
8183
+ async function insertMemoryCardsForBatch(rows) {
8184
+ const cards = rows.flatMap(extractMemoryCards);
8185
+ if (cards.length === 0) return 0;
8186
+ const now = (/* @__PURE__ */ new Date()).toISOString();
8187
+ const client = getClient();
8188
+ const stmts = cards.map((card) => ({
8189
+ sql: `INSERT OR IGNORE INTO memory_cards
8190
+ (id, memory_id, agent_id, session_id, project_name, timestamp, card_type,
8191
+ subject, predicate, object, content, source_ref, confidence, active, created_at)
8192
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?)`,
8193
+ args: [
8194
+ card.id,
8195
+ card.memory_id,
8196
+ card.agent_id,
8197
+ card.session_id,
8198
+ card.project_name,
8199
+ card.timestamp,
8200
+ card.card_type,
8201
+ card.subject,
8202
+ card.predicate,
8203
+ card.object,
8204
+ card.content,
8205
+ card.source_ref,
8206
+ card.confidence,
8207
+ now
8208
+ ]
8209
+ }));
8210
+ await client.batch(stmts, "write");
8211
+ return cards.length;
8212
+ }
8213
+ function buildMatchExpr(queryText) {
8214
+ 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);
8215
+ if (terms.length === 0) return null;
8216
+ return terms.map((t) => `${t}*`).join(terms.length >= 3 ? " AND " : " OR ");
8217
+ }
8218
+ async function searchMemoryCards(queryText, agentId, options) {
8219
+ const limit = options?.limit ?? 10;
8220
+ const matchExpr = buildMatchExpr(queryText);
8221
+ if (!matchExpr) return [];
8222
+ let sql = `SELECT c.id, c.memory_id, c.agent_id, c.session_id, c.project_name,
8223
+ c.timestamp, c.card_type, c.content, c.source_ref, c.confidence
8224
+ FROM memory_cards c
8225
+ JOIN memory_cards_fts fts ON c.rowid = fts.rowid
8226
+ WHERE memory_cards_fts MATCH ?
8227
+ AND c.agent_id = ?
8228
+ AND COALESCE(c.active, 1) = 1`;
8229
+ const args = [matchExpr, agentId];
8230
+ if (options?.projectName) {
8231
+ sql += ` AND c.project_name = ?`;
8232
+ args.push(options.projectName);
8233
+ }
8234
+ if (options?.since) {
8235
+ sql += ` AND c.timestamp >= ?`;
8236
+ args.push(options.since);
8237
+ }
8238
+ sql += ` ORDER BY rank LIMIT ?`;
8239
+ args.push(limit);
8240
+ const result = await getClient().execute({ sql, args });
8241
+ return result.rows.map((row) => ({
8242
+ id: `card:${String(row.id)}`,
8243
+ agent_id: String(row.agent_id),
8244
+ agent_role: "memory_card",
8245
+ session_id: String(row.session_id),
8246
+ timestamp: String(row.timestamp),
8247
+ tool_name: `memory_card:${String(row.card_type)}`,
8248
+ project_name: row.project_name == null ? "" : String(row.project_name),
8249
+ has_error: false,
8250
+ raw_text: `[${String(row.card_type)}] ${String(row.content)}
8251
+ Source memory: ${String(row.source_ref ?? row.memory_id)}`,
8252
+ vector: [],
8253
+ importance: 6,
8254
+ status: "active",
8255
+ confidence: Number(row.confidence ?? 0.6),
8256
+ last_accessed: String(row.timestamp)
8257
+ }));
8258
+ }
8259
+ var MAX_CARDS_PER_MEMORY, MAX_SENTENCE_CHARS;
8260
+ var init_memory_cards = __esm({
8261
+ "src/lib/memory-cards.ts"() {
8262
+ "use strict";
8263
+ init_database();
8264
+ MAX_CARDS_PER_MEMORY = 6;
8265
+ MAX_SENTENCE_CHARS = 360;
8266
+ }
8267
+ });
8268
+
7999
8269
  // src/lib/store.ts
8000
8270
  var store_exports = {};
8001
8271
  __export(store_exports, {
@@ -8334,6 +8604,11 @@ async function flushBatch() {
8334
8604
  const globalClient = getClient();
8335
8605
  const globalStmts = batch.map(buildStmt);
8336
8606
  await globalClient.batch(globalStmts, "write");
8607
+ try {
8608
+ const { insertMemoryCardsForBatch: insertMemoryCardsForBatch2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
8609
+ await insertMemoryCardsForBatch2(batch);
8610
+ } catch {
8611
+ }
8337
8612
  schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
8338
8613
  _pendingRecords.splice(0, batch.length);
8339
8614
  try {
@@ -14187,12 +14462,12 @@ Rules:
14187
14462
  };
14188
14463
  }
14189
14464
 
14190
- // src/gateway/providers/anthropic.ts
14465
+ // src/lib/providers/anthropic.ts
14191
14466
  import Anthropic2 from "@anthropic-ai/sdk";
14192
14467
  var AnthropicProvider = class {
14193
14468
  name;
14194
- client;
14195
14469
  defaultModel;
14470
+ client;
14196
14471
  constructor(name, config2) {
14197
14472
  this.name = name;
14198
14473
  this.defaultModel = config2.defaultModel ?? "claude-sonnet-4-20250514";
@@ -14283,13 +14558,13 @@ var AnthropicProvider = class {
14283
14558
  }
14284
14559
  };
14285
14560
 
14286
- // src/gateway/providers/openai-compat.ts
14561
+ // src/lib/providers/openai-compat.ts
14287
14562
  import OpenAI from "openai";
14288
14563
  import { randomUUID as randomUUID7 } from "crypto";
14289
14564
  var OpenAICompatProvider = class {
14290
14565
  name;
14291
- client;
14292
14566
  defaultModel;
14567
+ client;
14293
14568
  constructor(name, config2) {
14294
14569
  this.name = name;
14295
14570
  this.defaultModel = config2.defaultModel ?? "gpt-4o";
@@ -14419,12 +14694,12 @@ var OpenAICompatProvider = class {
14419
14694
  }
14420
14695
  };
14421
14696
 
14422
- // src/gateway/providers/ollama.ts
14697
+ // src/lib/providers/ollama.ts
14423
14698
  import { randomUUID as randomUUID8 } from "crypto";
14424
14699
  var OllamaProvider = class {
14425
14700
  name;
14426
- host;
14427
14701
  defaultModel;
14702
+ host;
14428
14703
  constructor(name, config2 = {}) {
14429
14704
  this.name = name;
14430
14705
  this.host = (config2.host ?? "http://localhost:11434").replace(/\/+$/, "");
@@ -74,8 +74,8 @@ var DEFAULT_CONFIG = {
74
74
  rerankerAutoTrigger: {
75
75
  enabled: true,
76
76
  broadQueryMinCardinality: 5e4,
77
- fetchTopK: 150,
78
- returnTopK: 5
77
+ fetchTopK: 200,
78
+ returnTopK: 20
79
79
  }
80
80
  },
81
81
  graphRagEnabled: true,
@@ -150,8 +150,8 @@ var init_config = __esm({
150
150
  rerankerAutoTrigger: {
151
151
  enabled: true,
152
152
  broadQueryMinCardinality: 5e4,
153
- fetchTopK: 150,
154
- returnTopK: 5
153
+ fetchTopK: 200,
154
+ returnTopK: 20
155
155
  }
156
156
  },
157
157
  graphRagEnabled: true,
@@ -2237,7 +2237,7 @@ async function ensureSchema() {
2237
2237
  ON session_kills(agent_id);
2238
2238
  `);
2239
2239
  await client.execute(`
2240
- CREATE TABLE IF NOT EXISTS global_procedures (
2240
+ CREATE TABLE IF NOT EXISTS company_procedures (
2241
2241
  id TEXT PRIMARY KEY,
2242
2242
  title TEXT NOT NULL,
2243
2243
  content TEXT NOT NULL,
@@ -2248,6 +2248,73 @@ async function ensureSchema() {
2248
2248
  updated_at TEXT NOT NULL
2249
2249
  )
2250
2250
  `);
2251
+ const legacyProcedureObject = await client.execute({
2252
+ sql: "SELECT type FROM sqlite_master WHERE name = 'global_procedures'",
2253
+ args: []
2254
+ });
2255
+ const legacyProcedureType = legacyProcedureObject.rows[0]?.type == null ? null : String(legacyProcedureObject.rows[0].type);
2256
+ if (legacyProcedureType === "table") {
2257
+ await client.execute(`
2258
+ INSERT OR IGNORE INTO company_procedures
2259
+ (id, title, content, priority, domain, active, created_at, updated_at)
2260
+ SELECT id, title, content, priority, domain, active, created_at, updated_at
2261
+ FROM global_procedures
2262
+ `);
2263
+ await client.executeMultiple(`
2264
+ CREATE TRIGGER IF NOT EXISTS global_procedures_mirror_insert
2265
+ AFTER INSERT ON global_procedures
2266
+ BEGIN
2267
+ INSERT OR IGNORE INTO company_procedures
2268
+ (id, title, content, priority, domain, active, created_at, updated_at)
2269
+ VALUES
2270
+ (NEW.id, NEW.title, NEW.content, NEW.priority, NEW.domain, NEW.active, NEW.created_at, NEW.updated_at);
2271
+ END;
2272
+
2273
+ CREATE TRIGGER IF NOT EXISTS global_procedures_mirror_update
2274
+ AFTER UPDATE ON global_procedures
2275
+ BEGIN
2276
+ UPDATE company_procedures
2277
+ SET title = NEW.title,
2278
+ content = NEW.content,
2279
+ priority = NEW.priority,
2280
+ domain = NEW.domain,
2281
+ active = NEW.active,
2282
+ created_at = NEW.created_at,
2283
+ updated_at = NEW.updated_at
2284
+ WHERE id = OLD.id;
2285
+ END;
2286
+ `);
2287
+ } else {
2288
+ await client.execute(`
2289
+ CREATE VIEW IF NOT EXISTS global_procedures AS
2290
+ SELECT id, title, content, priority, domain, active, created_at, updated_at
2291
+ FROM company_procedures
2292
+ `);
2293
+ await client.executeMultiple(`
2294
+ CREATE TRIGGER IF NOT EXISTS global_procedures_insert
2295
+ INSTEAD OF INSERT ON global_procedures
2296
+ BEGIN
2297
+ INSERT INTO company_procedures
2298
+ (id, title, content, priority, domain, active, created_at, updated_at)
2299
+ VALUES
2300
+ (NEW.id, NEW.title, NEW.content, NEW.priority, NEW.domain, NEW.active, NEW.created_at, NEW.updated_at);
2301
+ END;
2302
+
2303
+ CREATE TRIGGER IF NOT EXISTS global_procedures_update
2304
+ INSTEAD OF UPDATE ON global_procedures
2305
+ BEGIN
2306
+ UPDATE company_procedures
2307
+ SET title = NEW.title,
2308
+ content = NEW.content,
2309
+ priority = NEW.priority,
2310
+ domain = NEW.domain,
2311
+ active = NEW.active,
2312
+ created_at = NEW.created_at,
2313
+ updated_at = NEW.updated_at
2314
+ WHERE id = OLD.id;
2315
+ END;
2316
+ `);
2317
+ }
2251
2318
  await client.executeMultiple(`
2252
2319
  CREATE TABLE IF NOT EXISTS conversations (
2253
2320
  id TEXT PRIMARY KEY,
@@ -2387,6 +2454,51 @@ async function ensureSchema() {
2387
2454
  VALUES (new.rowid, new.content_text, new.sender_name, new.agent_response);
2388
2455
  END;
2389
2456
  `);
2457
+ await client.executeMultiple(`
2458
+ CREATE TABLE IF NOT EXISTS memory_cards (
2459
+ id TEXT PRIMARY KEY,
2460
+ memory_id TEXT NOT NULL,
2461
+ agent_id TEXT NOT NULL,
2462
+ session_id TEXT NOT NULL,
2463
+ project_name TEXT,
2464
+ timestamp TEXT NOT NULL,
2465
+ card_type TEXT NOT NULL,
2466
+ subject TEXT,
2467
+ predicate TEXT,
2468
+ object TEXT,
2469
+ content TEXT NOT NULL,
2470
+ source_ref TEXT,
2471
+ confidence REAL DEFAULT 0.6,
2472
+ active INTEGER DEFAULT 1,
2473
+ created_at TEXT NOT NULL
2474
+ );
2475
+
2476
+ CREATE INDEX IF NOT EXISTS idx_memory_cards_agent
2477
+ ON memory_cards(agent_id, active, timestamp);
2478
+
2479
+ CREATE INDEX IF NOT EXISTS idx_memory_cards_memory
2480
+ ON memory_cards(memory_id);
2481
+
2482
+ CREATE VIRTUAL TABLE IF NOT EXISTS memory_cards_fts
2483
+ USING fts5(content, subject, predicate, object, content='memory_cards', content_rowid='rowid');
2484
+
2485
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ai AFTER INSERT ON memory_cards BEGIN
2486
+ INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
2487
+ VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
2488
+ END;
2489
+
2490
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ad AFTER DELETE ON memory_cards BEGIN
2491
+ INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
2492
+ VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
2493
+ END;
2494
+
2495
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_au AFTER UPDATE ON memory_cards BEGIN
2496
+ INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
2497
+ VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
2498
+ INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
2499
+ VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
2500
+ END;
2501
+ `);
2390
2502
  try {
2391
2503
  await client.execute({
2392
2504
  sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
@@ -3692,12 +3804,12 @@ async function cloudSync(config) {
3692
3804
  try {
3693
3805
  await cloudPushGlobalProcedures(config);
3694
3806
  } catch (err) {
3695
- logError(`[cloud-sync] Global procedures push: ${err instanceof Error ? err.message : String(err)}`);
3807
+ logError(`[cloud-sync] Company procedures push: ${err instanceof Error ? err.message : String(err)}`);
3696
3808
  }
3697
3809
  try {
3698
3810
  await cloudPullGlobalProcedures(config);
3699
3811
  } catch (err) {
3700
- logError(`[cloud-sync] Global procedures pull: ${err instanceof Error ? err.message : String(err)}`);
3812
+ logError(`[cloud-sync] Company procedures pull: ${err instanceof Error ? err.message : String(err)}`);
3701
3813
  }
3702
3814
  const countRows = async (sql) => {
3703
3815
  try {
@@ -4107,12 +4219,12 @@ async function cloudPullBlob(route, config) {
4107
4219
  }
4108
4220
  async function cloudPushGlobalProcedures(config) {
4109
4221
  const client = getClient();
4110
- const result = await client.execute("SELECT * FROM global_procedures LIMIT 1000");
4222
+ const result = await client.execute("SELECT * FROM company_procedures LIMIT 1000");
4111
4223
  const rows = result.rows;
4112
4224
  const { ok } = await cloudPushBlob(
4113
4225
  "/sync/push-global-procedures",
4114
4226
  rows,
4115
- "last_global_procedures_push_version",
4227
+ "last_company_procedures_push_version",
4116
4228
  config
4117
4229
  );
4118
4230
  return ok;
@@ -4125,7 +4237,7 @@ async function cloudPullGlobalProcedures(config) {
4125
4237
  if (!remoteProcs || remoteProcs.length === 0) return { pulled: 0 };
4126
4238
  const client = getClient();
4127
4239
  const stmts = remoteProcs.map((p) => ({
4128
- sql: `INSERT INTO global_procedures
4240
+ sql: `INSERT INTO company_procedures
4129
4241
  (id, title, content, priority, domain, active, created_at, updated_at)
4130
4242
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)
4131
4243
  ON CONFLICT(id) DO UPDATE SET
@@ -4135,7 +4247,7 @@ async function cloudPullGlobalProcedures(config) {
4135
4247
  domain = excluded.domain,
4136
4248
  active = excluded.active,
4137
4249
  updated_at = excluded.updated_at
4138
- WHERE excluded.updated_at > global_procedures.updated_at`,
4250
+ WHERE excluded.updated_at > company_procedures.updated_at`,
4139
4251
  args: [
4140
4252
  sqlSafe(p.id),
4141
4253
  sqlSafe(p.title),
@@ -70,8 +70,8 @@ var DEFAULT_CONFIG = {
70
70
  rerankerAutoTrigger: {
71
71
  enabled: true,
72
72
  broadQueryMinCardinality: 5e4,
73
- fetchTopK: 150,
74
- returnTopK: 5
73
+ fetchTopK: 200,
74
+ returnTopK: 20
75
75
  }
76
76
  },
77
77
  graphRagEnabled: true,
@@ -103,8 +103,8 @@ var init_config = __esm({
103
103
  rerankerAutoTrigger: {
104
104
  enabled: true,
105
105
  broadQueryMinCardinality: 5e4,
106
- fetchTopK: 150,
107
- returnTopK: 5
106
+ fetchTopK: 200,
107
+ returnTopK: 20
108
108
  }
109
109
  },
110
110
  graphRagEnabled: true,