agent-recall-core 3.4.22 → 3.4.24

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 (63) hide show
  1. package/dist/helpers/activity-feed.d.ts +27 -0
  2. package/dist/helpers/activity-feed.d.ts.map +1 -0
  3. package/dist/helpers/activity-feed.js +276 -0
  4. package/dist/helpers/activity-feed.js.map +1 -0
  5. package/dist/helpers/handoff.d.ts +26 -0
  6. package/dist/helpers/handoff.d.ts.map +1 -0
  7. package/dist/helpers/handoff.js +225 -0
  8. package/dist/helpers/handoff.js.map +1 -0
  9. package/dist/index.d.ts +10 -6
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +7 -3
  12. package/dist/index.js.map +1 -1
  13. package/dist/palace/insights-index.d.ts +31 -1
  14. package/dist/palace/insights-index.d.ts.map +1 -1
  15. package/dist/palace/insights-index.js +100 -30
  16. package/dist/palace/insights-index.js.map +1 -1
  17. package/dist/palace/rooms.d.ts.map +1 -1
  18. package/dist/palace/rooms.js +11 -2
  19. package/dist/palace/rooms.js.map +1 -1
  20. package/dist/storage/corrections.d.ts +51 -1
  21. package/dist/storage/corrections.d.ts.map +1 -1
  22. package/dist/storage/corrections.js +117 -2
  23. package/dist/storage/corrections.js.map +1 -1
  24. package/dist/tools-logic/check.d.ts +6 -0
  25. package/dist/tools-logic/check.d.ts.map +1 -1
  26. package/dist/tools-logic/check.js +10 -1
  27. package/dist/tools-logic/check.js.map +1 -1
  28. package/dist/tools-logic/dashboard-export.d.ts +55 -0
  29. package/dist/tools-logic/dashboard-export.d.ts.map +1 -1
  30. package/dist/tools-logic/dashboard-export.js +217 -15
  31. package/dist/tools-logic/dashboard-export.js.map +1 -1
  32. package/dist/tools-logic/journal-capture.d.ts.map +1 -1
  33. package/dist/tools-logic/journal-capture.js +3 -1
  34. package/dist/tools-logic/journal-capture.js.map +1 -1
  35. package/dist/tools-logic/journal-write.d.ts.map +1 -1
  36. package/dist/tools-logic/journal-write.js +4 -1
  37. package/dist/tools-logic/journal-write.js.map +1 -1
  38. package/dist/tools-logic/palace-write.d.ts.map +1 -1
  39. package/dist/tools-logic/palace-write.js +13 -6
  40. package/dist/tools-logic/palace-write.js.map +1 -1
  41. package/dist/tools-logic/recall-backend.d.ts +7 -2
  42. package/dist/tools-logic/recall-backend.d.ts.map +1 -1
  43. package/dist/tools-logic/recall-backend.js +36 -2
  44. package/dist/tools-logic/recall-backend.js.map +1 -1
  45. package/dist/tools-logic/session-end.d.ts +6 -0
  46. package/dist/tools-logic/session-end.d.ts.map +1 -1
  47. package/dist/tools-logic/session-end.js +95 -2
  48. package/dist/tools-logic/session-end.js.map +1 -1
  49. package/dist/tools-logic/session-start.d.ts +11 -0
  50. package/dist/tools-logic/session-start.d.ts.map +1 -1
  51. package/dist/tools-logic/session-start.js +49 -1
  52. package/dist/tools-logic/session-start.js.map +1 -1
  53. package/dist/tools-logic/smart-recall.d.ts +6 -0
  54. package/dist/tools-logic/smart-recall.d.ts.map +1 -1
  55. package/dist/tools-logic/smart-recall.js +51 -10
  56. package/dist/tools-logic/smart-recall.js.map +1 -1
  57. package/dist/types.d.ts +1 -1
  58. package/dist/types.js +1 -1
  59. package/dist/vector/embedding.d.ts +1 -1
  60. package/dist/vector/embedding.d.ts.map +1 -1
  61. package/dist/vector/embedding.js +5 -2
  62. package/dist/vector/embedding.js.map +1 -1
  63. package/package.json +1 -1
@@ -0,0 +1,27 @@
1
+ /**
2
+ * activity-feed — build a recent-activity timeline for a project.
3
+ *
4
+ * Merges events from:
5
+ * - journal/*.md → kind:"session_end", ts from frontmatter `created` or filename date
6
+ * - corrections/*.json → kind:"correction" (active) / "retracted" (active:false)
7
+ * - corrections/_outcomes.jsonl → kind:"retrieved"|"heeded"|"recurred"
8
+ * - palace/pipeline/*.md → kind:"phase_open"/"phase_close" from status+opened/closed
9
+ * - palace/skills/*.md → kind:"skill_write", ts from frontmatter `created`
10
+ *
11
+ * Each event: { ts: ISO, kind, desc: <=120 chars }
12
+ * Sorted newest-first, capped at limit (default 20).
13
+ * Be defensive: missing dir/file → skip. Never throws.
14
+ */
15
+ export interface ActivityEvent {
16
+ ts: string;
17
+ kind: "session_end" | "correction" | "retracted" | "retrieved" | "heeded" | "recurred" | "phase_open" | "phase_close" | "skill_write";
18
+ desc: string;
19
+ }
20
+ /**
21
+ * Build a recent-activity feed for a project.
22
+ *
23
+ * Merges events from all five sources, sorts newest-first, caps at limit.
24
+ * Returns [] on any error — never throws.
25
+ */
26
+ export declare function buildRecentActivity(slug: string, limit?: number): ActivityEvent[];
27
+ //# sourceMappingURL=activity-feed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-feed.d.ts","sourceRoot":"","sources":["../../src/helpers/activity-feed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EACA,aAAa,GACb,YAAY,GACZ,WAAW,GACX,WAAW,GACX,QAAQ,GACR,UAAU,GACV,YAAY,GACZ,aAAa,GACb,aAAa,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAiQD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,KAAK,SAAK,GACT,aAAa,EAAE,CAiBjB"}
@@ -0,0 +1,276 @@
1
+ /**
2
+ * activity-feed — build a recent-activity timeline for a project.
3
+ *
4
+ * Merges events from:
5
+ * - journal/*.md → kind:"session_end", ts from frontmatter `created` or filename date
6
+ * - corrections/*.json → kind:"correction" (active) / "retracted" (active:false)
7
+ * - corrections/_outcomes.jsonl → kind:"retrieved"|"heeded"|"recurred"
8
+ * - palace/pipeline/*.md → kind:"phase_open"/"phase_close" from status+opened/closed
9
+ * - palace/skills/*.md → kind:"skill_write", ts from frontmatter `created`
10
+ *
11
+ * Each event: { ts: ISO, kind, desc: <=120 chars }
12
+ * Sorted newest-first, capped at limit (default 20).
13
+ * Be defensive: missing dir/file → skip. Never throws.
14
+ */
15
+ import * as fs from "node:fs";
16
+ import * as path from "node:path";
17
+ import { palaceDir } from "../storage/paths.js";
18
+ import { getRoot } from "../types.js";
19
+ // ---------------------------------------------------------------------------
20
+ // Internal helpers
21
+ // ---------------------------------------------------------------------------
22
+ /**
23
+ * Safely read a file to string. Returns null on any error.
24
+ */
25
+ function safeRead(p) {
26
+ try {
27
+ return fs.readFileSync(p, "utf-8");
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ /**
34
+ * List files in a directory matching a filter. Returns [] if dir absent/unreadable.
35
+ */
36
+ function safeReaddir(dir, filter) {
37
+ try {
38
+ if (!fs.existsSync(dir))
39
+ return [];
40
+ return fs.readdirSync(dir).filter(filter);
41
+ }
42
+ catch {
43
+ return [];
44
+ }
45
+ }
46
+ function trunc(s, maxLen = 120) {
47
+ return s.length > maxLen ? s.slice(0, maxLen - 1) + "…" : s;
48
+ }
49
+ /**
50
+ * Extract `created` ISO string from YAML-ish frontmatter.
51
+ * Returns null when absent or malformed.
52
+ */
53
+ function extractFrontmatterCreated(content) {
54
+ const fm = content.match(/^---\s*\r?\n([\s\S]*?)\r?\n---\s*\r?\n/);
55
+ if (!fm)
56
+ return null;
57
+ const line = fm[1].split(/\r?\n/).find((l) => /^created\s*:/.test(l));
58
+ if (!line)
59
+ return null;
60
+ const raw = line.slice(line.indexOf(":") + 1).trim();
61
+ // Accept bare ISO or quoted ISO
62
+ const stripped = raw.replace(/^"|"$/g, "").replace(/^'|'$/g, "");
63
+ // Validate: must start with YYYY-MM-DD
64
+ if (!/^\d{4}-\d{2}-\d{2}/.test(stripped))
65
+ return null;
66
+ return stripped;
67
+ }
68
+ /**
69
+ * Convert YYYY-MM-DD date string to a midnight ISO timestamp.
70
+ * Used as a fallback when no precise timestamp is available.
71
+ */
72
+ function dateToTs(date) {
73
+ return `${date}T00:00:00.000Z`;
74
+ }
75
+ // ---------------------------------------------------------------------------
76
+ // Per-source event builders
77
+ // ---------------------------------------------------------------------------
78
+ function journalEvents(slug) {
79
+ const journalDir = path.join(getRoot(), "projects", slug, "journal");
80
+ const files = safeReaddir(journalDir, (f) => f.endsWith(".md") && f !== "index.md");
81
+ const events = [];
82
+ for (const f of files) {
83
+ // Skip capture/log files — not session completions
84
+ if (f.includes("-log.md") || f.includes("--capture--"))
85
+ continue;
86
+ const dateMatch = f.match(/^(\d{4}-\d{2}-\d{2})/);
87
+ if (!dateMatch)
88
+ continue;
89
+ const fileDate = dateMatch[1];
90
+ const content = safeRead(path.join(journalDir, f));
91
+ const created = content ? extractFrontmatterCreated(content) : null;
92
+ const ts = created ?? dateToTs(fileDate);
93
+ // Extract a brief description: first non-empty, non-header line after frontmatter
94
+ let desc = `Session on ${fileDate}`;
95
+ if (content) {
96
+ const lines = content.split("\n");
97
+ for (const line of lines) {
98
+ const t = line.trim();
99
+ if (t && !t.startsWith("#") && !t.startsWith("---") && !t.startsWith(">")) {
100
+ desc = trunc(`Session ${fileDate}: ${t}`);
101
+ break;
102
+ }
103
+ }
104
+ }
105
+ events.push({ ts, kind: "session_end", desc });
106
+ }
107
+ return events;
108
+ }
109
+ function correctionEvents(slug) {
110
+ const corrDir = path.join(getRoot(), "projects", slug, "corrections");
111
+ const files = safeReaddir(corrDir, (f) => f.endsWith(".json") && !f.startsWith("_"));
112
+ const events = [];
113
+ for (const f of files) {
114
+ const raw = safeRead(path.join(corrDir, f));
115
+ if (!raw)
116
+ continue;
117
+ let rec;
118
+ try {
119
+ rec = JSON.parse(raw);
120
+ }
121
+ catch {
122
+ continue;
123
+ }
124
+ const dateStr = typeof rec.date === "string" ? rec.date : "";
125
+ const rule = typeof rec.rule === "string" ? rec.rule : "";
126
+ const isActive = rec.active !== false;
127
+ // Use retracted_at for retracted items, else fall back to date
128
+ let ts;
129
+ if (!isActive && typeof rec.retracted_at === "string") {
130
+ ts = rec.retracted_at;
131
+ }
132
+ else {
133
+ ts = dateToTs(dateStr);
134
+ }
135
+ const kind = isActive ? "correction" : "retracted";
136
+ const prefix = isActive ? "Correction" : "Retracted";
137
+ const desc = trunc(`${prefix}: ${rule}`);
138
+ events.push({ ts, kind, desc });
139
+ }
140
+ return events;
141
+ }
142
+ function outcomeEvents(slug) {
143
+ const outcomesPath = path.join(getRoot(), "projects", slug, "corrections", "_outcomes.jsonl");
144
+ const raw = safeRead(outcomesPath);
145
+ if (!raw)
146
+ return [];
147
+ const events = [];
148
+ for (const line of raw.split("\n")) {
149
+ const trimmed = line.trim();
150
+ if (!trimmed)
151
+ continue;
152
+ let obj;
153
+ try {
154
+ obj = JSON.parse(trimmed);
155
+ }
156
+ catch {
157
+ continue;
158
+ }
159
+ const kind = obj.kind;
160
+ if (kind !== "retrieved" && kind !== "heeded" && kind !== "recurred")
161
+ continue;
162
+ const ts = typeof obj.at === "string" ? obj.at : "";
163
+ if (!ts)
164
+ continue;
165
+ const corrId = typeof obj.correction_id === "string" ? obj.correction_id : "?";
166
+ const evidence = typeof obj.evidence === "string" ? ` (${obj.evidence})` : "";
167
+ const desc = trunc(`${kind.charAt(0).toUpperCase() + kind.slice(1)}: ${corrId}${evidence}`);
168
+ events.push({
169
+ ts,
170
+ kind: kind,
171
+ desc,
172
+ });
173
+ }
174
+ return events;
175
+ }
176
+ function pipelineEvents(slug) {
177
+ const pDir = path.join(palaceDir(slug), "pipeline");
178
+ const files = safeReaddir(pDir, (f) => f.endsWith(".md") && /^\d+-/.test(f));
179
+ const events = [];
180
+ for (const f of files) {
181
+ const content = safeRead(path.join(pDir, f));
182
+ if (!content)
183
+ continue;
184
+ // Parse frontmatter minimally
185
+ const fm = content.match(/^---\s*\r?\n([\s\S]*?)\r?\n---\s*\r?\n/);
186
+ if (!fm)
187
+ continue;
188
+ const lines = fm[1].split(/\r?\n/);
189
+ const meta = {};
190
+ for (const l of lines) {
191
+ const idx = l.indexOf(":");
192
+ if (idx < 0)
193
+ continue;
194
+ const key = l.slice(0, idx).trim();
195
+ meta[key] = l.slice(idx + 1).trim().replace(/^"|"$/g, "");
196
+ }
197
+ const phase = meta.phase ?? path.basename(f, ".md");
198
+ const status = meta.status ?? "active";
199
+ const opened = meta.opened ?? "";
200
+ const closed = meta.closed ?? "";
201
+ if (opened) {
202
+ events.push({
203
+ ts: /^\d{4}-\d{2}-\d{2}/.test(opened) ? dateToTs(opened) : opened,
204
+ kind: "phase_open",
205
+ desc: trunc(`Phase opened: ${phase}`),
206
+ });
207
+ }
208
+ if ((status === "closed" || status === "abandoned") && closed) {
209
+ events.push({
210
+ ts: /^\d{4}-\d{2}-\d{2}/.test(closed) ? dateToTs(closed) : closed,
211
+ kind: "phase_close",
212
+ desc: trunc(`Phase ${status}: ${phase}`),
213
+ });
214
+ }
215
+ }
216
+ return events;
217
+ }
218
+ function skillEvents(slug) {
219
+ const sDir = path.join(palaceDir(slug), "skills");
220
+ const files = safeReaddir(sDir, (f) => f.endsWith(".md") && /^\d+-/.test(f));
221
+ const events = [];
222
+ for (const f of files) {
223
+ const content = safeRead(path.join(sDir, f));
224
+ const created = content ? extractFrontmatterCreated(content) : null;
225
+ if (!created) {
226
+ // Fallback: file mtime
227
+ try {
228
+ const stat = fs.statSync(path.join(sDir, f));
229
+ const name = path.basename(f, ".md").replace(/^\d+-/, "");
230
+ events.push({
231
+ ts: stat.mtime.toISOString(),
232
+ kind: "skill_write",
233
+ desc: trunc(`Skill written: ${name}`),
234
+ });
235
+ }
236
+ catch {
237
+ // Skip entirely
238
+ }
239
+ continue;
240
+ }
241
+ const name = path.basename(f, ".md").replace(/^\d+-/, "");
242
+ events.push({
243
+ ts: created,
244
+ kind: "skill_write",
245
+ desc: trunc(`Skill written: ${name}`),
246
+ });
247
+ }
248
+ return events;
249
+ }
250
+ // ---------------------------------------------------------------------------
251
+ // Public API
252
+ // ---------------------------------------------------------------------------
253
+ /**
254
+ * Build a recent-activity feed for a project.
255
+ *
256
+ * Merges events from all five sources, sorts newest-first, caps at limit.
257
+ * Returns [] on any error — never throws.
258
+ */
259
+ export function buildRecentActivity(slug, limit = 20) {
260
+ try {
261
+ const all = [
262
+ ...journalEvents(slug),
263
+ ...correctionEvents(slug),
264
+ ...outcomeEvents(slug),
265
+ ...pipelineEvents(slug),
266
+ ...skillEvents(slug),
267
+ ];
268
+ // Sort descending by ts (ISO strings sort lexicographically)
269
+ all.sort((a, b) => b.ts.localeCompare(a.ts));
270
+ return all.slice(0, limit);
271
+ }
272
+ catch {
273
+ return [];
274
+ }
275
+ }
276
+ //# sourceMappingURL=activity-feed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-feed.js","sourceRoot":"","sources":["../../src/helpers/activity-feed.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Handoff artifact — portable cross-agent briefing written at session_end.
3
+ *
4
+ * Automaticity Law: the file appears at projects/<slug>/handoff.md automatically
5
+ * every session_end; no new MCP tool, no agent prompt needed.
6
+ *
7
+ * Budget: HARD LIMIT 2200 chars (~500 tokens). Content is truncated at word
8
+ * boundaries and sections are omitted when empty.
9
+ */
10
+ export interface HandoffResult {
11
+ path: string;
12
+ tokens_estimate: number;
13
+ }
14
+ /**
15
+ * Generate the handoff markdown for a project.
16
+ * Pure function — reads stores, returns a string.
17
+ * Never throws: missing stores produce empty sections which are omitted.
18
+ */
19
+ export declare function generateHandoff(slug: string): string;
20
+ /**
21
+ * Write the handoff file for a project atomically.
22
+ * Returns path and rough token estimate (chars / 4).
23
+ * Never throws — errors are propagated to caller for fire-and-forget swallowing.
24
+ */
25
+ export declare function writeHandoff(slug: string): HandoffResult;
26
+ //# sourceMappingURL=handoff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handoff.d.ts","sourceRoot":"","sources":["../../src/helpers/handoff.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA+CH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmJpD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAuBxD"}
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Handoff artifact — portable cross-agent briefing written at session_end.
3
+ *
4
+ * Automaticity Law: the file appears at projects/<slug>/handoff.md automatically
5
+ * every session_end; no new MCP tool, no agent prompt needed.
6
+ *
7
+ * Budget: HARD LIMIT 2200 chars (~500 tokens). Content is truncated at word
8
+ * boundaries and sections are omitted when empty.
9
+ */
10
+ import * as fs from "node:fs";
11
+ import * as path from "node:path";
12
+ import { getRoot } from "../types.js";
13
+ import { readP0Corrections } from "../storage/corrections.js";
14
+ import { readBehaviorPolicies } from "../storage/behavior-policies.js";
15
+ import { readInsightsIndex } from "../palace/insights-index.js";
16
+ import { readIdentity } from "../palace/identity.js";
17
+ import { ensureDir } from "../storage/fs-utils.js";
18
+ import { listJournalFiles } from "./journal-files.js";
19
+ const HARD_BUDGET = 2200;
20
+ /**
21
+ * Truncate a string at word boundary, appending "…" if truncated.
22
+ */
23
+ function truncateAt(text, maxChars) {
24
+ if (text.length <= maxChars)
25
+ return text;
26
+ const cut = text.lastIndexOf(" ", maxChars - 1);
27
+ const boundary = cut > 0 ? cut : maxChars;
28
+ return text.slice(0, boundary) + "…";
29
+ }
30
+ /**
31
+ * Extract the first meaningful (non-heading, non-blank) line from a markdown string.
32
+ * Returns empty string when nothing is found.
33
+ */
34
+ function firstMeaningfulLine(md) {
35
+ for (const line of md.split("\n")) {
36
+ const t = line.trim();
37
+ if (t && !t.startsWith("#") && !t.startsWith(">") && !t.startsWith("---")) {
38
+ return t;
39
+ }
40
+ }
41
+ return "";
42
+ }
43
+ /**
44
+ * Local-date string in YYYY-MM-DD format (system TZ).
45
+ */
46
+ function localDate() {
47
+ return new Date().toLocaleDateString("sv"); // 'sv' locale gives YYYY-MM-DD
48
+ }
49
+ /**
50
+ * Generate the handoff markdown for a project.
51
+ * Pure function — reads stores, returns a string.
52
+ * Never throws: missing stores produce empty sections which are omitted.
53
+ */
54
+ export function generateHandoff(slug) {
55
+ const date = localDate();
56
+ const lines = [];
57
+ // ── Header ────────────────────────────────────────────────────────────────
58
+ lines.push(`# Handoff — ${slug} (${date})`);
59
+ lines.push("");
60
+ // ── Intention ─────────────────────────────────────────────────────────────
61
+ try {
62
+ const identity = readIdentity(slug);
63
+ let intention = firstMeaningfulLine(identity);
64
+ // identity.md often already starts with "**Intention:** ..." — strip the
65
+ // prefix so the template's own label doesn't double it.
66
+ if (intention)
67
+ intention = intention.replace(/^\*{0,2}Intention:?\*{0,2}\s*/i, "");
68
+ if (intention) {
69
+ lines.push(`**Intention:** ${intention}`);
70
+ lines.push("");
71
+ }
72
+ }
73
+ catch { /* omit */ }
74
+ // ── Binding rules (P0 corrections, ≤5) ───────────────────────────────────
75
+ try {
76
+ const p0 = readP0Corrections(slug).slice(0, 5);
77
+ if (p0.length > 0) {
78
+ lines.push("## Binding rules");
79
+ for (const c of p0) {
80
+ lines.push(`- ${c.rule}`);
81
+ }
82
+ lines.push("");
83
+ }
84
+ }
85
+ catch { /* omit */ }
86
+ // ── Behavior policies (≤3) ────────────────────────────────────────────────
87
+ try {
88
+ const { rules } = readBehaviorPolicies(slug);
89
+ const top = rules.slice(0, 3);
90
+ if (top.length > 0) {
91
+ lines.push("## Behavior policies");
92
+ for (const r of top) {
93
+ lines.push(`- **${r.name}**: ${r.do}`);
94
+ }
95
+ lines.push("");
96
+ }
97
+ }
98
+ catch { /* omit */ }
99
+ // ── Active blockers (from latest journal "## Blockers" section) ───────────
100
+ try {
101
+ const entries = listJournalFiles(slug);
102
+ if (entries.length > 0) {
103
+ const latest = entries[0];
104
+ const content = fs.readFileSync(path.join(latest.dir, latest.file), "utf-8");
105
+ // extractSection expects the SECTION_HEADERS map key; check if a
106
+ // "## Blockers" heading is present by scanning directly (no SECTION_HEADERS key).
107
+ const blockerIdx = content.indexOf("## Blockers");
108
+ if (blockerIdx !== -1) {
109
+ const section = content.slice(blockerIdx);
110
+ const sectionLines = section.split("\n");
111
+ const body = [];
112
+ for (let i = 1; i < sectionLines.length; i++) {
113
+ if (sectionLines[i].startsWith("## "))
114
+ break;
115
+ const t = sectionLines[i].trim();
116
+ if (t)
117
+ body.push(t);
118
+ }
119
+ if (body.length > 0) {
120
+ lines.push("## Active blockers");
121
+ lines.push(body.slice(0, 5).join("\n"));
122
+ lines.push("");
123
+ }
124
+ }
125
+ }
126
+ }
127
+ catch { /* omit */ }
128
+ // ── Top insights (≤3, highest confirmed_count for this project) ───────────
129
+ try {
130
+ const index = readInsightsIndex();
131
+ const projectInsights = index.insights
132
+ .filter((i) => !i.projects || i.projects.length === 0 || i.projects.includes(slug))
133
+ .sort((a, b) => b.confirmed_count - a.confirmed_count)
134
+ .slice(0, 3);
135
+ if (projectInsights.length > 0) {
136
+ lines.push("## Top insights");
137
+ for (const ins of projectInsights) {
138
+ lines.push(`- ${ins.title} (confirmed ×${ins.confirmed_count})`);
139
+ }
140
+ lines.push("");
141
+ }
142
+ }
143
+ catch { /* omit */ }
144
+ // ── Trajectory (## Next from newest journal) ──────────────────────────────
145
+ try {
146
+ const entries = listJournalFiles(slug);
147
+ if (entries.length > 0) {
148
+ const latest = entries[0];
149
+ const content = fs.readFileSync(path.join(latest.dir, latest.file), "utf-8");
150
+ // Use extractSection for the "next" key if available; fall back to raw scan.
151
+ let nextText = null;
152
+ const nextIdx = content.indexOf("## Next");
153
+ if (nextIdx !== -1) {
154
+ const section = content.slice(nextIdx);
155
+ const sectionLines = section.split("\n");
156
+ const body = [];
157
+ for (let i = 1; i < sectionLines.length; i++) {
158
+ if (sectionLines[i].startsWith("## "))
159
+ break;
160
+ const t = sectionLines[i].trim();
161
+ if (t)
162
+ body.push(t);
163
+ }
164
+ if (body.length > 0) {
165
+ nextText = body.join(" ");
166
+ }
167
+ }
168
+ if (nextText) {
169
+ lines.push("## Trajectory");
170
+ lines.push(truncateAt(nextText, 300));
171
+ lines.push("");
172
+ }
173
+ }
174
+ }
175
+ catch { /* omit */ }
176
+ // ── Footer ────────────────────────────────────────────────────────────────
177
+ lines.push("---");
178
+ lines.push("*Generated by AgentRecall session_end · paste into any agent*");
179
+ // ── Budget enforcement ─────────────────────────────────────────────────────
180
+ // HARD LIMIT: output MUST NOT exceed HARD_BUDGET characters.
181
+ // Truncate at word boundary, preserving the footer.
182
+ const footer = "\n---\n*Generated by AgentRecall session_end · paste into any agent*";
183
+ let body = lines.join("\n");
184
+ // Remove the footer from body before budget check, re-append after.
185
+ const bodyWithoutFooter = body.endsWith(footer)
186
+ ? body.slice(0, body.length - footer.length)
187
+ : body.slice(0, body.lastIndexOf("\n---\n"));
188
+ if (body.length > HARD_BUDGET) {
189
+ const budgetForBody = HARD_BUDGET - footer.length - 1;
190
+ const truncated = truncateAt(bodyWithoutFooter.trimEnd(), budgetForBody);
191
+ body = truncated + "\n" + footer;
192
+ }
193
+ // Assertion: enforce hard budget (catches regressions in section growth).
194
+ if (body.length > HARD_BUDGET) {
195
+ // Last-resort hard slice at word boundary.
196
+ body = truncateAt(body, HARD_BUDGET);
197
+ }
198
+ return body;
199
+ }
200
+ /**
201
+ * Write the handoff file for a project atomically.
202
+ * Returns path and rough token estimate (chars / 4).
203
+ * Never throws — errors are propagated to caller for fire-and-forget swallowing.
204
+ */
205
+ export function writeHandoff(slug) {
206
+ const root = getRoot();
207
+ // Sanitize slug for path safety (same pattern as sanitizeProject).
208
+ const safe = (slug || "unnamed")
209
+ .replace(/[^a-zA-Z0-9_\-]/g, "-")
210
+ .replace(/^-+|-+$/g, "")
211
+ .slice(0, 100) || "unnamed";
212
+ const projectDir = path.join(root, "projects", safe);
213
+ ensureDir(projectDir);
214
+ const handoffPath = path.join(projectDir, "handoff.md");
215
+ const content = generateHandoff(slug);
216
+ // Atomic write: tmp + rename (POSIX-atomic).
217
+ const tmp = `${handoffPath}.tmp.${process.pid}.${Date.now()}`;
218
+ fs.writeFileSync(tmp, content, { encoding: "utf-8", mode: 0o600 });
219
+ fs.renameSync(tmp, handoffPath);
220
+ return {
221
+ path: handoffPath,
222
+ tokens_estimate: Math.ceil(content.length / 4),
223
+ };
224
+ }
225
+ //# sourceMappingURL=handoff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handoff.js","sourceRoot":"","sources":["../../src/helpers/handoff.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ export type { FanOutResult } from "./palace/fan-out.js";
13
13
  export { readAwareness, writeAwareness, readAwarenessState, writeAwarenessState, initAwareness, addInsight, detectCompoundInsights, renderAwareness, readAwarenessArchive, writeAwarenessArchive, resurrectFromArchive, } from "./palace/awareness.js";
14
14
  export type { Insight, CompoundInsight, AwarenessState, } from "./palace/awareness.js";
15
15
  export { computeSalience, ARCHIVE_THRESHOLD, AUTO_ARCHIVE_THRESHOLD, CATEGORY_DECAY, URGENCY_WEIGHTS, } from "./palace/salience.js";
16
- export { readInsightsIndex, writeInsightsIndex, addIndexedInsight, recallInsights, } from "./palace/insights-index.js";
16
+ export { readInsightsIndex, writeInsightsIndex, addIndexedInsight, recallInsights, findSimilarInsight, normalizeTitle, tokenOverlap, } from "./palace/insights-index.js";
17
17
  export type { IndexedInsight, InsightsIndex, } from "./palace/insights-index.js";
18
18
  export { readIdentity, writeIdentity } from "./palace/identity.js";
19
19
  export { readPalaceIndex, updatePalaceIndex } from "./palace/index-manager.js";
@@ -37,8 +37,8 @@ export type { CheckActionInput, CheckActionResult, RuleMatch, CorrectionMatch, I
37
37
  export { getSessionId, journalFileName, captureLogFileName, resetOwnedFiles, resetSessionState } from "./storage/session.js";
38
38
  export type { SaveType, SmartNameOpts } from "./storage/session.js";
39
39
  export { acquireLock, withLock } from "./storage/filelock.js";
40
- export { writeCorrection, readCorrections, readActiveCorrections, readP0Corrections } from "./storage/corrections.js";
41
- export type { CorrectionRecord } from "./storage/corrections.js";
40
+ export { writeCorrection, readCorrections, readActiveCorrections, readP0Corrections, retractCorrection, isLikelyRealCorrection, } from "./storage/corrections.js";
41
+ export type { CorrectionRecord, WriteCorrectionResult, RetractCorrectionResult, } from "./storage/corrections.js";
42
42
  export { listJournalFiles, readJournalFile, extractTitle, extractMomentum, countLogEntries, updateIndex, } from "./helpers/journal-files.js";
43
43
  export { extractSection, appendToSection } from "./helpers/sections.js";
44
44
  export { isoWeek, weekKey, groupByWeek, synthesizeWeek } from "./helpers/rollup.js";
@@ -55,6 +55,8 @@ export { stem, getSynonyms, expandQuery } from "./helpers/normalize.js";
55
55
  export { isJournalFile } from "./helpers/journal-filter.js";
56
56
  export { readAlignmentLog, extractWatchPatterns } from "./helpers/alignment-patterns.js";
57
57
  export type { WatchForPattern } from "./helpers/alignment-patterns.js";
58
+ export { generateHandoff, writeHandoff } from "./helpers/handoff.js";
59
+ export type { HandoffResult } from "./helpers/handoff.js";
58
60
  export { journalRead, type JournalReadInput, type JournalReadResult } from "./tools-logic/journal-read.js";
59
61
  export { journalWrite, type JournalWriteInput, type JournalWriteResult } from "./tools-logic/journal-write.js";
60
62
  export { journalCapture, type JournalCaptureInput, type JournalCaptureResult } from "./tools-logic/journal-capture.js";
@@ -81,7 +83,7 @@ export { recallInsight, type RecallInsightInput, type RecallInsightResult } from
81
83
  export { journalMerge, type JournalMergeInput, type MergeReceipt } from "./tools-logic/journal-merge.js";
82
84
  export { smartRemember, type SmartRememberInput, type SmartRememberResult } from "./tools-logic/smart-remember.js";
83
85
  export { smartRemember as remember } from "./tools-logic/smart-remember.js";
84
- export { smartRecall, type SmartRecallInput, type SmartRecallResult, type SmartRecallResultItem } from "./tools-logic/smart-recall.js";
86
+ export { smartRecall, type SmartRecallInput, type SmartRecallResult, type SmartRecallResultItem, type SmartRecallDegraded } from "./tools-logic/smart-recall.js";
85
87
  export { sessionStart, type SessionStartInput, type SessionStartResult } from "./tools-logic/session-start.js";
86
88
  export { sessionEnd, checkInsightQuality, type SessionEndInput, type SessionEndResult, type InsightQualityWarning, type MergeSuggestion } from "./tools-logic/session-end.js";
87
89
  export { promoteConfirmedInsights, type PromotionResult } from "./tools-logic/insight-promotion.js";
@@ -103,7 +105,7 @@ export { OpenAIEmbedding, VoyageEmbedding, zeroPad, createEmbeddingProvider } fr
103
105
  export type { EmbeddingProvider } from "./supabase/embedding.js";
104
106
  export { syncToSupabase, backfill, contentHash, parseMemoryFile, deriveSlug, logSyncError } from "./supabase/sync.js";
105
107
  export type { ParsedMemoryFile } from "./supabase/sync.js";
106
- export { LocalRecallBackend, getRecallBackend, resetRecallBackend } from "./tools-logic/recall-backend.js";
108
+ export { LocalRecallBackend, getRecallBackend, resetRecallBackend, recordRemoteFailure, recordRemoteSuccess } from "./tools-logic/recall-backend.js";
107
109
  export type { RecallBackend } from "./tools-logic/recall-backend.js";
108
110
  export { SupabaseRecallBackend } from "./supabase/recall-backend.js";
109
111
  export { LocalVectorRecallBackend } from "./vector/local-vector-backend.js";
@@ -143,5 +145,7 @@ export type { SessionStartLiteInput, SessionStartLiteResult } from "./tools-logi
143
145
  export { sessionEndReflect } from "./tools-logic/session-end-reflect.js";
144
146
  export type { ReflectInput, ReflectResult, ReflectInputBundle } from "./tools-logic/session-end-reflect.js";
145
147
  export { dashboardExport } from "./tools-logic/dashboard-export.js";
146
- export type { DashboardExportInput, DashboardExportResult, DashboardSnapshot, DashboardProjectSnapshot, } from "./tools-logic/dashboard-export.js";
148
+ export type { DashboardExportInput, DashboardExportResult, DashboardSnapshot, DashboardProjectSnapshot, DashboardDreamHealth, DreamHealthCell, } from "./tools-logic/dashboard-export.js";
149
+ export { buildRecentActivity } from "./helpers/activity-feed.js";
150
+ export type { ActivityEvent } from "./helpers/activity-feed.js";
147
151
  //# sourceMappingURL=index.d.ts.map