agent-recall-core 3.4.18 → 3.4.21
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.
- package/README.md +404 -981
- package/dist/index.d.ts +45 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -1
- package/dist/index.js.map +1 -1
- package/dist/naming.d.ts +109 -0
- package/dist/naming.d.ts.map +1 -0
- package/dist/naming.js +198 -0
- package/dist/naming.js.map +1 -0
- package/dist/palace/awareness.d.ts +6 -0
- package/dist/palace/awareness.d.ts.map +1 -1
- package/dist/palace/awareness.js +19 -0
- package/dist/palace/awareness.js.map +1 -1
- package/dist/palace/fsrs.d.ts +64 -0
- package/dist/palace/fsrs.d.ts.map +1 -0
- package/dist/palace/fsrs.js +86 -0
- package/dist/palace/fsrs.js.map +1 -0
- package/dist/palace/hopfield.d.ts +108 -0
- package/dist/palace/hopfield.d.ts.map +1 -0
- package/dist/palace/hopfield.js +237 -0
- package/dist/palace/hopfield.js.map +1 -0
- package/dist/palace/obsidian.d.ts.map +1 -1
- package/dist/palace/obsidian.js +25 -1
- package/dist/palace/obsidian.js.map +1 -1
- package/dist/palace/pipeline.d.ts +61 -0
- package/dist/palace/pipeline.d.ts.map +1 -0
- package/dist/palace/pipeline.js +289 -0
- package/dist/palace/pipeline.js.map +1 -0
- package/dist/palace/skills.d.ts +71 -0
- package/dist/palace/skills.d.ts.map +1 -0
- package/dist/palace/skills.js +225 -0
- package/dist/palace/skills.js.map +1 -0
- package/dist/storage/behavior-policies.d.ts +54 -0
- package/dist/storage/behavior-policies.d.ts.map +1 -0
- package/dist/storage/behavior-policies.js +98 -0
- package/dist/storage/behavior-policies.js.map +1 -0
- package/dist/storage/corrections.d.ts +54 -0
- package/dist/storage/corrections.d.ts.map +1 -1
- package/dist/storage/corrections.js +93 -4
- package/dist/storage/corrections.js.map +1 -1
- package/dist/storage/cwd-allowlist.d.ts +33 -0
- package/dist/storage/cwd-allowlist.d.ts.map +1 -0
- package/dist/storage/cwd-allowlist.js +106 -0
- package/dist/storage/cwd-allowlist.js.map +1 -0
- package/dist/storage/dream-health.d.ts +19 -0
- package/dist/storage/dream-health.d.ts.map +1 -0
- package/dist/storage/dream-health.js +79 -0
- package/dist/storage/dream-health.js.map +1 -0
- package/dist/storage/paths.d.ts +12 -0
- package/dist/storage/paths.d.ts.map +1 -1
- package/dist/storage/paths.js +37 -15
- package/dist/storage/paths.js.map +1 -1
- package/dist/storage/project.d.ts +6 -0
- package/dist/storage/project.d.ts.map +1 -1
- package/dist/storage/project.js +26 -1
- package/dist/storage/project.js.map +1 -1
- package/dist/storage/session.d.ts.map +1 -1
- package/dist/storage/session.js +16 -1
- package/dist/storage/session.js.map +1 -1
- package/dist/tools-logic/bootstrap.d.ts.map +1 -1
- package/dist/tools-logic/bootstrap.js +69 -6
- package/dist/tools-logic/bootstrap.js.map +1 -1
- package/dist/tools-logic/check-action.d.ts +55 -0
- package/dist/tools-logic/check-action.d.ts.map +1 -0
- package/dist/tools-logic/check-action.js +152 -0
- package/dist/tools-logic/check-action.js.map +1 -0
- package/dist/tools-logic/dashboard-export.d.ts +75 -0
- package/dist/tools-logic/dashboard-export.d.ts.map +1 -0
- package/dist/tools-logic/dashboard-export.js +271 -0
- package/dist/tools-logic/dashboard-export.js.map +1 -0
- package/dist/tools-logic/pipeline-close.d.ts +22 -0
- package/dist/tools-logic/pipeline-close.d.ts.map +1 -0
- package/dist/tools-logic/pipeline-close.js +66 -0
- package/dist/tools-logic/pipeline-close.js.map +1 -0
- package/dist/tools-logic/pipeline-current.d.ts +11 -0
- package/dist/tools-logic/pipeline-current.d.ts.map +1 -0
- package/dist/tools-logic/pipeline-current.js +8 -0
- package/dist/tools-logic/pipeline-current.js.map +1 -0
- package/dist/tools-logic/pipeline-list.d.ts +11 -0
- package/dist/tools-logic/pipeline-list.d.ts.map +1 -0
- package/dist/tools-logic/pipeline-list.js +8 -0
- package/dist/tools-logic/pipeline-list.js.map +1 -0
- package/dist/tools-logic/pipeline-open.d.ts +23 -0
- package/dist/tools-logic/pipeline-open.d.ts.map +1 -0
- package/dist/tools-logic/pipeline-open.js +109 -0
- package/dist/tools-logic/pipeline-open.js.map +1 -0
- package/dist/tools-logic/pipeline-show.d.ts +34 -0
- package/dist/tools-logic/pipeline-show.d.ts.map +1 -0
- package/dist/tools-logic/pipeline-show.js +134 -0
- package/dist/tools-logic/pipeline-show.js.map +1 -0
- package/dist/tools-logic/register-rule.d.ts +15 -0
- package/dist/tools-logic/register-rule.d.ts.map +1 -0
- package/dist/tools-logic/register-rule.js +13 -0
- package/dist/tools-logic/register-rule.js.map +1 -0
- package/dist/tools-logic/session-end-reflect.d.ts +57 -0
- package/dist/tools-logic/session-end-reflect.d.ts.map +1 -0
- package/dist/tools-logic/session-end-reflect.js +117 -0
- package/dist/tools-logic/session-end-reflect.js.map +1 -0
- package/dist/tools-logic/session-end.d.ts +29 -0
- package/dist/tools-logic/session-end.d.ts.map +1 -1
- package/dist/tools-logic/session-end.js +34 -0
- package/dist/tools-logic/session-end.js.map +1 -1
- package/dist/tools-logic/session-start-lite.d.ts +26 -0
- package/dist/tools-logic/session-start-lite.d.ts.map +1 -0
- package/dist/tools-logic/session-start-lite.js +46 -0
- package/dist/tools-logic/session-start-lite.js.map +1 -0
- package/dist/tools-logic/session-start.d.ts +26 -0
- package/dist/tools-logic/session-start.d.ts.map +1 -1
- package/dist/tools-logic/session-start.js +53 -7
- package/dist/tools-logic/session-start.js.map +1 -1
- package/dist/tools-logic/skill-list.d.ts +19 -0
- package/dist/tools-logic/skill-list.d.ts.map +1 -0
- package/dist/tools-logic/skill-list.js +20 -0
- package/dist/tools-logic/skill-list.js.map +1 -0
- package/dist/tools-logic/skill-recall.d.ts +26 -0
- package/dist/tools-logic/skill-recall.d.ts.map +1 -0
- package/dist/tools-logic/skill-recall.js +32 -0
- package/dist/tools-logic/skill-recall.js.map +1 -0
- package/dist/tools-logic/skill-write.d.ts +23 -0
- package/dist/tools-logic/skill-write.d.ts.map +1 -0
- package/dist/tools-logic/skill-write.js +46 -0
- package/dist/tools-logic/skill-write.js.map +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline layer — project milestone narrative spine.
|
|
3
|
+
* Stored under palace/pipeline/NNNN-phase-slug.md, one file per phase.
|
|
4
|
+
* Distinct from journal (chronology), palace/rooms (facts), awareness (cross-project).
|
|
5
|
+
*
|
|
6
|
+
* Hardening notes:
|
|
7
|
+
* - Order numbers sorted numerically (lex sort breaks at 10).
|
|
8
|
+
* - Atomic writes via tmp+rename (writeFileSync is not crash-safe).
|
|
9
|
+
* - Section parser only ends at the four KNOWN headings, so user-supplied
|
|
10
|
+
* "## Anything" inside a section body cannot break it.
|
|
11
|
+
* - Frontmatter parser accepts both quoted (JSON-encoded) and bare scalars.
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from "node:fs";
|
|
14
|
+
import * as path from "node:path";
|
|
15
|
+
import { palaceDir, sanitizeSlug } from "../storage/paths.js";
|
|
16
|
+
import { ensureDir } from "../storage/fs-utils.js";
|
|
17
|
+
import { generateFrontmatter } from "./obsidian.js";
|
|
18
|
+
const PLACEHOLDER = "(in progress)";
|
|
19
|
+
const ORDER_PAD = 4;
|
|
20
|
+
const KNOWN_SECTIONS = ["Goal", "What was hard", "How solved", "Synthesis"];
|
|
21
|
+
export function pipelineDir(project) {
|
|
22
|
+
return path.join(palaceDir(project), "pipeline");
|
|
23
|
+
}
|
|
24
|
+
export function zeroPad(n, width = ORDER_PAD) {
|
|
25
|
+
return n.toString().padStart(width, "0");
|
|
26
|
+
}
|
|
27
|
+
export function milestoneFileName(order, phase) {
|
|
28
|
+
return `${zeroPad(order)}-${sanitizeSlug(phase)}.md`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Parse a quoted YAML scalar back to its native string.
|
|
32
|
+
* Handles both JSON-encoded (`"with \n escapes"`) and bare values.
|
|
33
|
+
*/
|
|
34
|
+
function parseScalar(raw) {
|
|
35
|
+
const trimmed = raw.trim();
|
|
36
|
+
if (trimmed === "" || trimmed === "null" || trimmed === "~")
|
|
37
|
+
return null;
|
|
38
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
39
|
+
try {
|
|
40
|
+
return JSON.parse(trimmed);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Fall through — return raw stripped quotes
|
|
44
|
+
return trimmed.slice(1, -1);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (/^-?\d+$/.test(trimmed))
|
|
48
|
+
return Number(trimmed);
|
|
49
|
+
return trimmed;
|
|
50
|
+
}
|
|
51
|
+
function parseFrontmatter(raw) {
|
|
52
|
+
// Accept LF or CRLF after the closing ---
|
|
53
|
+
const match = raw.match(/^---\s*\r?\n([\s\S]*?)\r?\n---\s*\r?\n([\s\S]*)$/);
|
|
54
|
+
if (!match)
|
|
55
|
+
return { meta: {}, body: raw };
|
|
56
|
+
const meta = {};
|
|
57
|
+
for (const line of match[1].split(/\r?\n/)) {
|
|
58
|
+
const idx = line.indexOf(":");
|
|
59
|
+
if (idx < 0)
|
|
60
|
+
continue;
|
|
61
|
+
const key = line.slice(0, idx).trim();
|
|
62
|
+
const rawValue = line.slice(idx + 1).trim();
|
|
63
|
+
if (!key)
|
|
64
|
+
continue;
|
|
65
|
+
if (rawValue.startsWith("[") && rawValue.endsWith("]")) {
|
|
66
|
+
const inner = rawValue.slice(1, -1).trim();
|
|
67
|
+
if (!inner) {
|
|
68
|
+
meta[key] = [];
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Split on commas that are NOT inside quoted strings
|
|
72
|
+
const items = [];
|
|
73
|
+
let depth = 0;
|
|
74
|
+
let cur = "";
|
|
75
|
+
let inQuote = false;
|
|
76
|
+
for (const ch of inner) {
|
|
77
|
+
if (ch === '"' && cur[cur.length - 1] !== "\\")
|
|
78
|
+
inQuote = !inQuote;
|
|
79
|
+
if (ch === "," && !inQuote && depth === 0) {
|
|
80
|
+
items.push(cur.trim());
|
|
81
|
+
cur = "";
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
cur += ch;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (cur.trim())
|
|
88
|
+
items.push(cur.trim());
|
|
89
|
+
meta[key] = items.map((s) => {
|
|
90
|
+
const scalar = parseScalar(s);
|
|
91
|
+
return scalar === null ? "" : String(scalar);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
meta[key] = parseScalar(rawValue);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return { meta, body: match[2] };
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Extract a section body by name via line-walk. Boundary is the next KNOWN
|
|
103
|
+
* section heading exactly matching one of Goal / What was hard / How solved /
|
|
104
|
+
* Synthesis. Anything else — including `## SomeOtherHeading` that the user
|
|
105
|
+
* (or an attacker) wrote inside a section body — is preserved verbatim.
|
|
106
|
+
*/
|
|
107
|
+
function extractSection(body, heading) {
|
|
108
|
+
const known = new Set(KNOWN_SECTIONS);
|
|
109
|
+
const lines = body.split(/\r?\n/);
|
|
110
|
+
let capturing = false;
|
|
111
|
+
const captured = [];
|
|
112
|
+
for (const line of lines) {
|
|
113
|
+
const m = line.match(/^##\s+(.+?)\s*$/);
|
|
114
|
+
if (m && known.has(m[1])) {
|
|
115
|
+
if (capturing)
|
|
116
|
+
break; // reached next KNOWN section — stop
|
|
117
|
+
if (m[1] === heading) {
|
|
118
|
+
capturing = true;
|
|
119
|
+
}
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (capturing)
|
|
123
|
+
captured.push(line);
|
|
124
|
+
}
|
|
125
|
+
// Trim trailing blank lines but preserve internal blank lines.
|
|
126
|
+
while (captured.length > 0 && captured[captured.length - 1].trim() === "")
|
|
127
|
+
captured.pop();
|
|
128
|
+
return captured.join("\n").trim();
|
|
129
|
+
}
|
|
130
|
+
function parseMeta(raw, fallbackOrder) {
|
|
131
|
+
const statusRaw = String(raw.status ?? "");
|
|
132
|
+
const status = statusRaw === "closed" || statusRaw === "abandoned" || statusRaw === "active" ? statusRaw : "active";
|
|
133
|
+
return {
|
|
134
|
+
phase: String(raw.phase ?? ""),
|
|
135
|
+
order: typeof raw.order === "number" ? raw.order : fallbackOrder,
|
|
136
|
+
status,
|
|
137
|
+
opened: String(raw.opened ?? ""),
|
|
138
|
+
closed: raw.closed === null || raw.closed === undefined ? null : String(raw.closed),
|
|
139
|
+
related_journal: Array.isArray(raw.related_journal) ? raw.related_journal : undefined,
|
|
140
|
+
related_insights: Array.isArray(raw.related_insights) ? raw.related_insights : undefined,
|
|
141
|
+
auto: raw.auto === true,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
export function parseMilestoneFile(filePath) {
|
|
145
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
146
|
+
const { meta: rawMeta, body } = parseFrontmatter(raw);
|
|
147
|
+
const base = path.basename(filePath, ".md");
|
|
148
|
+
const inferredOrder = Number(base.split("-")[0]) || 0;
|
|
149
|
+
return {
|
|
150
|
+
meta: parseMeta(rawMeta, inferredOrder),
|
|
151
|
+
sections: {
|
|
152
|
+
goal: extractSection(body, "Goal"),
|
|
153
|
+
what_was_hard: extractSection(body, "What was hard"),
|
|
154
|
+
how_solved: extractSection(body, "How solved"),
|
|
155
|
+
synthesis: extractSection(body, "Synthesis"),
|
|
156
|
+
},
|
|
157
|
+
file_path: filePath,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Validate a parsed milestone. Returns null if file is too broken to trust,
|
|
162
|
+
* which causes listMilestones to skip it (rather than promote junk to "active").
|
|
163
|
+
*/
|
|
164
|
+
function isWellFormed(m) {
|
|
165
|
+
if (!m.meta.phase)
|
|
166
|
+
return false;
|
|
167
|
+
if (!m.meta.opened)
|
|
168
|
+
return false;
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
export function listMilestones(project) {
|
|
172
|
+
const dir = pipelineDir(project);
|
|
173
|
+
if (!fs.existsSync(dir))
|
|
174
|
+
return [];
|
|
175
|
+
const files = fs.readdirSync(dir).filter((f) => f.endsWith(".md") && /^\d+-/.test(f));
|
|
176
|
+
const milestones = [];
|
|
177
|
+
for (const f of files) {
|
|
178
|
+
try {
|
|
179
|
+
const m = parseMilestoneFile(path.join(dir, f));
|
|
180
|
+
if (isWellFormed(m))
|
|
181
|
+
milestones.push(m);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// Skip unreadable files — don't crash list
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// Numeric sort by order (lex sort breaks at order=10)
|
|
188
|
+
milestones.sort((a, b) => a.meta.order - b.meta.order);
|
|
189
|
+
return milestones;
|
|
190
|
+
}
|
|
191
|
+
export function findActiveMilestone(project) {
|
|
192
|
+
const all = listMilestones(project);
|
|
193
|
+
return all.find((m) => m.meta.status === "active") ?? null;
|
|
194
|
+
}
|
|
195
|
+
export function nextOrder(project) {
|
|
196
|
+
const all = listMilestones(project);
|
|
197
|
+
if (all.length === 0)
|
|
198
|
+
return 1;
|
|
199
|
+
return Math.max(...all.map((m) => m.meta.order)) + 1;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Strip carriage returns, collapse newlines to spaces, and trim — for embedding
|
|
203
|
+
* user content into a single-line context (markdown heading, frontmatter).
|
|
204
|
+
*/
|
|
205
|
+
function singleLine(s) {
|
|
206
|
+
return s.replace(/\r/g, "").replace(/\n+/g, " ").trim();
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Escape body sections so that no user-supplied "## Known Heading" line can
|
|
210
|
+
* end a section prematurely. We prefix any such line with a zero-width-joiner
|
|
211
|
+
* marker that survives display but breaks the parser's regex.
|
|
212
|
+
*
|
|
213
|
+
* Cheap, reversible enough for human reading: the markdown renders normally
|
|
214
|
+
* except `## Goal` → `## Goal` (with U+200B). Most viewers show identically.
|
|
215
|
+
*/
|
|
216
|
+
function escapeSectionBody(s) {
|
|
217
|
+
return s.replace(/^(##\s+)(Goal|What was hard|How solved|Synthesis)\b/gim, "$1$2");
|
|
218
|
+
}
|
|
219
|
+
export function renderMilestone(meta, sections) {
|
|
220
|
+
const fm = generateFrontmatter({
|
|
221
|
+
phase: meta.phase,
|
|
222
|
+
order: meta.order,
|
|
223
|
+
status: meta.status,
|
|
224
|
+
opened: meta.opened,
|
|
225
|
+
closed: meta.closed ?? null,
|
|
226
|
+
auto: meta.auto === true ? true : false,
|
|
227
|
+
related_journal: meta.related_journal ?? [],
|
|
228
|
+
related_insights: meta.related_insights ?? [],
|
|
229
|
+
});
|
|
230
|
+
const safePhase = singleLine(meta.phase);
|
|
231
|
+
const g = escapeSectionBody(sections.goal || PLACEHOLDER);
|
|
232
|
+
const h = escapeSectionBody(sections.what_was_hard || PLACEHOLDER);
|
|
233
|
+
const s = escapeSectionBody(sections.how_solved || PLACEHOLDER);
|
|
234
|
+
const sy = escapeSectionBody(sections.synthesis || PLACEHOLDER);
|
|
235
|
+
return (fm +
|
|
236
|
+
`# Phase ${zeroPad(meta.order)} — ${safePhase}\n\n` +
|
|
237
|
+
`## Goal\n${g}\n\n` +
|
|
238
|
+
`## What was hard\n${h}\n\n` +
|
|
239
|
+
`## How solved\n${s}\n\n` +
|
|
240
|
+
`## Synthesis\n${sy}\n`);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Write a milestone file atomically via tmp + rename.
|
|
244
|
+
* Refuses to follow symlinks at the target path.
|
|
245
|
+
*/
|
|
246
|
+
export function writeMilestone(project, meta, sections, existingFilePath) {
|
|
247
|
+
const dir = pipelineDir(project);
|
|
248
|
+
ensureDir(dir);
|
|
249
|
+
const filePath = existingFilePath ?? path.join(dir, milestoneFileName(meta.order, meta.phase));
|
|
250
|
+
// Symlink guard: if the target already exists and is a symlink, refuse.
|
|
251
|
+
try {
|
|
252
|
+
const lst = fs.lstatSync(filePath);
|
|
253
|
+
if (lst.isSymbolicLink()) {
|
|
254
|
+
throw new Error(`Refusing to write through symlink: ${filePath}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
catch (err) {
|
|
258
|
+
if (err.code !== "ENOENT")
|
|
259
|
+
throw err;
|
|
260
|
+
}
|
|
261
|
+
// Same check on parent dir
|
|
262
|
+
try {
|
|
263
|
+
const dirStat = fs.lstatSync(dir);
|
|
264
|
+
if (dirStat.isSymbolicLink()) {
|
|
265
|
+
throw new Error(`Refusing to write into symlinked dir: ${dir}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
if (err.code !== "ENOENT")
|
|
270
|
+
throw err;
|
|
271
|
+
}
|
|
272
|
+
const tmp = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
273
|
+
fs.writeFileSync(tmp, renderMilestone(meta, sections), { encoding: "utf-8", mode: 0o600 });
|
|
274
|
+
fs.renameSync(tmp, filePath); // atomic on same filesystem
|
|
275
|
+
return filePath;
|
|
276
|
+
}
|
|
277
|
+
export function summarize(m) {
|
|
278
|
+
return {
|
|
279
|
+
order: m.meta.order,
|
|
280
|
+
phase: m.meta.phase,
|
|
281
|
+
status: m.meta.status,
|
|
282
|
+
opened: m.meta.opened,
|
|
283
|
+
closed: m.meta.closed ?? null,
|
|
284
|
+
synthesis: m.meta.status === "closed" ? m.sections.synthesis : null,
|
|
285
|
+
file_path: m.file_path,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
export { PLACEHOLDER };
|
|
289
|
+
//# sourceMappingURL=pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/palace/pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills — procedural memory layer (5th memory type).
|
|
3
|
+
*
|
|
4
|
+
* Closes the V10 (formal taxonomy) gap: AgentRecall today covers episodic
|
|
5
|
+
* (journal), semantic (palace/rooms + awareness), and narrative (pipeline)
|
|
6
|
+
* but has NO procedural store. Agents re-derive the same multi-step
|
|
7
|
+
* procedure every session — Cloudflare 4-step DNS+Proxy+OriginRule+SSL,
|
|
8
|
+
* git rm --cached for untracked file cleanup, OAuth refresh pre-check, etc.
|
|
9
|
+
*
|
|
10
|
+
* A Skill is a typed production rule:
|
|
11
|
+
* IF trigger matches AND preconditions hold THEN follow steps
|
|
12
|
+
*
|
|
13
|
+
* Storage: ~/.agent-recall/projects/<slug>/palace/skills/<NN>-<slug>.md
|
|
14
|
+
* (or global/procedural/<slug>.md for cross-project)
|
|
15
|
+
*
|
|
16
|
+
* Frontmatter shape conforms to naming.ts canonical schema for
|
|
17
|
+
* indexability + grep-friendly retrieval.
|
|
18
|
+
*/
|
|
19
|
+
import { type FsrsState } from "./fsrs.js";
|
|
20
|
+
export interface SkillMeta {
|
|
21
|
+
/** Stable kebab-case slug, unique within project. */
|
|
22
|
+
slug: string;
|
|
23
|
+
/** Short human-readable name. */
|
|
24
|
+
name: string;
|
|
25
|
+
/** Topic / category (e.g. "deploy", "git", "auth"). */
|
|
26
|
+
topic: string;
|
|
27
|
+
/** Keywords that match user intent — used for trigger lookup. */
|
|
28
|
+
triggers: string[];
|
|
29
|
+
/** Optional file-path globs that increase relevance. */
|
|
30
|
+
file_globs?: string[];
|
|
31
|
+
created: string;
|
|
32
|
+
updated: string;
|
|
33
|
+
/** Where this came from. */
|
|
34
|
+
source?: "manual" | "promoted_from_correction" | "promoted_from_pipeline" | "auto_reflection";
|
|
35
|
+
/** Embedded FSRS state for reinforcement-on-use. */
|
|
36
|
+
fsrs?: FsrsState;
|
|
37
|
+
}
|
|
38
|
+
export interface SkillBody {
|
|
39
|
+
/** When to use this skill (the IF). */
|
|
40
|
+
when: string;
|
|
41
|
+
/** Preconditions to check before applying (zero or more). */
|
|
42
|
+
preconditions: string[];
|
|
43
|
+
/** Ordered steps (the THEN). */
|
|
44
|
+
steps: string[];
|
|
45
|
+
/** What success looks like — falsifiable. */
|
|
46
|
+
postconditions: string[];
|
|
47
|
+
/** Failure modes / things that went wrong before. */
|
|
48
|
+
pitfalls?: string[];
|
|
49
|
+
/** Evidence refs — journal dates / commit SHAs / corrections that led to this. */
|
|
50
|
+
evidence?: string[];
|
|
51
|
+
}
|
|
52
|
+
export interface Skill {
|
|
53
|
+
meta: SkillMeta;
|
|
54
|
+
body: SkillBody;
|
|
55
|
+
file_path: string;
|
|
56
|
+
}
|
|
57
|
+
export declare function skillsDir(project: string): string;
|
|
58
|
+
export declare function parseSkillFile(filePath: string): Skill;
|
|
59
|
+
export declare function listSkills(project: string): Skill[];
|
|
60
|
+
export declare function nextSkillOrder(project: string): number;
|
|
61
|
+
export declare function writeSkill(project: string, meta: SkillMeta, body: SkillBody, order?: number): string;
|
|
62
|
+
/**
|
|
63
|
+
* Trigger-match: rank skills by overlap of intent keywords against the skill's
|
|
64
|
+
* declared `triggers` + topic + name. Returns top N. Pure scoring — no LLM call.
|
|
65
|
+
*/
|
|
66
|
+
export declare function recallSkillsByIntent(project: string, intent: string, limit?: number): Array<{
|
|
67
|
+
skill: Skill;
|
|
68
|
+
score: number;
|
|
69
|
+
matched_triggers: string[];
|
|
70
|
+
}>;
|
|
71
|
+
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/palace/skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,QAAQ,GAAG,0BAA0B,GAAG,wBAAwB,GAAG,iBAAiB,CAAC;IAC9F,oDAAoD;IACpD,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gCAAgC;IAChC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,6CAA6C;IAC7C,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjD;AAiDD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CA4BtD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,CAanD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQtD;AA2BD,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAuBpG;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,KAAK,SAAI,GACR,KAAK,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAiCpE"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills — procedural memory layer (5th memory type).
|
|
3
|
+
*
|
|
4
|
+
* Closes the V10 (formal taxonomy) gap: AgentRecall today covers episodic
|
|
5
|
+
* (journal), semantic (palace/rooms + awareness), and narrative (pipeline)
|
|
6
|
+
* but has NO procedural store. Agents re-derive the same multi-step
|
|
7
|
+
* procedure every session — Cloudflare 4-step DNS+Proxy+OriginRule+SSL,
|
|
8
|
+
* git rm --cached for untracked file cleanup, OAuth refresh pre-check, etc.
|
|
9
|
+
*
|
|
10
|
+
* A Skill is a typed production rule:
|
|
11
|
+
* IF trigger matches AND preconditions hold THEN follow steps
|
|
12
|
+
*
|
|
13
|
+
* Storage: ~/.agent-recall/projects/<slug>/palace/skills/<NN>-<slug>.md
|
|
14
|
+
* (or global/procedural/<slug>.md for cross-project)
|
|
15
|
+
*
|
|
16
|
+
* Frontmatter shape conforms to naming.ts canonical schema for
|
|
17
|
+
* indexability + grep-friendly retrieval.
|
|
18
|
+
*/
|
|
19
|
+
import * as fs from "node:fs";
|
|
20
|
+
import * as path from "node:path";
|
|
21
|
+
import { palaceDir, sanitizeSlug } from "../storage/paths.js";
|
|
22
|
+
import { ensureDir } from "../storage/fs-utils.js";
|
|
23
|
+
import { generateFrontmatter } from "./obsidian.js";
|
|
24
|
+
import { initFsrs } from "./fsrs.js";
|
|
25
|
+
const ORDER_PAD = 4;
|
|
26
|
+
export function skillsDir(project) {
|
|
27
|
+
return path.join(palaceDir(project), "skills");
|
|
28
|
+
}
|
|
29
|
+
function zeroPad(n, width = ORDER_PAD) {
|
|
30
|
+
return n.toString().padStart(width, "0");
|
|
31
|
+
}
|
|
32
|
+
function parseFrontmatter(raw) {
|
|
33
|
+
const match = raw.match(/^---\s*\r?\n([\s\S]*?)\r?\n---\s*\r?\n([\s\S]*)$/);
|
|
34
|
+
if (!match)
|
|
35
|
+
return { meta: {}, body: raw };
|
|
36
|
+
const meta = {};
|
|
37
|
+
for (const line of match[1].split(/\r?\n/)) {
|
|
38
|
+
const idx = line.indexOf(":");
|
|
39
|
+
if (idx < 0)
|
|
40
|
+
continue;
|
|
41
|
+
const key = line.slice(0, idx).trim();
|
|
42
|
+
const raw = line.slice(idx + 1).trim();
|
|
43
|
+
if (!key)
|
|
44
|
+
continue;
|
|
45
|
+
if (raw.startsWith("[") && raw.endsWith("]")) {
|
|
46
|
+
const inner = raw.slice(1, -1).trim();
|
|
47
|
+
meta[key] = inner ? inner.split(",").map((s) => s.trim().replace(/^"|"$/g, "")) : [];
|
|
48
|
+
}
|
|
49
|
+
else if (raw.startsWith("{") && raw.endsWith("}")) {
|
|
50
|
+
try {
|
|
51
|
+
meta[key] = JSON.parse(raw);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
meta[key] = raw;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else if (raw === "null" || raw === "") {
|
|
58
|
+
meta[key] = null;
|
|
59
|
+
}
|
|
60
|
+
else if (/^-?\d+(\.\d+)?$/.test(raw)) {
|
|
61
|
+
meta[key] = Number(raw);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
meta[key] = raw.replace(/^"|"$/g, "");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return { meta, body: match[2] };
|
|
68
|
+
}
|
|
69
|
+
function extractList(body, heading) {
|
|
70
|
+
const re = new RegExp(`^##\\s+${heading}\\s*\\r?\\n([\\s\\S]*?)(?=\\n##\\s+|\\s*$)`, "mi");
|
|
71
|
+
const m = body.match(re);
|
|
72
|
+
if (!m)
|
|
73
|
+
return [];
|
|
74
|
+
return m[1]
|
|
75
|
+
.split("\n")
|
|
76
|
+
.map((l) => l.trim())
|
|
77
|
+
.filter((l) => l.startsWith("- ") || l.startsWith("* "))
|
|
78
|
+
.map((l) => l.replace(/^[-*]\s+/, ""));
|
|
79
|
+
}
|
|
80
|
+
function extractParagraph(body, heading) {
|
|
81
|
+
const re = new RegExp(`^##\\s+${heading}\\s*\\r?\\n([\\s\\S]*?)(?=\\n##\\s+|\\s*$)`, "mi");
|
|
82
|
+
const m = body.match(re);
|
|
83
|
+
return m ? m[1].trim() : "";
|
|
84
|
+
}
|
|
85
|
+
export function parseSkillFile(filePath) {
|
|
86
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
87
|
+
const { meta: m, body } = parseFrontmatter(raw);
|
|
88
|
+
const meta = {
|
|
89
|
+
slug: String(m.slug ?? path.basename(filePath, ".md").split("-").slice(1).join("-")),
|
|
90
|
+
name: String(m.name ?? ""),
|
|
91
|
+
topic: String(m.topic ?? ""),
|
|
92
|
+
triggers: Array.isArray(m.triggers) ? m.triggers : [],
|
|
93
|
+
file_globs: Array.isArray(m.file_globs) ? m.file_globs : undefined,
|
|
94
|
+
created: String(m.created ?? ""),
|
|
95
|
+
updated: String(m.updated ?? ""),
|
|
96
|
+
source: m.source ?? "manual",
|
|
97
|
+
fsrs: m.fsrs && typeof m.fsrs === "object" ? m.fsrs : undefined,
|
|
98
|
+
};
|
|
99
|
+
return {
|
|
100
|
+
meta,
|
|
101
|
+
body: {
|
|
102
|
+
when: extractParagraph(body, "When"),
|
|
103
|
+
preconditions: extractList(body, "Preconditions"),
|
|
104
|
+
steps: extractList(body, "Steps"),
|
|
105
|
+
postconditions: extractList(body, "Postconditions"),
|
|
106
|
+
pitfalls: extractList(body, "Pitfalls"),
|
|
107
|
+
evidence: extractList(body, "Evidence"),
|
|
108
|
+
},
|
|
109
|
+
file_path: filePath,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
export function listSkills(project) {
|
|
113
|
+
const dir = skillsDir(project);
|
|
114
|
+
if (!fs.existsSync(dir))
|
|
115
|
+
return [];
|
|
116
|
+
const files = fs.readdirSync(dir).filter((f) => f.endsWith(".md") && /^\d+-/.test(f));
|
|
117
|
+
const skills = [];
|
|
118
|
+
for (const f of files) {
|
|
119
|
+
try {
|
|
120
|
+
skills.push(parseSkillFile(path.join(dir, f)));
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// skip unreadable
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return skills.sort((a, b) => a.meta.slug.localeCompare(b.meta.slug));
|
|
127
|
+
}
|
|
128
|
+
export function nextSkillOrder(project) {
|
|
129
|
+
const dir = skillsDir(project);
|
|
130
|
+
if (!fs.existsSync(dir))
|
|
131
|
+
return 1;
|
|
132
|
+
const orders = fs
|
|
133
|
+
.readdirSync(dir)
|
|
134
|
+
.filter((f) => /^\d+-/.test(f))
|
|
135
|
+
.map((f) => parseInt(f.split("-")[0], 10) || 0);
|
|
136
|
+
return orders.length === 0 ? 1 : Math.max(...orders) + 1;
|
|
137
|
+
}
|
|
138
|
+
function renderSkill(meta, body) {
|
|
139
|
+
const fm = generateFrontmatter({
|
|
140
|
+
slug: meta.slug,
|
|
141
|
+
name: meta.name,
|
|
142
|
+
topic: meta.topic,
|
|
143
|
+
triggers: meta.triggers,
|
|
144
|
+
file_globs: meta.file_globs ?? [],
|
|
145
|
+
created: meta.created,
|
|
146
|
+
updated: meta.updated,
|
|
147
|
+
source: meta.source ?? "manual",
|
|
148
|
+
fsrs: meta.fsrs ?? null,
|
|
149
|
+
});
|
|
150
|
+
const renderList = (xs) => xs.length ? xs.map((x) => `- ${x}`).join("\n") : "- _(none)_";
|
|
151
|
+
return (fm +
|
|
152
|
+
`# ${meta.name}\n\n` +
|
|
153
|
+
`## When\n${body.when || "_(describe the trigger condition)_"}\n\n` +
|
|
154
|
+
`## Preconditions\n${renderList(body.preconditions)}\n\n` +
|
|
155
|
+
`## Steps\n${renderList(body.steps)}\n\n` +
|
|
156
|
+
`## Postconditions\n${renderList(body.postconditions)}\n\n` +
|
|
157
|
+
(body.pitfalls && body.pitfalls.length > 0 ? `## Pitfalls\n${renderList(body.pitfalls)}\n\n` : "") +
|
|
158
|
+
(body.evidence && body.evidence.length > 0 ? `## Evidence\n${renderList(body.evidence)}\n` : ""));
|
|
159
|
+
}
|
|
160
|
+
export function writeSkill(project, meta, body, order) {
|
|
161
|
+
const dir = skillsDir(project);
|
|
162
|
+
ensureDir(dir);
|
|
163
|
+
const finalMeta = {
|
|
164
|
+
...meta,
|
|
165
|
+
slug: sanitizeSlug(meta.slug || meta.name),
|
|
166
|
+
fsrs: meta.fsrs ?? initFsrs(meta.created || new Date().toISOString()),
|
|
167
|
+
};
|
|
168
|
+
const ord = order ?? nextSkillOrder(project);
|
|
169
|
+
const filename = `${zeroPad(ord)}-${finalMeta.slug}.md`;
|
|
170
|
+
const filePath = path.join(dir, filename);
|
|
171
|
+
// Symlink guard
|
|
172
|
+
try {
|
|
173
|
+
const lst = fs.lstatSync(filePath);
|
|
174
|
+
if (lst.isSymbolicLink())
|
|
175
|
+
throw new Error(`Refusing to write symlinked skill file: ${filePath}`);
|
|
176
|
+
}
|
|
177
|
+
catch (e) {
|
|
178
|
+
if (e.code !== "ENOENT")
|
|
179
|
+
throw e;
|
|
180
|
+
}
|
|
181
|
+
// Atomic write
|
|
182
|
+
const tmp = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
183
|
+
fs.writeFileSync(tmp, renderSkill(finalMeta, body), { encoding: "utf-8", mode: 0o600 });
|
|
184
|
+
fs.renameSync(tmp, filePath);
|
|
185
|
+
return filePath;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Trigger-match: rank skills by overlap of intent keywords against the skill's
|
|
189
|
+
* declared `triggers` + topic + name. Returns top N. Pure scoring — no LLM call.
|
|
190
|
+
*/
|
|
191
|
+
export function recallSkillsByIntent(project, intent, limit = 5) {
|
|
192
|
+
const skills = listSkills(project);
|
|
193
|
+
if (skills.length === 0)
|
|
194
|
+
return [];
|
|
195
|
+
const intentWords = new Set(intent
|
|
196
|
+
.toLowerCase()
|
|
197
|
+
.normalize("NFKD")
|
|
198
|
+
.replace(/[^a-z0-9 ]+/g, " ")
|
|
199
|
+
.split(/\s+/)
|
|
200
|
+
.filter((w) => w.length >= 3));
|
|
201
|
+
const ranked = skills
|
|
202
|
+
.map((s) => {
|
|
203
|
+
const haystack = [s.meta.name, s.meta.topic, ...s.meta.triggers].join(" ").toLowerCase();
|
|
204
|
+
const haystackWords = new Set(haystack.split(/[^a-z0-9]+/).filter((w) => w.length >= 3));
|
|
205
|
+
const matched = [];
|
|
206
|
+
let score = 0;
|
|
207
|
+
for (const w of intentWords) {
|
|
208
|
+
if (haystackWords.has(w)) {
|
|
209
|
+
matched.push(w);
|
|
210
|
+
score += 1;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Boost: explicit trigger keyword matches count double
|
|
214
|
+
for (const t of s.meta.triggers) {
|
|
215
|
+
if (intent.toLowerCase().includes(t.toLowerCase()))
|
|
216
|
+
score += 1;
|
|
217
|
+
}
|
|
218
|
+
return { skill: s, score, matched_triggers: matched };
|
|
219
|
+
})
|
|
220
|
+
.filter((x) => x.score > 0)
|
|
221
|
+
.sort((a, b) => b.score - a.score)
|
|
222
|
+
.slice(0, limit);
|
|
223
|
+
return ranked;
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/palace/skills.ts"],"names":[],"mappings":"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"}
|