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,54 @@
|
|
|
1
|
+
import { describe, test, expect } from 'vitest';
|
|
2
|
+
import { CODE_LIMITS, BANNED_CODE_PATTERNS, UI_HARD_RULES, UI_BANNED_LIST, renderCodeLimits, renderBannedPatterns, renderUiHardRules, renderUiBannedList, renderPreFlightChecklist, } from '../quality-constraints.js';
|
|
3
|
+
describe('quality-constraints(质量约束单一真相源)', () => {
|
|
4
|
+
test('CODE_LIMITS 数值符合预期(单文件 500 / 函数 50)', () => {
|
|
5
|
+
expect(CODE_LIMITS.maxFileLines).toBe(500);
|
|
6
|
+
expect(CODE_LIMITS.maxFunctionLines).toBe(50);
|
|
7
|
+
expect(CODE_LIMITS.maxNestingDepth).toBe(4);
|
|
8
|
+
expect(CODE_LIMITS.maxParameters).toBe(3);
|
|
9
|
+
});
|
|
10
|
+
test('黑名单与硬约束清单非空', () => {
|
|
11
|
+
expect(BANNED_CODE_PATTERNS.length).toBeGreaterThan(0);
|
|
12
|
+
expect(UI_HARD_RULES.length).toBeGreaterThan(0);
|
|
13
|
+
expect(UI_BANNED_LIST.length).toBeGreaterThan(0);
|
|
14
|
+
});
|
|
15
|
+
test('代码完整性黑名单含关键占位模式', () => {
|
|
16
|
+
expect(BANNED_CODE_PATTERNS).toContain('// TODO');
|
|
17
|
+
expect(BANNED_CODE_PATTERNS).toContain('// ...');
|
|
18
|
+
});
|
|
19
|
+
test('UI 黑名单含 em-dash 零容忍与 AI 紫蓝渐变', () => {
|
|
20
|
+
expect(UI_BANNED_LIST.some((b) => b.includes('em-dash'))).toBe(true);
|
|
21
|
+
expect(UI_BANNED_LIST.some((b) => b.includes('紫蓝渐变'))).toBe(true);
|
|
22
|
+
});
|
|
23
|
+
test('renderCodeLimits 输出含 500 行红线', () => {
|
|
24
|
+
const out = renderCodeLimits();
|
|
25
|
+
expect(out).toContain('500');
|
|
26
|
+
expect(out).toContain('HIGH');
|
|
27
|
+
});
|
|
28
|
+
test('renderBannedPatterns 输出含 CRITICAL 与二元规则', () => {
|
|
29
|
+
const out = renderBannedPatterns();
|
|
30
|
+
expect(out).toContain('CRITICAL');
|
|
31
|
+
expect(out).toContain('二元');
|
|
32
|
+
});
|
|
33
|
+
test('renderUiHardRules 含 4pt 间距阶梯与对比度阈值', () => {
|
|
34
|
+
const out = renderUiHardRules();
|
|
35
|
+
expect(out).toContain('4, 8, 12, 16, 24, 32, 48, 64, 96');
|
|
36
|
+
expect(out).toContain('4.5:1');
|
|
37
|
+
});
|
|
38
|
+
test('renderUiBannedList 输出每条以 ❌ 标记', () => {
|
|
39
|
+
const out = renderUiBannedList();
|
|
40
|
+
expect(out).toContain('❌');
|
|
41
|
+
});
|
|
42
|
+
test('renderPreFlightChecklist 含 Scope-lock 与完整性勾选项', () => {
|
|
43
|
+
const out = renderPreFlightChecklist();
|
|
44
|
+
expect(out).toContain('Pre-Flight');
|
|
45
|
+
expect(out).toContain('Scope-lock');
|
|
46
|
+
expect(out).toContain('占位符');
|
|
47
|
+
});
|
|
48
|
+
// 防回归:注入下游 prompt 的渲染输出自身不得含 em-dash,否则与「em-dash 零容忍」自相矛盾
|
|
49
|
+
test('代码类渲染输出不含 em-dash(避免规则自相矛盾)', () => {
|
|
50
|
+
expect(renderCodeLimits()).not.toContain('—');
|
|
51
|
+
expect(renderBannedPatterns()).not.toContain('—');
|
|
52
|
+
expect(renderPreFlightChecklist()).not.toContain('—');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as os from 'node:os';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { afterEach, describe, expect, test } from 'vitest';
|
|
5
|
+
import { resolveBugfixFeatureName, resolveBugfixSpecGate, specArtifactsExist, } from '../spec-gate.js';
|
|
6
|
+
const tempDirs = [];
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
while (tempDirs.length > 0) {
|
|
9
|
+
const dir = tempDirs.pop();
|
|
10
|
+
if (dir) {
|
|
11
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
function makeSpecTree(featureName) {
|
|
16
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'spec-gate-'));
|
|
17
|
+
tempDirs.push(root);
|
|
18
|
+
const specDir = path.join(root, 'docs', 'specs', featureName);
|
|
19
|
+
fs.mkdirSync(specDir, { recursive: true });
|
|
20
|
+
fs.writeFileSync(path.join(specDir, 'requirements.md'), '# requirements\n');
|
|
21
|
+
return root;
|
|
22
|
+
}
|
|
23
|
+
describe('spec-gate', () => {
|
|
24
|
+
test('显式 feature_name 优先', () => {
|
|
25
|
+
const root = makeSpecTree('user-auth');
|
|
26
|
+
expect(resolveBugfixFeatureName('payment', root, 'docs', 'user-auth login failed')).toBe('payment');
|
|
27
|
+
});
|
|
28
|
+
test('仅一个 spec 目录时自动识别', () => {
|
|
29
|
+
const root = makeSpecTree('only-feature');
|
|
30
|
+
expect(resolveBugfixFeatureName('', root, 'docs', 'random error')).toBe('only-feature');
|
|
31
|
+
});
|
|
32
|
+
test('错误描述唯一匹配 spec 目录', () => {
|
|
33
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'spec-gate-'));
|
|
34
|
+
tempDirs.push(root);
|
|
35
|
+
for (const name of ['user-auth', 'billing']) {
|
|
36
|
+
const specDir = path.join(root, 'docs', 'specs', name);
|
|
37
|
+
fs.mkdirSync(specDir, { recursive: true });
|
|
38
|
+
fs.writeFileSync(path.join(specDir, 'tasks.md'), '# tasks\n');
|
|
39
|
+
}
|
|
40
|
+
expect(resolveBugfixFeatureName('', root, 'docs', 'billing invoice total mismatch')).toBe('billing');
|
|
41
|
+
});
|
|
42
|
+
test('resolveBugfixSpecGate 在规格存在时返回上下文', () => {
|
|
43
|
+
const root = makeSpecTree('checkout-flow');
|
|
44
|
+
const gate = resolveBugfixSpecGate({
|
|
45
|
+
featureName: 'checkout-flow',
|
|
46
|
+
projectRoot: root,
|
|
47
|
+
docsDir: 'docs',
|
|
48
|
+
hintText: 'checkout failed',
|
|
49
|
+
});
|
|
50
|
+
expect(gate?.featureName).toBe('checkout-flow');
|
|
51
|
+
expect(gate?.specDir).toBe('docs/specs/checkout-flow');
|
|
52
|
+
expect(specArtifactsExist(root, 'docs', 'checkout-flow')).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -1,75 +1,81 @@
|
|
|
1
1
|
import { describe, test, expect } from 'vitest';
|
|
2
2
|
import { validateSpecDocuments, extractFrIds } from '../spec-validator.js';
|
|
3
|
-
const goodReq = `# 需求文档:demo
|
|
4
|
-
|
|
5
|
-
## 功能概述
|
|
6
|
-
做一个登录功能。
|
|
7
|
-
|
|
8
|
-
## 历史经验与坑(来自记忆库)
|
|
9
|
-
- 可复用经验: 无
|
|
10
|
-
- 必须规避的坑: 无
|
|
11
|
-
|
|
12
|
-
## 范围边界
|
|
13
|
-
In Scope: 登录
|
|
14
|
-
Out of Scope: 注册
|
|
15
|
-
|
|
16
|
-
## 需求列表
|
|
17
|
-
### FR-1: 登录
|
|
18
|
-
**优先级:** Must
|
|
19
|
-
**用户故事:** 作为用户,我想登录,以便访问系统。
|
|
20
|
-
#### 验收标准(EARS)
|
|
21
|
-
1. WHEN 提交正确凭证 THEN 系统 SHALL 登录成功
|
|
22
|
-
|
|
23
|
-
## 非功能需求
|
|
24
|
-
- NFR-1: 登录响应 < 1s
|
|
25
|
-
|
|
26
|
-
## 依赖关系
|
|
27
|
-
- 无
|
|
3
|
+
const goodReq = `# 需求文档:demo
|
|
4
|
+
|
|
5
|
+
## 功能概述
|
|
6
|
+
做一个登录功能。
|
|
7
|
+
|
|
8
|
+
## 历史经验与坑(来自记忆库)
|
|
9
|
+
- 可复用经验: 无
|
|
10
|
+
- 必须规避的坑: 无
|
|
11
|
+
|
|
12
|
+
## 范围边界
|
|
13
|
+
In Scope: 登录
|
|
14
|
+
Out of Scope: 注册
|
|
15
|
+
|
|
16
|
+
## 需求列表
|
|
17
|
+
### FR-1: 登录
|
|
18
|
+
**优先级:** Must
|
|
19
|
+
**用户故事:** 作为用户,我想登录,以便访问系统。
|
|
20
|
+
#### 验收标准(EARS)
|
|
21
|
+
1. WHEN 提交正确凭证 THEN 系统 SHALL 登录成功
|
|
22
|
+
|
|
23
|
+
## 非功能需求
|
|
24
|
+
- NFR-1: 登录响应 < 1s
|
|
25
|
+
|
|
26
|
+
## 依赖关系
|
|
27
|
+
- 无
|
|
28
28
|
`;
|
|
29
|
-
const goodDesign = `# 设计文档:demo
|
|
30
|
-
|
|
31
|
-
## 概述
|
|
32
|
-
登录设计。
|
|
33
|
-
**对应需求:** FR-1
|
|
34
|
-
|
|
35
|
-
## 技术方案
|
|
36
|
-
### 技术选型
|
|
37
|
-
使用 JWT。
|
|
38
|
-
|
|
39
|
-
## 数据模型
|
|
40
|
-
不涉及。
|
|
41
|
-
|
|
42
|
-
## API 设计
|
|
43
|
-
POST /api/login
|
|
44
|
-
|
|
45
|
-
## 文件结构
|
|
46
|
-
src/login.ts
|
|
47
|
-
|
|
48
|
-
## 设计决策
|
|
49
|
-
决策 1:用 JWT。
|
|
50
|
-
|
|
51
|
-
## 风险评估
|
|
52
|
-
无。
|
|
29
|
+
const goodDesign = `# 设计文档:demo
|
|
30
|
+
|
|
31
|
+
## 概述
|
|
32
|
+
登录设计。
|
|
33
|
+
**对应需求:** FR-1
|
|
34
|
+
|
|
35
|
+
## 技术方案
|
|
36
|
+
### 技术选型
|
|
37
|
+
使用 JWT。
|
|
38
|
+
|
|
39
|
+
## 数据模型
|
|
40
|
+
不涉及。
|
|
41
|
+
|
|
42
|
+
## API 设计
|
|
43
|
+
POST /api/login
|
|
44
|
+
|
|
45
|
+
## 文件结构
|
|
46
|
+
src/login.ts
|
|
47
|
+
|
|
48
|
+
## 设计决策
|
|
49
|
+
决策 1:用 JWT。
|
|
50
|
+
|
|
51
|
+
## 风险评估
|
|
52
|
+
无。
|
|
53
53
|
`;
|
|
54
|
-
const goodTasks = `# 任务清单:demo
|
|
55
|
-
|
|
56
|
-
## 概述
|
|
57
|
-
任务分解。
|
|
58
|
-
|
|
59
|
-
##
|
|
60
|
-
|
|
61
|
-
-
|
|
62
|
-
|
|
63
|
-
##
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
54
|
+
const goodTasks = `# 任务清单:demo
|
|
55
|
+
|
|
56
|
+
## 概述
|
|
57
|
+
任务分解。
|
|
58
|
+
|
|
59
|
+
## 交付物清单(Scope-lock)
|
|
60
|
+
- 预计新建文件数: 1 个
|
|
61
|
+
- 预计修改文件数: 0 个
|
|
62
|
+
|
|
63
|
+
## 任务列表
|
|
64
|
+
### 阶段 2: 核心实现
|
|
65
|
+
- [ ] 2.1 实现登录接口 POST /api/login,校验邮箱并返回 JWT
|
|
66
|
+
- 证据块: 先读 src/router.ts:1,确认路由注册方式
|
|
67
|
+
- _需求: FR-1_ | _设计: API 设计_
|
|
68
|
+
|
|
69
|
+
## 检查点
|
|
70
|
+
- [ ] 阶段 2 完成后:登录可用
|
|
71
|
+
|
|
72
|
+
## 需求覆盖矩阵
|
|
73
|
+
| 需求 ID | 设计章节 | 任务编号 | 状态 |
|
|
74
|
+
| FR-1 | API 设计 | 2.1 | 未开始 |
|
|
75
|
+
|
|
76
|
+
## 文件变更清单
|
|
77
|
+
| 文件 | 操作 | 说明 |
|
|
78
|
+
| src/login.ts | 新建 | 登录接口 |
|
|
73
79
|
`;
|
|
74
80
|
describe('spec-validator(P1 填写后校验)', () => {
|
|
75
81
|
test('完整规格通过校验', () => {
|
|
@@ -98,12 +104,12 @@ describe('spec-validator(P1 填写后校验)', () => {
|
|
|
98
104
|
expect(r.issues.some((i) => i.code === 'no_acceptance')).toBe(true);
|
|
99
105
|
});
|
|
100
106
|
test('FR 未进 tasks 覆盖矩阵 → 跨文档未覆盖', () => {
|
|
101
|
-
const reqTwoFr = goodReq.replace('## 非功能需求', `### FR-2: 登出
|
|
102
|
-
**优先级:** Should
|
|
103
|
-
**用户故事:** 作为用户,我想登出。
|
|
104
|
-
#### 验收标准(EARS)
|
|
105
|
-
1. WHEN 点击登出 THEN 系统 SHALL 退出登录
|
|
106
|
-
|
|
107
|
+
const reqTwoFr = goodReq.replace('## 非功能需求', `### FR-2: 登出
|
|
108
|
+
**优先级:** Should
|
|
109
|
+
**用户故事:** 作为用户,我想登出。
|
|
110
|
+
#### 验收标准(EARS)
|
|
111
|
+
1. WHEN 点击登出 THEN 系统 SHALL 退出登录
|
|
112
|
+
|
|
107
113
|
## 非功能需求`);
|
|
108
114
|
const r = validateSpecDocuments({ requirements: reqTwoFr, design: goodDesign, tasks: goodTasks });
|
|
109
115
|
expect(r.passed).toBe(false);
|
|
@@ -112,4 +118,30 @@ describe('spec-validator(P1 填写后校验)', () => {
|
|
|
112
118
|
test('extractFrIds 去重并保序', () => {
|
|
113
119
|
expect(extractFrIds('FR-1 写了 FR-1 又写 FR-2')).toEqual(['FR-1', 'FR-2']);
|
|
114
120
|
});
|
|
121
|
+
test('tasks 缺少「交付物清单」章节 → 未通过', () => {
|
|
122
|
+
const tasksNoScope = goodTasks.replace(/## 交付物清单(Scope-lock)[\s\S]*?\n\n/, '');
|
|
123
|
+
// 防 fixture 漂移导致替换失效造成假通过
|
|
124
|
+
expect(tasksNoScope).not.toContain('交付物清单');
|
|
125
|
+
const r = validateSpecDocuments({ requirements: goodReq, design: goodDesign, tasks: tasksNoScope });
|
|
126
|
+
expect(r.passed).toBe(false);
|
|
127
|
+
expect(r.issues.some((i) => i.file === 'tasks' && i.code === 'missing_section')).toBe(true);
|
|
128
|
+
});
|
|
129
|
+
test('任务无「证据块」→ thin_task 提醒(warning,不阻断)', () => {
|
|
130
|
+
const tasksThin = goodTasks.replace(' - 证据块: 先读 src/router.ts:1,确认路由注册方式\n', '');
|
|
131
|
+
expect(tasksThin).not.toBe(goodTasks);
|
|
132
|
+
const r = validateSpecDocuments({ requirements: goodReq, design: goodDesign, tasks: tasksThin });
|
|
133
|
+
expect(r.issues.some((i) => i.code === 'thin_task')).toBe(true);
|
|
134
|
+
expect(r.warningCount).toBeGreaterThan(0);
|
|
135
|
+
// 核心语义:thin_task 是 warning,不应阻断 passed
|
|
136
|
+
expect(r.passed).toBe(true);
|
|
137
|
+
});
|
|
138
|
+
test('裸 [填写] 占位(无冒号)也应被检出', () => {
|
|
139
|
+
const r = validateSpecDocuments({
|
|
140
|
+
requirements: goodReq + '\n- 备注: [填写]',
|
|
141
|
+
design: goodDesign,
|
|
142
|
+
tasks: goodTasks,
|
|
143
|
+
});
|
|
144
|
+
expect(r.passed).toBe(false);
|
|
145
|
+
expect(r.issues.some((i) => i.file === 'requirements' && i.code === 'placeholder')).toBe(true);
|
|
146
|
+
});
|
|
115
147
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { describe, expect, test, afterEach } from 'vitest';
|
|
2
|
+
import { isAutoTaskTool, shouldAutoEscalateToTask } from '../task-defaults.js';
|
|
3
|
+
const originalDisable = process.env.MCP_DISABLE_AUTO_TASK;
|
|
4
|
+
afterEach(() => {
|
|
5
|
+
if (originalDisable === undefined) {
|
|
6
|
+
delete process.env.MCP_DISABLE_AUTO_TASK;
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
process.env.MCP_DISABLE_AUTO_TASK = originalDisable;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
describe('task-defaults', () => {
|
|
13
|
+
test('code_insight 与 scan 属于自动 Task 工具', () => {
|
|
14
|
+
expect(isAutoTaskTool('code_insight')).toBe(true);
|
|
15
|
+
expect(isAutoTaskTool('scan_and_extract_patterns')).toBe(true);
|
|
16
|
+
expect(isAutoTaskTool('search_memory')).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
test('默认对长耗时工具自动升级为 Task', () => {
|
|
19
|
+
delete process.env.MCP_DISABLE_AUTO_TASK;
|
|
20
|
+
expect(shouldAutoEscalateToTask('code_insight', false)).toBe(true);
|
|
21
|
+
expect(shouldAutoEscalateToTask('code_insight', true)).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
test('MCP_DISABLE_AUTO_TASK=1 时关闭自动 Task', () => {
|
|
24
|
+
process.env.MCP_DISABLE_AUTO_TASK = '1';
|
|
25
|
+
expect(shouldAutoEscalateToTask('code_insight', false)).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { afterEach, describe, expect, test } from "vitest";
|
|
5
|
+
import { VERSION } from "../../version.js";
|
|
6
|
+
import { ensureAgentsMdSkillReference, ensureMcpProbeKitBootstrap, ensureMcpProbeSkill, resolveProjectRootFromToolArgs, } from "../workflow-skill-installer.js";
|
|
7
|
+
import { formatSkillVersionMarker, agentsContextNeedsUpgrade, compareSemver, skillContentNeedsUpgrade, } from "../workflow-skill-version.js";
|
|
8
|
+
import { LEGACY_WORKFLOW_SKILL_REL_PATH, MCP_PROBE_SKILL_REL_PATH, } from "../workflow-skill-template.js";
|
|
9
|
+
import { wrapMcpProbeBlock } from "../merge-agents-md.js";
|
|
10
|
+
const tempDirs = [];
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
while (tempDirs.length > 0) {
|
|
13
|
+
const dir = tempDirs.pop();
|
|
14
|
+
if (dir) {
|
|
15
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
describe("workflow-skill-version", () => {
|
|
20
|
+
test("compareSemver 比较主次补丁", () => {
|
|
21
|
+
expect(compareSemver("3.5.0", "3.5.1")).toBeLessThan(0);
|
|
22
|
+
expect(compareSemver("3.6.0", "3.5.9")).toBeGreaterThan(0);
|
|
23
|
+
expect(compareSemver("3.5.0", "3.5.0")).toBe(0);
|
|
24
|
+
});
|
|
25
|
+
test("无版本标记视为需要升级", () => {
|
|
26
|
+
expect(skillContentNeedsUpgrade("# custom", VERSION)).toBe(true);
|
|
27
|
+
expect(agentsContextNeedsUpgrade("<!-- mcp-probe:context begin -->", VERSION)).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe("workflow-skill-installer", () => {
|
|
31
|
+
test("缺失时创建 mcp-probe-kit Skill", () => {
|
|
32
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "wf-skill-"));
|
|
33
|
+
tempDirs.push(root);
|
|
34
|
+
const result = ensureMcpProbeSkill(root);
|
|
35
|
+
expect(result.created).toBe(true);
|
|
36
|
+
expect(result.updated).toBe(false);
|
|
37
|
+
expect(result.version).toBe(VERSION);
|
|
38
|
+
const text = fs.readFileSync(path.join(root, MCP_PROBE_SKILL_REL_PATH), "utf8");
|
|
39
|
+
expect(text).toContain(formatSkillVersionMarker(VERSION));
|
|
40
|
+
expect(text).toContain("MCP 调用时机");
|
|
41
|
+
});
|
|
42
|
+
test("同版本 Skill 不覆盖", () => {
|
|
43
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "wf-skill-"));
|
|
44
|
+
tempDirs.push(root);
|
|
45
|
+
const skillPath = path.join(root, MCP_PROBE_SKILL_REL_PATH);
|
|
46
|
+
const content = `${formatSkillVersionMarker(VERSION)}\n# same version\n`;
|
|
47
|
+
fs.mkdirSync(path.dirname(skillPath), { recursive: true });
|
|
48
|
+
fs.writeFileSync(skillPath, content, "utf8");
|
|
49
|
+
const result = ensureMcpProbeSkill(root);
|
|
50
|
+
expect(result.created).toBe(false);
|
|
51
|
+
expect(result.updated).toBe(false);
|
|
52
|
+
expect(fs.readFileSync(skillPath, "utf8")).toBe(content);
|
|
53
|
+
});
|
|
54
|
+
test("旧版本 Skill 会升级覆盖", () => {
|
|
55
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "wf-skill-"));
|
|
56
|
+
tempDirs.push(root);
|
|
57
|
+
const skillPath = path.join(root, MCP_PROBE_SKILL_REL_PATH);
|
|
58
|
+
fs.mkdirSync(path.dirname(skillPath), { recursive: true });
|
|
59
|
+
fs.writeFileSync(skillPath, `${formatSkillVersionMarker("0.1.0")}\n# stale tools list\n`, "utf8");
|
|
60
|
+
const result = ensureMcpProbeSkill(root);
|
|
61
|
+
expect(result.updated).toBe(true);
|
|
62
|
+
expect(result.previousVersion).toBe("0.1.0");
|
|
63
|
+
const text = fs.readFileSync(skillPath, "utf8");
|
|
64
|
+
expect(text).toContain(formatSkillVersionMarker(VERSION));
|
|
65
|
+
expect(text).toContain("何时调用");
|
|
66
|
+
expect(text).not.toContain("stale tools list");
|
|
67
|
+
});
|
|
68
|
+
test("无 AGENTS.md 时创建并引用 Skill", () => {
|
|
69
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "wf-skill-"));
|
|
70
|
+
tempDirs.push(root);
|
|
71
|
+
const result = ensureAgentsMdSkillReference(root);
|
|
72
|
+
expect(result.created).toBe(true);
|
|
73
|
+
const agents = fs.readFileSync(path.join(root, "AGENTS.md"), "utf8");
|
|
74
|
+
expect(agents).toContain("mcp-probe:context-version");
|
|
75
|
+
expect(agents).toContain(MCP_PROBE_SKILL_REL_PATH);
|
|
76
|
+
});
|
|
77
|
+
test("已有 AGENTS.md 但缺 Skill 引用时更新", () => {
|
|
78
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "wf-skill-"));
|
|
79
|
+
tempDirs.push(root);
|
|
80
|
+
fs.writeFileSync(path.join(root, "AGENTS.md"), "# Custom rules\n", "utf8");
|
|
81
|
+
const result = ensureAgentsMdSkillReference(root);
|
|
82
|
+
expect(result.updated).toBe(true);
|
|
83
|
+
const agents = fs.readFileSync(path.join(root, "AGENTS.md"), "utf8");
|
|
84
|
+
expect(agents).toContain("# Custom rules");
|
|
85
|
+
expect(agents).toContain(MCP_PROBE_SKILL_REL_PATH);
|
|
86
|
+
});
|
|
87
|
+
test("旧 workflow Skill 路径会触发 AGENTS.md 更新", () => {
|
|
88
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "wf-skill-"));
|
|
89
|
+
tempDirs.push(root);
|
|
90
|
+
const legacyBlock = wrapMcpProbeBlock(`## MCP\nSee [skill](${LEGACY_WORKFLOW_SKILL_REL_PATH})`, "0.1.0");
|
|
91
|
+
fs.writeFileSync(path.join(root, "AGENTS.md"), `${legacyBlock}\n`, "utf8");
|
|
92
|
+
const result = ensureAgentsMdSkillReference(root);
|
|
93
|
+
expect(result.updated).toBe(true);
|
|
94
|
+
const agents = fs.readFileSync(path.join(root, "AGENTS.md"), "utf8");
|
|
95
|
+
expect(agents).toContain(MCP_PROBE_SKILL_REL_PATH);
|
|
96
|
+
expect(agents).toContain(`mcp-probe:context-version: ${VERSION}`);
|
|
97
|
+
});
|
|
98
|
+
test("bootstrap 同时处理 Skill 与 AGENTS.md", () => {
|
|
99
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "wf-skill-"));
|
|
100
|
+
tempDirs.push(root);
|
|
101
|
+
const result = ensureMcpProbeKitBootstrap(root);
|
|
102
|
+
expect(result.skill.created).toBe(true);
|
|
103
|
+
expect(result.agentsMd.created).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
test("从 tool args 解析 project_root", () => {
|
|
106
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "wf-skill-"));
|
|
107
|
+
tempDirs.push(root);
|
|
108
|
+
expect(resolveProjectRootFromToolArgs({ project_root: root })).toBe(path.resolve(root));
|
|
109
|
+
});
|
|
110
|
+
});
|
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
import { relativeLink } from "./project-context-layout.js";
|
|
2
|
+
import { MCP_PROBE_SKILL_REL_PATH } from "./workflow-skill-template.js";
|
|
2
3
|
function link(layout, targetRel) {
|
|
3
4
|
return relativeLink(layout.indexPath, targetRel);
|
|
4
5
|
}
|
|
5
6
|
function memorySection(locale) {
|
|
6
7
|
if (locale === "zh-CN") {
|
|
7
|
-
return `
|
|
8
|
-
记忆(需 MEMORY_QDRANT_URL 等已配置):
|
|
9
|
-
- 检索:\`start_*\` 命中后**自动注入**历史经验全文;中途补查可用 \`search_memory\`;单条精读仍可用 \`read_memory_asset\`
|
|
10
|
-
- 沉淀:跨仓库共享**勿填** source_project/source_path;路径写进 content;summary 写检索关键词
|
|
11
|
-
-
|
|
8
|
+
return `
|
|
9
|
+
记忆(需 MEMORY_QDRANT_URL 等已配置):
|
|
10
|
+
- 检索:\`start_*\` 命中后**自动注入**历史经验全文;中途补查可用 \`search_memory\`;单条精读仍可用 \`read_memory_asset\`
|
|
11
|
+
- 沉淀:跨仓库共享**勿填** source_project/source_path;路径写进 content;summary 写检索关键词
|
|
12
|
+
- 修正:已有资产可用 \`update_memory_asset\` 按 asset_id 原地更新(保留 ID)
|
|
13
|
+
- 清理:过时/错误/重复沉淀可用 \`delete_memory_asset\`(删除前建议 \`read_memory_asset\` 确认)
|
|
14
|
+
- Bug 修完验证通过 → **必须** \`memorize_asset\` type=\`bugfix\` tags=\`bugfix,root-cause\`(content 含【现象】【根因】【修复】【验证】)
|
|
12
15
|
- 功能/UI 可复用产出 → \`memorize_asset\` type=\`pattern\`/\`component\``;
|
|
13
16
|
}
|
|
14
|
-
return `
|
|
15
|
-
Memory (requires MEMORY_* env):
|
|
16
|
-
- Search: \`start_*\` auto-injects full memory hits; use \`search_memory\` mid-task; \`read_memory_asset\` for a specific id
|
|
17
|
-
- Store: do NOT use source_project/source_path for cross-repo pools; put paths in content; write keyword-rich summary
|
|
18
|
-
-
|
|
17
|
+
return `
|
|
18
|
+
Memory (requires MEMORY_* env):
|
|
19
|
+
- Search: \`start_*\` auto-injects full memory hits; use \`search_memory\` mid-task; \`read_memory_asset\` for a specific id
|
|
20
|
+
- Store: do NOT use source_project/source_path for cross-repo pools; put paths in content; write keyword-rich summary
|
|
21
|
+
- Update: fix existing entries in place with \`update_memory_asset\` by asset_id (preserves ID)
|
|
22
|
+
- Cleanup: remove stale/wrong/duplicate entries with \`delete_memory_asset\` (confirm via \`read_memory_asset\` first)
|
|
23
|
+
- After verified bugfix → MUST \`memorize_asset\` type=\`bugfix\` (sections: symptom, root cause, fix, verification)
|
|
19
24
|
- Reusable feature/UI → \`memorize_asset\` type=\`pattern\`/\`component\``;
|
|
20
25
|
}
|
|
21
26
|
/**
|
|
@@ -25,31 +30,34 @@ export function generateAgentsMdInner(input) {
|
|
|
25
30
|
const { layout, locale } = input;
|
|
26
31
|
const graph = link(layout, layout.latestMarkdownPath);
|
|
27
32
|
const ctxIndex = link(layout, layout.legacyIndexPath);
|
|
33
|
+
const skillLink = link(layout, MCP_PROBE_SKILL_REL_PATH);
|
|
28
34
|
if (locale === "zh-CN") {
|
|
29
|
-
return `## MCP(必须先调)
|
|
30
|
-
需已配置 mcp-probe-kit
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
return `## MCP(必须先调)
|
|
36
|
+
需已配置 mcp-probe-kit。写代码前先读 Skill:[MCP 调用时机](${skillLink})(\`${MCP_PROBE_SKILL_REL_PATH}\`,首次 MCP 调用自动创建)。
|
|
37
|
+
|
|
38
|
+
- 不确定用哪个 MCP → \`workflow\`(返回 firstTool)
|
|
39
|
+
- 新功能 → \`start_feature\`(会先搜记忆)
|
|
40
|
+
- Bug → \`start_bugfix\`(会先搜记忆)
|
|
41
|
+
- UI → \`start_ui\`(会先搜记忆)
|
|
42
|
+
- 不熟代码 / 影响面 → \`code_insight\`(context / impact / auto)
|
|
43
|
+
- 缺上下文 → \`init_project_context\`
|
|
44
|
+
- 提交 → \`gencommit\`
|
|
45
|
+
|
|
46
|
+
上下文:写代码前先读 [project-context](${ctxIndex})(链到 \`${layout.modularDir}/\` 各文档)
|
|
40
47
|
图谱:大改前读 [latest](${graph});过期 \`code_insight\` mode=auto save_to_docs=true${memorySection(locale)}`;
|
|
41
48
|
}
|
|
42
|
-
return `## MCP (call first)
|
|
43
|
-
Requires mcp-probe-kit.
|
|
44
|
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
return `## MCP (call first)
|
|
50
|
+
Requires mcp-probe-kit. Before coding, read Skill: [When to call MCP](${skillLink}) (\`${MCP_PROBE_SKILL_REL_PATH}\`, auto-created on first MCP call).
|
|
51
|
+
|
|
52
|
+
- Unsure which MCP → \`workflow\` (returns firstTool)
|
|
53
|
+
- Feature → \`start_feature\` (searches memory first)
|
|
54
|
+
- Bug → \`start_bugfix\` (searches memory first)
|
|
55
|
+
- UI → \`start_ui\` (searches memory first)
|
|
56
|
+
- Unfamiliar code / impact → \`code_insight\` (context / impact / auto)
|
|
57
|
+
- Missing context → \`init_project_context\`
|
|
58
|
+
- Commit → \`gencommit\`
|
|
59
|
+
|
|
60
|
+
Context: before coding read [project-context](${ctxIndex}) (links to \`${layout.modularDir}/\`)
|
|
53
61
|
Graph: read [latest](${graph}) before large changes; refresh \`code_insight\` mode=auto save_to_docs=true${memorySection(locale)}`;
|
|
54
62
|
}
|
|
55
63
|
export function generateAgentsMdTemplate(input) {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export interface CursorConversationSummary {
|
|
2
|
+
composerId: string;
|
|
3
|
+
name: string;
|
|
4
|
+
createdAt?: number;
|
|
5
|
+
lastUpdatedAt?: number;
|
|
6
|
+
workspaceId?: string;
|
|
7
|
+
workspacePath?: string;
|
|
8
|
+
mode?: string;
|
|
9
|
+
contextUsagePercent?: number;
|
|
10
|
+
subtitle?: string;
|
|
11
|
+
isArchived?: boolean;
|
|
12
|
+
source: 'composerHeaders';
|
|
13
|
+
}
|
|
14
|
+
export interface CursorConversationMessage {
|
|
15
|
+
bubbleId: string;
|
|
16
|
+
type: number;
|
|
17
|
+
text: string;
|
|
18
|
+
createdAt?: string;
|
|
19
|
+
requestId?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface CursorConversationDetail {
|
|
22
|
+
composerId: string;
|
|
23
|
+
messages: CursorConversationMessage[];
|
|
24
|
+
}
|
|
25
|
+
export interface CursorHistorySearchResult {
|
|
26
|
+
composerId: string;
|
|
27
|
+
conversationName: string;
|
|
28
|
+
bubbleId: string;
|
|
29
|
+
type: number;
|
|
30
|
+
text: string;
|
|
31
|
+
createdAt?: string;
|
|
32
|
+
requestId?: string;
|
|
33
|
+
}
|
|
34
|
+
export declare class CursorHistoryClient {
|
|
35
|
+
private withDatabase;
|
|
36
|
+
private loadConversationIndex;
|
|
37
|
+
listConversations(params?: {
|
|
38
|
+
titleQuery?: string;
|
|
39
|
+
workspaceQuery?: string;
|
|
40
|
+
includeArchived?: boolean;
|
|
41
|
+
limit?: number;
|
|
42
|
+
}): Promise<CursorConversationSummary[]>;
|
|
43
|
+
searchHistory(params: {
|
|
44
|
+
query: string;
|
|
45
|
+
composerId?: string;
|
|
46
|
+
limit?: number;
|
|
47
|
+
}): Promise<CursorHistorySearchResult[]>;
|
|
48
|
+
readConversation(params: {
|
|
49
|
+
composerId: string;
|
|
50
|
+
limit?: number;
|
|
51
|
+
includeEmpty?: boolean;
|
|
52
|
+
}): Promise<CursorConversationDetail>;
|
|
53
|
+
}
|
|
54
|
+
export declare function createCursorHistoryClient(): CursorHistoryClient;
|