myagentmemory 0.4.7 → 0.4.10
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 +32 -7
- package/dist/agent-memory +0 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +151 -12
- package/dist/core.d.ts +77 -2
- package/dist/core.js +502 -4
- package/package.json +1 -1
- package/scripts/install-skills.ps1 +5 -2
- package/scripts/install-skills.sh +54 -11
- package/skills/agent/SKILL.md +39 -14
- package/skills/claude-code/SKILL.md +39 -14
- package/skills/codex/SKILL.md +39 -14
- package/skills/cursor/SKILL.md +39 -14
- package/src/cli.ts +167 -14
- package/src/core.ts +605 -6
package/README.md
CHANGED
|
@@ -4,11 +4,15 @@ Persistent memory for coding agents — [Claude Code](https://claude.ai/code), [
|
|
|
4
4
|
|
|
5
5
|
Thanks to https://github.com/skyfallsin/pi-mem for inspiration.
|
|
6
6
|
|
|
7
|
-
Long-term facts, daily logs, and a scratchpad checklist stored as plain markdown files. Optional qmd integration adds keyword, semantic, and hybrid search across all memory files, plus automatic selective injection of relevant past memories into every turn.
|
|
7
|
+
Long-term facts, daily logs, topic/event notes, and a scratchpad checklist stored as plain markdown files. Optional qmd integration adds keyword, semantic, and hybrid search across all memory files, plus automatic selective injection of relevant past memories into every turn.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
+
# Homebrew (macOS)
|
|
13
|
+
brew tap jayzeng/agentmemory
|
|
14
|
+
brew install agent-memory
|
|
15
|
+
|
|
12
16
|
# Install the CLI globally
|
|
13
17
|
npm install -g myagentmemory
|
|
14
18
|
|
|
@@ -24,8 +28,15 @@ agent-memory init
|
|
|
24
28
|
|
|
25
29
|
# Install skill files for Claude Code, Codex, Cursor, and Agent
|
|
26
30
|
agent-memory install-skills
|
|
31
|
+
|
|
32
|
+
# Uninstall skill files
|
|
33
|
+
agent-memory uninstall-skills
|
|
27
34
|
```
|
|
28
35
|
|
|
36
|
+
### Pi users
|
|
37
|
+
|
|
38
|
+
If you're on Pi and prefer a native extension, use `pi-memory` (https://github.com/jayzeng/pi-memory) instead of installing this skill. The CLI + skill workflow here is the cross-platform alternative, and works fine on Pi without any extension.
|
|
39
|
+
|
|
29
40
|
This installs:
|
|
30
41
|
- `~/.claude/skills/agent-memory/SKILL.md` — Claude Code skill
|
|
31
42
|
- `~/.codex/skills/agent-memory/SKILL.md` — Codex skill
|
|
@@ -79,11 +90,12 @@ The memory directory defaults to `~/.agent-memory/`. Override with `AGENT_MEMORY
|
|
|
79
90
|
| Command | Purpose |
|
|
80
91
|
|---------|---------|
|
|
81
92
|
| `agent-memory context [--no-search]` | Build & print context injection string to stdout |
|
|
82
|
-
| `agent-memory write --target <long_term\|daily> --content <text> [--mode append\|overwrite]` | Write to memory files |
|
|
83
|
-
| `agent-memory read --target <long_term\|scratchpad\|daily\|list> [--date YYYY-MM-DD]` | Read memory files |
|
|
93
|
+
| `agent-memory write --target <long_term\|daily\|topic> --content <text> [--mode append\|overwrite] [--topic <name>] [--date YYYY-MM-DD]` | Write to memory files |
|
|
94
|
+
| `agent-memory read --target <long_term\|scratchpad\|daily\|list\|topic\|topics> [--date YYYY-MM-DD] [--topic <name>]` | Read memory files |
|
|
84
95
|
| `agent-memory scratchpad <add\|done\|undo\|clear_done\|list> [--text <text>]` | Manage checklist |
|
|
85
96
|
| `agent-memory search --query <text> [--mode keyword\|semantic\|deep] [--limit N]` | Search via qmd |
|
|
86
97
|
| `agent-memory install-skills` | Install bundled SKILL.md files into local agent directories |
|
|
98
|
+
| `agent-memory uninstall-skills` | Uninstall bundled SKILL.md files from local agent directories |
|
|
87
99
|
| `agent-memory init` | Create dirs, detect qmd, setup collection |
|
|
88
100
|
| `agent-memory status` | Show config, qmd status, file counts |
|
|
89
101
|
|
|
@@ -109,6 +121,18 @@ If the first search doesn't find what you need, try rephrasing or switching mode
|
|
|
109
121
|
2026-02-15.md # Daily append-only log
|
|
110
122
|
2026-02-14.md
|
|
111
123
|
...
|
|
124
|
+
topics/
|
|
125
|
+
auth.md # Topic/event log linked back to daily entries
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Topic notes
|
|
129
|
+
|
|
130
|
+
Topic files are for event- or theme-based tracking across days. Each topic entry includes a `Daily: [[YYYY-MM-DD]]` backlink so you can jump from the topic to the full daily log.
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
agent-memory write --target topic --topic "auth" --content "JWT refresh rolled out to edge #auth"
|
|
134
|
+
agent-memory read --target topic --topic "auth"
|
|
135
|
+
agent-memory read --target topics
|
|
112
136
|
```
|
|
113
137
|
|
|
114
138
|
## How it works
|
|
@@ -118,10 +142,11 @@ If the first search doesn't find what you need, try rephrasing or switching mode
|
|
|
118
142
|
Before every agent turn, the following are injected into the system prompt (in priority order):
|
|
119
143
|
|
|
120
144
|
1. **Open scratchpad items** (up to 2K chars)
|
|
121
|
-
2. **
|
|
122
|
-
3. **
|
|
123
|
-
4. **
|
|
124
|
-
5. **
|
|
145
|
+
2. **Recent topic entries** (up to 2K chars) — most recent topic notes with backlinks
|
|
146
|
+
3. **Today's daily log** (up to 3K chars, tail)
|
|
147
|
+
4. **Relevant memories via qmd search** (up to 2.5K chars) — searches using the user's current prompt to surface related past context
|
|
148
|
+
5. **MEMORY.md** (up to 4K chars, middle-truncated)
|
|
149
|
+
6. **Yesterday's daily log** (up to 3K chars, tail — lowest priority, trimmed first)
|
|
125
150
|
|
|
126
151
|
Total injection is capped at 16K chars. When qmd is unavailable, step 3 is skipped and the rest works as before.
|
|
127
152
|
|
package/dist/agent-memory
CHANGED
|
Binary file
|
package/dist/cli.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Subcommands:
|
|
6
6
|
* version — Print binary version
|
|
7
|
-
* install-skills — Install SKILL.md files into local agent directories
|
|
7
|
+
* install-skills — Install (or --uninstall) SKILL.md files into local agent directories
|
|
8
8
|
* context — Build & print context injection string to stdout
|
|
9
9
|
* write — Write to memory files
|
|
10
10
|
* read — Read memory files
|
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Subcommands:
|
|
6
6
|
* version — Print binary version
|
|
7
|
-
* install-skills — Install SKILL.md files into local agent directories
|
|
7
|
+
* install-skills — Install (or --uninstall) SKILL.md files into local agent directories
|
|
8
8
|
* context — Build & print context injection string to stdout
|
|
9
9
|
* write — Write to memory files
|
|
10
10
|
* read — Read memory files
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
* --json Machine-readable JSON output
|
|
19
19
|
*/
|
|
20
20
|
import * as fs from "node:fs";
|
|
21
|
+
import { _setBaseDir, buildMemoryContext, checkCollection, dailyPath, detectQmd, distilMemories, ensureDirs, ensureQmdAvailableForSync, ensureQmdAvailableForUpdate, getCollectionName, getDailyDir, getMemoryDir, getMemoryFile, getQmdEmbedMode, getQmdHealth, getQmdResultPath, getQmdResultText, getScratchpadFile, getTopicsDir, installSkills, nowTimestamp, parseScratchpad, readFileSafe, runQmdEmbedDetached, runQmdSearch, runQmdSync, runQmdUpdateNow, scheduleQmdUpdate, searchRelevantMemories, serializeScratchpad, setupQmdCollection, slugifyTopic, todayStr, topicPath, uninstallSkills, } from "./core.js";
|
|
21
22
|
const VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : "dev";
|
|
22
|
-
import { _setBaseDir, buildMemoryContext, checkCollection, dailyPath, detectQmd, ensureDirs, ensureQmdAvailableForSync, ensureQmdAvailableForUpdate, getCollectionName, getDailyDir, getMemoryDir, getMemoryFile, getQmdEmbedMode, getQmdHealth, getQmdResultPath, getQmdResultText, getScratchpadFile, installSkills, nowTimestamp, parseScratchpad, readFileSafe, runQmdEmbedDetached, runQmdSearch, runQmdSync, runQmdUpdateNow, scheduleQmdUpdate, searchRelevantMemories, serializeScratchpad, setupQmdCollection, todayStr, } from "./core.js";
|
|
23
23
|
function parseArgs(argv) {
|
|
24
24
|
const flags = {};
|
|
25
25
|
const positional = [];
|
|
@@ -97,11 +97,13 @@ async function cmdContext(flags) {
|
|
|
97
97
|
}
|
|
98
98
|
async function cmdWrite(flags) {
|
|
99
99
|
const json = hasFlag(flags, "json");
|
|
100
|
-
const target = getFlag(flags, "target");
|
|
100
|
+
const target = getFlag(flags, "target") ?? "daily";
|
|
101
101
|
const content = getFlag(flags, "content");
|
|
102
102
|
const mode = getFlag(flags, "mode") ?? "append";
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
const topic = getFlag(flags, "topic");
|
|
104
|
+
const date = getFlag(flags, "date");
|
|
105
|
+
if (!["long_term", "daily", "topic"].includes(target)) {
|
|
106
|
+
exitError("--target must be 'long_term', 'daily', or 'topic' (default: daily)", json);
|
|
105
107
|
}
|
|
106
108
|
if (!content) {
|
|
107
109
|
exitError("--content is required", json);
|
|
@@ -122,6 +124,29 @@ async function cmdWrite(flags) {
|
|
|
122
124
|
: `Appended to daily log: ${filePath}`, json);
|
|
123
125
|
return;
|
|
124
126
|
}
|
|
127
|
+
if (target === "topic") {
|
|
128
|
+
if (!topic) {
|
|
129
|
+
exitError("--topic is required when --target is 'topic'", json);
|
|
130
|
+
}
|
|
131
|
+
const slug = slugifyTopic(topic);
|
|
132
|
+
if (!slug) {
|
|
133
|
+
exitError("--topic must include at least one letter or number", json);
|
|
134
|
+
}
|
|
135
|
+
const filePath = topicPath(slug);
|
|
136
|
+
const existing = readFileSafe(filePath) ?? "";
|
|
137
|
+
const linkDate = date?.trim() || todayStr();
|
|
138
|
+
const header = `# Topic: ${topic}\n\n<!-- created: ${ts} [${sid}] -->\n`;
|
|
139
|
+
const separator = existing.trim() ? "\n\n" : "";
|
|
140
|
+
const base = existing.trim() ? existing : header.trimEnd();
|
|
141
|
+
const stamped = `<!-- ${ts} [${sid}] -->\n${content.trim()}\nDaily: [[${linkDate}]]`;
|
|
142
|
+
fs.writeFileSync(filePath, `${base}${separator}${stamped}`, "utf-8");
|
|
143
|
+
await ensureQmdAvailableForUpdate();
|
|
144
|
+
scheduleQmdUpdate();
|
|
145
|
+
output(json
|
|
146
|
+
? { ok: true, path: filePath, target, mode: "append", timestamp: ts, topic, slug, date: linkDate }
|
|
147
|
+
: `Appended to topic: ${filePath}`, json);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
125
150
|
// long_term
|
|
126
151
|
const memFile = getMemoryFile();
|
|
127
152
|
const existing = readFileSafe(memFile) ?? "";
|
|
@@ -144,8 +169,9 @@ async function cmdRead(flags) {
|
|
|
144
169
|
const json = hasFlag(flags, "json");
|
|
145
170
|
const target = getFlag(flags, "target");
|
|
146
171
|
const date = getFlag(flags, "date");
|
|
147
|
-
|
|
148
|
-
|
|
172
|
+
const topic = getFlag(flags, "topic");
|
|
173
|
+
if (!target || !["long_term", "scratchpad", "daily", "list", "topic", "topics"].includes(target)) {
|
|
174
|
+
exitError("--target must be 'long_term', 'scratchpad', 'daily', 'list', 'topic', or 'topics'", json);
|
|
149
175
|
}
|
|
150
176
|
ensureDirs();
|
|
151
177
|
if (target === "list") {
|
|
@@ -181,6 +207,42 @@ async function cmdRead(flags) {
|
|
|
181
207
|
output(json ? { content, date: d, path: filePath } : content, json);
|
|
182
208
|
return;
|
|
183
209
|
}
|
|
210
|
+
if (target === "topics") {
|
|
211
|
+
try {
|
|
212
|
+
const files = fs
|
|
213
|
+
.readdirSync(getTopicsDir())
|
|
214
|
+
.filter((f) => f.endsWith(".md"))
|
|
215
|
+
.sort()
|
|
216
|
+
.reverse();
|
|
217
|
+
if (json) {
|
|
218
|
+
output({ files }, true);
|
|
219
|
+
}
|
|
220
|
+
else if (files.length === 0) {
|
|
221
|
+
console.log("No topics found.");
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
console.log(`Topics:\n${files.map((f) => `- ${f}`).join("\n")}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
output(json ? { files: [] } : "No topics directory.", json);
|
|
229
|
+
}
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (target === "topic") {
|
|
233
|
+
if (!topic) {
|
|
234
|
+
exitError("--topic is required when --target is 'topic'", json);
|
|
235
|
+
}
|
|
236
|
+
const slug = slugifyTopic(topic);
|
|
237
|
+
const filePath = topicPath(slug);
|
|
238
|
+
const content = readFileSafe(filePath);
|
|
239
|
+
if (!content) {
|
|
240
|
+
output(json ? { content: null, topic } : `No topic file found for ${topic}.`, json);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
output(json ? { content, topic, slug, path: filePath } : content, json);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
184
246
|
if (target === "scratchpad") {
|
|
185
247
|
const content = readFileSafe(getScratchpadFile());
|
|
186
248
|
if (!content?.trim()) {
|
|
@@ -324,6 +386,27 @@ async function cmdSearch(flags) {
|
|
|
324
386
|
}
|
|
325
387
|
function cmdInstallSkills(flags) {
|
|
326
388
|
const json = hasFlag(flags, "json");
|
|
389
|
+
const uninstall = hasFlag(flags, "uninstall");
|
|
390
|
+
if (uninstall) {
|
|
391
|
+
const report = uninstallSkills();
|
|
392
|
+
if (!report.ok) {
|
|
393
|
+
exitError(report.error ?? "Failed to uninstall skills.", json);
|
|
394
|
+
}
|
|
395
|
+
if (json) {
|
|
396
|
+
output(report, true);
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
for (const item of report.removed) {
|
|
400
|
+
console.log(`Uninstalled ${item.label}: ${item.path}`);
|
|
401
|
+
}
|
|
402
|
+
for (const item of report.skipped) {
|
|
403
|
+
console.log(`Skipping ${item.label} (${item.reason})`);
|
|
404
|
+
}
|
|
405
|
+
if (report.removed.length === 0) {
|
|
406
|
+
console.log("No skills were installed.");
|
|
407
|
+
}
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
327
410
|
const report = installSkills();
|
|
328
411
|
if (!report.ok) {
|
|
329
412
|
exitError(report.error ?? "Failed to install skills.", json);
|
|
@@ -332,7 +415,17 @@ function cmdInstallSkills(flags) {
|
|
|
332
415
|
output(report, true);
|
|
333
416
|
return;
|
|
334
417
|
}
|
|
335
|
-
if (report.
|
|
418
|
+
if (report.checked.length > 0) {
|
|
419
|
+
for (const item of report.checked) {
|
|
420
|
+
if (item.status === "detected") {
|
|
421
|
+
console.log(`Detecting ${item.label}... found`);
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
console.log(`Detecting ${item.label}... not found (${item.reason ?? "unknown"})`);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
else if (report.detected.length === 0) {
|
|
336
429
|
console.log("No supported agent installations detected.");
|
|
337
430
|
}
|
|
338
431
|
else {
|
|
@@ -420,7 +513,7 @@ async function cmdInit(flags) {
|
|
|
420
513
|
}
|
|
421
514
|
else {
|
|
422
515
|
console.log(`Memory directory: ${dir}`);
|
|
423
|
-
console.log(` MEMORY.md, SCRATCHPAD.md, daily/ created.`);
|
|
516
|
+
console.log(` MEMORY.md, SCRATCHPAD.md, daily/, topics/ created.`);
|
|
424
517
|
if (qmdFound) {
|
|
425
518
|
if (collectionCreated) {
|
|
426
519
|
console.log(` qmd collection '${getCollectionName()}' created.`);
|
|
@@ -448,6 +541,7 @@ async function cmdStatus(flags) {
|
|
|
448
541
|
const memFile = getMemoryFile();
|
|
449
542
|
const spFile = getScratchpadFile();
|
|
450
543
|
const dailyDir = getDailyDir();
|
|
544
|
+
const topicsDir = getTopicsDir();
|
|
451
545
|
const memContent = readFileSafe(memFile);
|
|
452
546
|
const spContent = readFileSafe(spFile);
|
|
453
547
|
let dailyCount = 0;
|
|
@@ -457,6 +551,13 @@ async function cmdStatus(flags) {
|
|
|
457
551
|
catch {
|
|
458
552
|
// directory may not exist
|
|
459
553
|
}
|
|
554
|
+
let topicCount = 0;
|
|
555
|
+
try {
|
|
556
|
+
topicCount = fs.readdirSync(topicsDir).filter((f) => f.endsWith(".md")).length;
|
|
557
|
+
}
|
|
558
|
+
catch {
|
|
559
|
+
// directory may not exist
|
|
560
|
+
}
|
|
460
561
|
const qmdFound = await detectQmd();
|
|
461
562
|
let hasCollection = false;
|
|
462
563
|
let health = null;
|
|
@@ -482,6 +583,7 @@ async function cmdStatus(flags) {
|
|
|
482
583
|
openItems: spContent ? parseScratchpad(spContent).filter((i) => !i.done).length : 0,
|
|
483
584
|
},
|
|
484
585
|
dailyLogs: dailyCount,
|
|
586
|
+
topics: topicCount,
|
|
485
587
|
qmd: {
|
|
486
588
|
available: qmdFound,
|
|
487
589
|
collection: hasCollection ? getCollectionName() : null,
|
|
@@ -509,6 +611,7 @@ async function cmdStatus(flags) {
|
|
|
509
611
|
console.log("SCRATCHPAD.md: not created yet");
|
|
510
612
|
}
|
|
511
613
|
console.log(`Daily logs: ${dailyCount} file(s)`);
|
|
614
|
+
console.log(`Topics: ${topicCount} file(s)`);
|
|
512
615
|
console.log("");
|
|
513
616
|
if (qmdFound) {
|
|
514
617
|
console.log(`qmd: available`);
|
|
@@ -532,6 +635,29 @@ async function cmdStatus(flags) {
|
|
|
532
635
|
}
|
|
533
636
|
}
|
|
534
637
|
}
|
|
638
|
+
async function cmdDistil(flags) {
|
|
639
|
+
const json = hasFlag(flags, "json");
|
|
640
|
+
const dryRun = hasFlag(flags, "dry-run");
|
|
641
|
+
const result = await distilMemories({ dryRun });
|
|
642
|
+
if (json) {
|
|
643
|
+
output(result, true);
|
|
644
|
+
}
|
|
645
|
+
else {
|
|
646
|
+
if (result.totalEntries === 0) {
|
|
647
|
+
console.log(result.output.trim());
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
if (dryRun) {
|
|
651
|
+
console.log("--- Dry run (MEMORY.md not modified) ---\n");
|
|
652
|
+
}
|
|
653
|
+
console.log(result.output.trim());
|
|
654
|
+
console.log("");
|
|
655
|
+
console.log(`Distilled ${result.totalEntries} entries from ${result.totalDailyFiles} daily file(s) and ${result.totalTopicFiles} topic file(s), ${result.totalTags} tag(s).`);
|
|
656
|
+
if (!dryRun) {
|
|
657
|
+
console.log("MEMORY.md updated.");
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
535
661
|
// ---------------------------------------------------------------------------
|
|
536
662
|
// Usage
|
|
537
663
|
// ---------------------------------------------------------------------------
|
|
@@ -543,12 +669,14 @@ Usage:
|
|
|
543
669
|
|
|
544
670
|
Commands:
|
|
545
671
|
version Show binary version
|
|
546
|
-
install-skills Install bundled skills
|
|
672
|
+
install-skills Install (or --uninstall) bundled skills
|
|
673
|
+
uninstall-skills Uninstall bundled skills
|
|
547
674
|
context Build & print context injection string
|
|
548
|
-
write Write to memory files
|
|
675
|
+
write Write to memory files (default: daily)
|
|
549
676
|
read Read memory files
|
|
550
677
|
scratchpad Manage checklist items
|
|
551
678
|
search Search across memory files (requires qmd)
|
|
679
|
+
distil Generate compact MEMORY.md index from daily logs + topics
|
|
552
680
|
sync Re-index and embed all files (requires qmd)
|
|
553
681
|
init Initialize memory directory and qmd collection
|
|
554
682
|
status Show configuration and status
|
|
@@ -559,15 +687,19 @@ Global flags:
|
|
|
559
687
|
|
|
560
688
|
Examples:
|
|
561
689
|
agent-memory init
|
|
690
|
+
agent-memory write --content "Fixed auth bug in login flow"
|
|
562
691
|
agent-memory write --target long_term --content "User prefers dark mode"
|
|
563
|
-
agent-memory write --target
|
|
692
|
+
agent-memory write --target topic --topic "auth" --content "Rolled JWT refresh to edge"
|
|
564
693
|
agent-memory read --target long_term
|
|
565
694
|
agent-memory read --target daily --date 2026-02-15
|
|
566
695
|
agent-memory read --target list
|
|
696
|
+
agent-memory read --target topic --topic "auth"
|
|
697
|
+
agent-memory read --target topics
|
|
567
698
|
agent-memory scratchpad add --text "Review PR #42"
|
|
568
699
|
agent-memory scratchpad list
|
|
569
700
|
agent-memory scratchpad done --text "PR #42"
|
|
570
701
|
agent-memory search --query "database choice" --mode keyword
|
|
702
|
+
agent-memory distil --dry-run
|
|
571
703
|
agent-memory context --no-search
|
|
572
704
|
agent-memory sync
|
|
573
705
|
agent-memory status --json`);
|
|
@@ -610,6 +742,13 @@ async function main() {
|
|
|
610
742
|
case "install-skills":
|
|
611
743
|
cmdInstallSkills(flags);
|
|
612
744
|
break;
|
|
745
|
+
case "uninstall-skills":
|
|
746
|
+
cmdInstallSkills({ ...flags, uninstall: true });
|
|
747
|
+
break;
|
|
748
|
+
case "distil":
|
|
749
|
+
case "distill":
|
|
750
|
+
await cmdDistil(flags);
|
|
751
|
+
break;
|
|
613
752
|
case "sync":
|
|
614
753
|
await cmdSync(flags);
|
|
615
754
|
break;
|
package/dist/core.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ export declare function getMemoryFile(): string;
|
|
|
18
18
|
export declare function getScratchpadFile(): string;
|
|
19
19
|
/** Get the current daily log directory path. */
|
|
20
20
|
export declare function getDailyDir(): string;
|
|
21
|
+
/** Get the current topics directory path. */
|
|
22
|
+
export declare function getTopicsDir(): string;
|
|
21
23
|
export declare function ensureDirs(): void;
|
|
22
24
|
export declare function todayStr(): string;
|
|
23
25
|
export declare function yesterdayStr(): string;
|
|
@@ -25,6 +27,8 @@ export declare function nowTimestamp(): string;
|
|
|
25
27
|
export declare function shortSessionId(sessionId: string): string;
|
|
26
28
|
export declare function readFileSafe(filePath: string): string | null;
|
|
27
29
|
export declare function dailyPath(date: string): string;
|
|
30
|
+
export declare function topicPath(slug: string): string;
|
|
31
|
+
export declare function slugifyTopic(name: string): string;
|
|
28
32
|
export declare const RESPONSE_PREVIEW_MAX_CHARS = 4000;
|
|
29
33
|
export declare const RESPONSE_PREVIEW_MAX_LINES = 120;
|
|
30
34
|
export type TruncateMode = "start" | "end" | "middle";
|
|
@@ -112,6 +116,11 @@ export interface InstallSkillsReport {
|
|
|
112
116
|
ok: boolean;
|
|
113
117
|
projectDir?: string;
|
|
114
118
|
homeDir?: string;
|
|
119
|
+
checked: Array<{
|
|
120
|
+
label: string;
|
|
121
|
+
status: "detected" | "skipped";
|
|
122
|
+
reason?: string;
|
|
123
|
+
}>;
|
|
115
124
|
detected: Array<{
|
|
116
125
|
label: string;
|
|
117
126
|
homeMarker: string;
|
|
@@ -127,6 +136,20 @@ export interface InstallSkillsReport {
|
|
|
127
136
|
error?: string;
|
|
128
137
|
}
|
|
129
138
|
export declare function installSkills(): InstallSkillsReport;
|
|
139
|
+
export interface UninstallSkillsReport {
|
|
140
|
+
ok: boolean;
|
|
141
|
+
homeDir?: string;
|
|
142
|
+
removed: Array<{
|
|
143
|
+
label: string;
|
|
144
|
+
path: string;
|
|
145
|
+
}>;
|
|
146
|
+
skipped: Array<{
|
|
147
|
+
label: string;
|
|
148
|
+
reason: string;
|
|
149
|
+
}>;
|
|
150
|
+
error?: string;
|
|
151
|
+
}
|
|
152
|
+
export declare function uninstallSkills(): UninstallSkillsReport;
|
|
130
153
|
export interface QmdHealthInfo {
|
|
131
154
|
totalFiles: number | null;
|
|
132
155
|
vectorsEmbedded: number | null;
|
|
@@ -162,10 +185,12 @@ export interface ToolResult {
|
|
|
162
185
|
isError?: boolean;
|
|
163
186
|
}
|
|
164
187
|
export declare function memoryWrite(params: {
|
|
165
|
-
target
|
|
188
|
+
target?: "long_term" | "daily" | "topic";
|
|
166
189
|
content: string;
|
|
167
190
|
mode?: "append" | "overwrite";
|
|
168
191
|
sessionId?: string;
|
|
192
|
+
topic?: string;
|
|
193
|
+
date?: string;
|
|
169
194
|
}): Promise<ToolResult>;
|
|
170
195
|
export declare function scratchpadAction(params: {
|
|
171
196
|
action: "add" | "done" | "undo" | "clear_done" | "list";
|
|
@@ -173,12 +198,62 @@ export declare function scratchpadAction(params: {
|
|
|
173
198
|
sessionId?: string;
|
|
174
199
|
}): Promise<ToolResult>;
|
|
175
200
|
export declare function memoryRead(params: {
|
|
176
|
-
target: "long_term" | "scratchpad" | "daily" | "list";
|
|
201
|
+
target: "long_term" | "scratchpad" | "daily" | "list" | "topic" | "topics";
|
|
177
202
|
date?: string;
|
|
203
|
+
topic?: string;
|
|
178
204
|
}): Promise<ToolResult>;
|
|
179
205
|
export declare function memorySearch(params: {
|
|
180
206
|
query: string;
|
|
181
207
|
mode?: "keyword" | "semantic" | "deep";
|
|
182
208
|
limit?: number;
|
|
183
209
|
}): Promise<ToolResult>;
|
|
210
|
+
/** Extract #tag patterns, deduplicated and lowercased. */
|
|
211
|
+
export declare function extractTags(content: string): string[];
|
|
212
|
+
/** Extract [[link]] patterns. */
|
|
213
|
+
export declare function extractLinks(content: string): string[];
|
|
214
|
+
/** Extract file-path-like patterns (e.g. src/foo.ts), filtering out URLs. */
|
|
215
|
+
export declare function extractFilePaths(content: string): string[];
|
|
216
|
+
/** Extract backtick-quoted commands. */
|
|
217
|
+
export declare function extractCommands(content: string): string[];
|
|
218
|
+
export interface DailyEntry {
|
|
219
|
+
date: string;
|
|
220
|
+
timestamp: string;
|
|
221
|
+
sessionId: string;
|
|
222
|
+
content: string;
|
|
223
|
+
tags: string[];
|
|
224
|
+
links: string[];
|
|
225
|
+
filePaths: string[];
|
|
226
|
+
commands: string[];
|
|
227
|
+
}
|
|
228
|
+
/** Split a daily file on <!-- timestamp --> markers into individual entries. */
|
|
229
|
+
export declare function parseDailyEntries(date: string, content: string): DailyEntry[];
|
|
230
|
+
export interface TopicEntry {
|
|
231
|
+
topic: string;
|
|
232
|
+
slug: string;
|
|
233
|
+
date: string;
|
|
234
|
+
timestamp: string;
|
|
235
|
+
sessionId: string;
|
|
236
|
+
content: string;
|
|
237
|
+
tags: string[];
|
|
238
|
+
links: string[];
|
|
239
|
+
filePaths: string[];
|
|
240
|
+
commands: string[];
|
|
241
|
+
}
|
|
242
|
+
/** Split a topic file on <!-- timestamp --> markers into entries. */
|
|
243
|
+
export declare function parseTopicEntries(topic: string, slug: string, content: string): TopicEntry[];
|
|
244
|
+
export interface DistilResult {
|
|
245
|
+
ok: boolean;
|
|
246
|
+
dryRun: boolean;
|
|
247
|
+
totalDailyFiles: number;
|
|
248
|
+
totalTopicFiles: number;
|
|
249
|
+
totalEntries: number;
|
|
250
|
+
totalTopicEntries: number;
|
|
251
|
+
totalTags: number;
|
|
252
|
+
tagCounts: Record<string, number>;
|
|
253
|
+
output: string;
|
|
254
|
+
}
|
|
255
|
+
export declare function distilMemories(params?: {
|
|
256
|
+
dryRun?: boolean;
|
|
257
|
+
sessionId?: string;
|
|
258
|
+
}): Promise<DistilResult>;
|
|
184
259
|
export {};
|