openspec-mcp 0.1.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.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +205 -0
  3. package/README.zh.md +205 -0
  4. package/dist/api/routes/approvals.d.ts +7 -0
  5. package/dist/api/routes/approvals.d.ts.map +1 -0
  6. package/dist/api/routes/approvals.js +99 -0
  7. package/dist/api/routes/approvals.js.map +1 -0
  8. package/dist/api/routes/changes.d.ts +7 -0
  9. package/dist/api/routes/changes.d.ts.map +1 -0
  10. package/dist/api/routes/changes.js +55 -0
  11. package/dist/api/routes/changes.js.map +1 -0
  12. package/dist/api/routes/specs.d.ts +7 -0
  13. package/dist/api/routes/specs.d.ts.map +1 -0
  14. package/dist/api/routes/specs.js +34 -0
  15. package/dist/api/routes/specs.js.map +1 -0
  16. package/dist/api/routes/tasks.d.ts +7 -0
  17. package/dist/api/routes/tasks.d.ts.map +1 -0
  18. package/dist/api/routes/tasks.js +61 -0
  19. package/dist/api/routes/tasks.js.map +1 -0
  20. package/dist/api/server.d.ts +23 -0
  21. package/dist/api/server.d.ts.map +1 -0
  22. package/dist/api/server.js +142 -0
  23. package/dist/api/server.js.map +1 -0
  24. package/dist/core/approval-manager.d.ts +69 -0
  25. package/dist/core/approval-manager.d.ts.map +1 -0
  26. package/dist/core/approval-manager.js +268 -0
  27. package/dist/core/approval-manager.js.map +1 -0
  28. package/dist/core/file-watcher.d.ts +38 -0
  29. package/dist/core/file-watcher.d.ts.map +1 -0
  30. package/dist/core/file-watcher.js +128 -0
  31. package/dist/core/file-watcher.js.map +1 -0
  32. package/dist/core/openspec-cli.d.ts +94 -0
  33. package/dist/core/openspec-cli.d.ts.map +1 -0
  34. package/dist/core/openspec-cli.js +436 -0
  35. package/dist/core/openspec-cli.js.map +1 -0
  36. package/dist/core/task-parser.d.ts +48 -0
  37. package/dist/core/task-parser.d.ts.map +1 -0
  38. package/dist/core/task-parser.js +172 -0
  39. package/dist/core/task-parser.js.map +1 -0
  40. package/dist/index.d.ts +9 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +95 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/server/tools/approval.d.ts +8 -0
  45. package/dist/server/tools/approval.d.ts.map +1 -0
  46. package/dist/server/tools/approval.js +197 -0
  47. package/dist/server/tools/approval.js.map +1 -0
  48. package/dist/server/tools/archive.d.ts +8 -0
  49. package/dist/server/tools/archive.d.ts.map +1 -0
  50. package/dist/server/tools/archive.js +41 -0
  51. package/dist/server/tools/archive.js.map +1 -0
  52. package/dist/server/tools/guides.d.ts +8 -0
  53. package/dist/server/tools/guides.d.ts.map +1 -0
  54. package/dist/server/tools/guides.js +25 -0
  55. package/dist/server/tools/guides.js.map +1 -0
  56. package/dist/server/tools/management.d.ts +8 -0
  57. package/dist/server/tools/management.d.ts.map +1 -0
  58. package/dist/server/tools/management.js +96 -0
  59. package/dist/server/tools/management.js.map +1 -0
  60. package/dist/server/tools/tasks.d.ts +8 -0
  61. package/dist/server/tools/tasks.d.ts.map +1 -0
  62. package/dist/server/tools/tasks.js +124 -0
  63. package/dist/server/tools/tasks.js.map +1 -0
  64. package/dist/server/tools/validation.d.ts +8 -0
  65. package/dist/server/tools/validation.d.ts.map +1 -0
  66. package/dist/server/tools/validation.js +119 -0
  67. package/dist/server/tools/validation.js.map +1 -0
  68. package/dist/types/openspec.d.ts +141 -0
  69. package/dist/types/openspec.d.ts.map +1 -0
  70. package/dist/types/openspec.js +5 -0
  71. package/dist/types/openspec.js.map +1 -0
  72. package/package.json +58 -0
  73. package/web/dist/assets/index--LppUKpS.js +67 -0
  74. package/web/dist/assets/index-DdJQfs9Z.css +1 -0
  75. package/web/dist/index.html +14 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 OpenSpec MCP contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,205 @@
1
+ # OpenSpec MCP
2
+
3
+ [![npm version](https://img.shields.io/npm/v/openspec-mcp)](https://www.npmjs.com/package/openspec-mcp)
4
+
5
+ MCP (Model Context Protocol) server for [OpenSpec](https://github.com/Fission-AI/OpenSpec) - spec-driven development with real-time dashboard and approval workflow.
6
+
7
+ ## Features
8
+
9
+ - **MCP Tools**: Full OpenSpec CLI functionality exposed as MCP tools
10
+ - **Task Tracking**: Parse tasks.md and track progress in real-time
11
+ - **Approval Workflow**: Request, approve, and reject change proposals
12
+ - **Web Dashboard**: Visual management interface with real-time updates
13
+
14
+ ## Quick Start
15
+
16
+ ### 1. Add to your MCP configuration
17
+
18
+ **Claude Code CLI (recommended - uses current directory):**
19
+ ```bash
20
+ claude mcp add openspec -- npx openspec-mcp
21
+ ```
22
+
23
+ **Claude Code CLI with Dashboard:**
24
+ ```bash
25
+ claude mcp add openspec -- npx openspec-mcp --with-dashboard
26
+ ```
27
+
28
+ **Claude Code CLI with specific project path:**
29
+ ```bash
30
+ claude mcp add openspec -- npx openspec-mcp /path/to/your/project
31
+ ```
32
+
33
+ **Claude Desktop / Cursor / Other:**
34
+ ```json
35
+ {
36
+ "mcpServers": {
37
+ "openspec": {
38
+ "command": "npx",
39
+ "args": ["-y", "openspec-mcp"]
40
+ }
41
+ }
42
+ }
43
+ ```
44
+
45
+ **With Dashboard:**
46
+ ```json
47
+ {
48
+ "mcpServers": {
49
+ "openspec": {
50
+ "command": "npx",
51
+ "args": ["-y", "openspec-mcp", "--with-dashboard"]
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ ### 2. Use in conversation
58
+
59
+ ```
60
+ # List all changes
61
+ "List all openspec changes"
62
+
63
+ # Show change details
64
+ "Show me the add-user-auth change"
65
+
66
+ # Update task status
67
+ "Mark task 1.1 as done in add-user-auth"
68
+
69
+ # Request approval
70
+ "Request approval for add-user-auth from @reviewer"
71
+ ```
72
+
73
+ ## Available Tools
74
+
75
+ ### Guides
76
+ | Tool | Description |
77
+ |------|-------------|
78
+ | `openspec_get_instructions` | Get AGENTS.md usage guide |
79
+ | `openspec_get_project_context` | Get project.md context |
80
+
81
+ ### Management
82
+ | Tool | Description |
83
+ |------|-------------|
84
+ | `openspec_list_changes` | List all change proposals |
85
+ | `openspec_list_specs` | List all specifications |
86
+ | `openspec_show_change` | Show change details |
87
+ | `openspec_show_spec` | Show spec details |
88
+
89
+ ### Validation
90
+ | Tool | Description |
91
+ |------|-------------|
92
+ | `openspec_validate_change` | Validate a change |
93
+ | `openspec_validate_spec` | Validate a spec |
94
+ | `openspec_validate_all` | Batch validation |
95
+
96
+ ### Archive
97
+ | Tool | Description |
98
+ |------|-------------|
99
+ | `openspec_archive_change` | Archive completed change |
100
+
101
+ ### Tasks
102
+ | Tool | Description |
103
+ |------|-------------|
104
+ | `openspec_get_tasks` | Get tasks and progress |
105
+ | `openspec_update_task` | Update task status |
106
+ | `openspec_get_progress_summary` | Get all changes progress |
107
+
108
+ ### Approval
109
+ | Tool | Description |
110
+ |------|-------------|
111
+ | `openspec_get_approval_status` | Get approval status |
112
+ | `openspec_request_approval` | Request approval |
113
+ | `openspec_approve_change` | Approve a change |
114
+ | `openspec_reject_change` | Reject a change |
115
+ | `openspec_list_pending_approvals` | List pending approvals |
116
+
117
+ ## Approval Workflow
118
+
119
+ ```
120
+ draft -> pending_approval -> approved -> implementing -> completed -> archived
121
+ -> rejected -> draft (revise and resubmit)
122
+ ```
123
+
124
+ Approval records are stored in `openspec/approvals/<change-id>.json`.
125
+
126
+ ## CLI Options
127
+
128
+ ```bash
129
+ openspec-mcp [path] [options]
130
+
131
+ Arguments:
132
+ path Project directory path (default: current directory)
133
+
134
+ Options:
135
+ --dashboard Start web dashboard only (HTTP mode)
136
+ --with-dashboard Start MCP server with web dashboard
137
+ -p, --port <number> Dashboard port (default: 3000)
138
+ -V, --version Output version number
139
+ -h, --help Display help
140
+ ```
141
+
142
+ ### Examples
143
+
144
+ ```bash
145
+ # MCP server only (uses current directory)
146
+ openspec-mcp
147
+
148
+ # MCP server with specific project
149
+ openspec-mcp /path/to/project
150
+
151
+ # Dashboard only
152
+ openspec-mcp --dashboard
153
+
154
+ # MCP server + Dashboard
155
+ openspec-mcp --with-dashboard
156
+
157
+ # Dashboard on custom port
158
+ openspec-mcp --dashboard --port 8080
159
+ ```
160
+
161
+ ## Web Dashboard
162
+
163
+ The dashboard provides a visual interface for managing changes, tracking tasks, and handling approvals.
164
+
165
+ ### Dashboard Pages
166
+
167
+ | Route | Description |
168
+ |-------|-------------|
169
+ | `/` | Overview with stats and recent changes |
170
+ | `/changes` | List all changes with progress |
171
+ | `/changes/:id` | Change detail with task management |
172
+ | `/specs` | Browse specifications |
173
+ | `/approvals` | Approval queue management |
174
+
175
+ ### Features
176
+
177
+ - **Real-time Updates**: WebSocket connection for live progress updates
178
+ - **Task Management**: Toggle task status directly from the UI
179
+ - **Approval Actions**: Approve/reject changes with comments
180
+ - **Progress Visualization**: Progress bars and status badges
181
+
182
+ ## Development
183
+
184
+ ```bash
185
+ # Install dependencies
186
+ npm install
187
+
188
+ # Build
189
+ npm run build
190
+
191
+ # Development mode
192
+ npm run dev
193
+
194
+ # Run tests
195
+ npm test
196
+ ```
197
+
198
+ ## Requirements
199
+
200
+ - Node.js >= 20.0.0
201
+ - OpenSpec CLI (`npm install -g @fission-ai/openspec`)
202
+
203
+ ## License
204
+
205
+ MIT
package/README.zh.md ADDED
@@ -0,0 +1,205 @@
1
+ # OpenSpec MCP
2
+
3
+ [![npm version](https://img.shields.io/npm/v/openspec-mcp)](https://www.npmjs.com/package/openspec-mcp)
4
+
5
+ [OpenSpec](https://github.com/Fission-AI/OpenSpec) 的 MCP (Model Context Protocol) 服务器 - 规格驱动开发,支持实时仪表板和审批流程。
6
+
7
+ ## 功能特性
8
+
9
+ - **MCP 工具**: 将 OpenSpec CLI 完整功能暴露为 MCP 工具
10
+ - **任务追踪**: 解析 tasks.md 并实时追踪进度
11
+ - **审批流程**: 请求、批准和拒绝变更提案
12
+ - **Web 仪表板**: 可视化管理界面
13
+
14
+ ## 快速开始
15
+
16
+ ### 1. 添加到 MCP 配置
17
+
18
+ **Claude Code CLI(推荐,使用当前目录):**
19
+ ```bash
20
+ claude mcp add openspec -- npx openspec-mcp
21
+ ```
22
+
23
+ **Claude Code CLI 带仪表板:**
24
+ ```bash
25
+ claude mcp add openspec -- npx openspec-mcp --with-dashboard
26
+ ```
27
+
28
+ **Claude Code CLI 指定项目路径:**
29
+ ```bash
30
+ claude mcp add openspec -- npx openspec-mcp /path/to/your/project
31
+ ```
32
+
33
+ **Claude Desktop / Cursor / 其他:**
34
+ ```json
35
+ {
36
+ "mcpServers": {
37
+ "openspec": {
38
+ "command": "npx",
39
+ "args": ["-y", "openspec-mcp"]
40
+ }
41
+ }
42
+ }
43
+ ```
44
+
45
+ **带仪表板:**
46
+ ```json
47
+ {
48
+ "mcpServers": {
49
+ "openspec": {
50
+ "command": "npx",
51
+ "args": ["-y", "openspec-mcp", "--with-dashboard"]
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ ### 2. 在对话中使用
58
+
59
+ ```
60
+ # 列出所有变更
61
+ "列出所有 openspec 变更"
62
+
63
+ # 显示变更详情
64
+ "显示 add-user-auth 变更详情"
65
+
66
+ # 更新任务状态
67
+ "将 add-user-auth 中的任务 1.1 标记为完成"
68
+
69
+ # 请求审批
70
+ "向 @reviewer 请求审批 add-user-auth"
71
+ ```
72
+
73
+ ## 可用工具
74
+
75
+ ### 指南类 (Guides)
76
+ | 工具 | 描述 |
77
+ |------|------|
78
+ | `openspec_get_instructions` | 获取 AGENTS.md 使用指南 |
79
+ | `openspec_get_project_context` | 获取 project.md 项目上下文 |
80
+
81
+ ### 管理类 (Management)
82
+ | 工具 | 描述 |
83
+ |------|------|
84
+ | `openspec_list_changes` | 列出所有变更提案 |
85
+ | `openspec_list_specs` | 列出所有规格 |
86
+ | `openspec_show_change` | 显示变更详情 |
87
+ | `openspec_show_spec` | 显示规格详情 |
88
+
89
+ ### 验证类 (Validation)
90
+ | 工具 | 描述 |
91
+ |------|------|
92
+ | `openspec_validate_change` | 验证单个变更 |
93
+ | `openspec_validate_spec` | 验证单个规格 |
94
+ | `openspec_validate_all` | 批量验证 |
95
+
96
+ ### 归档类 (Archive)
97
+ | 工具 | 描述 |
98
+ |------|------|
99
+ | `openspec_archive_change` | 归档已完成变更 |
100
+
101
+ ### 任务类 (Tasks)
102
+ | 工具 | 描述 |
103
+ |------|------|
104
+ | `openspec_get_tasks` | 获取任务列表和进度 |
105
+ | `openspec_update_task` | 更新任务状态 |
106
+ | `openspec_get_progress_summary` | 获取所有变更进度汇总 |
107
+
108
+ ### 审批类 (Approval)
109
+ | 工具 | 描述 |
110
+ |------|------|
111
+ | `openspec_get_approval_status` | 获取审批状态 |
112
+ | `openspec_request_approval` | 请求审批 |
113
+ | `openspec_approve_change` | 批准变更 |
114
+ | `openspec_reject_change` | 拒绝变更 |
115
+ | `openspec_list_pending_approvals` | 列出待审批项 |
116
+
117
+ ## 审批流程
118
+
119
+ ```
120
+ draft -> pending_approval -> approved -> implementing -> completed -> archived
121
+ -> rejected -> draft (修改后重新提交)
122
+ ```
123
+
124
+ 审批记录存储在 `openspec/approvals/<change-id>.json`。
125
+
126
+ ## CLI 选项
127
+
128
+ ```bash
129
+ openspec-mcp [path] [options]
130
+
131
+ 参数:
132
+ path 项目目录路径(默认:当前目录)
133
+
134
+ 选项:
135
+ --dashboard 仅启动 Web 仪表板(HTTP 模式)
136
+ --with-dashboard 启动 MCP 服务器并同时启动仪表板
137
+ -p, --port <number> 仪表板端口(默认:3000)
138
+ -V, --version 显示版本号
139
+ -h, --help 显示帮助
140
+ ```
141
+
142
+ ### 示例
143
+
144
+ ```bash
145
+ # 仅 MCP 服务器(使用当前目录)
146
+ openspec-mcp
147
+
148
+ # MCP 服务器指定项目
149
+ openspec-mcp /path/to/project
150
+
151
+ # 仅仪表板
152
+ openspec-mcp --dashboard
153
+
154
+ # MCP 服务器 + 仪表板
155
+ openspec-mcp --with-dashboard
156
+
157
+ # 自定义端口启动仪表板
158
+ openspec-mcp --dashboard --port 8080
159
+ ```
160
+
161
+ ## Web 仪表板
162
+
163
+ 仪表板提供可视化界面,用于管理变更、追踪任务和处理审批。
164
+
165
+ ### 仪表板页面
166
+
167
+ | 路由 | 描述 |
168
+ |------|------|
169
+ | `/` | 概览统计和最近变更 |
170
+ | `/changes` | 变更列表及进度 |
171
+ | `/changes/:id` | 变更详情和任务管理 |
172
+ | `/specs` | 浏览规格文档 |
173
+ | `/approvals` | 审批队列管理 |
174
+
175
+ ### 功能亮点
176
+
177
+ - **实时更新**: WebSocket 连接实现实时进度更新
178
+ - **任务管理**: 直接在 UI 中切换任务状态
179
+ - **审批操作**: 带备注的批准/拒绝操作
180
+ - **进度可视化**: 进度条和状态徽章
181
+
182
+ ## 开发
183
+
184
+ ```bash
185
+ # 安装依赖
186
+ npm install
187
+
188
+ # 构建
189
+ npm run build
190
+
191
+ # 开发模式
192
+ npm run dev
193
+
194
+ # 运行测试
195
+ npm test
196
+ ```
197
+
198
+ ## 系统要求
199
+
200
+ - Node.js >= 20.0.0
201
+ - OpenSpec CLI (`npm install -g @fission-ai/openspec`)
202
+
203
+ ## 许可证
204
+
205
+ MIT
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Approvals REST API 路由
3
+ */
4
+ import type { FastifyInstance } from 'fastify';
5
+ import type { ApiContext } from '../server.js';
6
+ export declare function registerApprovalsRoutes(fastify: FastifyInstance, ctx: ApiContext): void;
7
+ //# sourceMappingURL=approvals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../../../src/api/routes/approvals.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,uBAAuB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAoHvF"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Approvals REST API 路由
3
+ */
4
+ export function registerApprovalsRoutes(fastify, ctx) {
5
+ const { approvalManager } = ctx;
6
+ /**
7
+ * GET /api/approvals - 列出所有审批记录
8
+ */
9
+ fastify.get('/approvals', async () => {
10
+ const approvals = await approvalManager.listApprovals();
11
+ return { approvals };
12
+ });
13
+ /**
14
+ * GET /api/approvals/pending - 列出待审批记录
15
+ */
16
+ fastify.get('/approvals/pending', async () => {
17
+ const approvals = await approvalManager.listPendingApprovals();
18
+ return { approvals };
19
+ });
20
+ /**
21
+ * GET /api/approvals/:changeId - 获取审批状态
22
+ */
23
+ fastify.get('/approvals/:changeId', async (request, reply) => {
24
+ const { changeId } = request.params;
25
+ const record = await approvalManager.getApprovalStatus(changeId);
26
+ if (!record) {
27
+ return reply.status(404).send({ error: 'Approval record not found' });
28
+ }
29
+ return { approval: record };
30
+ });
31
+ /**
32
+ * POST /api/approvals/:changeId/request - 请求审批
33
+ */
34
+ fastify.post('/approvals/:changeId/request', async (request, reply) => {
35
+ const { changeId } = request.params;
36
+ const { requestedBy, reviewers } = request.body;
37
+ if (!requestedBy) {
38
+ return reply.status(400).send({ error: 'requestedBy is required' });
39
+ }
40
+ try {
41
+ const record = await approvalManager.requestApproval(changeId, requestedBy, reviewers);
42
+ ctx.broadcast('approval:requested', { changeId, record });
43
+ return { approval: record };
44
+ }
45
+ catch (error) {
46
+ return reply.status(400).send({ error: error.message });
47
+ }
48
+ });
49
+ /**
50
+ * POST /api/approvals/:changeId/approve - 审批通过
51
+ */
52
+ fastify.post('/approvals/:changeId/approve', async (request, reply) => {
53
+ const { changeId } = request.params;
54
+ const { approver, comment } = request.body;
55
+ if (!approver) {
56
+ return reply.status(400).send({ error: 'approver is required' });
57
+ }
58
+ try {
59
+ const record = await approvalManager.approve(changeId, approver, comment);
60
+ ctx.broadcast('approval:approved', { changeId, record });
61
+ return { approval: record };
62
+ }
63
+ catch (error) {
64
+ return reply.status(400).send({ error: error.message });
65
+ }
66
+ });
67
+ /**
68
+ * POST /api/approvals/:changeId/reject - 审批拒绝
69
+ */
70
+ fastify.post('/approvals/:changeId/reject', async (request, reply) => {
71
+ const { changeId } = request.params;
72
+ const { rejector, reason } = request.body;
73
+ if (!rejector || !reason) {
74
+ return reply.status(400).send({ error: 'rejector and reason are required' });
75
+ }
76
+ try {
77
+ const record = await approvalManager.reject(changeId, rejector, reason);
78
+ ctx.broadcast('approval:rejected', { changeId, record });
79
+ return { approval: record };
80
+ }
81
+ catch (error) {
82
+ return reply.status(400).send({ error: error.message });
83
+ }
84
+ });
85
+ /**
86
+ * DELETE /api/approvals/:changeId - 删除审批记录
87
+ */
88
+ fastify.delete('/approvals/:changeId', async (request, reply) => {
89
+ const { changeId } = request.params;
90
+ const deleted = await approvalManager.deleteApproval(changeId);
91
+ if (deleted) {
92
+ return { success: true };
93
+ }
94
+ else {
95
+ return reply.status(404).send({ error: 'Approval record not found' });
96
+ }
97
+ });
98
+ }
99
+ //# sourceMappingURL=approvals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approvals.js","sourceRoot":"","sources":["../../../src/api/routes/approvals.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Changes REST API 路由
3
+ */
4
+ import type { FastifyInstance } from 'fastify';
5
+ import type { ApiContext } from '../server.js';
6
+ export declare function registerChangesRoutes(fastify: FastifyInstance, ctx: ApiContext): void;
7
+ //# sourceMappingURL=changes.d.ts.map
@@ -0,0 +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,CA0DrF"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Changes REST API 路由
3
+ */
4
+ export function registerChangesRoutes(fastify, ctx) {
5
+ const { cli } = ctx;
6
+ /**
7
+ * GET /api/changes - 列出所有变更
8
+ */
9
+ fastify.get('/changes', async (request, reply) => {
10
+ const { includeArchived } = request.query;
11
+ const changes = await cli.listChanges({
12
+ includeArchived: includeArchived === 'true',
13
+ });
14
+ return { changes };
15
+ });
16
+ /**
17
+ * GET /api/changes/:id - 获取变更详情
18
+ */
19
+ fastify.get('/changes/:id', async (request, reply) => {
20
+ const { id } = request.params;
21
+ const change = await cli.showChange(id);
22
+ if (!change) {
23
+ return reply.status(404).send({ error: 'Change not found' });
24
+ }
25
+ return { change };
26
+ });
27
+ /**
28
+ * POST /api/changes/:id/validate - 验证变更
29
+ */
30
+ fastify.post('/changes/:id/validate', async (request, reply) => {
31
+ const { id } = request.params;
32
+ const body = (request.body || {});
33
+ const { strict } = body;
34
+ const result = await cli.validateChange(id, { strict });
35
+ return result;
36
+ });
37
+ /**
38
+ * POST /api/changes/:id/archive - 归档变更
39
+ */
40
+ fastify.post('/changes/:id/archive', async (request, reply) => {
41
+ const { id } = request.params;
42
+ const body = (request.body || {});
43
+ const { skipSpecs } = body;
44
+ const result = await cli.archiveChange(id, { skipSpecs });
45
+ if (result.success) {
46
+ // 广播归档事件
47
+ ctx.broadcast('change:archived', { changeId: id, archivedPath: result.archivedPath });
48
+ return result;
49
+ }
50
+ else {
51
+ return reply.status(400).send(result);
52
+ }
53
+ });
54
+ }
55
+ //# sourceMappingURL=changes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changes.js","sourceRoot":"","sources":["../../../src/api/routes/changes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,UAAU,qBAAqB,CAAC,OAAwB,EAAE,GAAe;IAC7E,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC/C,MAAM,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,KAAqC,CAAC;QAC1E,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC;YACpC,eAAe,EAAE,eAAe,KAAK,MAAM;SAC5C,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACnD,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAwB,CAAC;QAChD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAExC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC/D,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,OAAO,CAAC,IAAI,CAAC,uBAAuB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC7D,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAwB,CAAC;QAChD,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAyB,CAAC;QAC1D,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAExB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACxD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC5D,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAwB,CAAC;QAChD,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC;QAC7D,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;QAE3B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAE1D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,SAAS;YACT,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;YACtF,OAAO,MAAM,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Specs REST API 路由
3
+ */
4
+ import type { FastifyInstance } from 'fastify';
5
+ import type { ApiContext } from '../server.js';
6
+ export declare function registerSpecsRoutes(fastify: FastifyInstance, ctx: ApiContext): void;
7
+ //# sourceMappingURL=specs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"specs.d.ts","sourceRoot":"","sources":["../../../src/api/routes/specs.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,mBAAmB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAmCnF"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Specs REST API 路由
3
+ */
4
+ export function registerSpecsRoutes(fastify, ctx) {
5
+ const { cli } = ctx;
6
+ /**
7
+ * GET /api/specs - 列出所有规格
8
+ */
9
+ fastify.get('/specs', async () => {
10
+ const specs = await cli.listSpecs();
11
+ return { specs };
12
+ });
13
+ /**
14
+ * GET /api/specs/:id - 获取规格详情
15
+ */
16
+ fastify.get('/specs/:id', async (request, reply) => {
17
+ const { id } = request.params;
18
+ const spec = await cli.showSpec(id);
19
+ if (!spec) {
20
+ return reply.status(404).send({ error: 'Spec not found' });
21
+ }
22
+ return { spec };
23
+ });
24
+ /**
25
+ * POST /api/specs/:id/validate - 验证规格
26
+ */
27
+ fastify.post('/specs/:id/validate', async (request) => {
28
+ const { id } = request.params;
29
+ const { strict } = request.body;
30
+ const result = await cli.validateSpec(id, { strict });
31
+ return result;
32
+ });
33
+ }
34
+ //# sourceMappingURL=specs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"specs.js","sourceRoot":"","sources":["../../../src/api/routes/specs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,UAAU,mBAAmB,CAAC,OAAwB,EAAE,GAAe;IAC3E,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;QAC/B,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,SAAS,EAAE,CAAC;QACpC,OAAO,EAAE,KAAK,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACjD,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAwB,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAEpC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACpD,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAwB,CAAC;QAChD,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAA4B,CAAC;QAExD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACtD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Tasks REST API 路由
3
+ */
4
+ import type { FastifyInstance } from 'fastify';
5
+ import type { ApiContext } from '../server.js';
6
+ export declare function registerTasksRoutes(fastify: FastifyInstance, ctx: ApiContext): void;
7
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../../src/api/routes/tasks.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,mBAAmB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAiEnF"}