@askexenow/exe-os 0.9.35 → 0.9.36

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 (66) hide show
  1. package/dist/bin/backfill-conversations.js +2 -1
  2. package/dist/bin/backfill-responses.js +2 -1
  3. package/dist/bin/backfill-vectors.js +1 -1
  4. package/dist/bin/cleanup-stale-review-tasks.js +7 -2
  5. package/dist/bin/cli.js +45 -14
  6. package/dist/bin/exe-agent.js +1 -1
  7. package/dist/bin/exe-assign.js +7 -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 +7 -2
  11. package/dist/bin/exe-doctor.js +1 -1
  12. package/dist/bin/exe-export-behaviors.js +84 -4
  13. package/dist/bin/exe-forget.js +28 -11
  14. package/dist/bin/exe-gateway.js +7 -2
  15. package/dist/bin/exe-heartbeat.js +7 -2
  16. package/dist/bin/exe-kill.js +7 -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 +7 -2
  20. package/dist/bin/exe-pending-notifications.js +7 -2
  21. package/dist/bin/exe-pending-reviews.js +7 -2
  22. package/dist/bin/exe-rename.js +1 -1
  23. package/dist/bin/exe-review.js +7 -2
  24. package/dist/bin/exe-search.js +29 -11
  25. package/dist/bin/exe-session-cleanup.js +7 -2
  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 +7 -2
  29. package/dist/bin/exe-team.js +7 -2
  30. package/dist/bin/git-sweep.js +7 -2
  31. package/dist/bin/graph-backfill.js +2 -1
  32. package/dist/bin/graph-export.js +7 -2
  33. package/dist/bin/install.js +25 -1
  34. package/dist/bin/intercom-check.js +7 -2
  35. package/dist/bin/scan-tasks.js +7 -2
  36. package/dist/bin/setup.js +7 -5
  37. package/dist/bin/shard-migrate.js +2 -1
  38. package/dist/gateway/index.js +7 -2
  39. package/dist/hooks/bug-report-worker.js +7 -2
  40. package/dist/hooks/codex-stop-task-finalizer.js +7 -2
  41. package/dist/hooks/commit-complete.js +7 -2
  42. package/dist/hooks/error-recall.js +29 -11
  43. package/dist/hooks/ingest.js +7 -2
  44. package/dist/hooks/instructions-loaded.js +7 -2
  45. package/dist/hooks/notification.js +7 -2
  46. package/dist/hooks/post-compact.js +7 -2
  47. package/dist/hooks/post-tool-combined.js +29 -11
  48. package/dist/hooks/pre-compact.js +7 -2
  49. package/dist/hooks/pre-tool-use.js +17 -8
  50. package/dist/hooks/prompt-submit.js +124 -12
  51. package/dist/hooks/session-end.js +7 -2
  52. package/dist/hooks/session-start.js +207 -38
  53. package/dist/hooks/stop.js +7 -2
  54. package/dist/hooks/subagent-stop.js +7 -2
  55. package/dist/hooks/summary-worker.js +1 -1
  56. package/dist/index.js +7 -2
  57. package/dist/lib/employee-templates.js +7 -5
  58. package/dist/lib/exe-daemon.js +115 -26
  59. package/dist/lib/hybrid-search.js +29 -11
  60. package/dist/lib/schedules.js +1 -1
  61. package/dist/lib/store.js +7 -2
  62. package/dist/mcp/server.js +109 -26
  63. package/dist/runtime/index.js +7 -2
  64. package/dist/tui/App.js +7 -2
  65. package/package.json +1 -1
  66. package/src/commands/exe/save.md +48 -0
@@ -3854,6 +3854,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3854
3854
  }
3855
3855
  }
3856
3856
  function schedulePostWriteMemoryHygiene(memoryIds) {
3857
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3857
3858
  if (memoryIds.length === 0) return;
3858
3859
  const run = () => {
3859
3860
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -4248,7 +4249,7 @@ var init_platform_procedures = __esm({
4248
4249
  title: "Chain of command \u2014 who talks to whom",
4249
4250
  domain: "workflow",
4250
4251
  priority: "p0",
4251
- 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."
4252
+ 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."
4252
4253
  },
4253
4254
  {
4254
4255
  title: "Single dispatch path \u2014 create_task only",
@@ -4920,7 +4921,11 @@ async function searchMemories(queryVector, agentId, options) {
4920
4921
  sql += ` AND timestamp >= ?`;
4921
4922
  args.push(options.since);
4922
4923
  }
4923
- if (options?.memoryType) {
4924
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4925
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4926
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4927
+ args.push(...uniqueTypes);
4928
+ } else if (options?.memoryType) {
4924
4929
  sql += ` AND memory_type = ?`;
4925
4930
  args.push(options.memoryType);
4926
4931
  }
@@ -3226,6 +3226,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3226
3226
  }
3227
3227
  }
3228
3228
  function schedulePostWriteMemoryHygiene(memoryIds) {
3229
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3229
3230
  if (memoryIds.length === 0) return;
3230
3231
  const run = () => {
3231
3232
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -3620,7 +3621,7 @@ var init_platform_procedures = __esm({
3620
3621
  title: "Chain of command \u2014 who talks to whom",
3621
3622
  domain: "workflow",
3622
3623
  priority: "p0",
3623
- 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."
3624
+ 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."
3624
3625
  },
3625
3626
  {
3626
3627
  title: "Single dispatch path \u2014 create_task only",
@@ -4292,7 +4293,11 @@ async function searchMemories(queryVector, agentId, options) {
4292
4293
  sql += ` AND timestamp >= ?`;
4293
4294
  args.push(options.since);
4294
4295
  }
4295
- if (options?.memoryType) {
4296
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4297
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4298
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4299
+ args.push(...uniqueTypes);
4300
+ } else if (options?.memoryType) {
4296
4301
  sql += ` AND memory_type = ?`;
4297
4302
  args.push(options.memoryType);
4298
4303
  }
@@ -3196,6 +3196,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3196
3196
  }
3197
3197
  }
3198
3198
  function schedulePostWriteMemoryHygiene(memoryIds) {
3199
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3199
3200
  if (memoryIds.length === 0) return;
3200
3201
  const run = () => {
3201
3202
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -3590,7 +3591,7 @@ var init_platform_procedures = __esm({
3590
3591
  title: "Chain of command \u2014 who talks to whom",
3591
3592
  domain: "workflow",
3592
3593
  priority: "p0",
3593
- 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."
3594
+ 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."
3594
3595
  },
3595
3596
  {
3596
3597
  title: "Single dispatch path \u2014 create_task only",
@@ -4262,7 +4263,11 @@ async function searchMemories(queryVector, agentId, options) {
4262
4263
  sql += ` AND timestamp >= ?`;
4263
4264
  args.push(options.since);
4264
4265
  }
4265
- if (options?.memoryType) {
4266
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4267
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4268
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4269
+ args.push(...uniqueTypes);
4270
+ } else if (options?.memoryType) {
4266
4271
  sql += ` AND memory_type = ?`;
4267
4272
  args.push(options.memoryType);
4268
4273
  }
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
6
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
7
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
8
  }) : x)(function(x) {
@@ -14,6 +16,15 @@ var __export = (target, all) => {
14
16
  for (var name in all)
15
17
  __defProp(target, name, { get: all[name], enumerable: true });
16
18
  };
19
+ var __copyProps = (to, from, except, desc) => {
20
+ if (from && typeof from === "object" || typeof from === "function") {
21
+ for (let key of __getOwnPropNames(from))
22
+ if (!__hasOwnProp.call(to, key) && key !== except)
23
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
24
+ }
25
+ return to;
26
+ };
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
17
28
 
18
29
  // src/types/memory.ts
19
30
  var EMBEDDING_DIM;
@@ -118,6 +129,21 @@ var init_secure_files = __esm({
118
129
  });
119
130
 
120
131
  // src/lib/config.ts
132
+ var config_exports = {};
133
+ __export(config_exports, {
134
+ CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
135
+ CONFIG_PATH: () => CONFIG_PATH,
136
+ CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
137
+ DB_PATH: () => DB_PATH,
138
+ EXE_AI_DIR: () => EXE_AI_DIR,
139
+ LEGACY_LANCE_PATH: () => LEGACY_LANCE_PATH,
140
+ MODELS_DIR: () => MODELS_DIR,
141
+ loadConfig: () => loadConfig,
142
+ loadConfigFrom: () => loadConfigFrom,
143
+ loadConfigSync: () => loadConfigSync,
144
+ migrateConfig: () => migrateConfig,
145
+ saveConfig: () => saveConfig
146
+ });
121
147
  import { readFile, writeFile } from "fs/promises";
122
148
  import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
123
149
  import path from "path";
@@ -221,6 +247,46 @@ async function loadConfig() {
221
247
  return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db") };
222
248
  }
223
249
  }
250
+ function loadConfigSync() {
251
+ const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
252
+ const configPath = path.join(dir, "config.json");
253
+ if (!existsSync2(configPath)) {
254
+ return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db") };
255
+ }
256
+ try {
257
+ const raw = readFileSync(configPath, "utf-8");
258
+ let parsed = JSON.parse(raw);
259
+ parsed = migrateLegacyConfig(parsed);
260
+ const { config: migratedCfg } = migrateConfig(parsed);
261
+ normalizeScalingRoadmap(migratedCfg);
262
+ normalizeSessionLifecycle(migratedCfg);
263
+ normalizeAutoUpdate(migratedCfg);
264
+ return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
265
+ } catch {
266
+ return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db") };
267
+ }
268
+ }
269
+ async function saveConfig(config) {
270
+ const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
271
+ await ensurePrivateDir(dir);
272
+ const configPath = path.join(dir, "config.json");
273
+ await writeFile(configPath, JSON.stringify(config, null, 2) + "\n");
274
+ await enforcePrivateFile(configPath);
275
+ }
276
+ async function loadConfigFrom(configPath) {
277
+ const raw = await readFile(configPath, "utf-8");
278
+ try {
279
+ let parsed = JSON.parse(raw);
280
+ parsed = migrateLegacyConfig(parsed);
281
+ const { config: migratedCfg } = migrateConfig(parsed);
282
+ normalizeScalingRoadmap(migratedCfg);
283
+ normalizeSessionLifecycle(migratedCfg);
284
+ normalizeAutoUpdate(migratedCfg);
285
+ return { ...DEFAULT_CONFIG, ...migratedCfg };
286
+ } catch {
287
+ return { ...DEFAULT_CONFIG };
288
+ }
289
+ }
224
290
  var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
225
291
  var init_config = __esm({
226
292
  "src/lib/config.ts"() {
@@ -3279,7 +3345,7 @@ var init_platform_procedures = __esm({
3279
3345
  title: "Chain of command \u2014 who talks to whom",
3280
3346
  domain: "workflow",
3281
3347
  priority: "p0",
3282
- 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."
3348
+ 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."
3283
3349
  },
3284
3350
  {
3285
3351
  title: "Single dispatch path \u2014 create_task only",
@@ -3530,8 +3596,9 @@ function personalizePrompt(prompt, templateName, actualName) {
3530
3596
  return prompt.replace(new RegExp(`\\bYou are ${escaped}\\b`, "g"), `You are ${actualName}`);
3531
3597
  }
3532
3598
  function renderClientCOOTemplate(vars) {
3599
+ const resolved = { ...vars, title: vars.title || "Chief Operating Officer" };
3533
3600
  for (const key of CLIENT_COO_PLACEHOLDERS) {
3534
- const value = vars[key];
3601
+ const value = resolved[key];
3535
3602
  if (typeof value !== "string" || value.length === 0) {
3536
3603
  throw new Error(
3537
3604
  `renderClientCOOTemplate: missing required variable "${key}"`
@@ -3540,7 +3607,7 @@ function renderClientCOOTemplate(vars) {
3540
3607
  }
3541
3608
  let out = CLIENT_COO_TEMPLATE;
3542
3609
  for (const key of CLIENT_COO_PLACEHOLDERS) {
3543
- out = out.split(`{{${key}}}`).join(vars[key]);
3610
+ out = out.split(`{{${key}}}`).join(resolved[key]);
3544
3611
  }
3545
3612
  if (vars.industry_context) {
3546
3613
  out += "\n" + vars.industry_context;
@@ -4017,7 +4084,7 @@ created_by: system
4017
4084
  ---
4018
4085
  ## Identity
4019
4086
 
4020
- You are {{agent_name}}, the Chief Operating Officer at {{company_name}}.
4087
+ You are {{agent_name}}, the {{title}} at {{company_name}}.
4021
4088
 
4022
4089
  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.
4023
4090
 
@@ -4104,7 +4171,8 @@ All memory, tasks, behaviors, documents, and wiki content belonging to {{company
4104
4171
  CLIENT_COO_PLACEHOLDERS = [
4105
4172
  "agent_name",
4106
4173
  "company_name",
4107
- "founder_name"
4174
+ "founder_name",
4175
+ "title"
4108
4176
  ];
4109
4177
  }
4110
4178
  });
@@ -4682,6 +4750,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
4682
4750
  }
4683
4751
  }
4684
4752
  function schedulePostWriteMemoryHygiene(memoryIds) {
4753
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
4685
4754
  if (memoryIds.length === 0) return;
4686
4755
  const run = () => {
4687
4756
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -5001,7 +5070,16 @@ var BEHAVIORS_EXPORT_DIR = path9.join(
5001
5070
  "behaviors-export"
5002
5071
  );
5003
5072
  var STALE_EXPORT_AGE_MS = 60 * 60 * 1e3;
5004
- var EXPORT_BEHAVIOR_LIMIT = 30;
5073
+ var DEFAULT_BEHAVIOR_LIMIT = 30;
5074
+ function getBehaviorLimit() {
5075
+ try {
5076
+ const { loadConfigSync: loadConfigSync2 } = (init_config(), __toCommonJS(config_exports));
5077
+ const cfg = loadConfigSync2();
5078
+ return cfg.behaviorExportLimit ?? DEFAULT_BEHAVIOR_LIMIT;
5079
+ } catch {
5080
+ return DEFAULT_BEHAVIOR_LIMIT;
5081
+ }
5082
+ }
5005
5083
  function sweepStaleBehaviorExports(now = Date.now()) {
5006
5084
  if (!existsSync9(BEHAVIORS_EXPORT_DIR)) return;
5007
5085
  let entries;
@@ -5055,7 +5133,7 @@ function exportFilePath(agentId, projectName, sessionKey) {
5055
5133
  async function exportBehaviorsForAgent(agentId, projectName, sessionKey) {
5056
5134
  mkdirSync3(BEHAVIORS_EXPORT_DIR, { recursive: true });
5057
5135
  sweepStaleBehaviorExports();
5058
- const behaviors = await listBehaviors(agentId, projectName, EXPORT_BEHAVIOR_LIMIT);
5136
+ const behaviors = await listBehaviors(agentId, projectName, getBehaviorLimit());
5059
5137
  if (behaviors.length === 0) return null;
5060
5138
  const body = renderBehaviorExport(behaviors);
5061
5139
  const target = exportFilePath(agentId, projectName, sessionKey);
@@ -1266,6 +1266,7 @@ __export(installer_exports, {
1266
1266
  });
1267
1267
  import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir } from "fs/promises";
1268
1268
  import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync7, copyFileSync, mkdirSync as mkdirSync6 } from "fs";
1269
+ import { createHash as createHash2 } from "crypto";
1269
1270
  import path11 from "path";
1270
1271
  import os7 from "os";
1271
1272
  import { execSync as execSync2 } from "child_process";
@@ -1950,7 +1951,30 @@ function setupTmux(home) {
1950
1951
  return;
1951
1952
  }
1952
1953
  mkdirSync6(exeDir, { recursive: true });
1953
- copyFileSync(assetPath, exeTmuxConf);
1954
+ if (existsSync11(exeTmuxConf)) {
1955
+ const currentContent = readFileSync9(exeTmuxConf, "utf8");
1956
+ const newContent = readFileSync9(assetPath, "utf8");
1957
+ const currentHash = createHash2("sha256").update(currentContent).digest("hex");
1958
+ const newHash = createHash2("sha256").update(newContent).digest("hex");
1959
+ if (currentHash !== newHash) {
1960
+ const shippedPath = path11.join(exeDir, ".tmux.conf.shipped-hash");
1961
+ const lastShippedHash = existsSync11(shippedPath) ? readFileSync9(shippedPath, "utf8").trim() : "";
1962
+ if (lastShippedHash && currentHash !== lastShippedHash) {
1963
+ process.stderr.write("exe-os: tmux config has user customizations \u2014 skipping overwrite\n");
1964
+ } else {
1965
+ copyFileSync(assetPath, exeTmuxConf);
1966
+ process.stderr.write("exe-os: tmux config updated\n");
1967
+ }
1968
+ writeFileSync7(shippedPath, newHash, "utf8");
1969
+ } else {
1970
+ process.stderr.write("exe-os: tmux config already up to date\n");
1971
+ }
1972
+ } else {
1973
+ copyFileSync(assetPath, exeTmuxConf);
1974
+ const newContent = readFileSync9(assetPath, "utf8");
1975
+ const newHash = createHash2("sha256").update(newContent).digest("hex");
1976
+ writeFileSync7(path11.join(exeDir, ".tmux.conf.shipped-hash"), newHash, "utf8");
1977
+ }
1954
1978
  if (existsSync11(userTmuxConf)) {
1955
1979
  const existing = readFileSync9(userTmuxConf, "utf8");
1956
1980
  if (!existing.includes(sourceLine)) {
@@ -2243,7 +2267,7 @@ var PLATFORM_PROCEDURES = [
2243
2267
  title: "Chain of command \u2014 who talks to whom",
2244
2268
  domain: "workflow",
2245
2269
  priority: "p0",
2246
- 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."
2270
+ 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."
2247
2271
  },
2248
2272
  {
2249
2273
  title: "Single dispatch path \u2014 create_task only",
@@ -3615,6 +3615,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3615
3615
  }
3616
3616
  }
3617
3617
  function schedulePostWriteMemoryHygiene(memoryIds) {
3618
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3618
3619
  if (memoryIds.length === 0) return;
3619
3620
  const run = () => {
3620
3621
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -4009,7 +4010,7 @@ var init_platform_procedures = __esm({
4009
4010
  title: "Chain of command \u2014 who talks to whom",
4010
4011
  domain: "workflow",
4011
4012
  priority: "p0",
4012
- 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."
4013
+ 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."
4013
4014
  },
4014
4015
  {
4015
4016
  title: "Single dispatch path \u2014 create_task only",
@@ -4681,7 +4682,11 @@ async function searchMemories(queryVector, agentId, options) {
4681
4682
  sql += ` AND timestamp >= ?`;
4682
4683
  args.push(options.since);
4683
4684
  }
4684
- if (options?.memoryType) {
4685
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4686
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4687
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4688
+ args.push(...uniqueTypes);
4689
+ } else if (options?.memoryType) {
4685
4690
  sql += ` AND memory_type = ?`;
4686
4691
  args.push(options.memoryType);
4687
4692
  }
@@ -3681,6 +3681,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3681
3681
  }
3682
3682
  }
3683
3683
  function schedulePostWriteMemoryHygiene(memoryIds) {
3684
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3684
3685
  if (memoryIds.length === 0) return;
3685
3686
  const run = () => {
3686
3687
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -4075,7 +4076,7 @@ var init_platform_procedures = __esm({
4075
4076
  title: "Chain of command \u2014 who talks to whom",
4076
4077
  domain: "workflow",
4077
4078
  priority: "p0",
4078
- 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."
4079
+ 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."
4079
4080
  },
4080
4081
  {
4081
4082
  title: "Single dispatch path \u2014 create_task only",
@@ -4747,7 +4748,11 @@ async function searchMemories(queryVector, agentId, options) {
4747
4748
  sql += ` AND timestamp >= ?`;
4748
4749
  args.push(options.since);
4749
4750
  }
4750
- if (options?.memoryType) {
4751
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4752
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4753
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4754
+ args.push(...uniqueTypes);
4755
+ } else if (options?.memoryType) {
4751
4756
  sql += ` AND memory_type = ?`;
4752
4757
  args.push(options.memoryType);
4753
4758
  }
@@ -3720,6 +3720,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3720
3720
  }
3721
3721
  }
3722
3722
  function schedulePostWriteMemoryHygiene(memoryIds) {
3723
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3723
3724
  if (memoryIds.length === 0) return;
3724
3725
  const run = () => {
3725
3726
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -4114,7 +4115,7 @@ var init_platform_procedures = __esm({
4114
4115
  title: "Chain of command \u2014 who talks to whom",
4115
4116
  domain: "workflow",
4116
4117
  priority: "p0",
4117
- 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."
4118
+ 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."
4118
4119
  },
4119
4120
  {
4120
4121
  title: "Single dispatch path \u2014 create_task only",
@@ -4786,7 +4787,11 @@ async function searchMemories(queryVector, agentId, options) {
4786
4787
  sql += ` AND timestamp >= ?`;
4787
4788
  args.push(options.since);
4788
4789
  }
4789
- if (options?.memoryType) {
4790
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4791
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4792
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4793
+ args.push(...uniqueTypes);
4794
+ } else if (options?.memoryType) {
4790
4795
  sql += ` AND memory_type = ?`;
4791
4796
  args.push(options.memoryType);
4792
4797
  }
@@ -2593,7 +2593,7 @@ var PLATFORM_PROCEDURES = [
2593
2593
  title: "Chain of command \u2014 who talks to whom",
2594
2594
  domain: "workflow",
2595
2595
  priority: "p0",
2596
- 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."
2596
+ 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."
2597
2597
  },
2598
2598
  {
2599
2599
  title: "Single dispatch path \u2014 create_task only",
@@ -3210,6 +3210,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3210
3210
  }
3211
3211
  }
3212
3212
  function schedulePostWriteMemoryHygiene(memoryIds) {
3213
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3213
3214
  if (memoryIds.length === 0) return;
3214
3215
  const run = () => {
3215
3216
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -3604,7 +3605,7 @@ var init_platform_procedures = __esm({
3604
3605
  title: "Chain of command \u2014 who talks to whom",
3605
3606
  domain: "workflow",
3606
3607
  priority: "p0",
3607
- 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."
3608
+ 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."
3608
3609
  },
3609
3610
  {
3610
3611
  title: "Single dispatch path \u2014 create_task only",
@@ -4276,7 +4277,11 @@ async function searchMemories(queryVector, agentId, options) {
4276
4277
  sql += ` AND timestamp >= ?`;
4277
4278
  args.push(options.since);
4278
4279
  }
4279
- if (options?.memoryType) {
4280
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4281
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4282
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4283
+ args.push(...uniqueTypes);
4284
+ } else if (options?.memoryType) {
4280
4285
  sql += ` AND memory_type = ?`;
4281
4286
  args.push(options.memoryType);
4282
4287
  }
@@ -3185,6 +3185,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3185
3185
  }
3186
3186
  }
3187
3187
  function schedulePostWriteMemoryHygiene(memoryIds) {
3188
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3188
3189
  if (memoryIds.length === 0) return;
3189
3190
  const run = () => {
3190
3191
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -3579,7 +3580,7 @@ var init_platform_procedures = __esm({
3579
3580
  title: "Chain of command \u2014 who talks to whom",
3580
3581
  domain: "workflow",
3581
3582
  priority: "p0",
3582
- 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."
3583
+ 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."
3583
3584
  },
3584
3585
  {
3585
3586
  title: "Single dispatch path \u2014 create_task only",
@@ -4251,7 +4252,11 @@ async function searchMemories(queryVector, agentId, options) {
4251
4252
  sql += ` AND timestamp >= ?`;
4252
4253
  args.push(options.since);
4253
4254
  }
4254
- if (options?.memoryType) {
4255
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4256
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4257
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4258
+ args.push(...uniqueTypes);
4259
+ } else if (options?.memoryType) {
4255
4260
  sql += ` AND memory_type = ?`;
4256
4261
  args.push(options.memoryType);
4257
4262
  }
@@ -5546,6 +5551,17 @@ init_store();
5546
5551
  init_store();
5547
5552
  init_database();
5548
5553
  var RRF_K = 60;
5554
+ function appendMemoryTypeFilter(sql, args, column, options) {
5555
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
5556
+ const uniqueTypes = [...new Set(options.memoryTypes)];
5557
+ sql += ` AND ${column} IN (${uniqueTypes.map(() => "?").join(",")})`;
5558
+ args.push(...uniqueTypes);
5559
+ } else if (options?.memoryType) {
5560
+ sql += ` AND ${column} = ?`;
5561
+ args.push(options.memoryType);
5562
+ }
5563
+ return sql;
5564
+ }
5549
5565
  async function hybridSearch(queryText, agentId, options) {
5550
5566
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
5551
5567
  const config = await loadConfig2();
@@ -5774,6 +5790,7 @@ async function estimateCardinality(agentId, options) {
5774
5790
  sql += ` AND timestamp >= ?`;
5775
5791
  args.push(options.since);
5776
5792
  }
5793
+ sql = appendMemoryTypeFilter(sql, args, "memory_type", options);
5777
5794
  try {
5778
5795
  const result = await client.execute({ sql, args });
5779
5796
  return Number(result.rows[0]?.cnt) || 0;
@@ -5892,10 +5909,7 @@ async function ftsQuery(client, matchExpr, agentId, options, limit) {
5892
5909
  sql += ` AND m.timestamp >= ?`;
5893
5910
  args.push(options.since);
5894
5911
  }
5895
- if (options?.memoryType) {
5896
- sql += ` AND m.memory_type = ?`;
5897
- args.push(options.memoryType);
5898
- }
5912
+ sql = appendMemoryTypeFilter(sql, args, "m.memory_type", options);
5899
5913
  sql += ` ORDER BY rank LIMIT ?`;
5900
5914
  args.push(limit);
5901
5915
  const result = await client.execute({ sql, args });
@@ -5952,9 +5966,16 @@ async function recentRecords(agentId, options, limit, textFilter) {
5952
5966
  AND timestamp >= ? AND timestamp <= ?
5953
5967
  AND COALESCE(status, 'active') = 'active'
5954
5968
  AND ${options?.includeRaw === false ? "COALESCE(memory_type, 'raw') != 'raw'" : "1 = 1"}
5969
+ ${options?.memoryTypes?.length ? `AND memory_type IN (${options.memoryTypes.map(() => "?").join(",")})` : options?.memoryType ? "AND memory_type = ?" : ""}
5955
5970
  AND COALESCE(confidence, 0.7) >= 0.3
5956
5971
  ORDER BY timestamp DESC LIMIT ?`,
5957
- args: [agentId, windowStart, killedAt, boundarySlots]
5972
+ args: [
5973
+ agentId,
5974
+ windowStart,
5975
+ killedAt,
5976
+ ...options?.memoryTypes?.length ? [...new Set(options.memoryTypes)] : options?.memoryType ? [options.memoryType] : [],
5977
+ boundarySlots
5978
+ ]
5958
5979
  });
5959
5980
  for (const row of boundaryResult.rows) {
5960
5981
  sessionBoundaryMemories.push(rowToMemoryRecord(row));
@@ -6000,10 +6021,7 @@ async function recentRecords(agentId, options, limit, textFilter) {
6000
6021
  sql += ` AND timestamp >= ?`;
6001
6022
  args.push(options.since);
6002
6023
  }
6003
- if (options?.memoryType) {
6004
- sql += ` AND memory_type = ?`;
6005
- args.push(options.memoryType);
6006
- }
6024
+ sql = appendMemoryTypeFilter(sql, args, "memory_type", options);
6007
6025
  if (textFilter) {
6008
6026
  sql += ` AND raw_text LIKE '%' || ? || '%'`;
6009
6027
  args.push(textFilter);
@@ -3229,6 +3229,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3229
3229
  }
3230
3230
  }
3231
3231
  function schedulePostWriteMemoryHygiene(memoryIds) {
3232
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3232
3233
  if (memoryIds.length === 0) return;
3233
3234
  const run = () => {
3234
3235
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -3623,7 +3624,7 @@ var init_platform_procedures = __esm({
3623
3624
  title: "Chain of command \u2014 who talks to whom",
3624
3625
  domain: "workflow",
3625
3626
  priority: "p0",
3626
- 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."
3627
+ 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."
3627
3628
  },
3628
3629
  {
3629
3630
  title: "Single dispatch path \u2014 create_task only",
@@ -4295,7 +4296,11 @@ async function searchMemories(queryVector, agentId, options) {
4295
4296
  sql += ` AND timestamp >= ?`;
4296
4297
  args.push(options.since);
4297
4298
  }
4298
- if (options?.memoryType) {
4299
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4300
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4301
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4302
+ args.push(...uniqueTypes);
4303
+ } else if (options?.memoryType) {
4299
4304
  sql += ` AND memory_type = ?`;
4300
4305
  args.push(options.memoryType);
4301
4306
  }