myagentmemory 0.4.3

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/dist/cli.js ADDED
@@ -0,0 +1,510 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * agent-memory CLI
4
+ *
5
+ * Subcommands:
6
+ * context — Build & print context injection string to stdout
7
+ * write — Write to memory files
8
+ * read — Read memory files
9
+ * scratchpad — Manage checklist
10
+ * search — Search via qmd
11
+ * init — Create dirs, detect qmd, setup collection
12
+ * status — Show config, qmd status, file counts
13
+ *
14
+ * Global flags:
15
+ * --dir <path> Override memory directory
16
+ * --json Machine-readable JSON output
17
+ */
18
+ import * as fs from "node:fs";
19
+ import { _setBaseDir, buildMemoryContext, checkCollection, dailyPath, detectQmd, ensureDirs, ensureQmdAvailableForUpdate, getCollectionName, getDailyDir, getMemoryDir, getMemoryFile, getQmdResultPath, getQmdResultText, getScratchpadFile, nowTimestamp, parseScratchpad, readFileSafe, runQmdSearch, scheduleQmdUpdate, searchRelevantMemories, serializeScratchpad, setupQmdCollection, todayStr, } from "./core.js";
20
+ function parseArgs(argv) {
21
+ const flags = {};
22
+ const positional = [];
23
+ let command = "";
24
+ for (let i = 0; i < argv.length; i++) {
25
+ const arg = argv[i];
26
+ if (!command && !arg.startsWith("-")) {
27
+ command = arg;
28
+ continue;
29
+ }
30
+ if (arg.startsWith("--")) {
31
+ const key = arg.slice(2);
32
+ const next = argv[i + 1];
33
+ if (next && !next.startsWith("--")) {
34
+ flags[key] = next;
35
+ i++;
36
+ }
37
+ else {
38
+ flags[key] = true;
39
+ }
40
+ }
41
+ else if (!arg.startsWith("-")) {
42
+ positional.push(arg);
43
+ }
44
+ }
45
+ return { command, flags, positional };
46
+ }
47
+ function getFlag(flags, key) {
48
+ const val = flags[key];
49
+ return typeof val === "string" ? val : undefined;
50
+ }
51
+ function hasFlag(flags, key) {
52
+ return key in flags;
53
+ }
54
+ // ---------------------------------------------------------------------------
55
+ // Output helpers
56
+ // ---------------------------------------------------------------------------
57
+ function output(data, json) {
58
+ if (json) {
59
+ console.log(JSON.stringify(data, null, 2));
60
+ }
61
+ else if (typeof data === "string") {
62
+ console.log(data);
63
+ }
64
+ else {
65
+ console.log(JSON.stringify(data, null, 2));
66
+ }
67
+ }
68
+ function exitError(message, json) {
69
+ if (json) {
70
+ console.error(JSON.stringify({ error: message }));
71
+ }
72
+ else {
73
+ console.error(`Error: ${message}`);
74
+ }
75
+ process.exit(1);
76
+ }
77
+ // ---------------------------------------------------------------------------
78
+ // Commands
79
+ // ---------------------------------------------------------------------------
80
+ async function cmdContext(flags) {
81
+ const json = hasFlag(flags, "json");
82
+ const noSearch = hasFlag(flags, "no-search");
83
+ ensureDirs();
84
+ const searchResults = noSearch ? "" : await searchRelevantMemories("");
85
+ const context = buildMemoryContext(searchResults);
86
+ if (json) {
87
+ output({ context, directory: getMemoryDir() }, true);
88
+ }
89
+ else {
90
+ if (context) {
91
+ process.stdout.write(context);
92
+ }
93
+ }
94
+ }
95
+ async function cmdWrite(flags) {
96
+ const json = hasFlag(flags, "json");
97
+ const target = getFlag(flags, "target");
98
+ const content = getFlag(flags, "content");
99
+ const mode = getFlag(flags, "mode") ?? "append";
100
+ if (!target || !["long_term", "daily"].includes(target)) {
101
+ exitError("--target must be 'long_term' or 'daily'", json);
102
+ }
103
+ if (!content) {
104
+ exitError("--content is required", json);
105
+ }
106
+ ensureDirs();
107
+ const ts = nowTimestamp();
108
+ const sid = "cli";
109
+ if (target === "daily") {
110
+ const filePath = dailyPath(todayStr());
111
+ const existing = readFileSafe(filePath) ?? "";
112
+ const separator = existing.trim() ? "\n\n" : "";
113
+ const stamped = `<!-- ${ts} [${sid}] -->\n${content}`;
114
+ fs.writeFileSync(filePath, existing + separator + stamped, "utf-8");
115
+ await ensureQmdAvailableForUpdate();
116
+ scheduleQmdUpdate();
117
+ output(json
118
+ ? { ok: true, path: filePath, target, mode: "append", timestamp: ts }
119
+ : `Appended to daily log: ${filePath}`, json);
120
+ return;
121
+ }
122
+ // long_term
123
+ const memFile = getMemoryFile();
124
+ const existing = readFileSafe(memFile) ?? "";
125
+ if (mode === "overwrite") {
126
+ const stamped = `<!-- last updated: ${ts} [${sid}] -->\n${content}`;
127
+ fs.writeFileSync(memFile, stamped, "utf-8");
128
+ }
129
+ else {
130
+ const separator = existing.trim() ? "\n\n" : "";
131
+ const stamped = `<!-- ${ts} [${sid}] -->\n${content}`;
132
+ fs.writeFileSync(memFile, existing + separator + stamped, "utf-8");
133
+ }
134
+ await ensureQmdAvailableForUpdate();
135
+ scheduleQmdUpdate();
136
+ output(json
137
+ ? { ok: true, path: memFile, target, mode, timestamp: ts }
138
+ : `${mode === "overwrite" ? "Overwrote" : "Appended to"} MEMORY.md`, json);
139
+ }
140
+ async function cmdRead(flags) {
141
+ const json = hasFlag(flags, "json");
142
+ const target = getFlag(flags, "target");
143
+ const date = getFlag(flags, "date");
144
+ if (!target || !["long_term", "scratchpad", "daily", "list"].includes(target)) {
145
+ exitError("--target must be 'long_term', 'scratchpad', 'daily', or 'list'", json);
146
+ }
147
+ ensureDirs();
148
+ if (target === "list") {
149
+ try {
150
+ const files = fs
151
+ .readdirSync(getDailyDir())
152
+ .filter((f) => f.endsWith(".md"))
153
+ .sort()
154
+ .reverse();
155
+ if (json) {
156
+ output({ files }, true);
157
+ }
158
+ else if (files.length === 0) {
159
+ console.log("No daily logs found.");
160
+ }
161
+ else {
162
+ console.log(`Daily logs:\n${files.map((f) => `- ${f}`).join("\n")}`);
163
+ }
164
+ }
165
+ catch {
166
+ output(json ? { files: [] } : "No daily logs directory.", json);
167
+ }
168
+ return;
169
+ }
170
+ if (target === "daily") {
171
+ const d = date ?? todayStr();
172
+ const filePath = dailyPath(d);
173
+ const content = readFileSafe(filePath);
174
+ if (!content) {
175
+ output(json ? { content: null, date: d } : `No daily log for ${d}.`, json);
176
+ return;
177
+ }
178
+ output(json ? { content, date: d, path: filePath } : content, json);
179
+ return;
180
+ }
181
+ if (target === "scratchpad") {
182
+ const content = readFileSafe(getScratchpadFile());
183
+ if (!content?.trim()) {
184
+ output(json ? { content: null } : "SCRATCHPAD.md is empty or does not exist.", json);
185
+ return;
186
+ }
187
+ output(json ? { content, path: getScratchpadFile() } : content, json);
188
+ return;
189
+ }
190
+ // long_term
191
+ const content = readFileSafe(getMemoryFile());
192
+ if (!content) {
193
+ output(json ? { content: null } : "MEMORY.md is empty or does not exist.", json);
194
+ return;
195
+ }
196
+ output(json ? { content, path: getMemoryFile() } : content, json);
197
+ }
198
+ async function cmdScratchpad(flags, positional) {
199
+ const json = hasFlag(flags, "json");
200
+ const action = positional[0];
201
+ const text = getFlag(flags, "text");
202
+ if (!action || !["add", "done", "undo", "clear_done", "list"].includes(action)) {
203
+ exitError("Usage: agent-memory scratchpad <add|done|undo|clear_done|list> [--text <text>]", json);
204
+ }
205
+ ensureDirs();
206
+ const spFile = getScratchpadFile();
207
+ const existing = readFileSafe(spFile) ?? "";
208
+ let items = parseScratchpad(existing);
209
+ if (action === "list") {
210
+ if (items.length === 0) {
211
+ output(json ? { items: [], count: 0, open: 0 } : "Scratchpad is empty.", json);
212
+ return;
213
+ }
214
+ if (json) {
215
+ output({
216
+ items: items.map((i) => ({ done: i.done, text: i.text })),
217
+ count: items.length,
218
+ open: items.filter((i) => !i.done).length,
219
+ }, true);
220
+ }
221
+ else {
222
+ console.log(serializeScratchpad(items));
223
+ }
224
+ return;
225
+ }
226
+ if (action === "add") {
227
+ if (!text)
228
+ exitError("--text is required for add", json);
229
+ const ts = nowTimestamp();
230
+ items.push({ done: false, text: text, meta: `<!-- ${ts} [cli] -->` });
231
+ fs.writeFileSync(spFile, serializeScratchpad(items), "utf-8");
232
+ await ensureQmdAvailableForUpdate();
233
+ scheduleQmdUpdate();
234
+ output(json ? { ok: true, action, text } : `Added: - [ ] ${text}`, json);
235
+ return;
236
+ }
237
+ if (action === "done" || action === "undo") {
238
+ if (!text)
239
+ exitError(`--text is required for ${action}`, json);
240
+ const needle = text.toLowerCase();
241
+ const targetDone = action === "done";
242
+ let matched = false;
243
+ for (const item of items) {
244
+ if (item.done !== targetDone && item.text.toLowerCase().includes(needle)) {
245
+ item.done = targetDone;
246
+ matched = true;
247
+ break;
248
+ }
249
+ }
250
+ if (!matched) {
251
+ exitError(`No matching ${targetDone ? "open" : "done"} item found for: "${text}"`, json);
252
+ }
253
+ fs.writeFileSync(spFile, serializeScratchpad(items), "utf-8");
254
+ await ensureQmdAvailableForUpdate();
255
+ scheduleQmdUpdate();
256
+ output(json ? { ok: true, action, text } : "Updated.", json);
257
+ return;
258
+ }
259
+ if (action === "clear_done") {
260
+ const before = items.length;
261
+ items = items.filter((i) => !i.done);
262
+ const removed = before - items.length;
263
+ fs.writeFileSync(spFile, serializeScratchpad(items), "utf-8");
264
+ await ensureQmdAvailableForUpdate();
265
+ scheduleQmdUpdate();
266
+ output(json ? { ok: true, action, removed } : `Cleared ${removed} done item(s).`, json);
267
+ }
268
+ }
269
+ async function cmdSearch(flags) {
270
+ const json = hasFlag(flags, "json");
271
+ const query = getFlag(flags, "query");
272
+ const mode = (getFlag(flags, "mode") ?? "keyword");
273
+ const limit = Number.parseInt(getFlag(flags, "limit") ?? "5", 10);
274
+ if (!query)
275
+ exitError("--query is required", json);
276
+ if (!["keyword", "semantic", "deep"].includes(mode)) {
277
+ exitError("--mode must be 'keyword', 'semantic', or 'deep'", json);
278
+ }
279
+ const qmdFound = await detectQmd();
280
+ if (!qmdFound) {
281
+ exitError("qmd is not installed. Install: bun install -g https://github.com/tobi/qmd", json);
282
+ }
283
+ const collName = getCollectionName();
284
+ const hasCollection = await checkCollection(collName);
285
+ if (!hasCollection) {
286
+ exitError(`qmd collection '${collName}' not found. Run: agent-memory init`, json);
287
+ }
288
+ try {
289
+ const { results, stderr } = await runQmdSearch(mode, query, limit);
290
+ if (json) {
291
+ output({ mode, query, count: results.length, results }, true);
292
+ return;
293
+ }
294
+ if (results.length === 0) {
295
+ const needsEmbed = /need embeddings/i.test(stderr ?? "");
296
+ if (needsEmbed && (mode === "semantic" || mode === "deep")) {
297
+ console.log(`No results found. qmd reports missing embeddings — run: qmd embed`);
298
+ }
299
+ else {
300
+ console.log(`No results found for "${query}" (mode: ${mode}).`);
301
+ }
302
+ return;
303
+ }
304
+ for (let i = 0; i < results.length; i++) {
305
+ const r = results[i];
306
+ const filePath = getQmdResultPath(r);
307
+ const text = getQmdResultText(r);
308
+ console.log(`--- Result ${i + 1} ---`);
309
+ if (filePath)
310
+ console.log(`File: ${filePath}`);
311
+ if (r.score != null)
312
+ console.log(`Score: ${r.score}`);
313
+ if (text)
314
+ console.log(text);
315
+ console.log("");
316
+ }
317
+ }
318
+ catch (err) {
319
+ exitError(`Search failed: ${err instanceof Error ? err.message : String(err)}`, json);
320
+ }
321
+ }
322
+ async function cmdInit(flags) {
323
+ const json = hasFlag(flags, "json");
324
+ ensureDirs();
325
+ const dir = getMemoryDir();
326
+ const qmdFound = await detectQmd();
327
+ let collectionCreated = false;
328
+ if (qmdFound) {
329
+ const collName = getCollectionName();
330
+ const hasCollection = await checkCollection(collName);
331
+ if (!hasCollection) {
332
+ collectionCreated = await setupQmdCollection();
333
+ }
334
+ }
335
+ if (json) {
336
+ output({
337
+ ok: true,
338
+ directory: dir,
339
+ qmd: qmdFound,
340
+ collectionCreated,
341
+ }, true);
342
+ }
343
+ else {
344
+ console.log(`Memory directory: ${dir}`);
345
+ console.log(` MEMORY.md, SCRATCHPAD.md, daily/ created.`);
346
+ if (qmdFound) {
347
+ if (collectionCreated) {
348
+ console.log(` qmd collection '${getCollectionName()}' created.`);
349
+ }
350
+ else {
351
+ console.log(` qmd collection '${getCollectionName()}' already exists.`);
352
+ }
353
+ }
354
+ else {
355
+ console.log(` qmd not found — search features unavailable.`);
356
+ console.log(` Install: bun install -g https://github.com/tobi/qmd`);
357
+ }
358
+ }
359
+ }
360
+ async function cmdStatus(flags) {
361
+ const json = hasFlag(flags, "json");
362
+ ensureDirs();
363
+ const dir = getMemoryDir();
364
+ const memFile = getMemoryFile();
365
+ const spFile = getScratchpadFile();
366
+ const dailyDir = getDailyDir();
367
+ const memContent = readFileSafe(memFile);
368
+ const spContent = readFileSafe(spFile);
369
+ let dailyCount = 0;
370
+ try {
371
+ dailyCount = fs.readdirSync(dailyDir).filter((f) => f.endsWith(".md")).length;
372
+ }
373
+ catch {
374
+ // directory may not exist
375
+ }
376
+ const qmdFound = await detectQmd();
377
+ let hasCollection = false;
378
+ if (qmdFound) {
379
+ hasCollection = await checkCollection();
380
+ }
381
+ if (json) {
382
+ output({
383
+ directory: dir,
384
+ memoryFile: {
385
+ exists: memContent !== null,
386
+ chars: memContent?.length ?? 0,
387
+ lines: memContent ? memContent.split("\n").length : 0,
388
+ },
389
+ scratchpadFile: {
390
+ exists: spContent !== null,
391
+ items: spContent ? parseScratchpad(spContent).length : 0,
392
+ openItems: spContent ? parseScratchpad(spContent).filter((i) => !i.done).length : 0,
393
+ },
394
+ dailyLogs: dailyCount,
395
+ qmd: {
396
+ available: qmdFound,
397
+ collection: hasCollection ? getCollectionName() : null,
398
+ },
399
+ }, true);
400
+ }
401
+ else {
402
+ console.log(`Memory directory: ${dir}`);
403
+ console.log("");
404
+ if (memContent !== null) {
405
+ const lines = memContent.split("\n").length;
406
+ console.log(`MEMORY.md: ${memContent.length} chars, ${lines} lines`);
407
+ }
408
+ else {
409
+ console.log("MEMORY.md: not created yet");
410
+ }
411
+ if (spContent !== null) {
412
+ const items = parseScratchpad(spContent);
413
+ const open = items.filter((i) => !i.done).length;
414
+ console.log(`SCRATCHPAD.md: ${items.length} items (${open} open)`);
415
+ }
416
+ else {
417
+ console.log("SCRATCHPAD.md: not created yet");
418
+ }
419
+ console.log(`Daily logs: ${dailyCount} file(s)`);
420
+ console.log("");
421
+ if (qmdFound) {
422
+ console.log(`qmd: available`);
423
+ console.log(`Collection '${getCollectionName()}': ${hasCollection ? "configured" : "not configured — run: agent-memory init"}`);
424
+ }
425
+ else {
426
+ console.log("qmd: not installed");
427
+ }
428
+ }
429
+ }
430
+ // ---------------------------------------------------------------------------
431
+ // Usage
432
+ // ---------------------------------------------------------------------------
433
+ function printUsage() {
434
+ console.log(`agent-memory — persistent memory for coding agents
435
+
436
+ Usage:
437
+ agent-memory <command> [options]
438
+
439
+ Commands:
440
+ context Build & print context injection string
441
+ write Write to memory files
442
+ read Read memory files
443
+ scratchpad Manage checklist items
444
+ search Search across memory files (requires qmd)
445
+ init Initialize memory directory and qmd collection
446
+ status Show configuration and status
447
+
448
+ Global flags:
449
+ --dir <path> Override memory directory
450
+ --json Machine-readable JSON output
451
+
452
+ Examples:
453
+ agent-memory init
454
+ agent-memory write --target long_term --content "User prefers dark mode"
455
+ agent-memory write --target daily --content "Fixed auth bug in login flow"
456
+ agent-memory read --target long_term
457
+ agent-memory read --target daily --date 2026-02-15
458
+ agent-memory read --target list
459
+ agent-memory scratchpad add --text "Review PR #42"
460
+ agent-memory scratchpad list
461
+ agent-memory scratchpad done --text "PR #42"
462
+ agent-memory search --query "database choice" --mode keyword
463
+ agent-memory context --no-search
464
+ agent-memory status --json`);
465
+ }
466
+ // ---------------------------------------------------------------------------
467
+ // Main
468
+ // ---------------------------------------------------------------------------
469
+ async function main() {
470
+ const { command, flags, positional } = parseArgs(process.argv.slice(2));
471
+ const json = hasFlag(flags, "json");
472
+ // Apply --dir override
473
+ const dir = getFlag(flags, "dir");
474
+ if (dir) {
475
+ _setBaseDir(dir);
476
+ }
477
+ if (!command || command === "help" || hasFlag(flags, "help")) {
478
+ printUsage();
479
+ return;
480
+ }
481
+ switch (command) {
482
+ case "context":
483
+ await cmdContext(flags);
484
+ break;
485
+ case "write":
486
+ await cmdWrite(flags);
487
+ break;
488
+ case "read":
489
+ await cmdRead(flags);
490
+ break;
491
+ case "scratchpad":
492
+ await cmdScratchpad(flags, positional);
493
+ break;
494
+ case "search":
495
+ await cmdSearch(flags);
496
+ break;
497
+ case "init":
498
+ await cmdInit(flags);
499
+ break;
500
+ case "status":
501
+ await cmdStatus(flags);
502
+ break;
503
+ default:
504
+ exitError(`Unknown command: ${command}. Run 'agent-memory help' for usage.`, json);
505
+ }
506
+ }
507
+ main().catch((err) => {
508
+ console.error(err instanceof Error ? err.message : String(err));
509
+ process.exit(1);
510
+ });
package/dist/core.d.ts ADDED
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Shared core logic for agent-memory.
3
+ *
4
+ * Core logic for agent-memory CLI and skills.
5
+ * Zero pi peer dependencies — only node:fs, node:path, node:child_process.
6
+ */
7
+ import { execFile } from "node:child_process";
8
+ /** Override base directory (for testing or platform-specific defaults). */
9
+ export declare function _setBaseDir(baseDir: string): void;
10
+ /** Reset to default paths. */
11
+ export declare function _resetBaseDir(): void;
12
+ /** Get the current memory directory path. */
13
+ export declare function getMemoryDir(): string;
14
+ /** Get the current MEMORY.md path. */
15
+ export declare function getMemoryFile(): string;
16
+ /** Get the current SCRATCHPAD.md path. */
17
+ export declare function getScratchpadFile(): string;
18
+ /** Get the current daily log directory path. */
19
+ export declare function getDailyDir(): string;
20
+ export declare function ensureDirs(): void;
21
+ export declare function todayStr(): string;
22
+ export declare function yesterdayStr(): string;
23
+ export declare function nowTimestamp(): string;
24
+ export declare function shortSessionId(sessionId: string): string;
25
+ export declare function readFileSafe(filePath: string): string | null;
26
+ export declare function dailyPath(date: string): string;
27
+ export declare const RESPONSE_PREVIEW_MAX_CHARS = 4000;
28
+ export declare const RESPONSE_PREVIEW_MAX_LINES = 120;
29
+ export type TruncateMode = "start" | "end" | "middle";
30
+ export interface PreviewResult {
31
+ preview: string;
32
+ truncated: boolean;
33
+ totalLines: number;
34
+ totalChars: number;
35
+ previewLines: number;
36
+ previewChars: number;
37
+ }
38
+ export declare function truncateLines(lines: string[], maxLines: number, mode: TruncateMode): {
39
+ lines: string[];
40
+ truncated: boolean;
41
+ };
42
+ export declare function truncateText(text: string, maxChars: number, mode: TruncateMode): {
43
+ text: string;
44
+ truncated: boolean;
45
+ };
46
+ export declare function buildPreview(content: string, options: {
47
+ maxLines: number;
48
+ maxChars: number;
49
+ mode: TruncateMode;
50
+ }): PreviewResult;
51
+ export declare function formatPreviewBlock(label: string, content: string, mode: TruncateMode): string;
52
+ export declare function formatContextSection(label: string, content: string, mode: TruncateMode, maxLines: number, maxChars: number): string;
53
+ export interface ScratchpadItem {
54
+ done: boolean;
55
+ text: string;
56
+ meta: string;
57
+ }
58
+ export declare function parseScratchpad(content: string): ScratchpadItem[];
59
+ export declare function serializeScratchpad(items: ScratchpadItem[]): string;
60
+ export declare function buildMemoryContext(searchResults?: string): string;
61
+ type ExecFileFn = typeof execFile;
62
+ /** Override execFile implementation (for testing). */
63
+ export declare function _setExecFileForTest(fn: ExecFileFn): void;
64
+ /** Reset execFile implementation (for testing). */
65
+ export declare function _resetExecFileForTest(): void;
66
+ /** Set qmd availability flag (for testing). */
67
+ export declare function _setQmdAvailable(value: boolean): void;
68
+ /** Get current qmd availability flag. */
69
+ export declare function _getQmdAvailable(): boolean;
70
+ /** Get current update timer (for testing). */
71
+ export declare function _getUpdateTimer(): ReturnType<typeof setTimeout> | null;
72
+ /** Clear the update timer (for testing). */
73
+ export declare function _clearUpdateTimer(): void;
74
+ /** Get the current QMD collection name. */
75
+ export declare function getCollectionName(): string;
76
+ /** Set the QMD collection name (for platform-specific overrides). */
77
+ export declare function setCollectionName(name: string): void;
78
+ export declare function qmdInstallInstructions(): string;
79
+ export declare function qmdCollectionInstructions(): string;
80
+ /** Auto-create the qmd collection and path contexts. */
81
+ export declare function setupQmdCollection(): Promise<boolean>;
82
+ export declare function detectQmd(): Promise<boolean>;
83
+ export declare function checkCollection(name?: string): Promise<boolean>;
84
+ export declare function getQmdUpdateMode(): "background" | "manual" | "off";
85
+ export declare function ensureQmdAvailableForUpdate(): Promise<boolean>;
86
+ export declare function scheduleQmdUpdate(): void;
87
+ export declare function runQmdUpdateNow(): Promise<void>;
88
+ /** Search for memories relevant to the user's prompt. Returns formatted markdown or empty string on error. */
89
+ export declare function searchRelevantMemories(prompt: string): Promise<string>;
90
+ export interface QmdSearchResult {
91
+ path?: string;
92
+ file?: string;
93
+ score?: number;
94
+ content?: string;
95
+ chunk?: string;
96
+ snippet?: string;
97
+ title?: string;
98
+ [key: string]: unknown;
99
+ }
100
+ export declare function getQmdResultPath(r: QmdSearchResult): string | undefined;
101
+ export declare function getQmdResultText(r: QmdSearchResult): string;
102
+ export declare function runQmdSearch(mode: "keyword" | "semantic" | "deep", query: string, limit: number): Promise<{
103
+ results: QmdSearchResult[];
104
+ stderr: string;
105
+ }>;
106
+ export interface ToolResult {
107
+ text: string;
108
+ details: Record<string, unknown>;
109
+ isError?: boolean;
110
+ }
111
+ export declare function memoryWrite(params: {
112
+ target: "long_term" | "daily";
113
+ content: string;
114
+ mode?: "append" | "overwrite";
115
+ sessionId?: string;
116
+ }): Promise<ToolResult>;
117
+ export declare function scratchpadAction(params: {
118
+ action: "add" | "done" | "undo" | "clear_done" | "list";
119
+ text?: string;
120
+ sessionId?: string;
121
+ }): Promise<ToolResult>;
122
+ export declare function memoryRead(params: {
123
+ target: "long_term" | "scratchpad" | "daily" | "list";
124
+ date?: string;
125
+ }): Promise<ToolResult>;
126
+ export declare function memorySearch(params: {
127
+ query: string;
128
+ mode?: "keyword" | "semantic" | "deep";
129
+ limit?: number;
130
+ }): Promise<ToolResult>;
131
+ export {};