metame-cli 1.4.27 → 1.4.29

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
@@ -32,7 +32,8 @@ irm https://raw.githubusercontent.com/Yaron9/MetaMe/main/install.ps1 | iex
32
32
 
33
33
  **Already have Node.js ≥ 18 (any platform):**
34
34
  ```bash
35
- npm install -g metame-cli && metame
35
+ npm install -g metame-cli
36
+ metame
36
37
  ```
37
38
 
38
39
  ---
@@ -210,17 +211,22 @@ irm https://raw.githubusercontent.com/Yaron9/MetaMe/main/install.ps1 | iex
210
211
 
211
212
  **Already have Node.js ≥ 18 (any platform):**
212
213
  ```bash
213
- npm install -g metame-cli && metame
214
+ npm install -g metame-cli
215
+ metame
214
216
  ```
215
217
 
216
- **3 minutes to full setup:**
218
+ **Setup guide (3 minutes):**
217
219
 
218
- | Step | Command | What happens |
219
- |------|---------|-------------|
220
- | 1. Install & profile | `metame` | First run: cognitive interview builds `~/.claude_profile.yaml` |
221
- | 2. Connect phone | Follow the setup wizard | Bot token + app credentials `~/.metame/daemon.yaml` |
222
- | 3. Start daemon | `metame start` | Background daemon launches, bot goes online |
223
- | 4. Register with system | macOS: `metame daemon install-launchd` · Linux: see below | Always-on, crash recovery |
220
+ | Step | What to do | What happens |
221
+ |------|-----------|-------------|
222
+ | 1. Log in to Claude | Run `claude` and complete the login (Anthropic account or API key) | Claude Code is ready to use |
223
+ | 2. Launch MetaMe | Run `metame` | Opens a Claude session with MetaMe loaded |
224
+ | 3. Cognitive interview | Just chat — MetaMe will automatically start a deep interview on first run | Builds `~/.claude_profile.yaml` (your digital twin's brain) |
225
+ | 4. Connect phone | Say "help me set up mobile access" or "connect my phone" | Interactive wizard for Telegram/Feishu bot setup → `~/.metame/daemon.yaml` |
226
+ | 5. Start daemon | `metame start` | Background daemon launches, bot goes online |
227
+ | 6. Register with system | macOS: `metame daemon install-launchd` · Linux: see below | Always-on, crash recovery |
228
+
229
+ > **First time?** Just run `metame` and talk naturally. The interview and setup are conversational — no commands to memorize.
224
230
 
225
231
  > **What does system registration mean?**
226
232
  > 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.
package/index.js CHANGED
@@ -1,10 +1,30 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // Suppress Node.js experimental warnings (e.g. SQLite)
4
+ process.removeAllListeners('warning');
5
+
3
6
  const fs = require('fs');
4
7
  const path = require('path');
5
8
  const os = require('os');
6
9
  const { spawn, execSync } = require('child_process');
7
10
 
11
+ // On Windows, resolve the full path to claude.cmd so we can spawn it
12
+ // via cmd.exe (using COMSPEC) without relying on shell:true finding cmd.exe in PATH
13
+ function resolveClaudeBin() {
14
+ if (process.platform !== 'win32') return 'claude';
15
+ try {
16
+ return execSync('where claude', { encoding: 'utf8' }).trim().split('\n')[0];
17
+ } catch { return 'claude'; }
18
+ }
19
+ function spawnClaude(args, options) {
20
+ if (process.platform === 'win32') {
21
+ const claudePath = resolveClaudeBin();
22
+ const comspec = process.env.COMSPEC || 'C:\\WINDOWS\\system32\\cmd.exe';
23
+ return spawn(comspec, ['/c', `"${claudePath}"`, ...args], options);
24
+ }
25
+ return spawn('claude', args, options);
26
+ }
27
+
8
28
  // ---------------------------------------------------------
9
29
  // 1. CONFIGURATION
10
30
  // ---------------------------------------------------------
@@ -751,7 +771,8 @@ try {
751
771
 
752
772
 
753
773
 
754
- console.log("🔮 MetaMe: Link Established.");
774
+ const pkgVersion = require('./package.json').version;
775
+ console.log(`🔮 MetaMe v${pkgVersion}: Link Established.`);
755
776
 
756
777
  // Memory system status — show live stats without blocking launch
757
778
  try {
@@ -1574,6 +1595,7 @@ WantedBy=default.target
1574
1595
  const bg = spawn(cmd, args, {
1575
1596
  detached: true,
1576
1597
  stdio: 'ignore',
1598
+ windowsHide: true,
1577
1599
  env: { ...process.env, HOME: HOME_DIR, METAME_ROOT: __dirname },
1578
1600
  });
1579
1601
  bg.unref();
@@ -1755,9 +1777,8 @@ if (isSync) {
1755
1777
  const providerEnv = (() => { try { return require(path.join(__dirname, 'scripts', 'providers.js')).buildActiveEnv(); } catch { return {}; } })();
1756
1778
  const resumeArgs = ['--resume', bestSession.id];
1757
1779
  if (daemonCfg.dangerously_skip_permissions) resumeArgs.push('--dangerously-skip-permissions');
1758
- const syncChild = spawn('claude', resumeArgs, {
1780
+ const syncChild = spawnClaude(resumeArgs, {
1759
1781
  stdio: 'inherit',
1760
- shell: process.platform === 'win32',
1761
1782
  env: { ...process.env, ...providerEnv, METAME_ACTIVE_SESSION: 'true' }
1762
1783
  });
1763
1784
  syncChild.on('error', () => {
@@ -1830,10 +1851,36 @@ try {
1830
1851
  memory.close();
1831
1852
  } catch { /* memory not available, non-fatal */ }
1832
1853
 
1854
+ // Auto-start daemon if config exists but daemon is not running
1855
+ try {
1856
+ if (fs.existsSync(DAEMON_CONFIG) && fs.existsSync(DAEMON_SCRIPT)) {
1857
+ let daemonRunning = false;
1858
+ if (fs.existsSync(DAEMON_PID)) {
1859
+ try {
1860
+ const pid = parseInt(fs.readFileSync(DAEMON_PID, 'utf8').trim(), 10);
1861
+ process.kill(pid, 0); // signal 0 = check if alive
1862
+ daemonRunning = true;
1863
+ } catch { /* PID file stale, daemon not running */ }
1864
+ }
1865
+ if (!daemonRunning) {
1866
+ const isNotWindows = process.platform !== 'win32';
1867
+ const dCmd = isNotWindows ? 'caffeinate' : process.execPath;
1868
+ const dArgs = isNotWindows ? ['-i', process.execPath, DAEMON_SCRIPT] : [DAEMON_SCRIPT];
1869
+ const bg = spawn(dCmd, dArgs, {
1870
+ detached: true,
1871
+ stdio: 'ignore',
1872
+ windowsHide: true,
1873
+ env: { ...process.env, HOME: HOME_DIR, METAME_ROOT: __dirname },
1874
+ });
1875
+ bg.unref();
1876
+ console.log(`🤖 Daemon auto-started (PID: ${bg.pid})`);
1877
+ }
1878
+ }
1879
+ } catch { /* non-fatal */ }
1880
+
1833
1881
  // Spawn the official claude tool with our marker + provider env
1834
- const child = spawn('claude', launchArgs, {
1882
+ const child = spawnClaude(launchArgs, {
1835
1883
  stdio: 'inherit',
1836
- shell: process.platform === 'win32',
1837
1884
  env: { ...process.env, ...activeProviderEnv, METAME_ACTIVE_SESSION: 'true' }
1838
1885
  });
1839
1886
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metame-cli",
3
- "version": "1.4.27",
3
+ "version": "1.4.29",
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": {
@@ -6,7 +6,7 @@ function createClaudeEngine(deps) {
6
6
  const {
7
7
  fs,
8
8
  path,
9
- spawn,
9
+ spawn: _spawn,
10
10
  CLAUDE_BIN,
11
11
  HOME,
12
12
  CONFIG_FILE,
@@ -41,6 +41,16 @@ function createClaudeEngine(deps) {
41
41
  statusThrottleMs = 3000,
42
42
  fallbackThrottleMs = 8000,
43
43
  } = deps;
44
+
45
+ // On Windows, spawn claude.cmd via COMSPEC instead of shell:true
46
+ function spawn(cmd, args, options) {
47
+ if (process.platform === 'win32' && cmd === CLAUDE_BIN) {
48
+ const comspec = process.env.COMSPEC || 'C:\\WINDOWS\\system32\\cmd.exe';
49
+ return _spawn(comspec, ['/c', `"${cmd}"`, ...args], options);
50
+ }
51
+ return _spawn(cmd, args, options);
52
+ }
53
+
44
54
  const SESSION_CWD_VALIDATION_TTL_MS = 30 * 1000;
45
55
  const _sessionCwdValidationCache = new Map(); // key: `${sessionId}@@${cwd}` -> { inCwd, ts }
46
56
 
@@ -320,7 +330,7 @@ Reply with ONLY the name, nothing else. Examples: 插件开发, API重构, Bug
320
330
  const child = spawn(CLAUDE_BIN, streamArgs, {
321
331
  cwd,
322
332
  stdio: ['pipe', 'pipe', 'pipe'],
323
- detached: true, // Create new process group so killing -pid kills all sub-agents too
333
+ detached: process.platform !== 'win32', // process groups are POSIX-only
324
334
  env: {
325
335
  ...process.env,
326
336
  ...getActiveProviderEnv(),
@@ -161,7 +161,7 @@ function createTaskScheduler(deps) {
161
161
  path,
162
162
  HOME,
163
163
  CLAUDE_BIN,
164
- spawn,
164
+ spawn: _spawn,
165
165
  execSync,
166
166
  execFileSync,
167
167
  parseInterval,
@@ -180,6 +180,15 @@ function createTaskScheduler(deps) {
180
180
  skillEvolution,
181
181
  } = deps;
182
182
 
183
+ // On Windows, spawn claude.cmd via COMSPEC instead of shell:true
184
+ function spawn(cmd, args, options) {
185
+ if (process.platform === 'win32' && cmd === CLAUDE_BIN) {
186
+ const comspec = process.env.COMSPEC || 'C:\\WINDOWS\\system32\\cmd.exe';
187
+ return _spawn(comspec, ['/c', `"${cmd}"`, ...args], options);
188
+ }
189
+ return _spawn(cmd, args, options);
190
+ }
191
+
183
192
  function checkPrecondition(task) {
184
193
  if (!task.precondition) return { pass: true, context: '' };
185
194
 
@@ -403,7 +412,7 @@ function createTaskScheduler(deps) {
403
412
  const child = spawn(CLAUDE_BIN, asyncArgs, {
404
413
  cwd: cwd || undefined,
405
414
  stdio: ['pipe', 'pipe', 'pipe'],
406
- detached: true, // own process group kills sub-agents on timeout too
415
+ detached: process.platform !== 'win32', // process groups are POSIX-only
407
416
  env: asyncEnv,
408
417
  });
409
418
 
package/scripts/daemon.js CHANGED
@@ -13,6 +13,9 @@
13
13
 
14
14
  'use strict';
15
15
 
16
+ // Suppress Node.js experimental warnings (e.g. SQLite)
17
+ process.removeAllListeners('warning');
18
+
16
19
  const fs = require('fs');
17
20
  const path = require('path');
18
21
  const os = require('os');