@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
@@ -3502,6 +3502,9 @@ function classifyMemoryType(input2) {
3502
3502
  if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
3503
3503
  if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
3504
3504
  if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
3505
+ if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
3506
+ if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
3507
+ if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
3505
3508
  if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
3506
3509
  if (tool === "store_memory" || tool === "manual") return "observation";
3507
3510
  return "raw";
@@ -3644,6 +3647,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3644
3647
  }
3645
3648
  }
3646
3649
  function schedulePostWriteMemoryHygiene(memoryIds) {
3650
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3647
3651
  if (memoryIds.length === 0) return;
3648
3652
  const run = () => {
3649
3653
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -4038,7 +4042,7 @@ var init_platform_procedures = __esm({
4038
4042
  title: "Chain of command \u2014 who talks to whom",
4039
4043
  domain: "workflow",
4040
4044
  priority: "p0",
4041
- 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."
4045
+ 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."
4042
4046
  },
4043
4047
  {
4044
4048
  title: "Single dispatch path \u2014 create_task only",
@@ -4710,7 +4714,11 @@ async function searchMemories(queryVector, agentId, options) {
4710
4714
  sql += ` AND timestamp >= ?`;
4711
4715
  args.push(options.since);
4712
4716
  }
4713
- if (options?.memoryType) {
4717
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4718
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4719
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4720
+ args.push(...uniqueTypes);
4721
+ } else if (options?.memoryType) {
4714
4722
  sql += ` AND memory_type = ?`;
4715
4723
  args.push(options.memoryType);
4716
4724
  }
@@ -5157,7 +5165,7 @@ function spawnDetachedWorker(workerPath, env, cwd) {
5157
5165
  } catch {
5158
5166
  }
5159
5167
  }
5160
- var MIN_LENGTH = 100;
5168
+ var MIN_LENGTH = 20;
5161
5169
  var timeout = setTimeout(() => {
5162
5170
  process.exit(0);
5163
5171
  }, 5e3);
@@ -5230,7 +5238,9 @@ process.stdin.on("end", () => {
5230
5238
  session_id: data.session_id,
5231
5239
  tool_name: "auto-checkpoint",
5232
5240
  project_name: process.env.EXE_PROJECT_NAME ?? "unknown",
5233
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
5241
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
5242
+ importance: 8,
5243
+ memory_type: "checkpoint"
5234
5244
  });
5235
5245
  process.stderr.write(`[stop] Context checkpoint stored for ${agent.agentId} (capacity signal detected)
5236
5246
  `);
@@ -3483,6 +3483,9 @@ function classifyMemoryType(input2) {
3483
3483
  if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
3484
3484
  if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
3485
3485
  if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
3486
+ if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
3487
+ if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
3488
+ if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
3486
3489
  if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
3487
3490
  if (tool === "store_memory" || tool === "manual") return "observation";
3488
3491
  return "raw";
@@ -3625,6 +3628,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
3625
3628
  }
3626
3629
  }
3627
3630
  function schedulePostWriteMemoryHygiene(memoryIds) {
3631
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
3628
3632
  if (memoryIds.length === 0) return;
3629
3633
  const run = () => {
3630
3634
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -4019,7 +4023,7 @@ var init_platform_procedures = __esm({
4019
4023
  title: "Chain of command \u2014 who talks to whom",
4020
4024
  domain: "workflow",
4021
4025
  priority: "p0",
4022
- 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."
4026
+ 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."
4023
4027
  },
4024
4028
  {
4025
4029
  title: "Single dispatch path \u2014 create_task only",
@@ -4691,7 +4695,11 @@ async function searchMemories(queryVector, agentId, options) {
4691
4695
  sql += ` AND timestamp >= ?`;
4692
4696
  args.push(options.since);
4693
4697
  }
4694
- if (options?.memoryType) {
4698
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
4699
+ const uniqueTypes = [...new Set(options.memoryTypes)];
4700
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
4701
+ args.push(...uniqueTypes);
4702
+ } else if (options?.memoryType) {
4695
4703
  sql += ` AND memory_type = ?`;
4696
4704
  args.push(options.memoryType);
4697
4705
  }
@@ -3576,7 +3576,7 @@ var init_platform_procedures = __esm({
3576
3576
  title: "Chain of command \u2014 who talks to whom",
3577
3577
  domain: "workflow",
3578
3578
  priority: "p0",
3579
- 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."
3579
+ 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."
3580
3580
  },
3581
3581
  {
3582
3582
  title: "Single dispatch path \u2014 create_task only",
@@ -6748,6 +6748,88 @@ init_employees();
6748
6748
  import { execSync as execSync5 } from "child_process";
6749
6749
  import { existsSync as existsSync19, mkdirSync as mkdirSync10, openSync as openSync3, closeSync as closeSync3 } from "fs";
6750
6750
  import path20 from "path";
6751
+
6752
+ // src/lib/auto-checkpoint.ts
6753
+ var FILE_RE = /(?:^|\s)([\w./-]+\.(?:ts|tsx|js|jsx|json|md|yml|yaml|sql|go|py|css|scss|html|sh))(?:\b|$)/g;
6754
+ var DECISION_RE = /\b(decision:|decided:|we decided|founder directive|captured in .*architecture|source of truth)\b/i;
6755
+ function asString(value, fallback = "") {
6756
+ if (value == null) return fallback;
6757
+ return String(value);
6758
+ }
6759
+ function compactLine(text, max = 220) {
6760
+ return text.replace(/\s+/g, " ").trim().slice(0, max);
6761
+ }
6762
+ function topEntries(counts, limit) {
6763
+ return [...counts.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, limit).map(([name, count]) => `${name}(${count})`);
6764
+ }
6765
+ function buildAutoCheckpoint(input) {
6766
+ const maxSamples = input.maxSamples ?? 8;
6767
+ const projectCounts = /* @__PURE__ */ new Map();
6768
+ const toolCounts = /* @__PURE__ */ new Map();
6769
+ const files = /* @__PURE__ */ new Set();
6770
+ const errors = [];
6771
+ const samples = [];
6772
+ const decisionTexts = [];
6773
+ for (const row of input.memories) {
6774
+ const tool = asString(row.tool_name, "unknown");
6775
+ const project = asString(row.project_name, input.projectName || "unknown");
6776
+ const raw = asString(row.raw_text);
6777
+ const hasError = row.has_error === 1 || row.has_error === true;
6778
+ toolCounts.set(tool, (toolCounts.get(tool) ?? 0) + 1);
6779
+ projectCounts.set(project, (projectCounts.get(project) ?? 0) + 1);
6780
+ if (hasError && errors.length < 5) errors.push(compactLine(raw, 180));
6781
+ if (samples.length < maxSamples && raw.length > 30) {
6782
+ samples.push(`[${tool}] ${compactLine(raw)}`);
6783
+ }
6784
+ if (DECISION_RE.test(raw) && decisionTexts.length < 5) {
6785
+ decisionTexts.push(`AUTO DECISION CANDIDATE [${input.agentId}]: ${compactLine(raw, 500)}`);
6786
+ }
6787
+ for (const match of raw.matchAll(FILE_RE)) {
6788
+ if (match[1]) files.add(match[1]);
6789
+ if (files.size >= 20) break;
6790
+ }
6791
+ }
6792
+ const taskLines = (input.tasks ?? []).slice(0, 10).map((task) => {
6793
+ const status = asString(task.status, "unknown");
6794
+ const priority = asString(task.priority, "?").toUpperCase();
6795
+ const title = asString(task.title, "untitled");
6796
+ const taskFile = asString(task.task_file);
6797
+ return `- [${status}/${priority}] ${title}${taskFile ? ` (${taskFile})` : ""}`;
6798
+ });
6799
+ const parts = [
6800
+ `CONTEXT CHECKPOINT [auto:${input.reason}]`,
6801
+ `Agent: ${input.agentId} (${input.agentRole})`,
6802
+ `Session: ${input.sessionId}`,
6803
+ `Project: ${input.projectName}`,
6804
+ `Time: ${(/* @__PURE__ */ new Date()).toISOString()}`,
6805
+ "",
6806
+ "## Recent Activity",
6807
+ `- Memories scanned: ${input.memories.length}`,
6808
+ `- Projects: ${topEntries(projectCounts, 5).join(", ") || input.projectName}`,
6809
+ `- Tools: ${topEntries(toolCounts, 8).join(", ") || "none"}`
6810
+ ];
6811
+ if (taskLines.length > 0) {
6812
+ parts.push("", "## Open / Active Tasks", ...taskLines);
6813
+ }
6814
+ if (files.size > 0) {
6815
+ parts.push("", "## Files Mentioned", ...[...files].slice(0, 20).map((f) => `- ${f}`));
6816
+ }
6817
+ if (samples.length > 0) {
6818
+ parts.push("", "## Important Recent Traces", ...samples.map((s) => `- ${s}`));
6819
+ }
6820
+ if (errors.length > 0) {
6821
+ parts.push("", "## Errors / Risks", ...errors.map((e) => `- ${e}`));
6822
+ }
6823
+ if (decisionTexts.length > 0) {
6824
+ parts.push("", "## Decision Candidates", ...decisionTexts.map((d) => `- ${d.replace(/^AUTO DECISION CANDIDATE \\[[^\\]]+\\]: /, "")}`));
6825
+ }
6826
+ return {
6827
+ checkpointText: parts.join("\n"),
6828
+ decisionTexts
6829
+ };
6830
+ }
6831
+
6832
+ // src/adapters/claude/hooks/summary-worker.ts
6751
6833
  async function main() {
6752
6834
  const agentId = process.env.AGENT_ID ?? "default";
6753
6835
  const agentRole = process.env.AGENT_ROLE ?? "employee";
@@ -6780,23 +6862,6 @@ async function main() {
6780
6862
  entry.samples.push(rawText.slice(0, 150));
6781
6863
  }
6782
6864
  }
6783
- const parts = [];
6784
- parts.push(`Auto-summary: ${totalCalls} tool calls (${writeCalls} writes)`);
6785
- parts.push(`Agent: ${agentId} (${agentRole})`);
6786
- parts.push(`Time: ${(/* @__PURE__ */ new Date()).toISOString()}`);
6787
- parts.push("");
6788
- for (const [project, data] of projects) {
6789
- parts.push(`Project: ${project}`);
6790
- parts.push(` Tools used: ${[...data.tools].join(", ")}`);
6791
- if (data.errors > 0) {
6792
- parts.push(` Errors encountered: ${data.errors}`);
6793
- }
6794
- for (const sample of data.samples) {
6795
- parts.push(` - ${sample}`);
6796
- }
6797
- parts.push("");
6798
- }
6799
- const summaryText = parts.join("\n");
6800
6865
  let primaryProject = "unknown";
6801
6866
  let maxCount = 0;
6802
6867
  const projectCounts = /* @__PURE__ */ new Map();
@@ -6809,6 +6874,28 @@ async function main() {
6809
6874
  primaryProject = p;
6810
6875
  }
6811
6876
  }
6877
+ let taskRows = [];
6878
+ try {
6879
+ const swScope = sessionScopeFilter();
6880
+ const tasks = await client.execute({
6881
+ sql: `SELECT title, status, task_file, priority
6882
+ FROM tasks
6883
+ WHERE assigned_to = ? AND status IN ('open', 'in_progress')${swScope.sql}
6884
+ ORDER BY priority ASC, updated_at DESC LIMIT 10`,
6885
+ args: [agentId, ...swScope.args]
6886
+ });
6887
+ taskRows = tasks.rows;
6888
+ } catch {
6889
+ }
6890
+ const { checkpointText: summaryText, decisionTexts } = buildAutoCheckpoint({
6891
+ agentId,
6892
+ agentRole,
6893
+ sessionId: `auto-summary-${Date.now()}`,
6894
+ projectName: primaryProject,
6895
+ reason: "periodic",
6896
+ memories: result.rows,
6897
+ tasks: taskRows
6898
+ });
6812
6899
  let limitReached = false;
6813
6900
  try {
6814
6901
  const { assertMemoryLimit: assertMemoryLimit2 } = await Promise.resolve().then(() => (init_plan_limits(), plan_limits_exports));
@@ -6833,8 +6920,23 @@ async function main() {
6833
6920
  session_id: `auto-summary-${Date.now()}`,
6834
6921
  tool_name: "auto-summary",
6835
6922
  project_name: primaryProject,
6836
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
6923
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
6924
+ importance: 7,
6925
+ memory_type: "checkpoint"
6837
6926
  });
6927
+ for (const decisionText of decisionTexts.slice(0, 3)) {
6928
+ await writeMemoryViaDaemon({
6929
+ raw_text: decisionText,
6930
+ agent_id: agentId,
6931
+ agent_role: agentRole,
6932
+ session_id: `auto-decision-${Date.now()}`,
6933
+ tool_name: "auto-decision",
6934
+ project_name: primaryProject,
6935
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
6936
+ importance: 8,
6937
+ memory_type: "decision"
6938
+ });
6939
+ }
6838
6940
  if (!canCoordinate(agentId, agentRole)) {
6839
6941
  let totalErrors = 0;
6840
6942
  for (const [, data] of projects) {
package/dist/index.js CHANGED
@@ -7027,6 +7027,9 @@ function classifyMemoryType(input) {
7027
7027
  if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
7028
7028
  if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
7029
7029
  if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
7030
+ if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
7031
+ if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
7032
+ if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
7030
7033
  if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
7031
7034
  if (tool === "store_memory" || tool === "manual") return "observation";
7032
7035
  return "raw";
@@ -7169,6 +7172,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
7169
7172
  }
7170
7173
  }
7171
7174
  function schedulePostWriteMemoryHygiene(memoryIds) {
7175
+ if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
7172
7176
  if (memoryIds.length === 0) return;
7173
7177
  const run = () => {
7174
7178
  void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
@@ -7563,7 +7567,7 @@ var init_platform_procedures = __esm({
7563
7567
  title: "Chain of command \u2014 who talks to whom",
7564
7568
  domain: "workflow",
7565
7569
  priority: "p0",
7566
- 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."
7570
+ 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."
7567
7571
  },
7568
7572
  {
7569
7573
  title: "Single dispatch path \u2014 create_task only",
@@ -8235,7 +8239,11 @@ async function searchMemories(queryVector, agentId, options) {
8235
8239
  sql += ` AND timestamp >= ?`;
8236
8240
  args.push(options.since);
8237
8241
  }
8238
- if (options?.memoryType) {
8242
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
8243
+ const uniqueTypes = [...new Set(options.memoryTypes)];
8244
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
8245
+ args.push(...uniqueTypes);
8246
+ } else if (options?.memoryType) {
8239
8247
  sql += ` AND memory_type = ?`;
8240
8248
  args.push(options.memoryType);
8241
8249
  }
@@ -12150,20 +12158,28 @@ function createExeOSHooks(config2) {
12150
12158
  async onSessionEnd(_context, summary) {
12151
12159
  try {
12152
12160
  const { writeMemory: writeMemory2 } = await Promise.resolve().then(() => (init_store(), store_exports));
12153
- if (summary) {
12154
- await writeMemory2({
12155
- id: randomUUID5(),
12156
- agent_id: config2.agentId,
12157
- agent_role: "employee",
12158
- session_id: `api-${config2.agentId}`,
12159
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
12160
- tool_name: "SessionEnd",
12161
- project_name: config2.projectName,
12162
- has_error: false,
12163
- raw_text: `Session ended. Summary: ${summary}`,
12164
- vector: null
12165
- });
12166
- }
12161
+ await writeMemory2({
12162
+ id: randomUUID5(),
12163
+ agent_id: config2.agentId,
12164
+ agent_role: "employee",
12165
+ session_id: `api-${config2.agentId}`,
12166
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
12167
+ tool_name: "SessionEnd",
12168
+ project_name: config2.projectName,
12169
+ has_error: false,
12170
+ raw_text: [
12171
+ "CONTEXT CHECKPOINT [auto:session-end]",
12172
+ `Agent: ${config2.agentId}`,
12173
+ `Project: ${config2.projectName}`,
12174
+ `Time: ${(/* @__PURE__ */ new Date()).toISOString()}`,
12175
+ "",
12176
+ "## Runtime Summary",
12177
+ summary || "Session ended. No runtime summary was provided."
12178
+ ].join("\n"),
12179
+ vector: null,
12180
+ importance: 8,
12181
+ memory_type: "checkpoint"
12182
+ });
12167
12183
  } catch (err) {
12168
12184
  process.stderr.write(
12169
12185
  `[exe-hooks] session summary store failed: ${err instanceof Error ? err.message : String(err)}
@@ -167,7 +167,7 @@ var PLATFORM_PROCEDURES = [
167
167
  title: "Chain of command \u2014 who talks to whom",
168
168
  domain: "workflow",
169
169
  priority: "p0",
170
- 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."
170
+ 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."
171
171
  },
172
172
  {
173
173
  title: "Single dispatch path \u2014 create_task only",
@@ -811,7 +811,7 @@ created_by: system
811
811
  ---
812
812
  ## Identity
813
813
 
814
- You are {{agent_name}}, the Chief Operating Officer at {{company_name}}.
814
+ You are {{agent_name}}, the {{title}} at {{company_name}}.
815
815
 
816
816
  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.
817
817
 
@@ -898,11 +898,13 @@ All memory, tasks, behaviors, documents, and wiki content belonging to {{company
898
898
  var CLIENT_COO_PLACEHOLDERS = [
899
899
  "agent_name",
900
900
  "company_name",
901
- "founder_name"
901
+ "founder_name",
902
+ "title"
902
903
  ];
903
904
  function renderClientCOOTemplate(vars) {
905
+ const resolved = { ...vars, title: vars.title || "Chief Operating Officer" };
904
906
  for (const key of CLIENT_COO_PLACEHOLDERS) {
905
- const value = vars[key];
907
+ const value = resolved[key];
906
908
  if (typeof value !== "string" || value.length === 0) {
907
909
  throw new Error(
908
910
  `renderClientCOOTemplate: missing required variable "${key}"`
@@ -911,7 +913,7 @@ function renderClientCOOTemplate(vars) {
911
913
  }
912
914
  let out = CLIENT_COO_TEMPLATE;
913
915
  for (const key of CLIENT_COO_PLACEHOLDERS) {
914
- out = out.split(`{{${key}}}`).join(vars[key]);
916
+ out = out.split(`{{${key}}}`).join(resolved[key]);
915
917
  }
916
918
  if (vars.industry_context) {
917
919
  out += "\n" + vars.industry_context;