@askexenow/exe-os 0.9.61 → 0.9.63

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 (103) hide show
  1. package/deploy/stack-manifests/v0.9.json +62 -13
  2. package/dist/bin/backfill-conversations.js +210 -2
  3. package/dist/bin/backfill-responses.js +210 -2
  4. package/dist/bin/backfill-vectors.js +47 -2
  5. package/dist/bin/cleanup-stale-review-tasks.js +210 -2
  6. package/dist/bin/cli.js +488 -25
  7. package/dist/bin/exe-agent-config.js +2 -2
  8. package/dist/bin/exe-agent.js +2 -2
  9. package/dist/bin/exe-assign.js +210 -2
  10. package/dist/bin/exe-boot.js +47 -2
  11. package/dist/bin/exe-call.js +2 -2
  12. package/dist/bin/exe-cloud.js +2 -2
  13. package/dist/bin/exe-dispatch.js +210 -2
  14. package/dist/bin/exe-doctor.js +2691 -1212
  15. package/dist/bin/exe-export-behaviors.js +210 -2
  16. package/dist/bin/exe-forget.js +264 -2
  17. package/dist/bin/exe-gateway.js +210 -2
  18. package/dist/bin/exe-heartbeat.js +212 -4
  19. package/dist/bin/exe-kill.js +210 -2
  20. package/dist/bin/exe-launch-agent.js +210 -2
  21. package/dist/bin/exe-link.js +47 -2
  22. package/dist/bin/exe-new-employee.js +113 -3
  23. package/dist/bin/exe-pending-messages.js +210 -2
  24. package/dist/bin/exe-pending-notifications.js +210 -2
  25. package/dist/bin/exe-pending-reviews.js +210 -2
  26. package/dist/bin/exe-rename.js +210 -2
  27. package/dist/bin/exe-review.js +210 -2
  28. package/dist/bin/exe-search.js +234 -3
  29. package/dist/bin/exe-session-cleanup.js +210 -2
  30. package/dist/bin/exe-settings.js +2 -2
  31. package/dist/bin/exe-start-codex.js +322 -4
  32. package/dist/bin/exe-start-opencode.js +336 -4
  33. package/dist/bin/exe-status.js +210 -2
  34. package/dist/bin/exe-team.js +210 -2
  35. package/dist/bin/git-sweep.js +210 -2
  36. package/dist/bin/graph-backfill.js +210 -2
  37. package/dist/bin/graph-export.js +210 -2
  38. package/dist/bin/install.js +113 -3
  39. package/dist/bin/intercom-check.js +210 -2
  40. package/dist/bin/scan-tasks.js +210 -2
  41. package/dist/bin/setup.js +47 -2
  42. package/dist/bin/shard-migrate.js +210 -2
  43. package/dist/bin/stack-update.js +158 -13
  44. package/dist/bin/update.js +2 -2
  45. package/dist/gateway/index.js +210 -2
  46. package/dist/hooks/bug-report-worker.js +321 -44
  47. package/dist/hooks/codex-stop-task-finalizer.js +210 -2
  48. package/dist/hooks/commit-complete.js +210 -2
  49. package/dist/hooks/error-recall.js +234 -3
  50. package/dist/hooks/exe-heartbeat-hook.js +2 -2
  51. package/dist/hooks/ingest-worker.js +2 -2
  52. package/dist/hooks/ingest.js +210 -2
  53. package/dist/hooks/instructions-loaded.js +210 -2
  54. package/dist/hooks/notification.js +210 -2
  55. package/dist/hooks/post-compact.js +210 -2
  56. package/dist/hooks/post-tool-combined.js +234 -3
  57. package/dist/hooks/pre-compact.js +446 -111
  58. package/dist/hooks/pre-tool-use.js +210 -2
  59. package/dist/hooks/prompt-submit.js +234 -3
  60. package/dist/hooks/session-end.js +347 -124
  61. package/dist/hooks/session-start.js +236 -5
  62. package/dist/hooks/stop.js +210 -2
  63. package/dist/hooks/subagent-stop.js +210 -2
  64. package/dist/hooks/summary-worker.js +171 -74
  65. package/dist/index.js +210 -2
  66. package/dist/lib/agent-config.js +2 -2
  67. package/dist/lib/cloud-sync.js +47 -2
  68. package/dist/lib/config.js +2 -2
  69. package/dist/lib/consolidation.js +2 -2
  70. package/dist/lib/database.js +47 -2
  71. package/dist/lib/db-daemon-client.js +2 -2
  72. package/dist/lib/db.js +47 -2
  73. package/dist/lib/device-registry.js +47 -2
  74. package/dist/lib/embedder.js +2 -2
  75. package/dist/lib/employee-templates.js +2 -2
  76. package/dist/lib/employees.js +2 -2
  77. package/dist/lib/exe-daemon-client.js +2 -2
  78. package/dist/lib/exe-daemon.js +592 -10
  79. package/dist/lib/hybrid-search.js +234 -3
  80. package/dist/lib/identity.js +2 -2
  81. package/dist/lib/license.js +2 -2
  82. package/dist/lib/messaging.js +2 -2
  83. package/dist/lib/reminders.js +2 -2
  84. package/dist/lib/schedules.js +47 -2
  85. package/dist/lib/skill-learning.js +2 -2
  86. package/dist/lib/store.js +210 -2
  87. package/dist/lib/task-router.js +2 -2
  88. package/dist/lib/tasks.js +2 -2
  89. package/dist/lib/tmux-routing.js +2 -2
  90. package/dist/lib/token-spend.js +2 -2
  91. package/dist/mcp/server.js +608 -10
  92. package/dist/mcp/tools/complete-reminder.js +2 -2
  93. package/dist/mcp/tools/create-reminder.js +2 -2
  94. package/dist/mcp/tools/create-task.js +2 -2
  95. package/dist/mcp/tools/deactivate-behavior.js +2 -2
  96. package/dist/mcp/tools/list-reminders.js +2 -2
  97. package/dist/mcp/tools/list-tasks.js +2 -2
  98. package/dist/mcp/tools/send-message.js +2 -2
  99. package/dist/mcp/tools/update-task.js +2 -2
  100. package/dist/runtime/index.js +210 -2
  101. package/dist/tui/App.js +210 -2
  102. package/package.json +3 -2
  103. package/stack.release.json +23 -7
@@ -202,8 +202,8 @@ var init_config = __esm({
202
202
  rerankerAutoTrigger: {
203
203
  enabled: true,
204
204
  broadQueryMinCardinality: 5e4,
205
- fetchTopK: 150,
206
- returnTopK: 5
205
+ fetchTopK: 200,
206
+ returnTopK: 20
207
207
  }
208
208
  },
209
209
  graphRagEnabled: true,
@@ -3025,6 +3025,51 @@ async function ensureSchema() {
3025
3025
  VALUES (new.rowid, new.content_text, new.sender_name, new.agent_response);
3026
3026
  END;
3027
3027
  `);
3028
+ await client.executeMultiple(`
3029
+ CREATE TABLE IF NOT EXISTS memory_cards (
3030
+ id TEXT PRIMARY KEY,
3031
+ memory_id TEXT NOT NULL,
3032
+ agent_id TEXT NOT NULL,
3033
+ session_id TEXT NOT NULL,
3034
+ project_name TEXT,
3035
+ timestamp TEXT NOT NULL,
3036
+ card_type TEXT NOT NULL,
3037
+ subject TEXT,
3038
+ predicate TEXT,
3039
+ object TEXT,
3040
+ content TEXT NOT NULL,
3041
+ source_ref TEXT,
3042
+ confidence REAL DEFAULT 0.6,
3043
+ active INTEGER DEFAULT 1,
3044
+ created_at TEXT NOT NULL
3045
+ );
3046
+
3047
+ CREATE INDEX IF NOT EXISTS idx_memory_cards_agent
3048
+ ON memory_cards(agent_id, active, timestamp);
3049
+
3050
+ CREATE INDEX IF NOT EXISTS idx_memory_cards_memory
3051
+ ON memory_cards(memory_id);
3052
+
3053
+ CREATE VIRTUAL TABLE IF NOT EXISTS memory_cards_fts
3054
+ USING fts5(content, subject, predicate, object, content='memory_cards', content_rowid='rowid');
3055
+
3056
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ai AFTER INSERT ON memory_cards BEGIN
3057
+ INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
3058
+ VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
3059
+ END;
3060
+
3061
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ad AFTER DELETE ON memory_cards BEGIN
3062
+ INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
3063
+ VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
3064
+ END;
3065
+
3066
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_au AFTER UPDATE ON memory_cards BEGIN
3067
+ INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
3068
+ VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
3069
+ INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
3070
+ VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
3071
+ END;
3072
+ `);
3028
3073
  try {
3029
3074
  await client.execute({
3030
3075
  sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
@@ -4457,6 +4502,164 @@ ${p.content}`).join("\n\n");
4457
4502
  }
4458
4503
  });
4459
4504
 
4505
+ // src/lib/memory-cards.ts
4506
+ var memory_cards_exports = {};
4507
+ __export(memory_cards_exports, {
4508
+ extractMemoryCards: () => extractMemoryCards,
4509
+ insertMemoryCardsForBatch: () => insertMemoryCardsForBatch,
4510
+ searchMemoryCards: () => searchMemoryCards
4511
+ });
4512
+ import { createHash as createHash2 } from "crypto";
4513
+ function stableId(memoryId, type, content) {
4514
+ return createHash2("sha256").update(`${memoryId}:${type}:${content}`).digest("hex").slice(0, 32);
4515
+ }
4516
+ function cleanText(text) {
4517
+ return text.replace(/```[\s\S]*?```/g, " ").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
4518
+ }
4519
+ function splitSentences(text) {
4520
+ return cleanText(text).split(/(?<=[.!?])\s+|\n+/).map((s) => s.trim()).filter((s) => s.length >= 24 && s.length <= MAX_SENTENCE_CHARS);
4521
+ }
4522
+ function inferCardType(sentence, toolName) {
4523
+ const lower = sentence.toLowerCase();
4524
+ if (toolName === "store_decision" || /\b(decided|decision|adr|approved|rejected)\b/.test(lower)) return "decision";
4525
+ if (/\b(prefers|preference|likes|dislikes|wants|doesn't want|does not want)\b/.test(lower)) return "preference";
4526
+ if (/\b(changed|updated|replaced|now|no longer|instead|supersedes)\b/.test(lower)) return "belief_update";
4527
+ if (toolName && ["Read", "Write", "Edit", "Bash"].includes(toolName)) return "code";
4528
+ if (/\b(meeting|deadline|shipped|launched|completed|failed|blocked|assigned|created)\b/.test(lower)) return "event";
4529
+ return "fact";
4530
+ }
4531
+ function extractSubject(sentence, agentId) {
4532
+ const explicit = sentence.match(/\b([A-Z][a-zA-Z0-9_-]{2,}(?:\s+[A-Z][a-zA-Z0-9_-]{2,})?)\b/);
4533
+ return explicit?.[1] ?? agentId;
4534
+ }
4535
+ function predicateFor(type) {
4536
+ switch (type) {
4537
+ case "preference":
4538
+ return "prefers";
4539
+ case "belief_update":
4540
+ return "updated";
4541
+ case "decision":
4542
+ return "decided";
4543
+ case "event":
4544
+ return "happened";
4545
+ case "code":
4546
+ return "implemented";
4547
+ default:
4548
+ return "states";
4549
+ }
4550
+ }
4551
+ function extractMemoryCards(row) {
4552
+ const sentences = splitSentences(row.raw_text);
4553
+ const cards = [];
4554
+ for (const sentence of sentences) {
4555
+ const type = inferCardType(sentence, row.tool_name);
4556
+ const subject = extractSubject(sentence, row.agent_id);
4557
+ const content = sentence.length > MAX_SENTENCE_CHARS ? `${sentence.slice(0, MAX_SENTENCE_CHARS - 1)}\u2026` : sentence;
4558
+ cards.push({
4559
+ id: stableId(row.id, type, content),
4560
+ memory_id: row.id,
4561
+ agent_id: row.agent_id,
4562
+ session_id: row.session_id,
4563
+ project_name: row.project_name ?? null,
4564
+ timestamp: row.timestamp,
4565
+ card_type: type,
4566
+ subject,
4567
+ predicate: predicateFor(type),
4568
+ object: content,
4569
+ content,
4570
+ source_ref: row.id,
4571
+ confidence: type === "fact" ? 0.55 : 0.65
4572
+ });
4573
+ if (cards.length >= MAX_CARDS_PER_MEMORY) break;
4574
+ }
4575
+ return cards;
4576
+ }
4577
+ async function insertMemoryCardsForBatch(rows) {
4578
+ const cards = rows.flatMap(extractMemoryCards);
4579
+ if (cards.length === 0) return 0;
4580
+ const now = (/* @__PURE__ */ new Date()).toISOString();
4581
+ const client = getClient();
4582
+ const stmts = cards.map((card) => ({
4583
+ sql: `INSERT OR IGNORE INTO memory_cards
4584
+ (id, memory_id, agent_id, session_id, project_name, timestamp, card_type,
4585
+ subject, predicate, object, content, source_ref, confidence, active, created_at)
4586
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?)`,
4587
+ args: [
4588
+ card.id,
4589
+ card.memory_id,
4590
+ card.agent_id,
4591
+ card.session_id,
4592
+ card.project_name,
4593
+ card.timestamp,
4594
+ card.card_type,
4595
+ card.subject,
4596
+ card.predicate,
4597
+ card.object,
4598
+ card.content,
4599
+ card.source_ref,
4600
+ card.confidence,
4601
+ now
4602
+ ]
4603
+ }));
4604
+ await client.batch(stmts, "write");
4605
+ return cards.length;
4606
+ }
4607
+ function buildMatchExpr(queryText) {
4608
+ const terms = queryText.toLowerCase().split(/\s+/).filter((t) => t.length >= 3).map((t) => t.replace(/[^a-z0-9_]/g, "")).filter((t) => t.length >= 3).slice(0, 12);
4609
+ if (terms.length === 0) return null;
4610
+ return terms.map((t) => `${t}*`).join(terms.length >= 3 ? " AND " : " OR ");
4611
+ }
4612
+ async function searchMemoryCards(queryText, agentId, options) {
4613
+ const limit = options?.limit ?? 10;
4614
+ const matchExpr = buildMatchExpr(queryText);
4615
+ if (!matchExpr) return [];
4616
+ let sql = `SELECT c.id, c.memory_id, c.agent_id, c.session_id, c.project_name,
4617
+ c.timestamp, c.card_type, c.content, c.source_ref, c.confidence
4618
+ FROM memory_cards c
4619
+ JOIN memory_cards_fts fts ON c.rowid = fts.rowid
4620
+ WHERE memory_cards_fts MATCH ?
4621
+ AND c.agent_id = ?
4622
+ AND COALESCE(c.active, 1) = 1`;
4623
+ const args = [matchExpr, agentId];
4624
+ if (options?.projectName) {
4625
+ sql += ` AND c.project_name = ?`;
4626
+ args.push(options.projectName);
4627
+ }
4628
+ if (options?.since) {
4629
+ sql += ` AND c.timestamp >= ?`;
4630
+ args.push(options.since);
4631
+ }
4632
+ sql += ` ORDER BY rank LIMIT ?`;
4633
+ args.push(limit);
4634
+ const result = await getClient().execute({ sql, args });
4635
+ return result.rows.map((row) => ({
4636
+ id: `card:${String(row.id)}`,
4637
+ agent_id: String(row.agent_id),
4638
+ agent_role: "memory_card",
4639
+ session_id: String(row.session_id),
4640
+ timestamp: String(row.timestamp),
4641
+ tool_name: `memory_card:${String(row.card_type)}`,
4642
+ project_name: row.project_name == null ? "" : String(row.project_name),
4643
+ has_error: false,
4644
+ raw_text: `[${String(row.card_type)}] ${String(row.content)}
4645
+ Source memory: ${String(row.source_ref ?? row.memory_id)}`,
4646
+ vector: [],
4647
+ importance: 6,
4648
+ status: "active",
4649
+ confidence: Number(row.confidence ?? 0.6),
4650
+ last_accessed: String(row.timestamp)
4651
+ }));
4652
+ }
4653
+ var MAX_CARDS_PER_MEMORY, MAX_SENTENCE_CHARS;
4654
+ var init_memory_cards = __esm({
4655
+ "src/lib/memory-cards.ts"() {
4656
+ "use strict";
4657
+ init_database();
4658
+ MAX_CARDS_PER_MEMORY = 6;
4659
+ MAX_SENTENCE_CHARS = 360;
4660
+ }
4661
+ });
4662
+
4460
4663
  // src/lib/store.ts
4461
4664
  var store_exports = {};
4462
4665
  __export(store_exports, {
@@ -4795,6 +4998,11 @@ async function flushBatch() {
4795
4998
  const globalClient = getClient();
4796
4999
  const globalStmts = batch.map(buildStmt);
4797
5000
  await globalClient.batch(globalStmts, "write");
5001
+ try {
5002
+ const { insertMemoryCardsForBatch: insertMemoryCardsForBatch2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
5003
+ await insertMemoryCardsForBatch2(batch);
5004
+ } catch {
5005
+ }
4798
5006
  schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
4799
5007
  _pendingRecords.splice(0, batch.length);
4800
5008
  try {
@@ -321,8 +321,8 @@ var init_config = __esm({
321
321
  rerankerAutoTrigger: {
322
322
  enabled: true,
323
323
  broadQueryMinCardinality: 5e4,
324
- fetchTopK: 150,
325
- returnTopK: 5
324
+ fetchTopK: 200,
325
+ returnTopK: 20
326
326
  }
327
327
  },
328
328
  graphRagEnabled: true,
@@ -2782,6 +2782,51 @@ async function ensureSchema() {
2782
2782
  VALUES (new.rowid, new.content_text, new.sender_name, new.agent_response);
2783
2783
  END;
2784
2784
  `);
2785
+ await client.executeMultiple(`
2786
+ CREATE TABLE IF NOT EXISTS memory_cards (
2787
+ id TEXT PRIMARY KEY,
2788
+ memory_id TEXT NOT NULL,
2789
+ agent_id TEXT NOT NULL,
2790
+ session_id TEXT NOT NULL,
2791
+ project_name TEXT,
2792
+ timestamp TEXT NOT NULL,
2793
+ card_type TEXT NOT NULL,
2794
+ subject TEXT,
2795
+ predicate TEXT,
2796
+ object TEXT,
2797
+ content TEXT NOT NULL,
2798
+ source_ref TEXT,
2799
+ confidence REAL DEFAULT 0.6,
2800
+ active INTEGER DEFAULT 1,
2801
+ created_at TEXT NOT NULL
2802
+ );
2803
+
2804
+ CREATE INDEX IF NOT EXISTS idx_memory_cards_agent
2805
+ ON memory_cards(agent_id, active, timestamp);
2806
+
2807
+ CREATE INDEX IF NOT EXISTS idx_memory_cards_memory
2808
+ ON memory_cards(memory_id);
2809
+
2810
+ CREATE VIRTUAL TABLE IF NOT EXISTS memory_cards_fts
2811
+ USING fts5(content, subject, predicate, object, content='memory_cards', content_rowid='rowid');
2812
+
2813
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ai AFTER INSERT ON memory_cards BEGIN
2814
+ INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
2815
+ VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
2816
+ END;
2817
+
2818
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ad AFTER DELETE ON memory_cards BEGIN
2819
+ INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
2820
+ VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
2821
+ END;
2822
+
2823
+ CREATE TRIGGER IF NOT EXISTS memory_cards_fts_au AFTER UPDATE ON memory_cards BEGIN
2824
+ INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
2825
+ VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
2826
+ INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
2827
+ VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
2828
+ END;
2829
+ `);
2785
2830
  try {
2786
2831
  await client.execute({
2787
2832
  sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
@@ -6907,46 +6952,6 @@ function vectorToBlob(vector) {
6907
6952
  // src/adapters/claude/hooks/summary-worker.ts
6908
6953
  init_database();
6909
6954
  init_notifications();
6910
-
6911
- // src/lib/memory-queue-client.ts
6912
- init_exe_daemon_client();
6913
-
6914
- // src/lib/memory-queue.ts
6915
- init_config();
6916
- import { appendFileSync as appendFileSync2, readFileSync as readFileSync11, renameSync as renameSync5, unlinkSync as unlinkSync4, existsSync as existsSync15, statSync as statSync3 } from "fs";
6917
- import path16 from "path";
6918
- var QUEUE_PATH2 = path16.join(EXE_AI_DIR, "memory-queue.jsonl");
6919
- var PROCESSING_PATH = QUEUE_PATH2 + ".processing";
6920
- var TTL_MS2 = 24 * 60 * 60 * 1e3;
6921
- function enqueueMemory(entry) {
6922
- appendFileSync2(QUEUE_PATH2, JSON.stringify(entry) + "\n");
6923
- }
6924
-
6925
- // src/lib/memory-queue-client.ts
6926
- async function writeMemoryViaDaemon(entry) {
6927
- if (process.env.EXE_IS_DAEMON === "1") {
6928
- enqueueMemory(entry);
6929
- return false;
6930
- }
6931
- if (!isClientConnected()) {
6932
- enqueueMemory(entry);
6933
- return false;
6934
- }
6935
- try {
6936
- const response = await sendDaemonRequest({
6937
- type: "write-memory",
6938
- entry
6939
- });
6940
- if (response.ok) return true;
6941
- enqueueMemory(entry);
6942
- return false;
6943
- } catch {
6944
- enqueueMemory(entry);
6945
- return false;
6946
- }
6947
- }
6948
-
6949
- // src/adapters/claude/hooks/summary-worker.ts
6950
6955
  init_task_scope();
6951
6956
  init_employees();
6952
6957
  import { execSync as execSync5 } from "child_process";
@@ -7033,6 +7038,119 @@ function buildAutoCheckpoint(input) {
7033
7038
  };
7034
7039
  }
7035
7040
 
7041
+ // src/lib/memory-queue-client.ts
7042
+ init_exe_daemon_client();
7043
+
7044
+ // src/lib/memory-queue.ts
7045
+ init_config();
7046
+ import { appendFileSync as appendFileSync2, readFileSync as readFileSync11, renameSync as renameSync5, unlinkSync as unlinkSync4, existsSync as existsSync15, statSync as statSync3 } from "fs";
7047
+ import path16 from "path";
7048
+ var QUEUE_PATH2 = path16.join(EXE_AI_DIR, "memory-queue.jsonl");
7049
+ var PROCESSING_PATH = QUEUE_PATH2 + ".processing";
7050
+ var TTL_MS2 = 24 * 60 * 60 * 1e3;
7051
+ function enqueueMemory(entry) {
7052
+ appendFileSync2(QUEUE_PATH2, JSON.stringify(entry) + "\n");
7053
+ }
7054
+
7055
+ // src/lib/memory-queue-client.ts
7056
+ async function writeMemoryViaDaemon(entry) {
7057
+ if (process.env.EXE_IS_DAEMON === "1") {
7058
+ enqueueMemory(entry);
7059
+ return false;
7060
+ }
7061
+ if (!isClientConnected()) {
7062
+ enqueueMemory(entry);
7063
+ return false;
7064
+ }
7065
+ try {
7066
+ const response = await sendDaemonRequest({
7067
+ type: "write-memory",
7068
+ entry
7069
+ });
7070
+ if (response.ok) return true;
7071
+ enqueueMemory(entry);
7072
+ return false;
7073
+ } catch {
7074
+ enqueueMemory(entry);
7075
+ return false;
7076
+ }
7077
+ }
7078
+
7079
+ // src/lib/checkpoint-orchestrator.ts
7080
+ function toolNameForReason(reason) {
7081
+ switch (reason) {
7082
+ case "periodic":
7083
+ return "auto-summary";
7084
+ case "session-end":
7085
+ return "SessionEnd";
7086
+ case "pre-compact":
7087
+ return "pre-compact-hook";
7088
+ case "capacity-signal":
7089
+ return "auto-checkpoint";
7090
+ }
7091
+ }
7092
+ function importanceForReason(reason, override) {
7093
+ if (override !== void 0) return override;
7094
+ switch (reason) {
7095
+ case "periodic":
7096
+ return 7;
7097
+ case "session-end":
7098
+ case "pre-compact":
7099
+ case "capacity-signal":
7100
+ return 8;
7101
+ }
7102
+ }
7103
+ function buildContinuityCheckpoint(input) {
7104
+ const { checkpointText, decisionTexts } = buildAutoCheckpoint({
7105
+ agentId: input.agentId,
7106
+ agentRole: input.agentRole,
7107
+ sessionId: input.sessionId,
7108
+ projectName: input.projectName,
7109
+ reason: input.reason,
7110
+ memories: input.memories ?? [],
7111
+ tasks: input.tasks ?? [],
7112
+ maxSamples: input.maxSamples
7113
+ });
7114
+ const extra = input.extraSections?.filter((section) => section.trim().length > 0) ?? [];
7115
+ return {
7116
+ checkpointText: extra.length > 0 ? `${checkpointText}
7117
+
7118
+ ${extra.join("\n\n")}` : checkpointText,
7119
+ decisionTexts
7120
+ };
7121
+ }
7122
+ async function writeContinuityCheckpoint(input) {
7123
+ const result = buildContinuityCheckpoint(input);
7124
+ const now = (/* @__PURE__ */ new Date()).toISOString();
7125
+ await writeMemoryViaDaemon({
7126
+ raw_text: result.checkpointText,
7127
+ agent_id: input.agentId,
7128
+ agent_role: input.agentRole,
7129
+ session_id: input.sessionId,
7130
+ tool_name: toolNameForReason(input.reason),
7131
+ project_name: input.projectName,
7132
+ timestamp: now,
7133
+ importance: importanceForReason(input.reason, input.importance),
7134
+ task_id: input.taskId,
7135
+ memory_type: "checkpoint"
7136
+ });
7137
+ const decisionLimit = input.reason === "periodic" ? 3 : 5;
7138
+ for (const decisionText of result.decisionTexts.slice(0, decisionLimit)) {
7139
+ await writeMemoryViaDaemon({
7140
+ raw_text: decisionText,
7141
+ agent_id: input.agentId,
7142
+ agent_role: input.agentRole,
7143
+ session_id: input.sessionId,
7144
+ tool_name: "auto-decision",
7145
+ project_name: input.projectName,
7146
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7147
+ importance: 8,
7148
+ memory_type: "decision"
7149
+ });
7150
+ }
7151
+ return result;
7152
+ }
7153
+
7036
7154
  // src/adapters/claude/hooks/summary-worker.ts
7037
7155
  async function main() {
7038
7156
  const agentId = process.env.AGENT_ID ?? "default";
@@ -7091,15 +7209,8 @@ async function main() {
7091
7209
  taskRows = tasks.rows;
7092
7210
  } catch {
7093
7211
  }
7094
- const { checkpointText: summaryText, decisionTexts } = buildAutoCheckpoint({
7095
- agentId,
7096
- agentRole,
7097
- sessionId: `auto-summary-${Date.now()}`,
7098
- projectName: primaryProject,
7099
- reason: "periodic",
7100
- memories: result.rows,
7101
- tasks: taskRows
7102
- });
7212
+ const summarySessionId = `auto-summary-${Date.now()}`;
7213
+ let summaryText = "";
7103
7214
  let limitReached = false;
7104
7215
  try {
7105
7216
  const { assertMemoryLimit: assertMemoryLimit2 } = await Promise.resolve().then(() => (init_plan_limits(), plan_limits_exports));
@@ -7117,30 +7228,16 @@ async function main() {
7117
7228
  }
7118
7229
  if (limitReached) {
7119
7230
  } else {
7120
- await writeMemoryViaDaemon({
7121
- raw_text: summaryText,
7122
- agent_id: agentId,
7123
- agent_role: agentRole,
7124
- session_id: `auto-summary-${Date.now()}`,
7125
- tool_name: "auto-summary",
7126
- project_name: primaryProject,
7127
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7128
- importance: 7,
7129
- memory_type: "checkpoint"
7231
+ const checkpointResult = await writeContinuityCheckpoint({
7232
+ agentId,
7233
+ agentRole,
7234
+ sessionId: summarySessionId,
7235
+ projectName: primaryProject,
7236
+ reason: "periodic",
7237
+ memories: result.rows,
7238
+ tasks: taskRows
7130
7239
  });
7131
- for (const decisionText of decisionTexts.slice(0, 3)) {
7132
- await writeMemoryViaDaemon({
7133
- raw_text: decisionText,
7134
- agent_id: agentId,
7135
- agent_role: agentRole,
7136
- session_id: `auto-decision-${Date.now()}`,
7137
- tool_name: "auto-decision",
7138
- project_name: primaryProject,
7139
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7140
- importance: 8,
7141
- memory_type: "decision"
7142
- });
7143
- }
7240
+ summaryText = checkpointResult.checkpointText;
7144
7241
  if (!canCoordinate(agentId, agentRole)) {
7145
7242
  let totalErrors = 0;
7146
7243
  for (const [, data] of projects) {