metame-cli 1.5.21 → 1.5.23
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 +25 -24
- package/package.json +1 -1
- package/scripts/agent-intent-shared.js +111 -0
- package/scripts/daemon-agent-commands.js +160 -354
- 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 +18 -5
- 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-session-commands.js +16 -2
- package/scripts/daemon-session-store.js +104 -0
- package/scripts/daemon-team-workflow.js +146 -0
- package/scripts/daemon.js +14 -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/resolve-yaml.js +3 -0
- package/scripts/runtime-bootstrap.js +77 -0
- package/scripts/hooks/intent-engine.js +0 -75
- package/scripts/hooks/team-context.js +0 -143
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* MetaMe Team Context Hook — UserPromptSubmit
|
|
4
|
-
*
|
|
5
|
-
* Detects communication intent towards team members in the prompt.
|
|
6
|
-
* If found, injects targeted dispatch_to hint(s) for only those members.
|
|
7
|
-
* Zero injection when no communication intent detected → zero wasted tokens.
|
|
8
|
-
*
|
|
9
|
-
* Triggers when the prompt contains:
|
|
10
|
-
* - A communication verb (告诉/让/发给/和...讨论/...) near a member nickname
|
|
11
|
-
* - Or a member nickname in a communication context
|
|
12
|
-
*/
|
|
13
|
-
'use strict';
|
|
14
|
-
|
|
15
|
-
const fs = require('fs');
|
|
16
|
-
const path = require('path');
|
|
17
|
-
const os = require('os');
|
|
18
|
-
|
|
19
|
-
const METAME_DIR = path.join(os.homedir(), '.metame');
|
|
20
|
-
|
|
21
|
-
// ── Communication intent patterns ────────────────────────────────────────────
|
|
22
|
-
// Three structural patterns:
|
|
23
|
-
// A) verb → name: 告诉工匠 / 发给builder / 通知乙
|
|
24
|
-
// B) name → verb: 工匠你来 / builder帮我 / 乙去做
|
|
25
|
-
// C) prep + name: 和工匠讨论 / 跟builder说 / 与乙沟通 (name between prep and verb)
|
|
26
|
-
|
|
27
|
-
const BEFORE_NAME_ZH = ['告诉', '通知', '让', '叫', '派', '交给', '转给', '发给', '联系', '找', '请', '问', '发消息给'];
|
|
28
|
-
const BEFORE_NAME_EN = ['tell', 'ask', 'notify', 'send to', 'assign to', 'delegate to', 'message', 'ping', 'contact'];
|
|
29
|
-
const AFTER_NAME_ZH = ['你来', '来做', '去做', '帮我', '帮忙', '负责', '处理', '跟进'];
|
|
30
|
-
const AFTER_NAME_EN = ['help', 'do this', 'handle', 'take care', 'follow up'];
|
|
31
|
-
// Prepositions that introduce a discussion partner (name follows immediately)
|
|
32
|
-
const PREP_ZH = ['和', '跟', '与'];
|
|
33
|
-
const DISC_EN = ['discuss with', 'talk to', 'chat with', 'coordinate with', 'sync with', 'work with'];
|
|
34
|
-
|
|
35
|
-
function hasCommIntent(text, nickname) {
|
|
36
|
-
const t = text.toLowerCase();
|
|
37
|
-
const n = nickname.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
38
|
-
|
|
39
|
-
// A) verb → name (within 15 chars)
|
|
40
|
-
for (const v of BEFORE_NAME_ZH) {
|
|
41
|
-
if (new RegExp(`${v}.{0,15}${n}`, 'u').test(t)) return true;
|
|
42
|
-
}
|
|
43
|
-
for (const v of BEFORE_NAME_EN) {
|
|
44
|
-
if (new RegExp(`${v}.{0,20}${n}`, 'i').test(t)) return true;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// B) name → verb (within 8 chars)
|
|
48
|
-
for (const v of AFTER_NAME_ZH) {
|
|
49
|
-
if (new RegExp(`${n}.{0,8}${v}`, 'u').test(t)) return true;
|
|
50
|
-
}
|
|
51
|
-
for (const v of AFTER_NAME_EN) {
|
|
52
|
-
if (new RegExp(`${n}.{0,10}${v}`, 'i').test(t)) return true;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// C) prep + name (和工匠/跟builder — prep within 3 chars before name)
|
|
56
|
-
for (const p of PREP_ZH) {
|
|
57
|
-
if (new RegExp(`${p}.{0,3}${n}`, 'u').test(t)) return true;
|
|
58
|
-
}
|
|
59
|
-
for (const v of DISC_EN) {
|
|
60
|
-
if (new RegExp(`${v}.{0,20}${n}`, 'i').test(t)) return true;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// ── Main ──────────────────────────────────────────────────────────────────────
|
|
67
|
-
function exit() { process.exit(0); }
|
|
68
|
-
|
|
69
|
-
let raw = '';
|
|
70
|
-
process.stdin.setEncoding('utf8');
|
|
71
|
-
process.stdin.on('data', c => { raw += c; });
|
|
72
|
-
process.stdin.on('end', () => {
|
|
73
|
-
try { run(JSON.parse(raw)); } catch { exit(); }
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
function run(data) {
|
|
77
|
-
const projectKey = process.env.METAME_PROJECT;
|
|
78
|
-
if (!projectKey || process.env.METAME_INTERNAL_PROMPT === '1') return exit();
|
|
79
|
-
|
|
80
|
-
const prompt = (data.prompt || data.user_prompt || '').trim();
|
|
81
|
-
if (!prompt) return exit();
|
|
82
|
-
|
|
83
|
-
// Load config
|
|
84
|
-
let config;
|
|
85
|
-
try {
|
|
86
|
-
const yaml = require('../resolve-yaml');
|
|
87
|
-
config = yaml.load(fs.readFileSync(path.join(METAME_DIR, 'daemon.yaml'), 'utf8'));
|
|
88
|
-
} catch { return exit(); }
|
|
89
|
-
|
|
90
|
-
if (!config || !config.projects) return exit();
|
|
91
|
-
|
|
92
|
-
// Collect all team members across all projects (caller may be top-level or member)
|
|
93
|
-
const allMembers = [];
|
|
94
|
-
for (const [parentKey, parent] of Object.entries(config.projects)) {
|
|
95
|
-
if (!Array.isArray(parent.team)) continue;
|
|
96
|
-
for (const member of parent.team) {
|
|
97
|
-
if (member.key === projectKey) continue; // skip self
|
|
98
|
-
allMembers.push({ member, parentKey, parent });
|
|
99
|
-
}
|
|
100
|
-
// Also allow dispatching to parent project itself (escalation)
|
|
101
|
-
if (parent.team.some(m => m.key === projectKey)) {
|
|
102
|
-
allMembers.push({
|
|
103
|
-
member: { key: parentKey, name: parent.name, nicknames: parent.nicknames },
|
|
104
|
-
parentKey,
|
|
105
|
-
parent,
|
|
106
|
-
isParent: true,
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (allMembers.length === 0) return exit();
|
|
112
|
-
|
|
113
|
-
const dispatchBin = path.join(METAME_DIR, 'bin', 'dispatch_to');
|
|
114
|
-
|
|
115
|
-
// Find members with communication intent in this prompt
|
|
116
|
-
const hits = [];
|
|
117
|
-
for (const { member, isParent } of allMembers) {
|
|
118
|
-
const nicks = [member.key, member.name, ...(Array.isArray(member.nicknames) ? member.nicknames : [])].filter(Boolean);
|
|
119
|
-
const matched = nicks.some(n => hasCommIntent(prompt, n));
|
|
120
|
-
if (matched) hits.push({ member, isParent });
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (hits.length === 0) return exit();
|
|
124
|
-
|
|
125
|
-
// Build targeted hint for matched members only
|
|
126
|
-
const lines = hits.map(({ member, isParent }) => {
|
|
127
|
-
const target = member.peer ? `${member.peer}:${member.key}` : member.key;
|
|
128
|
-
const location = member.peer ? ` [远端:${member.peer}]` : '';
|
|
129
|
-
const label = isParent ? `${member.key}(${member.name || member.key}, 向上汇报)` : `${member.key}(${member.name || member.key}${location})`;
|
|
130
|
-
return `- ${label}: \`${dispatchBin} --from ${projectKey} ${target} "消息"\``;
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
const hint = [
|
|
134
|
-
`[团队联络提示]`,
|
|
135
|
-
`以下成员可通过 dispatch_to 联络:`,
|
|
136
|
-
...lines,
|
|
137
|
-
].join('\n');
|
|
138
|
-
|
|
139
|
-
process.stdout.write(JSON.stringify({
|
|
140
|
-
hookSpecificOutput: { additionalSystemPrompt: hint },
|
|
141
|
-
}));
|
|
142
|
-
exit();
|
|
143
|
-
}
|