openspec-mcp 0.3.1 → 0.3.2

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.
Files changed (103) hide show
  1. package/README.md +22 -6
  2. package/README.zh.md +36 -1
  3. package/dist/api/routes/changes.d.ts.map +1 -1
  4. package/dist/api/routes/changes.js +42 -0
  5. package/dist/api/routes/changes.js.map +1 -1
  6. package/dist/api/routes/context.d.ts +8 -0
  7. package/dist/api/routes/context.d.ts.map +1 -0
  8. package/dist/api/routes/context.js +45 -0
  9. package/dist/api/routes/context.js.map +1 -0
  10. package/dist/api/routes/kanban.d.ts +8 -0
  11. package/dist/api/routes/kanban.d.ts.map +1 -0
  12. package/dist/api/routes/kanban.js +181 -0
  13. package/dist/api/routes/kanban.js.map +1 -0
  14. package/dist/api/routes/qa.d.ts +8 -0
  15. package/dist/api/routes/qa.d.ts.map +1 -0
  16. package/dist/api/routes/qa.js +98 -0
  17. package/dist/api/routes/qa.js.map +1 -0
  18. package/dist/api/server.d.ts +1 -0
  19. package/dist/api/server.d.ts.map +1 -1
  20. package/dist/api/server.js +7 -0
  21. package/dist/api/server.js.map +1 -1
  22. package/dist/core/approval-manager.d.ts.map +1 -1
  23. package/dist/core/approval-manager.js +9 -1
  24. package/dist/core/approval-manager.js.map +1 -1
  25. package/dist/core/approval-manager.test.js +14 -0
  26. package/dist/core/approval-manager.test.js.map +1 -1
  27. package/dist/core/context-analyzer.d.ts +116 -0
  28. package/dist/core/context-analyzer.d.ts.map +1 -0
  29. package/dist/core/context-analyzer.js +495 -0
  30. package/dist/core/context-analyzer.js.map +1 -0
  31. package/dist/core/prompt-manager.d.ts +50 -0
  32. package/dist/core/prompt-manager.d.ts.map +1 -0
  33. package/dist/core/prompt-manager.js +186 -0
  34. package/dist/core/prompt-manager.js.map +1 -0
  35. package/dist/core/qa-runner.d.ts +134 -0
  36. package/dist/core/qa-runner.d.ts.map +1 -0
  37. package/dist/core/qa-runner.js +299 -0
  38. package/dist/core/qa-runner.js.map +1 -0
  39. package/dist/core/spec-critic.d.ts +118 -0
  40. package/dist/core/spec-critic.d.ts.map +1 -0
  41. package/dist/core/spec-critic.js +478 -0
  42. package/dist/core/spec-critic.js.map +1 -0
  43. package/dist/core/spec-critic.test.d.ts +5 -0
  44. package/dist/core/spec-critic.test.d.ts.map +1 -0
  45. package/dist/core/spec-critic.test.js +152 -0
  46. package/dist/core/spec-critic.test.js.map +1 -0
  47. package/dist/index.js +33 -0
  48. package/dist/index.js.map +1 -1
  49. package/dist/server/tools/ai-context.d.ts +13 -0
  50. package/dist/server/tools/ai-context.d.ts.map +1 -0
  51. package/dist/server/tools/ai-context.js +212 -0
  52. package/dist/server/tools/ai-context.js.map +1 -0
  53. package/dist/server/tools/approval.d.ts.map +1 -1
  54. package/dist/server/tools/approval.js +33 -18
  55. package/dist/server/tools/approval.js.map +1 -1
  56. package/dist/server/tools/archive.d.ts.map +1 -1
  57. package/dist/server/tools/archive.js +9 -6
  58. package/dist/server/tools/archive.js.map +1 -1
  59. package/dist/server/tools/context.d.ts +12 -0
  60. package/dist/server/tools/context.d.ts.map +1 -0
  61. package/dist/server/tools/context.js +145 -0
  62. package/dist/server/tools/context.js.map +1 -0
  63. package/dist/server/tools/critique.d.ts +12 -0
  64. package/dist/server/tools/critique.d.ts.map +1 -0
  65. package/dist/server/tools/critique.js +194 -0
  66. package/dist/server/tools/critique.js.map +1 -0
  67. package/dist/server/tools/cross-service.d.ts.map +1 -1
  68. package/dist/server/tools/cross-service.js +11 -5
  69. package/dist/server/tools/cross-service.js.map +1 -1
  70. package/dist/server/tools/generator.d.ts.map +1 -1
  71. package/dist/server/tools/generator.js +27 -18
  72. package/dist/server/tools/generator.js.map +1 -1
  73. package/dist/server/tools/guides.d.ts.map +1 -1
  74. package/dist/server/tools/guides.js +8 -2
  75. package/dist/server/tools/guides.js.map +1 -1
  76. package/dist/server/tools/hooks.d.ts.map +1 -1
  77. package/dist/server/tools/hooks.js +7 -4
  78. package/dist/server/tools/hooks.js.map +1 -1
  79. package/dist/server/tools/management.d.ts.map +1 -1
  80. package/dist/server/tools/management.js +26 -14
  81. package/dist/server/tools/management.js.map +1 -1
  82. package/dist/server/tools/qa.d.ts +12 -0
  83. package/dist/server/tools/qa.d.ts.map +1 -0
  84. package/dist/server/tools/qa.js +248 -0
  85. package/dist/server/tools/qa.js.map +1 -0
  86. package/dist/server/tools/reviews.d.ts.map +1 -1
  87. package/dist/server/tools/reviews.js +55 -37
  88. package/dist/server/tools/reviews.js.map +1 -1
  89. package/dist/server/tools/tasks.d.ts.map +1 -1
  90. package/dist/server/tools/tasks.js +29 -17
  91. package/dist/server/tools/tasks.js.map +1 -1
  92. package/dist/server/tools/templates.d.ts.map +1 -1
  93. package/dist/server/tools/templates.js +26 -17
  94. package/dist/server/tools/templates.js.map +1 -1
  95. package/dist/server/tools/validation.d.ts.map +1 -1
  96. package/dist/server/tools/validation.js +31 -22
  97. package/dist/server/tools/validation.js.map +1 -1
  98. package/package.json +1 -1
  99. package/web/dist/assets/index-Bf5mzJti.css +1 -0
  100. package/web/dist/assets/index-W9UMaaAn.js +244 -0
  101. package/web/dist/index.html +2 -2
  102. package/web/dist/assets/index-CCYunmpc.css +0 -1
  103. package/web/dist/assets/index-wgGN6sVJ.js +0 -244
package/README.md CHANGED
@@ -77,14 +77,24 @@ claude mcp add openspec -- npx openspec-mcp /path/to/your/project
77
77
  "Request approval for add-user-auth from @reviewer"
78
78
  ```
79
79
 
80
+ ## Available Prompts (New!)
81
+
82
+ Directly leverage your Client's AI capabilities (Claude, Codex) with context-aware prompts.
83
+
84
+ | Prompt | Description |
85
+ | ----------------- | ----------------------------------------------- |
86
+ | `analyze-project` | Deep analysis of project architecture and stack |
87
+ | `review-change` | Intelligent review of changes with linked specs |
88
+
80
89
  ## Available Tools
81
90
 
82
- ### Guides
91
+ ### Guides & Context
83
92
 
84
- | Tool | Description |
85
- | ------------------------------ | ------------------------- |
86
- | `openspec_get_instructions` | Get AGENTS.md usage guide |
87
- | `openspec_get_project_context` | Get project.md context |
93
+ | Tool | Description |
94
+ | ------------------------------ | ---------------------------- |
95
+ | `openspec_get_instructions` | Get AGENTS.md usage guide |
96
+ | `openspec_get_project_context` | Get project.md context |
97
+ | `openspec_ai_analyze_context` | AI-enhanced context analysis |
88
98
 
89
99
  ### Management
90
100
 
@@ -243,14 +253,20 @@ The dashboard provides a visual interface for managing changes, tracking tasks,
243
253
  | Route | Description |
244
254
  | -------------- | -------------------------------------- |
245
255
  | `/` | Overview with stats and recent changes |
256
+ | `/kanban` | Drag-and-drop Kanban board |
246
257
  | `/changes` | List all changes with progress |
247
- | `/changes/:id` | Change detail with task management |
258
+ | `/changes/:id` | Change detail with Specs & Tasks |
259
+ | `/qa` | QA Runner dashboard |
260
+ | `/context` | Project analysis & Tech stack |
248
261
  | `/specs` | Browse specifications |
249
262
  | `/approvals` | Approval queue management |
250
263
 
251
264
  ### Features
252
265
 
253
266
  - **Real-time Updates**: WebSocket connection for live progress and review updates
267
+ - **Kanban Board**: 6-column workflow (Backlog -> Released) with drag-and-drop support
268
+ - **QA Dashboard**: Monitor and trigger quality checks directly from UI
269
+ - **Context Analysis**: Auto-detect tech stack and visualize directory structure
254
270
  - **Task Management**: Toggle task status directly from the UI
255
271
  - **Approval Actions**: Approve/reject changes with comments
256
272
  - **Progress Visualization**: Progress bars and status badges
package/README.zh.md CHANGED
@@ -77,14 +77,24 @@ claude mcp add openspec -- npx openspec-mcp /path/to/your/project
77
77
  "向 @reviewer 请求审批 add-user-auth"
78
78
  ```
79
79
 
80
+ ## 可用 Prompts (New!)
81
+
82
+ 直接利用 Client 的 AI 能力 (Claude, Codex) 并结合上下文感知 Prompt。
83
+
84
+ | Prompt | 描述 |
85
+ | ----------------- | ------------------------ |
86
+ | `analyze-project` | 深度分析项目架构和技术栈 |
87
+ | `review-change` | 智能审查变更及其关联规格 |
88
+
80
89
  ## 可用工具
81
90
 
82
- ### 指南类 (Guides)
91
+ ### 指南与上下文 (Guides & Context)
83
92
 
84
93
  | 工具 | 描述 |
85
94
  | ------------------------------ | -------------------------- |
86
95
  | `openspec_get_instructions` | 获取 AGENTS.md 使用指南 |
87
96
  | `openspec_get_project_context` | 获取 project.md 项目上下文 |
97
+ | `openspec_ai_analyze_context` | AI 增强的上下文分析 |
88
98
 
89
99
  ### 管理类 (Management)
90
100
 
@@ -139,6 +149,31 @@ claude mcp add openspec -- npx openspec-mcp /path/to/your/project
139
149
  | `openspec_get_review_summary` | 获取评审统计信息 |
140
150
  | `openspec_check_approval_readiness` | 检查是否可以请求审批 |
141
151
 
152
+ ### 评审自审类 (Critique)
153
+
154
+ | 工具 | 描述 |
155
+ | ------------------------------- | ---------------------------------- |
156
+ | `openspec_critique_proposal` | 评审 proposal/design,识别潜在问题 |
157
+ | `openspec_get_critique_history` | 获取评审历史记录 |
158
+ | `openspec_get_latest_critique` | 获取最新评审结果 |
159
+
160
+ ### 质量检查类 (QA)
161
+
162
+ | 工具 | 描述 |
163
+ | ------------------------- | ------------------------------ |
164
+ | `openspec_run_qa` | 运行质量检查(类型/lint/测试) |
165
+ | `openspec_get_qa_status` | 获取 QA 状态 |
166
+ | `openspec_get_qa_history` | 获取 QA 历史记录 |
167
+ | `openspec_stop_qa` | 停止正在运行的 QA |
168
+ | `openspec_get_qa_summary` | 获取所有变更的 QA 汇总 |
169
+
170
+ ### 上下文类 (Context)
171
+
172
+ | 工具 | 描述 |
173
+ | ------------------------------ | ----------------------------- |
174
+ | `openspec_analyze_context` | 分析项目上下文(技术栈/结构) |
175
+ | `openspec_get_context_summary` | 获取项目上下文摘要 |
176
+
142
177
  ### 模板类 (Templates)
143
178
 
144
179
  | 工具 | 描述 |
@@ -1 +1 @@
1
- {"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../../../src/api/routes/changes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAmKrF"}
1
+ {"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../../../src/api/routes/changes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAiNrF"}
@@ -105,6 +105,48 @@ export function registerChangesRoutes(fastify, ctx) {
105
105
  ctx.broadcast('review:resolved', { changeId: id, targetType, reviewId, status }, 'reviews');
106
106
  return { success: true };
107
107
  });
108
+ /**
109
+ * GET /api/changes/:id/specs - 获取 Change 关联的所有 specs
110
+ */
111
+ fastify.get('/changes/:id/specs', async (request, reply) => {
112
+ const { id } = request.params;
113
+ try {
114
+ // 获取 change 目录下的 specs
115
+ const specsDir = `${cli['getOpenSpecDir']()}/changes/${id}/specs`;
116
+ const specs = [];
117
+ const fs = await import('fs/promises');
118
+ const path = await import('path');
119
+ try {
120
+ const entries = await fs.readdir(specsDir, { withFileTypes: true });
121
+ for (const entry of entries) {
122
+ if (!entry.isDirectory())
123
+ continue;
124
+ const specPath = path.join(specsDir, entry.name, 'spec.md');
125
+ try {
126
+ const content = await fs.readFile(specPath, 'utf-8');
127
+ const titleMatch = content.match(/^#\s+(.+)/m);
128
+ const title = titleMatch ? titleMatch[1].trim() : entry.name;
129
+ specs.push({
130
+ id: entry.name,
131
+ title,
132
+ content,
133
+ });
134
+ }
135
+ catch {
136
+ // 没有 spec.md
137
+ }
138
+ }
139
+ }
140
+ catch {
141
+ // specs 目录不存在
142
+ }
143
+ return { specs };
144
+ }
145
+ catch (error) {
146
+ const message = error instanceof Error ? error.message : 'Failed to get specs';
147
+ return reply.status(500).send({ error: message });
148
+ }
149
+ });
108
150
  /**
109
151
  * GET /api/changes/:id/cross-service - 获取跨服务文档列表
110
152
  */
@@ -1 +1 @@
1
- {"version":3,"file":"changes.js","sourceRoot":"","sources":["../../../src/api/routes/changes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"changes.js","sourceRoot":"","sources":["../../../src/api/routes/changes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Context REST API 路由
3
+ * 提供项目上下文分析的 REST 接口
4
+ */
5
+ import type { FastifyInstance } from 'fastify';
6
+ import type { ApiContext } from '../server.js';
7
+ export declare function registerContextRoutes(fastify: FastifyInstance, ctx: ApiContext): void;
8
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/api/routes/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/C,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CA8CrF"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Context REST API 路由
3
+ * 提供项目上下文分析的 REST 接口
4
+ */
5
+ import { ContextAnalyzer } from '../../core/context-analyzer.js';
6
+ export function registerContextRoutes(fastify, ctx) {
7
+ // 创建 ContextAnalyzer 实例
8
+ const analyzer = new ContextAnalyzer({ cwd: ctx.cwd });
9
+ /**
10
+ * GET /api/context/analyze - 分析项目上下文
11
+ */
12
+ fastify.get('/context/analyze', async (request) => {
13
+ const { refresh } = request.query;
14
+ const context = refresh === 'true'
15
+ ? await analyzer.refreshContext()
16
+ : await analyzer.analyze();
17
+ return context;
18
+ });
19
+ /**
20
+ * GET /api/context/summary - 获取项目上下文摘要
21
+ */
22
+ fastify.get('/context/summary', async () => {
23
+ const cached = await analyzer.getCachedContext();
24
+ if (!cached) {
25
+ return { summary: null };
26
+ }
27
+ const languages = cached.stack.languages
28
+ .slice(0, 3)
29
+ .map(l => `${l.name} (${l.percentage}%)`)
30
+ .join(', ');
31
+ const summary = {
32
+ projectName: cached.projectName,
33
+ languages,
34
+ frameworks: cached.stack.frameworks.join(', ') || 'None detected',
35
+ packageManager: cached.stack.packageManager,
36
+ testFramework: cached.stack.testFramework || 'None detected',
37
+ architecture: cached.patterns.architecture,
38
+ totalFiles: cached.stats.totalFiles,
39
+ totalLines: cached.stats.totalLines,
40
+ analyzedAt: cached.analyzedAt,
41
+ };
42
+ return { summary };
43
+ });
44
+ }
45
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/api/routes/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEjE,MAAM,UAAU,qBAAqB,CAAC,OAAwB,EAAE,GAAe;IAC7E,wBAAwB;IACxB,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;IAEvD;;OAEG;IACH,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChD,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,KAA6B,CAAC;QAE1D,MAAM,OAAO,GAAG,OAAO,KAAK,MAAM;YAChC,CAAC,CAAC,MAAM,QAAQ,CAAC,cAAc,EAAE;YACjC,CAAC,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;QAE7B,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QACzC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,gBAAgB,EAAE,CAAC;QAEjD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS;aACrC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,UAAU,IAAI,CAAC;aACxC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,MAAM,OAAO,GAAG;YACd,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,SAAS;YACT,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,eAAe;YACjE,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,cAAc;YAC3C,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,eAAe;YAC5D,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,YAAY;YAC1C,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU;YACnC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU;YACnC,UAAU,EAAE,MAAM,CAAC,UAAU;SAC9B,CAAC;QAEF,OAAO,EAAE,OAAO,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Kanban REST API 路由
3
+ * 提供看板视图的后端支持
4
+ */
5
+ import type { FastifyInstance } from 'fastify';
6
+ import type { ApiContext } from '../server.js';
7
+ export declare function registerKanbanRoutes(fastify: FastifyInstance, ctx: ApiContext): void;
8
+ //# sourceMappingURL=kanban.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kanban.d.ts","sourceRoot":"","sources":["../../../src/api/routes/kanban.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAwD/C,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CA8KpF"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Kanban REST API 路由
3
+ * 提供看板视图的后端支持
4
+ */
5
+ // 列定义
6
+ const COLUMN_DEFINITIONS = [
7
+ { id: 'draft', title: 'Draft', color: '#6b7280' },
8
+ { id: 'pending_approval', title: 'Pending', color: '#f59e0b' },
9
+ { id: 'approved', title: 'Approved', color: '#10b981' },
10
+ { id: 'implementing', title: 'Implementing', color: '#3b82f6' },
11
+ { id: 'completed', title: 'Completed', color: '#8b5cf6' },
12
+ { id: 'archived', title: 'Archived', color: '#9ca3af' },
13
+ ];
14
+ // 状态到列的映射
15
+ function statusToColumn(status, isArchived) {
16
+ if (isArchived)
17
+ return 'archived';
18
+ const mapping = {
19
+ draft: 'draft',
20
+ pending_approval: 'pending_approval',
21
+ approved: 'approved',
22
+ rejected: 'draft', // 拒绝后回到 draft
23
+ implementing: 'implementing',
24
+ completed: 'completed',
25
+ };
26
+ return mapping[status || 'draft'] || 'draft';
27
+ }
28
+ export function registerKanbanRoutes(fastify, ctx) {
29
+ const { cli, approvalManager } = ctx;
30
+ /**
31
+ * GET /api/kanban - 获取看板数据
32
+ */
33
+ fastify.get('/kanban', async () => {
34
+ // 获取所有变更(包括归档)
35
+ const changes = await cli.listChanges({ includeArchived: true });
36
+ // 构建看板数据
37
+ const kanban = {
38
+ columns: COLUMN_DEFINITIONS.map(col => ({
39
+ ...col,
40
+ cards: [],
41
+ })),
42
+ summary: {
43
+ total: changes.length,
44
+ byColumn: {
45
+ draft: 0,
46
+ pending_approval: 0,
47
+ approved: 0,
48
+ implementing: 0,
49
+ completed: 0,
50
+ archived: 0,
51
+ },
52
+ },
53
+ };
54
+ // 分类变更到各列
55
+ for (const change of changes) {
56
+ // 获取审批状态
57
+ let approvalStatus;
58
+ try {
59
+ const approval = await approvalManager.getApprovalStatus(change.id);
60
+ approvalStatus = approval?.status;
61
+ }
62
+ catch {
63
+ // 忽略错误
64
+ }
65
+ const isArchived = change.status === 'archived';
66
+ const column = statusToColumn(approvalStatus, isArchived);
67
+ // 计算进度百分比
68
+ const progress = change.tasksTotal > 0
69
+ ? Math.round((change.tasksCompleted / change.tasksTotal) * 100)
70
+ : 0;
71
+ const card = {
72
+ id: change.id,
73
+ name: change.title || change.id,
74
+ description: undefined,
75
+ progress,
76
+ column,
77
+ labels: [],
78
+ priority: undefined,
79
+ updatedAt: change.updatedAt || new Date().toISOString(),
80
+ createdAt: change.createdAt || new Date().toISOString(),
81
+ };
82
+ // 添加标签
83
+ if (progress === 100)
84
+ card.labels.push('complete');
85
+ if (change.tasksTotal > 0)
86
+ card.labels.push('has-tasks');
87
+ // 添加到对应列
88
+ const colIndex = kanban.columns.findIndex(c => c.id === column);
89
+ if (colIndex >= 0) {
90
+ kanban.columns[colIndex].cards.push(card);
91
+ kanban.summary.byColumn[column]++;
92
+ }
93
+ }
94
+ // 按更新时间排序每列的卡片
95
+ for (const col of kanban.columns) {
96
+ col.cards.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
97
+ }
98
+ return kanban;
99
+ });
100
+ /**
101
+ * PUT /api/kanban/:id/move - 移动卡片到新列
102
+ */
103
+ fastify.put('/kanban/:id/move', async (request, reply) => {
104
+ const { id } = request.params;
105
+ const { toColumn, note } = request.body;
106
+ if (!COLUMN_DEFINITIONS.some(c => c.id === toColumn)) {
107
+ return reply.status(400).send({ error: 'Invalid column' });
108
+ }
109
+ // 根据目标列确定操作
110
+ try {
111
+ switch (toColumn) {
112
+ case 'pending_approval':
113
+ // 请求审批
114
+ await approvalManager.requestApproval(id, 'user', note ? [note] : undefined);
115
+ break;
116
+ case 'approved':
117
+ // 批准变更
118
+ await approvalManager.approve(id, 'user', note);
119
+ break;
120
+ case 'draft':
121
+ // 退回到草稿
122
+ await approvalManager.resetToDraft(id, 'user');
123
+ break;
124
+ case 'implementing':
125
+ // 开始实施
126
+ await approvalManager.startImplementation(id, 'user');
127
+ break;
128
+ case 'completed':
129
+ // 标记完成
130
+ await approvalManager.markCompleted(id, 'user');
131
+ break;
132
+ case 'archived':
133
+ // 归档
134
+ const result = await cli.archiveChange(id);
135
+ if (!result.success) {
136
+ return reply.status(400).send({ error: result.error });
137
+ }
138
+ break;
139
+ }
140
+ // 广播更新
141
+ ctx.broadcast('kanban:updated', { changeId: id, toColumn }, 'kanban');
142
+ return { success: true, changeId: id, newColumn: toColumn };
143
+ }
144
+ catch (error) {
145
+ const message = error instanceof Error ? error.message : 'Failed to move card';
146
+ return reply.status(400).send({ error: message });
147
+ }
148
+ });
149
+ /**
150
+ * GET /api/kanban/summary - 获取看板统计摘要
151
+ */
152
+ fastify.get('/kanban/summary', async () => {
153
+ const changes = await cli.listChanges({ includeArchived: true });
154
+ const summary = {
155
+ draft: 0,
156
+ pending_approval: 0,
157
+ approved: 0,
158
+ implementing: 0,
159
+ completed: 0,
160
+ archived: 0,
161
+ };
162
+ for (const change of changes) {
163
+ let approvalStatus;
164
+ try {
165
+ const approval = await approvalManager.getApprovalStatus(change.id);
166
+ approvalStatus = approval?.status;
167
+ }
168
+ catch {
169
+ // 忽略
170
+ }
171
+ const isArchived = change.status === 'archived';
172
+ const column = statusToColumn(approvalStatus, isArchived);
173
+ summary[column]++;
174
+ }
175
+ return {
176
+ total: changes.length,
177
+ columns: summary,
178
+ };
179
+ });
180
+ }
181
+ //# sourceMappingURL=kanban.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kanban.js","sourceRoot":"","sources":["../../../src/api/routes/kanban.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * QA REST API 路由
3
+ * 提供 QA Runner 的 REST 接口
4
+ */
5
+ import type { FastifyInstance } from 'fastify';
6
+ import type { ApiContext } from '../server.js';
7
+ export declare function registerQARoutes(fastify: FastifyInstance, ctx: ApiContext): void;
8
+ //# sourceMappingURL=qa.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qa.d.ts","sourceRoot":"","sources":["../../../src/api/routes/qa.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/C,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CA+GhF"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * QA REST API 路由
3
+ * 提供 QA Runner 的 REST 接口
4
+ */
5
+ import { QARunner } from '../../core/qa-runner.js';
6
+ export function registerQARoutes(fastify, ctx) {
7
+ // 创建 QARunner 实例
8
+ const qaRunner = new QARunner({ cwd: ctx.cwd });
9
+ /**
10
+ * GET /api/qa/status/:changeName - 获取指定变更的 QA 状态
11
+ */
12
+ fastify.get('/qa/status/:changeName', async (request) => {
13
+ const { changeName } = request.params;
14
+ const status = await qaRunner.getQAStatus(changeName);
15
+ return { status };
16
+ });
17
+ /**
18
+ * GET /api/qa/history/:changeName - 获取指定变更的 QA 历史
19
+ */
20
+ fastify.get('/qa/history/:changeName', async (request) => {
21
+ const { changeName } = request.params;
22
+ const { limit } = request.query;
23
+ const history = await qaRunner.getQAHistory(changeName, limit ? parseInt(limit, 10) : 10);
24
+ return { history };
25
+ });
26
+ /**
27
+ * GET /api/qa/summary - 获取所有变更的 QA 摘要统计
28
+ */
29
+ fastify.get('/qa/summary', async () => {
30
+ const summary = await qaRunner.getQASummary();
31
+ return summary;
32
+ });
33
+ /**
34
+ * POST /api/qa/run/:changeName - 触发指定变更的 QA 运行
35
+ */
36
+ fastify.post('/qa/run/:changeName', async (request, reply) => {
37
+ const { changeName } = request.params;
38
+ const { checks } = request.body;
39
+ // 检查是否已有运行中的 QA
40
+ if (qaRunner.isRunning(changeName)) {
41
+ return reply.status(409).send({
42
+ error: 'A QA check is already running for this change',
43
+ changeName
44
+ });
45
+ }
46
+ // 异步运行 QA,立即返回
47
+ const runPromise = qaRunner.runQA(changeName, { checks });
48
+ // 广播开始事件
49
+ ctx.broadcast('qa:started', { changeName, checks });
50
+ // 后台处理结果
51
+ runPromise.then(result => {
52
+ ctx.broadcast('qa:completed', {
53
+ changeName,
54
+ status: result.status,
55
+ summary: result.summary
56
+ });
57
+ }).catch(error => {
58
+ ctx.broadcast('qa:error', {
59
+ changeName,
60
+ error: error instanceof Error ? error.message : 'Unknown error'
61
+ });
62
+ });
63
+ return {
64
+ message: 'QA check started',
65
+ changeName,
66
+ checks: checks || ['typecheck', 'lint', 'test']
67
+ };
68
+ });
69
+ /**
70
+ * POST /api/qa/stop/:changeName - 停止运行中的 QA
71
+ */
72
+ fastify.post('/qa/stop/:changeName', async (request, reply) => {
73
+ const { changeName } = request.params;
74
+ if (!qaRunner.isRunning(changeName)) {
75
+ return reply.status(400).send({
76
+ error: 'No QA check is currently running for this change',
77
+ changeName
78
+ });
79
+ }
80
+ const stopped = await qaRunner.stopQA(changeName);
81
+ if (stopped) {
82
+ ctx.broadcast('qa:stopped', { changeName });
83
+ return { message: 'QA check stopped', changeName };
84
+ }
85
+ else {
86
+ return reply.status(500).send({ error: 'Failed to stop QA check' });
87
+ }
88
+ });
89
+ /**
90
+ * GET /api/qa/running - 获取所有正在运行的 QA
91
+ */
92
+ fastify.get('/qa/running', async () => {
93
+ const summary = await qaRunner.getQASummary();
94
+ const running = summary.changes.filter(c => c.status === 'running');
95
+ return { running };
96
+ });
97
+ }
98
+ //# sourceMappingURL=qa.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qa.js","sourceRoot":"","sources":["../../../src/api/routes/qa.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,7 @@ export interface ApiContext {
20
20
  specParser: SpecParser;
21
21
  fileWatcher: FileWatcher;
22
22
  crossServiceManager: CrossServiceManager;
23
+ cwd: string;
23
24
  broadcast: (event: string, data: any, topic?: string) => void;
24
25
  }
25
26
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAOnD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAMpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAMvE,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,WAAW,CAAC;IACjB,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/D;AA2CD;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAwQxF"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAOnD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AASpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAMvE,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,WAAW,CAAC;IACjB,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/D;AA2CD;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CA4QxF"}
@@ -18,6 +18,9 @@ import { registerSpecsRoutes } from './routes/specs.js';
18
18
  import { registerTasksRoutes } from './routes/tasks.js';
19
19
  import { registerApprovalsRoutes } from './routes/approvals.js';
20
20
  import { registerProjectRoutes } from './routes/project.js';
21
+ import { registerKanbanRoutes } from './routes/kanban.js';
22
+ import { registerContextRoutes } from './routes/context.js';
23
+ import { registerQARoutes } from './routes/qa.js';
21
24
  import { CrossServiceManager } from '../core/cross-service-manager.js';
22
25
  import { VERSION } from '../utils/version.js';
23
26
  const __filename = fileURLToPath(import.meta.url);
@@ -120,6 +123,7 @@ export async function startApiServer(options) {
120
123
  specParser,
121
124
  fileWatcher,
122
125
  crossServiceManager,
126
+ cwd,
123
127
  broadcast,
124
128
  };
125
129
  // 注册 WebSocket 路由
@@ -181,6 +185,9 @@ export async function startApiServer(options) {
181
185
  registerTasksRoutes(instance, ctx);
182
186
  registerApprovalsRoutes(instance, ctx);
183
187
  registerProjectRoutes(instance, ctx);
188
+ registerKanbanRoutes(instance, ctx);
189
+ registerContextRoutes(instance, ctx);
190
+ registerQARoutes(instance, ctx);
184
191
  }, { prefix: '/api' });
185
192
  // 健康检查
186
193
  fastify.get('/health', async () => {