plugmem 0.1.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.
Files changed (2) hide show
  1. package/README.md +136 -0
  2. package/package.json +49 -0
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # plugmem-napi
2
+
3
+ > ⚠️ Experimental. plugmem is mostly an AI-built experiment — written with
4
+ > the help of a small local model (Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf) and various
5
+ > Claude models, in roughly equal measure. Expect non-professional design
6
+ > choices, rough edges, broken behavior, or mistakes. Use it at your own risk.
7
+
8
+ `plugmem-napi` is the **native Node.js addon** for the plugmem
9
+ [temporal-memory engine](https://docs.rs/plugmem-core/latest) — it embeds
10
+ [`plugmem-host`](https://docs.rs/plugmem-host/latest) **in the Node process**
11
+ (real mmap, file locking, cross-process MVCC — the whole engine, unchanged) and
12
+ exposes it to **JavaScript / TypeScript** as a `Plugmem` class. It is published
13
+ to npm as **`plugmem`**.
14
+
15
+ Because it is native (not WebAssembly), there is no whole-file-in-RAM copy and no
16
+ 4 GiB ceiling: the OS pages the snapshot in and out exactly as it does for the
17
+ Rust library. It loads in **Node, and any N-API host (Deno, Bun)**.
18
+
19
+ ## Install
20
+
21
+ ```console
22
+ $ npm install plugmem
23
+ ```
24
+
25
+ `npm i plugmem` pulls the meta package, which through `optionalDependencies`
26
+ installs only the prebuilt binary for your platform — one of
27
+ `plugmem-{linux-x64-gnu, linux-arm64-gnu, darwin-x64, darwin-arm64,
28
+ win32-x64-msvc, win32-arm64-msvc}`. No toolchain, no build step.
29
+
30
+ ## Which door is this?
31
+
32
+ plugmem is **embedded-first, like SQLite**. Pick the door for your language:
33
+
34
+ | You are… | Use | Why |
35
+ |---|---|---|
36
+ | **writing JavaScript / TypeScript for Node** | **`plugmem-napi`** (this, npm `plugmem`) | The engine *in your Node process*, native speed, typed for TS. |
37
+ | **writing Rust** | [`plugmem-host`](https://docs.rs/plugmem-host/latest) | The engine in your process, like linking SQLite. |
38
+ | **an agent, or another language** (Python, Go…) | [`plugmem-mcp`](https://docs.rs/plugmem-mcp/latest) | A long-lived stdio JSON-RPC sidecar; language-independent. |
39
+ | a person at a **terminal / script** | [`plugmem-cli`](https://docs.rs/plugmem-cli/latest) | The human door. |
40
+
41
+ So: **Node/TS → napi; Rust → host; an agent or other language → MCP; a human →
42
+ the CLI.**
43
+
44
+ ## Usage (TypeScript)
45
+
46
+ Every argument and result is typed — napi generates `index.d.ts`, so a TS host
47
+ gets full autocomplete and checking:
48
+
49
+ ```typescript
50
+ import { Plugmem } from "plugmem";
51
+
52
+ const db = new Plugmem("agent.plugmem"); // or { readOnly: true }
53
+
54
+ const out = db.remember({
55
+ text: "prefers tokio",
56
+ entity: "user",
57
+ tags: ["pref"],
58
+ links: [{ rel: "works_at", entity: "acme" }],
59
+ metadata: { source: "chat", uri: "s3://bucket/note.txt" }, // opaque; a pointer
60
+ });
61
+ out.id; // number
62
+ out.similar; // Similar[] — the engine surfaces conflicts, you decide
63
+
64
+ const res = db.recall({ query: "runtime?", k: 5 });
65
+ res.rendered; // the prompt-ready block
66
+ res.facts; // RecalledFact[] — { id, score, entity, recordedAt, … }
67
+
68
+ const card = db.get(out.id);
69
+ card.metadata; // Record<string,string> — keys sorted, {} when none
70
+
71
+ db.revise(out.id, { text: "prefers async-std" });
72
+ db.link({ src: "user", rel: "works_at", dst: "acme" });
73
+
74
+ await db.checkpoint(); // async (see below)
75
+ db.close(); // release the file + lock explicitly
76
+ ```
77
+
78
+ ## Configuration & embeddings
79
+
80
+ The constructor resolves settings **exactly like the CLI and MCP server**: an
81
+ explicit `config` path wins, else `$PLUGMEM_CONFIG`, else
82
+ `$XDG_CONFIG_HOME/plugmem/config.toml`, else all defaults.
83
+
84
+ ```typescript
85
+ const db = new Plugmem("agent.plugmem", { config: "./plugmem.toml" });
86
+ ```
87
+
88
+ ```toml
89
+ # plugmem.toml
90
+ [engine]
91
+ dim = 768 # embedding size (0 = vectors off)
92
+
93
+ [embedder] # optional — omit for lexical/tag/graph/time only
94
+ kind = "ollama" # or openai / lmstudio / vllm / llamacpp
95
+ url = "http://localhost:11434/v1/embeddings"
96
+ model = "nomic-embed-text"
97
+ ```
98
+
99
+ With an `[embedder]`, a text-only `remember`/`recall` **auto-embeds** — the
100
+ provider's HTTP call runs outside the engine lock. Without one, there is no
101
+ embedder and vector recall is skipped (lexical, tag, graph and time recall still
102
+ answer). The optional `dim` open option sets the embedding size when there is no
103
+ config; if the config configured an embedder, its dimension governs and `dim`
104
+ must agree. A `{ readOnly: true }` handle never auto-embeds — pass a vector.
105
+
106
+ ## The verbs
107
+
108
+ Method names mirror `plugmem-host`'s `Database` one-to-one.
109
+
110
+ **Writer** (default): `remember`, `recall`, `revise(id, args)`, `forget(id)`,
111
+ `link`, `get(id)`, `stats`, `export`, `verify`, and the two **async** verbs
112
+ below. **Read-only** (`{ readOnly: true }`, observing another process's writer):
113
+ `recall`, `get`, `stats`, `export`, `verify`, plus `generation()` (the pinned
114
+ snapshot generation) and `refresh()` (advance to the writer's latest checkpoint);
115
+ the write verbs throw.
116
+
117
+ **No `import` verb** — bulk-loading a `backup.jsonl` reads a file on disk, which
118
+ is [`plugmem-cli import`](https://docs.rs/plugmem-cli/latest)'s job. An agent
119
+ remembers facts one at a time as the conversation goes.
120
+
121
+ ## Async and concurrency (no tokio)
122
+
123
+ `maintain()` and `checkpoint()` do real disk I/O (compaction, HNSW build,
124
+ fsync), so they return a **`Promise`** and run on the **libuv** thread pool —
125
+ they never block the event loop. Every other verb is microsecond-fast in memory
126
+ and stays synchronous (a Promise there would be pure overhead). There is no async
127
+ runtime: the engine is CPU-bound, and the one thing that can wait — a remote
128
+ embedder's HTTP call — happens outside the engine lock.
129
+
130
+ `close()` releases the file and its lock; every verb afterwards throws, and it is
131
+ idempotent (the handle is also released on garbage collection, but `close()`
132
+ makes the moment explicit — e.g. before reopening the same file read-only).
133
+
134
+ ## License
135
+
136
+ MIT.
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "plugmem",
3
+ "version": "0.1.3",
4
+ "description": "Native Node.js addon for plugmem: an embedded long-term memory engine for LLM agents (remember / recall / revise / forget over one local file).",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/m62624/plugmem.git"
8
+ },
9
+ "license": "MIT",
10
+ "main": "index.js",
11
+ "types": "index.d.ts",
12
+ "files": [
13
+ "index.js",
14
+ "index.d.ts"
15
+ ],
16
+ "napi": {
17
+ "name": "plugmem",
18
+ "triples": {
19
+ "defaults": false,
20
+ "additional": [
21
+ "x86_64-unknown-linux-gnu",
22
+ "aarch64-unknown-linux-gnu",
23
+ "x86_64-apple-darwin",
24
+ "aarch64-apple-darwin",
25
+ "x86_64-pc-windows-msvc",
26
+ "aarch64-pc-windows-msvc"
27
+ ]
28
+ }
29
+ },
30
+ "engines": {
31
+ "node": ">= 16"
32
+ },
33
+ "devDependencies": {
34
+ "@napi-rs/cli": "^2.18.4"
35
+ },
36
+ "scripts": {
37
+ "build": "napi build --platform --release",
38
+ "build:debug": "napi build --platform",
39
+ "test": "node --test __test__/*.test.mjs"
40
+ },
41
+ "optionalDependencies": {
42
+ "plugmem-linux-x64-gnu": "0.1.3",
43
+ "plugmem-linux-arm64-gnu": "0.1.3",
44
+ "plugmem-darwin-x64": "0.1.3",
45
+ "plugmem-darwin-arm64": "0.1.3",
46
+ "plugmem-win32-x64-msvc": "0.1.3",
47
+ "plugmem-win32-arm64-msvc": "0.1.3"
48
+ }
49
+ }