@blackms/aistack 1.1.0 → 1.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/dist/memory/index.d.ts +23 -1
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +54 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/sqlite-store.d.ts +26 -1
- package/dist/memory/sqlite-store.d.ts.map +1 -1
- package/dist/memory/sqlite-store.js +356 -0
- package/dist/memory/sqlite-store.js.map +1 -1
- package/dist/types.d.ts +56 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/validation.d.ts +2 -2
- package/dist/web/routes/filesystem.d.ts +7 -0
- package/dist/web/routes/filesystem.d.ts.map +1 -0
- package/dist/web/routes/filesystem.js +212 -0
- package/dist/web/routes/filesystem.js.map +1 -0
- package/dist/web/routes/index.d.ts +3 -0
- package/dist/web/routes/index.d.ts.map +1 -1
- package/dist/web/routes/index.js +3 -0
- package/dist/web/routes/index.js.map +1 -1
- package/dist/web/routes/projects.d.ts +7 -0
- package/dist/web/routes/projects.d.ts.map +1 -0
- package/dist/web/routes/projects.js +296 -0
- package/dist/web/routes/projects.js.map +1 -0
- package/dist/web/routes/specifications.d.ts +7 -0
- package/dist/web/routes/specifications.d.ts.map +1 -0
- package/dist/web/routes/specifications.js +267 -0
- package/dist/web/routes/specifications.js.map +1 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +7 -1
- package/dist/web/server.js.map +1 -1
- package/dist/web/types.d.ts +64 -0
- package/dist/web/types.d.ts.map +1 -1
- package/dist/web/websocket/event-bridge.d.ts +38 -1
- package/dist/web/websocket/event-bridge.d.ts.map +1 -1
- package/dist/web/websocket/event-bridge.js +7 -0
- package/dist/web/websocket/event-bridge.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project routes
|
|
3
|
+
*/
|
|
4
|
+
import { PHASE_TRANSITIONS } from '../../types.js';
|
|
5
|
+
import { sendJson } from '../router.js';
|
|
6
|
+
import { badRequest, notFound } from '../middleware/error.js';
|
|
7
|
+
import { getMemoryManager } from '../../memory/index.js';
|
|
8
|
+
import { agentEvents } from '../websocket/event-bridge.js';
|
|
9
|
+
export function registerProjectRoutes(router, config) {
|
|
10
|
+
const getManager = () => getMemoryManager(config);
|
|
11
|
+
// GET /api/v1/projects - List projects
|
|
12
|
+
router.get('/api/v1/projects', (_req, res, params) => {
|
|
13
|
+
const status = params.query.status;
|
|
14
|
+
const manager = getManager();
|
|
15
|
+
const projects = manager.listProjects(status);
|
|
16
|
+
sendJson(res, projects.map(project => ({
|
|
17
|
+
...project,
|
|
18
|
+
createdAt: project.createdAt.toISOString(),
|
|
19
|
+
updatedAt: project.updatedAt.toISOString(),
|
|
20
|
+
})));
|
|
21
|
+
});
|
|
22
|
+
// POST /api/v1/projects - Create project
|
|
23
|
+
router.post('/api/v1/projects', (_req, res, params) => {
|
|
24
|
+
const body = params.body;
|
|
25
|
+
if (!body?.name) {
|
|
26
|
+
throw badRequest('Project name is required');
|
|
27
|
+
}
|
|
28
|
+
if (!body?.path) {
|
|
29
|
+
throw badRequest('Project path is required');
|
|
30
|
+
}
|
|
31
|
+
const manager = getManager();
|
|
32
|
+
const project = manager.createProject(body.name, body.path, body.description, body.metadata);
|
|
33
|
+
// Emit event for WebSocket clients
|
|
34
|
+
agentEvents.emit('project:created', {
|
|
35
|
+
id: project.id,
|
|
36
|
+
name: project.name,
|
|
37
|
+
path: project.path,
|
|
38
|
+
});
|
|
39
|
+
sendJson(res, {
|
|
40
|
+
...project,
|
|
41
|
+
createdAt: project.createdAt.toISOString(),
|
|
42
|
+
updatedAt: project.updatedAt.toISOString(),
|
|
43
|
+
}, 201);
|
|
44
|
+
});
|
|
45
|
+
// GET /api/v1/projects/:id - Get project by ID
|
|
46
|
+
router.get('/api/v1/projects/:id', (_req, res, params) => {
|
|
47
|
+
const projectId = params.path[0];
|
|
48
|
+
if (!projectId) {
|
|
49
|
+
throw badRequest('Project ID is required');
|
|
50
|
+
}
|
|
51
|
+
const manager = getManager();
|
|
52
|
+
const project = manager.getProject(projectId);
|
|
53
|
+
if (!project) {
|
|
54
|
+
throw notFound('Project');
|
|
55
|
+
}
|
|
56
|
+
sendJson(res, {
|
|
57
|
+
...project,
|
|
58
|
+
createdAt: project.createdAt.toISOString(),
|
|
59
|
+
updatedAt: project.updatedAt.toISOString(),
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
// PUT /api/v1/projects/:id - Update project
|
|
63
|
+
router.put('/api/v1/projects/:id', (_req, res, params) => {
|
|
64
|
+
const projectId = params.path[0];
|
|
65
|
+
if (!projectId) {
|
|
66
|
+
throw badRequest('Project ID is required');
|
|
67
|
+
}
|
|
68
|
+
const body = params.body;
|
|
69
|
+
if (!body) {
|
|
70
|
+
throw badRequest('Request body is required');
|
|
71
|
+
}
|
|
72
|
+
const manager = getManager();
|
|
73
|
+
const project = manager.getProject(projectId);
|
|
74
|
+
if (!project) {
|
|
75
|
+
throw notFound('Project');
|
|
76
|
+
}
|
|
77
|
+
const success = manager.updateProject(projectId, body);
|
|
78
|
+
if (!success) {
|
|
79
|
+
throw notFound('Project');
|
|
80
|
+
}
|
|
81
|
+
const updated = manager.getProject(projectId);
|
|
82
|
+
// Emit event for WebSocket clients
|
|
83
|
+
agentEvents.emit('project:updated', {
|
|
84
|
+
id: projectId,
|
|
85
|
+
changes: body,
|
|
86
|
+
});
|
|
87
|
+
sendJson(res, {
|
|
88
|
+
...updated,
|
|
89
|
+
createdAt: updated?.createdAt.toISOString(),
|
|
90
|
+
updatedAt: updated?.updatedAt.toISOString(),
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
// DELETE /api/v1/projects/:id - Delete project
|
|
94
|
+
router.delete('/api/v1/projects/:id', (_req, res, params) => {
|
|
95
|
+
const projectId = params.path[0];
|
|
96
|
+
if (!projectId) {
|
|
97
|
+
throw badRequest('Project ID is required');
|
|
98
|
+
}
|
|
99
|
+
const manager = getManager();
|
|
100
|
+
const success = manager.deleteProject(projectId);
|
|
101
|
+
if (!success) {
|
|
102
|
+
throw notFound('Project');
|
|
103
|
+
}
|
|
104
|
+
sendJson(res, { deleted: true });
|
|
105
|
+
});
|
|
106
|
+
// GET /api/v1/projects/:id/tasks - List project tasks
|
|
107
|
+
router.get('/api/v1/projects/:id/tasks', (_req, res, params) => {
|
|
108
|
+
const projectId = params.path[0];
|
|
109
|
+
if (!projectId) {
|
|
110
|
+
throw badRequest('Project ID is required');
|
|
111
|
+
}
|
|
112
|
+
const phase = params.query.phase;
|
|
113
|
+
const manager = getManager();
|
|
114
|
+
const project = manager.getProject(projectId);
|
|
115
|
+
if (!project) {
|
|
116
|
+
throw notFound('Project');
|
|
117
|
+
}
|
|
118
|
+
const tasks = manager.listProjectTasks(projectId, phase);
|
|
119
|
+
sendJson(res, tasks.map(task => ({
|
|
120
|
+
...task,
|
|
121
|
+
createdAt: task.createdAt.toISOString(),
|
|
122
|
+
updatedAt: task.updatedAt.toISOString(),
|
|
123
|
+
completedAt: task.completedAt?.toISOString(),
|
|
124
|
+
})));
|
|
125
|
+
});
|
|
126
|
+
// POST /api/v1/projects/:id/tasks - Create project task
|
|
127
|
+
router.post('/api/v1/projects/:id/tasks', (_req, res, params) => {
|
|
128
|
+
const projectId = params.path[0];
|
|
129
|
+
if (!projectId) {
|
|
130
|
+
throw badRequest('Project ID is required');
|
|
131
|
+
}
|
|
132
|
+
const body = params.body;
|
|
133
|
+
if (!body?.title) {
|
|
134
|
+
throw badRequest('Task title is required');
|
|
135
|
+
}
|
|
136
|
+
const manager = getManager();
|
|
137
|
+
const project = manager.getProject(projectId);
|
|
138
|
+
if (!project) {
|
|
139
|
+
throw notFound('Project');
|
|
140
|
+
}
|
|
141
|
+
const task = manager.createProjectTask(projectId, body.title, {
|
|
142
|
+
description: body.description,
|
|
143
|
+
priority: body.priority,
|
|
144
|
+
assignedAgents: body.assignedAgents,
|
|
145
|
+
});
|
|
146
|
+
// Emit event for WebSocket clients
|
|
147
|
+
agentEvents.emit('project:task:created', {
|
|
148
|
+
projectId,
|
|
149
|
+
taskId: task.id,
|
|
150
|
+
title: task.title,
|
|
151
|
+
});
|
|
152
|
+
sendJson(res, {
|
|
153
|
+
...task,
|
|
154
|
+
createdAt: task.createdAt.toISOString(),
|
|
155
|
+
updatedAt: task.updatedAt.toISOString(),
|
|
156
|
+
}, 201);
|
|
157
|
+
});
|
|
158
|
+
// GET /api/v1/projects/:id/tasks/:taskId - Get project task
|
|
159
|
+
router.get('/api/v1/projects/:id/tasks/:taskId', (_req, res, params) => {
|
|
160
|
+
const projectId = params.path[0];
|
|
161
|
+
const taskId = params.path[1];
|
|
162
|
+
if (!projectId || !taskId) {
|
|
163
|
+
throw badRequest('Project ID and Task ID are required');
|
|
164
|
+
}
|
|
165
|
+
const manager = getManager();
|
|
166
|
+
const task = manager.getProjectTask(taskId);
|
|
167
|
+
if (!task || task.projectId !== projectId) {
|
|
168
|
+
throw notFound('Project task');
|
|
169
|
+
}
|
|
170
|
+
sendJson(res, {
|
|
171
|
+
...task,
|
|
172
|
+
createdAt: task.createdAt.toISOString(),
|
|
173
|
+
updatedAt: task.updatedAt.toISOString(),
|
|
174
|
+
completedAt: task.completedAt?.toISOString(),
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
// PUT /api/v1/projects/:id/tasks/:taskId - Update project task
|
|
178
|
+
router.put('/api/v1/projects/:id/tasks/:taskId', (_req, res, params) => {
|
|
179
|
+
const projectId = params.path[0];
|
|
180
|
+
const taskId = params.path[1];
|
|
181
|
+
if (!projectId || !taskId) {
|
|
182
|
+
throw badRequest('Project ID and Task ID are required');
|
|
183
|
+
}
|
|
184
|
+
const body = params.body;
|
|
185
|
+
if (!body) {
|
|
186
|
+
throw badRequest('Request body is required');
|
|
187
|
+
}
|
|
188
|
+
const manager = getManager();
|
|
189
|
+
const task = manager.getProjectTask(taskId);
|
|
190
|
+
if (!task || task.projectId !== projectId) {
|
|
191
|
+
throw notFound('Project task');
|
|
192
|
+
}
|
|
193
|
+
const success = manager.updateProjectTask(taskId, body);
|
|
194
|
+
if (!success) {
|
|
195
|
+
throw notFound('Project task');
|
|
196
|
+
}
|
|
197
|
+
const updated = manager.getProjectTask(taskId);
|
|
198
|
+
sendJson(res, {
|
|
199
|
+
...updated,
|
|
200
|
+
createdAt: updated?.createdAt.toISOString(),
|
|
201
|
+
updatedAt: updated?.updatedAt.toISOString(),
|
|
202
|
+
completedAt: updated?.completedAt?.toISOString(),
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
// DELETE /api/v1/projects/:id/tasks/:taskId - Delete project task
|
|
206
|
+
router.delete('/api/v1/projects/:id/tasks/:taskId', (_req, res, params) => {
|
|
207
|
+
const projectId = params.path[0];
|
|
208
|
+
const taskId = params.path[1];
|
|
209
|
+
if (!projectId || !taskId) {
|
|
210
|
+
throw badRequest('Project ID and Task ID are required');
|
|
211
|
+
}
|
|
212
|
+
const manager = getManager();
|
|
213
|
+
const task = manager.getProjectTask(taskId);
|
|
214
|
+
if (!task || task.projectId !== projectId) {
|
|
215
|
+
throw notFound('Project task');
|
|
216
|
+
}
|
|
217
|
+
const success = manager.deleteProjectTask(taskId);
|
|
218
|
+
if (!success) {
|
|
219
|
+
throw notFound('Project task');
|
|
220
|
+
}
|
|
221
|
+
sendJson(res, { deleted: true });
|
|
222
|
+
});
|
|
223
|
+
// PUT /api/v1/projects/:id/tasks/:taskId/phase - Transition task phase
|
|
224
|
+
router.put('/api/v1/projects/:id/tasks/:taskId/phase', (_req, res, params) => {
|
|
225
|
+
const projectId = params.path[0];
|
|
226
|
+
const taskId = params.path[1];
|
|
227
|
+
if (!projectId || !taskId) {
|
|
228
|
+
throw badRequest('Project ID and Task ID are required');
|
|
229
|
+
}
|
|
230
|
+
const body = params.body;
|
|
231
|
+
if (!body?.phase) {
|
|
232
|
+
throw badRequest('Phase is required');
|
|
233
|
+
}
|
|
234
|
+
const validPhases = ['draft', 'specification', 'review', 'development', 'completed', 'cancelled'];
|
|
235
|
+
if (!validPhases.includes(body.phase)) {
|
|
236
|
+
throw badRequest(`Invalid phase. Must be one of: ${validPhases.join(', ')}`);
|
|
237
|
+
}
|
|
238
|
+
const manager = getManager();
|
|
239
|
+
const task = manager.getProjectTask(taskId);
|
|
240
|
+
if (!task || task.projectId !== projectId) {
|
|
241
|
+
throw notFound('Project task');
|
|
242
|
+
}
|
|
243
|
+
// Check if transition is valid
|
|
244
|
+
const allowedTransitions = PHASE_TRANSITIONS[task.phase];
|
|
245
|
+
if (!allowedTransitions.includes(body.phase)) {
|
|
246
|
+
throw badRequest(`Cannot transition from ${task.phase} to ${body.phase}. Allowed: ${allowedTransitions.join(', ')}`);
|
|
247
|
+
}
|
|
248
|
+
const success = manager.updateProjectTaskPhase(taskId, body.phase);
|
|
249
|
+
if (!success) {
|
|
250
|
+
throw notFound('Project task');
|
|
251
|
+
}
|
|
252
|
+
const updated = manager.getProjectTask(taskId);
|
|
253
|
+
// Emit event for WebSocket clients
|
|
254
|
+
agentEvents.emit('project:task:phase', {
|
|
255
|
+
projectId,
|
|
256
|
+
taskId,
|
|
257
|
+
fromPhase: task.phase,
|
|
258
|
+
toPhase: body.phase,
|
|
259
|
+
});
|
|
260
|
+
sendJson(res, {
|
|
261
|
+
...updated,
|
|
262
|
+
createdAt: updated?.createdAt.toISOString(),
|
|
263
|
+
updatedAt: updated?.updatedAt.toISOString(),
|
|
264
|
+
completedAt: updated?.completedAt?.toISOString(),
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
// PUT /api/v1/projects/:id/tasks/:taskId/assign - Assign agents to task
|
|
268
|
+
router.put('/api/v1/projects/:id/tasks/:taskId/assign', (_req, res, params) => {
|
|
269
|
+
const projectId = params.path[0];
|
|
270
|
+
const taskId = params.path[1];
|
|
271
|
+
if (!projectId || !taskId) {
|
|
272
|
+
throw badRequest('Project ID and Task ID are required');
|
|
273
|
+
}
|
|
274
|
+
const body = params.body;
|
|
275
|
+
if (!body?.agents || !Array.isArray(body.agents)) {
|
|
276
|
+
throw badRequest('Agents array is required');
|
|
277
|
+
}
|
|
278
|
+
const manager = getManager();
|
|
279
|
+
const task = manager.getProjectTask(taskId);
|
|
280
|
+
if (!task || task.projectId !== projectId) {
|
|
281
|
+
throw notFound('Project task');
|
|
282
|
+
}
|
|
283
|
+
const success = manager.updateProjectTask(taskId, { assignedAgents: body.agents });
|
|
284
|
+
if (!success) {
|
|
285
|
+
throw notFound('Project task');
|
|
286
|
+
}
|
|
287
|
+
const updated = manager.getProjectTask(taskId);
|
|
288
|
+
sendJson(res, {
|
|
289
|
+
...updated,
|
|
290
|
+
createdAt: updated?.createdAt.toISOString(),
|
|
291
|
+
updatedAt: updated?.updatedAt.toISOString(),
|
|
292
|
+
completedAt: updated?.completedAt?.toISOString(),
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../../src/web/routes/projects.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Specification routes
|
|
3
|
+
*/
|
|
4
|
+
import type { AgentStackConfig } from '../../types.js';
|
|
5
|
+
import type { Router } from '../router.js';
|
|
6
|
+
export declare function registerSpecificationRoutes(router: Router, config: AgentStackConfig): void;
|
|
7
|
+
//# sourceMappingURL=specifications.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"specifications.d.ts","sourceRoot":"","sources":["../../../src/web/routes/specifications.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAyD,MAAM,gBAAgB,CAAC;AAC9G,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAY3C,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CA4T1F"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Specification routes
|
|
3
|
+
*/
|
|
4
|
+
import { sendJson } from '../router.js';
|
|
5
|
+
import { badRequest, notFound } from '../middleware/error.js';
|
|
6
|
+
import { getMemoryManager } from '../../memory/index.js';
|
|
7
|
+
import { agentEvents } from '../websocket/event-bridge.js';
|
|
8
|
+
export function registerSpecificationRoutes(router, config) {
|
|
9
|
+
const getManager = () => getMemoryManager(config);
|
|
10
|
+
// GET /api/v1/tasks/:taskId/specs - List specifications for a task
|
|
11
|
+
router.get('/api/v1/tasks/:taskId/specs', (_req, res, params) => {
|
|
12
|
+
const taskId = params.path[0];
|
|
13
|
+
if (!taskId) {
|
|
14
|
+
throw badRequest('Task ID is required');
|
|
15
|
+
}
|
|
16
|
+
const status = params.query.status;
|
|
17
|
+
const manager = getManager();
|
|
18
|
+
const task = manager.getProjectTask(taskId);
|
|
19
|
+
if (!task) {
|
|
20
|
+
throw notFound('Project task');
|
|
21
|
+
}
|
|
22
|
+
const specs = manager.listSpecifications(taskId, status);
|
|
23
|
+
sendJson(res, specs.map(spec => ({
|
|
24
|
+
...spec,
|
|
25
|
+
createdAt: spec.createdAt.toISOString(),
|
|
26
|
+
updatedAt: spec.updatedAt.toISOString(),
|
|
27
|
+
approvedAt: spec.approvedAt?.toISOString(),
|
|
28
|
+
})));
|
|
29
|
+
});
|
|
30
|
+
// POST /api/v1/tasks/:taskId/specs - Create specification
|
|
31
|
+
router.post('/api/v1/tasks/:taskId/specs', (_req, res, params) => {
|
|
32
|
+
const taskId = params.path[0];
|
|
33
|
+
if (!taskId) {
|
|
34
|
+
throw badRequest('Task ID is required');
|
|
35
|
+
}
|
|
36
|
+
const body = params.body;
|
|
37
|
+
if (!body?.type) {
|
|
38
|
+
throw badRequest('Specification type is required');
|
|
39
|
+
}
|
|
40
|
+
if (!body?.title) {
|
|
41
|
+
throw badRequest('Specification title is required');
|
|
42
|
+
}
|
|
43
|
+
if (!body?.content) {
|
|
44
|
+
throw badRequest('Specification content is required');
|
|
45
|
+
}
|
|
46
|
+
if (!body?.createdBy) {
|
|
47
|
+
throw badRequest('CreatedBy is required');
|
|
48
|
+
}
|
|
49
|
+
const validTypes = ['architecture', 'requirements', 'design', 'api', 'other'];
|
|
50
|
+
if (!validTypes.includes(body.type)) {
|
|
51
|
+
throw badRequest(`Invalid type. Must be one of: ${validTypes.join(', ')}`);
|
|
52
|
+
}
|
|
53
|
+
const manager = getManager();
|
|
54
|
+
const task = manager.getProjectTask(taskId);
|
|
55
|
+
if (!task) {
|
|
56
|
+
throw notFound('Project task');
|
|
57
|
+
}
|
|
58
|
+
const spec = manager.createSpecification(taskId, body.type, body.title, body.content, body.createdBy);
|
|
59
|
+
// Emit event for WebSocket clients
|
|
60
|
+
agentEvents.emit('spec:created', {
|
|
61
|
+
id: spec.id,
|
|
62
|
+
taskId,
|
|
63
|
+
type: spec.type,
|
|
64
|
+
title: spec.title,
|
|
65
|
+
});
|
|
66
|
+
sendJson(res, {
|
|
67
|
+
...spec,
|
|
68
|
+
createdAt: spec.createdAt.toISOString(),
|
|
69
|
+
updatedAt: spec.updatedAt.toISOString(),
|
|
70
|
+
}, 201);
|
|
71
|
+
});
|
|
72
|
+
// GET /api/v1/specs/:specId - Get specification by ID
|
|
73
|
+
router.get('/api/v1/specs/:specId', (_req, res, params) => {
|
|
74
|
+
const specId = params.path[0];
|
|
75
|
+
if (!specId) {
|
|
76
|
+
throw badRequest('Specification ID is required');
|
|
77
|
+
}
|
|
78
|
+
const manager = getManager();
|
|
79
|
+
const spec = manager.getSpecification(specId);
|
|
80
|
+
if (!spec) {
|
|
81
|
+
throw notFound('Specification');
|
|
82
|
+
}
|
|
83
|
+
sendJson(res, {
|
|
84
|
+
...spec,
|
|
85
|
+
createdAt: spec.createdAt.toISOString(),
|
|
86
|
+
updatedAt: spec.updatedAt.toISOString(),
|
|
87
|
+
approvedAt: spec.approvedAt?.toISOString(),
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
// PUT /api/v1/specs/:specId - Update specification
|
|
91
|
+
router.put('/api/v1/specs/:specId', (_req, res, params) => {
|
|
92
|
+
const specId = params.path[0];
|
|
93
|
+
if (!specId) {
|
|
94
|
+
throw badRequest('Specification ID is required');
|
|
95
|
+
}
|
|
96
|
+
const body = params.body;
|
|
97
|
+
if (!body) {
|
|
98
|
+
throw badRequest('Request body is required');
|
|
99
|
+
}
|
|
100
|
+
if (body.type) {
|
|
101
|
+
const validTypes = ['architecture', 'requirements', 'design', 'api', 'other'];
|
|
102
|
+
if (!validTypes.includes(body.type)) {
|
|
103
|
+
throw badRequest(`Invalid type. Must be one of: ${validTypes.join(', ')}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const manager = getManager();
|
|
107
|
+
const spec = manager.getSpecification(specId);
|
|
108
|
+
if (!spec) {
|
|
109
|
+
throw notFound('Specification');
|
|
110
|
+
}
|
|
111
|
+
// Can only update draft or pending_review specs
|
|
112
|
+
if (spec.status === 'approved') {
|
|
113
|
+
throw badRequest('Cannot update an approved specification');
|
|
114
|
+
}
|
|
115
|
+
const success = manager.updateSpecification(specId, body);
|
|
116
|
+
if (!success) {
|
|
117
|
+
throw notFound('Specification');
|
|
118
|
+
}
|
|
119
|
+
const updated = manager.getSpecification(specId);
|
|
120
|
+
sendJson(res, {
|
|
121
|
+
...updated,
|
|
122
|
+
createdAt: updated?.createdAt.toISOString(),
|
|
123
|
+
updatedAt: updated?.updatedAt.toISOString(),
|
|
124
|
+
approvedAt: updated?.approvedAt?.toISOString(),
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
// DELETE /api/v1/specs/:specId - Delete specification
|
|
128
|
+
router.delete('/api/v1/specs/:specId', (_req, res, params) => {
|
|
129
|
+
const specId = params.path[0];
|
|
130
|
+
if (!specId) {
|
|
131
|
+
throw badRequest('Specification ID is required');
|
|
132
|
+
}
|
|
133
|
+
const manager = getManager();
|
|
134
|
+
const spec = manager.getSpecification(specId);
|
|
135
|
+
if (!spec) {
|
|
136
|
+
throw notFound('Specification');
|
|
137
|
+
}
|
|
138
|
+
const success = manager.deleteSpecification(specId);
|
|
139
|
+
if (!success) {
|
|
140
|
+
throw notFound('Specification');
|
|
141
|
+
}
|
|
142
|
+
sendJson(res, { deleted: true });
|
|
143
|
+
});
|
|
144
|
+
// PUT /api/v1/specs/:specId/submit - Submit specification for review
|
|
145
|
+
router.put('/api/v1/specs/:specId/submit', (_req, res, params) => {
|
|
146
|
+
const specId = params.path[0];
|
|
147
|
+
if (!specId) {
|
|
148
|
+
throw badRequest('Specification ID is required');
|
|
149
|
+
}
|
|
150
|
+
const manager = getManager();
|
|
151
|
+
const spec = manager.getSpecification(specId);
|
|
152
|
+
if (!spec) {
|
|
153
|
+
throw notFound('Specification');
|
|
154
|
+
}
|
|
155
|
+
if (spec.status !== 'draft') {
|
|
156
|
+
throw badRequest('Only draft specifications can be submitted for review');
|
|
157
|
+
}
|
|
158
|
+
const success = manager.updateSpecificationStatus(specId, 'pending_review');
|
|
159
|
+
if (!success) {
|
|
160
|
+
throw notFound('Specification');
|
|
161
|
+
}
|
|
162
|
+
const updated = manager.getSpecification(specId);
|
|
163
|
+
// Emit event for WebSocket clients
|
|
164
|
+
agentEvents.emit('spec:status', {
|
|
165
|
+
id: specId,
|
|
166
|
+
status: 'pending_review',
|
|
167
|
+
});
|
|
168
|
+
sendJson(res, {
|
|
169
|
+
...updated,
|
|
170
|
+
createdAt: updated?.createdAt.toISOString(),
|
|
171
|
+
updatedAt: updated?.updatedAt.toISOString(),
|
|
172
|
+
approvedAt: updated?.approvedAt?.toISOString(),
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
// PUT /api/v1/specs/:specId/approve - Approve specification
|
|
176
|
+
router.put('/api/v1/specs/:specId/approve', (_req, res, params) => {
|
|
177
|
+
const specId = params.path[0];
|
|
178
|
+
if (!specId) {
|
|
179
|
+
throw badRequest('Specification ID is required');
|
|
180
|
+
}
|
|
181
|
+
const body = params.body;
|
|
182
|
+
if (!body?.reviewedBy) {
|
|
183
|
+
throw badRequest('ReviewedBy is required');
|
|
184
|
+
}
|
|
185
|
+
const manager = getManager();
|
|
186
|
+
const spec = manager.getSpecification(specId);
|
|
187
|
+
if (!spec) {
|
|
188
|
+
throw notFound('Specification');
|
|
189
|
+
}
|
|
190
|
+
if (spec.status !== 'pending_review') {
|
|
191
|
+
throw badRequest('Only pending_review specifications can be approved');
|
|
192
|
+
}
|
|
193
|
+
// Convert comments from request to ReviewComment[]
|
|
194
|
+
const comments = body.comments?.map(c => ({
|
|
195
|
+
id: c.id,
|
|
196
|
+
author: c.author,
|
|
197
|
+
content: c.content,
|
|
198
|
+
createdAt: new Date(c.createdAt),
|
|
199
|
+
resolved: c.resolved,
|
|
200
|
+
}));
|
|
201
|
+
const success = manager.updateSpecificationStatus(specId, 'approved', body.reviewedBy, comments);
|
|
202
|
+
if (!success) {
|
|
203
|
+
throw notFound('Specification');
|
|
204
|
+
}
|
|
205
|
+
const updated = manager.getSpecification(specId);
|
|
206
|
+
// Emit event for WebSocket clients
|
|
207
|
+
agentEvents.emit('spec:status', {
|
|
208
|
+
id: specId,
|
|
209
|
+
status: 'approved',
|
|
210
|
+
reviewedBy: body.reviewedBy,
|
|
211
|
+
});
|
|
212
|
+
sendJson(res, {
|
|
213
|
+
...updated,
|
|
214
|
+
createdAt: updated?.createdAt.toISOString(),
|
|
215
|
+
updatedAt: updated?.updatedAt.toISOString(),
|
|
216
|
+
approvedAt: updated?.approvedAt?.toISOString(),
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
// PUT /api/v1/specs/:specId/reject - Reject specification
|
|
220
|
+
router.put('/api/v1/specs/:specId/reject', (_req, res, params) => {
|
|
221
|
+
const specId = params.path[0];
|
|
222
|
+
if (!specId) {
|
|
223
|
+
throw badRequest('Specification ID is required');
|
|
224
|
+
}
|
|
225
|
+
const body = params.body;
|
|
226
|
+
if (!body?.reviewedBy) {
|
|
227
|
+
throw badRequest('ReviewedBy is required');
|
|
228
|
+
}
|
|
229
|
+
if (!body?.comments || body.comments.length === 0) {
|
|
230
|
+
throw badRequest('At least one comment is required when rejecting');
|
|
231
|
+
}
|
|
232
|
+
const manager = getManager();
|
|
233
|
+
const spec = manager.getSpecification(specId);
|
|
234
|
+
if (!spec) {
|
|
235
|
+
throw notFound('Specification');
|
|
236
|
+
}
|
|
237
|
+
if (spec.status !== 'pending_review') {
|
|
238
|
+
throw badRequest('Only pending_review specifications can be rejected');
|
|
239
|
+
}
|
|
240
|
+
// Convert comments from request to ReviewComment[]
|
|
241
|
+
const comments = body.comments.map(c => ({
|
|
242
|
+
id: c.id,
|
|
243
|
+
author: c.author,
|
|
244
|
+
content: c.content,
|
|
245
|
+
createdAt: new Date(c.createdAt),
|
|
246
|
+
resolved: c.resolved,
|
|
247
|
+
}));
|
|
248
|
+
const success = manager.updateSpecificationStatus(specId, 'rejected', body.reviewedBy, comments);
|
|
249
|
+
if (!success) {
|
|
250
|
+
throw notFound('Specification');
|
|
251
|
+
}
|
|
252
|
+
const updated = manager.getSpecification(specId);
|
|
253
|
+
// Emit event for WebSocket clients
|
|
254
|
+
agentEvents.emit('spec:status', {
|
|
255
|
+
id: specId,
|
|
256
|
+
status: 'rejected',
|
|
257
|
+
reviewedBy: body.reviewedBy,
|
|
258
|
+
});
|
|
259
|
+
sendJson(res, {
|
|
260
|
+
...updated,
|
|
261
|
+
createdAt: updated?.createdAt.toISOString(),
|
|
262
|
+
updatedAt: updated?.updatedAt.toISOString(),
|
|
263
|
+
approvedAt: updated?.approvedAt?.toISOString(),
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=specifications.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"specifications.js","sourceRoot":"","sources":["../../../src/web/routes/specifications.ts"],"names":[],"mappings":"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"}
|
package/dist/web/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAiBpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAK5C,eAAO,MAAM,gBAAgB,EAAE,SAO9B,CAAC;AAEF,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,cAAc,CAA0C;gBAEpD,MAAM,EAAE,gBAAgB,EAAE,SAAS,GAAE,OAAO,CAAC,SAAS,CAAM;IASxE,OAAO,CAAC,WAAW;IAgCnB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmD5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB3B;;OAEG;YACW,WAAW;IAqEzB;;OAEG;IACH,SAAS,IAAI;QACX,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB;CAQF;AAKD;;GAEG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,gBAAgB,EACxB,SAAS,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAC7B,OAAO,CAAC,SAAS,CAAC,CASpB;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAKnD;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAE/C"}
|
package/dist/web/server.js
CHANGED
|
@@ -10,7 +10,7 @@ import { Router, sendJson, sendError } from './router.js';
|
|
|
10
10
|
import { createCorsMiddleware } from './middleware/cors.js';
|
|
11
11
|
import { handleError } from './middleware/error.js';
|
|
12
12
|
import { handleWebSocketUpgrade, closeAllConnections, getClientCount } from './websocket/handler.js';
|
|
13
|
-
import { registerAgentRoutes, registerMemoryRoutes, registerTaskRoutes, registerSessionRoutes, registerWorkflowRoutes, registerSystemRoutes, } from './routes/index.js';
|
|
13
|
+
import { registerAgentRoutes, registerMemoryRoutes, registerTaskRoutes, registerSessionRoutes, registerWorkflowRoutes, registerSystemRoutes, registerProjectRoutes, registerSpecificationRoutes, registerFilesystemRoutes, } from './routes/index.js';
|
|
14
14
|
const log = logger.child('web:server');
|
|
15
15
|
// Default web configuration
|
|
16
16
|
export const defaultWebConfig = {
|
|
@@ -42,6 +42,9 @@ export class WebServer {
|
|
|
42
42
|
registerSessionRoutes(this.router, this.config);
|
|
43
43
|
registerWorkflowRoutes(this.router, this.config);
|
|
44
44
|
registerSystemRoutes(this.router, this.config);
|
|
45
|
+
registerProjectRoutes(this.router, this.config);
|
|
46
|
+
registerSpecificationRoutes(this.router, this.config);
|
|
47
|
+
registerFilesystemRoutes(this.router, this.config);
|
|
45
48
|
// Root endpoint
|
|
46
49
|
this.router.get('/api/v1', (_req, res) => {
|
|
47
50
|
sendJson(res, {
|
|
@@ -54,6 +57,9 @@ export class WebServer {
|
|
|
54
57
|
'/api/v1/sessions',
|
|
55
58
|
'/api/v1/workflows',
|
|
56
59
|
'/api/v1/system',
|
|
60
|
+
'/api/v1/projects',
|
|
61
|
+
'/api/v1/specs',
|
|
62
|
+
'/api/v1/filesystem',
|
|
57
63
|
],
|
|
58
64
|
});
|
|
59
65
|
});
|