metame-cli 1.4.34 → 1.5.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 (44) hide show
  1. package/README.md +146 -32
  2. package/index.js +148 -9
  3. package/package.json +6 -3
  4. package/scripts/daemon-admin-commands.js +254 -9
  5. package/scripts/daemon-agent-commands.js +64 -6
  6. package/scripts/daemon-agent-tools.js +26 -5
  7. package/scripts/daemon-bridges.js +110 -20
  8. package/scripts/daemon-claude-engine.js +698 -239
  9. package/scripts/daemon-command-router.js +24 -8
  10. package/scripts/daemon-default.yaml +28 -4
  11. package/scripts/daemon-engine-runtime.js +275 -0
  12. package/scripts/daemon-exec-commands.js +10 -4
  13. package/scripts/daemon-notify.js +37 -1
  14. package/scripts/daemon-runtime-lifecycle.js +2 -1
  15. package/scripts/daemon-session-commands.js +52 -4
  16. package/scripts/daemon-session-store.js +2 -1
  17. package/scripts/daemon-task-scheduler.js +68 -38
  18. package/scripts/daemon-user-acl.js +26 -9
  19. package/scripts/daemon.js +81 -17
  20. package/scripts/distill.js +323 -18
  21. package/scripts/docs/agent-guide.md +12 -0
  22. package/scripts/docs/maintenance-manual.md +119 -0
  23. package/scripts/docs/pointer-map.md +88 -0
  24. package/scripts/feishu-adapter.js +6 -1
  25. package/scripts/hooks/stop-session-capture.js +243 -0
  26. package/scripts/memory-extract.js +100 -5
  27. package/scripts/memory-nightly-reflect.js +196 -11
  28. package/scripts/memory.js +134 -3
  29. package/scripts/mentor-engine.js +405 -0
  30. package/scripts/platform.js +2 -0
  31. package/scripts/providers.js +169 -21
  32. package/scripts/schema.js +12 -0
  33. package/scripts/session-analytics.js +245 -12
  34. package/scripts/skill-changelog.js +245 -0
  35. package/scripts/skill-evolution.js +288 -5
  36. package/scripts/usage-classifier.js +1 -1
  37. package/scripts/daemon-admin-commands.test.js +0 -333
  38. package/scripts/daemon-task-envelope.test.js +0 -59
  39. package/scripts/daemon-task-scheduler.test.js +0 -106
  40. package/scripts/reliability-core.test.js +0 -280
  41. package/scripts/skill-evolution.test.js +0 -113
  42. package/scripts/task-board.test.js +0 -83
  43. package/scripts/test_daemon.js +0 -1407
  44. package/scripts/utils.test.js +0 -192
package/README.md CHANGED
@@ -38,10 +38,17 @@ metame
38
38
 
39
39
  ---
40
40
 
41
- > ### 🚀 v1.4.336-Dimension Soul Schema + Nightly Reflection + Auto-Provisioning
41
+ > ### 🚀 v1.4.34Mentor Mode Step 4 + Distiller/Memory Closed Loop
42
42
  >
43
+ > - **Multi-engine runtime adapter (MVP)**: daemon now supports engine routing by project (`project.engine`) with shared execution flow for Claude/Codex.
44
+ > - **Codex session continuity**: supports `exec`/`resume`, thread id backfill, one-shot resume fallback (max once per 10 minutes per chat), and auth/rate-limit error mapping.
45
+ > - **Agent engine inference**: natural-language agent creation can infer `codex`; default `claude` keeps zero-regression (no `engine` field persisted).
43
46
  > - **6-dimension soul schema**: cognitive profile upgraded from key-value pairs to a structured 67-field model covering Values, Drive, Cognition Style, Stress & Shadow, Relational, and Identity Narrative — with tier-based lock protection.
44
- > - **Nightly reflection**: every night, hot-zone facts are distilled into searchable decision logs and lessons learned.
47
+ > - **Mentor mode hooks**: pre-flight emotion breaker, context-time mentor prompt, and post-flight reflection debt registration are wired into daemon flow.
48
+ > - **Distiller Step 4**: competence signals now merge into `user_competence_map` (upgrade-by-default, downgrade only with explicit evidence).
49
+ > - **Memory extraction labels**: `memory-extract` writes concept labels into `fact_labels` (linked by fact id from `saveFacts().savedFacts`).
50
+ > - **Nightly closed loop**: nightly reflection writes back `synthesized_insight` facts and generates `knowledge_capsule` documents + facts.
51
+ > - **Postmortem artifacts**: significant sessions now produce `postmortem` markdown and `bug_lesson` facts.
45
52
  > - **Memory index**: auto-generated global index of all memory documents for instant retrieval.
46
53
  > - **Auto-provisioning**: first run automatically deploys default CLAUDE.md, docs, and `dispatch_to` — zero manual setup.
47
54
  > - **Token budget tracking**: daily token usage monitoring with per-category breakdown and 80% warning threshold.
@@ -69,9 +76,10 @@ $ metame
69
76
  Link Established. What are we building?
70
77
  ```
71
78
 
72
- ### 2. Full Claude Code From Your Phone
79
+ ### 2. Full Claude/Codex Sessions From Your Phone
73
80
 
74
- Your Mac runs a daemon. Your phone sends messages via Telegram or Feishu. Same Claude Code engine — same tools, same files, same session.
81
+ Your Mac runs a daemon. Your phone sends messages via Telegram or Feishu.
82
+ Engine is selected per project (`project.engine: claude|codex`) — same tools, same files, same session continuity.
75
83
 
76
84
  ```
77
85
  You (phone): Fix the auth bug in api/login.ts
@@ -87,7 +95,7 @@ Start on your laptop, continue on the train. `/stop` to interrupt, `/undo` to ro
87
95
  MetaMe's memory system runs automatically in the background — no prompts, no manual saves. Five layers, fully autonomous.
88
96
 
89
97
  **Layer 1 — Long-term Facts**
90
- When you go idle, MetaMe runs memory consolidation: extracts key decisions, patterns, and knowledge from your sessions into a persistent facts store. These are semantically recalled on every session start.
98
+ When you go idle, MetaMe runs memory consolidation: extracts key decisions, patterns, and knowledge from your sessions into a persistent facts store. Facts can also carry concept labels (`fact_labels`) for faster cross-domain retrieval.
91
99
 
92
100
  **Layer 2 — Session Continuity**
93
101
  Resuming a conversation after 2+ hours? MetaMe injects a brief summary of what you were working on last time — so you pick up where you left off without re-explaining context.
@@ -96,10 +104,10 @@ Resuming a conversation after 2+ hours? MetaMe injects a brief summary of what y
96
104
  Every session gets tagged with topics and intent. This powers future session routing: when you reference "that thing we worked on last week", MetaMe knows where to look.
97
105
 
98
106
  **Layer 4 — Nightly Reflection**
99
- Every night at 01:00, MetaMe reviews your most-accessed facts from the past week and distills them into high-level decision logs and operational lessons searchable documents that grow your personal knowledge base over time.
107
+ Every night at 01:00, MetaMe reviews your most-accessed facts from the past week and distills them into high-level decision logs and operational lessons. Distilled outputs are also written back to `memory.db` as `synthesized_insight`, enabling retrieval in future sessions.
100
108
 
101
109
  **Layer 5 — Memory Index**
102
- At 01:30, an auto-generated global index (`INDEX.md`) maps every memory document across all categories. This serves as a fast lookup table so MetaMe always knows where to find relevant context.
110
+ At 01:30, an auto-generated global index (`INDEX.md`) maps every memory document across all categories (including capsules and postmortems). This serves as a fast lookup table so MetaMe always knows where to find relevant context.
103
111
 
104
112
  ```
105
113
  [Background, while you sleep]
@@ -133,9 +141,9 @@ Five tasks shipped out of the box. They are precondition-gated and run only when
133
141
 
134
142
  ```yaml
135
143
  - cognitive-distill # 4h · has signals? → distill preferences into profile
136
- - memory-extract # 4h · scan sessions → extract long-term facts + topic tags
144
+ - memory-extract # 4h · scan sessions → extract long-term facts + concept labels
137
145
  - skill-evolve # 6h · has signals? → evolve skills from task outcomes
138
- - nightly-reflect # 01:00 daily · hot facts → decision logs + lessons learned
146
+ - nightly-reflect # 01:00 daily · hot facts → decisions/lessons + synthesized facts + capsules
139
147
  - memory-index # 01:30 daily · regenerate global memory index
140
148
  ```
141
149
 
@@ -195,18 +203,19 @@ Chain skills into multi-step workflows — research → write → publish — fu
195
203
 
196
204
  ### 5. Skills That Evolve Themselves
197
205
 
198
- MetaMe has a living skill ecosystem. Skills aren't static configs they grow.
206
+ MetaMe's current skill loop is queue-driven and reviewable (not magic black-box automation).
199
207
 
200
- - **Auto-discovery**: When a task fails or a capability is missing, MetaMe's skill-scout automatically searches for, installs, and verifies new skills.
201
- - **Learning by watching**: Can't automate a complex browser workflow? Say "我来演示" and MetaMe records your actions, then converts them into a reusable skill.
202
- - **Post-task evolution**: After every significant task, the skill-evolution-manager reviews what worked and what didn't, then surgically updates the relevant skills with new knowledge.
203
- - **Composable**: Skills chain together in workflows. A `deep-research` skill feeds into `tech-writing`, which feeds into `wechat-publisher` each one improving from real usage.
208
+ - **Signal capture**: task outcomes and failures are captured into evolution signals.
209
+ - **Hot/cold evolution**: `skill-evolution` runs on task hot path and heartbeat cold path.
210
+ - **Workflow proposals**: repeated multi-tool patterns are merged into workflow sketches and queued as proposals.
211
+ - **Human approval gate**: review and operate with `/skill-evo list`, `/skill-evo approve <id>`, `/skill-evo done <id>`, `/skill-evo dismiss <id>`.
212
+ - **Skill manager fallback**: when capability is missing, runtime routes to `skill-manager` skill guidance instead of blind guessing.
204
213
 
205
214
  ```
206
- Task fails → skill-scout finds a skill → installs → retries → succeeds
207
-
208
- skill-evolution-manager
209
- updates skill with lessons learned
215
+ task outcome/failure → skill signal buffer
216
+ → hot/cold evolution
217
+ → proposal queue
218
+ /skill-evo approve|done|dismiss
210
219
  ```
211
220
 
212
221
  ---
@@ -229,8 +238,8 @@ metame
229
238
 
230
239
  | Step | What to do | What happens |
231
240
  |------|-----------|-------------|
232
- | 1. Log in to Claude | Run `claude` and complete the login (Anthropic account or API key) | Claude Code is ready to use |
233
- | 2. Launch MetaMe | Run `metame` | Opens a Claude session with MetaMe loaded |
241
+ | 1. Log in to your engine | Run `claude` (Claude user) or `codex login` (Codex user) | Your local CLI engine is ready |
242
+ | 2. Launch MetaMe | Run `metame` (Claude) or `metame codex` (Codex) | Opens a MetaMe-initialized session |
234
243
  | 3. Genesis Interview | Just chat — MetaMe will automatically start a deep soul interview on first run | Builds `~/.claude_profile.yaml` (6-dimension cognitive profile) |
235
244
  | 4. Connect phone | Say "help me set up mobile access" or "connect my phone" | Interactive wizard for Telegram/Feishu bot setup → `~/.metame/daemon.yaml` |
236
245
  | 5. Start daemon | `metame start` | Background daemon launches, bot goes online |
@@ -243,6 +252,68 @@ metame
243
252
  npm install -g metame-cli
244
253
  ```
245
254
 
255
+ ### Install Path By User Type
256
+
257
+ **Claude Code only (plugin path, one-liner):**
258
+ ```bash
259
+ claude plugin install github:Yaron9/MetaMe/plugin
260
+ ```
261
+
262
+ **Claude Code only (npm CLI path, one-liner):**
263
+ ```bash
264
+ npm install -g @anthropic-ai/claude-code metame-cli && claude && metame
265
+ ```
266
+
267
+ **Codex only (CLI path, one-liner):**
268
+ ```bash
269
+ npm install -g @openai/codex metame-cli && codex login && metame codex
270
+ ```
271
+
272
+ **Claude + Codex (one-liner):**
273
+ ```bash
274
+ npm install -g @anthropic-ai/claude-code @openai/codex metame-cli
275
+ ```
276
+
277
+ Then run `claude` once (Claude login), `codex login` once (Codex login), and use:
278
+ - `metame` for Claude
279
+ - `metame codex` for Codex
280
+
281
+ > `metame-cli` is engine-agnostic. It does not bundle Claude or Codex.
282
+ > You install the engine(s) separately, and MetaMe routes/launches them.
283
+
284
+ ### Install FAQ
285
+
286
+ - **Does Claude plugin mode support daemon + phone access?** Yes. Plugin mode can start the daemon (via `SessionStart` after `daemon.yaml` exists), and phone access works while the daemon is running.
287
+ - **Does `npm install -g metame-cli` install Claude or Codex?** No. It only installs MetaMe. Install `@anthropic-ai/claude-code` and/or `@openai/codex` separately.
288
+ - **If I only install one engine, does MetaMe still work?** Yes. MetaMe will run on the installed engine. `/doctor` marks the non-default missing engine as warning, not hard failure.
289
+
290
+ ### Uninstall (CLI Path)
291
+
292
+ ```bash
293
+ metame stop
294
+ npm uninstall -g metame-cli
295
+ ```
296
+
297
+ Codex-only cleanup:
298
+ ```bash
299
+ npm uninstall -g metame-cli @openai/codex
300
+ ```
301
+
302
+ Claude-only cleanup:
303
+ ```bash
304
+ npm uninstall -g metame-cli @anthropic-ai/claude-code
305
+ ```
306
+
307
+ Optional data cleanup:
308
+ ```bash
309
+ rm -rf ~/.metame ~/.claude_profile.yaml
310
+ ```
311
+
312
+ Optional service cleanup:
313
+ - macOS: `launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.metame.daemon.plist && rm -f ~/Library/LaunchAgents/com.metame.daemon.plist`
314
+ - Windows: `schtasks /delete /tn "MetaMe-Daemon" /f`
315
+ - Linux/WSL(systemd): `systemctl --user disable --now metame && rm -f ~/.config/systemd/user/metame.service`
316
+
246
317
  > **What does system registration mean?**
247
318
  > Once registered, MetaMe runs in the background automatically — screen locked, lid closed, woken from sleep — as long as the machine is on. Scheduled tasks fire on time. No terminal window needed.
248
319
 
@@ -298,9 +369,9 @@ systemctl --user start metame
298
369
  | Capability | What It Does |
299
370
  |-----------|-------------|
300
371
  | **Cognitive Profile** | 6-dimension soul schema (Values, Drive, Cognition Style, Stress & Shadow, Relational, Identity Narrative). 67 fields, tier-locked, 800-token budget. First-time Genesis Interview builds your profile from scratch. |
301
- | **Layered Memory** | Five-tier memory: long-term facts (semantic recall), session summaries (continuity bridge), session index (topic tags), nightly reflection (decision/lesson distillation), memory index (global lookup). All automatic. |
302
- | **Mobile Bridge** | Full Claude Code via Telegram/Feishu. Stateful sessions, file transfer both ways, real-time streaming status. |
303
- | **Skill Evolution** | Self-healing skill system. Auto-discovers missing skills, learns from browser recordings, evolves after every task. Skills get smarter over time. |
372
+ | **Layered Memory** | Five-tier memory: long-term facts (+ concept labels), session summaries (continuity bridge), session index (topic tags), nightly reflection (distill + write-back), memory index (global lookup). All automatic. |
373
+ | **Mobile Bridge** | Full Claude/Codex via Telegram/Feishu. Stateful sessions, file transfer both ways, real-time streaming status. |
374
+ | **Skill Evolution** | Queue-driven skill evolution: captures task signals, generates workflow proposals, and supports explicit approval/resolve via `/skill-evo` commands. |
304
375
  | **Token Budget** | Daily token usage tracking with per-category breakdown. Configurable daily limit, automatic 80% warning threshold, usage history with rollover. |
305
376
  | **Auto-Provisioning** | First run deploys default CLAUDE.md, documentation, and `dispatch_to` to `~/.metame/`. Subsequent runs sync scripts without overwriting user config. |
306
377
  | **Heartbeat System** | Three-layer programmable nervous system. Layer 0 kernel always-on (zero config). Layer 1 system evolution built-in (5 tasks: distill + memory + skills + nightly reflection + memory index). Layer 2 your custom scheduled tasks with `require_idle`, `precondition`, `notify`, workflows. |
@@ -309,6 +380,7 @@ systemctl --user start metame
309
380
  | **Cross-Platform** | Native support for macOS and Windows. Platform abstraction layer handles spawn, IPC, process management, and terminal encoding automatically. |
310
381
  | **Provider Relay** | Route through any Anthropic-compatible API. Use GPT-4, DeepSeek, Gemini — zero config file mutation. |
311
382
  | **Metacognition** | Detects behavioral patterns (decision style, comfort zones, goal drift) and injects mirror observations. Zero extra API cost. |
383
+ | **Mentor Mode** | `/mentor on|off|level|status` controls friction mode. Emotion breaker, zone-adaptive mentor prompts, and reflection debt run as optional hooks. |
312
384
  | **Multi-User ACL** | Role-based permission system (admin / member / stranger). Share bots with teammates safely. Dynamic user management via `/user` commands with hot-reload config. |
313
385
  | **Team Task** | Multi-agent task board for cross-agent collaboration. Agents can create, assign, and track tasks across workspaces. N-agent session scoping for parallel team workflows. |
314
386
  | **Emergency Tools** | `/doctor` diagnostics, `/mac` macOS control helpers, `/sh` raw shell, `/fix` config restore, `/undo` git-based rollback. |
@@ -417,6 +489,9 @@ All agents share your cognitive profile (`~/.claude_profile.yaml`) — they all
417
489
  | `/undo <hash>` | Roll back to a specific git checkpoint |
418
490
  | `/list` | Browse & download project files |
419
491
  | `/model` | Switch model (sonnet/opus/haiku) |
492
+ | `/engine` | Show/switch default engine (`claude`/`codex`) |
493
+ | `/distill-model` | Show/update background distill model (default: `haiku`) |
494
+ | `/mentor` | Mentor mode control: on/off/level/status |
420
495
  | `/activate` | Activate and bind the most recently created pending agent in a new group |
421
496
  | `/agent bind <name> [dir]` | Manually register group as dedicated agent |
422
497
  | `/mac` | macOS control helper: permissions check/open + AppleScript/JXA execution |
@@ -434,6 +509,34 @@ All agents share your cognitive profile (`~/.claude_profile.yaml`) — they all
434
509
  | `/teamtask <task_id>` | View task detail |
435
510
  | `/teamtask resume <task_id>` | Resume a task |
436
511
 
512
+ ## Mentor Mode (Why + How)
513
+
514
+ Mentor Mode is designed for users who want MetaMe to actively improve decision quality, not just execute commands.
515
+
516
+ - `/mentor on` — enable mentor hooks
517
+ - `/mentor off` — disable mentor hooks
518
+ - `/mentor level <0-10>` — set friction level
519
+ - `/mentor status` — show current mode/level
520
+
521
+ Runtime behavior:
522
+ - Pre-flight emotion breaker (cooldown-aware)
523
+ - Context-time mentor prompts (zone-aware: comfort/stretch/panic)
524
+ - Reflection debt registration on heavy code outputs (intense mode)
525
+
526
+ Level mapping:
527
+ - `0-3` → `gentle`
528
+ - `4-7` → `active`
529
+ - `8-10` → `intense`
530
+
531
+ ## Hook Optimizations (Default On)
532
+
533
+ MetaMe installs and maintains two core Claude hooks automatically on launch:
534
+
535
+ - `UserPromptSubmit` hook (`scripts/signal-capture.js`): captures high-signal preference/task traces with layered filtering.
536
+ - `Stop` hook (`scripts/hooks/stop-session-capture.js`): records session-end/tool-failure signals with watermark protection.
537
+
538
+ If hook installation fails, MetaMe logs and continues the session (non-blocking fallback).
539
+
437
540
  ## How It Works
438
541
 
439
542
  ```
@@ -442,8 +545,8 @@ All agents share your cognitive profile (`~/.claude_profile.yaml`) — they all
442
545
  └─────────────┘ │ (your machine, 24/7) │
443
546
  │ │
444
547
  │ ┌──────────────┐ │
445
- │ │ Claude Code │ │
446
- │ │ (same engine) │ │
548
+ │ │ Claude/Codex │ │
549
+ │ │ (same runtime)│ │
447
550
  │ └──────────────┘ │
448
551
  │ │
449
552
  │ ~/.claude_profile │
@@ -463,12 +566,19 @@ All agents share your cognitive profile (`~/.claude_profile.yaml`) — they all
463
566
 
464
567
  - **Profile** (`~/.claude_profile.yaml`): 6-dimension soul schema. Injected into every Claude session via `CLAUDE.md`.
465
568
  - **Daemon**: Background process handling Telegram/Feishu messages, heartbeat tasks, Unix socket dispatch, and idle/sleep transitions.
466
- - **Distillation**: Heartbeat task (4h, signal-gated) that updates your cognitive profile.
467
- - **Memory Extract**: Heartbeat task (4h, idle-gated) that extracts long-term facts and session topic tags.
468
- - **Nightly Reflection**: Daily at 01:00. Distills hot-zone facts into decision logs and operational lessons.
569
+ - **Runtime Adapter** (`scripts/daemon-engine-runtime.js`): normalizes engine args/env/event parsing across Claude/Codex.
570
+ - **Distillation**: Heartbeat task (4h, signal-gated) that updates your cognitive profile, merges competence signals, and emits postmortems for significant sessions.
571
+ - **Memory Extract**: Heartbeat task (4h, idle-gated) that extracts long-term facts, then writes concept labels (`fact_labels`) linked by fact id.
572
+ - **Nightly Reflection**: Daily at 01:00. Distills hot-zone facts into decision logs/lessons, writes back `synthesized_insight`, and generates knowledge capsules.
469
573
  - **Memory Index**: Daily at 01:30. Regenerates the global memory index for fast retrieval.
470
574
  - **Session Summarize**: Generates a brief summary for idle sessions. Injected as context when resuming after a 2h+ gap.
471
575
 
576
+ ## Scripts Docs Pointer Map
577
+
578
+ Use `scripts/docs/pointer-map.md` as the source-of-truth map for script entry points and Step 1-4 landing zones (`session-analytics` / `mentor-engine` / `daemon-claude-engine` / `distill` / `memory-extract` / `memory-nightly-reflect`).
579
+
580
+ For day-2 operations and troubleshooting (engine routing, codex login/rate-limit, compact boundary), use `scripts/docs/maintenance-manual.md`.
581
+
472
582
  ## Security
473
583
 
474
584
  - All data stays on your machine. No cloud, no telemetry.
@@ -488,10 +598,10 @@ All agents share your cognitive profile (`~/.claude_profile.yaml`) — they all
488
598
  | Cognitive profile injection | ~800 tokens/session (0.4% of 200k context) |
489
599
  | Dispatch latency (Unix socket) | <100ms |
490
600
  | Memory consolidation (per session) | ~1,500–2,000 tokens input + ~50–300 tokens output (Haiku) |
491
- | Session summary (per session) | ~400–900 tokens input + ≤250 tokens output (Haiku) |
601
+ | Session summary (per session) | ~400–900 tokens input + ≤250 tokens output (distill model configurable) |
492
602
  | Mobile commands (`/stop`, `/list`, `/undo`) | 0 tokens |
493
603
 
494
- > Both memory consolidation and session summarization run in the background via Haiku (`--model haiku`). Input is capped by code: skeleton text ≤ 3,000 chars, summary output ≤ 500 chars. Neither runs per-message — memory consolidation follows heartbeat schedule with idle/precondition guards, and summaries trigger once per idle session on sleep-mode transitions.
604
+ > Memory consolidation and session summarization run in the background via the configured distill model (`/distill-model`, default `haiku`). Input is capped by code: skeleton text ≤ 3,000 chars, summary output ≤ 500 chars. Neither runs per-message — memory consolidation follows heartbeat schedule with idle/precondition guards, and summaries trigger once per idle session on sleep-mode transitions.
495
605
 
496
606
  ## Plugin
497
607
 
@@ -503,9 +613,13 @@ claude plugin install github:Yaron9/MetaMe/plugin
503
613
 
504
614
  Includes: cognitive profile injection, daemon (Telegram/Feishu), heartbeat tasks, layered memory, all mobile commands, slash commands (`/metame:evolve`, `/metame:daemon`, `/metame:refresh`, etc.).
505
615
 
506
- **One key difference from the npm CLI:** the plugin daemon starts when you open Claude Code and stops when you close it. It does not run 24/7 in the background. For always-on mobile access (receiving messages while Claude Code is closed), use the npm CLI with `metame daemon install-launchd`.
616
+ **Current behavior (code-aligned):**
617
+ - Plugin auto-starts daemon on Claude `SessionStart` (if `~/.metame/daemon.yaml` exists).
618
+ - Daemon runs detached; phone access works while daemon is running.
619
+ - Plugin path does **not** auto-register OS service (launchd/task-scheduler/systemd). After reboot, open Claude once or run daemon start manually.
507
620
 
508
- Use the plugin if you prefer not to install a global npm package and only need mobile access while Claude Code is open. Use the npm CLI (`metame-cli`) for 24/7 daemon, the `metame` command, and first-run interview.
621
+ Use the plugin if you want zero npm-global setup and Claude-integrated bootstrap.
622
+ Use npm CLI (`metame-cli`) if you want explicit system-service management and CLI-first operations.
509
623
 
510
624
  ## Contributing
511
625
 
package/index.js CHANGED
@@ -88,7 +88,7 @@ function syncDirFiles(srcDir, destDir, { fileList, chmod } = {}) {
88
88
  // Auto-deploy bundled scripts to ~/.metame/
89
89
  // IMPORTANT: daemon.yaml is USER CONFIG — never overwrite it. Only daemon-default.yaml (template) is synced.
90
90
  const scriptsDir = path.join(__dirname, 'scripts');
91
- const BUNDLED_BASE_SCRIPTS = ['platform.js', 'signal-capture.js', 'distill.js', 'schema.js', 'pending-traits.js', 'migrate-v2.js', 'daemon.js', 'telegram-adapter.js', 'feishu-adapter.js', 'daemon-default.yaml', 'providers.js', 'session-analytics.js', 'resolve-yaml.js', 'utils.js', 'skill-evolution.js', 'memory.js', 'memory-extract.js', 'memory-search.js', 'memory-gc.js', 'qmd-client.js', 'session-summarize.js', 'check-macos-control-capabilities.sh', 'usage-classifier.js', 'task-board.js', 'memory-nightly-reflect.js', 'memory-index.js'];
91
+ const BUNDLED_BASE_SCRIPTS = ['platform.js', 'signal-capture.js', 'distill.js', 'schema.js', 'pending-traits.js', 'daemon.js', 'telegram-adapter.js', 'feishu-adapter.js', 'daemon-default.yaml', 'providers.js', 'session-analytics.js', 'resolve-yaml.js', 'utils.js', 'skill-evolution.js', 'memory.js', 'memory-extract.js', 'memory-search.js', 'memory-write.js', 'memory-gc.js', 'qmd-client.js', 'session-summarize.js', 'mentor-engine.js', 'check-macos-control-capabilities.sh', 'usage-classifier.js', 'task-board.js', 'memory-nightly-reflect.js', 'memory-index.js', 'skill-changelog.js'];
92
92
  const DAEMON_MODULE_SCRIPTS = (() => {
93
93
  try {
94
94
  return fs.readdirSync(scriptsDir).filter((f) => /^daemon-[\w-]+\.js$/.test(f));
@@ -124,6 +124,8 @@ if (scriptsUpdated) {
124
124
  syncDirFiles(path.join(__dirname, 'scripts', 'docs'), path.join(METAME_DIR, 'docs'));
125
125
  // Bin: CLI tools (dispatch_to etc.)
126
126
  syncDirFiles(path.join(__dirname, 'scripts', 'bin'), path.join(METAME_DIR, 'bin'), { chmod: 0o755 });
127
+ // Hooks: Claude Code event hooks (Stop, PostToolUse, etc.)
128
+ syncDirFiles(path.join(__dirname, 'scripts', 'hooks'), path.join(METAME_DIR, 'hooks'));
127
129
 
128
130
  // ---------------------------------------------------------
129
131
  // Deploy bundled skills to ~/.claude/skills/
@@ -163,6 +165,29 @@ if (fs.existsSync(bundledSkillsDir)) {
163
165
  }
164
166
  }
165
167
 
168
+ // Ensure ~/.codex/skills and ~/.agents/skills are symlinks to ~/.claude/skills
169
+ // This keeps skill evolution unified across all engines.
170
+ for (const altDir of [
171
+ path.join(HOME_DIR, '.codex', 'skills'),
172
+ path.join(HOME_DIR, '.agents', 'skills'),
173
+ ]) {
174
+ try {
175
+ const parentDir = path.dirname(altDir);
176
+ if (!fs.existsSync(parentDir)) continue; // engine not installed, skip
177
+ const stat = fs.lstatSync(altDir);
178
+ if (stat.isSymbolicLink()) continue; // already a symlink, good
179
+ // Physical directory exists — replace with symlink
180
+ fs.rmSync(altDir, { recursive: true, force: true });
181
+ fs.symlinkSync(CLAUDE_SKILLS_DIR, altDir);
182
+ } catch (e) {
183
+ if (e.code === 'ENOENT') {
184
+ // Directory doesn't exist — create symlink
185
+ try { fs.symlinkSync(CLAUDE_SKILLS_DIR, altDir); } catch { /* non-fatal */ }
186
+ }
187
+ // Other errors: non-fatal, skip
188
+ }
189
+ }
190
+
166
191
  // Load daemon config for local launch flags
167
192
  let daemonCfg = {};
168
193
  try {
@@ -231,6 +256,8 @@ function ensureHookInstalled() {
231
256
  entry.hooks?.some(h => h.command && h.command.includes('signal-capture.js'))
232
257
  );
233
258
 
259
+ let modified = false;
260
+
234
261
  if (!stillInstalled) {
235
262
  if (!settings.hooks) settings.hooks = {};
236
263
  if (!settings.hooks.UserPromptSubmit) settings.hooks.UserPromptSubmit = [];
@@ -241,9 +268,33 @@ function ensureHookInstalled() {
241
268
  command: hookCommand
242
269
  }]
243
270
  });
271
+ modified = true;
272
+ console.log(`${icon("hook")} MetaMe: Signal capture hook installed.`);
273
+ }
274
+
275
+ // Ensure Stop hook (session-logger + tool-failure capture) is installed
276
+ const stopHookScript = path.join(METAME_DIR, 'hooks', 'stop-session-capture.js').replace(/\\/g, '/');
277
+ const stopHookCommand = `node "${stopHookScript}"`;
278
+ const stopHookInstalled = (settings.hooks?.Stop || []).some(entry =>
279
+ entry.hooks?.some(h => h.command && h.command.includes('stop-session-capture.js'))
280
+ );
281
+
282
+ if (!stopHookInstalled) {
283
+ if (!settings.hooks) settings.hooks = {};
284
+ if (!settings.hooks.Stop) settings.hooks.Stop = [];
285
+
286
+ settings.hooks.Stop.push({
287
+ hooks: [{
288
+ type: 'command',
289
+ command: stopHookCommand
290
+ }]
291
+ });
292
+ modified = true;
293
+ console.log(`${icon("hook")} MetaMe: Stop session capture hook installed.`);
294
+ }
244
295
 
296
+ if (modified) {
245
297
  fs.writeFileSync(CLAUDE_SETTINGS, JSON.stringify(settings, null, 2), 'utf8');
246
- console.log(`${icon("hook")} MetaMe: Signal capture hook installed.`);
247
298
  }
248
299
  } catch (e) {
249
300
  // Non-fatal: hook install failure shouldn't block launch
@@ -743,7 +794,8 @@ const GLOBAL_MARKER_END = '<!-- METAME-GLOBAL:END -->';
743
794
  // Build dynamic Agent dispatch table from daemon.yaml projects.
744
795
  // Only include agents whose cwd actually exists on disk — test/stale agents
745
796
  // with deleted paths are automatically excluded, no manual cleanup needed.
746
- let dispatchTable = '';
797
+ // The table is written to ~/.metame/docs/dispatch-table.md (NOT inlined into CLAUDE.md).
798
+ const DISPATCH_TABLE_PATH = path.join(METAME_DIR, 'docs', 'dispatch-table.md');
747
799
  try {
748
800
  const daemonYamlPath = path.join(os.homedir(), '.metame', 'daemon.yaml');
749
801
  if (fs.existsSync(daemonYamlPath)) {
@@ -752,13 +804,29 @@ try {
752
804
  const rows = Object.entries(projects)
753
805
  .filter(([, p]) => {
754
806
  if (!p || !p.name || !p.cwd) return false;
755
- // Expand ~ to home directory
756
807
  const expandedCwd = String(p.cwd).replace(/^~/, os.homedir());
757
808
  return fs.existsSync(expandedCwd);
758
809
  })
759
810
  .map(([key, p]) => `| \`${key}\` | ${p.name} |`);
760
811
  if (rows.length > 0) {
761
- dispatchTable = '\n\n| project_key | 昵称 |\n|-------------|------|\n' + rows.join('\n') + '\n\n`--new` 强制新建会话(用户说"新开会话"时加此参数)。';
812
+ const tableContent = [
813
+ '# Agent Dispatch 路由表',
814
+ '',
815
+ '> 自动生成,来源:daemon.yaml。勿手动编辑。',
816
+ '',
817
+ '| project_key | 昵称 |',
818
+ '|-------------|------|',
819
+ ...rows,
820
+ '',
821
+ '## 使用方法',
822
+ '```bash',
823
+ '~/.metame/bin/dispatch_to [--new] <project_key> "内容"',
824
+ '```',
825
+ '`--new` 强制新建会话(用户说"新开会话"时加此参数)。',
826
+ '新增 Agent:`/agent bind <名称> <工作目录>`',
827
+ ].join('\n') + '\n';
828
+ fs.mkdirSync(path.dirname(DISPATCH_TABLE_PATH), { recursive: true });
829
+ fs.writeFileSync(DISPATCH_TABLE_PATH, tableContent);
762
830
  }
763
831
  }
764
832
  } catch { /* daemon.yaml missing or invalid — skip dispatch table */ }
@@ -771,11 +839,11 @@ const KERNEL_BODY = PROTOCOL_NORMAL
771
839
 
772
840
  const CAPABILITY_SECTIONS = [
773
841
  '## Agent Dispatch',
774
- `"告诉X/让X" → \`~/.metame/bin/dispatch_to <project_key> "内容"\`,手机端 \`/dispatch to <key> <消息>\`。` + dispatchTable,
775
- '新增 Agent:`/agent bind <名称> <工作目录>`',
842
+ '识别到"告诉X/让X/通知X"等转发意图时先 `cat ~/.metame/docs/dispatch-table.md` 获取路由表(昵称→project_key),再执行转发。不要凭记忆猜测昵称对应关系。',
776
843
  '',
777
844
  '## Agent 创建与管理',
778
845
  '用户问创建/管理/绑定 Agent 时 → 先 `cat ~/.metame/docs/agent-guide.md` 再回答。',
846
+ '用户问代码结构/升级进度/脚本入口时 → 先 `cat ~/.metame/docs/pointer-map.md` 再回答。',
779
847
  '',
780
848
  '## 手机端文件交互',
781
849
  '用户要文件("发给我"/"发过来"/"导出")→ 先 `cat ~/.metame/docs/file-transfer.md` 再执行。',
@@ -882,7 +950,37 @@ try {
882
950
  }
883
951
  } catch { /* non-fatal */ }
884
952
 
953
+ // Skill evolution status
954
+ try {
955
+ const skillChangelog = require('./scripts/skill-changelog');
956
+ const skillCount = skillChangelog.countInstalledSkills();
957
+ const lastSession = skillChangelog.getLastSessionStart();
958
+ const recentChanges = skillChangelog.getRecentChanges(lastSession);
959
+
960
+ if (recentChanges.length === 0) {
961
+ console.log(`${icon("tool")} Skills: ${skillCount} installed · 无新变更`);
962
+ } else {
963
+ const evolved = recentChanges.filter(c => c.action === 'evolved');
964
+ const others = recentChanges.filter(c => c.action !== 'evolved');
965
+ const parts = [`${skillCount} installed`];
966
+ if (evolved.length > 0) parts.push(`${evolved.length} evolved since last session`);
967
+ if (others.length > 0) parts.push(`${others.length} other event${others.length > 1 ? 's' : ''}`);
968
+ console.log(`${icon("tool")} Skills: ${parts.join(' · ')}`);
969
+
970
+ // Show up to 3 details
971
+ const shown = recentChanges.slice(0, 3);
972
+ for (const c of shown) {
973
+ const actionIcon = skillChangelog.getActionIcon(c.action);
974
+ console.log(` ${actionIcon} ${c.skill || 'system'}: ${c.summary}`);
975
+ }
976
+ if (recentChanges.length > 3) {
977
+ console.log(` +${recentChanges.length - 3} more`);
978
+ }
979
+ }
885
980
 
981
+ // Write session start marker for next time
982
+ skillChangelog.writeSessionStart();
983
+ } catch { /* non-fatal */ }
886
984
 
887
985
  // ---------------------------------------------------------
888
986
  // 4.9 AUTO-UPDATE CHECK (non-blocking)
@@ -1806,7 +1904,12 @@ WantedBy=default.target
1806
1904
  }
1807
1905
 
1808
1906
  // Unknown subcommand
1809
- console.log(`${icon("book")} MetaMe Daemon Commands:`);
1907
+ console.log(`${icon("book")} MetaMe Commands:`);
1908
+ console.log(" metame — launch Claude with MetaMe init");
1909
+ console.log(" metame codex [args] — launch Codex with MetaMe init");
1910
+ console.log(" metame continue — resume latest session");
1911
+ console.log("");
1912
+ console.log(`${icon("book")} Daemon Commands:`);
1810
1913
  console.log(" metame start — start background daemon");
1811
1914
  console.log(" metame stop — stop daemon");
1812
1915
  console.log(" metame status — show status & budget");
@@ -1824,7 +1927,43 @@ WantedBy=default.target
1824
1927
  }
1825
1928
 
1826
1929
  // ---------------------------------------------------------
1827
- // 5.8 CONTINUE/SYNCresume latest session from terminal
1930
+ // 5.8 CODEXlaunch Codex with MetaMe initialization
1931
+ // ---------------------------------------------------------
1932
+ const isCodex = process.argv[2] === 'codex';
1933
+ if (isCodex) {
1934
+ // spawn() resolves PATH automatically; error event handles missing binary
1935
+ const codexBin = 'codex';
1936
+
1937
+ // Build codex args: remaining user args after 'codex'
1938
+ const codexUserArgs = process.argv.slice(3);
1939
+ let codexArgs;
1940
+ if (codexUserArgs.length === 0) {
1941
+ // Interactive mode: `codex --full-auto`
1942
+ codexArgs = ['--full-auto'];
1943
+ } else {
1944
+ // Non-interactive: `codex exec --full-auto <user args>`
1945
+ codexArgs = ['exec', '--full-auto', ...codexUserArgs];
1946
+ }
1947
+
1948
+ const codexChild = spawn(codexBin, codexArgs, {
1949
+ stdio: 'inherit',
1950
+ cwd: process.cwd(),
1951
+ env: { ...process.env, METAME_ACTIVE_SESSION: 'true' },
1952
+ });
1953
+
1954
+ codexChild.on('error', () => {
1955
+ console.error(`\n${icon("fail")} Error: Could not launch 'codex'.`);
1956
+ console.error(" Please install: npm install -g @openai/codex");
1957
+ });
1958
+ codexChild.on('close', (code) => process.exit(code || 0));
1959
+
1960
+ // Background distillation
1961
+ spawnDistillBackground();
1962
+ return;
1963
+ }
1964
+
1965
+ // ---------------------------------------------------------
1966
+ // 5.9 CONTINUE/SYNC — resume latest session from terminal
1828
1967
  // ---------------------------------------------------------
1829
1968
  // Usage: exit Claude first, then run `metame continue` from terminal.
1830
1969
  // Finds the most recent session and launches Claude with --resume.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metame-cli",
3
- "version": "1.4.34",
3
+ "version": "1.5.0",
4
4
  "description": "The Cognitive Profile Layer for Claude Code. Knows how you think, not just what you said.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -8,12 +8,15 @@
8
8
  },
9
9
  "files": [
10
10
  "index.js",
11
- "scripts/"
11
+ "scripts/",
12
+ "!scripts/*.test.js",
13
+ "!scripts/test_daemon.js",
14
+ "!scripts/hooks/test-*.js"
12
15
  ],
13
16
  "scripts": {
14
17
  "test": "node --test scripts/*.test.js",
15
18
  "start": "node index.js",
16
- "sync:plugin": "cp scripts/platform.js scripts/schema.js scripts/pending-traits.js scripts/signal-capture.js scripts/distill.js scripts/daemon.js scripts/daemon-agent-commands.js scripts/daemon-session-commands.js scripts/daemon-admin-commands.js scripts/daemon-exec-commands.js scripts/daemon-ops-commands.js scripts/daemon-session-store.js scripts/daemon-checkpoints.js scripts/daemon-bridges.js scripts/daemon-file-browser.js scripts/daemon-runtime-lifecycle.js scripts/daemon-notify.js scripts/daemon-claude-engine.js scripts/daemon-command-router.js scripts/daemon-user-acl.js scripts/daemon-agent-tools.js scripts/daemon-task-scheduler.js scripts/daemon-task-envelope.js scripts/task-board.js scripts/telegram-adapter.js scripts/feishu-adapter.js scripts/daemon-default.yaml scripts/providers.js scripts/utils.js scripts/usage-classifier.js scripts/resolve-yaml.js scripts/memory.js scripts/memory-extract.js scripts/qmd-client.js scripts/session-summarize.js scripts/session-analytics.js scripts/skill-evolution.js scripts/check-macos-control-capabilities.sh plugin/scripts/ && echo '✅ Plugin scripts synced'",
19
+ "sync:plugin": "cp scripts/platform.js scripts/schema.js scripts/pending-traits.js scripts/signal-capture.js scripts/distill.js scripts/daemon.js scripts/daemon-agent-commands.js scripts/daemon-session-commands.js scripts/daemon-admin-commands.js scripts/daemon-exec-commands.js scripts/daemon-ops-commands.js scripts/daemon-session-store.js scripts/daemon-checkpoints.js scripts/daemon-bridges.js scripts/daemon-file-browser.js scripts/daemon-runtime-lifecycle.js scripts/daemon-notify.js scripts/daemon-claude-engine.js scripts/daemon-engine-runtime.js scripts/daemon-command-router.js scripts/daemon-user-acl.js scripts/daemon-agent-tools.js scripts/daemon-task-scheduler.js scripts/daemon-task-envelope.js scripts/task-board.js scripts/telegram-adapter.js scripts/feishu-adapter.js scripts/daemon-default.yaml scripts/providers.js scripts/utils.js scripts/usage-classifier.js scripts/resolve-yaml.js scripts/memory.js scripts/memory-write.js scripts/memory-extract.js scripts/memory-search.js scripts/memory-gc.js scripts/memory-nightly-reflect.js scripts/memory-index.js scripts/qmd-client.js scripts/session-summarize.js scripts/session-analytics.js scripts/mentor-engine.js scripts/skill-evolution.js scripts/skill-changelog.js scripts/check-macos-control-capabilities.sh plugin/scripts/ && echo '✅ Plugin scripts synced'",
17
20
  "sync:readme": "node scripts/sync-readme.js",
18
21
  "restart:daemon": "node index.js stop 2>/dev/null; sleep 1; node index.js start 2>/dev/null || echo '⚠️ Daemon not running or restart failed'",
19
22
  "precommit": "npm run sync:plugin && npm run restart:daemon"