metame-cli 1.5.20 → 1.5.22
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 +3 -2
- package/index.js +7 -23
- package/package.json +1 -1
- package/scripts/agent-intent-shared.js +111 -0
- package/scripts/daemon-agent-commands.js +150 -353
- package/scripts/daemon-agent-intent.js +282 -0
- package/scripts/daemon-agent-lifecycle.js +243 -0
- package/scripts/daemon-agent-workflow.js +295 -0
- package/scripts/daemon-bridges.js +32 -9
- package/scripts/daemon-claude-engine.js +74 -75
- package/scripts/daemon-command-router.js +24 -294
- package/scripts/daemon-prompt-context.js +127 -0
- package/scripts/daemon-reactive-lifecycle.js +138 -6
- package/scripts/daemon-team-workflow.js +146 -0
- package/scripts/daemon.js +7 -3
- package/scripts/docs/hook-config.md +41 -21
- package/scripts/docs/maintenance-manual.md +2 -2
- package/scripts/docs/orphan-files-review.md +1 -1
- package/scripts/docs/pointer-map.md +2 -2
- package/scripts/hooks/intent-agent-capability.js +51 -0
- package/scripts/hooks/intent-doc-router.js +23 -11
- package/scripts/hooks/intent-memory-recall.js +1 -3
- package/scripts/hooks/intent-team-dispatch.js +1 -1
- package/scripts/intent-registry.js +78 -14
- package/scripts/ops-mission-queue.js +101 -36
- package/scripts/ops-reactive-bootstrap.js +86 -0
- package/scripts/hooks/intent-engine.js +0 -75
- package/scripts/hooks/team-context.js +0 -143
package/README.md
CHANGED
|
@@ -614,12 +614,13 @@ Level mapping:
|
|
|
614
614
|
|
|
615
615
|
## Hook Optimizations (Default On)
|
|
616
616
|
|
|
617
|
-
MetaMe
|
|
617
|
+
MetaMe keeps Claude hooks minimal and non-essential:
|
|
618
618
|
|
|
619
|
-
- `UserPromptSubmit` hook (`scripts/hooks/intent-engine.js`): Unified intent engine for team dispatch, ops assist, and task creation hints.
|
|
620
619
|
- `UserPromptSubmit` hook (`scripts/signal-capture.js`): captures high-signal preference/task traces with layered filtering.
|
|
621
620
|
- `Stop` hook (`scripts/hooks/stop-session-capture.js`): records session-end/tool-failure signals with watermark protection.
|
|
622
621
|
|
|
622
|
+
Semantic intent recognition and prompt hint injection now run only inside the daemon runtime, so Claude and Codex share the same injection path.
|
|
623
|
+
|
|
623
624
|
If hook installation fails, MetaMe logs and continues the session (non-blocking fallback).
|
|
624
625
|
|
|
625
626
|
## How It Works
|
package/index.js
CHANGED
|
@@ -756,12 +756,17 @@ function ensureHookInstalled() {
|
|
|
756
756
|
console.log(`${icon("hook")} MetaMe: Stop session capture hook installed.`);
|
|
757
757
|
}
|
|
758
758
|
|
|
759
|
-
// Migrate: remove
|
|
759
|
+
// Migrate: remove obsolete semantic injection hooks.
|
|
760
|
+
// Intent routing now happens only inside the daemon runtime so Claude/Codex
|
|
761
|
+
// share one platform-agnostic path.
|
|
760
762
|
if (settings.hooks?.UserPromptSubmit) {
|
|
761
763
|
const before = settings.hooks.UserPromptSubmit.length;
|
|
762
764
|
for (const entry of settings.hooks.UserPromptSubmit) {
|
|
763
765
|
if (entry.hooks) {
|
|
764
|
-
entry.hooks = entry.hooks.filter(h =>
|
|
766
|
+
entry.hooks = entry.hooks.filter((h) => {
|
|
767
|
+
const cmd = h && h.command ? String(h.command) : '';
|
|
768
|
+
return !(cmd.includes('team-context.js') || cmd.includes('intent-engine.js'));
|
|
769
|
+
});
|
|
765
770
|
}
|
|
766
771
|
}
|
|
767
772
|
settings.hooks.UserPromptSubmit = settings.hooks.UserPromptSubmit.filter(
|
|
@@ -770,27 +775,6 @@ function ensureHookInstalled() {
|
|
|
770
775
|
if (settings.hooks.UserPromptSubmit.length !== before) modified = true;
|
|
771
776
|
}
|
|
772
777
|
|
|
773
|
-
// Ensure intent-engine hook (unified intent detection + hint injection)
|
|
774
|
-
const intentEngineScript = path.join(METAME_DIR, 'hooks', 'intent-engine.js').replace(/\\/g, '/');
|
|
775
|
-
const intentEngineCommand = `node "${intentEngineScript}"`;
|
|
776
|
-
const intentEngineInstalled = (settings.hooks?.UserPromptSubmit || []).some(entry =>
|
|
777
|
-
entry.hooks?.some(h => h.command && h.command.includes('intent-engine.js'))
|
|
778
|
-
);
|
|
779
|
-
|
|
780
|
-
if (!intentEngineInstalled) {
|
|
781
|
-
if (!settings.hooks) settings.hooks = {};
|
|
782
|
-
if (!settings.hooks.UserPromptSubmit) settings.hooks.UserPromptSubmit = [];
|
|
783
|
-
|
|
784
|
-
settings.hooks.UserPromptSubmit.push({
|
|
785
|
-
hooks: [{
|
|
786
|
-
type: 'command',
|
|
787
|
-
command: intentEngineCommand,
|
|
788
|
-
}]
|
|
789
|
-
});
|
|
790
|
-
modified = true;
|
|
791
|
-
console.log(`${icon("hook")} MetaMe: Intent engine hook installed.`);
|
|
792
|
-
}
|
|
793
|
-
|
|
794
778
|
if (modified) {
|
|
795
779
|
fs.writeFileSync(CLAUDE_SETTINGS, JSON.stringify(settings, null, 2), 'utf8');
|
|
796
780
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function extractPathFromText(input) {
|
|
4
|
+
const text = String(input || '');
|
|
5
|
+
const unixMatch = text.match(/(?:~\/|\/|\.\/|\.\.\/)[^\s,。;;!!??"“”'‘’`]+/);
|
|
6
|
+
if (unixMatch) return unixMatch[0].replace(/[,。;;!!??]+$/, '');
|
|
7
|
+
|
|
8
|
+
const windowsMatch = text.match(/[A-Za-z]:[\\/][^\s,。;;!!??"“”'‘’`]+/);
|
|
9
|
+
if (windowsMatch) return windowsMatch[0].replace(/[,。;;!!??]+$/, '');
|
|
10
|
+
|
|
11
|
+
return '';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function detectCloneIntent(text) {
|
|
15
|
+
if (!text || text.startsWith('/') || text.length < 3) return false;
|
|
16
|
+
const cloneKeywords = ['分身', '再造', '克隆', '副本', '另一个自己', '另一个我'];
|
|
17
|
+
const hasCloneKeyword = cloneKeywords.some(k => text.includes(k));
|
|
18
|
+
if (hasCloneKeyword) {
|
|
19
|
+
const excludePatterns = [/已经/, /存在/, /有了/, /好了/, /完成/, /搞定/, /配置好/, /怎么建/, /如何建/, /方法/, /步骤/];
|
|
20
|
+
if (excludePatterns.some(p => p.test(text))) return false;
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
const actionKeywords = ['新建', '创建', '造', '做一个', '加一个', '增加', '添加'];
|
|
24
|
+
const hasAction = actionKeywords.some(k => text.includes(k));
|
|
25
|
+
if (hasAction && /分身|数字/.test(text)) return true;
|
|
26
|
+
if (/让.*做分身|叫.*做分身|甲.*做分身/.test(text)) return true;
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function detectTeamIntent(text) {
|
|
31
|
+
if (!text || text.startsWith('/') || text.length < 4) return false;
|
|
32
|
+
if (/走team|用team|通过team|team里|team中|团队里|团队中|走团队|用团队|在team|在团队|team.*已经|团队.*已经|team.*讨论|团队.*讨论/.test(text)) return false;
|
|
33
|
+
if ((text.includes('团队') || text.includes('工作组'))) {
|
|
34
|
+
if (/(新建|创建|造一个|加一个|组建|设置|建|搞)/.test(text)) {
|
|
35
|
+
if (/怎么|如何|方法|步骤/.test(text)) return false;
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (/^(新建|创建|建|搞).*团队/.test(text)) return true;
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function isLikelyDirectAgentAction(input) {
|
|
44
|
+
const text = String(input || '').trim();
|
|
45
|
+
return /^(?:请|帮我|麻烦|给我|给这个群|给当前群|在这个群|把这个群|把当前群|将这个群|这个群|当前群|本群|群里|我想|我要|我需要|创建|新建|新增|搞一个|加一个|create|bind|绑定|列出|查看|显示|有哪些|解绑|取消绑定|断开绑定|修改|调整)/i.test(text);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function looksLikeAgentIssueReport(input) {
|
|
49
|
+
const text = String(input || '').trim();
|
|
50
|
+
const hasIssueWords = /(用户反馈|反馈|报错|bug|问题|故障|异常|修复|改一下|修一下|任务|工单|代码)/i.test(text);
|
|
51
|
+
const hasAgentWords = /(agent|智能体|session|会话|目录|工作区|绑定|切换)/i.test(text);
|
|
52
|
+
return hasIssueWords && hasAgentWords;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function classifyAgentIntent(input) {
|
|
56
|
+
const text = String(input || '').trim();
|
|
57
|
+
if (!text || text.startsWith('/')) return null;
|
|
58
|
+
|
|
59
|
+
const workspaceDir = extractPathFromText(text);
|
|
60
|
+
const hasWorkspacePath = !!workspaceDir;
|
|
61
|
+
const directAction = isLikelyDirectAgentAction(text);
|
|
62
|
+
const issueReport = looksLikeAgentIssueReport(text);
|
|
63
|
+
if (issueReport && !directAction) return null;
|
|
64
|
+
|
|
65
|
+
const hasThirdPartyName = /(阿里|百度|腾讯|字节|谷歌|google|openai|微软|microsoft|deepseek|豆包|通义|文心|kimi)/i.test(text);
|
|
66
|
+
const hasAgentWord = /(智能体|agent|助手|机器人)/i.test(text);
|
|
67
|
+
const isAboutOurAgents = /(我的|我们的|当前|这个群|这里的|metame)/i.test(text);
|
|
68
|
+
if (hasThirdPartyName && hasAgentWord && !isAboutOurAgents) return null;
|
|
69
|
+
|
|
70
|
+
const hasAgentContext = /(agent|智能体|工作区|人设|绑定|当前群|这个群|chat|workspace)/i.test(text);
|
|
71
|
+
const wantsList = /(列出|查看|显示|有哪些|list|show)/i.test(text) && /(agent|智能体|工作区|绑定)/i.test(text);
|
|
72
|
+
const wantsUnbind = /(解绑|取消绑定|断开绑定|unbind|unassign)/i.test(text) && hasAgentContext;
|
|
73
|
+
const wantsEditRole =
|
|
74
|
+
((/(角色|职责|人设)/i.test(text) && /(改|修改|调整|更新|变成|改成|改为)/i.test(text)) ||
|
|
75
|
+
/(把这个agent|把当前agent|当前群.*角色|当前群.*职责)/i.test(text));
|
|
76
|
+
const wantsCreate =
|
|
77
|
+
(/(创建|新建|新增|搞一个|加一个|create)/i.test(text) && /(agent|智能体|人设|工作区)/i.test(text) && (directAction || hasWorkspacePath));
|
|
78
|
+
const wantsBind =
|
|
79
|
+
!wantsCreate &&
|
|
80
|
+
(/(绑定|bind)/i.test(text) && hasAgentContext && (directAction || hasWorkspacePath));
|
|
81
|
+
const wantsActivate = /(?:在新群|新群里|新群中|目标群|另一个群).{0,12}(激活|activate)|(?:激活|activate).{0,12}(agent|智能体|绑定)|\/activate/i.test(text);
|
|
82
|
+
const wantsReset =
|
|
83
|
+
/(重置|清空|删除).{0,24}(agent|智能体|助手|角色|职责|人设).{0,12}(角色|职责|人设)?/i.test(text) ||
|
|
84
|
+
/(?:角色|职责|人设).{0,12}(重置|清空|删除)/i.test(text) ||
|
|
85
|
+
/\/agent reset/i.test(text);
|
|
86
|
+
const wantsSoul = /(soul|灵魂|身份设定|人格设定)/i.test(text) && /(查看|修复|编辑|修改|更新|repair|edit|show|看)/i.test(text);
|
|
87
|
+
const wantsAgentDoc =
|
|
88
|
+
/(?:agent|智能体|机器人|bot).{0,12}(文档|手册|说明|guide)/i.test(text) ||
|
|
89
|
+
/(?:怎么|如何|手册|文档|说明).{0,12}(配置|管理|使用).{0,12}(agent|智能体|机器人|bot)/i.test(text) ||
|
|
90
|
+
/(?:agent|智能体|机器人|bot).{0,12}(怎么|如何).{0,12}(配置|管理|使用)/i.test(text);
|
|
91
|
+
|
|
92
|
+
if (wantsList) return { action: 'list', workspaceDir };
|
|
93
|
+
if (wantsUnbind) return { action: 'unbind', workspaceDir };
|
|
94
|
+
if (wantsEditRole) return { action: 'edit_role', workspaceDir };
|
|
95
|
+
if (wantsCreate) return { action: 'create', workspaceDir };
|
|
96
|
+
if (wantsBind) return { action: 'bind', workspaceDir };
|
|
97
|
+
if (wantsAgentDoc) return { action: 'agent_doc', workspaceDir };
|
|
98
|
+
if (wantsActivate) return { action: 'activate', workspaceDir };
|
|
99
|
+
if (wantsReset) return { action: 'reset', workspaceDir };
|
|
100
|
+
if (wantsSoul) return { action: 'soul', workspaceDir };
|
|
101
|
+
if (detectCloneIntent(text)) return { action: 'wizard_clone', workspaceDir };
|
|
102
|
+
if (detectTeamIntent(text)) return { action: 'wizard_team', workspaceDir };
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports = {
|
|
107
|
+
classifyAgentIntent,
|
|
108
|
+
detectCloneIntent,
|
|
109
|
+
detectTeamIntent,
|
|
110
|
+
extractPathFromText,
|
|
111
|
+
};
|