mcp-probe-kit 3.2.0 → 3.6.0
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 +25 -7
- package/build/index.js +45 -79
- package/build/lib/__tests__/agents-md-template.unit.test.js +1 -0
- package/build/lib/__tests__/dev-workflow.unit.test.js +22 -0
- package/build/lib/__tests__/handles.unit.test.js +19 -0
- package/build/lib/__tests__/mcp-apps.unit.test.d.ts +1 -0
- package/build/lib/__tests__/mcp-apps.unit.test.js +52 -0
- package/build/lib/__tests__/mcp-tool-skill-registry.unit.test.d.ts +1 -0
- package/build/lib/__tests__/mcp-tool-skill-registry.unit.test.js +18 -0
- package/build/lib/__tests__/memory-client.unit.test.js +105 -0
- package/build/lib/__tests__/memory-orchestration.unit.test.d.ts +1 -0
- package/build/lib/__tests__/memory-orchestration.unit.test.js +88 -0
- package/build/lib/__tests__/memory-payload.unit.test.d.ts +1 -0
- package/build/lib/__tests__/memory-payload.unit.test.js +35 -0
- package/build/lib/__tests__/quality-constraints.unit.test.d.ts +1 -0
- package/build/lib/__tests__/quality-constraints.unit.test.js +54 -0
- package/build/lib/__tests__/spec-gate.unit.test.d.ts +1 -0
- package/build/lib/__tests__/spec-gate.unit.test.js +54 -0
- package/build/lib/__tests__/spec-validator.unit.test.js +106 -74
- package/build/lib/__tests__/task-defaults.unit.test.d.ts +1 -0
- package/build/lib/__tests__/task-defaults.unit.test.js +27 -0
- package/build/lib/__tests__/workflow-skill-installer.unit.test.d.ts +1 -0
- package/build/lib/__tests__/workflow-skill-installer.unit.test.js +110 -0
- package/build/lib/agents-md-template.js +40 -32
- package/build/lib/cursor-history-client.d.ts +54 -0
- package/build/lib/cursor-history-client.js +240 -0
- package/build/lib/dev-workflow.d.ts +36 -0
- package/build/lib/dev-workflow.js +497 -0
- package/build/lib/handles.d.ts +31 -0
- package/build/lib/handles.js +36 -0
- package/build/lib/mcp-apps.d.ts +14 -0
- package/build/lib/mcp-apps.js +234 -0
- package/build/lib/mcp-tool-skill-registry.d.ts +46 -0
- package/build/lib/mcp-tool-skill-registry.js +256 -0
- package/build/lib/memory-client.d.ts +19 -0
- package/build/lib/memory-client.js +69 -0
- package/build/lib/memory-orchestration.d.ts +5 -0
- package/build/lib/memory-orchestration.js +20 -0
- package/build/lib/merge-agents-md.d.ts +2 -2
- package/build/lib/merge-agents-md.js +7 -4
- package/build/lib/output-schema-registry.d.ts +11 -0
- package/build/lib/output-schema-registry.js +80 -0
- package/build/lib/quality-constraints.d.ts +54 -0
- package/build/lib/quality-constraints.js +155 -0
- package/build/lib/skill-bridge.js +12 -12
- package/build/lib/spec-gate.d.ts +32 -0
- package/build/lib/spec-gate.js +83 -0
- package/build/lib/spec-validator.js +16 -3
- package/build/lib/task-defaults.d.ts +6 -0
- package/build/lib/task-defaults.js +20 -0
- package/build/lib/template-loader.js +83 -23
- package/build/lib/tool-annotations.js +3 -0
- package/build/lib/toolset-manager.js +2 -0
- package/build/lib/workflow-skill-installer.d.ts +38 -0
- package/build/lib/workflow-skill-installer.js +158 -0
- package/build/lib/workflow-skill-template.d.ts +9 -0
- package/build/lib/workflow-skill-template.js +85 -0
- package/build/lib/workflow-skill-version.d.ts +15 -0
- package/build/lib/workflow-skill-version.js +68 -0
- package/build/resources/ui-ux-data/guidelines/vercel-web-interface.json +1632 -1632
- package/build/resources/ui-ux-data/metadata.json +30 -30
- package/build/resources/ui-ux-data/shadcn/blocks.json +2541 -2541
- package/build/resources/ui-ux-data/shadcn/components.json +997 -997
- package/build/resources/ui-ux-data/themes/presets.json +483 -483
- package/build/schemas/index.d.ts +110 -0
- package/build/schemas/index.js +1 -0
- package/build/schemas/memory-tools.d.ts +83 -0
- package/build/schemas/memory-tools.js +43 -0
- package/build/schemas/orchestration-tools.d.ts +8 -0
- package/build/schemas/orchestration-tools.js +8 -0
- package/build/schemas/output/code-insight-tools.d.ts +65 -0
- package/build/schemas/output/code-insight-tools.js +42 -0
- package/build/schemas/output/memory-tools.d.ts +576 -0
- package/build/schemas/output/memory-tools.js +148 -0
- package/build/schemas/project-tools.d.ts +19 -0
- package/build/schemas/project-tools.js +20 -0
- package/build/tools/__tests__/cursor-history.unit.test.d.ts +1 -0
- package/build/tools/__tests__/cursor-history.unit.test.js +38 -0
- package/build/tools/__tests__/delete_memory_asset.unit.test.d.ts +1 -0
- package/build/tools/__tests__/delete_memory_asset.unit.test.js +87 -0
- package/build/tools/__tests__/search_memory.unit.test.js +1 -0
- package/build/tools/__tests__/start_bugfix.unit.test.js +34 -1
- package/build/tools/__tests__/update_memory_asset.unit.test.d.ts +1 -0
- package/build/tools/__tests__/update_memory_asset.unit.test.js +82 -0
- package/build/tools/__tests__/workflow.unit.test.d.ts +1 -0
- package/build/tools/__tests__/workflow.unit.test.js +24 -0
- package/build/tools/check_spec.js +16 -16
- package/build/tools/code_insight.js +46 -42
- package/build/tools/code_review.js +11 -4
- package/build/tools/cursor_read_conversation.d.ts +7 -0
- package/build/tools/cursor_read_conversation.js +36 -0
- package/build/tools/delete_memory_asset.d.ts +7 -0
- package/build/tools/delete_memory_asset.js +57 -0
- package/build/tools/fix_bug.js +161 -161
- package/build/tools/gencommit.js +60 -60
- package/build/tools/index.d.ts +3 -0
- package/build/tools/index.js +3 -0
- package/build/tools/init_project_context.js +432 -432
- package/build/tools/search_memory.js +5 -2
- package/build/tools/start_bugfix.js +37 -4
- package/build/tools/start_feature.js +4 -3
- package/build/tools/start_product.js +1 -1
- package/build/tools/start_ui.js +22 -4
- package/build/tools/ui-ux-tools.d.ts +3 -0
- package/build/tools/ui-ux-tools.js +302 -290
- package/build/tools/update_memory_asset.d.ts +7 -0
- package/build/tools/update_memory_asset.js +98 -0
- package/build/tools/workflow.d.ts +13 -0
- package/build/tools/workflow.js +69 -0
- package/build/utils/__tests__/vercel-guidelines-sync.unit.test.js +12 -12
- package/build/utils/design-reasoning-engine.d.ts +2 -0
- package/build/utils/design-reasoning-engine.js +3 -0
- package/build/utils/themes-sync.js +8 -8
- package/package.json +6 -3
- package/build/resources/index.d.ts +0 -4
- package/build/resources/index.js +0 -4
- package/build/resources/tool-params-guide.d.ts +0 -571
- package/build/resources/tool-params-guide.js +0 -488
- package/build/tools/analyze_project.d.ts +0 -1
- package/build/tools/analyze_project.js +0 -527
- package/build/tools/check_deps.d.ts +0 -13
- package/build/tools/check_deps.js +0 -204
- package/build/tools/convert.d.ts +0 -13
- package/build/tools/convert.js +0 -599
- package/build/tools/css_order.d.ts +0 -13
- package/build/tools/css_order.js +0 -81
- package/build/tools/debug.d.ts +0 -13
- package/build/tools/debug.js +0 -131
- package/build/tools/design2code.d.ts +0 -20
- package/build/tools/design2code.js +0 -426
- package/build/tools/detect_shell.d.ts +0 -6
- package/build/tools/detect_shell.js +0 -151
- package/build/tools/explain.d.ts +0 -13
- package/build/tools/explain.js +0 -390
- package/build/tools/fix.d.ts +0 -13
- package/build/tools/fix.js +0 -303
- package/build/tools/gen_mock.d.ts +0 -22
- package/build/tools/gen_mock.js +0 -269
- package/build/tools/gen_skill.d.ts +0 -13
- package/build/tools/gen_skill.js +0 -560
- package/build/tools/genapi.d.ts +0 -13
- package/build/tools/genapi.js +0 -174
- package/build/tools/genchangelog.d.ts +0 -13
- package/build/tools/genchangelog.js +0 -250
- package/build/tools/gendoc.d.ts +0 -13
- package/build/tools/gendoc.js +0 -232
- package/build/tools/genpr.d.ts +0 -13
- package/build/tools/genpr.js +0 -194
- package/build/tools/genreadme.d.ts +0 -13
- package/build/tools/genreadme.js +0 -626
- package/build/tools/gensql.d.ts +0 -13
- package/build/tools/gensql.js +0 -320
- package/build/tools/genui.d.ts +0 -13
- package/build/tools/genui.js +0 -803
- package/build/tools/init_component_catalog.d.ts +0 -22
- package/build/tools/init_component_catalog.js +0 -809
- package/build/tools/init_setting.d.ts +0 -13
- package/build/tools/init_setting.js +0 -47
- package/build/tools/perf.d.ts +0 -13
- package/build/tools/perf.js +0 -409
- package/build/tools/render_ui.d.ts +0 -22
- package/build/tools/render_ui.js +0 -384
- package/build/tools/resolve_conflict.d.ts +0 -13
- package/build/tools/resolve_conflict.js +0 -349
- package/build/tools/security_scan.d.ts +0 -22
- package/build/tools/security_scan.js +0 -323
- package/build/tools/split.d.ts +0 -13
- package/build/tools/split.js +0 -599
- package/build/tools/start_api.d.ts +0 -13
- package/build/tools/start_api.js +0 -193
- package/build/tools/start_doc.d.ts +0 -13
- package/build/tools/start_doc.js +0 -207
- package/build/tools/start_refactor.d.ts +0 -13
- package/build/tools/start_refactor.js +0 -188
- package/build/tools/start_release.d.ts +0 -13
- package/build/tools/start_release.js +0 -167
- package/build/tools/start_review.d.ts +0 -13
- package/build/tools/start_review.js +0 -175
- /package/build/{utils/design-docs-generator.d.ts → lib/__tests__/dev-workflow.unit.test.d.ts} +0 -0
- /package/build/{utils/design-docs-generator.js → lib/__tests__/handles.unit.test.d.ts} +0 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Apps 预览 HTML 生成(text/html resource)
|
|
3
|
+
*/
|
|
4
|
+
export const MCP_UI_APP_TOOLS = new Set([
|
|
5
|
+
'ui_design_system',
|
|
6
|
+
'ui_search',
|
|
7
|
+
'sync_ui_data',
|
|
8
|
+
'start_ui',
|
|
9
|
+
'start_product',
|
|
10
|
+
'search_memory',
|
|
11
|
+
'code_insight',
|
|
12
|
+
]);
|
|
13
|
+
export function isMcpUiAppTool(name) {
|
|
14
|
+
return MCP_UI_APP_TOOLS.has(name);
|
|
15
|
+
}
|
|
16
|
+
export function escapeHtml(value) {
|
|
17
|
+
return value
|
|
18
|
+
.replace(/&/g, '&')
|
|
19
|
+
.replace(/</g, '<')
|
|
20
|
+
.replace(/>/g, '>')
|
|
21
|
+
.replace(/"/g, '"')
|
|
22
|
+
.replace(/'/g, ''');
|
|
23
|
+
}
|
|
24
|
+
function extractTextBlocks(result) {
|
|
25
|
+
if (!Array.isArray(result.content)) {
|
|
26
|
+
return '';
|
|
27
|
+
}
|
|
28
|
+
return result.content
|
|
29
|
+
.map((item) => {
|
|
30
|
+
if (!item || typeof item !== 'object') {
|
|
31
|
+
return '';
|
|
32
|
+
}
|
|
33
|
+
const text = item.text;
|
|
34
|
+
return typeof text === 'string' ? text : '';
|
|
35
|
+
})
|
|
36
|
+
.filter(Boolean)
|
|
37
|
+
.join('\n\n');
|
|
38
|
+
}
|
|
39
|
+
const BASE_STYLES = `
|
|
40
|
+
:root { color-scheme: light dark; --bg: #f4f7fb; --card: #fff; --text: #1e2a35; --muted: #4f6880; --accent: #2563eb; --ok: #15803d; --warn: #b45309; --border: #d8e2ec; }
|
|
41
|
+
@media (prefers-color-scheme: dark) {
|
|
42
|
+
:root { --bg: #0f1720; --card: #162231; --text: #e8f0fa; --muted: #9fb3c8; --accent: #60a5fa; --ok: #4ade80; --warn: #fbbf24; --border: #2a3b4f; }
|
|
43
|
+
}
|
|
44
|
+
* { box-sizing: border-box; }
|
|
45
|
+
body { font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; margin: 0; background: var(--bg); color: var(--text); }
|
|
46
|
+
.wrap { max-width: 1040px; margin: 0 auto; padding: 20px; }
|
|
47
|
+
.card { background: var(--card); border: 1px solid var(--border); border-radius: 14px; padding: 16px 18px; margin-bottom: 14px; }
|
|
48
|
+
h1 { margin: 0 0 6px; font-size: 22px; }
|
|
49
|
+
h2 { margin: 0 0 10px; font-size: 15px; color: var(--muted); font-weight: 600; }
|
|
50
|
+
.meta { color: var(--muted); font-size: 12px; }
|
|
51
|
+
.badge { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; }
|
|
52
|
+
.badge-ok { background: color-mix(in srgb, var(--ok) 18%, transparent); color: var(--ok); }
|
|
53
|
+
.badge-warn { background: color-mix(in srgb, var(--warn) 18%, transparent); color: var(--warn); }
|
|
54
|
+
.badge-info { background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent); }
|
|
55
|
+
pre, code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
|
|
56
|
+
pre { white-space: pre-wrap; word-break: break-word; background: #0f1720; color: #d9e7f7; border-radius: 10px; padding: 12px; font-size: 12px; line-height: 1.45; margin: 0; }
|
|
57
|
+
.item { border: 1px solid var(--border); border-radius: 12px; padding: 12px; margin-bottom: 10px; }
|
|
58
|
+
.item h3 { margin: 0 0 6px; font-size: 15px; }
|
|
59
|
+
.row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 8px; }
|
|
60
|
+
.score { font-size: 12px; color: var(--muted); }
|
|
61
|
+
.summary { font-size: 13px; line-height: 1.5; margin: 6px 0; }
|
|
62
|
+
.actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
|
|
63
|
+
button { border: 1px solid var(--border); background: var(--card); color: var(--text); border-radius: 8px; padding: 6px 10px; font-size: 12px; cursor: pointer; }
|
|
64
|
+
button:hover { border-color: var(--accent); color: var(--accent); }
|
|
65
|
+
details { margin-top: 8px; }
|
|
66
|
+
summary { cursor: pointer; color: var(--accent); font-size: 13px; }
|
|
67
|
+
table { width: 100%; border-collapse: collapse; font-size: 13px; }
|
|
68
|
+
th, td { text-align: left; padding: 8px; border-bottom: 1px solid var(--border); vertical-align: top; }
|
|
69
|
+
a { color: var(--accent); }
|
|
70
|
+
`;
|
|
71
|
+
function wrapAppHtml(title, body) {
|
|
72
|
+
const now = new Date().toISOString();
|
|
73
|
+
return `<!doctype html>
|
|
74
|
+
<html lang="zh-CN">
|
|
75
|
+
<head>
|
|
76
|
+
<meta charset="utf-8">
|
|
77
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
78
|
+
<title>${escapeHtml(title)} · MCP Apps</title>
|
|
79
|
+
<style>${BASE_STYLES}</style>
|
|
80
|
+
</head>
|
|
81
|
+
<body>
|
|
82
|
+
<div class="wrap">
|
|
83
|
+
<div class="card">
|
|
84
|
+
<h1>${escapeHtml(title)}</h1>
|
|
85
|
+
<div class="meta">Generated at ${escapeHtml(now)} · MCP Probe Kit Apps</div>
|
|
86
|
+
</div>
|
|
87
|
+
${body}
|
|
88
|
+
</div>
|
|
89
|
+
</body>
|
|
90
|
+
</html>`;
|
|
91
|
+
}
|
|
92
|
+
export function buildGenericMcpAppHtml(toolName, args, result) {
|
|
93
|
+
const structured = result.structuredContent
|
|
94
|
+
? JSON.stringify(result.structuredContent, null, 2)
|
|
95
|
+
: '{}';
|
|
96
|
+
const argJson = JSON.stringify(args ?? {}, null, 2);
|
|
97
|
+
const textBlocks = extractTextBlocks(result);
|
|
98
|
+
return wrapAppHtml(toolName, `<div class="card"><h2>Text Output</h2><pre>${escapeHtml(textBlocks || '(no text output)')}</pre></div>
|
|
99
|
+
<div class="card"><h2>Structured Content</h2><pre>${escapeHtml(structured)}</pre></div>
|
|
100
|
+
<div class="card"><h2>Arguments</h2><pre>${escapeHtml(argJson)}</pre></div>`);
|
|
101
|
+
}
|
|
102
|
+
export function buildSearchMemoryAppHtml(args, result) {
|
|
103
|
+
const structured = result.structuredContent && typeof result.structuredContent === 'object'
|
|
104
|
+
? result.structuredContent
|
|
105
|
+
: {};
|
|
106
|
+
const results = Array.isArray(structured.results) ? structured.results : [];
|
|
107
|
+
const query = typeof structured.query === 'string' ? structured.query : '';
|
|
108
|
+
const count = typeof structured.count === 'number' ? structured.count : results.length;
|
|
109
|
+
const handles = structured.handles && typeof structured.handles === 'object'
|
|
110
|
+
? structured.handles
|
|
111
|
+
: {};
|
|
112
|
+
const itemsHtml = results.length === 0
|
|
113
|
+
? '<div class="card"><p>未找到相关记忆</p></div>'
|
|
114
|
+
: results
|
|
115
|
+
.map((raw, index) => {
|
|
116
|
+
const item = raw && typeof raw === 'object' ? raw : {};
|
|
117
|
+
const id = typeof item.id === 'string' ? item.id : '';
|
|
118
|
+
const name = typeof item.name === 'string' ? item.name : `result-${index + 1}`;
|
|
119
|
+
const type = typeof item.type === 'string' ? item.type : 'unknown';
|
|
120
|
+
const score = typeof item.score === 'number' ? item.score.toFixed(3) : '—';
|
|
121
|
+
const summary = typeof item.summary === 'string' ? item.summary : '';
|
|
122
|
+
const description = typeof item.description === 'string' ? item.description : '';
|
|
123
|
+
const content = typeof item.content === 'string' ? item.content : '';
|
|
124
|
+
const tags = Array.isArray(item.tags) ? item.tags.filter((t) => typeof t === 'string') : [];
|
|
125
|
+
const readPayload = JSON.stringify({ asset_id: id });
|
|
126
|
+
return `<article class="item" data-id="${escapeHtml(id)}">
|
|
127
|
+
<h3>${escapeHtml(name)} <span class="badge badge-info">${escapeHtml(type)}</span></h3>
|
|
128
|
+
<div class="row"><span class="score">score=${escapeHtml(score)}</span>${tags.map((t) => `<span class="badge badge-info">${escapeHtml(t)}</span>`).join('')}</div>
|
|
129
|
+
${summary ? `<div class="summary"><strong>摘要</strong> ${escapeHtml(summary)}</div>` : ''}
|
|
130
|
+
${description ? `<div class="summary"><strong>描述</strong> ${escapeHtml(description)}</div>` : ''}
|
|
131
|
+
<div class="actions">
|
|
132
|
+
<button type="button" data-copy='${escapeHtml(readPayload)}'>复制 read_memory_asset</button>
|
|
133
|
+
<code>id: ${escapeHtml(id)}</code>
|
|
134
|
+
</div>
|
|
135
|
+
${content ? `<details><summary>展开 content</summary><pre>${escapeHtml(content)}</pre></details>` : ''}
|
|
136
|
+
</article>`;
|
|
137
|
+
})
|
|
138
|
+
.join('');
|
|
139
|
+
const script = `<script>
|
|
140
|
+
document.querySelectorAll('button[data-copy]').forEach((btn) => {
|
|
141
|
+
btn.addEventListener('click', async () => {
|
|
142
|
+
const payload = btn.getAttribute('data-copy') || '';
|
|
143
|
+
try {
|
|
144
|
+
await navigator.clipboard.writeText('read_memory_asset ' + payload);
|
|
145
|
+
btn.textContent = '已复制';
|
|
146
|
+
setTimeout(() => { btn.textContent = '复制 read_memory_asset'; }, 1200);
|
|
147
|
+
} catch (e) {
|
|
148
|
+
btn.textContent = '复制失败';
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
</script>`;
|
|
153
|
+
return wrapAppHtml('search_memory', `<div class="card">
|
|
154
|
+
<h2>检索结果</h2>
|
|
155
|
+
<div class="meta">query: ${escapeHtml(query || '(n/a)')} · ${count} 条</div>
|
|
156
|
+
</div>
|
|
157
|
+
${itemsHtml}
|
|
158
|
+
<div class="card"><h2>Handles</h2><pre>${escapeHtml(JSON.stringify(handles, null, 2))}</pre></div>
|
|
159
|
+
${script}`);
|
|
160
|
+
}
|
|
161
|
+
function statusBadge(status) {
|
|
162
|
+
if (status === 'ok')
|
|
163
|
+
return 'badge-ok';
|
|
164
|
+
if (status === 'ambiguous' || status === 'degraded')
|
|
165
|
+
return 'badge-warn';
|
|
166
|
+
return 'badge-info';
|
|
167
|
+
}
|
|
168
|
+
export function buildCodeInsightAppHtml(args, result) {
|
|
169
|
+
const structured = result.structuredContent && typeof result.structuredContent === 'object'
|
|
170
|
+
? result.structuredContent
|
|
171
|
+
: {};
|
|
172
|
+
const status = typeof structured.status === 'string' ? structured.status : 'unknown';
|
|
173
|
+
const summary = typeof structured.summary === 'string' ? structured.summary : '';
|
|
174
|
+
const provider = typeof structured.provider === 'string' ? structured.provider : '';
|
|
175
|
+
const mode = structured.mode && typeof structured.mode === 'object'
|
|
176
|
+
? structured.mode
|
|
177
|
+
: {};
|
|
178
|
+
const warnings = Array.isArray(structured.warnings)
|
|
179
|
+
? structured.warnings.filter((w) => typeof w === 'string')
|
|
180
|
+
: [];
|
|
181
|
+
const executions = Array.isArray(structured.executions) ? structured.executions : [];
|
|
182
|
+
const ambiguities = Array.isArray(structured.ambiguities) ? structured.ambiguities : [];
|
|
183
|
+
const handles = structured.handles && typeof structured.handles === 'object' ? structured.handles : {};
|
|
184
|
+
const nextAction = typeof structured.nextAction === 'string' ? structured.nextAction : '';
|
|
185
|
+
const execRows = executions
|
|
186
|
+
.map((raw) => {
|
|
187
|
+
const row = raw && typeof raw === 'object' ? raw : {};
|
|
188
|
+
const tool = typeof row.tool === 'string' ? row.tool : '—';
|
|
189
|
+
const ok = row.ok === true;
|
|
190
|
+
const text = typeof row.text === 'string' ? row.text.slice(0, 400) : '';
|
|
191
|
+
return `<tr><td>${escapeHtml(tool)}</td><td><span class="badge ${ok ? 'badge-ok' : 'badge-warn'}">${ok ? 'ok' : 'fail'}</span></td><td><pre>${escapeHtml(text || '—')}</pre></td></tr>`;
|
|
192
|
+
})
|
|
193
|
+
.join('');
|
|
194
|
+
const ambiguityHtml = ambiguities.length > 0
|
|
195
|
+
? `<div class="card"><h2>歧义候选</h2><pre>${escapeHtml(JSON.stringify(ambiguities, null, 2))}</pre></div>`
|
|
196
|
+
: '';
|
|
197
|
+
const graphSnapshot = handles && typeof handles === 'object' && typeof handles.graph_snapshot === 'string'
|
|
198
|
+
? String(handles.graph_snapshot)
|
|
199
|
+
: '';
|
|
200
|
+
const graphResource = handles && typeof handles === 'object' && typeof handles.graph_resource === 'string'
|
|
201
|
+
? String(handles.graph_resource)
|
|
202
|
+
: 'probe://graph/latest';
|
|
203
|
+
return wrapAppHtml('code_insight', `<div class="card">
|
|
204
|
+
<h2>分析摘要</h2>
|
|
205
|
+
<div class="row">
|
|
206
|
+
<span class="badge ${statusBadge(status)}">${escapeHtml(status)}</span>
|
|
207
|
+
<span class="meta">provider: ${escapeHtml(provider || 'n/a')}</span>
|
|
208
|
+
<span class="meta">mode: ${escapeHtml(String(mode.requested ?? '?'))} → ${escapeHtml(String(mode.resolved ?? '?'))}</span>
|
|
209
|
+
</div>
|
|
210
|
+
<p class="summary">${escapeHtml(summary || '(no summary)')}</p>
|
|
211
|
+
${nextAction ? `<p class="summary"><strong>下一步</strong> ${escapeHtml(nextAction)}</p>` : ''}
|
|
212
|
+
${warnings.length > 0 ? `<p class="summary"><strong>警告</strong> ${escapeHtml(warnings.join(' · '))}</p>` : ''}
|
|
213
|
+
<div class="actions">
|
|
214
|
+
<a href="${escapeHtml(graphResource)}">图谱资源</a>
|
|
215
|
+
${graphSnapshot ? `<a href="${escapeHtml(graphSnapshot)}">本次快照</a>` : ''}
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
<div class="card">
|
|
219
|
+
<h2>执行详情</h2>
|
|
220
|
+
<table><thead><tr><th>Tool</th><th>Status</th><th>Output</th></tr></thead><tbody>${execRows || '<tr><td colspan="3">无</td></tr>'}</tbody></table>
|
|
221
|
+
</div>
|
|
222
|
+
${ambiguityHtml}
|
|
223
|
+
<div class="card"><h2>Arguments</h2><pre>${escapeHtml(JSON.stringify(args ?? {}, null, 2))}</pre></div>
|
|
224
|
+
<div class="card"><h2>Handles</h2><pre>${escapeHtml(JSON.stringify(handles, null, 2))}</pre></div>`);
|
|
225
|
+
}
|
|
226
|
+
export function buildMcpAppHtml(toolName, args, result) {
|
|
227
|
+
if (toolName === 'search_memory') {
|
|
228
|
+
return buildSearchMemoryAppHtml(args, result);
|
|
229
|
+
}
|
|
230
|
+
if (toolName === 'code_insight') {
|
|
231
|
+
return buildCodeInsightAppHtml(args, result);
|
|
232
|
+
}
|
|
233
|
+
return buildGenericMcpAppHtml(toolName, args, result);
|
|
234
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP 工具「何时调用」注册表 — Skill 模板唯一真相源。
|
|
3
|
+
*
|
|
4
|
+
* **增删改工具时必同步本文件**(`npm run verify-workflow-skill` / prebuild 会校验)。
|
|
5
|
+
* 与 `src/schemas/*` 的 `allToolSchemas` 工具名必须一一对应。
|
|
6
|
+
*/
|
|
7
|
+
export interface McpToolSkillEntry {
|
|
8
|
+
name: string;
|
|
9
|
+
/** Skill 表格「何时调用」列(中文) */
|
|
10
|
+
whenToCall: string;
|
|
11
|
+
}
|
|
12
|
+
export interface McpToolSkillGroup {
|
|
13
|
+
id: string;
|
|
14
|
+
title: string;
|
|
15
|
+
note?: string;
|
|
16
|
+
tools: McpToolSkillEntry[];
|
|
17
|
+
}
|
|
18
|
+
/** 意图速查:用户信号 → 第一个应调的 MCP */
|
|
19
|
+
export interface McpIntentQuickEntry {
|
|
20
|
+
signal: string;
|
|
21
|
+
firstTool: string;
|
|
22
|
+
}
|
|
23
|
+
export declare const MCP_INTENT_QUICK_LOOKUP: McpIntentQuickEntry[];
|
|
24
|
+
export declare const MCP_TOOL_SKILL_GROUPS: McpToolSkillGroup[];
|
|
25
|
+
export declare const MCP_SKILL_COMMON_FLOWS: readonly [{
|
|
26
|
+
readonly label: "新功能";
|
|
27
|
+
readonly chain: "start_feature → add_feature → check_spec(通过)→ 写代码 → gentest → gencommit";
|
|
28
|
+
}, {
|
|
29
|
+
readonly label: "修 Bug";
|
|
30
|
+
readonly chain: "start_bugfix → fix_bug → 改代码 → gentest → 跑测试 → memorize_asset(type=bugfix)";
|
|
31
|
+
}, {
|
|
32
|
+
readonly label: "不熟代码";
|
|
33
|
+
readonly chain: "code_insight → 再 start_feature / start_bugfix";
|
|
34
|
+
}, {
|
|
35
|
+
readonly label: "大重构";
|
|
36
|
+
readonly chain: "code_insight(impact)→ refactor → gentest → code_review";
|
|
37
|
+
}];
|
|
38
|
+
export declare const MCP_SKILL_AVOID_RULES: readonly ["有对应 MCP 却**直接大段写实现**", "`check_spec` **未通过**就写功能代码", "Bug 修完**不** `memorize_asset`", "`delete_memory_asset` 不带 `confirm: true`"];
|
|
39
|
+
export declare function listMcpToolSkillRegistryNames(): string[];
|
|
40
|
+
export declare function validateMcpToolSkillRegistry(registeredToolNames: string[]): {
|
|
41
|
+
ok: boolean;
|
|
42
|
+
missingInRegistry: string[];
|
|
43
|
+
extraInRegistry: string[];
|
|
44
|
+
duplicateInRegistry: string[];
|
|
45
|
+
};
|
|
46
|
+
export declare function formatSkillRegistryMismatchMessage(result: ReturnType<typeof validateMcpToolSkillRegistry>): string;
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP 工具「何时调用」注册表 — Skill 模板唯一真相源。
|
|
3
|
+
*
|
|
4
|
+
* **增删改工具时必同步本文件**(`npm run verify-workflow-skill` / prebuild 会校验)。
|
|
5
|
+
* 与 `src/schemas/*` 的 `allToolSchemas` 工具名必须一一对应。
|
|
6
|
+
*/
|
|
7
|
+
export const MCP_INTENT_QUICK_LOOKUP = [
|
|
8
|
+
{ signal: "新功能、加模块、做需求", firstTool: "start_feature" },
|
|
9
|
+
{ signal: "Bug、报错、异常、排查、不生效", firstTool: "start_bugfix" },
|
|
10
|
+
{ signal: "页面、组件、样式、UI、交互", firstTool: "start_ui" },
|
|
11
|
+
{ signal: "不熟代码、架构、调用链、影响面", firstTool: "code_insight" },
|
|
12
|
+
{ signal: "新项目上手、熟悉仓库", firstTool: "start_onboard" },
|
|
13
|
+
{ signal: "产品方案、PRD、原型", firstTool: "start_product" },
|
|
14
|
+
{ signal: "长周期自主迭代(Ralph)", firstTool: "start_ralph" },
|
|
15
|
+
{ signal: "缺 AGENTS.md / 项目上下文", firstTool: "init_project_context" },
|
|
16
|
+
{ signal: "全新空仓库脚手架", firstTool: "init_project" },
|
|
17
|
+
{ signal: "写 commit message", firstTool: "gencommit" },
|
|
18
|
+
{ signal: "代码评审、安全检查", firstTool: "code_review" },
|
|
19
|
+
{ signal: "重构、整理代码", firstTool: "refactor(大改前先 code_insight)" },
|
|
20
|
+
{ signal: "估算工时、排期", firstTool: "estimate" },
|
|
21
|
+
{ signal: "校验规格是否写全", firstTool: "check_spec" },
|
|
22
|
+
{ signal: "查历史踩坑、可复用经验", firstTool: "search_memory" },
|
|
23
|
+
{ signal: "需求不清楚、要澄清", firstTool: "ask_user 或 interview" },
|
|
24
|
+
{ signal: "工作报告、周报、git 汇总", firstTool: "git_work_report" },
|
|
25
|
+
{ signal: "不确定用哪个 MCP", firstTool: "workflow" },
|
|
26
|
+
];
|
|
27
|
+
export const MCP_TOOL_SKILL_GROUPS = [
|
|
28
|
+
{
|
|
29
|
+
id: "orchestration",
|
|
30
|
+
title: "编排入口 `start_*`(复杂任务的第一步)",
|
|
31
|
+
tools: [
|
|
32
|
+
{
|
|
33
|
+
name: "start_feature",
|
|
34
|
+
whenToCall: "任何**新功能 / 增强**;会先搜记忆,再指引 `add_feature` → `check_spec` → 实现",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "start_bugfix",
|
|
38
|
+
whenToCall: "任何 **Bug / 报错**;指引 `fix_bug`(真因)→ `gentest` → 测试",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: "start_ui",
|
|
42
|
+
whenToCall: "任何 **UI / 页面 / 组件**;指引设计系统、模板检索、实现约束",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "start_onboard",
|
|
46
|
+
whenToCall: "**新成员 / 新仓库**快速建立心智模型",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "start_product",
|
|
50
|
+
whenToCall: "从 0 做**产品方案**(PRD、原型思路)",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "start_ralph",
|
|
54
|
+
whenToCall: "需要**多轮自主迭代**、长任务循环时",
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "routing",
|
|
60
|
+
title: "路由",
|
|
61
|
+
tools: [
|
|
62
|
+
{
|
|
63
|
+
name: "workflow",
|
|
64
|
+
whenToCall: "**不确定**该用哪个 MCP;或担心 Agent 跳过 MCP 直接写代码时",
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: "project-spec",
|
|
70
|
+
title: "项目与规格",
|
|
71
|
+
tools: [
|
|
72
|
+
{
|
|
73
|
+
name: "init_project_context",
|
|
74
|
+
whenToCall: "没有 **AGENTS.md**、`docs/project-context/`、图谱索引;大改前缺上下文",
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: "init_project",
|
|
78
|
+
whenToCall: "**空目录**需要初始化项目结构",
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "add_feature",
|
|
82
|
+
whenToCall: "需要生成 `docs/specs/<feature>/` 规格(通常由 `start_feature` 触发)",
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: "check_spec",
|
|
86
|
+
whenToCall: "规格写完后、**写实现代码前**;或 Bug 修完要过规格闸门",
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: "estimate",
|
|
90
|
+
whenToCall: "需要**故事点 / 工时 / 风险**评估(通常在 `add_feature` 之后)",
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "code-analysis",
|
|
96
|
+
title: "代码分析(可直接调,不必等 start_*)",
|
|
97
|
+
tools: [
|
|
98
|
+
{
|
|
99
|
+
name: "code_insight",
|
|
100
|
+
whenToCall: "读不懂代码、找入口、看**调用链 / 影响面**;大重构前;`mode=impact` 评估改动范围",
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: "fix_bug",
|
|
104
|
+
whenToCall: "需要 **TBP 真因分析**指南(通常由 `start_bugfix` 触发)",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: "gentest",
|
|
108
|
+
whenToCall: "需要**补测试 / 回归用例**(Bug 修复后、功能完成后)",
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: "code_review",
|
|
112
|
+
whenToCall: "用户要**审查**指定文件或 diff(含安全项)",
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: "refactor",
|
|
116
|
+
whenToCall: "需要**分步重构计划**;范围大时先 `code_insight`",
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
id: "git",
|
|
122
|
+
title: "Git",
|
|
123
|
+
tools: [
|
|
124
|
+
{
|
|
125
|
+
name: "gencommit",
|
|
126
|
+
whenToCall: "变更完成,需要**规范 commit message**",
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: "git_work_report",
|
|
130
|
+
whenToCall: "需要基于 git 历史的**工作报告 / 周报**",
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: "ui",
|
|
136
|
+
title: "UI 子工具(通常由 `start_ui` 串联)",
|
|
137
|
+
tools: [
|
|
138
|
+
{
|
|
139
|
+
name: "ui_design_system",
|
|
140
|
+
whenToCall: "需要**设计 token / 组件规范**",
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
name: "ui_search",
|
|
144
|
+
whenToCall: "需要搜 **UI/UX 模板、模式**",
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: "sync_ui_data",
|
|
148
|
+
whenToCall: "UI 内嵌数据过期,需要**同步缓存**",
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
id: "memory",
|
|
154
|
+
title: "记忆(需 MEMORY 已配置)",
|
|
155
|
+
tools: [
|
|
156
|
+
{
|
|
157
|
+
name: "search_memory",
|
|
158
|
+
whenToCall: "主动查**历史经验**;`start_*` 未覆盖时补查",
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: "read_memory_asset",
|
|
162
|
+
whenToCall: "`search_memory` 命中后需要**读全文**",
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
name: "memorize_asset",
|
|
166
|
+
whenToCall: "Bug **验证通过**后沉淀;有可复用 pattern/component",
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: "update_memory_asset",
|
|
170
|
+
whenToCall: "修正已有记忆条目",
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: "delete_memory_asset",
|
|
174
|
+
whenToCall: "删除错误记忆(需 `confirm: true`)",
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: "scan_and_extract_patterns",
|
|
178
|
+
whenToCall: "从代码库**批量提取**可复用模式并建议沉淀",
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
id: "interactive",
|
|
184
|
+
title: "交互",
|
|
185
|
+
tools: [
|
|
186
|
+
{
|
|
187
|
+
name: "ask_user",
|
|
188
|
+
whenToCall: "目标模糊、缺关键信息,需要**向用户提问**",
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: "interview",
|
|
192
|
+
whenToCall: "需要结构化**需求访谈**",
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
},
|
|
196
|
+
];
|
|
197
|
+
export const MCP_SKILL_COMMON_FLOWS = [
|
|
198
|
+
{
|
|
199
|
+
label: "新功能",
|
|
200
|
+
chain: "start_feature → add_feature → check_spec(通过)→ 写代码 → gentest → gencommit",
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
label: "修 Bug",
|
|
204
|
+
chain: "start_bugfix → fix_bug → 改代码 → gentest → 跑测试 → memorize_asset(type=bugfix)",
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
label: "不熟代码",
|
|
208
|
+
chain: "code_insight → 再 start_feature / start_bugfix",
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
label: "大重构",
|
|
212
|
+
chain: "code_insight(impact)→ refactor → gentest → code_review",
|
|
213
|
+
},
|
|
214
|
+
];
|
|
215
|
+
export const MCP_SKILL_AVOID_RULES = [
|
|
216
|
+
"有对应 MCP 却**直接大段写实现**",
|
|
217
|
+
"`check_spec` **未通过**就写功能代码",
|
|
218
|
+
"Bug 修完**不** `memorize_asset`",
|
|
219
|
+
"`delete_memory_asset` 不带 `confirm: true`",
|
|
220
|
+
];
|
|
221
|
+
export function listMcpToolSkillRegistryNames() {
|
|
222
|
+
return MCP_TOOL_SKILL_GROUPS.flatMap((group) => group.tools.map((tool) => tool.name));
|
|
223
|
+
}
|
|
224
|
+
export function validateMcpToolSkillRegistry(registeredToolNames) {
|
|
225
|
+
const registryNames = listMcpToolSkillRegistryNames();
|
|
226
|
+
const registered = new Set(registeredToolNames);
|
|
227
|
+
const registrySet = new Set(registryNames);
|
|
228
|
+
const duplicates = registryNames.filter((name, index) => registryNames.indexOf(name) !== index);
|
|
229
|
+
const missingInRegistry = registeredToolNames.filter((name) => !registrySet.has(name));
|
|
230
|
+
const extraInRegistry = registryNames.filter((name) => !registered.has(name));
|
|
231
|
+
return {
|
|
232
|
+
ok: missingInRegistry.length === 0 &&
|
|
233
|
+
extraInRegistry.length === 0 &&
|
|
234
|
+
duplicates.length === 0,
|
|
235
|
+
missingInRegistry,
|
|
236
|
+
extraInRegistry,
|
|
237
|
+
duplicateInRegistry: [...new Set(duplicates)],
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
export function formatSkillRegistryMismatchMessage(result) {
|
|
241
|
+
const lines = [
|
|
242
|
+
"MCP Skill 注册表与 allToolSchemas 不一致。",
|
|
243
|
+
"增删工具时请同步更新 src/lib/mcp-tool-skill-registry.ts",
|
|
244
|
+
"",
|
|
245
|
+
];
|
|
246
|
+
if (result.missingInRegistry.length > 0) {
|
|
247
|
+
lines.push(`注册表缺少(已注册 MCP 工具但未写 whenToCall): ${result.missingInRegistry.join(", ")}`);
|
|
248
|
+
}
|
|
249
|
+
if (result.extraInRegistry.length > 0) {
|
|
250
|
+
lines.push(`注册表多余(工具已删但注册表未清): ${result.extraInRegistry.join(", ")}`);
|
|
251
|
+
}
|
|
252
|
+
if (result.duplicateInRegistry.length > 0) {
|
|
253
|
+
lines.push(`注册表重复: ${result.duplicateInRegistry.join(", ")}`);
|
|
254
|
+
}
|
|
255
|
+
return lines.join("\n");
|
|
256
|
+
}
|
|
@@ -66,5 +66,24 @@ export declare class MemoryClient {
|
|
|
66
66
|
}): Promise<MemoryAsset>;
|
|
67
67
|
search(query: string, options?: MemorySearchOptions): Promise<MemorySearchResult[]>;
|
|
68
68
|
getAsset(assetId: string): Promise<MemoryAsset | null>;
|
|
69
|
+
deleteAsset(assetId: string): Promise<{
|
|
70
|
+
deleted: boolean;
|
|
71
|
+
asset: MemoryAsset | null;
|
|
72
|
+
}>;
|
|
73
|
+
updateAsset(assetId: string, patch: {
|
|
74
|
+
name?: string;
|
|
75
|
+
type?: string;
|
|
76
|
+
description?: string;
|
|
77
|
+
summary?: string;
|
|
78
|
+
content?: string;
|
|
79
|
+
tags?: string[];
|
|
80
|
+
confidence?: number;
|
|
81
|
+
sourceProject?: string;
|
|
82
|
+
sourcePath?: string;
|
|
83
|
+
usage?: string;
|
|
84
|
+
}): Promise<{
|
|
85
|
+
updated: boolean;
|
|
86
|
+
asset: MemoryAsset | null;
|
|
87
|
+
}>;
|
|
69
88
|
}
|
|
70
89
|
export declare function createMemoryClient(): MemoryClient;
|
|
@@ -273,6 +273,75 @@ export class MemoryClient {
|
|
|
273
273
|
id: fields.id || assetId,
|
|
274
274
|
};
|
|
275
275
|
}
|
|
276
|
+
async deleteAsset(assetId) {
|
|
277
|
+
if (!this.isReadEnabled()) {
|
|
278
|
+
throw new Error('记忆系统未启用');
|
|
279
|
+
}
|
|
280
|
+
const asset = await this.getAsset(assetId);
|
|
281
|
+
if (!asset) {
|
|
282
|
+
return { deleted: false, asset: null };
|
|
283
|
+
}
|
|
284
|
+
await this.requestJson(`${this.config.qdrantUrl}/collections/${encodeURIComponent(this.config.qdrantCollection)}/points/delete?wait=true`, {
|
|
285
|
+
method: 'POST',
|
|
286
|
+
headers: this.buildHeaders(),
|
|
287
|
+
body: JSON.stringify({
|
|
288
|
+
points: [assetId],
|
|
289
|
+
}),
|
|
290
|
+
});
|
|
291
|
+
return { deleted: true, asset };
|
|
292
|
+
}
|
|
293
|
+
async updateAsset(assetId, patch) {
|
|
294
|
+
if (!this.isEnabled()) {
|
|
295
|
+
throw new Error('记忆系统未启用');
|
|
296
|
+
}
|
|
297
|
+
const existing = await this.getAsset(assetId);
|
|
298
|
+
if (!existing) {
|
|
299
|
+
return { updated: false, asset: null };
|
|
300
|
+
}
|
|
301
|
+
const asset = {
|
|
302
|
+
...existing,
|
|
303
|
+
name: patch.name ?? existing.name,
|
|
304
|
+
type: patch.type ?? existing.type,
|
|
305
|
+
description: patch.description ?? existing.description,
|
|
306
|
+
summary: patch.summary ?? existing.summary,
|
|
307
|
+
content: patch.content ?? existing.content,
|
|
308
|
+
tags: patch.tags ?? existing.tags,
|
|
309
|
+
confidence: patch.confidence ?? existing.confidence,
|
|
310
|
+
sourceProject: patch.sourceProject !== undefined ? patch.sourceProject : existing.sourceProject,
|
|
311
|
+
sourcePath: patch.sourcePath !== undefined ? patch.sourcePath : existing.sourcePath,
|
|
312
|
+
usage: patch.usage !== undefined ? patch.usage : existing.usage,
|
|
313
|
+
id: existing.id,
|
|
314
|
+
createdAt: existing.createdAt,
|
|
315
|
+
updatedAt: new Date().toISOString(),
|
|
316
|
+
};
|
|
317
|
+
const hashes = buildMemoryContentHashes(asset.content);
|
|
318
|
+
asset.contentHash = hashes.contentHash;
|
|
319
|
+
asset.normalizedContentHash = hashes.normalizedContentHash;
|
|
320
|
+
const vector = await this.embed(buildEmbeddingInput({
|
|
321
|
+
name: asset.name,
|
|
322
|
+
type: asset.type,
|
|
323
|
+
description: asset.description,
|
|
324
|
+
summary: asset.summary,
|
|
325
|
+
tags: asset.tags,
|
|
326
|
+
usage: asset.usage,
|
|
327
|
+
content: asset.content,
|
|
328
|
+
}));
|
|
329
|
+
await this.ensureCollection(vector.length);
|
|
330
|
+
await this.requestJson(`${this.config.qdrantUrl}/collections/${encodeURIComponent(this.config.qdrantCollection)}/points?wait=true`, {
|
|
331
|
+
method: 'PUT',
|
|
332
|
+
headers: this.buildHeaders(),
|
|
333
|
+
body: JSON.stringify({
|
|
334
|
+
points: [
|
|
335
|
+
{
|
|
336
|
+
id: assetId,
|
|
337
|
+
vector,
|
|
338
|
+
payload: asset,
|
|
339
|
+
},
|
|
340
|
+
],
|
|
341
|
+
}),
|
|
342
|
+
});
|
|
343
|
+
return { updated: true, asset };
|
|
344
|
+
}
|
|
276
345
|
}
|
|
277
346
|
function rankSearchResults(results, preferTypes = [], preferTags = []) {
|
|
278
347
|
if (preferTypes.length === 0 && preferTags.length === 0) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { MemoryAsset, MemorySearchResult } from './memory-client.js';
|
|
2
2
|
import { type MemoryConfig } from './memory-config.js';
|
|
3
|
+
import { type ToolHandles } from './handles.js';
|
|
3
4
|
export type MemoryPlanKind = 'feature' | 'bugfix' | 'ui' | 'default';
|
|
4
5
|
export interface MemoryInjectionContext {
|
|
5
6
|
enabled: boolean;
|
|
@@ -20,6 +21,10 @@ export declare function formatMemoryAssetText(asset: MemoryAsset, options?: {
|
|
|
20
21
|
}): string;
|
|
21
22
|
export declare function formatReadMemoryAssetText(asset: MemoryAsset): string;
|
|
22
23
|
export declare function renderMemoryGuideSection(context: MemoryInjectionContext): string;
|
|
24
|
+
export declare function buildMemoryInjectionHandles(context: MemoryInjectionContext): ToolHandles;
|
|
25
|
+
export declare function buildOrchestrationHandles(memoryContext?: MemoryInjectionContext, options?: {
|
|
26
|
+
graphResourceUri?: string;
|
|
27
|
+
}): ToolHandles;
|
|
23
28
|
export declare function buildMemoryPlanStep(kind?: MemoryPlanKind): {
|
|
24
29
|
id: string;
|
|
25
30
|
tool: string;
|