metame-cli 1.4.28 → 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 +12 -8
- package/index.js +48 -5
- package/package.json +1 -1
- package/scripts/daemon-claude-engine.js +11 -3
- package/scripts/daemon-task-scheduler.js +10 -2
package/README.md
CHANGED
|
@@ -215,14 +215,18 @@ npm install -g metame-cli
|
|
|
215
215
|
metame
|
|
216
216
|
```
|
|
217
217
|
|
|
218
|
-
**3 minutes
|
|
219
|
-
|
|
220
|
-
| Step |
|
|
221
|
-
|
|
222
|
-
| 1.
|
|
223
|
-
| 2.
|
|
224
|
-
| 3.
|
|
225
|
-
| 4.
|
|
218
|
+
**Setup guide (3 minutes):**
|
|
219
|
+
|
|
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.
|
|
226
230
|
|
|
227
231
|
> **What does system registration mean?**
|
|
228
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
|
@@ -8,6 +8,23 @@ const path = require('path');
|
|
|
8
8
|
const os = require('os');
|
|
9
9
|
const { spawn, execSync } = require('child_process');
|
|
10
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
|
+
|
|
11
28
|
// ---------------------------------------------------------
|
|
12
29
|
// 1. CONFIGURATION
|
|
13
30
|
// ---------------------------------------------------------
|
|
@@ -754,7 +771,8 @@ try {
|
|
|
754
771
|
|
|
755
772
|
|
|
756
773
|
|
|
757
|
-
|
|
774
|
+
const pkgVersion = require('./package.json').version;
|
|
775
|
+
console.log(`🔮 MetaMe v${pkgVersion}: Link Established.`);
|
|
758
776
|
|
|
759
777
|
// Memory system status — show live stats without blocking launch
|
|
760
778
|
try {
|
|
@@ -1759,9 +1777,8 @@ if (isSync) {
|
|
|
1759
1777
|
const providerEnv = (() => { try { return require(path.join(__dirname, 'scripts', 'providers.js')).buildActiveEnv(); } catch { return {}; } })();
|
|
1760
1778
|
const resumeArgs = ['--resume', bestSession.id];
|
|
1761
1779
|
if (daemonCfg.dangerously_skip_permissions) resumeArgs.push('--dangerously-skip-permissions');
|
|
1762
|
-
const syncChild =
|
|
1780
|
+
const syncChild = spawnClaude(resumeArgs, {
|
|
1763
1781
|
stdio: 'inherit',
|
|
1764
|
-
shell: process.platform === 'win32',
|
|
1765
1782
|
env: { ...process.env, ...providerEnv, METAME_ACTIVE_SESSION: 'true' }
|
|
1766
1783
|
});
|
|
1767
1784
|
syncChild.on('error', () => {
|
|
@@ -1834,10 +1851,36 @@ try {
|
|
|
1834
1851
|
memory.close();
|
|
1835
1852
|
} catch { /* memory not available, non-fatal */ }
|
|
1836
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
|
+
|
|
1837
1881
|
// Spawn the official claude tool with our marker + provider env
|
|
1838
|
-
const child =
|
|
1882
|
+
const child = spawnClaude(launchArgs, {
|
|
1839
1883
|
stdio: 'inherit',
|
|
1840
|
-
shell: process.platform === 'win32',
|
|
1841
1884
|
env: { ...process.env, ...activeProviderEnv, METAME_ACTIVE_SESSION: 'true' }
|
|
1842
1885
|
});
|
|
1843
1886
|
|
package/package.json
CHANGED
|
@@ -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
|
|
|
@@ -242,7 +252,6 @@ Reply with ONLY the name, nothing else. Examples: 插件开发, API重构, Bug
|
|
|
242
252
|
const child = spawn(CLAUDE_BIN, args, {
|
|
243
253
|
cwd,
|
|
244
254
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
245
|
-
shell: process.platform === 'win32',
|
|
246
255
|
env: {
|
|
247
256
|
...process.env,
|
|
248
257
|
...getActiveProviderEnv(),
|
|
@@ -321,7 +330,6 @@ Reply with ONLY the name, nothing else. Examples: 插件开发, API重构, Bug
|
|
|
321
330
|
const child = spawn(CLAUDE_BIN, streamArgs, {
|
|
322
331
|
cwd,
|
|
323
332
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
324
|
-
shell: process.platform === 'win32',
|
|
325
333
|
detached: process.platform !== 'win32', // process groups are POSIX-only
|
|
326
334
|
env: {
|
|
327
335
|
...process.env,
|
|
@@ -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,6 @@ function createTaskScheduler(deps) {
|
|
|
403
412
|
const child = spawn(CLAUDE_BIN, asyncArgs, {
|
|
404
413
|
cwd: cwd || undefined,
|
|
405
414
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
406
|
-
shell: process.platform === 'win32',
|
|
407
415
|
detached: process.platform !== 'win32', // process groups are POSIX-only
|
|
408
416
|
env: asyncEnv,
|
|
409
417
|
});
|