@log0u7/opencode-memory 0.4.0 → 0.5.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/CHANGELOG.md +72 -0
- package/README.md +13 -9
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/db.d.ts +3 -0
- package/dist/lib/db.d.ts.map +1 -1
- package/dist/lib/db.js +26 -1
- package/dist/lib/db.js.map +1 -1
- package/dist/lib/memory-ops.d.ts +9 -3
- package/dist/lib/memory-ops.d.ts.map +1 -1
- package/dist/lib/memory-ops.js +47 -14
- package/dist/lib/memory-ops.js.map +1 -1
- package/dist/lib/sqlite.d.ts +1 -1
- package/dist/lib/sqlite.d.ts.map +1 -1
- package/dist/lib/sqlite.js +12 -9
- package/dist/lib/sqlite.js.map +1 -1
- package/dist/lib/store.d.ts +39 -1
- package/dist/lib/store.d.ts.map +1 -1
- package/dist/lib/store.js +139 -50
- package/dist/lib/store.js.map +1 -1
- package/dist/options.d.ts +13 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +24 -0
- package/dist/options.js.map +1 -0
- package/dist/plugin-v2.d.ts.map +1 -1
- package/dist/plugin-v2.js +20 -4
- package/dist/plugin-v2.js.map +1 -1
- package/dist/plugin.d.ts +0 -12
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +10 -25
- package/dist/plugin.js.map +1 -1
- package/dist/types/entry.d.ts +4 -0
- package/dist/types/entry.d.ts.map +1 -1
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,78 @@ All notable changes to this project are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.5.1] - 2026-10-24
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- The package loads under OpenCode 2 again. The v1 implementation imports
|
|
15
|
+
`@opencode-ai/plugin`, which only v1 hosts resolve, and it sat in the static
|
|
16
|
+
import graph, so v2 hosts rejected the whole plugin at load time
|
|
17
|
+
(`Cannot find package '@opencode-ai/plugin'`). The v1 entry is now loaded
|
|
18
|
+
lazily from `server()`: a v2 host never calls `server()` and therefore never
|
|
19
|
+
resolves the v1-only packages. The named `MemoryPlugin` export is type-only.
|
|
20
|
+
- Shared option plumbing and the system-guidance/compaction constants moved
|
|
21
|
+
from `plugin.ts` to `options.ts` so the v2 adapter no longer imports the v1
|
|
22
|
+
module statically.
|
|
23
|
+
- New `smoke:dist` script audits the static import graph of `dist/`: no
|
|
24
|
+
`@opencode-ai/*` import may be reachable statically, `plugin.js` must only
|
|
25
|
+
be reached through a dynamic `import()`, and every other bare import must
|
|
26
|
+
be `@opencode/plugin`, a Node builtin, or a declared runtime dependency.
|
|
27
|
+
|
|
28
|
+
## [0.5.0] - 2026-10-20
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- The plugin opened its SQLite store through the `Bun.sqlite` global, which Bun 1.3
|
|
33
|
+
removed: the first `openMemoryDb` threw on every Bun 1.3 runtime, which is what the
|
|
34
|
+
installed OpenCode embeds. It now reads `process.versions.bun` and loads the `bun:sqlite`
|
|
35
|
+
module through the same `createRequire` seam as `node:sqlite`, so one path covers old and
|
|
36
|
+
new Bun. Verified against the built output under Bun 1.3.14 (open, save, search, stats,
|
|
37
|
+
trash and restore).
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
|
|
41
|
+
- `memory_restore` puts a trashed entry back by id, wherever it lived. `memory_forget` now
|
|
42
|
+
trashes instead of dropping, so a wrong delete is recoverable; a sweep hard-deletes trash
|
|
43
|
+
older than 30 days so the trash cannot grow without bound.
|
|
44
|
+
- Entries record the agent that wrote them (`source`; distilled lessons carry
|
|
45
|
+
`reflection`), the session inventory names the writer, and a store created by an earlier
|
|
46
|
+
release gains the column on open instead of failing to read.
|
|
47
|
+
|
|
48
|
+
### Security
|
|
49
|
+
|
|
50
|
+
- The secret guard now refuses the token formats released since it was written: GitHub
|
|
51
|
+
fine-grained PATs (`github_pat_`), the GitHub OAuth and server-to-server classes
|
|
52
|
+
(`gho_`, `ghs_`, `ghu_`, `ghr_`), GitLab rotate tokens (`glrt-`), npm granular tokens
|
|
53
|
+
(`npm_`), AWS temporary key ids (`ASIA`), Google OAuth access tokens (`ya29.`) and Slack
|
|
54
|
+
incoming webhook URLs. The existing `sk-` pattern already covered Anthropic `sk-ant-`
|
|
55
|
+
keys. The three patterns whose tail class allows `_` or `-` (`github_pat_`, `gl(?:pat|rt)-`
|
|
56
|
+
and `ya29.`) additionally require a digit or an uppercase letter in the tail, so a sentence
|
|
57
|
+
written as one long lowercase snake_case or hyphenated token right after a prefix is saved
|
|
58
|
+
instead of being refused as a credential. A run carrying a digit or an uppercase anywhere
|
|
59
|
+
inside the run of the pattern's tail class is still refused: the guard forgives lowercase
|
|
60
|
+
prose only. The older `sk-`, `AIza` and `xox[ap]-` patterns keep their original shape.
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- `memory_search` fuses its two rankings instead of discarding one: entries matching
|
|
65
|
+
every query token come first, then prefix matches fill the remaining slots. A query
|
|
66
|
+
where two entries hold every token used to answer a limit of ten with two results.
|
|
67
|
+
- `memory_save` reports whether it created an entry or rewrote the one already holding that
|
|
68
|
+
scope and title, instead of one undifferentiated receipt: the in-place dedup rewrite is
|
|
69
|
+
no longer silent.
|
|
70
|
+
- `memory_forget` lists the titles and ids it removed (ten named, then a count of the
|
|
71
|
+
rest) instead of only a count, so a broad query delete is auditable. `store.forget`
|
|
72
|
+
now returns the removed entries rather than a number.
|
|
73
|
+
- `memory_stats` reports the store size on disk and the oldest live entry beside the kind
|
|
74
|
+
counts. The store has no size cap and no eviction, so this is the only signal that it is
|
|
75
|
+
growing.
|
|
76
|
+
- Dev-dependency bumps from the Dependabot minor-and-patch group: `@biomejs/biome`
|
|
77
|
+
2.5.15, `@opencode-ai/plugin` 1.18.35 (with the transitive `@opencode-ai/sdk` 1.18.35),
|
|
78
|
+
`lefthook` 2.1.17, and in-range lockfile refreshes (vitest 5.0.3, `@types/node` 26.6.4).
|
|
79
|
+
|
|
8
80
|
## [0.4.0] - 2026-10-14
|
|
9
81
|
|
|
10
82
|
### Added
|
package/README.md
CHANGED
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
|
|
9
9
|
Working memory for [OpenCode](https://opencode.ai): a shared SQLite store that all sessions on a machine read and write, so decisions, facts, and compaction summaries survive session boundaries.
|
|
10
10
|
|
|
11
|
-
Every session gets
|
|
11
|
+
Every session gets six tools (`memory_save`, `memory_search`, `memory_list`, `memory_forget`, `memory_stats`, `memory_restore`). Entries are scoped per project worktree (plus a `global` scope), searched with SQLite FTS5 (BM25 ranking, entries matching every query token first, then prefix matches fill the remaining slots). Recent entries are also injected into the prompt: once per session, and again during compaction. 100% local, no cloud, no API keys.
|
|
12
12
|
|
|
13
13
|
## Safety limits
|
|
14
14
|
|
|
15
15
|
- Results are capped: at most 50 entries per call, and each body is rendered as a 500-character preview. A tool result has a bounded size whatever the model asks for.
|
|
16
16
|
- `memory_save` rewrites an entry that repeats a scope and title instead of stacking duplicates, and purges expired rows.
|
|
17
|
-
- `memory_forget` by query only deletes inside the caller's scope (plus the shared `global` scope); by id it
|
|
18
|
-
- Entries that look like secrets (`sk-…`, `
|
|
17
|
+
- `memory_forget` by query only deletes inside the caller's scope (plus the shared `global` scope); by id it trashes the entry wherever it lives, since ids are globally unique. Either way it reports the titles and ids it removed, so a broad query delete is auditable.
|
|
18
|
+
- Entries that look like secrets (`sk-…`, `github_pat_…`, `gho_…`, `glpat-…`, `xoxb-…`, webhook URLs, …) are refused, in the title, kind, body and tags alike.
|
|
19
19
|
|
|
20
20
|
## Install
|
|
21
21
|
|
|
@@ -33,7 +33,7 @@ The package is installed automatically at startup into opencode's plugin cache (
|
|
|
33
33
|
|
|
34
34
|
```json
|
|
35
35
|
{
|
|
36
|
-
"plugin": ["@log0u7/opencode-memory@0.
|
|
36
|
+
"plugin": ["@log0u7/opencode-memory@0.5.1"]
|
|
37
37
|
}
|
|
38
38
|
```
|
|
39
39
|
|
|
@@ -56,10 +56,11 @@ memory_stats()
|
|
|
56
56
|
| Tool | Args | Description |
|
|
57
57
|
|---|---|---|
|
|
58
58
|
| `memory_save` | `kind`, `title`, `body`, `scope?`, `tags?`, `expires_at?` | Save an entry. Default scope is the session worktree. |
|
|
59
|
-
| `memory_search` | `query`, `scope?`, `limit?` | FTS5 BM25 search;
|
|
59
|
+
| `memory_search` | `query`, `scope?`, `limit?` | FTS5 BM25 search; entries matching every query token first, then prefix matches fill the remaining slots. |
|
|
60
60
|
| `memory_list` | `scope?`, `limit?` | Recent entries, newest first. |
|
|
61
|
-
| `memory_forget` | `id` or `query` |
|
|
62
|
-
| `memory_stats` | `scope?` | Count entries by kind (plus global) with a total
|
|
61
|
+
| `memory_forget` | `id` or `query` | Trash one entry by id, or all matching a query. |
|
|
62
|
+
| `memory_stats` | `scope?` | Count entries by kind (plus global) with a total, plus the store size and oldest entry. |
|
|
63
|
+
| `memory_restore` | `id` | Put a trashed entry back, wherever it lived. |
|
|
63
64
|
|
|
64
65
|
Entry `kind` is free-form; conventions that work well: `decision`, `fact`, `preference`, `gotcha`, `lesson`, `compaction`.
|
|
65
66
|
|
|
@@ -84,9 +85,12 @@ Cost per reflection: ~2k input tokens (the bounded transcript) and at most ~300
|
|
|
84
85
|
### Notes
|
|
85
86
|
|
|
86
87
|
- All sessions on the machine share one store (WAL mode, concurrent-safe).
|
|
87
|
-
- Entries that look like secrets (`sk-…`, `
|
|
88
|
+
- Entries that look like secrets (`sk-…`, `github_pat_…`, `gho_…`, `glpat-…`, `xoxb-…`, webhook URLs, …) are refused, in the title, kind, body and tags.
|
|
88
89
|
- Every repeated `memory_save` of the same title in the same scope rewrites the entry, so the store does not grow with duplicates, and expired rows are purged on save.
|
|
89
|
-
- `memory_forget` by
|
|
90
|
+
- `memory_forget` never destroys anything: both forms move entries to a trash that `memory_restore` brings back by id, and a sweep drops trash older than 30 days. Query deletes still never leave the scope they are called from, so a project cannot fuzzily delete another project's entries, and by id they trash anywhere (ids are globally unique), which keeps closed worktrees cleanable. Both forms report the titles and ids they removed.
|
|
91
|
+
- `memory_save` reports whether it created an entry or rewrote the one already holding that scope and title, so a silent overwrite is visible to the model.
|
|
92
|
+
- `memory_stats` reports the store size on disk and the oldest live entry next to the kind counts. The store has no size cap and no eviction, so this is the only growth signal.
|
|
93
|
+
- Every entry records the agent that wrote it (`source`; distilled lessons carry `reflection`), and the session inventory names the writer, so knowledge from a sibling session or from reflection is distinguishable from what this session wrote.
|
|
90
94
|
- On the first request of a session, the most recent entries are injected into the system prompt as a bounded list (titles only), so the model does not have to remember to search. `memory_search` remains the tool for deeper lookups.
|
|
91
95
|
- On session compaction, the plugin lists the stored entries in the compaction context and asks the compaction prompt to emit durable decisions, so the model summarises from an inventory instead of recall.
|
|
92
96
|
- Injections stay bounded (~1200 characters worst case) and nothing is injected, nor any store file created, when memory is unused.
|
package/dist/index.d.ts
CHANGED
|
@@ -5,16 +5,22 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @packageDocumentation
|
|
7
7
|
*/
|
|
8
|
+
type V1Plugin = typeof import("./plugin.js").MemoryPlugin;
|
|
8
9
|
/**
|
|
9
10
|
* Dual entrypoint: v1 hosts call `server()`, v2 hosts call `setup()`
|
|
10
11
|
* (see https://opencode.ai/v2/docs/build/plugins/migrate-v1).
|
|
12
|
+
*
|
|
13
|
+
* The v1 implementation imports `@opencode-ai/plugin`, which only v1 hosts
|
|
14
|
+
* resolve. It must stay out of the static import graph or v2 hosts reject the
|
|
15
|
+
* whole package at load time, so `server()` loads it lazily; a v2 host never
|
|
16
|
+
* calls `server()` and therefore never resolves it.
|
|
11
17
|
*/
|
|
12
18
|
export declare const pluginModule: {
|
|
13
19
|
id: string;
|
|
14
20
|
setup: (context: import("@opencode/plugin/promise/plugin").Context) => Promise<import("@opencode/plugin/promise/plugin").Cleanup | void> | import("@opencode/plugin/promise/plugin").Cleanup | void;
|
|
15
|
-
server: import("@opencode-ai/plugin").
|
|
21
|
+
server(input: import("@opencode-ai/plugin").PluginInput, options?: import("@opencode-ai/plugin").PluginOptions | undefined): Promise<Awaited<ReturnType<V1Plugin>>>;
|
|
16
22
|
};
|
|
17
23
|
export default pluginModule;
|
|
18
24
|
export type { Entry, EntryInput, EntryKind } from "./types/entry.js";
|
|
19
|
-
export { MemoryPlugin } from "./plugin.js";
|
|
25
|
+
export type { MemoryPlugin } from "./plugin.js";
|
|
20
26
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,KAAK,QAAQ,GAAG,cAAc,aAAa,EAAE,YAAY,CAAC;AAE1D;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY;;;iIAEsB,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;CAIN,CAAC;eAEjE,YAAY;AAE3B,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAErE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,15 +6,21 @@
|
|
|
6
6
|
* @packageDocumentation
|
|
7
7
|
*/
|
|
8
8
|
import { MemoryV2 } from "./plugin-v2.js";
|
|
9
|
-
import { MemoryPlugin } from "./plugin.js";
|
|
10
9
|
/**
|
|
11
10
|
* Dual entrypoint: v1 hosts call `server()`, v2 hosts call `setup()`
|
|
12
11
|
* (see https://opencode.ai/v2/docs/build/plugins/migrate-v1).
|
|
12
|
+
*
|
|
13
|
+
* The v1 implementation imports `@opencode-ai/plugin`, which only v1 hosts
|
|
14
|
+
* resolve. It must stay out of the static import graph or v2 hosts reject the
|
|
15
|
+
* whole package at load time, so `server()` loads it lazily; a v2 host never
|
|
16
|
+
* calls `server()` and therefore never resolves it.
|
|
13
17
|
*/
|
|
14
18
|
export const pluginModule = {
|
|
15
19
|
...MemoryV2,
|
|
16
|
-
server
|
|
20
|
+
async server(...args) {
|
|
21
|
+
const { MemoryPlugin } = await import("./plugin.js");
|
|
22
|
+
return MemoryPlugin(...args);
|
|
23
|
+
},
|
|
17
24
|
};
|
|
18
25
|
export default pluginModule;
|
|
19
|
-
export { MemoryPlugin } from "./plugin.js";
|
|
20
26
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAI1C;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,GAAG,QAAQ;IACX,KAAK,CAAC,MAAM,CAAC,GAAG,IAA0B;QACxC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QACrD,OAAO,YAAY,CAAC,GAAG,IAAI,CAAC,CAAC;IAC/B,CAAC;CAC4E,CAAC;AAEhF,eAAe,YAAY,CAAC"}
|
package/dist/lib/db.d.ts
CHANGED
|
@@ -4,4 +4,7 @@ export type MemoryDb = {
|
|
|
4
4
|
close(): void;
|
|
5
5
|
};
|
|
6
6
|
export declare function openMemoryDb(path: string): MemoryDb;
|
|
7
|
+
/** Size the database occupies on disk, WAL sidecars excluded. The store has no size cap
|
|
8
|
+
* and no eviction, so this is the only signal a caller gets that it is growing. */
|
|
9
|
+
export declare function databaseSizeBytes(db: MemoryDb): number;
|
|
7
10
|
//# sourceMappingURL=db.d.ts.map
|
package/dist/lib/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/lib/db.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/lib/db.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AA4CF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CA4BnD;AAED;mFACmF;AACnF,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,CAItD"}
|
package/dist/lib/db.js
CHANGED
|
@@ -11,7 +11,9 @@ CREATE TABLE IF NOT EXISTS entries (
|
|
|
11
11
|
tags TEXT NOT NULL DEFAULT '[]',
|
|
12
12
|
created_at INTEGER NOT NULL,
|
|
13
13
|
updated_at INTEGER NOT NULL,
|
|
14
|
-
expires_at INTEGER
|
|
14
|
+
expires_at INTEGER,
|
|
15
|
+
source TEXT,
|
|
16
|
+
deleted_at INTEGER
|
|
15
17
|
);
|
|
16
18
|
CREATE VIRTUAL TABLE IF NOT EXISTS entries_fts USING fts5(
|
|
17
19
|
title, body, tags,
|
|
@@ -29,6 +31,9 @@ CREATE TRIGGER IF NOT EXISTS entries_au AFTER UPDATE ON entries BEGIN
|
|
|
29
31
|
END;
|
|
30
32
|
CREATE INDEX IF NOT EXISTS entries_scope_title ON entries(scope, lower(trim(title)));
|
|
31
33
|
`;
|
|
34
|
+
/** Columns added after the first release. `CREATE TABLE IF NOT EXISTS` never adds a column
|
|
35
|
+
* to an existing database, so each one is backfilled on open. */
|
|
36
|
+
const ADDED_COLUMNS = ["source TEXT", "deleted_at INTEGER"];
|
|
32
37
|
// SECURITY.md promises restrictive permissions whatever the user's umask is, so the
|
|
33
38
|
// directory and files are mode-enforced explicitly instead of left to the umask.
|
|
34
39
|
// POSIX only: chmodSync on Windows flips a read-only bit, which would corrupt usage.
|
|
@@ -43,6 +48,7 @@ export function openMemoryDb(path) {
|
|
|
43
48
|
conn.run("PRAGMA journal_mode = WAL");
|
|
44
49
|
conn.run("PRAGMA busy_timeout = 5000");
|
|
45
50
|
conn.exec(SCHEMA);
|
|
51
|
+
addMissingColumns(conn);
|
|
46
52
|
if (POSIX && path !== ":memory:") {
|
|
47
53
|
// Also fixes databases created earlier with a permissive umask.
|
|
48
54
|
chmodSync(path, 0o600);
|
|
@@ -61,4 +67,23 @@ export function openMemoryDb(path) {
|
|
|
61
67
|
}
|
|
62
68
|
return { conn, close: () => conn.close() };
|
|
63
69
|
}
|
|
70
|
+
/** Size the database occupies on disk, WAL sidecars excluded. The store has no size cap
|
|
71
|
+
* and no eviction, so this is the only signal a caller gets that it is growing. */
|
|
72
|
+
export function databaseSizeBytes(db) {
|
|
73
|
+
const pages = db.conn.get("PRAGMA page_count")?.page_count ?? 0;
|
|
74
|
+
const pageSize = db.conn.get("PRAGMA page_size")?.page_size ?? 0;
|
|
75
|
+
return pages * pageSize;
|
|
76
|
+
}
|
|
77
|
+
/** Backfills the columns added since a store was first created, so a database written by
|
|
78
|
+
* an older release opens on the current schema with its rows intact. Idempotent: the
|
|
79
|
+
* second open finds nothing to add. */
|
|
80
|
+
function addMissingColumns(conn) {
|
|
81
|
+
const present = new Set(conn.all("PRAGMA table_info(entries)").map((column) => column.name));
|
|
82
|
+
for (const column of ADDED_COLUMNS) {
|
|
83
|
+
const name = column.split(" ")[0] ?? "";
|
|
84
|
+
if (!present.has(name)) {
|
|
85
|
+
conn.run(`ALTER TABLE entries ADD COLUMN ${column}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
64
89
|
//# sourceMappingURL=db.js.map
|
package/dist/lib/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/lib/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,UAAU,EAAmB,MAAM,aAAa,CAAC;AAO1D,MAAM,MAAM,GAAG
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/lib/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,UAAU,EAAmB,MAAM,aAAa,CAAC;AAO1D,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6Bd,CAAC;AAEF;iEACiE;AACjE,MAAM,aAAa,GAAG,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAC;AAE5D,oFAAoF;AACpF,iFAAiF;AACjF,qFAAqF;AACrF,gFAAgF;AAChF,wDAAwD;AACxD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AAE3C,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClB,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAExB,IAAI,KAAK,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACjC,gEAAgE;QAChE,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvB,KAAK,MAAM,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC;gBACH,SAAS,CAAC,GAAG,IAAI,GAAG,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC;YACvC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,8DAA8D;gBAC9D,uDAAuD;gBACvD,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACvD,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;AAC7C,CAAC;AAED;mFACmF;AACnF,MAAM,UAAU,iBAAiB,CAAC,EAAY;IAC5C,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAyB,mBAAmB,CAAC,EAAE,UAAU,IAAI,CAAC,CAAC;IACxF,MAAM,QAAQ,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAwB,kBAAkB,CAAC,EAAE,SAAS,IAAI,CAAC,CAAC;IACxF,OAAO,KAAK,GAAG,QAAQ,CAAC;AAC1B,CAAC;AAED;;uCAEuC;AACvC,SAAS,iBAAiB,CAAC,IAAgB;IACzC,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,IAAI,CAAC,GAAG,CAAmB,4BAA4B,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CACtF,CAAC;IACF,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,kCAAkC,MAAM,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;AACH,CAAC"}
|
package/dist/lib/memory-ops.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type MemoryDb } from "./db.js";
|
|
2
2
|
export type SaveArgs = {
|
|
3
3
|
kind: string;
|
|
4
4
|
title: string;
|
|
5
5
|
body: string;
|
|
6
6
|
tags?: string[] | undefined;
|
|
7
7
|
expires_at?: number | null | undefined;
|
|
8
|
+
source?: string | undefined;
|
|
8
9
|
};
|
|
9
10
|
export type SearchArgs = {
|
|
10
11
|
query: string;
|
|
@@ -17,14 +18,18 @@ export type ForgetArgs = {
|
|
|
17
18
|
id?: string | undefined;
|
|
18
19
|
query?: string | undefined;
|
|
19
20
|
};
|
|
21
|
+
export type RestoreArgs = {
|
|
22
|
+
id: string;
|
|
23
|
+
};
|
|
20
24
|
/** One shared behaviour behind both plugin entry points. Every operation returns the
|
|
21
25
|
* model-facing text directly, so a caller cannot bypass caps or error handling. */
|
|
22
26
|
export type MemoryOps = {
|
|
23
|
-
save: (args: SaveArgs, scope: string) => string;
|
|
27
|
+
save: (args: SaveArgs, scope: string, source?: string) => string;
|
|
24
28
|
search: (args: SearchArgs, scope: string) => string;
|
|
25
29
|
list: (args: ListArgs, scope: string) => string;
|
|
26
30
|
forget: (args: ForgetArgs, scope: string) => string;
|
|
27
31
|
stats: (scope: string) => string;
|
|
32
|
+
restore: (args: RestoreArgs) => string;
|
|
28
33
|
};
|
|
29
34
|
export declare function createMemoryOps(getDb: () => MemoryDb): MemoryOps;
|
|
30
35
|
/** How much of the store is summarised into a prompt, worst case. */
|
|
@@ -32,10 +37,11 @@ export declare const INVENTORY_MAX_CHARS = 1200;
|
|
|
32
37
|
/** Tool descriptions shared by both entry points so the two hosts cannot drift. */
|
|
33
38
|
export declare const TOOL_DESCRIPTIONS: {
|
|
34
39
|
readonly save: "Save a durable entry to shared working memory (decisions, facts, preferences, gotchas, lessons). Never store credentials.";
|
|
35
|
-
readonly search: "Search shared working memory (all sessions on this machine). Results include this project's scope and global entries.";
|
|
40
|
+
readonly search: "Search shared working memory (all sessions on this machine). Results include this project's scope and global entries: entries matching every query token come first, then entries matching some token as a prefix fill the remaining slots.";
|
|
36
41
|
readonly list: "List recent memory entries for a scope (default: this project), newest first.";
|
|
37
42
|
readonly forget: "Delete memory entries by id (any scope: ids are globally unique), or all entries matching a query. Query deletes stay inside this project's scope (plus global entries); an entry saved under another scope needs its id, or that scope, to be removed.";
|
|
38
43
|
readonly stats: "Count memory entries by kind for this project (plus global entries), with a total. Use it to see how much memory already exists, for example how many lessons reflection has written.";
|
|
44
|
+
readonly restore: "Put a trashed entry back, by id. Deletes are recoverable: memory_forget reports the ids it trashed, and memory_restore brings one of them back. An entry stays restorable for 30 days.";
|
|
39
45
|
};
|
|
40
46
|
/**
|
|
41
47
|
* Produces at most one injection per session key, and only on the first request where
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-ops.d.ts","sourceRoot":"","sources":["../../src/lib/memory-ops.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"memory-ops.d.ts","sourceRoot":"","sources":["../../src/lib/memory-ops.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqB,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAgB3D,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,CAAC;AACF,MAAM,MAAM,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AACvE,MAAM,MAAM,QAAQ,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AACtD,MAAM,MAAM,UAAU,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AACjF,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;mFACmF;AACnF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACjE,MAAM,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACpD,IAAI,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAChD,MAAM,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACpD,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACjC,OAAO,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,MAAM,CAAC;CACxC,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,QAAQ,GAAG,SAAS,CAuEhE;AAmBD,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAIxC,mFAAmF;AACnF,eAAO,MAAM,iBAAiB;aAC5B,IAAI,EAAE,2HAA2H;aACjI,MAAM,EACJ,6OAA6O;aAC/O,IAAI,EAAE,+EAA+E;aACrF,MAAM,EACJ,yPAAyP;aAC3P,KAAK,EACH,uLAAuL;aACzL,OAAO,EACL,wLAAwL;CAClL,CAAC;AAEX;;;;;;GAMG;AACH,wBAAgB,cAAc;kBAGP,MAAM,GAAG,SAAS,WAAW,MAAM,MAAM,GAAG,IAAI,KAAG,MAAM,GAAG,IAAI;;EAgBtF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,QAAQ,EACrB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,IAAI,CA0Bf"}
|
package/dist/lib/memory-ops.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
|
-
import {
|
|
2
|
+
import { databaseSizeBytes } from "./db.js";
|
|
3
|
+
import { forget, list, oldestCreated, renderEntries, restore, saveEntry, search, SecretDetectedError, stats, } from "./store.js";
|
|
3
4
|
export function createMemoryOps(getDb) {
|
|
4
5
|
return {
|
|
5
|
-
save: (args, scope) => run(() => {
|
|
6
|
-
const entry =
|
|
6
|
+
save: (args, scope, source) => run(() => {
|
|
7
|
+
const { entry, created } = saveEntry(getDb(), {
|
|
7
8
|
scope,
|
|
8
9
|
kind: args.kind,
|
|
9
10
|
title: args.title,
|
|
10
11
|
body: args.body,
|
|
11
12
|
tags: args.tags ?? [],
|
|
12
13
|
expires_at: args.expires_at ?? null,
|
|
14
|
+
...(source !== undefined ? { source } : {}),
|
|
13
15
|
});
|
|
14
|
-
return `saved ${entry.id} (${entry.scope})`;
|
|
16
|
+
return `saved ${entry.id} (${entry.scope}, ${created ? "created" : "updated"})`;
|
|
15
17
|
}),
|
|
16
18
|
search: (args, scope) => run(() => {
|
|
17
19
|
const hits = search(getDb(), {
|
|
@@ -29,15 +31,19 @@ export function createMemoryOps(getDb) {
|
|
|
29
31
|
return entries.length === 0 ? "no memory entries" : renderEntries(entries);
|
|
30
32
|
}),
|
|
31
33
|
forget: (args, scope) => run(() => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
const removed = args.id !== undefined
|
|
35
|
+
? forget(getDb(), { id: args.id, scope })
|
|
36
|
+
: args.query !== undefined
|
|
37
|
+
? forget(getDb(), { query: args.query, scope })
|
|
38
|
+
: null;
|
|
39
|
+
if (removed === null) {
|
|
40
|
+
return "provide id or query";
|
|
35
41
|
}
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
return `deleted ${deleted} entr${deleted === 1 ? "y" : "ies"}`;
|
|
42
|
+
if (removed.length === 0) {
|
|
43
|
+
return "deleted 0 entries";
|
|
39
44
|
}
|
|
40
|
-
|
|
45
|
+
const plural = removed.length === 1 ? "y" : "ies";
|
|
46
|
+
return `deleted ${removed.length} entr${plural}: ${renderRemoved(removed)}`;
|
|
41
47
|
}),
|
|
42
48
|
stats: (scope) => run(() => {
|
|
43
49
|
const counts = stats(getDb(), { scope });
|
|
@@ -45,20 +51,46 @@ export function createMemoryOps(getDb) {
|
|
|
45
51
|
return "no memory entries";
|
|
46
52
|
}
|
|
47
53
|
const total = counts.reduce((sum, row) => sum + row.count, 0);
|
|
48
|
-
|
|
54
|
+
const oldest = oldestCreated(getDb(), { scope });
|
|
55
|
+
const size = formatBytes(databaseSizeBytes(getDb()));
|
|
56
|
+
const age = oldest === null ? "" : `, oldest: ${dayOf(oldest)}`;
|
|
57
|
+
return `store: ${size}${age}, ${counts
|
|
58
|
+
.map((row) => `${row.kind}: ${row.count}`)
|
|
59
|
+
.join(", ")}, total: ${total}`;
|
|
60
|
+
}),
|
|
61
|
+
restore: (args) => run(() => {
|
|
62
|
+
const entry = restore(getDb(), { id: args.id });
|
|
63
|
+
return entry === null
|
|
64
|
+
? "no entry with that id"
|
|
65
|
+
: `restored ${JSON.stringify(entry.title)} (${entry.id})`;
|
|
49
66
|
}),
|
|
50
67
|
};
|
|
51
68
|
}
|
|
69
|
+
/** How many removed entries a delete report names before it summarizes the rest, so a
|
|
70
|
+
* broad query delete stays a bounded tool result. */
|
|
71
|
+
const REMOVED_REPORT_MAX = 10;
|
|
72
|
+
function renderRemoved(entries) {
|
|
73
|
+
const listed = entries
|
|
74
|
+
.slice(0, REMOVED_REPORT_MAX)
|
|
75
|
+
.map((entry) => `${JSON.stringify(entry.title)} (${entry.id})`);
|
|
76
|
+
const rest = entries.length - REMOVED_REPORT_MAX;
|
|
77
|
+
return rest > 0 ? `${listed.join(", ")}, and ${rest} more` : listed.join(", ");
|
|
78
|
+
}
|
|
79
|
+
function formatBytes(bytes) {
|
|
80
|
+
const kb = bytes / 1024;
|
|
81
|
+
return kb < 1024 ? `${kb.toFixed(1)} KB` : `${(kb / 1024).toFixed(1)} MB`;
|
|
82
|
+
}
|
|
52
83
|
/** How much of the store is summarised into a prompt, worst case. */
|
|
53
84
|
export const INVENTORY_MAX_CHARS = 1200;
|
|
54
85
|
const INVENTORY_HEADER = "Memory already stored for this project (lessons first, then newest):";
|
|
55
86
|
/** Tool descriptions shared by both entry points so the two hosts cannot drift. */
|
|
56
87
|
export const TOOL_DESCRIPTIONS = {
|
|
57
88
|
save: "Save a durable entry to shared working memory (decisions, facts, preferences, gotchas, lessons). Never store credentials.",
|
|
58
|
-
search: "Search shared working memory (all sessions on this machine). Results include this project's scope and global entries.",
|
|
89
|
+
search: "Search shared working memory (all sessions on this machine). Results include this project's scope and global entries: entries matching every query token come first, then entries matching some token as a prefix fill the remaining slots.",
|
|
59
90
|
list: "List recent memory entries for a scope (default: this project), newest first.",
|
|
60
91
|
forget: "Delete memory entries by id (any scope: ids are globally unique), or all entries matching a query. Query deletes stay inside this project's scope (plus global entries); an entry saved under another scope needs its id, or that scope, to be removed.",
|
|
61
92
|
stats: "Count memory entries by kind for this project (plus global entries), with a total. Use it to see how much memory already exists, for example how many lessons reflection has written.",
|
|
93
|
+
restore: "Put a trashed entry back, by id. Deletes are recoverable: memory_forget reports the ids it trashed, and memory_restore brings one of them back. An entry stays restorable for 30 days.",
|
|
62
94
|
};
|
|
63
95
|
/**
|
|
64
96
|
* Produces at most one injection per session key, and only on the first request where
|
|
@@ -107,7 +139,8 @@ export function memoryInventory(getDb, dbPath, scope) {
|
|
|
107
139
|
const lines = [INVENTORY_HEADER];
|
|
108
140
|
let size = INVENTORY_HEADER.length;
|
|
109
141
|
for (const entry of ordered) {
|
|
110
|
-
const
|
|
142
|
+
const by = entry.source === undefined ? "" : `, by ${entry.source}`;
|
|
143
|
+
const line = `- [${entry.kind}] ${entry.title} (updated ${dayOf(entry.updated_at)}${by})`;
|
|
111
144
|
if (size + line.length + 1 > INVENTORY_MAX_CHARS) {
|
|
112
145
|
break;
|
|
113
146
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-ops.js","sourceRoot":"","sources":["../../src/lib/memory-ops.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-ops.js","sourceRoot":"","sources":["../../src/lib/memory-ops.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/sqlite.d.ts
CHANGED
|
@@ -5,5 +5,5 @@ export interface SqliteConn {
|
|
|
5
5
|
exec(sql: string): void;
|
|
6
6
|
close(): void;
|
|
7
7
|
}
|
|
8
|
-
export declare function openSqlite(path: string): SqliteConn;
|
|
8
|
+
export declare function openSqlite(path: string, load?: (id: string) => unknown): SqliteConn;
|
|
9
9
|
//# sourceMappingURL=sqlite.d.ts.map
|
package/dist/lib/sqlite.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/lib/sqlite.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;IACvD,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IAC5D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC3C,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/lib/sqlite.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;IACvD,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IAC5D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC3C,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;CACf;AAsED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAqB,GAAG,UAAU,CAQhG"}
|
package/dist/lib/sqlite.js
CHANGED
|
@@ -40,16 +40,19 @@ function createBunConn(db) {
|
|
|
40
40
|
},
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
-
// Open a sqlite connection with the runtime's bundled engine: bun:sqlite when
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
// Open a sqlite connection with the runtime's bundled engine: bun:sqlite when running
|
|
44
|
+
// inside OpenCode (Bun), node:sqlite when running under Node (tests, CI).
|
|
45
|
+
// Bun 1.3 removed the Bun.sqlite global and ships the engine as the bun:sqlite module, so
|
|
46
|
+
// the branch reads the runtime version and the module goes through the same createRequire
|
|
47
|
+
// seam either way: the module exists in old and new Bun alike, and a bare require is not
|
|
48
|
+
// defined in the ES module the plugin ships as.
|
|
49
|
+
// The loader is a parameter so tests can supply the module on a runtime that lacks it.
|
|
50
|
+
export function openSqlite(path, load = nodeRequire) {
|
|
51
|
+
if (process.versions.bun !== undefined) {
|
|
52
|
+
const { Database } = load("bun:sqlite");
|
|
53
|
+
return createBunConn(new Database(path));
|
|
49
54
|
}
|
|
50
|
-
|
|
51
|
-
// runtimes without node:sqlite: a bare require is not defined in an ES module.
|
|
52
|
-
const { DatabaseSync } = nodeRequire("node:sqlite");
|
|
55
|
+
const { DatabaseSync } = load("node:sqlite");
|
|
53
56
|
return createPreparedConn(new DatabaseSync(path));
|
|
54
57
|
}
|
|
55
58
|
const nodeRequire = createRequire(import.meta.url);
|
package/dist/lib/sqlite.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/lib/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/lib/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA4B5C,SAAS,kBAAkB,CAAC,EAAsB;IAChD,OAAO;QACL,GAAG,CAAc,GAAW,EAAE,MAAkB;YAC9C,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC7B,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAQ,CAAC;QAC5C,CAAC;QACD,GAAG,CAAc,GAAW,EAAE,MAAkB;YAC9C,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC7B,OAAQ,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAmB,IAAI,IAAI,CAAC;QAChE,CAAC;QACD,GAAG,CAAC,GAAW,EAAE,MAAkB;YACjC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC7B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,GAAW;YACd,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACf,CAAC;QACD,KAAK;YACH,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,EAAqB;IAC1C,OAAO;QACL,GAAG,CAAc,GAAW,EAAE,MAAkB;YAC9C,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAQ,CAAC;QACrD,CAAC;QACD,GAAG,CAAc,GAAW,EAAE,MAAkB;YAC9C,OAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAmB,IAAI,IAAI,CAAC;QACzE,CAAC;QACD,GAAG,CAAC,GAAW,EAAE,MAAkB;YACjC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,GAAW;YACd,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,CAAC;QACD,KAAK;YACH,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC;AAED,sFAAsF;AACtF,0EAA0E;AAC1E,0FAA0F;AAC1F,0FAA0F;AAC1F,yFAAyF;AACzF,gDAAgD;AAChD,uFAAuF;AACvF,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,IAAI,GAA4B,WAAW;IAClF,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,YAAY,CAAqB,CAAC;QAC5D,OAAO,aAAa,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,aAAa,CAAsB,CAAC;IAClE,OAAO,kBAAkB,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC"}
|
package/dist/lib/store.d.ts
CHANGED
|
@@ -12,6 +12,9 @@ export declare const DEFAULT_LIMIT: {
|
|
|
12
12
|
};
|
|
13
13
|
/** Scope used when no worktree and no directory is known, so rows stay addressable. */
|
|
14
14
|
export declare const FALLBACK_SCOPE = "/";
|
|
15
|
+
/** How long a trashed entry stays restorable before a sweep drops it for good. A
|
|
16
|
+
* recoverable delete is worthless if the trash itself grows without bound. */
|
|
17
|
+
export declare const TRASH_RETENTION_MS: number;
|
|
15
18
|
export declare class SecretDetectedError extends Error {
|
|
16
19
|
constructor();
|
|
17
20
|
}
|
|
@@ -33,9 +36,27 @@ export declare function renderEntries(entries: Entry[]): string;
|
|
|
33
36
|
export declare function sweep(db: MemoryDb, options?: {
|
|
34
37
|
now?: number;
|
|
35
38
|
}): number;
|
|
39
|
+
/** Whether a save inserted a row or rewrote the one already holding that scope and
|
|
40
|
+
* title, so a caller can tell the model what actually happened. */
|
|
41
|
+
export type SaveResult = {
|
|
42
|
+
entry: Entry;
|
|
43
|
+
created: boolean;
|
|
44
|
+
};
|
|
36
45
|
export declare function save(db: MemoryDb, input: EntryInput, options?: {
|
|
37
46
|
now?: number;
|
|
38
47
|
}): Entry;
|
|
48
|
+
export declare function saveEntry(db: MemoryDb, input: EntryInput, options?: {
|
|
49
|
+
now?: number;
|
|
50
|
+
}): SaveResult;
|
|
51
|
+
/**
|
|
52
|
+
* Fused search. The strict pass runs first and the prefix pass only fills what is left of
|
|
53
|
+
* the limit, so a query never loses the loose matches it used to discard: two entries
|
|
54
|
+
* holding every token answer a limit of ten with two results today.
|
|
55
|
+
*
|
|
56
|
+
* A strict hit contains every token by construction, so it is definitionally stronger
|
|
57
|
+
* than a prefix hit. Pinning strict above prefix is therefore the correct special case of
|
|
58
|
+
* reciprocal rank fusion, without the score arithmetic.
|
|
59
|
+
*/
|
|
39
60
|
export declare function search(db: MemoryDb, query: {
|
|
40
61
|
query: string;
|
|
41
62
|
scope: string;
|
|
@@ -63,10 +84,27 @@ export declare function stats(db: MemoryDb, query: {
|
|
|
63
84
|
kind: string;
|
|
64
85
|
count: number;
|
|
65
86
|
}>;
|
|
87
|
+
/** Creation date of the oldest live entry in one scope plus `global`, or null when the
|
|
88
|
+
* scope is empty: the store grows without bound, so age is the signal that knowledge is
|
|
89
|
+
* rotting rather than accumulating. */
|
|
90
|
+
export declare function oldestCreated(db: MemoryDb, query: {
|
|
91
|
+
scope: string;
|
|
92
|
+
now?: number;
|
|
93
|
+
}): number | null;
|
|
66
94
|
/**
|
|
67
95
|
* Query deletes stay inside one scope (plus the shared `global` scope): a fuzzy match
|
|
68
96
|
* must never silently hit other projects' entries. Id deletes are machine-wide because
|
|
69
97
|
* the id is globally unique: closed worktrees stay cleanable from any project.
|
|
98
|
+
*
|
|
99
|
+
* Both forms trash instead of dropping, so a wrong delete is recoverable, and both report
|
|
100
|
+
* the entries they moved: a broad query can take many rows at once, and the caller has to
|
|
101
|
+
* be able to say which ones. Only live rows count, so a second delete of the same target
|
|
102
|
+
* is a no-op.
|
|
70
103
|
*/
|
|
71
|
-
export declare function forget(db: MemoryDb, target: ForgetTarget):
|
|
104
|
+
export declare function forget(db: MemoryDb, target: ForgetTarget): Entry[];
|
|
105
|
+
/** Puts a trashed entry back into every read. Machine-wide by id, mirroring the delete it
|
|
106
|
+
* undoes; `null` when the id is not in the trash. */
|
|
107
|
+
export declare function restore(db: MemoryDb, target: {
|
|
108
|
+
id: string;
|
|
109
|
+
}): Entry | null;
|
|
72
110
|
//# sourceMappingURL=store.d.ts.map
|
package/dist/lib/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/lib/store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAK3D,eAAO,MAAM,OAAO,KAAK,CAAC;AAC1B,eAAO,MAAM,QAAQ,KAAK,CAAC;AAC3B,sFAAsF;AACtF,eAAO,MAAM,SAAS,KAAK,CAAC;AAC5B,kFAAkF;AAClF,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC,eAAO,MAAM,aAAa;IAAK,MAAM;IAAM,IAAI;CAAM,CAAC;AAEtD,uFAAuF;AACvF,eAAO,MAAM,cAAc,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/lib/store.ts"],"names":[],"mappings":"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"}
|