@ectplsm/relic 0.2.0 → 0.2.2

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 CHANGED
@@ -42,27 +42,52 @@ npm install -g @ectplsm/relic
42
42
 
43
43
  ## Quick Start
44
44
 
45
+ ### 1. Initialize
46
+
45
47
  ```bash
46
- # Initialize — creates config and sample Engrams
47
48
  relic init
48
49
  # → Prompts: "Set a default Engram? (press Enter for "johnny", or enter ID, or "n" to skip):"
49
50
 
50
- # List available Engrams
51
- relic list
51
+ relic list # List available Engrams
52
+ relic config default-engram motoko # (Optional) Set your default Engram
53
+ ```
54
+
55
+ ### 2. Set Up Memory (MCP)
52
56
 
53
- # Preview an Engram's composed prompt
54
- relic show motoko
57
+ Register the MCP server so the Construct can search past conversations and distill memories. Pick your shell:
55
58
 
56
- # Launch a Shell (uses default Engram if --engram is omitted)
57
- relic claude
59
+ ```bash
60
+ # Claude Code
61
+ claude mcp add --scope user relic -- relic-mcp
62
+
63
+ # Codex CLI
64
+ codex mcp add relic -- relic-mcp
65
+
66
+ # Gemini CLI — add to ~/.gemini/settings.json:
67
+ # { "mcpServers": { "relic": { "command": "relic-mcp", "trust": true } } }
68
+ ```
69
+
70
+ > For auto-approval setup and per-shell details, see [MCP Server](#mcp-server).
71
+
72
+ ### 3. Launch a Shell
73
+
74
+ ```bash
75
+ relic claude # Uses default Engram
76
+ relic claude --engram motoko # Specify explicitly
58
77
  relic codex
59
78
  relic gemini
60
-
61
- # Or specify explicitly
62
- relic claude --engram motoko
63
- relic codex --engram johnny
64
79
  ```
65
80
 
81
+ ### 4. Organize Memories
82
+
83
+ As you use a Construct, conversation logs are automatically saved to `archive.md` by background hooks. To distill these into lasting memory, periodically tell the Construct:
84
+
85
+ > **"Organize my memories"**
86
+
87
+ The Construct will review recent conversations, extract key facts and decisions into `memory/*.md`, promote important long-term insights to `MEMORY.md`, and update your preferences in `USER.md`. These distilled memories are then loaded into future sessions automatically.
88
+
89
+ > For details on the memory system, see [Memory Management](#memory-management).
90
+
66
91
  ## What `relic init` Creates
67
92
 
68
93
  Running `relic init` creates `~/.relic/`, writes `config.json`, and seeds two sample Engrams under `~/.relic/engrams/`.
@@ -73,12 +98,14 @@ Running `relic init` creates `~/.relic/`, writes `config.json`, and seeds two sa
73
98
  └── engrams/
74
99
  ├── johnny/
75
100
  │ ├── engram.json
101
+ │ ├── manifest.json
76
102
  │ ├── SOUL.md
77
103
  │ ├── IDENTITY.md
78
104
  │ └── memory/
79
105
  │ └── YYYY-MM-DD.md
80
106
  └── motoko/
81
107
  ├── engram.json
108
+ ├── manifest.json
82
109
  ├── SOUL.md
83
110
  ├── IDENTITY.md
84
111
  └── memory/
@@ -87,9 +114,12 @@ Running `relic init` creates `~/.relic/`, writes `config.json`, and seeds two sa
87
114
 
88
115
  - `config.json` stores global Relic settings such as `engramsPath`, `defaultEngram`, `clawPath`, and `memoryWindowSize`.
89
116
  - `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.
117
+ - `engram.json` stores editable profile fields like display name, description, and tags.
118
+ - `manifest.json` stores system-managed fields like the Engram ID and timestamps.
91
119
  - `SOUL.md` and `IDENTITY.md` define the persona itself.
92
120
  - `memory/YYYY-MM-DD.md` stores dated distilled memory entries. `relic init` seeds an initial memory file for each sample Engram.
121
+ - `relic migrate engrams` can be used to front-load legacy Engrams into the new `manifest.json` format, although normal Engram reads also migrate automatically.
122
+ - `relic refresh-samples` refreshes bundled sample personas like `johnny` and `motoko` without touching memory or archive files.
93
123
 
94
124
  As you keep using an Engram, more files are added to the same workspace:
95
125
 
@@ -314,11 +344,23 @@ Add to `~/.gemini/settings.json`:
314
344
 
315
345
  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.
316
346
 
317
- Agent Name = Engram ID. All Claw commands live under `relic claw`:
347
+ Current rule: **Agent Name = Engram ID**. Relic treats them as the same name by default. This keeps Claw integration simple: once Engram and agent names diverge, Relic has to introduce explicit mapping logic, which adds complexity that the current workflow does not need.
348
+
349
+ All Claw commands live under `relic claw`:
350
+
351
+ ### Command Summary
352
+
353
+ | Command | Direction | Description |
354
+ |---------|-----------|-------------|
355
+ | `relic claw inject -e <id>` | Relic → Claw | Push persona + auto-sync (`--yes` skips overwrite confirmation, `--no-sync` skips sync, `--merge-identity` for non-OpenClaw) |
356
+ | `relic claw extract -a <name>` | Claw → Relic | New import or persona-only overwrite, then auto-sync that target (`--force`, `--yes`, `--no-sync`) |
357
+ | `relic claw sync` | Relic ↔ Claw | Bidirectional merge (memory, MEMORY.md, USER.md; `--target` limits sync to one target) |
318
358
 
319
359
  ### Inject — Push an Engram into a Claw workspace
320
360
 
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.
361
+ Writes the persona files (`SOUL.md`, `IDENTITY.md`) into the agent workspace, then syncs `USER.md` and memory files (`MEMORY.md`, `memory/*.md`). The sync is bidirectional and merge-based, not a blind overwrite. `AGENTS.md` and `HEARTBEAT.md` remain under Claw's control.
362
+
363
+ If persona files already exist in the target workspace and differ from the local Relic Engram, `inject` asks for confirmation by default. Use `--yes` to skip the prompt. If the target persona already matches, Relic skips the persona rewrite and only runs the memory sync.
322
364
 
323
365
  > **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.
324
366
 
@@ -326,20 +368,26 @@ Injects persona files (SOUL.md, IDENTITY.md) into the agent's workspace director
326
368
  # Inject Engram "motoko" → workspace-motoko/
327
369
  relic claw inject --engram motoko
328
370
 
329
- # Inject into a differently-named agent
330
- relic claw inject --engram motoko --to main
331
- # → workspace/ receives motoko's persona
332
-
333
371
  # Override Claw directory (or configure once with: relic config claw-path)
334
372
  relic claw inject --engram motoko --dir /path/to/.fooclaw
335
373
 
336
374
  # Non-OpenClaw frameworks: merge IDENTITY.md into SOUL.md
337
375
  relic claw inject --engram motoko --dir ~/.nanobot --merge-identity
376
+
377
+ # Skip overwrite confirmation if persona files differ
378
+ relic claw inject --engram motoko --yes
338
379
  ```
339
380
 
340
- ### Extract — Import a Claw agent as a new Engram
381
+ ### Extract — Import a Claw agent as an Engram
382
+
383
+ Creates a new Engram from an existing Claw agent workspace.
384
+
385
+ What `extract` writes locally:
386
+ - New extract: `engram.json`, `manifest.json`, `SOUL.md`, `IDENTITY.md`, `USER.md`, `MEMORY.md`, `memory/*.md`
387
+ - `extract --force`: only `SOUL.md` and `IDENTITY.md`
388
+ - `extract --force --name`: `SOUL.md`, `IDENTITY.md`, and `engram.json.name`
341
389
 
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.
390
+ After `extract`, Relic automatically runs a targeted sync for that same Engram/agent target. Use `--no-sync` to skip it.
343
391
 
344
392
  ```bash
345
393
  # Extract from the default (main) agent
@@ -351,18 +399,32 @@ relic claw extract --agent johnny
351
399
  # Set a custom display name
352
400
  relic claw extract --agent analyst --name "Data Analyst"
353
401
 
402
+ # Overwrite local persona files from the Claw workspace
403
+ relic claw extract --agent johnny --force
404
+
405
+ # Skip overwrite confirmation
406
+ relic claw extract --agent johnny --force --yes
407
+
408
+ # Skip the automatic targeted sync after extract
409
+ relic claw extract --agent johnny --no-sync
410
+
354
411
  # Override Claw directory
355
412
  relic claw extract --agent johnny --dir /path/to/.fooclaw
356
413
  ```
357
414
 
358
415
  ### Sync — Bidirectional merge
359
416
 
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`).
417
+ Merges `memory/*.md`, `MEMORY.md`, and `USER.md` between matching Engram/agent targets. Only targets where both the Engram and agent exist are synced. Also runs automatically after `inject` (skip with `--no-sync`).
418
+
419
+ By default, `sync` scans all matching targets. Use `--target <id>` to sync only one target by shared Engram/agent name.
361
420
 
362
421
  ```bash
363
- # Sync all matching pairs
422
+ # Sync all matching targets
364
423
  relic claw sync
365
424
 
425
+ # Sync only one matching target
426
+ relic claw sync --target johnny
427
+
366
428
  # Override Claw directory
367
429
  relic claw sync --dir /path/to/.fooclaw
368
430
  ```
@@ -372,13 +434,30 @@ Merge rules:
372
434
  - Same content → skipped
373
435
  - Different content → merged (deduplicated) and written to both sides
374
436
 
375
- ### Command Summary
376
-
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) |
437
+ ### Behavior Matrix
438
+
439
+ | Command | State | Flags | Result |
440
+ |---------|------|------|------|
441
+ | `inject` | Workspace missing | none | Fail and ask you to create the agent first |
442
+ | `inject` | Persona matches local Engram | none | Skip persona rewrite, then auto-sync that target |
443
+ | `inject` | Persona differs from local Engram | none | Ask for confirmation before overwriting persona, then auto-sync that target |
444
+ | `inject` | Persona differs from local Engram | `--yes` | Overwrite persona without confirmation, then auto-sync that target |
445
+ | `inject` | any successful inject | `--no-sync` | Skip the automatic targeted sync |
446
+ | `extract` | Local Engram missing | none | Create a new Engram from workspace files, then auto-sync that target |
447
+ | `extract` | Local Engram missing | `--force` | Same as normal new extract, then auto-sync that target |
448
+ | `extract` | Local Engram exists | none | Fail and require `--force` |
449
+ | `extract` | Local Engram exists, no persona drift | `--force` | Skip persona overwrite, then auto-sync that target |
450
+ | `extract` | Local Engram exists, persona differs | `--force` | Ask for confirmation before overwriting `SOUL.md` / `IDENTITY.md`, then auto-sync that target |
451
+ | `extract` | Local Engram exists, persona differs | `--force --yes` | Overwrite `SOUL.md` / `IDENTITY.md` without confirmation, then auto-sync that target |
452
+ | `extract` | any successful extract | `--no-sync` | Skip the automatic targeted sync |
453
+ | `sync` | no target | none | Scan and sync all matching targets |
454
+ | `sync` | explicit target | `--target <id>` | Sync one matching target where `agentName = engramId` |
455
+
456
+ Notes:
457
+ - "Persona" means `SOUL.md` and `IDENTITY.md`
458
+ - `extract --force` only overwrites `SOUL.md` and `IDENTITY.md`
459
+ - `extract --force` does not overwrite `USER.md`, `MEMORY.md`, or `memory/*.md`
460
+ - If `--name` is provided together with `extract --force`, Relic also updates `engram.json.name`
382
461
 
383
462
  ## Memory Management
384
463
 
@@ -439,7 +518,8 @@ Create a directory under `~/.relic/engrams/` with the following structure:
439
518
 
440
519
  ```
441
520
  ~/.relic/engrams/your-persona/
442
- ├── engram.json # Metadata (id, name, description, tags)
521
+ ├── engram.json # Editable profile (name, description, tags)
522
+ ├── manifest.json # System-managed identity (id, createdAt, updatedAt)
443
523
  ├── SOUL.md # Core directive — how the persona thinks and acts
444
524
  ├── IDENTITY.md # Name, tone, background, personality
445
525
  ├── AGENTS.md # (optional) Tool usage policies
@@ -453,15 +533,21 @@ Create a directory under `~/.relic/engrams/` with the following structure:
453
533
  **engram.json:**
454
534
  ```json
455
535
  {
456
- "id": "your-persona",
457
536
  "name": "Display Name",
458
537
  "description": "A short description",
459
- "createdAt": "2026-03-21T00:00:00Z",
460
- "updatedAt": "2026-03-21T00:00:00Z",
461
538
  "tags": ["custom"]
462
539
  }
463
540
  ```
464
541
 
542
+ **manifest.json:**
543
+ ```json
544
+ {
545
+ "id": "your-persona",
546
+ "createdAt": "2026-03-21T00:00:00Z",
547
+ "updatedAt": "2026-03-21T00:00:00Z"
548
+ }
549
+ ```
550
+
465
551
  **SOUL.md** — The most important file. Defines how the persona behaves. Follows the [OpenClaw](https://github.com/openclaw/openclaw) format:
466
552
  ```markdown
467
553
  # SOUL.md - Who You Are
@@ -523,9 +609,9 @@ relic config default-engram your-persona
523
609
  - [x] Claw integration (inject / extract / sync)
524
610
  - [x] `relic claw sync` — bidirectional memory sync with Claw workspaces
525
611
  - [x] `relic config` — manage default Engram, Claw path, memory window
526
- - [ ] `relic login` — authenticate with Mikoshi (OAuth Device Flow)
527
- - [ ] `relic push` / `relic pull` — sync Engrams with Mikoshi
528
612
  - [ ] Mikoshi cloud backend (`mikoshi.ectplsm.com`)
613
+ - [ ] `relic mikoshi login` — authenticate with Mikoshi (OAuth Device Flow)
614
+ - [ ] `relic mikoshi upload` / `relic mikoshi download` / `relic mikoshi sync` — sync Engrams with Mikoshi
529
615
  - [ ] `relic create` — interactive Engram creation wizard
530
616
 
531
617
  ## License
@@ -6,7 +6,8 @@ import type { EngramRepository } from "../../core/ports/engram-repository.js";
6
6
  *
7
7
  * ディレクトリ構造:
8
8
  * {basePath}/{engramId}/
9
- * ├── engram.json (メタデータ)
9
+ * ├── engram.json (ユーザー編集可能なプロフィール)
10
+ * ├── manifest.json (システム管理の識別子・タイムスタンプ)
10
11
  * ├── SOUL.md
11
12
  * ├── IDENTITY.md
12
13
  * ├── AGENTS.md (optional)
@@ -24,5 +25,8 @@ export declare class LocalEngramRepository implements EngramRepository {
24
25
  save(engram: Engram): Promise<void>;
25
26
  delete(id: string): Promise<void>;
26
27
  private readMeta;
28
+ private toProfile;
29
+ private toManifest;
30
+ private writeMetaFiles;
27
31
  private readFiles;
28
32
  }
@@ -1,7 +1,7 @@
1
1
  import { readdir, readFile, writeFile, mkdir, rm } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  import { existsSync } from "node:fs";
4
- import { EngramMetaSchema } from "../../core/entities/engram.js";
4
+ import { EngramManifestSchema, EngramMetaSchema, EngramProfileSchema, } from "../../core/entities/engram.js";
5
5
  /**
6
6
  * OpenClaw互換のファイル名マッピング
7
7
  * EngramFiles のキー → 実ファイル名
@@ -14,7 +14,8 @@ const FILE_MAP = {
14
14
  memory: "MEMORY.md",
15
15
  heartbeat: "HEARTBEAT.md",
16
16
  };
17
- const META_FILE = "engram.json";
17
+ const PROFILE_FILE = "engram.json";
18
+ const MANIFEST_FILE = "manifest.json";
18
19
  const MEMORY_DIR = "memory";
19
20
  /**
20
21
  * LocalEngramRepository — ローカルファイルシステム上の
@@ -22,7 +23,8 @@ const MEMORY_DIR = "memory";
22
23
  *
23
24
  * ディレクトリ構造:
24
25
  * {basePath}/{engramId}/
25
- * ├── engram.json (メタデータ)
26
+ * ├── engram.json (ユーザー編集可能なプロフィール)
27
+ * ├── manifest.json (システム管理の識別子・タイムスタンプ)
26
28
  * ├── SOUL.md
27
29
  * ├── IDENTITY.md
28
30
  * ├── AGENTS.md (optional)
@@ -45,13 +47,9 @@ export class LocalEngramRepository {
45
47
  const dirs = entries.filter((e) => e.isDirectory());
46
48
  const metas = [];
47
49
  for (const dir of dirs) {
48
- const metaPath = join(this.basePath, dir.name, META_FILE);
49
- if (!existsSync(metaPath))
50
- continue;
51
- const raw = await readFile(metaPath, "utf-8");
52
- const parsed = EngramMetaSchema.safeParse(JSON.parse(raw));
53
- if (parsed.success) {
54
- metas.push(parsed.data);
50
+ const meta = await this.readMeta(join(this.basePath, dir.name));
51
+ if (meta) {
52
+ metas.push(meta);
55
53
  }
56
54
  }
57
55
  return metas;
@@ -61,7 +59,7 @@ export class LocalEngramRepository {
61
59
  if (!existsSync(engramDir)) {
62
60
  return null;
63
61
  }
64
- const meta = await this.readMeta(engramDir);
62
+ const meta = await this.readMeta(engramDir, { migrateLegacy: true });
65
63
  if (!meta)
66
64
  return null;
67
65
  const files = await this.readFiles(engramDir);
@@ -70,8 +68,7 @@ export class LocalEngramRepository {
70
68
  async save(engram) {
71
69
  const engramDir = join(this.basePath, engram.meta.id);
72
70
  await mkdir(engramDir, { recursive: true });
73
- // メタデータ書き込み
74
- await writeFile(join(engramDir, META_FILE), JSON.stringify(engram.meta, null, 2), "utf-8");
71
+ await this.writeMetaFiles(engramDir, engram.meta);
75
72
  // 必須ファイル書き込み
76
73
  for (const [key, filename] of Object.entries(FILE_MAP)) {
77
74
  const content = engram.files[key];
@@ -95,13 +92,50 @@ export class LocalEngramRepository {
95
92
  }
96
93
  }
97
94
  // --- private ---
98
- async readMeta(engramDir) {
99
- const metaPath = join(engramDir, META_FILE);
100
- if (!existsSync(metaPath))
95
+ async readMeta(engramDir, options) {
96
+ const profilePath = join(engramDir, PROFILE_FILE);
97
+ if (!existsSync(profilePath))
101
98
  return null;
102
- const raw = await readFile(metaPath, "utf-8");
103
- const parsed = EngramMetaSchema.safeParse(JSON.parse(raw));
104
- return parsed.success ? parsed.data : null;
99
+ const profileRaw = JSON.parse(await readFile(profilePath, "utf-8"));
100
+ const manifestPath = join(engramDir, MANIFEST_FILE);
101
+ if (existsSync(manifestPath)) {
102
+ const profile = EngramProfileSchema.safeParse(profileRaw);
103
+ if (!profile.success)
104
+ return null;
105
+ const manifest = EngramManifestSchema.safeParse(JSON.parse(await readFile(manifestPath, "utf-8")));
106
+ if (!manifest.success)
107
+ return null;
108
+ return {
109
+ ...profile.data,
110
+ ...manifest.data,
111
+ };
112
+ }
113
+ // 後方互換: 旧形式では engram.json に profile + manifest が同居していた
114
+ const legacy = EngramMetaSchema.safeParse(profileRaw);
115
+ if (!legacy.success)
116
+ return null;
117
+ if (options?.migrateLegacy) {
118
+ await this.writeMetaFiles(engramDir, legacy.data);
119
+ }
120
+ return legacy.data;
121
+ }
122
+ toProfile(meta) {
123
+ return {
124
+ name: meta.name,
125
+ description: meta.description,
126
+ tags: meta.tags,
127
+ };
128
+ }
129
+ toManifest(meta) {
130
+ return {
131
+ id: meta.id,
132
+ createdAt: meta.createdAt,
133
+ updatedAt: meta.updatedAt,
134
+ };
135
+ }
136
+ async writeMetaFiles(engramDir, meta) {
137
+ await writeFile(join(engramDir, PROFILE_FILE), JSON.stringify(this.toProfile(meta), null, 2), "utf-8");
138
+ await writeFile(join(engramDir, MANIFEST_FILE), JSON.stringify(this.toManifest(meta), null, 2), "utf-8");
105
139
  }
106
140
  async readFiles(engramDir) {
107
141
  const files = {};
@@ -37,31 +37,72 @@ export declare const EngramFileSchema: z.ZodObject<{
37
37
  }>;
38
38
  export type EngramFiles = z.infer<typeof EngramFileSchema>;
39
39
  /**
40
- * EngramメタデータMikoshiでの管理情報
40
+ * Engramプロフィールユーザーが編集可能な表示用メタデータ
41
41
  */
42
- export declare const EngramMetaSchema: z.ZodObject<{
43
- /** 一意識別子 (例: "ghost-in-the-shell") */
44
- id: z.ZodString;
42
+ export declare const EngramProfileSchema: z.ZodObject<{
45
43
  /** 表示名 (例: "攻殻機動隊の少佐") */
46
44
  name: z.ZodString;
47
45
  /** 説明 */
48
46
  description: z.ZodOptional<z.ZodString>;
47
+ /** タグ */
48
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
49
+ }, "strip", z.ZodTypeAny, {
50
+ name: string;
51
+ description?: string | undefined;
52
+ tags?: string[] | undefined;
53
+ }, {
54
+ name: string;
55
+ description?: string | undefined;
56
+ tags?: string[] | undefined;
57
+ }>;
58
+ export type EngramProfile = z.infer<typeof EngramProfileSchema>;
59
+ /**
60
+ * Engramマニフェスト — システム管理の不変識別子と監査情報
61
+ */
62
+ export declare const EngramManifestSchema: z.ZodObject<{
63
+ /** 一意識別子 (例: "ghost-in-the-shell") */
64
+ id: z.ZodString;
49
65
  /** 作成日時 */
50
66
  createdAt: z.ZodString;
51
67
  /** 最終更新日時 */
52
68
  updatedAt: z.ZodString;
69
+ }, "strip", z.ZodTypeAny, {
70
+ id: string;
71
+ createdAt: string;
72
+ updatedAt: string;
73
+ }, {
74
+ id: string;
75
+ createdAt: string;
76
+ updatedAt: string;
77
+ }>;
78
+ export type EngramManifest = z.infer<typeof EngramManifestSchema>;
79
+ /**
80
+ * Engramメタデータ — プロフィールとマニフェストを結合した利用時ビュー
81
+ */
82
+ export declare const EngramMetaSchema: z.ZodObject<{
83
+ /** 表示名 (例: "攻殻機動隊の少佐") */
84
+ name: z.ZodString;
85
+ /** 説明 */
86
+ description: z.ZodOptional<z.ZodString>;
53
87
  /** タグ */
54
88
  tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
89
+ } & {
90
+ /** 一意識別子 (例: "ghost-in-the-shell") */
91
+ id: z.ZodString;
92
+ /** 作成日時 */
93
+ createdAt: z.ZodString;
94
+ /** 最終更新日時 */
95
+ updatedAt: z.ZodString;
55
96
  }, "strip", z.ZodTypeAny, {
56
- id: string;
57
97
  name: string;
98
+ id: string;
58
99
  createdAt: string;
59
100
  updatedAt: string;
60
101
  description?: string | undefined;
61
102
  tags?: string[] | undefined;
62
103
  }, {
63
- id: string;
64
104
  name: string;
105
+ id: string;
65
106
  createdAt: string;
66
107
  updatedAt: string;
67
108
  description?: string | undefined;
@@ -74,28 +115,29 @@ export type EngramMeta = z.infer<typeof EngramMetaSchema>;
74
115
  */
75
116
  export declare const EngramSchema: z.ZodObject<{
76
117
  meta: z.ZodObject<{
77
- /** 一意識別子 (例: "ghost-in-the-shell") */
78
- id: z.ZodString;
79
118
  /** 表示名 (例: "攻殻機動隊の少佐") */
80
119
  name: z.ZodString;
81
120
  /** 説明 */
82
121
  description: z.ZodOptional<z.ZodString>;
122
+ /** タグ */
123
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
124
+ } & {
125
+ /** 一意識別子 (例: "ghost-in-the-shell") */
126
+ id: z.ZodString;
83
127
  /** 作成日時 */
84
128
  createdAt: z.ZodString;
85
129
  /** 最終更新日時 */
86
130
  updatedAt: z.ZodString;
87
- /** タグ */
88
- tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
89
131
  }, "strip", z.ZodTypeAny, {
90
- id: string;
91
132
  name: string;
133
+ id: string;
92
134
  createdAt: string;
93
135
  updatedAt: string;
94
136
  description?: string | undefined;
95
137
  tags?: string[] | undefined;
96
138
  }, {
97
- id: string;
98
139
  name: string;
140
+ id: string;
99
141
  createdAt: string;
100
142
  updatedAt: string;
101
143
  description?: string | undefined;
@@ -135,8 +177,8 @@ export declare const EngramSchema: z.ZodObject<{
135
177
  }>;
136
178
  }, "strip", z.ZodTypeAny, {
137
179
  meta: {
138
- id: string;
139
180
  name: string;
181
+ id: string;
140
182
  createdAt: string;
141
183
  updatedAt: string;
142
184
  description?: string | undefined;
@@ -153,8 +195,8 @@ export declare const EngramSchema: z.ZodObject<{
153
195
  };
154
196
  }, {
155
197
  meta: {
156
- id: string;
157
198
  name: string;
199
+ id: string;
158
200
  createdAt: string;
159
201
  updatedAt: string;
160
202
  description?: string | undefined;
@@ -23,22 +23,31 @@ export const EngramFileSchema = z.object({
23
23
  memoryEntries: z.record(z.string(), z.string()).optional(),
24
24
  });
25
25
  /**
26
- * EngramメタデータMikoshiでの管理情報
26
+ * Engramプロフィールユーザーが編集可能な表示用メタデータ
27
27
  */
28
- export const EngramMetaSchema = z.object({
29
- /** 一意識別子 (例: "ghost-in-the-shell") */
30
- id: z.string(),
28
+ export const EngramProfileSchema = z.object({
31
29
  /** 表示名 (例: "攻殻機動隊の少佐") */
32
30
  name: z.string(),
33
31
  /** 説明 */
34
32
  description: z.string().optional(),
33
+ /** タグ */
34
+ tags: z.array(z.string()).optional(),
35
+ });
36
+ /**
37
+ * Engramマニフェスト — システム管理の不変識別子と監査情報
38
+ */
39
+ export const EngramManifestSchema = z.object({
40
+ /** 一意識別子 (例: "ghost-in-the-shell") */
41
+ id: z.string(),
35
42
  /** 作成日時 */
36
43
  createdAt: z.string().datetime(),
37
44
  /** 最終更新日時 */
38
45
  updatedAt: z.string().datetime(),
39
- /** タグ */
40
- tags: z.array(z.string()).optional(),
41
46
  });
47
+ /**
48
+ * Engramメタデータ — プロフィールとマニフェストを結合した利用時ビュー
49
+ */
50
+ export const EngramMetaSchema = EngramProfileSchema.merge(EngramManifestSchema);
42
51
  /**
43
52
  * Engram — 完全な人格データセット
44
53
  * メタデータとファイル群の統合体
@@ -1 +1 @@
1
- export { EngramSchema, EngramFileSchema, EngramMetaSchema, ConstructStatusSchema, ShellTypeSchema, type Engram, type EngramFiles, type EngramMeta, type ConstructStatus, type ShellType, } from "./engram.js";
1
+ export { EngramSchema, EngramFileSchema, EngramProfileSchema, EngramManifestSchema, EngramMetaSchema, ConstructStatusSchema, ShellTypeSchema, type Engram, type EngramFiles, type EngramProfile, type EngramManifest, type EngramMeta, type ConstructStatus, type ShellType, } from "./engram.js";
@@ -1 +1 @@
1
- export { EngramSchema, EngramFileSchema, EngramMetaSchema, ConstructStatusSchema, ShellTypeSchema, } from "./engram.js";
1
+ export { EngramSchema, EngramFileSchema, EngramProfileSchema, EngramManifestSchema, EngramMetaSchema, ConstructStatusSchema, ShellTypeSchema, } from "./engram.js";
@@ -1,4 +1,15 @@
1
1
  import type { EngramRepository } from "../ports/engram-repository.js";
2
+ export type ExtractPersonaFileDiff = "missing" | "same" | "different";
3
+ export interface ExtractPersonaDiffResult {
4
+ engramId: string;
5
+ engramName: string;
6
+ sourcePath: string;
7
+ existing: boolean;
8
+ name: ExtractPersonaFileDiff;
9
+ soul: ExtractPersonaFileDiff;
10
+ identity: ExtractPersonaFileDiff;
11
+ overwriteRequired: boolean;
12
+ }
2
13
  export interface ExtractResult {
3
14
  engramId: string;
4
15
  engramName: string;
@@ -14,10 +25,16 @@ export interface ExtractResult {
14
25
  export declare class Extract {
15
26
  private readonly repository;
16
27
  constructor(repository: EngramRepository);
28
+ inspectPersona(agentName: string, options?: {
29
+ name?: string;
30
+ openclawDir?: string;
31
+ }): Promise<ExtractPersonaDiffResult>;
17
32
  execute(agentName: string, options?: {
18
33
  name?: string;
19
34
  openclawDir?: string;
35
+ force?: boolean;
20
36
  }): Promise<ExtractResult>;
37
+ private comparePersonaFile;
21
38
  private readFiles;
22
39
  }
23
40
  export declare class WorkspaceNotFoundError extends Error {