@askexenow/exe-os 0.9.35 → 0.9.37

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 (67) hide show
  1. package/dist/bin/backfill-conversations.js +5 -1
  2. package/dist/bin/backfill-responses.js +5 -1
  3. package/dist/bin/backfill-vectors.js +1 -1
  4. package/dist/bin/cleanup-stale-review-tasks.js +10 -2
  5. package/dist/bin/cli.js +48 -14
  6. package/dist/bin/exe-agent.js +1 -1
  7. package/dist/bin/exe-assign.js +10 -2
  8. package/dist/bin/exe-boot.js +1 -1
  9. package/dist/bin/exe-call.js +7 -5
  10. package/dist/bin/exe-dispatch.js +10 -2
  11. package/dist/bin/exe-doctor.js +1 -1
  12. package/dist/bin/exe-export-behaviors.js +87 -4
  13. package/dist/bin/exe-forget.js +31 -11
  14. package/dist/bin/exe-gateway.js +10 -2
  15. package/dist/bin/exe-heartbeat.js +10 -2
  16. package/dist/bin/exe-kill.js +10 -2
  17. package/dist/bin/exe-launch-agent.js +85 -7
  18. package/dist/bin/exe-new-employee.js +26 -2
  19. package/dist/bin/exe-pending-messages.js +10 -2
  20. package/dist/bin/exe-pending-notifications.js +10 -2
  21. package/dist/bin/exe-pending-reviews.js +10 -2
  22. package/dist/bin/exe-rename.js +1 -1
  23. package/dist/bin/exe-review.js +10 -2
  24. package/dist/bin/exe-search.js +38 -19
  25. package/dist/bin/exe-session-cleanup.js +14 -3
  26. package/dist/bin/exe-start-codex.js +69 -3
  27. package/dist/bin/exe-start-opencode.js +80 -3
  28. package/dist/bin/exe-status.js +10 -2
  29. package/dist/bin/exe-team.js +10 -2
  30. package/dist/bin/git-sweep.js +10 -2
  31. package/dist/bin/graph-backfill.js +2 -1
  32. package/dist/bin/graph-export.js +10 -2
  33. package/dist/bin/install.js +25 -1
  34. package/dist/bin/intercom-check.js +10 -2
  35. package/dist/bin/scan-tasks.js +10 -2
  36. package/dist/bin/setup.js +7 -5
  37. package/dist/bin/shard-migrate.js +2 -1
  38. package/dist/gateway/index.js +10 -2
  39. package/dist/hooks/bug-report-worker.js +10 -2
  40. package/dist/hooks/codex-stop-task-finalizer.js +10 -2
  41. package/dist/hooks/commit-complete.js +10 -2
  42. package/dist/hooks/error-recall.js +38 -19
  43. package/dist/hooks/ingest-worker.js +9 -2
  44. package/dist/hooks/ingest.js +10 -2
  45. package/dist/hooks/instructions-loaded.js +10 -2
  46. package/dist/hooks/notification.js +10 -2
  47. package/dist/hooks/post-compact.js +10 -2
  48. package/dist/hooks/post-tool-combined.js +47 -21
  49. package/dist/hooks/pre-compact.js +12 -3
  50. package/dist/hooks/pre-tool-use.js +20 -8
  51. package/dist/hooks/prompt-submit.js +133 -20
  52. package/dist/hooks/session-end.js +138 -5
  53. package/dist/hooks/session-start.js +216 -46
  54. package/dist/hooks/stop.js +14 -4
  55. package/dist/hooks/subagent-stop.js +10 -2
  56. package/dist/hooks/summary-worker.js +121 -19
  57. package/dist/index.js +32 -16
  58. package/dist/lib/employee-templates.js +7 -5
  59. package/dist/lib/exe-daemon.js +124 -34
  60. package/dist/lib/hybrid-search.js +38 -19
  61. package/dist/lib/schedules.js +1 -1
  62. package/dist/lib/store.js +10 -2
  63. package/dist/mcp/server.js +118 -34
  64. package/dist/runtime/index.js +32 -16
  65. package/dist/tui/App.js +10 -2
  66. package/package.json +1 -1
  67. package/src/commands/exe/save.md +52 -0
@@ -610,6 +610,7 @@ var init_preferences = __esm({
610
610
  // src/adapters/claude/installer.ts
611
611
  import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir } from "fs/promises";
612
612
  import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync4, copyFileSync, mkdirSync as mkdirSync3 } from "fs";
613
+ import { createHash } from "crypto";
613
614
  import path6 from "path";
614
615
  import os5 from "os";
615
616
  import { execSync as execSync2 } from "child_process";
@@ -1294,7 +1295,30 @@ function setupTmux(home) {
1294
1295
  return;
1295
1296
  }
1296
1297
  mkdirSync3(exeDir, { recursive: true });
1297
- copyFileSync(assetPath, exeTmuxConf);
1298
+ if (existsSync7(exeTmuxConf)) {
1299
+ const currentContent = readFileSync5(exeTmuxConf, "utf8");
1300
+ const newContent = readFileSync5(assetPath, "utf8");
1301
+ const currentHash = createHash("sha256").update(currentContent).digest("hex");
1302
+ const newHash = createHash("sha256").update(newContent).digest("hex");
1303
+ if (currentHash !== newHash) {
1304
+ const shippedPath = path6.join(exeDir, ".tmux.conf.shipped-hash");
1305
+ const lastShippedHash = existsSync7(shippedPath) ? readFileSync5(shippedPath, "utf8").trim() : "";
1306
+ if (lastShippedHash && currentHash !== lastShippedHash) {
1307
+ process.stderr.write("exe-os: tmux config has user customizations \u2014 skipping overwrite\n");
1308
+ } else {
1309
+ copyFileSync(assetPath, exeTmuxConf);
1310
+ process.stderr.write("exe-os: tmux config updated\n");
1311
+ }
1312
+ writeFileSync4(shippedPath, newHash, "utf8");
1313
+ } else {
1314
+ process.stderr.write("exe-os: tmux config already up to date\n");
1315
+ }
1316
+ } else {
1317
+ copyFileSync(assetPath, exeTmuxConf);
1318
+ const newContent = readFileSync5(assetPath, "utf8");
1319
+ const newHash = createHash("sha256").update(newContent).digest("hex");
1320
+ writeFileSync4(path6.join(exeDir, ".tmux.conf.shipped-hash"), newHash, "utf8");
1321
+ }
1298
1322
  if (existsSync7(userTmuxConf)) {
1299
1323
  const existing = readFileSync5(userTmuxConf, "utf8");
1300
1324
  if (!existing.includes(sourceLine)) {
@@ -3153,6 +3153,9 @@ function classifyMemoryType(input) {
3153
3153
  if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
3154
3154
  if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
3155
3155
  if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
3156
+ if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
3157
+ if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
3158
+ if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
3156
3159
  if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
3157
3160
  if (tool === "store_memory" || tool === "manual") return "observation";
3158
3161
  return "raw";
@@ -3295,6 +3298,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3295
3298
  }
3296
3299
  }
3297
3300
  function schedulePostWriteMemoryHygiene(memoryIds) {
3301
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3298
3302
  if (memoryIds.length === 0) return;
3299
3303
  const run = () => {
3300
3304
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -3689,7 +3693,7 @@ var init_platform_procedures = __esm({
3689
3693
  title: "Chain of command \u2014 who talks to whom",
3690
3694
  domain: "workflow",
3691
3695
  priority: "p0",
3692
- content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the COO does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
3696
+ content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
3693
3697
  },
3694
3698
  {
3695
3699
  title: "Single dispatch path \u2014 create_task only",
@@ -4361,7 +4365,11 @@ async function searchMemories(queryVector, agentId, options) {
4361
4365
  sql += ` AND timestamp >= ?`;
4362
4366
  args.push(options.since);
4363
4367
  }
4364
- if (options?.memoryType) {
4368
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4369
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4370
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4371
+ args.push(...uniqueTypes);
4372
+ } else if (options?.memoryType) {
4365
4373
  sql += ` AND memory_type = ?`;
4366
4374
  args.push(options.memoryType);
4367
4375
  }
@@ -6759,6 +6759,9 @@ function classifyMemoryType(input) {
6759
6759
  if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
6760
6760
  if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
6761
6761
  if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
6762
+ if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
6763
+ if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
6764
+ if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
6762
6765
  if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
6763
6766
  if (tool === "store_memory" || tool === "manual") return "observation";
6764
6767
  return "raw";
@@ -6901,6 +6904,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
6901
6904
  }
6902
6905
  }
6903
6906
  function schedulePostWriteMemoryHygiene(memoryIds) {
6907
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
6904
6908
  if (memoryIds.length === 0) return;
6905
6909
  const run = () => {
6906
6910
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -7295,7 +7299,7 @@ var init_platform_procedures = __esm({
7295
7299
  title: "Chain of command \u2014 who talks to whom",
7296
7300
  domain: "workflow",
7297
7301
  priority: "p0",
7298
- content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the COO does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
7302
+ content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
7299
7303
  },
7300
7304
  {
7301
7305
  title: "Single dispatch path \u2014 create_task only",
@@ -7967,7 +7971,11 @@ async function searchMemories(queryVector, agentId, options) {
7967
7971
  sql += ` AND timestamp >= ?`;
7968
7972
  args.push(options.since);
7969
7973
  }
7970
- if (options?.memoryType) {
7974
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
7975
+ const uniqueTypes = [...new Set(options.memoryTypes)];
7976
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
7977
+ args.push(...uniqueTypes);
7978
+ } else if (options?.memoryType) {
7971
7979
  sql += ` AND memory_type = ?`;
7972
7980
  args.push(options.memoryType);
7973
7981
  }
package/dist/bin/setup.js CHANGED
@@ -5659,7 +5659,7 @@ var init_platform_procedures = __esm({
5659
5659
  title: "Chain of command \u2014 who talks to whom",
5660
5660
  domain: "workflow",
5661
5661
  priority: "p0",
5662
- content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the COO does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
5662
+ content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
5663
5663
  },
5664
5664
  {
5665
5665
  title: "Single dispatch path \u2014 create_task only",
@@ -5864,8 +5864,9 @@ function personalizePrompt(prompt, templateName, actualName) {
5864
5864
  return prompt.replace(new RegExp(`\\bYou are ${escaped}\\b`, "g"), `You are ${actualName}`);
5865
5865
  }
5866
5866
  function renderClientCOOTemplate(vars) {
5867
+ const resolved = { ...vars, title: vars.title || "Chief Operating Officer" };
5867
5868
  for (const key of CLIENT_COO_PLACEHOLDERS) {
5868
- const value = vars[key];
5869
+ const value = resolved[key];
5869
5870
  if (typeof value !== "string" || value.length === 0) {
5870
5871
  throw new Error(
5871
5872
  `renderClientCOOTemplate: missing required variable "${key}"`
@@ -5874,7 +5875,7 @@ function renderClientCOOTemplate(vars) {
5874
5875
  }
5875
5876
  let out = CLIENT_COO_TEMPLATE;
5876
5877
  for (const key of CLIENT_COO_PLACEHOLDERS) {
5877
- out = out.split(`{{${key}}}`).join(vars[key]);
5878
+ out = out.split(`{{${key}}}`).join(resolved[key]);
5878
5879
  }
5879
5880
  if (vars.industry_context) {
5880
5881
  out += "\n" + vars.industry_context;
@@ -6351,7 +6352,7 @@ created_by: system
6351
6352
  ---
6352
6353
  ## Identity
6353
6354
 
6354
- You are {{agent_name}}, the Chief Operating Officer at {{company_name}}.
6355
+ You are {{agent_name}}, the {{title}} at {{company_name}}.
6355
6356
 
6356
6357
  You are {{founder_name}}'s most reliable teammate in business \u2014 the knowledgeable older sibling who has been through it all. You have seen projects succeed and fail. You know what matters and what is noise. You do not get anxious about problems; you see them coming, stay calm, and handle them.
6357
6358
 
@@ -6438,7 +6439,8 @@ All memory, tasks, behaviors, documents, and wiki content belonging to {{company
6438
6439
  CLIENT_COO_PLACEHOLDERS = [
6439
6440
  "agent_name",
6440
6441
  "company_name",
6441
- "founder_name"
6442
+ "founder_name",
6443
+ "title"
6442
6444
  ];
6443
6445
  }
6444
6446
  });
@@ -2945,7 +2945,7 @@ var init_platform_procedures = __esm({
2945
2945
  title: "Chain of command \u2014 who talks to whom",
2946
2946
  domain: "workflow",
2947
2947
  priority: "p0",
2948
- content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the COO does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
2948
+ content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
2949
2949
  },
2950
2950
  {
2951
2951
  title: "Single dispatch path \u2014 create_task only",
@@ -3466,6 +3466,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3466
3466
  }
3467
3467
  }
3468
3468
  function schedulePostWriteMemoryHygiene(memoryIds) {
3469
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3469
3470
  if (memoryIds.length === 0) return;
3470
3471
  const run = () => {
3471
3472
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -3711,6 +3711,9 @@ function classifyMemoryType(input) {
3711
3711
  if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
3712
3712
  if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
3713
3713
  if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
3714
+ if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
3715
+ if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
3716
+ if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
3714
3717
  if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
3715
3718
  if (tool === "store_memory" || tool === "manual") return "observation";
3716
3719
  return "raw";
@@ -3853,6 +3856,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3853
3856
  }
3854
3857
  }
3855
3858
  function schedulePostWriteMemoryHygiene(memoryIds) {
3859
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3856
3860
  if (memoryIds.length === 0) return;
3857
3861
  const run = () => {
3858
3862
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -4247,7 +4251,7 @@ var init_platform_procedures = __esm({
4247
4251
  title: "Chain of command \u2014 who talks to whom",
4248
4252
  domain: "workflow",
4249
4253
  priority: "p0",
4250
- content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the COO does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
4254
+ content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
4251
4255
  },
4252
4256
  {
4253
4257
  title: "Single dispatch path \u2014 create_task only",
@@ -4919,7 +4923,11 @@ async function searchMemories(queryVector, agentId, options) {
4919
4923
  sql += ` AND timestamp >= ?`;
4920
4924
  args.push(options.since);
4921
4925
  }
4922
- if (options?.memoryType) {
4926
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4927
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4928
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4929
+ args.push(...uniqueTypes);
4930
+ } else if (options?.memoryType) {
4923
4931
  sql += ` AND memory_type = ?`;
4924
4932
  args.push(options.memoryType);
4925
4933
  }
@@ -3453,6 +3453,9 @@ function classifyMemoryType(input) {
3453
3453
  if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
3454
3454
  if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
3455
3455
  if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
3456
+ if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
3457
+ if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
3458
+ if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
3456
3459
  if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
3457
3460
  if (tool === "store_memory" || tool === "manual") return "observation";
3458
3461
  return "raw";
@@ -3595,6 +3598,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3595
3598
  }
3596
3599
  }
3597
3600
  function schedulePostWriteMemoryHygiene(memoryIds) {
3601
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3598
3602
  if (memoryIds.length === 0) return;
3599
3603
  const run = () => {
3600
3604
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -3989,7 +3993,7 @@ var init_platform_procedures = __esm({
3989
3993
  title: "Chain of command \u2014 who talks to whom",
3990
3994
  domain: "workflow",
3991
3995
  priority: "p0",
3992
- content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the COO does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
3996
+ content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
3993
3997
  },
3994
3998
  {
3995
3999
  title: "Single dispatch path \u2014 create_task only",
@@ -4661,7 +4665,11 @@ async function searchMemories(queryVector, agentId, options) {
4661
4665
  sql += ` AND timestamp >= ?`;
4662
4666
  args.push(options.since);
4663
4667
  }
4664
- if (options?.memoryType) {
4668
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4669
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4670
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4671
+ args.push(...uniqueTypes);
4672
+ } else if (options?.memoryType) {
4665
4673
  sql += ` AND memory_type = ?`;
4666
4674
  args.push(options.memoryType);
4667
4675
  }
@@ -3137,6 +3137,9 @@ function classifyMemoryType(input) {
3137
3137
  if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
3138
3138
  if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
3139
3139
  if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
3140
+ if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
3141
+ if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
3142
+ if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
3140
3143
  if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
3141
3144
  if (tool === "store_memory" || tool === "manual") return "observation";
3142
3145
  return "raw";
@@ -3279,6 +3282,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3279
3282
  }
3280
3283
  }
3281
3284
  function schedulePostWriteMemoryHygiene(memoryIds) {
3285
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3282
3286
  if (memoryIds.length === 0) return;
3283
3287
  const run = () => {
3284
3288
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -3673,7 +3677,7 @@ var init_platform_procedures = __esm({
3673
3677
  title: "Chain of command \u2014 who talks to whom",
3674
3678
  domain: "workflow",
3675
3679
  priority: "p0",
3676
- content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the COO does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
3680
+ content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
3677
3681
  },
3678
3682
  {
3679
3683
  title: "Single dispatch path \u2014 create_task only",
@@ -4345,7 +4349,11 @@ async function searchMemories(queryVector, agentId, options) {
4345
4349
  sql += ` AND timestamp >= ?`;
4346
4350
  args.push(options.since);
4347
4351
  }
4348
- if (options?.memoryType) {
4352
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4353
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4354
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4355
+ args.push(...uniqueTypes);
4356
+ } else if (options?.memoryType) {
4349
4357
  sql += ` AND memory_type = ?`;
4350
4358
  args.push(options.memoryType);
4351
4359
  }
@@ -6753,6 +6753,9 @@ function classifyMemoryType(input) {
6753
6753
  if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
6754
6754
  if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
6755
6755
  if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
6756
+ if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
6757
+ if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
6758
+ if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
6756
6759
  if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
6757
6760
  if (tool === "store_memory" || tool === "manual") return "observation";
6758
6761
  return "raw";
@@ -6895,6 +6898,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
6895
6898
  }
6896
6899
  }
6897
6900
  function schedulePostWriteMemoryHygiene(memoryIds) {
6901
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
6898
6902
  if (memoryIds.length === 0) return;
6899
6903
  const run = () => {
6900
6904
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -7289,7 +7293,7 @@ var init_platform_procedures = __esm({
7289
7293
  title: "Chain of command \u2014 who talks to whom",
7290
7294
  domain: "workflow",
7291
7295
  priority: "p0",
7292
- content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the COO does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
7296
+ content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
7293
7297
  },
7294
7298
  {
7295
7299
  title: "Single dispatch path \u2014 create_task only",
@@ -7961,7 +7965,11 @@ async function searchMemories(queryVector, agentId, options) {
7961
7965
  sql += ` AND timestamp >= ?`;
7962
7966
  args.push(options.since);
7963
7967
  }
7964
- if (options?.memoryType) {
7968
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
7969
+ const uniqueTypes = [...new Set(options.memoryTypes)];
7970
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
7971
+ args.push(...uniqueTypes);
7972
+ } else if (options?.memoryType) {
7965
7973
  sql += ` AND memory_type = ?`;
7966
7974
  args.push(options.memoryType);
7967
7975
  }
@@ -3045,6 +3045,9 @@ function classifyMemoryType(input2) {
3045
3045
  if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
3046
3046
  if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
3047
3047
  if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
3048
+ if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
3049
+ if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
3050
+ if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
3048
3051
  if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
3049
3052
  if (tool === "store_memory" || tool === "manual") return "observation";
3050
3053
  return "raw";
@@ -3187,6 +3190,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3187
3190
  }
3188
3191
  }
3189
3192
  function schedulePostWriteMemoryHygiene(memoryIds) {
3193
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3190
3194
  if (memoryIds.length === 0) return;
3191
3195
  const run = () => {
3192
3196
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -3581,7 +3585,7 @@ var init_platform_procedures = __esm({
3581
3585
  title: "Chain of command \u2014 who talks to whom",
3582
3586
  domain: "workflow",
3583
3587
  priority: "p0",
3584
- content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the COO does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
3588
+ content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
3585
3589
  },
3586
3590
  {
3587
3591
  title: "Single dispatch path \u2014 create_task only",
@@ -4253,7 +4257,11 @@ async function searchMemories(queryVector, agentId, options) {
4253
4257
  sql += ` AND timestamp >= ?`;
4254
4258
  args.push(options.since);
4255
4259
  }
4256
- if (options?.memoryType) {
4260
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4261
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4262
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4263
+ args.push(...uniqueTypes);
4264
+ } else if (options?.memoryType) {
4257
4265
  sql += ` AND memory_type = ?`;
4258
4266
  args.push(options.memoryType);
4259
4267
  }
@@ -5655,6 +5663,17 @@ init_store();
5655
5663
  init_store();
5656
5664
  init_database();
5657
5665
  var RRF_K = 60;
5666
+ function appendMemoryTypeFilter(sql, args, column, options) {
5667
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
5668
+ const uniqueTypes = [...new Set(options.memoryTypes)];
5669
+ sql += ` AND ${column} IN (${uniqueTypes.map(() => "?").join(",")})`;
5670
+ args.push(...uniqueTypes);
5671
+ } else if (options?.memoryType) {
5672
+ sql += ` AND ${column} = ?`;
5673
+ args.push(options.memoryType);
5674
+ }
5675
+ return sql;
5676
+ }
5658
5677
  async function hybridSearch(queryText, agentId, options) {
5659
5678
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
5660
5679
  const config = await loadConfig2();
@@ -5750,7 +5769,7 @@ async function hybridSearch(queryText, agentId, options) {
5750
5769
  }
5751
5770
  if (lists.length === 0) return [];
5752
5771
  if (lists.length === 1 && !effectiveIsBroad) return lists[0].slice(0, limit);
5753
- const rrfLimit = effectiveIsBroad ? Math.max(limit * 5, 150) : limit;
5772
+ const rrfLimit = effectiveIsBroad ? Math.max(limit * 5, broadFetchTopK) : limit;
5754
5773
  let merged = lists.length === 1 ? lists[0].slice(0, rrfLimit) : rrfMergeMulti(lists, rrfLimit, RRF_K, weights);
5755
5774
  let graphContextMap = /* @__PURE__ */ new Map();
5756
5775
  let entityBoostRan = false;
@@ -5771,6 +5790,7 @@ async function hybridSearch(queryText, agentId, options) {
5771
5790
  returnTopK: 5
5772
5791
  };
5773
5792
  let rerankedAndBlended = null;
5793
+ const rerankReturnLimit = Math.max(limit, auto.returnTopK ?? 5);
5774
5794
  if (effectiveIsBroad && auto.enabled && rerankerAvailable) {
5775
5795
  const cardinality2 = await estimateCardinality(agentId, effectiveOptions);
5776
5796
  if (cardinality2 > auto.broadQueryMinCardinality) {
@@ -5782,16 +5802,16 @@ async function hybridSearch(queryText, agentId, options) {
5782
5802
  text: m.raw_text,
5783
5803
  context: graphContextMap.get(m.id)
5784
5804
  }));
5785
- const scored = await rerankWithContext2(effectiveQuery, candidates, auto.returnTopK);
5805
+ const scored = await rerankWithContext2(effectiveQuery, candidates, rerankReturnLimit);
5786
5806
  rerankedRecords = scored.map((s) => merged[s.index]);
5787
5807
  } else {
5788
5808
  const { rerank: rerank2 } = await Promise.resolve().then(() => (init_reranker(), reranker_exports));
5789
- rerankedRecords = await rerank2(effectiveQuery, merged, auto.returnTopK);
5809
+ rerankedRecords = await rerank2(effectiveQuery, merged, rerankReturnLimit);
5790
5810
  }
5791
5811
  if (rerankedRecords.length > 0) {
5792
5812
  rerankedAndBlended = rrfMergeMulti(
5793
5813
  [rerankedRecords],
5794
- auto.returnTopK,
5814
+ rerankReturnLimit,
5795
5815
  RRF_K
5796
5816
  );
5797
5817
  }
@@ -5799,10 +5819,7 @@ async function hybridSearch(queryText, agentId, options) {
5799
5819
  }
5800
5820
  }
5801
5821
  }
5802
- const finalResults = (rerankedAndBlended ?? merged).slice(
5803
- 0,
5804
- rerankedAndBlended ? auto.returnTopK : limit
5805
- );
5822
+ const finalResults = (rerankedAndBlended ?? merged).slice(0, limit);
5806
5823
  if (options?.includeSource && finalResults.length > 0) {
5807
5824
  await attachDocumentMetadata(finalResults);
5808
5825
  }
@@ -5883,6 +5900,7 @@ async function estimateCardinality(agentId, options) {
5883
5900
  sql += ` AND timestamp >= ?`;
5884
5901
  args.push(options.since);
5885
5902
  }
5903
+ sql = appendMemoryTypeFilter(sql, args, "memory_type", options);
5886
5904
  try {
5887
5905
  const result = await client.execute({ sql, args });
5888
5906
  return Number(result.rows[0]?.cnt) || 0;
@@ -6001,10 +6019,7 @@ async function ftsQuery(client, matchExpr, agentId, options, limit) {
6001
6019
  sql += ` AND m.timestamp >= ?`;
6002
6020
  args.push(options.since);
6003
6021
  }
6004
- if (options?.memoryType) {
6005
- sql += ` AND m.memory_type = ?`;
6006
- args.push(options.memoryType);
6007
- }
6022
+ sql = appendMemoryTypeFilter(sql, args, "m.memory_type", options);
6008
6023
  sql += ` ORDER BY rank LIMIT ?`;
6009
6024
  args.push(limit);
6010
6025
  const result = await client.execute({ sql, args });
@@ -6061,9 +6076,16 @@ async function recentRecords(agentId, options, limit, textFilter) {
6061
6076
  AND timestamp >= ? AND timestamp <= ?
6062
6077
  AND COALESCE(status, 'active') = 'active'
6063
6078
  AND ${options?.includeRaw === false ? "COALESCE(memory_type, 'raw') != 'raw'" : "1 = 1"}
6079
+ ${options?.memoryTypes?.length ? `AND memory_type IN (${options.memoryTypes.map(() => "?").join(",")})` : options?.memoryType ? "AND memory_type = ?" : ""}
6064
6080
  AND COALESCE(confidence, 0.7) >= 0.3
6065
6081
  ORDER BY timestamp DESC LIMIT ?`,
6066
- args: [agentId, windowStart, killedAt, boundarySlots]
6082
+ args: [
6083
+ agentId,
6084
+ windowStart,
6085
+ killedAt,
6086
+ ...options?.memoryTypes?.length ? [...new Set(options.memoryTypes)] : options?.memoryType ? [options.memoryType] : [],
6087
+ boundarySlots
6088
+ ]
6067
6089
  });
6068
6090
  for (const row of boundaryResult.rows) {
6069
6091
  sessionBoundaryMemories.push(rowToMemoryRecord(row));
@@ -6109,10 +6131,7 @@ async function recentRecords(agentId, options, limit, textFilter) {
6109
6131
  sql += ` AND timestamp >= ?`;
6110
6132
  args.push(options.since);
6111
6133
  }
6112
- if (options?.memoryType) {
6113
- sql += ` AND memory_type = ?`;
6114
- args.push(options.memoryType);
6115
- }
6134
+ sql = appendMemoryTypeFilter(sql, args, "memory_type", options);
6116
6135
  if (textFilter) {
6117
6136
  sql += ` AND raw_text LIKE '%' || ? || '%'`;
6118
6137
  args.push(textFilter);
@@ -544,8 +544,15 @@ process.stdin.on("end", async () => {
544
544
  `);
545
545
  process.exit(0);
546
546
  }
547
- const rawText = extractSemanticText(data.tool_name, data.tool_input, data.tool_response);
548
- if (rawText.length < 50) {
547
+ let rawText = extractSemanticText(data.tool_name, data.tool_input, data.tool_response);
548
+ if (rawText.trim().length < 10) {
549
+ const inputPreview = JSON.stringify(data.tool_input ?? "").slice(0, 500);
550
+ const outputPreview = JSON.stringify(data.tool_response ?? "").slice(0, 500);
551
+ rawText = `Tool call: ${data.tool_name}
552
+ Input: ${inputPreview}
553
+ Output: ${outputPreview}`;
554
+ }
555
+ if (rawText.trim().length < 10) {
549
556
  process.exit(0);
550
557
  }
551
558
  const agentId = process.env.AGENT_ID ?? "default";
@@ -3221,6 +3221,9 @@ function classifyMemoryType(input2) {
3221
3221
  if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
3222
3222
  if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
3223
3223
  if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
3224
+ if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
3225
+ if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
3226
+ if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
3224
3227
  if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
3225
3228
  if (tool === "store_memory" || tool === "manual") return "observation";
3226
3229
  return "raw";
@@ -3363,6 +3366,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3363
3366
  }
3364
3367
  }
3365
3368
  function schedulePostWriteMemoryHygiene(memoryIds) {
3369
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3366
3370
  if (memoryIds.length === 0) return;
3367
3371
  const run = () => {
3368
3372
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -3757,7 +3761,7 @@ var init_platform_procedures = __esm({
3757
3761
  title: "Chain of command \u2014 who talks to whom",
3758
3762
  domain: "workflow",
3759
3763
  priority: "p0",
3760
- content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the COO does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
3764
+ content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
3761
3765
  },
3762
3766
  {
3763
3767
  title: "Single dispatch path \u2014 create_task only",
@@ -4429,7 +4433,11 @@ async function searchMemories(queryVector, agentId, options) {
4429
4433
  sql += ` AND timestamp >= ?`;
4430
4434
  args.push(options.since);
4431
4435
  }
4432
- if (options?.memoryType) {
4436
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4437
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4438
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4439
+ args.push(...uniqueTypes);
4440
+ } else if (options?.memoryType) {
4433
4441
  sql += ` AND memory_type = ?`;
4434
4442
  args.push(options.memoryType);
4435
4443
  }
@@ -3056,6 +3056,9 @@ function classifyMemoryType(input2) {
3056
3056
  if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
3057
3057
  if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
3058
3058
  if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
3059
+ if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
3060
+ if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
3061
+ if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
3059
3062
  if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
3060
3063
  if (tool === "store_memory" || tool === "manual") return "observation";
3061
3064
  return "raw";
@@ -3198,6 +3201,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3198
3201
  }
3199
3202
  }
3200
3203
  function schedulePostWriteMemoryHygiene(memoryIds) {
3204
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3201
3205
  if (memoryIds.length === 0) return;
3202
3206
  const run = () => {
3203
3207
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -3592,7 +3596,7 @@ var init_platform_procedures = __esm({
3592
3596
  title: "Chain of command \u2014 who talks to whom",
3593
3597
  domain: "workflow",
3594
3598
  priority: "p0",
3595
- content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the COO does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
3599
+ content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
3596
3600
  },
3597
3601
  {
3598
3602
  title: "Single dispatch path \u2014 create_task only",
@@ -4264,7 +4268,11 @@ async function searchMemories(queryVector, agentId, options) {
4264
4268
  sql += ` AND timestamp >= ?`;
4265
4269
  args.push(options.since);
4266
4270
  }
4267
- if (options?.memoryType) {
4271
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4272
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4273
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4274
+ args.push(...uniqueTypes);
4275
+ } else if (options?.memoryType) {
4268
4276
  sql += ` AND memory_type = ?`;
4269
4277
  args.push(options.memoryType);
4270
4278
  }