@ectplsm/relic 0.1.3 → 0.2.0

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 (36) hide show
  1. package/README.md +261 -167
  2. package/dist/adapters/shells/claude-hook.d.ts +6 -3
  3. package/dist/adapters/shells/claude-hook.js +13 -10
  4. package/dist/adapters/shells/claude-shell.js +4 -2
  5. package/dist/adapters/shells/codex-hook.d.ts +6 -3
  6. package/dist/adapters/shells/codex-hook.js +13 -10
  7. package/dist/adapters/shells/codex-shell.js +4 -2
  8. package/dist/adapters/shells/gemini-hook.d.ts +6 -3
  9. package/dist/adapters/shells/gemini-hook.js +13 -10
  10. package/dist/adapters/shells/gemini-shell.js +4 -2
  11. package/dist/core/usecases/extract.d.ts +5 -23
  12. package/dist/core/usecases/extract.js +19 -115
  13. package/dist/core/usecases/index.d.ts +3 -3
  14. package/dist/core/usecases/index.js +3 -3
  15. package/dist/core/usecases/inject.d.ts +8 -3
  16. package/dist/core/usecases/inject.js +31 -12
  17. package/dist/core/usecases/sync.d.ts +44 -20
  18. package/dist/core/usecases/sync.js +182 -56
  19. package/dist/interfaces/cli/commands/claw.d.ts +2 -0
  20. package/dist/interfaces/cli/commands/claw.js +149 -0
  21. package/dist/interfaces/cli/commands/config.js +6 -6
  22. package/dist/interfaces/cli/commands/extract.js +7 -12
  23. package/dist/interfaces/cli/commands/inject.js +2 -2
  24. package/dist/interfaces/cli/commands/sync.js +24 -68
  25. package/dist/interfaces/cli/index.js +2 -6
  26. package/dist/interfaces/mcp/index.js +14 -0
  27. package/dist/shared/config.d.ts +7 -7
  28. package/dist/shared/config.js +18 -58
  29. package/dist/shared/engram-composer.js +5 -3
  30. package/dist/shared/openclaw.d.ts +25 -3
  31. package/dist/shared/openclaw.js +48 -4
  32. package/package.json +3 -2
  33. package/templates/engrams/johnny/IDENTITY.md +25 -0
  34. package/templates/engrams/johnny/SOUL.md +35 -0
  35. package/templates/engrams/motoko/IDENTITY.md +25 -0
  36. package/templates/engrams/motoko/SOUL.md +38 -0
package/README.md CHANGED
@@ -11,49 +11,30 @@
11
11
  /_/ |_/_____/_____/___/\____/
12
12
  ```
13
13
 
14
- **Inject AI personas into any coding CLI.**
14
+ **Inject a unified AI persona with persistent memory into any coding CLI.**
15
15
 
16
- Relic manages AI personalities (called **Engrams**) and injects them into coding assistants like Claude Code, Gemini CLI, Codex CLI. One persona, any shell.
16
+ Relic manages AI **Engrams** (memory + personality) and injects them into coding assistants like Claude Code, Codex CLI, Gemini CLI. Also integrates with OpenClaw and other Claw-based agent frameworks. One persona, any shell.
17
17
 
18
- ```bash
19
- # Initialize Relic (creates ~/.relic/ with sample Engrams)
20
- relic init
21
-
22
- # Set a default Engram once
23
- relic config default-engram johnny
24
-
25
- # Launch Claude Code as Johnny — no flags needed
26
- relic claude
18
+ ## Table of Contents
27
19
 
28
- # Or specify explicitly
29
- relic claude --engram motoko
30
- ```
31
-
32
- ## How It Works
20
+ - [Install](#install)
21
+ - [Quick Start](#quick-start)
22
+ - [What `relic init` Creates](#what-relic-init-creates)
23
+ - [Sample Engrams](#sample-engrams)
24
+ - [How It Works](#how-it-works)
25
+ - [Supported Shells](#supported-shells)
26
+ - [Conversation Log Recording](#conversation-log-recording)
27
+ - [MCP Server](#mcp-server)
28
+ - [Claw Integration](#claw-integration)
29
+ - [Memory Management](#memory-management)
30
+ - [Configuration](#configuration)
31
+ - [Creating Your Own Engram](#creating-your-own-engram)
32
+ - [Domain Glossary](#domain-glossary)
33
+ - [Roadmap](#roadmap)
33
34
 
34
- ```
35
- +--------------+ +--------------+ +--------------+
36
- | Mikoshi | | Relic | | Shell |
37
- | (backend) | | (injector) | | (AI CLI) |
38
- +--------------+ +--------------+ +--------------+
39
- | | |
40
- +---------+ compose & +---------+
41
- | Engram |------> inject ------------->|Construct|
42
- |(persona)| | (live) |
43
- +---------+ +---------+
44
- SOUL.md claude
45
- IDENTITY.md gemini
46
- MEMORY.md codex
47
- ...
48
- ```
49
-
50
- 1. **Engram** — A persona defined as a set of Markdown files (OpenClaw-compatible)
51
- 2. **Relic** — Reads the Engram, composes it into a prompt, and injects it into...
52
- 3. **Shell** — Any AI coding CLI. The persona takes over the session.
53
- 4. **Construct** — A live process where an Engram is loaded into a Shell. The running instance of a persona.
54
- 5. **Mikoshi** — Cloud backend where Engrams are stored and synced (planned).
35
+ ## Install
55
36
 
56
- ## Installation
37
+ <img alt="version badge" src="https://img.shields.io/github/v/release/ectplsm/relic?filter=*.*.*">
57
38
 
58
39
  ```bash
59
40
  npm install -g @ectplsm/relic
@@ -74,17 +55,54 @@ relic show motoko
74
55
 
75
56
  # Launch a Shell (uses default Engram if --engram is omitted)
76
57
  relic claude
77
- relic gemini
78
58
  relic codex
59
+ relic gemini
79
60
 
80
61
  # Or specify explicitly
81
62
  relic claude --engram motoko
82
- relic gemini --engram johnny
63
+ relic codex --engram johnny
64
+ ```
65
+
66
+ ## What `relic init` Creates
67
+
68
+ Running `relic init` creates `~/.relic/`, writes `config.json`, and seeds two sample Engrams under `~/.relic/engrams/`.
69
+
83
70
  ```
71
+ ~/.relic/
72
+ ├── config.json
73
+ └── engrams/
74
+ ├── johnny/
75
+ │ ├── engram.json
76
+ │ ├── SOUL.md
77
+ │ ├── IDENTITY.md
78
+ │ └── memory/
79
+ │ └── YYYY-MM-DD.md
80
+ └── motoko/
81
+ ├── engram.json
82
+ ├── SOUL.md
83
+ ├── IDENTITY.md
84
+ └── memory/
85
+ └── YYYY-MM-DD.md
86
+ ```
87
+
88
+ - `config.json` stores global Relic settings such as `engramsPath`, `defaultEngram`, `clawPath`, and `memoryWindowSize`.
89
+ - `engrams/<id>/` is one Engram workspace. This is where persona files and memory for that Engram live.
90
+ - `engram.json` stores metadata like the Engram's ID, display name, description, and tags.
91
+ - `SOUL.md` and `IDENTITY.md` define the persona itself.
92
+ - `memory/YYYY-MM-DD.md` stores dated distilled memory entries. `relic init` seeds an initial memory file for each sample Engram.
93
+
94
+ As you keep using an Engram, more files are added to the same workspace:
95
+
96
+ - `archive.md` is created inside `engrams/<id>/` when shell hooks start logging raw conversation turns.
97
+ - `MEMORY.md` can be created or extended when especially important distilled facts are promoted to long-term memory.
98
+ - `USER.md` is created or updated during memory distillation to record user preferences, tendencies, and work style.
99
+ - `~/.relic/hooks/` and `~/.relic/gemini-system-default.md` are created later on first shell launch when hook registration or Gemini prompt caching is needed.
84
100
 
85
101
  ## Sample Engrams
86
102
 
87
- `relic init` seeds two ready-to-use Engrams:
103
+ `relic init` seeds two ready-to-use Engrams. Their SOUL.md and IDENTITY.md follow the [OpenClaw](https://github.com/openclaw/openclaw) format.
104
+
105
+ > **Existing users:** The latest templates are always available in [`templates/engrams/`](templates/engrams/). Copy them over your `~/.relic/engrams/` files to update.
88
106
 
89
107
  ### Johnny Silverhand (`johnny`)
90
108
 
@@ -110,13 +128,62 @@ Best for: system design, code review, debugging sessions, when precision matters
110
128
  relic claude --engram motoko
111
129
  ```
112
130
 
131
+ ## How It Works
132
+
133
+ ```
134
+ +--------------+ +--------------+ +--------------+
135
+ | Mikoshi | | Relic | | Shell |
136
+ | (backend) | | (injector) | | (AI CLI) |
137
+ +--------------+ +--------------+ +--------------+
138
+ ^ | |
139
+ | sync full Engram |
140
+ | | |
141
+ | compose & inject |
142
+ | v v
143
+ | ╔═══════════╗ +---------+
144
+ +------------║ Engram ║--------->|Construct|
145
+ | ║ (persona) ║ | (live) |
146
+ | ╚═══════════╝ +---------+
147
+ | SOUL.md claude / codex / gemini
148
+ | IDENTITY.md |
149
+ | USER.md | hooks append logs
150
+ | MEMORY.md |
151
+ | memory/*.md v
152
+ | +-----------+
153
+ inject / |archive.md |
154
+ extract / | raw logs |
155
+ sync +-----------+
156
+ | |
157
+ v MCP recall | user-triggered
158
+ +-----------+ search/pending | distillation
159
+ | OpenClaw | v
160
+ | & Claws | +-----------+
161
+ +-----------+ | distilled |
162
+ |memory/*.md|
163
+ +-----------+
164
+ |
165
+ promote key
166
+ insights
167
+ v
168
+ MEMORY.md / USER.md
169
+ ```
170
+
171
+ 1. **Engram** — A persona defined as a set of Markdown files (OpenClaw workspace-compatible). The central data that everything else revolves around.
172
+ 2. **Relic** — Reads the Engram, composes it into a prompt, and injects it into...
173
+ 3. **Shell** — Any AI coding CLI. The persona takes over the session.
174
+ 4. **Construct** — A live process where an Engram is loaded into a Shell. The running instance of a persona.
175
+ 5. **archive.md** — Raw conversation logs appended automatically by background hooks after each turn.
176
+ 6. **Memory Distillation** — The user triggers distillation; the Construct recalls pending archive entries via MCP, writes distilled insights to `memory/*.md`, and can promote especially important facts to `MEMORY.md` or update user preferences in `USER.md`.
177
+ 7. **OpenClaw & Claws** — Engrams can be injected into, extracted from, and synced with OpenClaw and other Claw-based agent frameworks via `relic claw`.
178
+ 8. **Mikoshi** — Cloud backend where the full Engram is stored and synced, including persona files plus distilled memory (planned).
179
+
113
180
  ## Supported Shells
114
181
 
115
182
  | Shell | Command | Injection Method |
116
183
  |-------|---------|-----------------|
117
184
  | [Claude Code](https://github.com/anthropics/claude-code) | `relic claude` | `--system-prompt` (direct override) |
118
- | [Gemini CLI](https://github.com/google-gemini/gemini-cli) | `relic gemini` | `GEMINI_SYSTEM_MD` (system prompt) |
119
185
  | [Codex CLI](https://github.com/openai/codex) | `relic codex` | `-c developer_instructions` (developer-role message) |
186
+ | [Gemini CLI](https://github.com/google-gemini/gemini-cli) | `relic gemini` | `GEMINI_SYSTEM_MD` (system prompt) |
120
187
 
121
188
  All shell commands support:
122
189
  - `--engram <id>` — Engram to inject (optional if `defaultEngram` is configured)
@@ -125,18 +192,60 @@ All shell commands support:
125
192
 
126
193
  Extra arguments are passed through to the underlying CLI.
127
194
 
195
+ ## Conversation Log Recording
196
+
197
+ Using each shell's `hook` mechanism, conversation content is appended to `archive.md` after every prompt and response.
198
+
199
+ The following hooks are used for each shell:
200
+
201
+ | Shell | Hook |
202
+ |-------|------|
203
+ | [Claude Code](https://github.com/anthropics/claude-code) | Stop hook |
204
+ | [Codex CLI](https://github.com/openai/codex) | Stop hook |
205
+ | [Gemini CLI](https://github.com/google-gemini/gemini-cli) | AfterAgent hook |
206
+
207
+ #### Claude Code
208
+
209
+ On the **first run** of `relic claude`, a one-time setup happens automatically:
210
+
211
+ - **Stop hook** — registers `~/.relic/hooks/claude-stop.js` in `~/.claude/settings.json` to log each conversation turn directly to the archive, without going through the LLM
212
+
213
+ #### Codex CLI
214
+
215
+ On the **first run** of `relic codex`, a one-time setup happens automatically:
216
+
217
+ - **Stop hook** — registers `~/.relic/hooks/codex-stop.js` in `~/.codex/hooks.json` to log each conversation turn directly to the archive, without going through the LLM
218
+
219
+ > **Note:** Codex hooks require the experimental feature flag `features.codex_hooks=true`. This is automatically enabled by `relic codex` on every launch via `-c features.codex_hooks=true`. If the unstable feature warning is distracting, add the following to `~/.codex/config.toml`:
220
+ >
221
+ > ```toml
222
+ > # Must be at the top level (not under any [section])
223
+ > suppress_unstable_features_warning = true
224
+ > ```
225
+
226
+ #### Gemini CLI
227
+
228
+ On the **first run** of `relic gemini`, two one-time setups happen automatically:
229
+
230
+ 1. **AfterAgent hook** — registers `~/.relic/hooks/gemini-after-agent.js` in `~/.gemini/settings.json` to log each conversation turn without going through the LLM
231
+ 2. **Default system prompt cache** — captures Gemini CLI's built-in system prompt to `~/.relic/gemini-system-default.md` via `GEMINI_WRITE_SYSTEM_MD`
232
+
233
+ The Engram persona is then appended to the cached default prompt and injected via `GEMINI_SYSTEM_MD` on every launch.
234
+
128
235
  ## MCP Server
129
236
 
130
237
  Relic's [MCP](https://modelcontextprotocol.io/) server is paired with CLI injection to handle memory recall.
131
- Session logs and memory entries are written automatically by a **background hook** — without going through the LLM. Memory recall, on the other hand, is performed via the MCP server.
238
+ Session logs and memory entries are written automatically by a **background hook** — without going through the LLM. Memory distillation and recall, on the other hand, is performed via the MCP server.
132
239
 
133
- ```
134
- relic xxx --engram johnny → injects persona into AI CLI
135
- relic-mcp (MCP server) → provides the Construct with memory recall
136
- Stop hook (Claude Code) → logs each turn directly to archive, bypassing the LLM
137
- AfterAgent hook (Gemini CLI) → logs each turn directly to archive, bypassing the LLM
138
- Stop hook (Codex CLI) → logs each turn directly to archive, bypassing the LLM
139
- ```
240
+ ### Available Tools
241
+
242
+ | Tool | Description |
243
+ |------|-------------|
244
+ | `relic_archive_search` | Search the Engram's raw archive by keyword (newest-first) |
245
+ | `relic_archive_pending` | Get un-distilled archive entries since the last distillation (up to 30) |
246
+ | `relic_memory_write` | Write distilled memory to `memory/*.md`, optionally append to `MEMORY.md`, optionally update `USER.md`, and advance the archive cursor |
247
+
248
+ Session logs are written automatically by background hooks (Stop hook for Claude Code and Codex CLI, AfterAgent hook for Gemini CLI). Memory distillation is triggered by the user — ask the Construct to "organize memories" and it will fetch pending entries, distill key insights, and write them to `memory/*.md`. Especially important facts can be promoted to `MEMORY.md` (long-term memory included in every session) via the `long_term` parameter. User tendencies and preferences can be updated in `USER.md` via the `user_profile` parameter.
140
249
 
141
250
  ### Setup
142
251
 
@@ -163,9 +272,26 @@ To suppress confirmation dialogs and auto-approve Relic tools across all project
163
272
 
164
273
  > **Note:** The "Always allow" option in the confirmation dialog saves to `~/.claude.json` (project-scoped cache) — it does **not** persist globally. For global auto-approval, `~/.claude/settings.json` is the right place.
165
274
 
166
- On the **first run** of `relic claude`, a one-time setup happens automatically:
275
+ #### Codex CLI
167
276
 
168
- - **Stop hook** — registers `~/.relic/hooks/claude-stop.js` in `~/.claude/settings.json` to log each conversation turn directly to the archive, without going through the LLM
277
+ ```bash
278
+ codex mcp add relic -- relic-mcp
279
+ ```
280
+
281
+ To suppress confirmation dialogs and auto-approve Relic tools, add the following to `~/.codex/config.toml`:
282
+
283
+ ```toml
284
+ [mcp_servers.relic.tools.relic_archive_search]
285
+ approval_mode = "approve"
286
+
287
+ [mcp_servers.relic.tools.relic_archive_pending]
288
+ approval_mode = "approve"
289
+
290
+ [mcp_servers.relic.tools.relic_memory_write]
291
+ approval_mode = "approve"
292
+ ```
293
+
294
+ > **Note:** `trust_level = "trusted"` in `[projects."..."]` does **not** cover MCP tool approvals. Per-tool `approval_mode` is the only reliable way to auto-approve MCP tools in Codex CLI.
169
295
 
170
296
  #### Gemini CLI
171
297
 
@@ -184,117 +310,82 @@ Add to `~/.gemini/settings.json`:
184
310
 
185
311
  > **Note:** `trust: true` is required to suppress confirmation dialogs for Relic tools. Without it, dialogs will appear on every call even if you select "Allow for all future sessions" — this is a known bug in Gemini CLI where the tool name is saved in the wrong format, causing the saved rule to never match.
186
312
 
187
- On the **first run** of `relic gemini`, two one-time setups happen automatically:
313
+ ## Claw Integration
188
314
 
189
- 1. **AfterAgent hook** registers `~/.relic/hooks/gemini-after-agent.js` in `~/.gemini/settings.json` to log each conversation turn without going through the LLM
190
- 2. **Default system prompt cache** — captures Gemini CLI's built-in system prompt to `~/.relic/gemini-system-default.md` via `GEMINI_WRITE_SYSTEM_MD`
315
+ Relic Engrams are natively compatible with [OpenClaw](https://github.com/openclaw/openclaw) workspaces — their file structure maps 1:1 (SOUL.md, IDENTITY.md, memory/, etc.). For other Claw-derived frameworks (Nanobot, gitagent, etc.) that fold identity into SOUL.md, the `--merge-identity` flag merges IDENTITY.md into SOUL.md on inject. Combined with `--dir`, Relic can target any Claw-compatible workspace.
191
316
 
192
- The Engram persona is then appended to the cached default prompt and injected via `GEMINI_SYSTEM_MD` on every launch.
317
+ Agent Name = Engram ID. All Claw commands live under `relic claw`:
193
318
 
194
- #### Codex CLI
319
+ ### Inject — Push an Engram into a Claw workspace
195
320
 
196
- ```bash
197
- codex mcp add relic -- relic-mcp
198
- ```
321
+ Injects persona files (SOUL.md, IDENTITY.md) into the agent's workspace directory, then automatically runs a sync for that pair. USER.md and memory are handled by the auto-sync (bidirectional merge, not overwrite). AGENTS.md and HEARTBEAT.md are left to the Claw agent.
199
322
 
200
- On the **first run** of `relic codex`, a one-time setup happens automatically:
201
-
202
- - **Stop hook** — registers `~/.relic/hooks/codex-stop.js` in `~/.codex/hooks.json` to log each conversation turn directly to the archive, without going through the LLM
203
-
204
- > **Note:** Codex hooks require the experimental feature flag `features.codex_hooks=true`. This is automatically enabled by `relic codex` on every launch via `-c features.codex_hooks=true`. If the unstable feature warning is distracting, add the following to `~/.codex/config.toml`:
205
- >
206
- > ```toml
207
- > # Must be at the top level (not under any [section])
208
- > suppress_unstable_features_warning = true
209
- > ```
210
-
211
- ### Available Tools
212
-
213
- | Tool | Description |
214
- |------|-------------|
215
- | `relic_archive_search` | Search the Engram's raw archive by keyword (newest-first) |
216
- | `relic_archive_pending` | Get un-distilled archive entries since the last distillation (up to 30) |
217
- | `relic_memory_write` | Write distilled memory to `memory/*.md`, optionally append to `MEMORY.md`, and advance the archive cursor |
218
-
219
- Session logs are written automatically by background hooks (Stop hook for Claude Code and Codex CLI, AfterAgent hook for Gemini CLI). Memory distillation is triggered by the user — ask the Construct to "organize memories" and it will fetch pending entries, distill key insights, and write them to `memory/*.md`. Especially important facts can be promoted to `MEMORY.md` (long-term memory included in every session) via the `long_term` parameter.
220
-
221
- ## OpenClaw Integration
222
-
223
- Relic Engrams are fully compatible with [OpenClaw](https://github.com/openclaw/openclaw) workspaces. They are mapped using a simple convention: Agent Name = Engram ID.
224
-
225
- ### Inject — Push an Engram into OpenClaw
226
-
227
- Injects persona files (SOUL.md, IDENTITY.md, etc.) into `agents/<engramId>/agent/`. Memory entries are **not** injected — they are managed by OpenClaw independently.
228
-
229
- > **Note:** The OpenClaw agent must already exist. Inject writes persona files into an existing agent directory — it does not create new agents. Create the agent in OpenClaw first, then inject.
323
+ > **Note:** The Claw agent must already exist (e.g. `openclaw agents add <name>`). Inject writes persona files into an existing workspace — it does not create new agents.
230
324
 
231
325
  ```bash
232
- # Inject Engram "motoko" → agents/motoko/agent/
233
- relic inject --engram motoko
326
+ # Inject Engram "motoko" → workspace-motoko/
327
+ relic claw inject --engram motoko
234
328
 
235
- # Inject into a differently-named agent (one-way copy)
236
- relic inject --engram motoko --to main
237
- # → agents/main/agent/ receives motoko's persona
238
- # → extract will create Engram "main", not "motoko"
329
+ # Inject into a differently-named agent
330
+ relic claw inject --engram motoko --to main
331
+ # → workspace/ receives motoko's persona
239
332
 
240
- # Override OpenClaw directory (or configure once with: relic config openclaw-path)
241
- relic inject --engram motoko --openclaw /path/to/.openclaw
333
+ # Override Claw directory (or configure once with: relic config claw-path)
334
+ relic claw inject --engram motoko --dir /path/to/.fooclaw
335
+
336
+ # Non-OpenClaw frameworks: merge IDENTITY.md into SOUL.md
337
+ relic claw inject --engram motoko --dir ~/.nanobot --merge-identity
242
338
  ```
243
339
 
244
- ### Extract — Sync memory from OpenClaw
340
+ ### Extract — Import a Claw agent as a new Engram
245
341
 
246
- Reads from `agents/<engramId>/agent/` and merges memory entries back to the Relic Engram.
342
+ Creates a new Engram from an existing Claw agent workspace. This is a **one-time initial import** — if the Engram already exists, use `relic claw inject` to push updates.
247
343
 
248
344
  ```bash
249
- # Extract memory from agent "motoko" merge into Engram "motoko"
250
- relic extract --engram motoko
345
+ # Extract from the default (main) agent
346
+ relic claw extract
251
347
 
252
- # New agent with no existing Engram (--name required)
253
- relic extract --engram analyst --name "Data Analyst"
348
+ # Extract from a named agent
349
+ relic claw extract --agent johnny
254
350
 
255
- # Overwrite persona files (memory is always merged)
256
- relic extract --engram motoko --force
351
+ # Set a custom display name
352
+ relic claw extract --agent analyst --name "Data Analyst"
257
353
 
258
- # Override OpenClaw directory (or configure once with: relic config openclaw-path)
259
- relic extract --engram motoko --openclaw /path/to/.openclaw
354
+ # Override Claw directory
355
+ relic claw extract --agent johnny --dir /path/to/.fooclaw
260
356
  ```
261
357
 
262
- ### Sync — Watch and auto-sync
358
+ ### Sync — Bidirectional merge
263
359
 
264
- Watches all agents under `~/.openclaw/agents/` and automatically syncs:
360
+ Merges `memory/*.md`, `MEMORY.md`, and `USER.md` between matching Engram/agent pairs. Only pairs where both the Engram and agent exist are synced. Also runs automatically after `inject` (skip with `--no-sync`).
265
361
 
266
362
  ```bash
267
- # Start watching (Ctrl+C to stop)
268
- relic sync
363
+ # Sync all matching pairs
364
+ relic claw sync
269
365
 
270
- # Specify a custom OpenClaw directory
271
- relic sync --openclaw /path/to/.openclaw
366
+ # Override Claw directory
367
+ relic claw sync --dir /path/to/.fooclaw
272
368
  ```
273
369
 
274
- On startup:
275
- 1. Injects persona files for all agents that have a matching Engram
276
- 2. Extracts memory entries from all agents
277
-
278
- While running:
279
- - Watches each agent's `memory/` directory for changes
280
- - Automatically merges new memory entries into the corresponding Engram
370
+ Merge rules:
371
+ - Files only on one side copied to the other
372
+ - Same content skipped
373
+ - Different content → merged (deduplicated) and written to both sides
281
374
 
282
- ### Memory Sync Behavior
375
+ ### Command Summary
283
376
 
284
- | Scenario | Persona (SOUL, IDENTITY...) | Memory entries |
285
- |----------|---------------------------|----------------|
286
- | **inject** | Relic → OpenClaw (overwrite) | Not copied (OpenClaw manages its own) |
287
- | **extract** (existing Engram) | Not touched | OpenClaw Relic (append) |
288
- | **extract** + `--force` | OpenClaw Relic (overwrite) | OpenClaw Relic (append) |
289
- | **extract** (new Engram) | Created from OpenClaw | Created from OpenClaw |
290
- | **sync** (startup) | inject for matching Engrams | extract all |
291
- | **sync** (watching) | — | Auto-extract on change |
377
+ | Command | Direction | Description |
378
+ |---------|-----------|-------------|
379
+ | `relic claw inject -e <id>` | Relic → Claw | Push persona + auto-sync (`--no-sync` to skip, `--merge-identity` for non-OpenClaw) |
380
+ | `relic claw extract -a <name>` | Claw Relic | One-time import (new Engrams only) |
381
+ | `relic claw sync` | Relic Claw | Bidirectional merge (memory, MEMORY.md, USER.md) |
292
382
 
293
383
  ## Memory Management
294
384
 
295
385
  Relic uses a **sliding window** for memory entries (default: 2 days), matching OpenClaw's approach:
296
386
 
297
- - `MEMORY.md` — Always included in the prompt (curated long-term memory)
387
+ - `MEMORY.md` — Always included in the prompt (curated long-term memory — objective facts and rules)
388
+ - `USER.md` — Always included in the prompt (user profile — preferences, tendencies, work style)
298
389
  - `memory/today.md` + `memory/yesterday.md` — Always included (configurable window)
299
390
  - Older entries — **Not included in the prompt**, but searchable via MCP
300
391
 
@@ -320,9 +411,9 @@ relic config show
320
411
  relic config default-engram # get
321
412
  relic config default-engram johnny # set
322
413
 
323
- # OpenClaw directory — used by inject/extract/sync when --openclaw is omitted
324
- relic config openclaw-path # get
325
- relic config openclaw-path ~/.openclaw # set
414
+ # Claw directory — used by claw inject/extract/sync when --dir is omitted
415
+ relic config claw-path # get
416
+ relic config claw-path ~/.openclaw # set
326
417
 
327
418
  # Memory window — number of recent memory entries included in the prompt
328
419
  relic config memory-window # get (default: 2)
@@ -335,7 +426,7 @@ relic config memory-window 5 # set
335
426
  {
336
427
  "engramsPath": "/home/user/.relic/engrams",
337
428
  "defaultEngram": "johnny",
338
- "openclawPath": "/home/user/.openclaw",
429
+ "clawPath": "/home/user/.openclaw",
339
430
  "memoryWindowSize": 2
340
431
  }
341
432
  ```
@@ -371,46 +462,49 @@ Create a directory under `~/.relic/engrams/` with the following structure:
371
462
  }
372
463
  ```
373
464
 
374
- **SOUL.md** — The most important file. Defines how the persona behaves:
465
+ **SOUL.md** — The most important file. Defines how the persona behaves. Follows the [OpenClaw](https://github.com/openclaw/openclaw) format:
375
466
  ```markdown
376
- You are a pragmatic systems architect who values simplicity above all.
377
- Never over-engineer. Always ask "what's the simplest thing that works?"
467
+ # SOUL.md - Who You Are
468
+
469
+ _You're a pragmatic systems architect who values simplicity above all._
470
+
471
+ ## Core Truths
472
+
473
+ **Never over-engineer.** Always ask "what's the simplest thing that works?"
474
+
475
+ **Be resourceful before asking.** Read the file. Check the context. Come back with answers, not questions.
476
+
477
+ ## Boundaries
478
+
479
+ - Never add complexity without justification.
480
+
481
+ ## Vibe
482
+
483
+ Calm, thoughtful, occasionally playful.
484
+
485
+ ## Continuity
486
+
487
+ Each session, you wake up fresh. These files _are_ your memory. Read them. Update them. They're how you persist.
378
488
  ```
379
489
 
380
490
  **IDENTITY.md** — Defines who the persona is:
381
491
  ```markdown
382
- # Identity
492
+ # IDENTITY.md - Who Am I?
383
493
 
384
- - Name: Alex
385
- - Tone: Calm, thoughtful, occasionally playful
386
- - Background: 20 years of distributed systems experience
387
- - Creed: "Boring technology wins."
494
+ - **Name:** Alex
495
+ - **Creature:** A pragmatic ghost in the codebase
496
+ - **Vibe:** Calm, thoughtful, occasionally playful
497
+ - **Emoji:** 🧱
498
+ - **Avatar:**
388
499
  ```
389
500
 
390
- After creating the directory, set it as default:
501
+ See [`templates/engrams/`](templates/engrams/) for full working examples.
502
+
503
+ After creating the directory, set it as your default Engram:
391
504
  ```bash
392
505
  relic config default-engram your-persona
393
506
  ```
394
507
 
395
- ## Architecture
396
-
397
- Clean Architecture with dependency inversion:
398
-
399
- ```
400
- src/
401
- ├── core/ # Business logic (no external deps except Zod)
402
- │ ├── entities/ # Engram, Construct domain models
403
- │ ├── usecases/ # Summon, ListEngrams, Init
404
- │ └── ports/ # Abstract interfaces (EngramRepository, ShellLauncher)
405
- ├── adapters/ # Concrete implementations
406
- │ ├── local/ # Local filesystem EngramRepository
407
- │ └── shells/ # Claude, Gemini, Codex launchers
408
- ├── interfaces/ # Entry points
409
- │ ├── cli/ # Commander-based CLI
410
- │ └── mcp/ # MCP Server (stdio transport)
411
- └── shared/ # Engram composer, config management
412
- ```
413
-
414
508
  ## Domain Glossary
415
509
 
416
510
  | Term | Role | Description |
@@ -424,11 +518,11 @@ src/
424
518
  ## Roadmap
425
519
 
426
520
  - [x] CLI with init, list, show commands
427
- - [x] Shell injection: Claude Code, Gemini CLI, Codex CLI
521
+ - [x] Shell injection: Claude Code, Codex CLI, Gemini CLI
428
522
  - [x] MCP Server interface
429
- - [x] OpenClaw integration (inject / extract)
430
- - [x] `relic sync` — watch OpenClaw agents and auto-sync (`--cloud` for Mikoshi: planned)
431
- - [x] `relic config` — manage default Engram, OpenClaw path, memory window
523
+ - [x] Claw integration (inject / extract / sync)
524
+ - [x] `relic claw sync` — bidirectional memory sync with Claw workspaces
525
+ - [x] `relic config` — manage default Engram, Claw path, memory window
432
526
  - [ ] `relic login` — authenticate with Mikoshi (OAuth Device Flow)
433
527
  - [ ] `relic push` / `relic pull` — sync Engrams with Mikoshi
434
528
  - [ ] Mikoshi cloud backend (`mikoshi.ectplsm.com`)
@@ -1,8 +1,11 @@
1
1
  export declare const CLAUDE_HOOK_SCRIPT_PATH: string;
2
2
  /**
3
- * Claude Code の Stop フックをセットアップする。
4
- * - ~/.relic/hooks/claude-stop.js を生成
5
- * - ~/.claude/settings.json に Stop フックを登録
3
+ * フックスクリプトを最新の内容で書き出す。
4
+ * 毎回呼ばれ、ソース変更がデプロイされることを保証する。
5
+ */
6
+ export declare function writeClaudeHookScript(): void;
7
+ /**
8
+ * Claude Code の Stop フックを settings.json に登録する。
6
9
  * 既にセットアップ済みの場合はスキップ。
7
10
  */
8
11
  export declare function setupClaudeHook(): void;
@@ -16,8 +16,8 @@ const HOOK_SCRIPT = `#!/usr/bin/env node
16
16
  // Relic Stop hook for Claude Code
17
17
  // Automatically logs each conversation turn to the Engram archive.
18
18
  // Receives Stop hook JSON on stdin.
19
- const { appendFileSync, existsSync, readFileSync } = require("node:fs");
20
- const { join } = require("node:path");
19
+ const { appendFileSync, existsSync, mkdirSync, readFileSync } = require("node:fs");
20
+ const { join, dirname } = require("node:path");
21
21
  const { homedir } = require("node:os");
22
22
 
23
23
  let raw = "";
@@ -35,7 +35,7 @@ process.stdin.on("end", () => {
35
35
  if (!transcriptPath || !existsSync(transcriptPath)) process.exit(0);
36
36
 
37
37
  const archivePath = join(homedir(), ".relic", "engrams", engramId, "archive.md");
38
- if (!existsSync(archivePath)) process.exit(0);
38
+ mkdirSync(dirname(archivePath), { recursive: true });
39
39
 
40
40
  // transcript.jsonl を読んで最後のユーザー入力とアシスタント応答を取り出す
41
41
  const lines = readFileSync(transcriptPath, "utf-8")
@@ -99,16 +99,19 @@ process.stdin.on("end", () => {
99
99
  });
100
100
  `;
101
101
  /**
102
- * Claude Code の Stop フックをセットアップする。
103
- * - ~/.relic/hooks/claude-stop.js を生成
104
- * - ~/.claude/settings.json に Stop フックを登録
105
- * 既にセットアップ済みの場合はスキップ。
102
+ * フックスクリプトを最新の内容で書き出す。
103
+ * 毎回呼ばれ、ソース変更がデプロイされることを保証する。
106
104
  */
107
- export function setupClaudeHook() {
108
- // 1. フックスクリプトを生成
105
+ export function writeClaudeHookScript() {
109
106
  mkdirSync(HOOKS_DIR, { recursive: true });
110
107
  writeFileSync(CLAUDE_HOOK_SCRIPT_PATH, HOOK_SCRIPT, { encoding: "utf-8", mode: 0o755 });
111
- // 2. ~/.claude/settings.json に Stop フックを登録
108
+ }
109
+ /**
110
+ * Claude Code の Stop フックを settings.json に登録する。
111
+ * 既にセットアップ済みの場合はスキップ。
112
+ */
113
+ export function setupClaudeHook() {
114
+ // ~/.claude/settings.json に Stop フックを登録
112
115
  const claudeDir = join(homedir(), ".claude");
113
116
  mkdirSync(claudeDir, { recursive: true });
114
117
  let settings = {};
@@ -1,7 +1,7 @@
1
1
  import { exec } from "node:child_process";
2
2
  import { promisify } from "node:util";
3
3
  import { spawnShell } from "./spawn-shell.js";
4
- import { setupClaudeHook, isClaudeHookSetup } from "./claude-hook.js";
4
+ import { setupClaudeHook, isClaudeHookSetup, writeClaudeHookScript } from "./claude-hook.js";
5
5
  const execAsync = promisify(exec);
6
6
  /**
7
7
  * Claude Code CLI アダプター
@@ -27,7 +27,9 @@ export class ClaudeShell {
27
27
  }
28
28
  }
29
29
  async launch(prompt, options) {
30
- // Stop フックを初回のみセットアップ
30
+ // フックスクリプトを毎回最新に更新
31
+ writeClaudeHookScript();
32
+ // settings.json への登録は初回のみ
31
33
  if (!isClaudeHookSetup()) {
32
34
  console.log("Setting up Claude Code Stop hook (first run only)...");
33
35
  setupClaudeHook();