metame-cli 1.4.7 → 1.4.10
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/index.js +11 -26
- package/package.json +2 -2
- package/scripts/daemon.js +19 -6
- package/scripts/feishu-adapter.js +4 -1
package/index.js
CHANGED
|
@@ -627,38 +627,23 @@ const GLOBAL_MARKER_END = '<!-- METAME-GLOBAL:END -->';
|
|
|
627
627
|
// Sections to inject (each only injected if not already present in user's manual content)
|
|
628
628
|
const GLOBAL_SECTIONS = [
|
|
629
629
|
{ detect: /dispatch_to|Agent Dispatch/i, text: [
|
|
630
|
-
'## Agent Dispatch
|
|
631
|
-
'',
|
|
632
|
-
'识别到"告诉X/让X/通知X"且 X 为已知 Agent 昵称时,直接调用 dispatch,无需确认:',
|
|
633
|
-
'',
|
|
634
|
-
'```bash',
|
|
635
|
-
'~/.metame/bin/dispatch_to <project_key> "内容"',
|
|
636
|
-
'```',
|
|
637
|
-
'',
|
|
638
|
-
'手机端用户可发送 `/dispatch <project_key> <消息>` 跨 agent 通信。',
|
|
639
|
-
'',
|
|
630
|
+
'## Agent Dispatch',
|
|
631
|
+
'"告诉X/让X"→ `~/.metame/bin/dispatch_to <project_key> "内容"`,手机端 `/dispatch <key> <消息>`。',
|
|
640
632
|
'新增 Agent:`/agent bind <名称> <工作目录>`',
|
|
641
633
|
]},
|
|
642
634
|
{ detect: /memory-search\.js|跨会话记忆/i, text: [
|
|
643
635
|
'## 跨会话记忆',
|
|
644
|
-
'',
|
|
645
|
-
'
|
|
646
|
-
'```bash',
|
|
647
|
-
'node ~/.metame/memory-search.js "关键词1" "keyword2" "函数名"',
|
|
648
|
-
'# 只搜事实:--facts;只搜会话:--sessions;最近会话:--recent',
|
|
649
|
-
'```',
|
|
650
|
-
'',
|
|
651
|
-
'**搜索策略**:一次传 3-4 个关键词(中文描述 + 英文术语 + 函数/配置名)。',
|
|
652
|
-
'**触发场景**:用户说"上次/之前/以前"、涉及已有决策/踩过的坑、排查"之前能用现在不行"。',
|
|
636
|
+
'用户提"上次/之前"时搜索:`node ~/.metame/memory-search.js "关键词1" "keyword2"`',
|
|
637
|
+
'一次传 3-4 个关键词(中文+英文+函数名),`--facts` 只搜事实,`--sessions` 只搜会话。',
|
|
653
638
|
]},
|
|
654
639
|
{ detect: /skill-manager|Skills.*技能/i, text: [
|
|
655
|
-
'## Skills
|
|
656
|
-
'',
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
'
|
|
660
|
-
'
|
|
661
|
-
'
|
|
640
|
+
'## Skills',
|
|
641
|
+
'能力不足/工具缺失/任务失败 → 先查 `cat ~/.claude/skills/skill-manager/SKILL.md`,不要自己猜。',
|
|
642
|
+
]},
|
|
643
|
+
{ detect: /\[\[FILE:|手机端文件/i, text: [
|
|
644
|
+
'## 手机端文件交互',
|
|
645
|
+
'**收**:用户发图片/文件自动存到 `upload/`,用 Read 查看。',
|
|
646
|
+
'**发**:回复末尾加 `[[FILE:/absolute/path]]`,daemon 自动发手机。不要读内容再复述。',
|
|
662
647
|
]},
|
|
663
648
|
];
|
|
664
649
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metame-cli",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.10",
|
|
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": {
|
|
@@ -33,4 +33,4 @@
|
|
|
33
33
|
"engines": {
|
|
34
34
|
"node": ">=22.5"
|
|
35
35
|
}
|
|
36
|
-
}
|
|
36
|
+
}
|
package/scripts/daemon.js
CHANGED
|
@@ -29,6 +29,19 @@ const DISPATCH_DIR = path.join(METAME_DIR, 'dispatch');
|
|
|
29
29
|
const DISPATCH_LOG = path.join(DISPATCH_DIR, 'dispatch-log.jsonl');
|
|
30
30
|
const SOCK_PATH = path.join(METAME_DIR, 'daemon.sock');
|
|
31
31
|
|
|
32
|
+
// Resolve claude binary path (daemon may not inherit user's full PATH)
|
|
33
|
+
const CLAUDE_BIN = (() => {
|
|
34
|
+
const candidates = [
|
|
35
|
+
path.join(HOME, '.local', 'bin', 'claude'), // npm global (Linux/Mac)
|
|
36
|
+
path.join(HOME, '.npm-global', 'bin', 'claude'), // custom npm prefix
|
|
37
|
+
'/usr/local/bin/claude',
|
|
38
|
+
'/opt/homebrew/bin/claude',
|
|
39
|
+
];
|
|
40
|
+
try { return execSync('which claude 2>/dev/null', { encoding: 'utf8' }).trim(); } catch {}
|
|
41
|
+
for (const p of candidates) { if (fs.existsSync(p)) return p; }
|
|
42
|
+
return 'claude'; // fallback: hope it's in PATH
|
|
43
|
+
})();
|
|
44
|
+
|
|
32
45
|
// Skill evolution module (hot path + cold path)
|
|
33
46
|
let skillEvolution = null;
|
|
34
47
|
try { skillEvolution = require('./skill-evolution'); } catch { /* graceful fallback */ }
|
|
@@ -395,7 +408,7 @@ function executeTask(task, config) {
|
|
|
395
408
|
const asyncEnv = { ...process.env, ...getDaemonProviderEnv(), CLAUDECODE: undefined };
|
|
396
409
|
|
|
397
410
|
return new Promise((resolve) => {
|
|
398
|
-
const child = spawn(
|
|
411
|
+
const child = spawn(CLAUDE_BIN, asyncArgs, {
|
|
399
412
|
cwd: cwd || undefined,
|
|
400
413
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
401
414
|
detached: true, // own process group — kills sub-agents on timeout too
|
|
@@ -1129,7 +1142,7 @@ async function startTelegramBridge(config, executeTaskByName) {
|
|
|
1129
1142
|
const isBindCmd = trimmedText && (trimmedText.startsWith('/bind') || trimmedText.startsWith('/agent bind') || trimmedText.startsWith('/agent new'));
|
|
1130
1143
|
if (!allowedIds.includes(chatId) && !isBindCmd) {
|
|
1131
1144
|
log('WARN', `Rejected message from unauthorized chat: ${chatId}`);
|
|
1132
|
-
bot.sendMessage(chatId, `⚠️ This chat
|
|
1145
|
+
bot.sendMessage(chatId, `⚠️ This chat is not authorized.\n\nCopy and send this command to register:\n\n/agent bind personal`).catch(() => {});
|
|
1133
1146
|
continue;
|
|
1134
1147
|
}
|
|
1135
1148
|
|
|
@@ -3709,7 +3722,7 @@ Reply with ONLY the name, nothing else. Examples: 插件开发, API重构, Bug
|
|
|
3709
3722
|
*/
|
|
3710
3723
|
function spawnClaudeAsync(args, input, cwd, timeoutMs = 300000) {
|
|
3711
3724
|
return new Promise((resolve) => {
|
|
3712
|
-
const child = spawn(
|
|
3725
|
+
const child = spawn(CLAUDE_BIN, args, {
|
|
3713
3726
|
cwd,
|
|
3714
3727
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
3715
3728
|
env: { ...process.env, ...getActiveProviderEnv(), CLAUDECODE: undefined },
|
|
@@ -4005,7 +4018,7 @@ function spawnClaudeStreaming(args, input, cwd, onStatus, timeoutMs = 600000, ch
|
|
|
4005
4018
|
// Add stream-json output format (requires --verbose)
|
|
4006
4019
|
const streamArgs = [...args, '--output-format', 'stream-json', '--verbose'];
|
|
4007
4020
|
|
|
4008
|
-
const child = spawn(
|
|
4021
|
+
const child = spawn(CLAUDE_BIN, streamArgs, {
|
|
4009
4022
|
cwd,
|
|
4010
4023
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
4011
4024
|
detached: true, // Create new process group so killing -pid kills all sub-agents too
|
|
@@ -4232,7 +4245,7 @@ async function askClaude(bot, chatId, prompt, config, readOnly = false) {
|
|
|
4232
4245
|
// Send a single status message, updated in-place, deleted on completion
|
|
4233
4246
|
let statusMsgId = null;
|
|
4234
4247
|
try {
|
|
4235
|
-
const msg = await bot.sendMessage(chatId, '🤔');
|
|
4248
|
+
const msg = await (bot.sendMarkdown ? bot.sendMarkdown(chatId, '🤔') : bot.sendMessage(chatId, '🤔'));
|
|
4236
4249
|
if (msg && msg.message_id) statusMsgId = msg.message_id;
|
|
4237
4250
|
} catch (e) {
|
|
4238
4251
|
log('ERROR', `Failed to send ack to ${chatId}: ${e.message}`);
|
|
@@ -4613,7 +4626,7 @@ async function startFeishuBridge(config, executeTaskByName) {
|
|
|
4613
4626
|
const isBindCmd = trimmedText && (trimmedText.startsWith('/bind') || trimmedText.startsWith('/agent bind') || trimmedText.startsWith('/agent new'));
|
|
4614
4627
|
if (!allowedIds.includes(chatId) && !isBindCmd) {
|
|
4615
4628
|
log('WARN', `Feishu: rejected message from ${chatId}`);
|
|
4616
|
-
(bot.sendMarkdown ? bot.sendMarkdown(chatId, `⚠️ **此会话未授权**\n\n
|
|
4629
|
+
(bot.sendMarkdown ? bot.sendMarkdown(chatId, `⚠️ **此会话未授权**\n\n复制下方命令发送即可注册:\n\`\`\`\n/agent bind personal\n\`\`\``) : bot.sendMessage(chatId, `⚠️ 此会话未授权。\n\n复制下方命令发送即可注册:\n/agent bind personal`)).catch(() => {});
|
|
4617
4630
|
return;
|
|
4618
4631
|
}
|
|
4619
4632
|
|
|
@@ -100,9 +100,12 @@ function createBot(config) {
|
|
|
100
100
|
async editMessage(chatId, messageId, text) {
|
|
101
101
|
if (this._editBroken) return false;
|
|
102
102
|
try {
|
|
103
|
+
// Feishu patch API only works on card (interactive) messages
|
|
104
|
+
// Update card content with markdown element
|
|
105
|
+
const card = { schema: '2.0', body: { elements: [{ tag: 'markdown', content: text }] } };
|
|
103
106
|
await withTimeout(client.im.message.patch({
|
|
104
107
|
path: { message_id: messageId },
|
|
105
|
-
data: { content: JSON.stringify(
|
|
108
|
+
data: { content: JSON.stringify(card) },
|
|
106
109
|
}));
|
|
107
110
|
return true;
|
|
108
111
|
} catch (e) {
|