openspec-mcp 0.1.0 → 0.2.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 +83 -35
- package/README.zh.md +81 -33
- package/dist/api/routes/changes.d.ts.map +1 -1
- package/dist/api/routes/changes.js +54 -0
- package/dist/api/routes/changes.js.map +1 -1
- package/dist/api/routes/project.d.ts +7 -0
- package/dist/api/routes/project.d.ts.map +1 -0
- package/dist/api/routes/project.js +14 -0
- package/dist/api/routes/project.js.map +1 -0
- package/dist/api/routes/specs.d.ts.map +1 -1
- package/dist/api/routes/specs.js +100 -1
- package/dist/api/routes/specs.js.map +1 -1
- package/dist/api/routes/tasks.d.ts.map +1 -1
- package/dist/api/routes/tasks.js +33 -0
- package/dist/api/routes/tasks.js.map +1 -1
- package/dist/api/server.d.ts +5 -1
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +107 -14
- package/dist/api/server.js.map +1 -1
- package/dist/core/approval-manager.test.d.ts +5 -0
- package/dist/core/approval-manager.test.d.ts.map +1 -0
- package/dist/core/approval-manager.test.js +114 -0
- package/dist/core/approval-manager.test.js.map +1 -0
- package/dist/core/file-watcher.d.ts.map +1 -1
- package/dist/core/file-watcher.js +13 -0
- package/dist/core/file-watcher.js.map +1 -1
- package/dist/core/hooks-manager.d.ts +43 -0
- package/dist/core/hooks-manager.d.ts.map +1 -0
- package/dist/core/hooks-manager.js +194 -0
- package/dist/core/hooks-manager.js.map +1 -0
- package/dist/core/openspec-cli.d.ts +12 -0
- package/dist/core/openspec-cli.d.ts.map +1 -1
- package/dist/core/openspec-cli.js +85 -0
- package/dist/core/openspec-cli.js.map +1 -1
- package/dist/core/proposal-generator.d.ts +46 -0
- package/dist/core/proposal-generator.d.ts.map +1 -0
- package/dist/core/proposal-generator.js +155 -0
- package/dist/core/proposal-generator.js.map +1 -0
- package/dist/core/review-manager.d.ts +147 -0
- package/dist/core/review-manager.d.ts.map +1 -0
- package/dist/core/review-manager.js +235 -0
- package/dist/core/review-manager.js.map +1 -0
- package/dist/core/spec-parser.d.ts +51 -0
- package/dist/core/spec-parser.d.ts.map +1 -0
- package/dist/core/spec-parser.js +130 -0
- package/dist/core/spec-parser.js.map +1 -0
- package/dist/core/task-parser.test.d.ts +5 -0
- package/dist/core/task-parser.test.d.ts.map +1 -0
- package/dist/core/task-parser.test.js +124 -0
- package/dist/core/task-parser.test.js.map +1 -0
- package/dist/core/template-manager.d.ts +48 -0
- package/dist/core/template-manager.d.ts.map +1 -0
- package/dist/core/template-manager.js +268 -0
- package/dist/core/template-manager.js.map +1 -0
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/dist/server/tools/generator.d.ts +8 -0
- package/dist/server/tools/generator.d.ts.map +1 -0
- package/dist/server/tools/generator.js +121 -0
- package/dist/server/tools/generator.js.map +1 -0
- package/dist/server/tools/hooks.d.ts +8 -0
- package/dist/server/tools/hooks.d.ts.map +1 -0
- package/dist/server/tools/hooks.js +86 -0
- package/dist/server/tools/hooks.js.map +1 -0
- package/dist/server/tools/management.d.ts.map +1 -1
- package/dist/server/tools/management.js +37 -2
- package/dist/server/tools/management.js.map +1 -1
- package/dist/server/tools/reviews.d.ts +8 -0
- package/dist/server/tools/reviews.d.ts.map +1 -0
- package/dist/server/tools/reviews.js +178 -0
- package/dist/server/tools/reviews.js.map +1 -0
- package/dist/server/tools/tasks.d.ts.map +1 -1
- package/dist/server/tools/tasks.js +38 -0
- package/dist/server/tools/tasks.js.map +1 -1
- package/dist/server/tools/templates.d.ts +8 -0
- package/dist/server/tools/templates.d.ts.map +1 -0
- package/dist/server/tools/templates.js +89 -0
- package/dist/server/tools/templates.js.map +1 -0
- package/dist/utils/constants.d.ts +54 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +54 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/version.d.ts +13 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +26 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +2 -6
- package/web/dist/assets/index-BGNTCJhf.css +1 -0
- package/web/dist/assets/index-DKBVRb7-.js +99 -0
- package/web/dist/index.html +2 -2
- package/web/dist/assets/index--LppUKpS.js +0 -67
- package/web/dist/assets/index-DdJQfs9Z.css +0 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TaskParser 单元测试
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect } from 'vitest';
|
|
5
|
+
import { TaskParser } from './task-parser.js';
|
|
6
|
+
describe('TaskParser', () => {
|
|
7
|
+
const parser = new TaskParser();
|
|
8
|
+
describe('parseTasksFromContent', () => {
|
|
9
|
+
it('should parse tasks with ID format', () => {
|
|
10
|
+
const content = `
|
|
11
|
+
## Implementation
|
|
12
|
+
|
|
13
|
+
- [x] **1.1** Complete the first task
|
|
14
|
+
- [ ] **1.2** Do the second task
|
|
15
|
+
- [-] **1.3** Working on third task
|
|
16
|
+
`;
|
|
17
|
+
const tasks = parser.parseTasksFromContent(content);
|
|
18
|
+
expect(tasks).toHaveLength(3);
|
|
19
|
+
expect(tasks[0]).toMatchObject({
|
|
20
|
+
id: '1.1',
|
|
21
|
+
section: 'Implementation',
|
|
22
|
+
title: 'Complete the first task',
|
|
23
|
+
status: 'done',
|
|
24
|
+
});
|
|
25
|
+
expect(tasks[1]).toMatchObject({
|
|
26
|
+
id: '1.2',
|
|
27
|
+
section: 'Implementation',
|
|
28
|
+
title: 'Do the second task',
|
|
29
|
+
status: 'pending',
|
|
30
|
+
});
|
|
31
|
+
expect(tasks[2]).toMatchObject({
|
|
32
|
+
id: '1.3',
|
|
33
|
+
section: 'Implementation',
|
|
34
|
+
title: 'Working on third task',
|
|
35
|
+
status: 'in_progress',
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
it('should parse simple tasks without ID', () => {
|
|
39
|
+
const content = `
|
|
40
|
+
## Tasks
|
|
41
|
+
|
|
42
|
+
- [x] First simple task
|
|
43
|
+
- [ ] Second simple task
|
|
44
|
+
`;
|
|
45
|
+
const tasks = parser.parseTasksFromContent(content);
|
|
46
|
+
expect(tasks).toHaveLength(2);
|
|
47
|
+
expect(tasks[0].title).toBe('First simple task');
|
|
48
|
+
expect(tasks[0].status).toBe('done');
|
|
49
|
+
expect(tasks[0].id).toMatch(/^line-\d+$/);
|
|
50
|
+
expect(tasks[1].title).toBe('Second simple task');
|
|
51
|
+
expect(tasks[1].status).toBe('pending');
|
|
52
|
+
});
|
|
53
|
+
it('should handle nested task IDs', () => {
|
|
54
|
+
const content = `
|
|
55
|
+
## Phase 1
|
|
56
|
+
|
|
57
|
+
- [x] **1.1** Main task
|
|
58
|
+
- [ ] **1.1.1** Sub task
|
|
59
|
+
- [ ] **1.1.2** Another sub task
|
|
60
|
+
`;
|
|
61
|
+
const tasks = parser.parseTasksFromContent(content);
|
|
62
|
+
expect(tasks).toHaveLength(3);
|
|
63
|
+
expect(tasks[0].id).toBe('1.1');
|
|
64
|
+
expect(tasks[1].id).toBe('1.1.1');
|
|
65
|
+
expect(tasks[2].id).toBe('1.1.2');
|
|
66
|
+
});
|
|
67
|
+
it('should handle multiple sections', () => {
|
|
68
|
+
const content = `
|
|
69
|
+
## Phase 1
|
|
70
|
+
|
|
71
|
+
- [x] **1.1** Task in phase 1
|
|
72
|
+
|
|
73
|
+
## Phase 2
|
|
74
|
+
|
|
75
|
+
- [ ] **2.1** Task in phase 2
|
|
76
|
+
`;
|
|
77
|
+
const tasks = parser.parseTasksFromContent(content);
|
|
78
|
+
expect(tasks).toHaveLength(2);
|
|
79
|
+
expect(tasks[0].section).toBe('Phase 1');
|
|
80
|
+
expect(tasks[1].section).toBe('Phase 2');
|
|
81
|
+
});
|
|
82
|
+
it('should return empty array for content with no tasks', () => {
|
|
83
|
+
const content = `
|
|
84
|
+
# Just a title
|
|
85
|
+
|
|
86
|
+
Some text without any tasks.
|
|
87
|
+
`;
|
|
88
|
+
const tasks = parser.parseTasksFromContent(content);
|
|
89
|
+
expect(tasks).toHaveLength(0);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
describe('calculateProgress', () => {
|
|
93
|
+
it('should calculate progress correctly', () => {
|
|
94
|
+
const tasks = [
|
|
95
|
+
{ id: '1.1', section: '', title: 'Task 1', status: 'done', line: 1 },
|
|
96
|
+
{ id: '1.2', section: '', title: 'Task 2', status: 'done', line: 2 },
|
|
97
|
+
{ id: '1.3', section: '', title: 'Task 3', status: 'in_progress', line: 3 },
|
|
98
|
+
{ id: '1.4', section: '', title: 'Task 4', status: 'pending', line: 4 },
|
|
99
|
+
];
|
|
100
|
+
const progress = parser.calculateProgress(tasks);
|
|
101
|
+
expect(progress.total).toBe(4);
|
|
102
|
+
expect(progress.completed).toBe(2);
|
|
103
|
+
expect(progress.inProgress).toBe(1);
|
|
104
|
+
expect(progress.pending).toBe(1);
|
|
105
|
+
expect(progress.percentage).toBe(50);
|
|
106
|
+
});
|
|
107
|
+
it('should handle empty task list', () => {
|
|
108
|
+
const progress = parser.calculateProgress([]);
|
|
109
|
+
expect(progress.total).toBe(0);
|
|
110
|
+
expect(progress.completed).toBe(0);
|
|
111
|
+
expect(progress.percentage).toBe(0);
|
|
112
|
+
});
|
|
113
|
+
it('should round percentage correctly', () => {
|
|
114
|
+
const tasks = [
|
|
115
|
+
{ id: '1.1', section: '', title: 'Task 1', status: 'done', line: 1 },
|
|
116
|
+
{ id: '1.2', section: '', title: 'Task 2', status: 'pending', line: 2 },
|
|
117
|
+
{ id: '1.3', section: '', title: 'Task 3', status: 'pending', line: 3 },
|
|
118
|
+
];
|
|
119
|
+
const progress = parser.calculateProgress(tasks);
|
|
120
|
+
expect(progress.percentage).toBe(33); // 1/3 = 33.33... rounded to 33
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=task-parser.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-parser.test.js","sourceRoot":"","sources":["../../src/core/task-parser.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 模板管理器
|
|
3
|
+
* 管理 Change 模板的创建和使用
|
|
4
|
+
*/
|
|
5
|
+
export interface TemplateFiles {
|
|
6
|
+
proposal: string;
|
|
7
|
+
tasks: string;
|
|
8
|
+
design?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface TemplateInfo {
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
files: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare class TemplateManager {
|
|
16
|
+
private cwd;
|
|
17
|
+
constructor(options?: {
|
|
18
|
+
cwd?: string;
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* 获取 openspec 目录
|
|
22
|
+
*/
|
|
23
|
+
private getOpenSpecDir;
|
|
24
|
+
/**
|
|
25
|
+
* 获取模板目录
|
|
26
|
+
*/
|
|
27
|
+
private getTemplatesDir;
|
|
28
|
+
/**
|
|
29
|
+
* 列出所有可用模板
|
|
30
|
+
*/
|
|
31
|
+
listTemplates(): Promise<TemplateInfo[]>;
|
|
32
|
+
/**
|
|
33
|
+
* 获取模板内容
|
|
34
|
+
*/
|
|
35
|
+
getTemplate(name: string): Promise<TemplateFiles | null>;
|
|
36
|
+
/**
|
|
37
|
+
* 创建新的 Change
|
|
38
|
+
*/
|
|
39
|
+
createChange(changeId: string, options?: {
|
|
40
|
+
template?: string;
|
|
41
|
+
title?: string;
|
|
42
|
+
}): Promise<{
|
|
43
|
+
success: boolean;
|
|
44
|
+
path?: string;
|
|
45
|
+
error?: string;
|
|
46
|
+
}>;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=template-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-manager.d.ts","sourceRoot":"","sources":["../../src/core/template-manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAuJD,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAS;gBAER,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE;IAItC;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAkC9C;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAuB9D;;OAEG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAC9C,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAmDhE"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 模板管理器
|
|
3
|
+
* 管理 Change 模板的创建和使用
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'fs/promises';
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
/**
|
|
8
|
+
* 默认模板定义
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_TEMPLATES = {
|
|
11
|
+
feature: {
|
|
12
|
+
description: 'New feature implementation',
|
|
13
|
+
files: {
|
|
14
|
+
proposal: `# Feature: {title}
|
|
15
|
+
|
|
16
|
+
## Summary
|
|
17
|
+
|
|
18
|
+
Brief description of the feature.
|
|
19
|
+
|
|
20
|
+
## Motivation
|
|
21
|
+
|
|
22
|
+
Why is this feature needed?
|
|
23
|
+
|
|
24
|
+
## Proposed Solution
|
|
25
|
+
|
|
26
|
+
High-level description of the solution.
|
|
27
|
+
|
|
28
|
+
## Alternatives Considered
|
|
29
|
+
|
|
30
|
+
Other approaches that were considered.
|
|
31
|
+
|
|
32
|
+
## Impact
|
|
33
|
+
|
|
34
|
+
- [ ] Breaking changes
|
|
35
|
+
- [ ] Database migrations
|
|
36
|
+
- [ ] API changes
|
|
37
|
+
`,
|
|
38
|
+
tasks: `# Tasks for {title}
|
|
39
|
+
|
|
40
|
+
## 1. Planning
|
|
41
|
+
|
|
42
|
+
- [ ] **1.1** Review requirements
|
|
43
|
+
- [ ] **1.2** Design API/interface
|
|
44
|
+
|
|
45
|
+
## 2. Implementation
|
|
46
|
+
|
|
47
|
+
- [ ] **2.1** Implement core logic
|
|
48
|
+
- [ ] **2.2** Add error handling
|
|
49
|
+
- [ ] **2.3** Write unit tests
|
|
50
|
+
|
|
51
|
+
## 3. Integration
|
|
52
|
+
|
|
53
|
+
- [ ] **3.1** Integration testing
|
|
54
|
+
- [ ] **3.2** Documentation
|
|
55
|
+
- [ ] **3.3** Code review
|
|
56
|
+
`,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
bugfix: {
|
|
60
|
+
description: 'Bug fix',
|
|
61
|
+
files: {
|
|
62
|
+
proposal: `# Bugfix: {title}
|
|
63
|
+
|
|
64
|
+
## Bug Description
|
|
65
|
+
|
|
66
|
+
What is the bug?
|
|
67
|
+
|
|
68
|
+
## Steps to Reproduce
|
|
69
|
+
|
|
70
|
+
1. Step 1
|
|
71
|
+
2. Step 2
|
|
72
|
+
3. Observe error
|
|
73
|
+
|
|
74
|
+
## Expected Behavior
|
|
75
|
+
|
|
76
|
+
What should happen?
|
|
77
|
+
|
|
78
|
+
## Root Cause
|
|
79
|
+
|
|
80
|
+
Analysis of why the bug occurs.
|
|
81
|
+
|
|
82
|
+
## Proposed Fix
|
|
83
|
+
|
|
84
|
+
How will the bug be fixed?
|
|
85
|
+
`,
|
|
86
|
+
tasks: `# Tasks for {title}
|
|
87
|
+
|
|
88
|
+
## 1. Investigation
|
|
89
|
+
|
|
90
|
+
- [ ] **1.1** Reproduce the bug
|
|
91
|
+
- [ ] **1.2** Identify root cause
|
|
92
|
+
|
|
93
|
+
## 2. Fix
|
|
94
|
+
|
|
95
|
+
- [ ] **2.1** Implement fix
|
|
96
|
+
- [ ] **2.2** Add regression test
|
|
97
|
+
|
|
98
|
+
## 3. Verification
|
|
99
|
+
|
|
100
|
+
- [ ] **3.1** Verify fix works
|
|
101
|
+
- [ ] **3.2** Check for side effects
|
|
102
|
+
- [ ] **3.3** Code review
|
|
103
|
+
`,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
refactor: {
|
|
107
|
+
description: 'Code refactoring',
|
|
108
|
+
files: {
|
|
109
|
+
proposal: `# Refactor: {title}
|
|
110
|
+
|
|
111
|
+
## Current State
|
|
112
|
+
|
|
113
|
+
Description of the current implementation.
|
|
114
|
+
|
|
115
|
+
## Problems
|
|
116
|
+
|
|
117
|
+
What issues does the current implementation have?
|
|
118
|
+
|
|
119
|
+
## Proposed Changes
|
|
120
|
+
|
|
121
|
+
How will the code be refactored?
|
|
122
|
+
|
|
123
|
+
## Benefits
|
|
124
|
+
|
|
125
|
+
- Improved maintainability
|
|
126
|
+
- Better performance
|
|
127
|
+
- Cleaner code
|
|
128
|
+
|
|
129
|
+
## Risks
|
|
130
|
+
|
|
131
|
+
Potential risks and mitigation strategies.
|
|
132
|
+
`,
|
|
133
|
+
tasks: `# Tasks for {title}
|
|
134
|
+
|
|
135
|
+
## 1. Preparation
|
|
136
|
+
|
|
137
|
+
- [ ] **1.1** Ensure test coverage
|
|
138
|
+
- [ ] **1.2** Document current behavior
|
|
139
|
+
|
|
140
|
+
## 2. Refactoring
|
|
141
|
+
|
|
142
|
+
- [ ] **2.1** Extract/rename components
|
|
143
|
+
- [ ] **2.2** Simplify logic
|
|
144
|
+
- [ ] **2.3** Update tests
|
|
145
|
+
|
|
146
|
+
## 3. Validation
|
|
147
|
+
|
|
148
|
+
- [ ] **3.1** Run all tests
|
|
149
|
+
- [ ] **3.2** Performance check
|
|
150
|
+
- [ ] **3.3** Code review
|
|
151
|
+
`,
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
export class TemplateManager {
|
|
156
|
+
cwd;
|
|
157
|
+
constructor(options) {
|
|
158
|
+
this.cwd = options?.cwd || process.cwd();
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* 获取 openspec 目录
|
|
162
|
+
*/
|
|
163
|
+
getOpenSpecDir() {
|
|
164
|
+
return path.join(this.cwd, 'openspec');
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* 获取模板目录
|
|
168
|
+
*/
|
|
169
|
+
getTemplatesDir() {
|
|
170
|
+
return path.join(this.getOpenSpecDir(), 'templates');
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* 列出所有可用模板
|
|
174
|
+
*/
|
|
175
|
+
async listTemplates() {
|
|
176
|
+
const templates = [];
|
|
177
|
+
// 添加内置模板
|
|
178
|
+
for (const [name, template] of Object.entries(DEFAULT_TEMPLATES)) {
|
|
179
|
+
templates.push({
|
|
180
|
+
name,
|
|
181
|
+
description: template.description,
|
|
182
|
+
files: Object.keys(template.files),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
// 检查自定义模板
|
|
186
|
+
try {
|
|
187
|
+
const templatesDir = this.getTemplatesDir();
|
|
188
|
+
const entries = await fs.readdir(templatesDir, { withFileTypes: true });
|
|
189
|
+
for (const entry of entries) {
|
|
190
|
+
if (entry.isDirectory() && !DEFAULT_TEMPLATES[entry.name]) {
|
|
191
|
+
const files = await fs.readdir(path.join(templatesDir, entry.name));
|
|
192
|
+
templates.push({
|
|
193
|
+
name: entry.name,
|
|
194
|
+
description: 'Custom template',
|
|
195
|
+
files: files.filter((f) => f.endsWith('.md')),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// 模板目录不存在
|
|
202
|
+
}
|
|
203
|
+
return templates;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* 获取模板内容
|
|
207
|
+
*/
|
|
208
|
+
async getTemplate(name) {
|
|
209
|
+
// 先检查内置模板
|
|
210
|
+
if (DEFAULT_TEMPLATES[name]) {
|
|
211
|
+
return DEFAULT_TEMPLATES[name].files;
|
|
212
|
+
}
|
|
213
|
+
// 检查自定义模板
|
|
214
|
+
const templateDir = path.join(this.getTemplatesDir(), name);
|
|
215
|
+
try {
|
|
216
|
+
const proposal = await fs.readFile(path.join(templateDir, 'proposal.md'), 'utf-8');
|
|
217
|
+
const tasks = await fs.readFile(path.join(templateDir, 'tasks.md'), 'utf-8');
|
|
218
|
+
let design;
|
|
219
|
+
try {
|
|
220
|
+
design = await fs.readFile(path.join(templateDir, 'design.md'), 'utf-8');
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// design.md 是可选的
|
|
224
|
+
}
|
|
225
|
+
return { proposal, tasks, design };
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* 创建新的 Change
|
|
233
|
+
*/
|
|
234
|
+
async createChange(changeId, options) {
|
|
235
|
+
const templateName = options?.template || 'feature';
|
|
236
|
+
const title = options?.title || changeId;
|
|
237
|
+
// 获取模板
|
|
238
|
+
const template = await this.getTemplate(templateName);
|
|
239
|
+
if (!template) {
|
|
240
|
+
return { success: false, error: `Template not found: ${templateName}` };
|
|
241
|
+
}
|
|
242
|
+
// 创建 change 目录
|
|
243
|
+
const changeDir = path.join(this.getOpenSpecDir(), 'changes', changeId);
|
|
244
|
+
try {
|
|
245
|
+
await fs.access(changeDir);
|
|
246
|
+
return { success: false, error: `Change already exists: ${changeId}` };
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
// 目录不存在,可以创建
|
|
250
|
+
}
|
|
251
|
+
try {
|
|
252
|
+
await fs.mkdir(changeDir, { recursive: true });
|
|
253
|
+
// 替换模板中的占位符
|
|
254
|
+
const replacePlaceholders = (content) => content.replace(/\{title\}/g, title).replace(/\{changeId\}/g, changeId);
|
|
255
|
+
// 写入文件
|
|
256
|
+
await fs.writeFile(path.join(changeDir, 'proposal.md'), replacePlaceholders(template.proposal), 'utf-8');
|
|
257
|
+
await fs.writeFile(path.join(changeDir, 'tasks.md'), replacePlaceholders(template.tasks), 'utf-8');
|
|
258
|
+
if (template.design) {
|
|
259
|
+
await fs.writeFile(path.join(changeDir, 'design.md'), replacePlaceholders(template.design), 'utf-8');
|
|
260
|
+
}
|
|
261
|
+
return { success: true, path: changeDir };
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
return { success: false, error: error.message };
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=template-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-manager.js","sourceRoot":"","sources":["../../src/core/template-manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAc7B;;GAEG;AACH,MAAM,iBAAiB,GAAkE;IACvF,OAAO,EAAE;QACP,WAAW,EAAE,4BAA4B;QACzC,KAAK,EAAE;YACL,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;CAuBf;YACK,KAAK,EAAE;;;;;;;;;;;;;;;;;;CAkBZ;SACI;KACF;IACD,MAAM,EAAE;QACN,WAAW,EAAE,SAAS;QACtB,KAAK,EAAE;YACL,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;CAuBf;YACK,KAAK,EAAE;;;;;;;;;;;;;;;;;CAiBZ;SACI;KACF;IACD,QAAQ,EAAE;QACR,WAAW,EAAE,kBAAkB;QAC/B,KAAK,EAAE;YACL,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;CAuBf;YACK,KAAK,EAAE;;;;;;;;;;;;;;;;;;CAkBZ;SACI;KACF;CACF,CAAC;AAEF,MAAM,OAAO,eAAe;IAClB,GAAG,CAAS;IAEpB,YAAY,OAA0B;QACpC,IAAI,CAAC,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC3C,CAAC;IAED;;OAEG;IACK,cAAc;QACpB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACK,eAAe;QACrB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,WAAW,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,SAAS,GAAmB,EAAE,CAAC;QAErC,SAAS;QACT,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACjE,SAAS,CAAC,IAAI,CAAC;gBACb,IAAI;gBACJ,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;aACnC,CAAC,CAAC;QACL,CAAC;QAED,UAAU;QACV,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YAExE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1D,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;oBACpE,SAAS,CAAC,IAAI,CAAC;wBACb,IAAI,EAAE,KAAK,CAAC,IAAI;wBAChB,WAAW,EAAE,iBAAiB;wBAC9B,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;qBAC9C,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,UAAU;QACZ,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,IAAY;QAC5B,UAAU;QACV,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;QACvC,CAAC;QAED,UAAU;QACV,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,IAAI,CAAC,CAAC;QAC5D,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE,OAAO,CAAC,CAAC;YACnF,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC;YAC7E,IAAI,MAA0B,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC;YAC3E,CAAC;YAAC,MAAM,CAAC;gBACP,iBAAiB;YACnB,CAAC;YACD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAChB,QAAgB,EAChB,OAA+C;QAE/C,MAAM,YAAY,GAAG,OAAO,EAAE,QAAQ,IAAI,SAAS,CAAC;QACpD,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,QAAQ,CAAC;QAEzC,OAAO;QACP,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QACtD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,uBAAuB,YAAY,EAAE,EAAE,CAAC;QAC1E,CAAC;QAED,eAAe;QACf,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QACxE,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC3B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,QAAQ,EAAE,EAAE,CAAC;QACzE,CAAC;QAAC,MAAM,CAAC;YACP,aAAa;QACf,CAAC;QAED,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAE/C,YAAY;YACZ,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAE,EAAE,CAC9C,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;YAE1E,OAAO;YACP,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,EACnC,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EACtC,OAAO,CACR,CAAC;YACF,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EAChC,mBAAmB,CAAC,QAAQ,CAAC,KAAK,CAAC,EACnC,OAAO,CACR,CAAC;YAEF,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACpB,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EACjC,mBAAmB,CAAC,QAAQ,CAAC,MAAM,CAAC,EACpC,OAAO,CACR,CAAC;YACJ,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC5C,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QAClD,CAAC;IACH,CAAC;CACF"}
|
package/dist/index.js
CHANGED
|
@@ -10,13 +10,21 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
|
10
10
|
import { Command } from 'commander';
|
|
11
11
|
import { OpenSpecCli } from './core/openspec-cli.js';
|
|
12
12
|
import { ApprovalManager } from './core/approval-manager.js';
|
|
13
|
+
import { ReviewManager } from './core/review-manager.js';
|
|
14
|
+
import { TemplateManager } from './core/template-manager.js';
|
|
15
|
+
import { HooksManager } from './core/hooks-manager.js';
|
|
16
|
+
import { ProposalGenerator } from './core/proposal-generator.js';
|
|
13
17
|
import { registerGuidesTools } from './server/tools/guides.js';
|
|
14
18
|
import { registerManagementTools } from './server/tools/management.js';
|
|
15
19
|
import { registerValidationTools } from './server/tools/validation.js';
|
|
16
20
|
import { registerArchiveTools } from './server/tools/archive.js';
|
|
17
21
|
import { registerTasksTools } from './server/tools/tasks.js';
|
|
18
22
|
import { registerApprovalTools } from './server/tools/approval.js';
|
|
19
|
-
|
|
23
|
+
import { registerReviewTools } from './server/tools/reviews.js';
|
|
24
|
+
import { registerTemplatesTools } from './server/tools/templates.js';
|
|
25
|
+
import { registerHooksTools } from './server/tools/hooks.js';
|
|
26
|
+
import { registerGeneratorTools } from './server/tools/generator.js';
|
|
27
|
+
import { VERSION } from './utils/version.js';
|
|
20
28
|
/**
|
|
21
29
|
* 创建并配置 MCP Server
|
|
22
30
|
*/
|
|
@@ -28,6 +36,10 @@ function createMcpServer(cwd) {
|
|
|
28
36
|
// 创建核心模块实例
|
|
29
37
|
const cli = new OpenSpecCli({ cwd });
|
|
30
38
|
const approvalManager = new ApprovalManager({ cwd });
|
|
39
|
+
const reviewManager = new ReviewManager({ cwd });
|
|
40
|
+
const templateManager = new TemplateManager({ cwd });
|
|
41
|
+
const hooksManager = new HooksManager({ cwd });
|
|
42
|
+
const proposalGenerator = new ProposalGenerator({ cwd });
|
|
31
43
|
// 注册所有工具
|
|
32
44
|
registerGuidesTools(server, cli);
|
|
33
45
|
registerManagementTools(server, cli);
|
|
@@ -35,6 +47,10 @@ function createMcpServer(cwd) {
|
|
|
35
47
|
registerArchiveTools(server, cli);
|
|
36
48
|
registerTasksTools(server, cli);
|
|
37
49
|
registerApprovalTools(server, approvalManager);
|
|
50
|
+
registerReviewTools(server, reviewManager);
|
|
51
|
+
registerTemplatesTools(server, templateManager);
|
|
52
|
+
registerHooksTools(server, hooksManager);
|
|
53
|
+
registerGeneratorTools(server, proposalGenerator);
|
|
38
54
|
return server;
|
|
39
55
|
}
|
|
40
56
|
/**
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C;;GAEG;AACH,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,WAAW;IACX,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACrC,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACrD,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACjD,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/C,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IAEzD,SAAS;IACT,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,qBAAqB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC/C,mBAAmB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC3C,sBAAsB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAChD,kBAAkB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACzC,sBAAsB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAElD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,cAAc,CAAC,GAAW;IACvC,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,OAAO,CAAC,KAAK,CAAC,wBAAwB,OAAO,UAAU,CAAC,CAAC;IACzD,OAAO,CAAC,KAAK,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,IAAY;IACrD,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAC3D,MAAM,cAAc,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,cAAc,CAAC;SACpB,WAAW,CAAC,mDAAmD,CAAC;SAChE,OAAO,CAAC,OAAO,CAAC;SAChB,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;SAC3D,MAAM,CAAC,aAAa,EAAE,2CAA2C,CAAC;SAClE,MAAM,CAAC,kBAAkB,EAAE,qCAAqC,CAAC;SACjE,MAAM,CAAC,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,CAAC;SACvD,MAAM,CAAC,KAAK,EAAE,WAAmB,EAAE,OAAuE,EAAE,EAAE;QAC7G,MAAM,GAAG,GAAG,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC;YACrC,CAAC,CAAC,WAAW;YACb,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,WAAW,EAAE,CAAC;QAEtC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,iBAAiB;YACjB,MAAM,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QACxD,CAAC;aAAM,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;YACjC,qBAAqB;YACrB,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACrE,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,WAAW;YACX,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,KAAK;AACL,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generator 类工具
|
|
3
|
+
* AI 辅助生成 Proposal
|
|
4
|
+
*/
|
|
5
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
|
+
import { ProposalGenerator } from '../../core/proposal-generator.js';
|
|
7
|
+
export declare function registerGeneratorTools(server: McpServer, proposalGenerator: ProposalGenerator): void;
|
|
8
|
+
//# sourceMappingURL=generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/server/tools/generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAErE,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,EACjB,iBAAiB,EAAE,iBAAiB,GACnC,IAAI,CAyIN"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generator 类工具
|
|
3
|
+
* AI 辅助生成 Proposal
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
export function registerGeneratorTools(server, proposalGenerator) {
|
|
7
|
+
/**
|
|
8
|
+
* 准备生成 proposal(返回 prompt 供 AI 使用)
|
|
9
|
+
*/
|
|
10
|
+
server.tool('openspec_prepare_proposal', 'Prepare context and prompt for generating a proposal from a requirement', {
|
|
11
|
+
requirement: z
|
|
12
|
+
.string()
|
|
13
|
+
.describe('Description of the feature or change requirement'),
|
|
14
|
+
}, async ({ requirement }) => {
|
|
15
|
+
const result = await proposalGenerator.prepareGeneration(requirement);
|
|
16
|
+
let text = `# Proposal Generation Prepared\n\n`;
|
|
17
|
+
text += `**Suggested Change ID**: \`${result.suggestedId}\`\n\n`;
|
|
18
|
+
text += `## Context Gathered\n\n`;
|
|
19
|
+
text += result.context || '_No project context found_';
|
|
20
|
+
text += `\n\n## Generation Prompt\n\n`;
|
|
21
|
+
text += `Use the following prompt to generate the proposal:\n\n`;
|
|
22
|
+
text += '```\n' + result.prompt + '\n```\n';
|
|
23
|
+
return {
|
|
24
|
+
content: [{ type: 'text', text }],
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* 保存生成的 proposal
|
|
29
|
+
*/
|
|
30
|
+
server.tool('openspec_save_proposal', 'Save a generated proposal and tasks to a new change', {
|
|
31
|
+
changeId: z
|
|
32
|
+
.string()
|
|
33
|
+
.describe('Change ID (kebab-case, e.g., add-user-auth)'),
|
|
34
|
+
proposal: z.string().describe('Content of proposal.md'),
|
|
35
|
+
tasks: z.string().describe('Content of tasks.md'),
|
|
36
|
+
}, async ({ changeId, proposal, tasks }) => {
|
|
37
|
+
const result = await proposalGenerator.saveDraft(changeId, proposal, tasks);
|
|
38
|
+
if (result.success) {
|
|
39
|
+
return {
|
|
40
|
+
content: [
|
|
41
|
+
{
|
|
42
|
+
type: 'text',
|
|
43
|
+
text: `✅ Saved proposal to: ${result.path}\n\nCreated files:\n- proposal.md\n- tasks.md`,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
return {
|
|
50
|
+
content: [
|
|
51
|
+
{
|
|
52
|
+
type: 'text',
|
|
53
|
+
text: `❌ Failed to save: ${result.error}`,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
isError: true,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
/**
|
|
61
|
+
* 一站式生成并保存(返回示例,需 AI 填充内容)
|
|
62
|
+
*/
|
|
63
|
+
server.tool('openspec_generate_proposal', 'Generate a proposal from requirement description (returns template for AI to complete)', {
|
|
64
|
+
requirement: z
|
|
65
|
+
.string()
|
|
66
|
+
.describe('Description of the feature or change requirement'),
|
|
67
|
+
changeId: z
|
|
68
|
+
.string()
|
|
69
|
+
.optional()
|
|
70
|
+
.describe('Optional custom change ID'),
|
|
71
|
+
}, async ({ requirement, changeId }) => {
|
|
72
|
+
const preparation = await proposalGenerator.prepareGeneration(requirement);
|
|
73
|
+
const finalId = changeId || preparation.suggestedId;
|
|
74
|
+
// 生成模板(AI 应该替换这些内容)
|
|
75
|
+
const proposalTemplate = `# ${requirement}
|
|
76
|
+
|
|
77
|
+
## Summary
|
|
78
|
+
|
|
79
|
+
[AI: Write a brief summary based on the requirement]
|
|
80
|
+
|
|
81
|
+
## Motivation
|
|
82
|
+
|
|
83
|
+
[AI: Explain why this change is needed]
|
|
84
|
+
|
|
85
|
+
## Proposed Solution
|
|
86
|
+
|
|
87
|
+
[AI: Describe the high-level solution]
|
|
88
|
+
|
|
89
|
+
## Impact
|
|
90
|
+
|
|
91
|
+
- [ ] Breaking changes: [AI: List any breaking changes]
|
|
92
|
+
- [ ] Dependencies: [AI: List affected dependencies]
|
|
93
|
+
`;
|
|
94
|
+
const tasksTemplate = `# Tasks for ${requirement}
|
|
95
|
+
|
|
96
|
+
## 1. Planning
|
|
97
|
+
|
|
98
|
+
- [ ] **1.1** [AI: Add planning tasks]
|
|
99
|
+
|
|
100
|
+
## 2. Implementation
|
|
101
|
+
|
|
102
|
+
- [ ] **2.1** [AI: Add implementation tasks]
|
|
103
|
+
- [ ] **2.2** [AI: Add more tasks as needed]
|
|
104
|
+
|
|
105
|
+
## 3. Verification
|
|
106
|
+
|
|
107
|
+
- [ ] **3.1** [AI: Add verification tasks]
|
|
108
|
+
`;
|
|
109
|
+
let text = `# Proposal Generation for: ${finalId}\n\n`;
|
|
110
|
+
text += `## Suggested Change ID\n\n\`${finalId}\`\n\n`;
|
|
111
|
+
text += `## Context\n\n${preparation.context || '_No project context_'}\n\n`;
|
|
112
|
+
text += `## Template proposal.md\n\n\`\`\`markdown\n${proposalTemplate}\`\`\`\n\n`;
|
|
113
|
+
text += `## Template tasks.md\n\n\`\`\`markdown\n${tasksTemplate}\`\`\`\n\n`;
|
|
114
|
+
text += `---\n\n`;
|
|
115
|
+
text += `**Next step**: Review and fill in the [AI: ...] placeholders, then use \`openspec_save_proposal\` to save.\n`;
|
|
116
|
+
return {
|
|
117
|
+
content: [{ type: 'text', text }],
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../src/server/tools/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hooks 类工具
|
|
3
|
+
* Git hooks 管理
|
|
4
|
+
*/
|
|
5
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
|
+
import { HooksManager } from '../../core/hooks-manager.js';
|
|
7
|
+
export declare function registerHooksTools(server: McpServer, hooksManager: HooksManager): void;
|
|
8
|
+
//# sourceMappingURL=hooks.d.ts.map
|