metame-cli 1.3.8 → 1.3.9

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
@@ -6,15 +6,27 @@
6
6
 
7
7
  > **The Cognitive Profile Layer for Claude Code.**
8
8
  >
9
- > *Not a memory system — a cognitive mirror. It knows how you think, decide, and communicate, and it protects your core values.*
9
+ > *Knows how you think. Works wherever you are.*
10
10
 
11
11
  ## 📖 Introduction
12
12
 
13
- **Claude Code** is a powerful tool, but it suffers from "Project Amnesia." Every time you switch folders, it forgets who you are, your communication style, and your specific constraints.
13
+ **Claude Code** is powerful, but it has two pain points:
14
14
 
15
- **MetaMe** solves this by wrapping Claude in a **Cognitive Profile Layer** . It creates a persistent "Global Brain" that travels with you across every project. Unlike ChatGPT/Claude/Gemini's built-in memory (which stores *facts* like "user lives in X"), MetaMe captures *how you think* your decision style, cognitive load preferences, motivation patterns, and communication traits.
15
+ 1. **Project Amnesia** Switch folders, and it forgets who you are. Your communication style, coding preferences, constraintsgone. Every project, you start from scratch.
16
16
 
17
- It is not a memory system; it is a **Cognitive Mirror** .
17
+ 2. **Desktop-Bound** Leave your computer, work stops. You can't continue that debugging session on your phone. You can't vibe with Claude on the train, in bed, or waiting in line.
18
+
19
+ **MetaMe** solves both — and more:
20
+
21
+ **🧠 Cognitive Profile** — A persistent "Global Brain" (`~/.claude_profile.yaml`) that travels with you across every project. Unlike ChatGPT/Claude's built-in memory (which stores *facts* like "user lives in X"), MetaMe captures *how you think* — your decision style, cognitive load preferences, and communication traits. It's not a memory system; it's a **Cognitive Mirror**.
22
+
23
+ **📱 Mobile Bridge** — Full Claude Code from your phone via Telegram or Feishu. Same tools, same files, same conversation history. Start on your computer, continue anywhere. `/cd last` syncs you to exactly where you left off.
24
+
25
+ **🔔 Remote Wake** — Daemon runs in the background on your computer. Send a message from your phone, and it wakes up Claude Code to do real work — edit files, run commands, commit code — even while you're away from your desk.
26
+
27
+ **📂 File Transfer** — Send files from your computer to your phone (ask Claude to send any project file). Send files from your phone to your computer (just attach them in chat). Seamless both ways.
28
+
29
+ **⏰ Heartbeat Tasks** — Schedule Claude to run automatically. Daily summaries, automated workflows, multi-step skill chains — all running on your machine, pushing results to your phone.
18
30
 
19
31
  ## ✨ Key Features
20
32
 
@@ -34,15 +46,19 @@ MetaMe is a wrapper around **Claude Code**. You must have Node.js and the offici
34
46
 
35
47
  ## 📦 Installation
36
48
 
37
- Install MetaMe globally via NPM:
38
-
39
- **Bash**
49
+ **Option A: NPM (recommended)** — full CLI with daemon, mobile bridge, interview
40
50
 
41
- ```
51
+ ```bash
42
52
  npm install -g metame-cli
43
53
  ```
44
54
 
45
- *(Note: If you encounter permission errors on Mac/Linux, use `sudo npm install -g metame-cli`)*
55
+ **Option B: Claude Code Plugin** lightweight, profile injection + slash commands
56
+
57
+ ```bash
58
+ claude plugin install github:Yaron9/MetaMe/plugin
59
+ ```
60
+
61
+ *(NPM note: If you encounter permission errors on Mac/Linux, use `sudo npm install -g metame-cli`)*
46
62
 
47
63
  ## 🚀 Usage
48
64
 
@@ -170,7 +186,6 @@ metame daemon install-launchd # macOS auto-start (RunAtLoad + KeepAlive)
170
186
  | `/cd` | Change working directory — with directory browser |
171
187
  | `/cd last` | **Sync to computer** — jump to the most recent session's directory |
172
188
  | `/session` | Current session info |
173
- | `/continue` | Continue the most recent terminal session |
174
189
 
175
190
  Just type naturally for conversation — every message stays in the same Claude Code session with full context.
176
191
 
@@ -190,7 +205,9 @@ Each chat gets a persistent session via `claude -p --resume <session-id>`. This
190
205
  💻 Bash: 「git status」
191
206
  ```
192
207
 
193
- **File sending (v1.3.7):** Ask Claude to send any file to your phone:
208
+ **File transfer (v1.3.8):** Seamlessly move files between your phone and computer.
209
+
210
+ *Computer → Phone (download):* Ask Claude to send any project file:
194
211
 
195
212
  ```
196
213
  You: Send me report.md
@@ -200,8 +217,18 @@ Claude: Here you go!
200
217
 
201
218
  Works for documents, audio, images, etc. Click button to download. Links valid for 30 minutes.
202
219
 
220
+ *Phone → Computer (upload):* Send files directly to your project:
221
+
222
+ ```
223
+ [📎 You send a PDF, image, or any file]
224
+ Claude: 📥 Saved: document.pdf
225
+ File is in your project's upload/ folder.
226
+ ```
227
+
228
+ Uploaded files are saved to `<project>/upload/`. Claude won't read large files automatically — just tell it when you want it to process them.
229
+
203
230
  - **Telegram:** Works out of the box
204
- - **Feishu:** Requires `im:resource` permission in app settings
231
+ - **Feishu:** Requires `im:resource` + `im:message` permissions in app settings
205
232
 
206
233
  **Other commands:**
207
234
 
package/index.js CHANGED
@@ -598,10 +598,15 @@ if (isDaemon) {
598
598
 
599
599
  // --- Telegram Setup ---
600
600
  console.log("━━━ 📱 Telegram Setup ━━━");
601
- console.log("Steps:");
602
- console.log(" 1. Open Telegram, search @BotFather");
603
- console.log(" 2. Send /newbot, follow prompts to create a bot");
604
- console.log(" 3. Copy the bot token (looks like: 123456:ABC-DEF...)");
601
+ console.log("");
602
+ console.log("Step 1: Create a Bot");
603
+ console.log(" Open Telegram app on your phone or desktop");
604
+ console.log(" Search for @BotFather (official Telegram bot)");
605
+ console.log(" • Send /newbot command");
606
+ console.log(" • Enter a display name (e.g., 'My MetaMe Bot')");
607
+ console.log(" • Enter a username (must end in 'bot', e.g., 'my_metame_bot')");
608
+ console.log(" • BotFather will reply with your bot token");
609
+ console.log(" (looks like: 123456789:ABCdefGHI-jklMNOpqrSTUvwxYZ)");
605
610
  console.log("");
606
611
 
607
612
  const tgToken = (await ask("Paste your Telegram bot token (Enter to skip): ")).trim();
@@ -652,17 +657,38 @@ if (isDaemon) {
652
657
 
653
658
  // --- Feishu Setup ---
654
659
  console.log("━━━ 📘 Feishu (Lark) Setup ━━━");
655
- console.log("Steps:");
656
- console.log(" 1. Go to: https://open.feishu.cn/app");
657
- console.log(" Create App (企业自建应用)");
658
- console.log(" 2. In 'Credentials' (凭证与基础信息), copy App ID & App Secret");
659
- console.log(" 3. In 'Bot' (机器人), enable bot capability");
660
- console.log(" 4. In 'Event Subscription' (事件订阅):");
661
- console.log(" Set mode to 'Long Connection' (使用长连接接收事件)");
662
- console.log(" Add event: im.message.receive_v1 (接收消息)");
663
- console.log(" 5. In 'Permissions' (权限管理), add:");
664
- console.log(" → im:message, im:message:send_as_bot, im:chat");
665
- console.log(" 6. Publish the app version (创建版本 → 申请发布)");
660
+ console.log("");
661
+ console.log("Step 1: Create an App");
662
+ console.log(" Go to: https://open.feishu.cn/app");
663
+ console.log(" Click '创建企业自建应用' (Create Enterprise App)");
664
+ console.log(" Fill in app name and description");
665
+ console.log("");
666
+ console.log("Step 2: Get Credentials");
667
+ console.log(" In left sidebar → '凭证与基础信息' (Credentials)");
668
+ console.log(" Copy App ID and App Secret");
669
+ console.log("");
670
+ console.log("Step 3: Enable Bot");
671
+ console.log(" • In left sidebar → '应用能力' → '机器人' (Bot)");
672
+ console.log(" • Enable the bot capability");
673
+ console.log("");
674
+ console.log("Step 4: Configure Events");
675
+ console.log(" • In left sidebar → '事件订阅' (Event Subscription)");
676
+ console.log(" • Choose '使用长连接接收事件' (Long Connection mode) — important!");
677
+ console.log(" • Add event: im.message.receive_v1 (接收消息)");
678
+ console.log("");
679
+ console.log("Step 5: Add Permissions");
680
+ console.log(" • In left sidebar → '权限管理' (Permissions)");
681
+ console.log(" • Search and enable these 5 permissions:");
682
+ console.log(" → im:message (获取与发送单聊、群组消息)");
683
+ console.log(" → im:message.p2p_msg:readonly (读取用户发给机器人的单聊消息)");
684
+ console.log(" → im:message.group_at_msg:readonly (接收群聊中@机器人消息事件)");
685
+ console.log(" → im:message:send_as_bot (以应用的身份发消息)");
686
+ console.log(" → im:resource (文件上传下载 - for file transfer)");
687
+ console.log("");
688
+ console.log("Step 6: Publish");
689
+ console.log(" • In left sidebar → '版本管理与发布' (Version Management)");
690
+ console.log(" • Click '创建版本' → fill version (e.g., 1.0.0)");
691
+ console.log(" • Click '申请发布' (Apply for Release)");
666
692
  console.log("");
667
693
 
668
694
  const feishuAppId = (await ask("Paste your Feishu App ID (Enter to skip): ")).trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metame-cli",
3
- "version": "1.3.8",
3
+ "version": "1.3.9",
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": {
@@ -13,7 +13,8 @@
13
13
  "scripts": {
14
14
  "start": "node index.js",
15
15
  "sync:plugin": "cp scripts/schema.js scripts/pending-traits.js scripts/signal-capture.js scripts/distill.js scripts/daemon.js scripts/telegram-adapter.js scripts/feishu-adapter.js scripts/daemon-default.yaml plugin/scripts/ && echo '✅ Plugin scripts synced'",
16
- "precommit": "npm run sync:plugin"
16
+ "restart:daemon": "node index.js daemon stop 2>/dev/null; sleep 1; node index.js daemon start 2>/dev/null || echo '⚠️ Daemon not running or restart failed'",
17
+ "precommit": "npm run sync:plugin && npm run restart:daemon"
17
18
  },
18
19
  "keywords": [
19
20
  "claude",
package/scripts/daemon.js CHANGED
@@ -669,22 +669,6 @@ async function handleCommand(bot, chatId, text, config, executeTaskByName) {
669
669
  return;
670
670
  }
671
671
 
672
- if (text === '/continue') {
673
- // Continue the most recent conversation in current workdir
674
- const session = getSession(chatId);
675
- const cwd = session ? session.cwd : HOME;
676
- const state2 = loadState();
677
- state2.sessions[chatId] = {
678
- id: '__continue__',
679
- cwd,
680
- created: new Date().toISOString(),
681
- started: true,
682
- };
683
- saveState(state2);
684
- await bot.sendMessage(chatId, `Resuming last conversation in ${cwd}`);
685
- return;
686
- }
687
-
688
672
  // /file <shortId> — send cached file (from button callback)
689
673
  if (text.startsWith('/file ')) {
690
674
  const shortId = text.slice(6).trim();
@@ -1006,7 +990,7 @@ async function handleCommand(bot, chatId, text, config, executeTaskByName) {
1006
990
  '/cd <path> — 切换工作目录',
1007
991
  '/session — 查看当前会话',
1008
992
  '',
1009
- '⚙️ /status /tasks /budget /reload',
993
+ '⚙️ /status /tasks /run <name> /budget /reload',
1010
994
  '',
1011
995
  '直接打字即可对话 💬',
1012
996
  ].join('\n'));
@@ -1904,6 +1888,27 @@ async function main() {
1904
1888
  }, 1000);
1905
1889
  });
1906
1890
 
1891
+ // Auto-restart: watch daemon.js for code changes (hot restart)
1892
+ const DAEMON_SCRIPT = path.join(METAME_DIR, 'daemon.js');
1893
+ let _restartDebounce = null;
1894
+ fs.watchFile(DAEMON_SCRIPT, { interval: 3000 }, (curr, prev) => {
1895
+ if (curr.mtimeMs === prev.mtimeMs) return;
1896
+ if (_restartDebounce) clearTimeout(_restartDebounce);
1897
+ _restartDebounce = setTimeout(async () => {
1898
+ log('INFO', 'daemon.js changed on disk — auto-restarting...');
1899
+ await notifyFn('🔄 Code updated, daemon restarting...').catch(() => {});
1900
+ // Spawn new daemon process, then exit
1901
+ const { spawn } = require('child_process');
1902
+ const newDaemon = spawn(process.execPath, [DAEMON_SCRIPT], {
1903
+ detached: true,
1904
+ stdio: 'ignore',
1905
+ env: { ...process.env, METAME_ROOT: process.env.METAME_ROOT || path.dirname(__dirname) },
1906
+ });
1907
+ newDaemon.unref();
1908
+ setTimeout(() => process.exit(0), 500);
1909
+ }, 2000);
1910
+ });
1911
+
1907
1912
  // Start bridges (both can run simultaneously)
1908
1913
  telegramBridge = await startTelegramBridge(config, executeTaskByName);
1909
1914
  feishuBridge = await startFeishuBridge(config, executeTaskByName);
@@ -1912,6 +1917,7 @@ async function main() {
1912
1917
  const shutdown = () => {
1913
1918
  log('INFO', 'Daemon shutting down...');
1914
1919
  fs.unwatchFile(CONFIG_FILE);
1920
+ fs.unwatchFile(DAEMON_SCRIPT);
1915
1921
  if (heartbeatTimer) clearInterval(heartbeatTimer);
1916
1922
  if (telegramBridge) telegramBridge.stop();
1917
1923
  if (feishuBridge) feishuBridge.stop();