@devxiyang/agent-memo 0.0.1
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 +193 -0
- package/dist/core/memo/constants.d.ts +6 -0
- package/dist/core/memo/constants.d.ts.map +1 -0
- package/dist/core/memo/constants.js +6 -0
- package/dist/core/memo/constants.js.map +1 -0
- package/dist/core/memo/file-fs.d.ts +39 -0
- package/dist/core/memo/file-fs.d.ts.map +1 -0
- package/dist/core/memo/file-fs.js +259 -0
- package/dist/core/memo/file-fs.js.map +1 -0
- package/dist/core/memo/index.d.ts +7 -0
- package/dist/core/memo/index.d.ts.map +1 -0
- package/dist/core/memo/index.js +7 -0
- package/dist/core/memo/index.js.map +1 -0
- package/dist/core/memo/memo.d.ts +1 -0
- package/dist/core/memo/memo.d.ts.map +1 -0
- package/dist/core/memo/memo.js +3 -0
- package/dist/core/memo/memo.js.map +1 -0
- package/dist/core/memo/mime.d.ts +10 -0
- package/dist/core/memo/mime.d.ts.map +1 -0
- package/dist/core/memo/mime.js +13 -0
- package/dist/core/memo/mime.js.map +1 -0
- package/dist/core/memo/search/index.d.ts +3 -0
- package/dist/core/memo/search/index.d.ts.map +1 -0
- package/dist/core/memo/search/index.js +3 -0
- package/dist/core/memo/search/index.js.map +1 -0
- package/dist/core/memo/search/ripgrep.d.ts +11 -0
- package/dist/core/memo/search/ripgrep.d.ts.map +1 -0
- package/dist/core/memo/search/ripgrep.js +71 -0
- package/dist/core/memo/search/ripgrep.js.map +1 -0
- package/dist/core/memo/search/text.d.ts +10 -0
- package/dist/core/memo/search/text.d.ts.map +1 -0
- package/dist/core/memo/search/text.js +63 -0
- package/dist/core/memo/search/text.js.map +1 -0
- package/dist/core/memo/types.d.ts +113 -0
- package/dist/core/memo/types.d.ts.map +1 -0
- package/dist/core/memo/types.js +3 -0
- package/dist/core/memo/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# agent.memo
|
|
2
|
+
|
|
3
|
+
Agent memory SDK based on a filesystem paradigm. Organizes memories, resources and skills as a hierarchical virtual filesystem with `memo://` URIs — inspired by [OpenViking](https://github.com/volcengine/OpenViking).
|
|
4
|
+
|
|
5
|
+
## Concepts
|
|
6
|
+
|
|
7
|
+
Every directory carries up to four meta files managed by the **caller** (typically via LLM):
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
{workspace}/user/memories/preferences/
|
|
11
|
+
├── .abstract.md # L0 ~100 tokens, one-sentence summary
|
|
12
|
+
├── .overview.md # L1 ~1-2k tokens, navigational overview
|
|
13
|
+
├── .relations.json # links to other nodes
|
|
14
|
+
├── .meta.json # arbitrary structured metadata
|
|
15
|
+
└── coding.md # L2 actual content
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Tiered context loading:**
|
|
19
|
+
|
|
20
|
+
| Tier | Source | Cost |
|
|
21
|
+
|------|--------|------|
|
|
22
|
+
| 0 | `.abstract.md` | cheap, always-on |
|
|
23
|
+
| 1 | `.overview.md` | medium |
|
|
24
|
+
| 2 | full file content | full |
|
|
25
|
+
|
|
26
|
+
**URI scheme:** `memo://path/to/node` maps directly to `{workspace}/path/to/node`.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install @devxiyang/agent-memo
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
> `RipgrepSearchBackend` (default) uses a bundled `rg` binary via `@vscode/ripgrep` — no manual installation needed.
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { FileMemo, type Memo, type MemoLifecycle } from '@devxiyang/agent-memo'
|
|
40
|
+
|
|
41
|
+
await using memo = new FileMemo({
|
|
42
|
+
workspace: '/path/to/workspace',
|
|
43
|
+
hooks: {
|
|
44
|
+
onWritten: async (uri, parentDirs) => {
|
|
45
|
+
// Called after any file write or update (SDK or external tool)
|
|
46
|
+
// Regenerate .abstract.md for affected directories
|
|
47
|
+
for (const dir of parentDirs) {
|
|
48
|
+
const abstract = await myLLM.summarize(await memo.ls(dir))
|
|
49
|
+
await memo.writeMeta(dir, { abstract })
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
onError: (err, event) => console.error(`[memo:${event}]`, err),
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
// Write content
|
|
57
|
+
await memo.write('memo://user/memories/preferences/coding.md', 'Prefers TypeScript strict mode')
|
|
58
|
+
|
|
59
|
+
// List directory (includes mimeType for files, abstract for subdirs)
|
|
60
|
+
const nodes = await memo.ls('memo://user/memories/')
|
|
61
|
+
|
|
62
|
+
// Search
|
|
63
|
+
const results = await memo.search('TypeScript', {
|
|
64
|
+
scope: ['memo://user/memories/'],
|
|
65
|
+
limit: 10,
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
// Build LLM context
|
|
69
|
+
const systemPrompt = await memo.context(['memo://user/memories/'], 0) // L0, cheap
|
|
70
|
+
const detail = await memo.context(['memo://user/memories/preferences/coding.md'], 2) // full
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Binary Files
|
|
74
|
+
|
|
75
|
+
For binary files (images, PDFs, audio), use `toPath()` to get the physical path and write directly — the filesystem watcher picks it up automatically:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const path = memo.toPath('memo://user/memories/photos/avatar.jpg')
|
|
79
|
+
await sharp(imageBuffer).toFile(path)
|
|
80
|
+
// onWrite hook fires automatically, caller generates .abstract.md via VLM
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## API
|
|
84
|
+
|
|
85
|
+
### `new FileMemo(options: FileMemoOptions)`
|
|
86
|
+
|
|
87
|
+
| Option | Type | Default | Description |
|
|
88
|
+
|--------|------|---------|-------------|
|
|
89
|
+
| `workspace` | `string` | required | Root directory |
|
|
90
|
+
| `hooks` | `MemoHooks` | — | Lifecycle hooks |
|
|
91
|
+
| `search` | `SearchBackend` | `RipgrepSearchBackend` | Search implementation |
|
|
92
|
+
| `mime` | `MimeDetector` | `MagicMimeDetector` | MIME type detection |
|
|
93
|
+
| `watch` | `boolean` | `true` | Auto-start filesystem watcher |
|
|
94
|
+
|
|
95
|
+
### `Memo` interface
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
// Content
|
|
99
|
+
read(uri): Promise<string | null>
|
|
100
|
+
write(uri, content): Promise<void>
|
|
101
|
+
delete(uri): Promise<void>
|
|
102
|
+
|
|
103
|
+
// Directory
|
|
104
|
+
ls(uri): Promise<MemoNode[]>
|
|
105
|
+
mkdir(uri): Promise<void>
|
|
106
|
+
rmdir(uri, recursive?): Promise<void>
|
|
107
|
+
|
|
108
|
+
// Meta (caller manages content)
|
|
109
|
+
readMeta(uri): Promise<DirMeta>
|
|
110
|
+
writeMeta(uri, meta): Promise<void>
|
|
111
|
+
|
|
112
|
+
// Relations
|
|
113
|
+
link(uri, targets, reason?): Promise<void>
|
|
114
|
+
unlink(uri, target): Promise<void>
|
|
115
|
+
relations(uri): Promise<Relation[]>
|
|
116
|
+
|
|
117
|
+
// Search
|
|
118
|
+
search(query, options?): Promise<SearchResult[]>
|
|
119
|
+
|
|
120
|
+
// LLM context assembly
|
|
121
|
+
context(uris, tier: 0 | 1 | 2): Promise<string>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### `MemoLifecycle` interface
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
toPath(uri): string // get physical path for binary access
|
|
128
|
+
watch(): void // start watcher
|
|
129
|
+
unwatch(): Promise<void> // stop watcher
|
|
130
|
+
[Symbol.asyncDispose]() // used by `await using`
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Hooks
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
interface MemoHooks {
|
|
137
|
+
onWritten?(uri, parentDirs): void | Promise<void>
|
|
138
|
+
onDeleted?(uri, parentDirs): void | Promise<void>
|
|
139
|
+
onLinked?(uri, targets): void | Promise<void>
|
|
140
|
+
onUnlinked?(uri, target): void | Promise<void>
|
|
141
|
+
onError?(err, event): void
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
All hooks are **fire-and-forget** — the SDK does not await them. Errors are forwarded to `onError`.
|
|
146
|
+
|
|
147
|
+
### Search Backends
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// Default — bundled rg binary, fast
|
|
151
|
+
new RipgrepSearchBackend()
|
|
152
|
+
|
|
153
|
+
// Fallback — pure JS, no system dependencies
|
|
154
|
+
new SimpleSearchBackend()
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### MIME Detector
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// Default — magic bytes detection via file-type
|
|
161
|
+
new MagicMimeDetector()
|
|
162
|
+
|
|
163
|
+
// Custom
|
|
164
|
+
class MyDetector implements MimeDetector {
|
|
165
|
+
async detect(path: string): Promise<string | undefined> { ... }
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Filesystem Structure
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
{workspace}/
|
|
173
|
+
├── user/
|
|
174
|
+
│ └── memories/
|
|
175
|
+
│ ├── .abstract.md
|
|
176
|
+
│ ├── .overview.md
|
|
177
|
+
│ ├── .relations.json
|
|
178
|
+
│ ├── preferences/
|
|
179
|
+
│ │ ├── .abstract.md
|
|
180
|
+
│ │ └── coding.md
|
|
181
|
+
│ └── photos/
|
|
182
|
+
│ └── avatar.jpg
|
|
183
|
+
├── agent/
|
|
184
|
+
│ └── memories/
|
|
185
|
+
│ ├── cases/
|
|
186
|
+
│ └── patterns/
|
|
187
|
+
└── session/
|
|
188
|
+
└── {session-id}/
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
MIT
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const META_ABSTRACT = ".abstract.md";
|
|
2
|
+
export declare const META_OVERVIEW = ".overview.md";
|
|
3
|
+
export declare const META_RELATIONS = ".relations.json";
|
|
4
|
+
export declare const META_META = ".meta.json";
|
|
5
|
+
export declare const META_FILES: Set<string>;
|
|
6
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/core/memo/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,iBAAkB,CAAA;AAC5C,eAAO,MAAM,aAAa,iBAAkB,CAAA;AAC5C,eAAO,MAAM,cAAc,oBAAoB,CAAA;AAC/C,eAAO,MAAM,SAAS,eAAoB,CAAA;AAE1C,eAAO,MAAM,UAAU,aAAqE,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const META_ABSTRACT = '.abstract.md';
|
|
2
|
+
export const META_OVERVIEW = '.overview.md';
|
|
3
|
+
export const META_RELATIONS = '.relations.json';
|
|
4
|
+
export const META_META = '.meta.json';
|
|
5
|
+
export const META_FILES = new Set([META_ABSTRACT, META_OVERVIEW, META_RELATIONS, META_META]);
|
|
6
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/core/memo/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAI,cAAc,CAAA;AAC5C,MAAM,CAAC,MAAM,aAAa,GAAI,cAAc,CAAA;AAC5C,MAAM,CAAC,MAAM,cAAc,GAAG,iBAAiB,CAAA;AAC/C,MAAM,CAAC,MAAM,SAAS,GAAQ,YAAY,CAAA;AAE1C,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Memo, MemoLifecycle, MemoUri, MemoNode, DirMeta, Relation, SearchOptions, SearchResult, FileMemoOptions } from './types.js';
|
|
2
|
+
export declare class FileMemo implements Memo, MemoLifecycle {
|
|
3
|
+
private readonly options;
|
|
4
|
+
private readonly hooks;
|
|
5
|
+
private readonly backend;
|
|
6
|
+
private readonly mime;
|
|
7
|
+
private readonly index;
|
|
8
|
+
private watcher;
|
|
9
|
+
constructor(options: FileMemoOptions);
|
|
10
|
+
private get workspace();
|
|
11
|
+
private absToUri;
|
|
12
|
+
private fire;
|
|
13
|
+
private _indexFile;
|
|
14
|
+
/** Convert a memo URI to an absolute filesystem path (for binary file access). */
|
|
15
|
+
toPath(uri: MemoUri): string;
|
|
16
|
+
/**
|
|
17
|
+
* Start watching the workspace with chokidar.
|
|
18
|
+
* On startup: scans existing files to build the index (no hooks fired).
|
|
19
|
+
* Afterwards: all filesystem changes update the index and fire hooks.
|
|
20
|
+
* Meta files are excluded to prevent infinite loops.
|
|
21
|
+
*/
|
|
22
|
+
watch(): void;
|
|
23
|
+
unwatch(): Promise<void>;
|
|
24
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
25
|
+
read(uri: MemoUri): Promise<string | null>;
|
|
26
|
+
write(uri: MemoUri, content: string): Promise<void>;
|
|
27
|
+
delete(uri: MemoUri): Promise<void>;
|
|
28
|
+
ls(uri: MemoUri): Promise<MemoNode[]>;
|
|
29
|
+
mkdir(uri: MemoUri): Promise<void>;
|
|
30
|
+
rmdir(uri: MemoUri, recursive?: boolean): Promise<void>;
|
|
31
|
+
readMeta(uri: MemoUri): Promise<DirMeta>;
|
|
32
|
+
writeMeta(uri: MemoUri, meta: Partial<DirMeta>): Promise<void>;
|
|
33
|
+
relations(uri: MemoUri): Promise<Relation[]>;
|
|
34
|
+
link(uri: MemoUri, targets: MemoUri[], reason?: string): Promise<void>;
|
|
35
|
+
unlink(uri: MemoUri, target: MemoUri): Promise<void>;
|
|
36
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
37
|
+
context(uris: MemoUri[], tier: 0 | 1 | 2): Promise<string>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=file-fs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-fs.d.ts","sourceRoot":"","sources":["../../../src/core/memo/file-fs.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,OAAO,EACP,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,aAAa,EACb,YAAY,EAKZ,eAAe,EAChB,MAAM,YAAY,CAAA;AA+BnB,qBAAa,QAAS,YAAW,IAAI,EAAE,aAAa;IAOtC,OAAO,CAAC,QAAQ,CAAC,OAAO;IANpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuC;IAC7D,OAAO,CAAC,OAAO,CAAkC;gBAEpB,OAAO,EAAE,eAAe;IAWrD,OAAO,KAAK,SAAS,GAAoC;IAEzD,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,IAAI;YAME,UAAU;IAUxB,kFAAkF;IAClF,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM;IAI5B;;;;;OAKG;IACH,KAAK,IAAI,IAAI;IAiDP,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAMxB,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtC,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAQ1C,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASnD,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IASnC,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAiCrC,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrD,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAcxC,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB9D,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAS5C,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBtE,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAapD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAMvE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;CAqBjE"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { readFile, writeFile, mkdir, rm, readdir, stat } from 'node:fs/promises';
|
|
2
|
+
import { join, dirname, basename } from 'node:path';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import chokidar from 'chokidar';
|
|
5
|
+
import { META_ABSTRACT, META_OVERVIEW, META_RELATIONS, META_META, META_FILES } from './constants.js';
|
|
6
|
+
import { RipgrepSearchBackend } from './search/index.js';
|
|
7
|
+
import { MagicMimeDetector } from './mime.js';
|
|
8
|
+
// ─── URI helpers ──────────────────────────────────────────────────────────────
|
|
9
|
+
function uriToRel(uri) {
|
|
10
|
+
if (!uri.startsWith('memo://'))
|
|
11
|
+
throw new Error(`Invalid memo URI: "${uri}"`);
|
|
12
|
+
return uri.slice('memo://'.length);
|
|
13
|
+
}
|
|
14
|
+
function parentDirs(uri) {
|
|
15
|
+
const parts = uriToRel(uri).split('/').filter(Boolean);
|
|
16
|
+
const dirs = [];
|
|
17
|
+
for (let i = parts.length - 1; i > 0; i--) {
|
|
18
|
+
dirs.push(`memo://${parts.slice(0, i).join('/')}`);
|
|
19
|
+
}
|
|
20
|
+
return dirs;
|
|
21
|
+
}
|
|
22
|
+
// ─── FileMemo ───────────────────────────────────────────────────────────────
|
|
23
|
+
export class FileMemo {
|
|
24
|
+
options;
|
|
25
|
+
hooks;
|
|
26
|
+
backend;
|
|
27
|
+
mime;
|
|
28
|
+
index = new Map();
|
|
29
|
+
watcher = null;
|
|
30
|
+
constructor(options) {
|
|
31
|
+
this.options = options;
|
|
32
|
+
this.hooks = options.hooks ?? {};
|
|
33
|
+
this.backend = options.search ?? new RipgrepSearchBackend();
|
|
34
|
+
this.mime = options.mime ?? new MagicMimeDetector();
|
|
35
|
+
this.backend.init(options.workspace);
|
|
36
|
+
if (options.watch !== false)
|
|
37
|
+
this.watch();
|
|
38
|
+
}
|
|
39
|
+
// ── Internal helpers ───────────────────────────────────────────────────────
|
|
40
|
+
get workspace() { return this.options.workspace; }
|
|
41
|
+
absToUri(absPath) {
|
|
42
|
+
const rel = absPath.slice(this.workspace.length).replace(/^[/\\]/, '');
|
|
43
|
+
return `memo://${rel}`;
|
|
44
|
+
}
|
|
45
|
+
fire(result, event) {
|
|
46
|
+
if (result instanceof Promise) {
|
|
47
|
+
result.catch(err => this.hooks.onError?.(err, event));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async _indexFile(absPath) {
|
|
51
|
+
const [s, mimeType] = await Promise.all([
|
|
52
|
+
stat(absPath).catch(() => null),
|
|
53
|
+
this.mime.detect(absPath).catch(() => undefined),
|
|
54
|
+
]);
|
|
55
|
+
return { mimeType, size: s?.size ?? 0, modTime: s?.mtimeMs ?? 0 };
|
|
56
|
+
}
|
|
57
|
+
// ── MemoLifecycle ────────────────────────────────────────────────────────
|
|
58
|
+
/** Convert a memo URI to an absolute filesystem path (for binary file access). */
|
|
59
|
+
toPath(uri) {
|
|
60
|
+
return join(this.workspace, uriToRel(uri));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Start watching the workspace with chokidar.
|
|
64
|
+
* On startup: scans existing files to build the index (no hooks fired).
|
|
65
|
+
* Afterwards: all filesystem changes update the index and fire hooks.
|
|
66
|
+
* Meta files are excluded to prevent infinite loops.
|
|
67
|
+
*/
|
|
68
|
+
watch() {
|
|
69
|
+
if (this.watcher)
|
|
70
|
+
return;
|
|
71
|
+
let ready = false;
|
|
72
|
+
this.watcher = chokidar.watch(this.workspace, {
|
|
73
|
+
ignoreInitial: false,
|
|
74
|
+
ignored: (p) => META_FILES.has(basename(p)),
|
|
75
|
+
});
|
|
76
|
+
this.watcher.on('add', async (p) => {
|
|
77
|
+
const entry = await this._indexFile(p);
|
|
78
|
+
this.index.set(p, entry);
|
|
79
|
+
if (ready) {
|
|
80
|
+
const uri = this.absToUri(p);
|
|
81
|
+
this.fire(this.hooks.onWritten?.(uri, parentDirs(uri)), 'write');
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
this.watcher.on('change', async (p) => {
|
|
85
|
+
const entry = await this._indexFile(p);
|
|
86
|
+
this.index.set(p, entry);
|
|
87
|
+
if (ready) {
|
|
88
|
+
const uri = this.absToUri(p);
|
|
89
|
+
this.fire(this.hooks.onWritten?.(uri, parentDirs(uri)), 'write');
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
this.watcher.on('unlink', (p) => {
|
|
93
|
+
this.index.delete(p);
|
|
94
|
+
if (ready) {
|
|
95
|
+
const uri = this.absToUri(p);
|
|
96
|
+
this.fire(this.hooks.onDeleted?.(uri, parentDirs(uri)), 'delete');
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
this.watcher.on('unlinkDir', (p) => {
|
|
100
|
+
for (const key of this.index.keys()) {
|
|
101
|
+
if (key.startsWith(p))
|
|
102
|
+
this.index.delete(key);
|
|
103
|
+
}
|
|
104
|
+
if (ready) {
|
|
105
|
+
const uri = this.absToUri(p);
|
|
106
|
+
this.fire(this.hooks.onDeleted?.(uri, parentDirs(uri)), 'delete');
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
this.watcher.on('ready', () => { ready = true; });
|
|
110
|
+
}
|
|
111
|
+
async unwatch() {
|
|
112
|
+
await this.watcher?.close();
|
|
113
|
+
this.watcher = null;
|
|
114
|
+
this.index.clear();
|
|
115
|
+
}
|
|
116
|
+
async [Symbol.asyncDispose]() {
|
|
117
|
+
await this.unwatch();
|
|
118
|
+
}
|
|
119
|
+
// ── Content files ──────────────────────────────────────────────────────────
|
|
120
|
+
async read(uri) {
|
|
121
|
+
try {
|
|
122
|
+
return await readFile(this.toPath(uri), 'utf-8');
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async write(uri, content) {
|
|
129
|
+
const p = this.toPath(uri);
|
|
130
|
+
await mkdir(dirname(p), { recursive: true });
|
|
131
|
+
await writeFile(p, content, 'utf-8');
|
|
132
|
+
if (!this.watcher) {
|
|
133
|
+
this.fire(this.hooks.onWritten?.(uri, parentDirs(uri)), 'write');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async delete(uri) {
|
|
137
|
+
await rm(this.toPath(uri), { force: true });
|
|
138
|
+
if (!this.watcher) {
|
|
139
|
+
this.fire(this.hooks.onDeleted?.(uri, parentDirs(uri)), 'delete');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// ── Directory ──────────────────────────────────────────────────────────────
|
|
143
|
+
async ls(uri) {
|
|
144
|
+
const p = this.toPath(uri);
|
|
145
|
+
let entries;
|
|
146
|
+
try {
|
|
147
|
+
entries = await readdir(p, { withFileTypes: true, encoding: 'utf8' });
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return [];
|
|
151
|
+
}
|
|
152
|
+
return Promise.all(entries
|
|
153
|
+
.filter(e => !META_FILES.has(e.name))
|
|
154
|
+
.map(async (e) => {
|
|
155
|
+
const childPath = join(p, e.name);
|
|
156
|
+
const isDir = e.isDirectory();
|
|
157
|
+
const indexed = !isDir ? this.index.get(childPath) : undefined;
|
|
158
|
+
const s = indexed ? null : await stat(childPath).catch(() => null);
|
|
159
|
+
return {
|
|
160
|
+
uri: this.absToUri(childPath),
|
|
161
|
+
name: e.name,
|
|
162
|
+
isDir,
|
|
163
|
+
size: indexed?.size ?? s?.size ?? 0,
|
|
164
|
+
modTime: indexed?.modTime ?? s?.mtimeMs ?? 0,
|
|
165
|
+
mimeType: indexed?.mimeType,
|
|
166
|
+
abstract: isDir
|
|
167
|
+
? await readFile(join(childPath, META_ABSTRACT), 'utf-8').catch(() => undefined)
|
|
168
|
+
: undefined,
|
|
169
|
+
};
|
|
170
|
+
}));
|
|
171
|
+
}
|
|
172
|
+
async mkdir(uri) {
|
|
173
|
+
await mkdir(this.toPath(uri), { recursive: true });
|
|
174
|
+
}
|
|
175
|
+
async rmdir(uri, recursive = false) {
|
|
176
|
+
await rm(this.toPath(uri), { recursive, force: true });
|
|
177
|
+
}
|
|
178
|
+
// ── Meta ───────────────────────────────────────────────────────────────────
|
|
179
|
+
async readMeta(uri) {
|
|
180
|
+
const p = this.toPath(uri);
|
|
181
|
+
const [abstract, overview, metaRaw] = await Promise.all([
|
|
182
|
+
readFile(join(p, META_ABSTRACT), 'utf-8').catch(() => undefined),
|
|
183
|
+
readFile(join(p, META_OVERVIEW), 'utf-8').catch(() => undefined),
|
|
184
|
+
readFile(join(p, META_META), 'utf-8').catch(() => undefined),
|
|
185
|
+
]);
|
|
186
|
+
return {
|
|
187
|
+
abstract,
|
|
188
|
+
overview,
|
|
189
|
+
meta: metaRaw ? JSON.parse(metaRaw) : undefined,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
async writeMeta(uri, meta) {
|
|
193
|
+
const p = this.toPath(uri);
|
|
194
|
+
await mkdir(p, { recursive: true });
|
|
195
|
+
const writes = [];
|
|
196
|
+
if (meta.abstract !== undefined)
|
|
197
|
+
writes.push(writeFile(join(p, META_ABSTRACT), meta.abstract, 'utf-8'));
|
|
198
|
+
if (meta.overview !== undefined)
|
|
199
|
+
writes.push(writeFile(join(p, META_OVERVIEW), meta.overview, 'utf-8'));
|
|
200
|
+
if (meta.meta !== undefined)
|
|
201
|
+
writes.push(writeFile(join(p, META_META), JSON.stringify(meta.meta, null, 2), 'utf-8'));
|
|
202
|
+
await Promise.all(writes);
|
|
203
|
+
}
|
|
204
|
+
// ── Relations ──────────────────────────────────────────────────────────────
|
|
205
|
+
async relations(uri) {
|
|
206
|
+
try {
|
|
207
|
+
const raw = await readFile(join(this.toPath(uri), META_RELATIONS), 'utf-8');
|
|
208
|
+
return JSON.parse(raw);
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
async link(uri, targets, reason) {
|
|
215
|
+
const p = this.toPath(uri);
|
|
216
|
+
await mkdir(p, { recursive: true });
|
|
217
|
+
const existing = await this.relations(uri);
|
|
218
|
+
existing.push({
|
|
219
|
+
id: randomUUID(),
|
|
220
|
+
uris: [uri, ...targets],
|
|
221
|
+
reason,
|
|
222
|
+
createdAt: new Date().toISOString(),
|
|
223
|
+
});
|
|
224
|
+
await writeFile(join(p, META_RELATIONS), JSON.stringify(existing, null, 2), 'utf-8');
|
|
225
|
+
if (!this.watcher) {
|
|
226
|
+
this.fire(this.hooks.onLinked?.(uri, targets), 'link');
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
async unlink(uri, target) {
|
|
230
|
+
const existing = await this.relations(uri);
|
|
231
|
+
const filtered = existing.filter(r => !r.uris.includes(target));
|
|
232
|
+
await writeFile(join(this.toPath(uri), META_RELATIONS), JSON.stringify(filtered, null, 2), 'utf-8');
|
|
233
|
+
this.fire(this.hooks.onUnlinked?.(uri, target), 'unlink');
|
|
234
|
+
}
|
|
235
|
+
// ── Search ─────────────────────────────────────────────────────────────────
|
|
236
|
+
async search(query, options) {
|
|
237
|
+
return this.backend.search(query, options);
|
|
238
|
+
}
|
|
239
|
+
// ── Context assembly ───────────────────────────────────────────────────────
|
|
240
|
+
async context(uris, tier) {
|
|
241
|
+
const parts = await Promise.all(uris.map(async (uri) => {
|
|
242
|
+
let body;
|
|
243
|
+
if (tier === 0) {
|
|
244
|
+
const m = await this.readMeta(uri);
|
|
245
|
+
body = m.abstract;
|
|
246
|
+
}
|
|
247
|
+
else if (tier === 1) {
|
|
248
|
+
const m = await this.readMeta(uri);
|
|
249
|
+
body = m.overview ?? m.abstract;
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
body = (await this.read(uri)) ?? undefined;
|
|
253
|
+
}
|
|
254
|
+
return body ? `## ${uri}\n\n${body}` : null;
|
|
255
|
+
}));
|
|
256
|
+
return parts.filter(Boolean).join('\n\n---\n\n');
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=file-fs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-fs.js","sourceRoot":"","sources":["../../../src/core/memo/file-fs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './constants.js';
|
|
3
|
+
export { FileMemo } from './file-fs.js';
|
|
4
|
+
export { MagicMimeDetector } from './mime.js';
|
|
5
|
+
export { SimpleSearchBackend } from './search/text.js';
|
|
6
|
+
export { RipgrepSearchBackend } from './search/ripgrep.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/memo/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAe,cAAc,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAQ,WAAW,CAAA;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './constants.js';
|
|
3
|
+
export { FileMemo } from './file-fs.js';
|
|
4
|
+
export { MagicMimeDetector } from './mime.js';
|
|
5
|
+
export { SimpleSearchBackend } from './search/text.js';
|
|
6
|
+
export { RipgrepSearchBackend } from './search/ripgrep.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/memo/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAe,cAAc,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAQ,WAAW,CAAA;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=memo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memo.d.ts","sourceRoot":"","sources":["../../../src/core/memo/memo.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memo.js","sourceRoot":"","sources":["../../../src/core/memo/memo.ts"],"names":[],"mappings":";AAAA,2CAA2C"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MimeDetector } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* MIME type detector based on magic bytes (file-type).
|
|
4
|
+
* More accurate than extension-based detection since it reads the file header.
|
|
5
|
+
* Returns undefined for plain text files or unrecognised formats.
|
|
6
|
+
*/
|
|
7
|
+
export declare class MagicMimeDetector implements MimeDetector {
|
|
8
|
+
detect(path: string): Promise<string | undefined>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=mime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime.d.ts","sourceRoot":"","sources":["../../../src/core/memo/mime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C;;;;GAIG;AACH,qBAAa,iBAAkB,YAAW,YAAY;IAC9C,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CAIxD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { fileTypeFromFile } from 'file-type';
|
|
2
|
+
/**
|
|
3
|
+
* MIME type detector based on magic bytes (file-type).
|
|
4
|
+
* More accurate than extension-based detection since it reads the file header.
|
|
5
|
+
* Returns undefined for plain text files or unrecognised formats.
|
|
6
|
+
*/
|
|
7
|
+
export class MagicMimeDetector {
|
|
8
|
+
async detect(path) {
|
|
9
|
+
const result = await fileTypeFromFile(path);
|
|
10
|
+
return result?.mime;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=mime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime.js","sourceRoot":"","sources":["../../../src/core/memo/mime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAG5C;;;;GAIG;AACH,MAAM,OAAO,iBAAiB;IAC5B,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAA;QAC3C,OAAO,MAAM,EAAE,IAAI,CAAA;IACrB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/memo/search/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAS,WAAW,CAAA;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/memo/search/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAS,WAAW,CAAA;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SearchBackend, SearchOptions, SearchResult } from '../types.js';
|
|
2
|
+
export declare class RipgrepSearchBackend implements SearchBackend {
|
|
3
|
+
private readonly rgBin;
|
|
4
|
+
private workspace;
|
|
5
|
+
constructor(rgBin?: string);
|
|
6
|
+
init(workspace: string): void;
|
|
7
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
8
|
+
private _toPath;
|
|
9
|
+
private _toUri;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=ripgrep.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ripgrep.d.ts","sourceRoot":"","sources":["../../../../src/core/memo/search/ripgrep.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAW,MAAM,aAAa,CAAA;AActF,qBAAa,oBAAqB,YAAW,aAAa;IAG5C,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFlC,OAAO,CAAC,SAAS,CAAK;gBAEO,KAAK,SAAS;IAE3C,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIvB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAkD7E,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,MAAM;CAIf"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { rgPath } from '@vscode/ripgrep';
|
|
4
|
+
import { META_FILES } from '../constants.js';
|
|
5
|
+
export class RipgrepSearchBackend {
|
|
6
|
+
rgBin;
|
|
7
|
+
workspace = '';
|
|
8
|
+
constructor(rgBin = rgPath) {
|
|
9
|
+
this.rgBin = rgBin;
|
|
10
|
+
}
|
|
11
|
+
init(workspace) {
|
|
12
|
+
this.workspace = workspace;
|
|
13
|
+
}
|
|
14
|
+
async search(query, options) {
|
|
15
|
+
const limit = options?.limit ?? 20;
|
|
16
|
+
const paths = options?.scope?.map(u => this._toPath(u)) ?? [this.workspace];
|
|
17
|
+
const args = [
|
|
18
|
+
query,
|
|
19
|
+
...paths,
|
|
20
|
+
'--json',
|
|
21
|
+
'--max-count', '1',
|
|
22
|
+
...[...META_FILES].flatMap(f => ['--glob', `!${f}`]),
|
|
23
|
+
];
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
const child = spawn(this.rgBin, args);
|
|
26
|
+
const results = [];
|
|
27
|
+
let buffer = '';
|
|
28
|
+
child.stderr.resume(); // drain stderr to prevent buffer blocking
|
|
29
|
+
child.stdout.on('data', (chunk) => {
|
|
30
|
+
buffer += chunk.toString('utf-8');
|
|
31
|
+
const lines = buffer.split('\n');
|
|
32
|
+
buffer = lines.pop() ?? '';
|
|
33
|
+
for (const line of lines) {
|
|
34
|
+
if (!line.trim() || results.length >= limit)
|
|
35
|
+
continue;
|
|
36
|
+
try {
|
|
37
|
+
const msg = JSON.parse(line);
|
|
38
|
+
if (msg.type !== 'match')
|
|
39
|
+
continue;
|
|
40
|
+
results.push({
|
|
41
|
+
uri: this._toUri(msg.data.path.text),
|
|
42
|
+
snippet: msg.data.lines.text.trim(),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch { /* skip malformed lines */ }
|
|
46
|
+
}
|
|
47
|
+
if (results.length >= limit)
|
|
48
|
+
child.kill();
|
|
49
|
+
});
|
|
50
|
+
child.on('close', () => resolve(results));
|
|
51
|
+
child.on('error', err => {
|
|
52
|
+
if (err.code === 'ENOENT') {
|
|
53
|
+
reject(new Error(`ripgrep binary not found: "${this.rgBin}". Try reinstalling @vscode/ripgrep.`));
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
reject(err);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
_toPath(uri) {
|
|
62
|
+
if (!uri.startsWith('memo://'))
|
|
63
|
+
throw new Error(`Invalid memo URI: "${uri}"`);
|
|
64
|
+
return join(this.workspace, uri.slice('memo://'.length));
|
|
65
|
+
}
|
|
66
|
+
_toUri(absPath) {
|
|
67
|
+
const rel = absPath.slice(this.workspace.length).replace(/^[/\\]/, '');
|
|
68
|
+
return `memo://${rel}`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=ripgrep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ripgrep.js","sourceRoot":"","sources":["../../../../src/core/memo/search/ripgrep.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SearchBackend, SearchOptions, SearchResult } from '../types.js';
|
|
2
|
+
export declare class SimpleSearchBackend implements SearchBackend {
|
|
3
|
+
private workspace;
|
|
4
|
+
init(workspace: string): void;
|
|
5
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
6
|
+
private _searchDir;
|
|
7
|
+
private _toPath;
|
|
8
|
+
private _toUri;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../../src/core/memo/search/text.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAW,MAAM,aAAa,CAAA;AAGtF,qBAAa,mBAAoB,YAAW,aAAa;IACvD,OAAO,CAAC,SAAS,CAAK;IAEtB,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIvB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;YAY/D,UAAU;IAoCxB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,MAAM;CAIf"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { readFile, readdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { META_FILES } from '../constants.js';
|
|
4
|
+
export class SimpleSearchBackend {
|
|
5
|
+
workspace = '';
|
|
6
|
+
init(workspace) {
|
|
7
|
+
this.workspace = workspace;
|
|
8
|
+
}
|
|
9
|
+
async search(query, options) {
|
|
10
|
+
const limit = options?.limit ?? 20;
|
|
11
|
+
const roots = options?.scope?.map(u => this._toPath(u)) ?? [this.workspace];
|
|
12
|
+
const results = [];
|
|
13
|
+
for (const root of roots) {
|
|
14
|
+
await this._searchDir(root, query, results, limit);
|
|
15
|
+
if (results.length >= limit)
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
return results;
|
|
19
|
+
}
|
|
20
|
+
async _searchDir(dir, query, results, limit) {
|
|
21
|
+
if (results.length >= limit)
|
|
22
|
+
return;
|
|
23
|
+
let entries;
|
|
24
|
+
try {
|
|
25
|
+
entries = await readdir(dir, { withFileTypes: true, encoding: 'utf8' });
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
for (const e of entries) {
|
|
31
|
+
if (results.length >= limit)
|
|
32
|
+
return;
|
|
33
|
+
const childPath = join(dir, e.name);
|
|
34
|
+
if (e.isDirectory()) {
|
|
35
|
+
await this._searchDir(childPath, query, results, limit);
|
|
36
|
+
}
|
|
37
|
+
else if (!META_FILES.has(e.name)) {
|
|
38
|
+
try {
|
|
39
|
+
const content = await readFile(childPath, 'utf-8');
|
|
40
|
+
const idx = content.toLowerCase().indexOf(query.toLowerCase());
|
|
41
|
+
if (idx === -1)
|
|
42
|
+
continue;
|
|
43
|
+
const start = Math.max(0, idx - 60);
|
|
44
|
+
const end = Math.min(content.length, idx + query.length + 60);
|
|
45
|
+
results.push({ uri: this._toUri(childPath), snippet: content.slice(start, end) });
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// skip binary / unreadable files
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
_toPath(uri) {
|
|
54
|
+
if (!uri.startsWith('memo://'))
|
|
55
|
+
throw new Error(`Invalid memo URI: "${uri}"`);
|
|
56
|
+
return join(this.workspace, uri.slice('memo://'.length));
|
|
57
|
+
}
|
|
58
|
+
_toUri(absPath) {
|
|
59
|
+
const rel = absPath.slice(this.workspace.length).replace(/^[/\\]/, '');
|
|
60
|
+
return `memo://${rel}`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../../../src/core/memo/search/text.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/** memo://user/memories/preferences/coding */
|
|
2
|
+
export type MemoUri = string;
|
|
3
|
+
export type MemoNode = {
|
|
4
|
+
uri: MemoUri;
|
|
5
|
+
name: string;
|
|
6
|
+
isDir: boolean;
|
|
7
|
+
size: number;
|
|
8
|
+
modTime: number;
|
|
9
|
+
mimeType?: string;
|
|
10
|
+
abstract?: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Every directory can carry three meta files:
|
|
14
|
+
* - .abstract.md L0 ~100 tokens, one-sentence summary
|
|
15
|
+
* - .overview.md L1 ~1-2k tokens, navigational overview
|
|
16
|
+
* - .meta.json arbitrary structured metadata
|
|
17
|
+
*
|
|
18
|
+
* Content is always written by the caller; the SDK only stores and retrieves.
|
|
19
|
+
*/
|
|
20
|
+
export type DirMeta = {
|
|
21
|
+
abstract?: string;
|
|
22
|
+
overview?: string;
|
|
23
|
+
meta?: Record<string, unknown>;
|
|
24
|
+
};
|
|
25
|
+
export type Relation = {
|
|
26
|
+
id: string;
|
|
27
|
+
uris: MemoUri[];
|
|
28
|
+
reason?: string;
|
|
29
|
+
createdAt: string;
|
|
30
|
+
};
|
|
31
|
+
export interface MimeDetector {
|
|
32
|
+
detect(path: string): Promise<string | undefined>;
|
|
33
|
+
}
|
|
34
|
+
export type SearchOptions = {
|
|
35
|
+
/** Scope search to these directory URIs. Defaults to entire workspace. */
|
|
36
|
+
scope?: MemoUri[];
|
|
37
|
+
limit?: number;
|
|
38
|
+
};
|
|
39
|
+
export type SearchResult = {
|
|
40
|
+
uri: MemoUri;
|
|
41
|
+
snippet: string;
|
|
42
|
+
};
|
|
43
|
+
export interface SearchBackend {
|
|
44
|
+
/** Called by FileMemo after construction to provide the workspace path. */
|
|
45
|
+
init(workspace: string): void;
|
|
46
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
47
|
+
}
|
|
48
|
+
export type HookEvent = 'write' | 'delete' | 'link' | 'unlink';
|
|
49
|
+
/**
|
|
50
|
+
* All hooks are fire-and-forget: the SDK does not await them.
|
|
51
|
+
* Promise rejections are forwarded to `onError` if provided.
|
|
52
|
+
*/
|
|
53
|
+
export interface MemoHooks {
|
|
54
|
+
/** Called after a content file is written or created. `parentDirs` lists all ancestor directory URIs. */
|
|
55
|
+
onWritten?: (uri: MemoUri, parentDirs: MemoUri[]) => void | Promise<void>;
|
|
56
|
+
/** Called after a content file or directory is deleted. */
|
|
57
|
+
onDeleted?: (uri: MemoUri, parentDirs: MemoUri[]) => void | Promise<void>;
|
|
58
|
+
/** Called after a relation is created. */
|
|
59
|
+
onLinked?: (uri: MemoUri, targets: MemoUri[]) => void | Promise<void>;
|
|
60
|
+
/** Called after a relation is removed. */
|
|
61
|
+
onUnlinked?: (uri: MemoUri, target: MemoUri) => void | Promise<void>;
|
|
62
|
+
/** Catches errors thrown inside any hook. */
|
|
63
|
+
onError?: (err: unknown, event: HookEvent) => void;
|
|
64
|
+
}
|
|
65
|
+
export interface FileMemoOptions {
|
|
66
|
+
workspace: string;
|
|
67
|
+
hooks?: MemoHooks;
|
|
68
|
+
/** Search backend. Defaults to RipgrepSearchBackend. */
|
|
69
|
+
search?: SearchBackend;
|
|
70
|
+
/** MIME type detector. Defaults to MagicMimeDetector (magic bytes). */
|
|
71
|
+
mime?: MimeDetector;
|
|
72
|
+
/**
|
|
73
|
+
* Auto-start filesystem watcher on construction. Default: true.
|
|
74
|
+
* When enabled, hooks fire for ALL filesystem changes and the in-memory
|
|
75
|
+
* index is kept up-to-date automatically.
|
|
76
|
+
*/
|
|
77
|
+
watch?: boolean;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Optional lifecycle interface for implementations that support filesystem
|
|
81
|
+
* watching and direct path access. Separate from Memo so that consumers
|
|
82
|
+
* can depend only on the storage primitives they need.
|
|
83
|
+
*/
|
|
84
|
+
export interface MemoLifecycle extends AsyncDisposable {
|
|
85
|
+
/** Convert a memo URI to an absolute filesystem path (for binary file access). */
|
|
86
|
+
toPath(uri: MemoUri): string;
|
|
87
|
+
/** Start watching the workspace; hooks fire for all filesystem changes. */
|
|
88
|
+
watch(): void;
|
|
89
|
+
/** Stop watching and release resources. */
|
|
90
|
+
unwatch(): Promise<void>;
|
|
91
|
+
}
|
|
92
|
+
export interface Memo {
|
|
93
|
+
read(uri: MemoUri): Promise<string | null>;
|
|
94
|
+
write(uri: MemoUri, content: string): Promise<void>;
|
|
95
|
+
delete(uri: MemoUri): Promise<void>;
|
|
96
|
+
ls(uri: MemoUri): Promise<MemoNode[]>;
|
|
97
|
+
mkdir(uri: MemoUri): Promise<void>;
|
|
98
|
+
rmdir(uri: MemoUri, recursive?: boolean): Promise<void>;
|
|
99
|
+
readMeta(uri: MemoUri): Promise<DirMeta>;
|
|
100
|
+
writeMeta(uri: MemoUri, meta: Partial<DirMeta>): Promise<void>;
|
|
101
|
+
link(uri: MemoUri, targets: MemoUri[], reason?: string): Promise<void>;
|
|
102
|
+
unlink(uri: MemoUri, target: MemoUri): Promise<void>;
|
|
103
|
+
relations(uri: MemoUri): Promise<Relation[]>;
|
|
104
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
105
|
+
/**
|
|
106
|
+
* Build a context string from a list of URIs at the given tier.
|
|
107
|
+
* tier 0 → .abstract.md (L0)
|
|
108
|
+
* tier 1 → .overview.md (L1), falls back to .abstract.md
|
|
109
|
+
* tier 2 → full file content (L2)
|
|
110
|
+
*/
|
|
111
|
+
context(uris: MemoUri[], tier: 0 | 1 | 2): Promise<string>;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/memo/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/memo/types.ts"],"names":[],"mappings":"AAAA,iFAAiF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@devxiyang/agent-memo",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Agent memory and memo SDK",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/devxiyang/agent.memo.git"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"agent",
|
|
12
|
+
"memory",
|
|
13
|
+
"memo",
|
|
14
|
+
"llm",
|
|
15
|
+
"typescript"
|
|
16
|
+
],
|
|
17
|
+
"type": "module",
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"import": "./dist/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./memo": {
|
|
26
|
+
"types": "./dist/core/memo/index.d.ts",
|
|
27
|
+
"import": "./dist/core/memo/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsc -p tsconfig.json",
|
|
35
|
+
"clean": "rm -rf dist",
|
|
36
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"test:watch": "vitest"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/node": "^24.11.0",
|
|
42
|
+
"typescript": "^5.8.0",
|
|
43
|
+
"vitest": "^4.0.18"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@vscode/ripgrep": ">=1.17.0",
|
|
47
|
+
"chokidar": ">=5.0.0",
|
|
48
|
+
"file-type": ">=21.0.0"
|
|
49
|
+
}
|
|
50
|
+
}
|