@lanonasis/recall-forge 1.1.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.
Files changed (68) hide show
  1. package/.claw/skills/SKILL.md +347 -0
  2. package/CHANGELOG.md +162 -0
  3. package/LICENSE +21 -0
  4. package/README.md +302 -0
  5. package/SETUP.md +190 -0
  6. package/dist/cli-common.d.ts +25 -0
  7. package/dist/cli-common.js +338 -0
  8. package/dist/cli-memory.d.ts +6 -0
  9. package/dist/cli-memory.js +146 -0
  10. package/dist/cli.d.ts +7 -0
  11. package/dist/cli.js +135 -0
  12. package/dist/client.d.ts +116 -0
  13. package/dist/client.js +643 -0
  14. package/dist/config.d.ts +41 -0
  15. package/dist/config.js +125 -0
  16. package/dist/enrichment/capture-filter.d.ts +4 -0
  17. package/dist/enrichment/capture-filter.js +44 -0
  18. package/dist/enrichment/prompt-safety.d.ts +13 -0
  19. package/dist/enrichment/prompt-safety.js +83 -0
  20. package/dist/enrichment/tag-extractor.d.ts +1 -0
  21. package/dist/enrichment/tag-extractor.js +47 -0
  22. package/dist/enrichment/type-detector.d.ts +2 -0
  23. package/dist/enrichment/type-detector.js +95 -0
  24. package/dist/extraction/cli-extract.d.ts +8 -0
  25. package/dist/extraction/cli-extract.js +66 -0
  26. package/dist/extraction/format-adapters.d.ts +8 -0
  27. package/dist/extraction/format-adapters.js +268 -0
  28. package/dist/extraction/index.d.ts +7 -0
  29. package/dist/extraction/index.js +7 -0
  30. package/dist/extraction/jsonl-extractor.d.ts +32 -0
  31. package/dist/extraction/jsonl-extractor.js +207 -0
  32. package/dist/extraction/markdown-extractor.d.ts +23 -0
  33. package/dist/extraction/markdown-extractor.js +228 -0
  34. package/dist/extraction/secret-redactor.d.ts +7 -0
  35. package/dist/extraction/secret-redactor.js +112 -0
  36. package/dist/extraction/sqlite-extractor.d.ts +15 -0
  37. package/dist/extraction/sqlite-extractor.js +245 -0
  38. package/dist/extraction/types.d.ts +50 -0
  39. package/dist/extraction/types.js +1 -0
  40. package/dist/hooks/capture.d.ts +23 -0
  41. package/dist/hooks/capture.js +162 -0
  42. package/dist/hooks/context-engine.d.ts +4 -0
  43. package/dist/hooks/context-engine.js +54 -0
  44. package/dist/hooks/local-fallback.d.ts +5 -0
  45. package/dist/hooks/local-fallback.js +31 -0
  46. package/dist/hooks/recall.d.ts +21 -0
  47. package/dist/hooks/recall.js +123 -0
  48. package/dist/index.d.ts +3 -0
  49. package/dist/index.js +103 -0
  50. package/dist/plugin-sdk-stub.d.ts +53 -0
  51. package/dist/plugin-sdk-stub.js +3 -0
  52. package/dist/privacy/privacy-guard.d.ts +33 -0
  53. package/dist/privacy/privacy-guard.js +130 -0
  54. package/dist/privacy/privacy-log.d.ts +6 -0
  55. package/dist/privacy/privacy-log.js +44 -0
  56. package/dist/tools/memory-forget.d.ts +3 -0
  57. package/dist/tools/memory-forget.js +109 -0
  58. package/dist/tools/memory-get.d.ts +3 -0
  59. package/dist/tools/memory-get.js +46 -0
  60. package/dist/tools/memory-search.d.ts +4 -0
  61. package/dist/tools/memory-search.js +95 -0
  62. package/dist/tools/memory-store.d.ts +5 -0
  63. package/dist/tools/memory-store.js +199 -0
  64. package/openclaw.plugin.json +315 -0
  65. package/package.json +90 -0
  66. package/setup/agents-memory.md +63 -0
  67. package/setup/heartbeat-memory.md +53 -0
  68. package/setup/install.sh +179 -0
package/README.md ADDED
@@ -0,0 +1,302 @@
1
+ # RecallForge
2
+
3
+ **Secret-safe memory and context engine for OpenClaw.**
4
+
5
+ RecallForge fills both OpenClaw plugin slots at once:
6
+
7
+ | Slot | What it does |
8
+ |------|-------------|
9
+ | `plugins.slots.memory` | Persists knowledge across sessions, devices, and agents via LanOnasis MaaS |
10
+ | `plugins.slots.contextEngine` | Builds and injects relevant context into the agent's prompt window on demand |
11
+
12
+ Every piece of content that enters either slot first passes through a 30-pattern secret redactor. Credentials, tokens, private keys, and connection strings are stripped before they reach memory storage or the context window — not as an afterthought, but as the first step in the pipeline.
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ openclaw plugins install @lanonasis/recall-forge
18
+ ```
19
+
20
+ > **Expected install warning:** OpenClaw's static scanner flags any plugin that reads environment variables and makes network requests. You will see:
21
+ > ```
22
+ > WARNING: Environment variable access combined with network send — possible credential harvesting
23
+ > ```
24
+ > This is a false positive with a documented explanation. RecallForge reads exactly two `LANONASIS_*` environment variables and sends requests to `api.lanonasis.com` — the service you configured. The credential resolution chain is documented in the module JSDoc in `dist/client.js`. Source is on [GitHub](https://github.com/thefixer3x/lan-onasis-monorepo/tree/main/apps/lanonasis-maas/packages/recall-forge) if you want to verify.
25
+
26
+ ## How it Works
27
+
28
+ ```
29
+ User prompt
30
+
31
+
32
+ [contextEngine] buildContext(session)
33
+ │ Tiered semantic search: personal → shared namespace
34
+ │ Prompt injection filter
35
+ │ Secret redaction (30+ patterns)
36
+ │ Character budget enforcement
37
+
38
+ Injected context block prepended to prompt
39
+
40
+
41
+ Agent runs
42
+
43
+
44
+ [memory] capture hook (agent_end / before_compaction)
45
+
46
+ ├─ Privacy Guard — Stage 1: secret-redactor (30 patterns — always-on)
47
+ ├─ Privacy Guard — Stage 2: privacy-sdk PII detection/masking
48
+ │ SSN, email, credit card, IBAN, passport, DOB, phone, IP...
49
+ │ Confidence threshold: 0.85 | Luhn + area-code validation
50
+ │ GDPR / CCPA / HIPAA / PCI-DSS compliance tagging
51
+
52
+ │ Capture filter (removes low-signal content)
53
+ │ Type detection + tag extraction + privacy tags
54
+ │ Vector dedup (0.985 threshold)
55
+ │ Privacy metadata written to memory.metadata
56
+
57
+ Memory stored in LanOnasis MaaS
58
+
59
+ ├─ [if localFallback] workspace/memory/YYYY-MM-DD.md (already sanitized)
60
+ └─ [if privacyNotifyUrl] webhook POST — privacy.intervention event
61
+ (action, piiTypes, regulations, timestamp — never content)
62
+ ```
63
+
64
+ The recall hook (`before_agent_start`) and contextEngine are two separate integration surfaces. The recall hook is passive and event-driven. The contextEngine is active — OpenClaw calls `buildContext()` whenever it needs to assemble context, giving RecallForge a direct seat in prompt construction.
65
+
66
+ ### Privacy Shield — What Gets Protected and Where You See It
67
+
68
+ Every memory that passes through a write path is scanned. When an intervention occurs:
69
+
70
+ **On the stored memory** (visible in `openclaw recall list` and `openclaw recall get <id>`):
71
+ ```
72
+ Tags: pii:email privacy:redacted compliant:gdpr
73
+ Metadata: privacy.action = "redacted+masked"
74
+ privacy.piiTypes = ["email"]
75
+ privacy.regulations = ["GDPR", "CCPA"]
76
+ ```
77
+
78
+ **In the daily audit log** (`workspace/memory/privacy/YYYY-MM-DD.md`):
79
+ ```markdown
80
+ | Time | Action | Secrets | PII Types | Sensitivity | Regulations |
81
+ |----------|-----------------|---------|-----------|-------------|-------------|
82
+ | 14:23:01 | redacted+masked | 1 | email | high | GDPR, CCPA |
83
+ ```
84
+
85
+ **Via webhook** (if `privacyNotifyUrl` is set):
86
+ ```json
87
+ {
88
+ "event": "privacy.intervention",
89
+ "plugin": "recall-forge",
90
+ "action": "redacted+masked",
91
+ "piiTypes": ["email"],
92
+ "regulations": ["GDPR", "CCPA"],
93
+ "timestamp": "2026-03-26T14:23:01Z"
94
+ }
95
+ ```
96
+
97
+ ## What Gets Redacted
98
+
99
+ Before content enters memory or context:
100
+
101
+ | Category | Examples |
102
+ |----------|---------|
103
+ | Anthropic keys | `sk-ant-api03-...` |
104
+ | OpenAI keys | `sk-proj-...`, `sk-...` |
105
+ | GitHub tokens | `ghp_...`, `github_pat_...`, `gho_...`, `ghs_...` |
106
+ | Supabase keys | `sbp_...`, `sba_...` |
107
+ | Stripe keys | `sk_live_...`, `pk_live_...`, `sk_test_...`, `whsec_...` |
108
+ | AWS access keys | `AKIA...` |
109
+ | Google API keys | `AIzaSy...` |
110
+ | Notion tokens | `ntn_...`, `secret_...` |
111
+ | LanOnasis keys | `lano_...`, `lns_...` |
112
+ | JWT tokens | `eyJ...` three-part format |
113
+ | PEM private keys | `-----BEGIN ... PRIVATE KEY-----` blocks |
114
+ | Database URLs | `postgres://user:pass@host/db`, `mysql://...`, etc. |
115
+ | Bearer tokens | `Bearer <40+ char token>` |
116
+ | Env assignments | `API_KEY=value`, `export SECRET=value` |
117
+ | Hex secrets | 64+ character hex strings |
118
+ | ElevenLabs keys | `el_...` |
119
+ | Telegram bots | `123456789:AbCdEfGh...` |
120
+
121
+ Matched values are replaced with `[REDACTED_<TYPE>]`. The redaction runs before any network call.
122
+
123
+ ## Configuration
124
+
125
+ Set credentials in `~/.openclaw/.env`:
126
+
127
+ ```bash
128
+ LANONASIS_API_KEY=your_key
129
+ LANONASIS_PROJECT_ID=your_project_id
130
+ ```
131
+
132
+ Or in `~/.openclaw/openclaw.json`:
133
+
134
+ ```json
135
+ {
136
+ "plugins": {
137
+ "allow": ["recall-forge"],
138
+ "slots": {
139
+ "memory": "recall-forge",
140
+ "contextEngine": "recall-forge"
141
+ },
142
+ "entries": {
143
+ "recall-forge": {
144
+ "enabled": true,
145
+ "config": {
146
+ "apiKey": "YOUR_LANONASIS_API_KEY",
147
+ "projectId": "YOUR_PROJECT_ID",
148
+ "agentId": "main",
149
+ "captureMode": "hybrid",
150
+ "autoRecall": true,
151
+ "localFallback": true,
152
+ "searchThreshold": 0.75,
153
+ "dedupeThreshold": 0.985,
154
+ "maxRecallResults": 5,
155
+ "maxRecallChars": 1500,
156
+ "memoryMode": "hybrid",
157
+ "sharedNamespace": "",
158
+ "syncMode": "realtime"
159
+ }
160
+ }
161
+ }
162
+ }
163
+ }
164
+ ```
165
+
166
+ ### Config Reference
167
+
168
+ | Field | Default | Description |
169
+ |-------|---------|-------------|
170
+ | `apiKey` | — | **Required.** LanOnasis API key |
171
+ | `projectId` | — | **Required.** Project ID from dashboard |
172
+ | `baseUrl` | `https://api.lanonasis.com` | API base URL |
173
+ | `agentId` | `main` | Tags memories with this agent ID |
174
+ | `autoRecall` | `true` | Inject memories before each session via recall hook |
175
+ | `recallMode` | `auto` | `auto`: inject automatically. `ondemand`: disable auto-injection, tools still available |
176
+ | `maxRecallChars` | `1500` | Hard cap on injected recall characters. Use `400–600` for Ollama/small-context models |
177
+ | `maxRecallResults` | `5` | Max memories returned per recall |
178
+ | `captureMode` | `hybrid` | `auto`: capture everything. `hybrid`: stricter filter. `explicit`: agent calls `memory_store` directly |
179
+ | `localFallback` | `true` | Write Markdown copies to `workspace/memory/YYYY-MM-DD.md` |
180
+ | `searchThreshold` | `0.75` | Minimum similarity score for recall results. Raise to `0.80` to reduce noise |
181
+ | `dedupeThreshold` | `0.985` | Similarity threshold for `memory_store` duplicate detection |
182
+ | `memoryMode` | `hybrid` | `remote`: cloud only. `local`: filesystem only. `hybrid`: cloud primary with local fallback |
183
+ | `sharedNamespace` | — | Cross-agent shared memory namespace. Empty = disabled |
184
+ | `syncMode` | `realtime` | `realtime`: immediate writes. `batch`: deferred. `manual`: explicit only |
185
+ | `embeddingProvider` | — | Provider for vector embeddings (e.g. `openai`, `ollama`) |
186
+ | `embeddingModel` | — | Embedding model name (e.g. `text-embedding-3-small`) |
187
+ | `embeddingProfileId` | — | Stamped into stored memories for mismatch detection |
188
+ | `privacyMode` | `mask` | PII protection: `mask` (detect + mask), `detect` (scan + tag only), `off` (credentials only) |
189
+ | `privacyLocale` | `US` | PII locale hint: `US`, `UK`, `EU`, `DE`, `FR`, `JP`, `AU`, `CA` |
190
+ | `privacyNotifyUrl` | — | Webhook URL for out-of-band privacy intervention events |
191
+
192
+ ## Context Window Management
193
+
194
+ The contextEngine and recall hook both respect `maxRecallChars`. For **Ollama and small-context models**:
195
+
196
+ ```json
197
+ "recallMode": "ondemand",
198
+ "maxRecallChars": 500,
199
+ "searchThreshold": 0.80,
200
+ "maxRecallResults": 3
201
+ ```
202
+
203
+ `recallMode: "ondemand"` disables the automatic recall hook. The contextEngine continues to respond to on-demand calls from OpenClaw. Memory tools remain available for manual recall.
204
+
205
+ ## Wiring Agent Guidance
206
+
207
+ After install, append the memory snippet to your workspace AGENTS.md:
208
+
209
+ ```bash
210
+ cat "$(openclaw plugins path recall-forge)/setup/agents-memory.md" >> ~/.openclaw/workspace/AGENTS.md
211
+ cat "$(openclaw plugins path recall-forge)/setup/heartbeat-memory.md" >> ~/.openclaw/workspace/HEARTBEAT.md
212
+ ```
213
+
214
+ ## CLI
215
+
216
+ ```bash
217
+ openclaw recall status
218
+ openclaw recall create --title "Title" --content "Content"
219
+ openclaw recall get <id-or-prefix>
220
+ openclaw recall update <id-or-prefix> --title "Updated"
221
+ openclaw recall delete <id-or-prefix> --force
222
+ openclaw recall search "query" --threshold 0.7 --type knowledge --tags alpha,beta
223
+ openclaw recall list --page 1 --sort created_at --order desc
224
+ openclaw recall stats
225
+ ```
226
+
227
+ The CLI accepts full UUIDs or unambiguous 8+ character prefixes for `get`, `update`, and `delete`.
228
+
229
+ ## Extraction
230
+
231
+ Import memories from existing session logs, Markdown docs, or SQLite databases. All extraction passes through the same secret redaction pipeline before storing.
232
+
233
+ **JSONL formats** (auto-detected):
234
+ - `openclaw-session` — nested `{ type: "message", message: { role, content[] } }` session logs
235
+ - `openclaw-cache` — cache-trace records
236
+ - `claude-code` — flat `{ role, content }` session logs
237
+ - `codex` — `{ type: "message", sender }` format
238
+ - `generic` — fallback for any JSON with text fields
239
+
240
+ **Document formats** (auto-detected by extension):
241
+ - `markdown` — `.md` / `.mdx` files, splits by heading sections
242
+ - `sqlite` — `.sqlite` / `.db` files, reads the OpenClaw `chunks` table
243
+
244
+ ```bash
245
+ openclaw recall extract ~/.openclaw/agents/main/sessions/sample.jsonl --dry-run
246
+ openclaw recall extract ~/.openclaw/workspace/SOUL.md --dry-run
247
+ openclaw recall extract ~/.openclaw/memory/main.sqlite --dry-run
248
+ ```
249
+
250
+ ## Agent Tools
251
+
252
+ RecallForge registers four tools always available to the agent:
253
+
254
+ | Tool | Description |
255
+ |------|-------------|
256
+ | `memory_search` | Semantic search through stored memories |
257
+ | `memory_get` | Fetch full memory by ID |
258
+ | `memory_store` | Store or update a memory (with auto-dedup) |
259
+ | `memory_forget` | Delete a memory by ID |
260
+
261
+ ## Cross-Agent Memory
262
+
263
+ When `sharedNamespace` is configured, recall uses a tiered strategy:
264
+
265
+ 1. **Personal** — search scoped to `agentId`
266
+ 2. **Shared** — search scoped to `sharedNamespace`
267
+ 3. **Deduplicate** — merge by memory ID, personal takes priority
268
+ 4. **Cap** — trim to `maxRecallResults`, sorted by similarity
269
+
270
+ Capture routes `knowledge`, `project`, and `reference` type memories to the shared namespace automatically.
271
+
272
+ ## Verification
273
+
274
+ ```bash
275
+ npm run typecheck
276
+ npm run test
277
+ npm run build
278
+ npm run pack:dry-run
279
+ ```
280
+
281
+ For local testing without publishing:
282
+
283
+ ```bash
284
+ cd apps/lanonasis-maas/packages/recall-forge
285
+ npm run build
286
+ openclaw plugins install "$(pwd)" --link --force
287
+ openclaw recall status
288
+ ```
289
+
290
+ ## Publish
291
+
292
+ ```bash
293
+ npm run verify:release
294
+ npm publish --access public
295
+ git tag recall-forge-v$(node -p "require('./package.json').version")
296
+ git push origin main --follow-tags
297
+ ```
298
+
299
+ ## More Docs
300
+
301
+ - [SETUP.md](./SETUP.md) — operator setup guide
302
+ - [CHANGELOG.md](./CHANGELOG.md) — release history
package/SETUP.md ADDED
@@ -0,0 +1,190 @@
1
+ # RecallForge — Operator Setup Guide
2
+
3
+ RecallForge adds cloud-backed semantic memory and a context engine to OpenClaw via LanOnasis MaaS. It registers in both the `memory` and `contextEngine` plugin slots.
4
+
5
+ ## Requirements
6
+
7
+ - OpenClaw `2026.3.1` or newer
8
+ - A LanOnasis API key ([dashboard](https://app.lanonasis.com))
9
+ - A LanOnasis project ID
10
+
11
+ ## Install From npm
12
+
13
+ ```bash
14
+ openclaw plugins install @lanonasis/recall-forge
15
+ ```
16
+
17
+ Then configure in `~/.openclaw/openclaw.json` (see below), or through the OpenClaw install flow if your UI supports manifest prompts.
18
+
19
+ ## Local Development Install
20
+
21
+ ```bash
22
+ cd apps/lanonasis-maas/packages/recall-forge
23
+ npm install
24
+ npm run build
25
+ openclaw plugins install "$(pwd)" --link
26
+ ```
27
+
28
+ After editing source files, re-run `npm run build` before testing — `dist/` must stay current.
29
+
30
+ Or use the helper script:
31
+
32
+ ```bash
33
+ bash setup/install.sh
34
+ ```
35
+
36
+ ## Minimal Configuration
37
+
38
+ Add to `~/.openclaw/openclaw.json`:
39
+
40
+ ```json
41
+ {
42
+ "plugins": {
43
+ "allow": ["recall-forge"],
44
+ "slots": {
45
+ "memory": "recall-forge",
46
+ "contextEngine": "recall-forge"
47
+ },
48
+ "entries": {
49
+ "recall-forge": {
50
+ "enabled": true,
51
+ "config": {
52
+ "apiKey": "YOUR_LANONASIS_API_KEY",
53
+ "projectId": "YOUR_PROJECT_ID",
54
+ "captureMode": "hybrid",
55
+ "localFallback": true,
56
+ "autoRecall": true,
57
+ "agentId": "main",
58
+ "dedupeThreshold": 0.985,
59
+ "privacyMode": "mask",
60
+ "privacyLocale": "US"
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
66
+ ```
67
+
68
+ Note: Both slots (`memory` and `contextEngine`) must point to `recall-forge` for full dual-slot functionality.
69
+
70
+ Optional: add `privacyNotifyUrl` to route intervention events to Slack, n8n, or any webhook receiver:
71
+
72
+ ```json
73
+ "privacyNotifyUrl": "https://hooks.slack.com/services/YOUR/HOOK/URL"
74
+ ```
75
+
76
+ ## Verify the Install
77
+
78
+ ```bash
79
+ openclaw recall status
80
+ openclaw recall create --title "RecallForge test" --content "Hello from RecallForge"
81
+ openclaw recall list --page 1 --sort created_at --order desc
82
+ openclaw recall stats
83
+ ```
84
+
85
+ Expected behavior:
86
+ - `status` — prints connection status, project ID, and server version
87
+ - `create` — prints stored memory ID, title, type, tags, and preview
88
+ - `list` — prints a table of memories
89
+ - `stats` — prints server-side memory stats
90
+
91
+ ## Workspace Snippets
92
+
93
+ ```bash
94
+ cat "$(openclaw plugins path recall-forge)/setup/agents-memory.md" >> ~/.openclaw/workspace/AGENTS.md
95
+ cat "$(openclaw plugins path recall-forge)/setup/heartbeat-memory.md" >> ~/.openclaw/workspace/HEARTBEAT.md
96
+ ```
97
+
98
+ ## CLI Commands
99
+
100
+ Core CRUD:
101
+
102
+ ```bash
103
+ openclaw recall create --title "..." --content "..."
104
+ openclaw recall get <id-or-prefix>
105
+ openclaw recall update <id-or-prefix> --title "..."
106
+ openclaw recall delete <id-or-prefix> --force
107
+ ```
108
+
109
+ Search and listing:
110
+
111
+ ```bash
112
+ openclaw recall search "query" --threshold 0.7 --type knowledge --tags alpha,beta
113
+ openclaw recall list --page 1 --sort created_at --order desc --tags alpha,beta
114
+ openclaw recall stats
115
+ ```
116
+
117
+ Extraction (secret-redacted before storing):
118
+
119
+ ```bash
120
+ openclaw recall extract ./sessions.jsonl --dry-run
121
+ openclaw recall extract ./SOUL.md --dry-run
122
+ openclaw recall extract ~/.openclaw/memory/main.sqlite --dry-run
123
+ ```
124
+
125
+ ## Confirming Dual-Slot Registration
126
+
127
+ When the plugin loads successfully, the startup log shows both slots:
128
+
129
+ ```
130
+ [recall-forge] Ready — slots: memory+contextEngine | mode: hybrid | memory: hybrid | recall: active | shared: off | fallback: true | privacy: mask | project: <project-id>
131
+ ```
132
+
133
+ If only the memory slot is needed, remove `"contextEngine": "recall-forge"` from the slots config — the contextEngine will still be registered internally, but OpenClaw will not route context-build calls to it.
134
+
135
+ ## Secret Redaction Verification
136
+
137
+ To confirm credential redaction is active before a UAT run:
138
+
139
+ ```bash
140
+ openclaw recall create \
141
+ --title "Redaction test" \
142
+ --content "API_KEY=sk-ant-api03-test123456789012345678 postgres://user:password123@localhost/db"
143
+ openclaw recall list --page 1
144
+ ```
145
+
146
+ The stored memory content should show `[REDACTED_ENV_SECRET]` and `[REDACTED_DATABASE_URL]` — not the original values.
147
+
148
+ ## Privacy Guard Verification
149
+
150
+ To confirm the PII layer is active:
151
+
152
+ ```bash
153
+ openclaw recall create \
154
+ --title "PII test" \
155
+ --content "Contact john.doe@example.com or call +1-555-123-4567 for support."
156
+ openclaw recall get <id-from-above>
157
+ ```
158
+
159
+ Expected:
160
+ - `content` shows `j******e@example.com` and masked phone
161
+ - `tags` includes `pii:email`, `pii:phone`
162
+ - `metadata.privacy.action` is `"masked"`
163
+ - `metadata.privacy.regulations` includes `["GDPR", "CCPA"]`
164
+
165
+ To check the daily audit log:
166
+
167
+ ```bash
168
+ cat ~/.openclaw/workspace/memory/privacy/$(date +%Y-%m-%d).md
169
+ ```
170
+
171
+ To test webhook delivery (replace with your endpoint):
172
+
173
+ ```bash
174
+ # Add to config temporarily:
175
+ # "privacyNotifyUrl": "https://webhook.site/your-test-id"
176
+ openclaw recall create --title "Webhook test" --content "SSN: 123-45-6789"
177
+ # Check your webhook.site inbox for the privacy.intervention event
178
+ ```
179
+
180
+ ## Publish Checklist
181
+
182
+ Before publishing a new version:
183
+
184
+ ```bash
185
+ npm run typecheck
186
+ npm run build
187
+ npm pack --dry-run
188
+ ```
189
+
190
+ The tarball must contain `dist/`, `openclaw.plugin.json`, setup assets, README, CHANGELOG, and LICENSE. No `.env` files, local configs, or workspace data.
@@ -0,0 +1,25 @@
1
+ import type { LanListSortField, LanMemory, LanMemoryStats, LanMemoryType, LanSortOrder } from "./client.js";
2
+ export declare const MEMORY_TYPES: LanMemoryType[];
3
+ export declare function exitWithError(error: unknown): never;
4
+ export declare function isNotFoundError(error: unknown): boolean;
5
+ export declare function normalizeTextInput(label: string, value: string | undefined): string | undefined;
6
+ export declare function resolveContentInput(options: {
7
+ content?: string;
8
+ contentFile?: string;
9
+ required?: boolean;
10
+ }): Promise<string | undefined>;
11
+ export declare function parseTags(input: string | undefined): string[] | undefined;
12
+ export declare function parsePositiveInt(flag: string, raw: string | undefined, defaultValue?: number): number | undefined;
13
+ export declare function parseThreshold(raw: string | undefined): number | undefined;
14
+ export declare function parseMemoryType(raw: string | undefined, flag?: string): LanMemoryType | undefined;
15
+ export declare function parseSortField(raw: string | undefined): LanListSortField | undefined;
16
+ export declare function parseSortOrder(raw: string | undefined): LanSortOrder | undefined;
17
+ export declare function requireMemoryId(id: string): string;
18
+ export declare function requireUpdateFields(updates: Record<string, unknown>, message?: string): void;
19
+ export declare function formatPreview(content: string, maxLength?: number): string;
20
+ export declare function memoryTypeOf(memory: LanMemory): string;
21
+ export declare function similarityOf(memory: LanMemory): number | undefined;
22
+ export declare function printMemorySummary(memory: LanMemory, heading: string): void;
23
+ export declare function printMemoryDetail(memory: LanMemory): void;
24
+ export declare function assertMemoryStatsShape(stats: unknown): LanMemoryStats;
25
+ export declare function printMemoryStats(stats: LanMemoryStats): void;