@chendpoc/pi-memory 0.2.3 → 0.3.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 +92 -43
- package/dist/adapters/llm/standalone.js +1 -1
- package/dist/cli/init.js +20 -3
- package/dist/cli/parseArgs.d.ts +5 -2
- package/dist/cli/parseArgs.js +13 -0
- package/dist/cli/schedulerSync.d.ts +2 -0
- package/dist/cli/schedulerSync.js +26 -0
- package/dist/cli/status.d.ts +4 -40
- package/dist/cli/status.js +6 -230
- package/dist/cli/theme.d.ts +2 -0
- package/dist/cli/theme.js +8 -0
- package/dist/cli.js +5 -0
- package/dist/commands/status.js +2 -2
- package/dist/compact/parseMemoryExport.js +2 -1
- package/dist/compact/register.js +1 -1
- package/dist/compact/runSummary.js +1 -16
- package/dist/compact/subagentDelta.js +3 -5
- package/dist/consolidate/index.d.ts +1 -0
- package/dist/consolidate/index.js +1 -0
- package/dist/consolidate/mergeEntries.js +3 -3
- package/dist/consolidate/mergeMemoryEntries.d.ts +8 -0
- package/dist/consolidate/mergeMemoryEntries.js +23 -0
- package/dist/consolidate/mergePrompt.js +2 -2
- package/dist/consolidate/mergeWithLlm.js +2 -2
- package/dist/consolidate/runJob.d.ts +2 -2
- package/dist/consolidate/runJob.js +6 -12
- package/dist/consolidate/scheduler.d.ts +2 -2
- package/dist/consolidate/scheduler.js +1 -1
- package/dist/constants/env.d.ts +1 -0
- package/dist/constants/env.js +1 -0
- package/dist/constants/paths.d.ts +3 -1
- package/dist/constants/paths.js +6 -1
- package/dist/extension/createMemoryRuntime.d.ts +3 -0
- package/dist/extension/createMemoryRuntime.js +203 -0
- package/dist/extension/index.d.ts +2 -0
- package/dist/extension/index.js +1 -0
- package/dist/extension/lifecycle.d.ts +28 -0
- package/dist/extension/lifecycle.js +52 -0
- package/dist/extension/messageUtils.d.ts +4 -0
- package/dist/extension/messageUtils.js +18 -0
- package/dist/extension/types.d.ts +35 -0
- package/dist/extension/types.js +1 -0
- package/dist/index.d.ts +7 -9
- package/dist/index.js +7 -9
- package/dist/pi-extension.js +26 -236
- package/dist/preflight/episodic.js +13 -30
- package/dist/preflight/queryIntent.js +1 -1
- package/dist/preflight/render.js +1 -1
- package/dist/preflight/strip.d.ts +0 -1
- package/dist/preflight/strip.js +0 -24
- package/dist/redaction/index.d.ts +4 -0
- package/dist/redaction/index.js +3 -0
- package/dist/redaction/patterns/constants.d.ts +6 -0
- package/dist/redaction/patterns/constants.js +6 -0
- package/dist/redaction/patterns/crypto.d.ts +3 -0
- package/dist/redaction/patterns/crypto.js +17 -0
- package/dist/redaction/patterns/generic.d.ts +3 -0
- package/dist/redaction/patterns/generic.js +38 -0
- package/dist/redaction/patterns/index.d.ts +16 -0
- package/dist/redaction/patterns/index.js +23 -0
- package/dist/redaction/patterns/llm.d.ts +3 -0
- package/dist/redaction/patterns/llm.js +144 -0
- package/dist/redaction/patterns/platform.d.ts +3 -0
- package/dist/redaction/patterns/platform.js +87 -0
- package/dist/redaction/patterns/types.d.ts +18 -0
- package/dist/redaction/patterns/types.js +1 -0
- package/dist/redaction/redactText.d.ts +9 -0
- package/dist/redaction/redactText.js +31 -0
- package/dist/redaction/types.d.ts +19 -0
- package/dist/redaction/types.js +1 -0
- package/dist/redaction/utils.d.ts +28 -0
- package/dist/redaction/utils.js +106 -0
- package/dist/scheduler/index.d.ts +3 -0
- package/dist/scheduler/index.js +3 -0
- package/dist/scheduler/launchd.d.ts +14 -0
- package/dist/scheduler/launchd.js +69 -0
- package/dist/scheduler/launchdPlist.d.ts +14 -0
- package/dist/scheduler/launchdPlist.js +62 -0
- package/dist/scheduler/sync.d.ts +36 -0
- package/dist/scheduler/sync.js +79 -0
- package/dist/shutdown/enqueue.d.ts +1 -1
- package/dist/shutdown/enqueue.js +2 -5
- package/dist/shutdown/readQueue.js +1 -1
- package/dist/shutdown/runDrainJob.js +8 -37
- package/dist/shutdown/sessionReader.js +1 -14
- package/dist/sidecar/client.d.ts +6 -2
- package/dist/sidecar/client.js +49 -14
- package/dist/{preflight → sidecar}/queryCache.d.ts +1 -1
- package/dist/sidecar/reindexBridge.js +2 -2
- package/dist/sidecar/server/server.js +1 -1
- package/dist/sidecar/server/vec/chunkQuery.d.ts +4 -0
- package/dist/sidecar/server/vec/chunkQuery.js +46 -0
- package/dist/sidecar/server/vec/chunkReindex.d.ts +5 -0
- package/dist/sidecar/server/vec/chunkReindex.js +40 -0
- package/dist/sidecar/server/vec/embeddingCodec.d.ts +2 -0
- package/dist/sidecar/server/vec/embeddingCodec.js +6 -0
- package/dist/sidecar/server/vec/schema.d.ts +20 -0
- package/dist/sidecar/server/vec/schema.js +61 -0
- package/dist/sidecar/server/vec/store.d.ts +2 -13
- package/dist/sidecar/server/vec/store.js +12 -139
- package/dist/sidecar/sidecarManager.js +4 -58
- package/dist/sidecar/spawnLock.d.ts +2 -0
- package/dist/sidecar/spawnLock.js +57 -0
- package/dist/sidecar/syncIndex.d.ts +3 -0
- package/dist/sidecar/syncIndex.js +12 -0
- package/dist/sidecar/warmup.js +1 -1
- package/dist/status/copy.d.ts +2 -0
- package/dist/status/copy.js +2 -0
- package/dist/status/format.d.ts +7 -0
- package/dist/status/format.js +133 -0
- package/dist/status/gather.d.ts +2 -0
- package/dist/status/gather.js +88 -0
- package/dist/status/index.d.ts +4 -0
- package/dist/status/index.js +3 -0
- package/dist/status/types.d.ts +33 -0
- package/dist/status/types.js +1 -0
- package/dist/store/consolidatePort.d.ts +11 -0
- package/dist/store/consolidatePort.js +1 -0
- package/dist/store/index.d.ts +2 -0
- package/dist/store/index.js +1 -0
- package/dist/store/ingestEntries.d.ts +16 -0
- package/dist/store/ingestEntries.js +22 -0
- package/dist/{init/workspace.d.ts → store/initWorkspace.d.ts} +1 -1
- package/dist/{init/workspace.js → store/initWorkspace.js} +7 -5
- package/dist/store/listeners.d.ts +11 -0
- package/dist/store/listeners.js +27 -0
- package/dist/store/markdown/insert.d.ts +3 -0
- package/dist/store/markdown/insert.js +23 -0
- package/dist/store/memoryStore.d.ts +9 -22
- package/dist/store/memoryStore.js +71 -205
- package/dist/store/resolveEntries.d.ts +11 -0
- package/dist/store/resolveEntries.js +23 -0
- package/dist/store/types.d.ts +0 -1
- package/dist/store/writePath.d.ts +20 -0
- package/dist/store/writePath.js +123 -0
- package/dist/ui/memoryStatusWidget.d.ts +4 -8
- package/dist/ui/memoryStatusWidget.js +5 -17
- package/dist/utils/async.d.ts +11 -0
- package/dist/utils/async.js +24 -0
- package/dist/utils/index.d.ts +5 -1
- package/dist/utils/index.js +5 -1
- package/dist/{ipc/jsonlFramer.d.ts → utils/jsonl.d.ts} +1 -1
- package/dist/{ipc/jsonlFramer.js → utils/jsonl.js} +1 -1
- package/dist/utils/memory/index.d.ts +10 -0
- package/dist/utils/memory/index.js +43 -0
- package/dist/utils/paths.d.ts +4 -0
- package/dist/utils/paths.js +13 -3
- package/dist/utils/scheduler.d.ts +1 -1
- package/dist/utils/scheduler.js +6 -6
- package/dist/{preflight/session.d.ts → utils/session/index.d.ts} +1 -0
- package/dist/{preflight/session.js → utils/session/index.js} +5 -2
- package/doc/README-zh.md +445 -0
- package/package.json +9 -4
- package/scripts/postinstall.mjs +11 -1
- package/templates/com.pi.memory.consolidate.plist.example +41 -0
- package/templates/consolidate.cmd.example +15 -0
- package/templates/crontab.example +14 -0
- package/templates/schtasks.example.txt +34 -0
- package/dist/consolidate/entryKey.d.ts +0 -5
- package/dist/consolidate/entryKey.js +0 -4
- /package/dist/{preflight → sidecar}/queryCache.js +0 -0
package/README.md
CHANGED
|
@@ -9,29 +9,37 @@
|
|
|
9
9
|
<a href="doc/README-zh.md">简体中文</a>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Local memory for the [Pi coding agent](https://pi.dev), so Pi can remember your preferences, project conventions, decisions, and open todos across sessions.
|
|
13
13
|
|
|
14
|
-
`pi-memory`
|
|
14
|
+
`pi-memory` keeps long-lived notes in local Markdown, recalls the relevant ones before Pi answers, and redacts common secrets before they are saved. The goal is simple: a new Pi session should start with the context you meant it to remember, without turning memory into an opaque hosted service.
|
|
15
15
|
|
|
16
16
|
## 🧠 What It Does
|
|
17
17
|
|
|
18
|
-
Pi already has compaction for long sessions. That
|
|
18
|
+
Pi already has compaction for long sessions. That helps continue a long conversation; it does not make a future session remember your stable preferences, project rules, prior decisions, or unresolved todos.
|
|
19
19
|
|
|
20
20
|
`pi-memory` fills that gap:
|
|
21
21
|
|
|
22
22
|
```text
|
|
23
|
-
|
|
23
|
+
things worth remembering -> local Markdown memory -> private context for future turns
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
It provides:
|
|
27
27
|
|
|
28
|
-
- ✍️ **
|
|
29
|
-
- 🔁 **
|
|
30
|
-
- 📥 **
|
|
31
|
-
- 🔦 **
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
28
|
+
- ✍️ **Save explicit notes** with `/remember`.
|
|
29
|
+
- 🔁 **Carry durable facts forward** from Pi compaction.
|
|
30
|
+
- 📥 **Recover useful facts from short sessions** with shutdown queue draining.
|
|
31
|
+
- 🔦 **Recall relevant memory before each answer**, privately and automatically.
|
|
32
|
+
- 🛡️ **Redact common secrets and tokens before saving memory**.
|
|
33
|
+
- 📄 **Keep memory inspectable and editable** in Markdown.
|
|
34
|
+
- ☂️ **Degrade gracefully** when recall is unavailable, so Pi can keep working.
|
|
35
|
+
- ⏳ **Keep maintenance out of the interactive turn** with offline cleanup jobs.
|
|
36
|
+
|
|
37
|
+
## 🚀 What's New in 0.3.0
|
|
38
|
+
|
|
39
|
+
- **Safer memory writes**: common API keys, bearer tokens, private keys, service-account JSON, connection URLs, and `.env`-style secrets are redacted before memory is saved.
|
|
40
|
+
- **More reliable recall**: when a Pi turn is cancelled, memory lookup is cancelled with it instead of waiting for an internal timeout.
|
|
41
|
+
- **Clearer status and maintenance output**: `/memory-status`, `pi-memory status`, queue draining, and reindex triggers now report more consistent counts.
|
|
42
|
+
- **Healthier foundation for future releases**: internals were simplified and split into smaller pieces. This is mostly a maintainer-facing change, but it reduces the risk of future feature work.
|
|
35
43
|
|
|
36
44
|
## 📦 Installation
|
|
37
45
|
|
|
@@ -70,12 +78,12 @@ Published npm packages ship precompiled `dist/`; `pi install npm:@chendpoc/pi-me
|
|
|
70
78
|
|
|
71
79
|
### 🌱 Memory workspace (automatic)
|
|
72
80
|
|
|
73
|
-
You usually **do not need to run `pi-memory init` manually**. The
|
|
81
|
+
You usually **do not need to run `pi-memory init` manually**. The memory workspace is prepared automatically and **never overwrites a non-empty `MEMORY.md`**:
|
|
74
82
|
|
|
75
83
|
| When | What happens |
|
|
76
84
|
| --- | --- |
|
|
77
85
|
| **`pnpm install`** | `postinstall` runs `pi-memory init` (or a pre-build fallback) |
|
|
78
|
-
| **First Pi session** |
|
|
86
|
+
| **First Pi session** | Pi verifies or creates the memory workspace |
|
|
79
87
|
| **Manual (optional)** | `pi-memory init` |
|
|
80
88
|
|
|
81
89
|
Run `pi-memory init` explicitly only when:
|
|
@@ -97,42 +105,30 @@ pi-memory init # optional; see above
|
|
|
97
105
|
| New session asks "continue the plan from last time" | Agent has to ask for context or guess from the current repo. | Preflight recalls matching `MEMORY.md` facts and injects private reference context. |
|
|
98
106
|
| User says "remember that this repo uses Vitest" | The fact may stay only in the current session summary. | `/remember` writes a `[user]` entry that consolidate must preserve. |
|
|
99
107
|
| Long session compacts | Compaction helps continue that session but does not create durable cross-session facts. | One dual-purpose compact summary keeps session context and exports durable facts. |
|
|
100
|
-
| Subagent is spawned | It may
|
|
101
|
-
|
|
|
108
|
+
| Subagent is spawned | It may inherit too much context or duplicate the parent session's memory writes. | Subagents receive a smaller scoped memory view by default, reducing noise and duplicate writes. |
|
|
109
|
+
| Memory recall is unavailable | A hard dependency would break the turn. | Pi falls back to Markdown or no memory injection; the model still runs. |
|
|
102
110
|
| Memory grows | A file can become noisy and unbounded. | 150-line `MEMORY.md` cap, `auto-*.md` overflow, consolidate merge/dedupe. |
|
|
103
111
|
|
|
104
112
|
### 🌟 Key Advantages
|
|
105
113
|
|
|
106
|
-
- 📓 **
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
-
|
|
114
|
-
- 👥 **Subagent policy**: root sessions get Memory Cap + Episodic Preflight; subagents get Memory Cap only by default.
|
|
115
|
-
- ☂️ **Graceful fallback**: if sidecar recall is empty, timed out, or unavailable, the turn still runs.
|
|
116
|
-
|
|
117
|
-
### ⚙️ Runtime Choices
|
|
118
|
-
|
|
119
|
-
| Choice | Why it matters |
|
|
120
|
-
| --- | --- |
|
|
121
|
-
| `MEMORY.md` as Ground Truth | Durable memory remains inspectable and editable instead of becoming opaque database state. |
|
|
122
|
-
| UDS JSONL over `node:net` | Local IPC stays private to the machine, avoids HTTP ports, and keeps request/response framing simple. |
|
|
123
|
-
| Spawned sidecar process | Vector query/reindex work is isolated from the Pi extension process; failures degrade to Markdown fallback. |
|
|
124
|
-
| Offline `maintenance` job | Consolidation and shutdown-queue draining can run outside the interactive agent turn. |
|
|
125
|
-
| Bounded Preflight | QueryIntent, sidecar query, cache, and fallback all share a tight latency budget. |
|
|
114
|
+
- 📓 **Auditable memory**: `MEMORY.md` and `auto-*.md` can be opened, reviewed, edited, grepped, copied, or versioned.
|
|
115
|
+
- 🔎 **Context appears before the answer**: Pi gets relevant private memory before the main model responds, so you do not have to manually paste old context.
|
|
116
|
+
- 🔒 **User notes stay protected**: `/remember` entries are marked as user-authored and consolidation must preserve them.
|
|
117
|
+
- 🛡️ **Safer by default**: common secrets and tokens are replaced before they reach durable memory.
|
|
118
|
+
- ☂️ **No hard dependency on recall**: if memory recall is empty, slow, or unavailable, the turn still runs.
|
|
119
|
+
- 💤 **Less interruption**: heavier cleanup runs through maintenance jobs instead of blocking ordinary Pi turns.
|
|
120
|
+
- 🧹 **Bounded growth**: the main memory file stays capped, overflow goes into reviewable files, and consolidation merges duplicates.
|
|
121
|
+
- 👥 **Subagent-aware behavior**: root sessions get fuller recall; subagents use a smaller memory view by default to reduce noise.
|
|
126
122
|
|
|
127
123
|
### ⚖️ Comparison
|
|
128
124
|
|
|
129
|
-
`pi-memory` is not trying to be every memory system. The value is a specific Pi-native loop: Markdown
|
|
125
|
+
`pi-memory` is not trying to be every memory system. The value is a specific Pi-native loop: local Markdown memory, private recall before answers, compaction export, and offline maintenance.
|
|
130
126
|
|
|
131
127
|
| System | Strength | Difference From `@chendpoc/pi-memory` |
|
|
132
128
|
| --- | --- | --- |
|
|
133
|
-
| Cursor Rules / OpenCode `AGENTS.md` | Static project instructions, predictable injection. | Mostly user-authored rules; no automatic durable fact extraction or
|
|
134
|
-
| Claude Code Auto Memory | Agent can write local memory files. | File-based memory, but no
|
|
135
|
-
| `pi-hermes-memory` | Rich Pi package with FTS5, failure memory, correction learning, security scanning. | More automated and feature-heavy;
|
|
129
|
+
| Cursor Rules / OpenCode `AGENTS.md` | Static project instructions, predictable injection. | Mostly user-authored rules; no automatic durable fact extraction or memory recall before every answer. |
|
|
130
|
+
| Claude Code Auto Memory | Agent can write local memory files. | File-based memory, but no Pi-specific compaction/shutdown integration or private recall-before-answer loop. |
|
|
131
|
+
| `pi-hermes-memory` | Rich Pi package with FTS5, failure memory, correction learning, security scanning. | More automated and feature-heavy; `pi-memory` is narrower, more Markdown-first, and focused on private pre-answer recall. |
|
|
136
132
|
| OpenClaw memory-core | Mature file + index design, dreaming, hybrid search, local embeddings. | Broader memory platform; `pi-memory` is narrower and Pi-extension focused. |
|
|
137
133
|
| Mem0 / Zep | Managed memory APIs with hybrid search, graph, temporal modeling. | Stronger retrieval infrastructure, but external service/database oriented and not Markdown-ground-truth first. |
|
|
138
134
|
| Letta | Context engineering with git-backed memory repos and sleep-time compute. | Powerful for autonomous memory management; heavier mental model than Pi's extension lifecycle. |
|
|
@@ -148,10 +144,22 @@ Where other systems are stronger:
|
|
|
148
144
|
|
|
149
145
|
## ⚙️ How It Works
|
|
150
146
|
|
|
147
|
+
### ⚙️ Technical Notes
|
|
148
|
+
|
|
149
|
+
These choices are mainly useful for operators and contributors. They explain how the user-facing behavior stays local, inspectable, and bounded.
|
|
150
|
+
|
|
151
|
+
| Choice | Why it matters |
|
|
152
|
+
| --- | --- |
|
|
153
|
+
| `MEMORY.md` as Ground Truth | Durable memory remains inspectable and editable instead of becoming opaque database state. |
|
|
154
|
+
| UDS JSONL over `node:net` | Local IPC stays private to the machine, avoids HTTP ports, and keeps request/response framing simple. |
|
|
155
|
+
| Spawned sidecar process | Vector query/reindex work is isolated from the Pi extension process; failures degrade to Markdown fallback. |
|
|
156
|
+
| Offline `maintenance` job | Consolidation and shutdown-queue draining can run outside the interactive agent turn. |
|
|
157
|
+
| Bounded Preflight | QueryIntent, sidecar query, cache, and fallback all share a tight latency budget. |
|
|
158
|
+
|
|
151
159
|
### 🏗️ Architecture
|
|
152
160
|
|
|
153
161
|
```text
|
|
154
|
-
Pi extension process
|
|
162
|
+
Pi extension process (MemoryRuntime)
|
|
155
163
|
|- session_start
|
|
156
164
|
| |- initialize MEMORY.md
|
|
157
165
|
| |- start/warm sidecar
|
|
@@ -159,7 +167,7 @@ Pi extension process
|
|
|
159
167
|
| `- preload Memory Cap
|
|
160
168
|
|
|
|
161
169
|
|- before_agent_start / context
|
|
162
|
-
| `- Preflight recall -> <private_memory>
|
|
170
|
+
| `- Preflight recall (AbortSignal-aware sidecar query) -> <private_memory>
|
|
163
171
|
|
|
|
164
172
|
|- /remember
|
|
165
173
|
| `- append [user] Memory Entry
|
|
@@ -214,6 +222,28 @@ Sidecar results
|
|
|
214
222
|
| Shutdown Queue | `session_shutdown` + `pi-memory maintenance` | Only offline, when no compaction summary exists | No during shutdown | Recover facts from short or missed sessions |
|
|
215
223
|
| Consolidate | overflow >= 12, 7 days, or daily cron | Optional | Offline/background | Dedupe, merge, prune obsolete todos |
|
|
216
224
|
|
|
225
|
+
### 🛡️ What Redaction Covers
|
|
226
|
+
|
|
227
|
+
`pi-memory` 0.3.0 redacts likely secrets before durable memory entries are written. This applies to every incremental write path that can persist to `MEMORY.md`, `auto-*.md`, or the derived vector index.
|
|
228
|
+
|
|
229
|
+
Covered write paths:
|
|
230
|
+
|
|
231
|
+
- `/remember`
|
|
232
|
+
- `append` / `appendUser` / `appendIfAbsent` / `appendMany`
|
|
233
|
+
- compaction `Memory Export` ingest
|
|
234
|
+
- shutdown queue drain ingest
|
|
235
|
+
|
|
236
|
+
The MVP focuses on **secrets and tokens**, including common API keys, bearer/JWT values, private-key blocks, service-account JSON, connection URLs, basic-auth URLs, and `.env`-style secret assignments. Matches are replaced with `[REDACTED]`; if nothing meaningful remains after redaction, the memory write is skipped instead of persisting a lone placeholder.
|
|
237
|
+
|
|
238
|
+
Current boundaries:
|
|
239
|
+
|
|
240
|
+
- Redaction is applied to **durable memory entries**, not full Pi session JSONL or LLM request bodies.
|
|
241
|
+
- Existing historical `MEMORY.md` content is not rewritten automatically.
|
|
242
|
+
- PII detection is intentionally out of scope for 0.3.0.
|
|
243
|
+
- Debug logs report hit counts and policy version only; they do not print matched secret material.
|
|
244
|
+
|
|
245
|
+
For contributors, the shared write gate is `prepareEntryForWrite`.
|
|
246
|
+
|
|
217
247
|
## 💾 Data And Memory Format
|
|
218
248
|
|
|
219
249
|
All artifacts live under one memory agent directory.
|
|
@@ -234,6 +264,10 @@ Resolution order:
|
|
|
234
264
|
| `.memory_shutdown_processed.json` | Drain idempotency state |
|
|
235
265
|
| `memory.vec.sqlite` | Derived Vector Index |
|
|
236
266
|
| `memory.sock` | Sidecar Unix domain socket |
|
|
267
|
+
| `logs/maintenance.log` | Scheduled `maintenance --cron` stdout log |
|
|
268
|
+
| `logs/maintenance.err.log` | Scheduled maintenance stderr log (launchd / Windows) |
|
|
269
|
+
|
|
270
|
+
The `logs/` directory is created automatically on **extension `session_start`**, `pi-memory init`, or CLI `maintenance`/`consolidate` — no manual `mkdir` required.
|
|
237
271
|
|
|
238
272
|
Canonical scaffold: [`templates/MEMORY.md.example`](./templates/MEMORY.md.example)
|
|
239
273
|
|
|
@@ -290,6 +324,7 @@ Common variables:
|
|
|
290
324
|
| `PI_MEMORY_MIN_RELEVANCE` | `0.4` | Minimum cosine similarity |
|
|
291
325
|
| `PI_MEMORY_CHUNK_MAX_CHARS` | `512` | Split long entries for indexing; `0` disables |
|
|
292
326
|
| `PI_MEMORY_DEBUG` | unset | `1` prints debug timing logs |
|
|
327
|
+
| `PI_MEMORY_SKIP_SCHEDULER_SYNC` | unset | `1` skips scheduler sync while set, including automatic sync and manual `scheduler sync` |
|
|
293
328
|
|
|
294
329
|
See [`.env.example`](./.env.example) for the full list.
|
|
295
330
|
|
|
@@ -328,13 +363,26 @@ pi-memory init # optional — usually automatic after install + first session
|
|
|
328
363
|
consolidate -> drain-shutdown-queue
|
|
329
364
|
```
|
|
330
365
|
|
|
331
|
-
|
|
366
|
+
**macOS launchd is managed automatically**: `postinstall`, `pi-memory init`, and every Pi **`session_start`** best-effort run `scheduler sync` (failures do not block install or sessions), writing `~/Library/LaunchAgents/com.pi.memory.maintenance.plist` and removing legacy labels (e.g. `dev.pi.memory-consolidate`). You usually do not edit plists by hand.
|
|
367
|
+
|
|
368
|
+
Manual trigger or troubleshooting:
|
|
369
|
+
|
|
370
|
+
```bash
|
|
371
|
+
pi-memory scheduler sync --verbose
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
If `PI_MEMORY_SKIP_SCHEDULER_SYNC=1` is set in the environment, unset it before running the manual sync command.
|
|
375
|
+
|
|
376
|
+
Linux / Windows: install from templates manually:
|
|
332
377
|
|
|
333
|
-
- [`templates/com.pi.memory.consolidate.plist.example`](./templates/com.pi.memory.consolidate.plist.example)
|
|
334
378
|
- [`templates/crontab.example`](./templates/crontab.example)
|
|
335
379
|
- [`templates/consolidate.cmd.example`](./templates/consolidate.cmd.example)
|
|
336
380
|
- [`templates/schtasks.example.txt`](./templates/schtasks.example.txt)
|
|
337
381
|
|
|
382
|
+
macOS reference plist (matches auto-generated job):
|
|
383
|
+
|
|
384
|
+
- [`templates/com.pi.memory.consolidate.plist.example`](./templates/com.pi.memory.consolidate.plist.example)
|
|
385
|
+
|
|
338
386
|
## 🩺 Diagnostics
|
|
339
387
|
|
|
340
388
|
Use `/memory-status` or `pi-memory status` to inspect:
|
|
@@ -389,6 +437,7 @@ The sidecar IPC test opens a Unix domain socket. If it fails with `listen EPERM`
|
|
|
389
437
|
|
|
390
438
|
- [Chinese README](./doc/README-zh.md)
|
|
391
439
|
- [Roadmap](./doc/ROADMAP.md)
|
|
440
|
+
- [Architecture refactor plan](./dev-doc/architecture-refactor-plan.md)
|
|
392
441
|
- [UBIQUITOUS_LANGUAGE.md](./UBIQUITOUS_LANGUAGE.md) - domain glossary
|
|
393
442
|
|
|
394
443
|
## 📜 License
|
package/dist/cli/init.js
CHANGED
|
@@ -1,12 +1,29 @@
|
|
|
1
|
-
import { initializeMemoryWorkspace } from "../
|
|
1
|
+
import { initializeMemoryWorkspace } from "../store/initWorkspace.js";
|
|
2
|
+
import { syncMaintenanceScheduler } from "../scheduler/sync.js";
|
|
2
3
|
export async function runInitCommand(agentDir, log) {
|
|
3
4
|
const result = await initializeMemoryWorkspace(agentDir);
|
|
4
5
|
log.line("agent dir", result.agentDir);
|
|
5
6
|
log.line("memory file", result.memoryFile);
|
|
6
7
|
if (result.skipped) {
|
|
7
8
|
log.warn("MEMORY.md already exists (left unchanged)");
|
|
8
|
-
return 0;
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
else {
|
|
11
|
+
log.success("Created MEMORY.md from pi-memory template");
|
|
12
|
+
}
|
|
13
|
+
const scheduler = await syncMaintenanceScheduler({ agentDir: result.agentDir });
|
|
14
|
+
if (scheduler.status === "synced") {
|
|
15
|
+
if (scheduler.changed) {
|
|
16
|
+
log.success(`launchd job installed (${scheduler.label})`);
|
|
17
|
+
}
|
|
18
|
+
else if (scheduler.bootstrapped) {
|
|
19
|
+
log.success(`launchd job loaded (${scheduler.label})`);
|
|
20
|
+
}
|
|
21
|
+
if (scheduler.removedLegacy.length > 0) {
|
|
22
|
+
log.line("removed legacy", scheduler.removedLegacy.join(", "));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
else if (scheduler.status === "failed") {
|
|
26
|
+
log.warn(`scheduler sync failed (${scheduler.message})`);
|
|
27
|
+
}
|
|
11
28
|
return 0;
|
|
12
29
|
}
|
package/dist/cli/parseArgs.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type CliCommand = "consolidate" | "maintenance" | "drain-shutdown-queue" | "init" | "status" | "help";
|
|
1
|
+
export type CliCommand = "consolidate" | "maintenance" | "drain-shutdown-queue" | "init" | "status" | "scheduler-sync" | "help";
|
|
2
2
|
export type CommonCliOptions = {
|
|
3
3
|
agentDir?: string;
|
|
4
4
|
verbose: boolean;
|
|
@@ -29,6 +29,9 @@ export type ParsedCli = {
|
|
|
29
29
|
} | {
|
|
30
30
|
command: "status";
|
|
31
31
|
options: StatusCliOptions;
|
|
32
|
+
} | {
|
|
33
|
+
command: "scheduler-sync";
|
|
34
|
+
options: CommonCliOptions;
|
|
32
35
|
};
|
|
33
36
|
export declare function parseCliArgs(argv: string[]): ParsedCli;
|
|
34
|
-
export declare const CLI_HELP = "pi-memory \u2014 standalone tools for Pi local memory\n\nUsage:\n pi-memory init [options]\n pi-memory status [options]\n pi-memory maintenance [options]\n pi-memory consolidate [options]\n pi-memory drain-shutdown-queue [options]\n\nCommands:\n init Create MEMORY.md from template when missing or empty\n status Print MEMORY.md, sidecar, and vector index diagnostics\n maintenance Daily job: consolidate, then drain shutdown queue\n consolidate Run consolidate job (dedupe + optional reindex)\n drain-shutdown-queue Ingest durable facts from queued session shutdown metadata\n\nOptions:\n --agent-dir PATH Memory data directory (overrides PI_MEMORY_AGENT_DIR)\n --verbose, -v Extra stderr output (TTY colors when supported)\n\nConsolidate / maintenance:\n --cron Daily OS cron slot (passes cronFired to shouldConsolidate)\n --force Run consolidate even when shouldConsolidate is false\n\nEnvironment:\n PI_MEMORY_ENV_FILE Explicit .env path\n PI_MEMORY_AGENT_DIR Memory data root; default ~/.pi/pi-memory-data\n PI_MEMORY_DEBUG=1 Debug stderr logs (extension preflight + CLI)\n NO_COLOR Disable chalk colors\n\nExamples:\n pi-memory init\n pi-memory status\n pi-memory maintenance --cron --verbose\n pi-memory consolidate --force --verbose\n pi-memory drain-shutdown-queue --verbose\n";
|
|
37
|
+
export declare const CLI_HELP = "pi-memory \u2014 standalone tools for Pi local memory\n\nUsage:\n pi-memory init [options]\n pi-memory status [options]\n pi-memory maintenance [options]\n pi-memory consolidate [options]\n pi-memory drain-shutdown-queue [options]\n pi-memory scheduler sync [options]\n\nCommands:\n init Create MEMORY.md from template when missing or empty\n status Print MEMORY.md, sidecar, and vector index diagnostics\n maintenance Daily job: consolidate, then drain shutdown queue\n consolidate Run consolidate job (dedupe + optional reindex)\n drain-shutdown-queue Ingest durable facts from queued session shutdown metadata\n scheduler sync Install or refresh the OS maintenance scheduler (macOS launchd)\n\nOptions:\n --agent-dir PATH Memory data directory (overrides PI_MEMORY_AGENT_DIR)\n --verbose, -v Extra stderr output (TTY colors when supported)\n\nConsolidate / maintenance:\n --cron Daily OS cron slot (passes cronFired to shouldConsolidate)\n --force Run consolidate even when shouldConsolidate is false\n\nEnvironment:\n PI_MEMORY_ENV_FILE Explicit .env path\n PI_MEMORY_AGENT_DIR Memory data root; default ~/.pi/pi-memory-data\n PI_MEMORY_DEBUG=1 Debug stderr logs (extension preflight + CLI)\n PI_MEMORY_SKIP_SCHEDULER_SYNC=1 Skip automatic launchd install/update\n NO_COLOR Disable chalk colors\n\nExamples:\n pi-memory init\n pi-memory status\n pi-memory maintenance --cron --verbose\n pi-memory consolidate --force --verbose\n pi-memory drain-shutdown-queue --verbose\n";
|
package/dist/cli/parseArgs.js
CHANGED
|
@@ -85,6 +85,16 @@ export function parseCliArgs(argv) {
|
|
|
85
85
|
return parsed;
|
|
86
86
|
return { command: "drain-shutdown-queue", options: parsed };
|
|
87
87
|
}
|
|
88
|
+
if (command === "scheduler") {
|
|
89
|
+
const [subcommand, ...subRest] = rest;
|
|
90
|
+
if (subcommand !== "sync") {
|
|
91
|
+
return { command: "help", error: "Usage: pi-memory scheduler sync" };
|
|
92
|
+
}
|
|
93
|
+
const parsed = parseCommonFlags(subRest, { verbose: false });
|
|
94
|
+
if ("command" in parsed)
|
|
95
|
+
return parsed;
|
|
96
|
+
return { command: "scheduler-sync", options: parsed };
|
|
97
|
+
}
|
|
88
98
|
return { command: "help", error: `Unknown command: ${command}` };
|
|
89
99
|
}
|
|
90
100
|
export const CLI_HELP = `pi-memory — standalone tools for Pi local memory
|
|
@@ -95,6 +105,7 @@ Usage:
|
|
|
95
105
|
pi-memory maintenance [options]
|
|
96
106
|
pi-memory consolidate [options]
|
|
97
107
|
pi-memory drain-shutdown-queue [options]
|
|
108
|
+
pi-memory scheduler sync [options]
|
|
98
109
|
|
|
99
110
|
Commands:
|
|
100
111
|
init Create MEMORY.md from template when missing or empty
|
|
@@ -102,6 +113,7 @@ Commands:
|
|
|
102
113
|
maintenance Daily job: consolidate, then drain shutdown queue
|
|
103
114
|
consolidate Run consolidate job (dedupe + optional reindex)
|
|
104
115
|
drain-shutdown-queue Ingest durable facts from queued session shutdown metadata
|
|
116
|
+
scheduler sync Install or refresh the OS maintenance scheduler (macOS launchd)
|
|
105
117
|
|
|
106
118
|
Options:
|
|
107
119
|
--agent-dir PATH Memory data directory (overrides PI_MEMORY_AGENT_DIR)
|
|
@@ -115,6 +127,7 @@ Environment:
|
|
|
115
127
|
PI_MEMORY_ENV_FILE Explicit .env path
|
|
116
128
|
PI_MEMORY_AGENT_DIR Memory data root; default ~/.pi/pi-memory-data
|
|
117
129
|
PI_MEMORY_DEBUG=1 Debug stderr logs (extension preflight + CLI)
|
|
130
|
+
PI_MEMORY_SKIP_SCHEDULER_SYNC=1 Skip automatic launchd install/update
|
|
118
131
|
NO_COLOR Disable chalk colors
|
|
119
132
|
|
|
120
133
|
Examples:
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { syncMaintenanceScheduler } from "../scheduler/sync.js";
|
|
2
|
+
export async function runSchedulerSyncCommand(agentDir, log) {
|
|
3
|
+
const result = await syncMaintenanceScheduler({ agentDir });
|
|
4
|
+
if (result.status === "skipped") {
|
|
5
|
+
log.warn(`scheduler sync skipped (${result.reason})`);
|
|
6
|
+
return 0;
|
|
7
|
+
}
|
|
8
|
+
if (result.status === "failed") {
|
|
9
|
+
log.error(`scheduler sync failed: ${result.message}`);
|
|
10
|
+
return 1;
|
|
11
|
+
}
|
|
12
|
+
if (result.removedLegacy.length > 0) {
|
|
13
|
+
log.line("removed legacy", result.removedLegacy.join(", "));
|
|
14
|
+
}
|
|
15
|
+
if (result.changed) {
|
|
16
|
+
log.success(`launchd job installed (${result.label})`);
|
|
17
|
+
}
|
|
18
|
+
else if (result.bootstrapped) {
|
|
19
|
+
log.success(`launchd job loaded (${result.label})`);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
log.info(`launchd job unchanged (${result.label})`);
|
|
23
|
+
}
|
|
24
|
+
log.line("plist", result.plistPath);
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
package/dist/cli/status.d.ts
CHANGED
|
@@ -1,43 +1,7 @@
|
|
|
1
|
-
import type { MemoryStats } from "../store/types.js";
|
|
2
|
-
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
3
1
|
import type { CliLog } from "./log.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
warn: (text: string) => string;
|
|
9
|
-
};
|
|
10
|
-
export declare function cliStatusPalette(): StatusPalette;
|
|
11
|
-
export declare function piStatusPalette(theme: Theme): StatusPalette;
|
|
12
|
-
export type MemoryStatusReport = {
|
|
13
|
-
agentDir: string;
|
|
14
|
-
memory: MemoryStats;
|
|
15
|
-
sidecar: {
|
|
16
|
-
socketPath: string;
|
|
17
|
-
running: boolean;
|
|
18
|
-
};
|
|
19
|
-
vectorIndex: {
|
|
20
|
-
dbPath: string;
|
|
21
|
-
exists: boolean;
|
|
22
|
-
generation?: number;
|
|
23
|
-
chunkCount?: number;
|
|
24
|
-
embeddingProvider?: string;
|
|
25
|
-
embeddingModel?: string;
|
|
26
|
-
embeddingDim?: number;
|
|
27
|
-
/** Set when the index file exists but could not be read locally. */
|
|
28
|
-
readError?: string;
|
|
29
|
-
/** Stats came from sidecar RPC rather than opening sqlite in-process. */
|
|
30
|
-
fromSidecar?: boolean;
|
|
31
|
-
};
|
|
32
|
-
embedder: {
|
|
33
|
-
provider: string;
|
|
34
|
-
model: string;
|
|
35
|
-
dim: number;
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
export declare function gatherMemoryStatus(agentDir: string): Promise<MemoryStatusReport>;
|
|
39
|
-
export declare function formatMemoryStatusSummary(report: MemoryStatusReport, palette: StatusPalette, accent: (text: string) => string): string;
|
|
40
|
-
export declare function formatMemoryStatusLines(report: MemoryStatusReport): string[];
|
|
41
|
-
export declare function formatMemoryStatusTuiLines(report: MemoryStatusReport, palette: StatusPalette, theme: Theme): string[];
|
|
2
|
+
import type { MemoryStatusReport } from "../status/types.js";
|
|
3
|
+
export type { MemoryStatusReport, StatusPalette } from "../status/types.js";
|
|
4
|
+
export { gatherMemoryStatus } from "../status/gather.js";
|
|
5
|
+
export { formatMemoryStatusLines, formatMemoryStatusSummary, formatMemoryStatusTuiLines, piStatusPalette, } from "../status/format.js";
|
|
42
6
|
export declare function printMemoryStatus(report: MemoryStatusReport, log: CliLog): void;
|
|
43
7
|
export declare function runStatusCommand(agentDir: string, log: CliLog): Promise<number>;
|