@sudocode-ai/local-server 0.1.0 → 0.1.1
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/cli.js +6 -104
- package/dist/cli.js.map +1 -7
- package/dist/execution/engine/engine.js +10 -0
- package/dist/execution/engine/engine.js.map +1 -0
- package/dist/execution/engine/simple-engine.js +611 -0
- package/dist/execution/engine/simple-engine.js.map +1 -0
- package/dist/execution/engine/types.js +10 -0
- package/dist/execution/engine/types.js.map +1 -0
- package/dist/execution/output/ag-ui-adapter.js +438 -0
- package/dist/execution/output/ag-ui-adapter.js.map +1 -0
- package/dist/execution/output/ag-ui-integration.js +96 -0
- package/dist/execution/output/ag-ui-integration.js.map +1 -0
- package/dist/execution/output/claude-code-output-processor.js +769 -0
- package/dist/execution/output/claude-code-output-processor.js.map +1 -0
- package/dist/execution/output/index.js +15 -0
- package/dist/execution/output/index.js.map +1 -0
- package/dist/execution/output/types.js +22 -0
- package/dist/execution/output/types.js.map +1 -0
- package/dist/execution/process/builders/claude.js +59 -0
- package/dist/execution/process/builders/claude.js.map +1 -0
- package/dist/execution/process/index.js +15 -0
- package/dist/execution/process/index.js.map +1 -0
- package/dist/execution/process/manager.js +10 -0
- package/dist/execution/process/manager.js.map +1 -0
- package/dist/execution/process/simple-manager.js +336 -0
- package/dist/execution/process/simple-manager.js.map +1 -0
- package/dist/execution/process/types.js +10 -0
- package/dist/execution/process/types.js.map +1 -0
- package/dist/execution/process/utils.js +97 -0
- package/dist/execution/process/utils.js.map +1 -0
- package/dist/execution/resilience/circuit-breaker.js +291 -0
- package/dist/execution/resilience/circuit-breaker.js.map +1 -0
- package/dist/execution/resilience/executor.js +10 -0
- package/dist/execution/resilience/executor.js.map +1 -0
- package/dist/execution/resilience/index.js +15 -0
- package/dist/execution/resilience/index.js.map +1 -0
- package/dist/execution/resilience/resilient-executor.js +261 -0
- package/dist/execution/resilience/resilient-executor.js.map +1 -0
- package/dist/execution/resilience/retry.js +234 -0
- package/dist/execution/resilience/retry.js.map +1 -0
- package/dist/execution/resilience/types.js +30 -0
- package/dist/execution/resilience/types.js.map +1 -0
- package/dist/execution/transport/event-buffer.js +208 -0
- package/dist/execution/transport/event-buffer.js.map +1 -0
- package/dist/execution/transport/index.js +10 -0
- package/dist/execution/transport/index.js.map +1 -0
- package/dist/execution/transport/sse-transport.js +282 -0
- package/dist/execution/transport/sse-transport.js.map +1 -0
- package/dist/execution/transport/transport-manager.js +231 -0
- package/dist/execution/transport/transport-manager.js.map +1 -0
- package/dist/execution/workflow/index.js +13 -0
- package/dist/execution/workflow/index.js.map +1 -0
- package/dist/execution/workflow/linear-orchestrator.js +683 -0
- package/dist/execution/workflow/linear-orchestrator.js.map +1 -0
- package/dist/execution/workflow/memory-storage.js +68 -0
- package/dist/execution/workflow/memory-storage.js.map +1 -0
- package/dist/execution/workflow/orchestrator.js +9 -0
- package/dist/execution/workflow/orchestrator.js.map +1 -0
- package/dist/execution/workflow/types.js +9 -0
- package/dist/execution/workflow/types.js.map +1 -0
- package/dist/execution/workflow/utils.js +152 -0
- package/dist/execution/workflow/utils.js.map +1 -0
- package/dist/execution/worktree/config.js +280 -0
- package/dist/execution/worktree/config.js.map +1 -0
- package/dist/execution/worktree/git-cli.js +189 -0
- package/dist/execution/worktree/git-cli.js.map +1 -0
- package/dist/execution/worktree/index.js +15 -0
- package/dist/execution/worktree/index.js.map +1 -0
- package/dist/execution/worktree/manager.js +452 -0
- package/dist/execution/worktree/manager.js.map +1 -0
- package/dist/execution/worktree/types.js +42 -0
- package/dist/execution/worktree/types.js.map +1 -0
- package/dist/index.js +356 -104
- package/dist/index.js.map +1 -7
- package/dist/routes/executions-stream.js +55 -0
- package/dist/routes/executions-stream.js.map +1 -0
- package/dist/routes/executions.js +267 -0
- package/dist/routes/executions.js.map +1 -0
- package/dist/routes/feedback.js +329 -0
- package/dist/routes/feedback.js.map +1 -0
- package/dist/routes/issues.js +280 -0
- package/dist/routes/issues.js.map +1 -0
- package/dist/routes/relationships.js +308 -0
- package/dist/routes/relationships.js.map +1 -0
- package/dist/routes/specs.js +270 -0
- package/dist/routes/specs.js.map +1 -0
- package/dist/services/db.js +85 -0
- package/dist/services/db.js.map +1 -0
- package/dist/services/execution-lifecycle.js +286 -0
- package/dist/services/execution-lifecycle.js.map +1 -0
- package/dist/services/execution-service.js +676 -0
- package/dist/services/execution-service.js.map +1 -0
- package/dist/services/executions.js +164 -0
- package/dist/services/executions.js.map +1 -0
- package/dist/services/export.js +106 -0
- package/dist/services/export.js.map +1 -0
- package/dist/services/feedback.js +54 -0
- package/dist/services/feedback.js.map +1 -0
- package/dist/services/issues.js +35 -0
- package/dist/services/issues.js.map +1 -0
- package/dist/services/prompt-template-engine.js +212 -0
- package/dist/services/prompt-template-engine.js.map +1 -0
- package/dist/services/prompt-templates.js +236 -0
- package/dist/services/prompt-templates.js.map +1 -0
- package/dist/services/relationships.js +42 -0
- package/dist/services/relationships.js.map +1 -0
- package/dist/services/specs.js +35 -0
- package/dist/services/specs.js.map +1 -0
- package/dist/services/watcher.js +69 -0
- package/dist/services/watcher.js.map +1 -0
- package/dist/services/websocket.js +389 -0
- package/dist/services/websocket.js.map +1 -0
- package/dist/utils/sudocode-dir.js +9 -0
- package/dist/utils/sudocode-dir.js.map +1 -0
- package/package.json +4 -6
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt Templates Service
|
|
3
|
+
*
|
|
4
|
+
* Manages prompt templates in the database, including:
|
|
5
|
+
* - Seeding default templates
|
|
6
|
+
* - Loading templates by ID or type
|
|
7
|
+
* - Validating template syntax
|
|
8
|
+
*
|
|
9
|
+
* @module services/prompt-templates
|
|
10
|
+
*/
|
|
11
|
+
import { randomUUID } from 'crypto';
|
|
12
|
+
import { PromptTemplateEngine } from './prompt-template-engine.js';
|
|
13
|
+
/**
|
|
14
|
+
* Default issue template
|
|
15
|
+
*
|
|
16
|
+
* Renders an issue into an executable prompt with:
|
|
17
|
+
* - Issue title and description
|
|
18
|
+
* - Related specifications
|
|
19
|
+
* - Feedback from previous execution attempts
|
|
20
|
+
*/
|
|
21
|
+
const DEFAULT_ISSUE_TEMPLATE = `Fix issue {{issueId}}: {{title}}
|
|
22
|
+
|
|
23
|
+
## Description
|
|
24
|
+
{{description}}
|
|
25
|
+
|
|
26
|
+
{{#if relatedSpecs}}
|
|
27
|
+
## Related Specifications
|
|
28
|
+
{{#each relatedSpecs}}
|
|
29
|
+
- [[{{id}}]]: {{title}}
|
|
30
|
+
{{/each}}
|
|
31
|
+
{{/if}}
|
|
32
|
+
|
|
33
|
+
{{#if feedback}}
|
|
34
|
+
## Feedback from Previous Attempts
|
|
35
|
+
{{#each feedback}}
|
|
36
|
+
- {{content}} (from {{issueId}})
|
|
37
|
+
{{/each}}
|
|
38
|
+
{{/if}}
|
|
39
|
+
|
|
40
|
+
Please implement a solution for this issue. Make sure to:
|
|
41
|
+
1. Read and understand the issue requirements
|
|
42
|
+
2. Check related specifications for context
|
|
43
|
+
3. Write clean, well-tested code
|
|
44
|
+
4. Update documentation if needed
|
|
45
|
+
`;
|
|
46
|
+
/**
|
|
47
|
+
* Initialize default prompt templates in the database
|
|
48
|
+
*
|
|
49
|
+
* This function is idempotent - it will only insert templates if they don't exist.
|
|
50
|
+
* Should be called during database initialization.
|
|
51
|
+
*
|
|
52
|
+
* @param db - Database instance
|
|
53
|
+
*/
|
|
54
|
+
export function initializeDefaultTemplates(db) {
|
|
55
|
+
const engine = new PromptTemplateEngine();
|
|
56
|
+
// Validate default template
|
|
57
|
+
const validation = engine.validate(DEFAULT_ISSUE_TEMPLATE);
|
|
58
|
+
if (!validation.valid) {
|
|
59
|
+
throw new Error(`Default issue template has invalid syntax: ${validation.errors.join(', ')}`);
|
|
60
|
+
}
|
|
61
|
+
// Check if default issue template already exists
|
|
62
|
+
const existing = db
|
|
63
|
+
.prepare(`
|
|
64
|
+
SELECT id FROM prompt_templates
|
|
65
|
+
WHERE type = 'issue' AND is_default = 1
|
|
66
|
+
`)
|
|
67
|
+
.get();
|
|
68
|
+
if (existing) {
|
|
69
|
+
// Default template already exists, skip initialization
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// Insert default issue template
|
|
73
|
+
const templateId = randomUUID();
|
|
74
|
+
const variables = JSON.stringify([
|
|
75
|
+
'issueId',
|
|
76
|
+
'title',
|
|
77
|
+
'description',
|
|
78
|
+
'relatedSpecs',
|
|
79
|
+
'feedback',
|
|
80
|
+
]);
|
|
81
|
+
db.prepare(`
|
|
82
|
+
INSERT INTO prompt_templates (
|
|
83
|
+
id, name, description, type, template, variables, is_default,
|
|
84
|
+
created_at, updated_at
|
|
85
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
86
|
+
`).run(templateId, 'Default Issue Template', 'Renders an issue into an executable prompt with related specs and feedback', 'issue', DEFAULT_ISSUE_TEMPLATE, variables, 1, // is_default
|
|
87
|
+
new Date().toISOString(), new Date().toISOString());
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get default template for a specific type
|
|
91
|
+
*
|
|
92
|
+
* @param db - Database instance
|
|
93
|
+
* @param type - Template type (issue, spec, custom)
|
|
94
|
+
* @returns Default template or null if not found
|
|
95
|
+
*/
|
|
96
|
+
export function getDefaultTemplate(db, type) {
|
|
97
|
+
const template = db
|
|
98
|
+
.prepare(`
|
|
99
|
+
SELECT * FROM prompt_templates
|
|
100
|
+
WHERE type = ? AND is_default = 1
|
|
101
|
+
LIMIT 1
|
|
102
|
+
`)
|
|
103
|
+
.get(type);
|
|
104
|
+
return template || null;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get template by ID
|
|
108
|
+
*
|
|
109
|
+
* @param db - Database instance
|
|
110
|
+
* @param templateId - Template ID
|
|
111
|
+
* @returns Template or null if not found
|
|
112
|
+
*/
|
|
113
|
+
export function getTemplateById(db, templateId) {
|
|
114
|
+
const template = db
|
|
115
|
+
.prepare('SELECT * FROM prompt_templates WHERE id = ?')
|
|
116
|
+
.get(templateId);
|
|
117
|
+
return template || null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* List all templates, optionally filtered by type
|
|
121
|
+
*
|
|
122
|
+
* @param db - Database instance
|
|
123
|
+
* @param type - Optional type filter
|
|
124
|
+
* @returns Array of templates
|
|
125
|
+
*/
|
|
126
|
+
export function listTemplates(db, type) {
|
|
127
|
+
if (type) {
|
|
128
|
+
return db
|
|
129
|
+
.prepare(`
|
|
130
|
+
SELECT * FROM prompt_templates
|
|
131
|
+
WHERE type = ?
|
|
132
|
+
ORDER BY is_default DESC, name ASC
|
|
133
|
+
`)
|
|
134
|
+
.all(type);
|
|
135
|
+
}
|
|
136
|
+
return db
|
|
137
|
+
.prepare(`
|
|
138
|
+
SELECT * FROM prompt_templates
|
|
139
|
+
ORDER BY is_default DESC, name ASC
|
|
140
|
+
`)
|
|
141
|
+
.all();
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Create a new custom template
|
|
145
|
+
*
|
|
146
|
+
* @param db - Database instance
|
|
147
|
+
* @param params - Template parameters
|
|
148
|
+
* @returns Created template
|
|
149
|
+
*/
|
|
150
|
+
export function createTemplate(db, params) {
|
|
151
|
+
// Validate template syntax
|
|
152
|
+
const engine = new PromptTemplateEngine();
|
|
153
|
+
const validation = engine.validate(params.template);
|
|
154
|
+
if (!validation.valid) {
|
|
155
|
+
throw new Error(`Invalid template syntax: ${validation.errors.join(', ')}`);
|
|
156
|
+
}
|
|
157
|
+
const templateId = randomUUID();
|
|
158
|
+
const now = new Date().toISOString();
|
|
159
|
+
db.prepare(`
|
|
160
|
+
INSERT INTO prompt_templates (
|
|
161
|
+
id, name, description, type, template, variables, is_default,
|
|
162
|
+
created_at, updated_at
|
|
163
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
164
|
+
`).run(templateId, params.name, params.description || null, params.type, params.template, JSON.stringify(params.variables), params.isDefault ? 1 : 0, now, now);
|
|
165
|
+
return getTemplateById(db, templateId);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Update an existing template
|
|
169
|
+
*
|
|
170
|
+
* @param db - Database instance
|
|
171
|
+
* @param templateId - Template ID
|
|
172
|
+
* @param updates - Fields to update
|
|
173
|
+
* @returns Updated template or null if not found
|
|
174
|
+
*/
|
|
175
|
+
export function updateTemplate(db, templateId, updates) {
|
|
176
|
+
const existing = getTemplateById(db, templateId);
|
|
177
|
+
if (!existing) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
// Validate template syntax if template is being updated
|
|
181
|
+
if (updates.template) {
|
|
182
|
+
const engine = new PromptTemplateEngine();
|
|
183
|
+
const validation = engine.validate(updates.template);
|
|
184
|
+
if (!validation.valid) {
|
|
185
|
+
throw new Error(`Invalid template syntax: ${validation.errors.join(', ')}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const fields = [];
|
|
189
|
+
const values = [];
|
|
190
|
+
if (updates.name !== undefined) {
|
|
191
|
+
fields.push('name = ?');
|
|
192
|
+
values.push(updates.name);
|
|
193
|
+
}
|
|
194
|
+
if (updates.description !== undefined) {
|
|
195
|
+
fields.push('description = ?');
|
|
196
|
+
values.push(updates.description);
|
|
197
|
+
}
|
|
198
|
+
if (updates.template !== undefined) {
|
|
199
|
+
fields.push('template = ?');
|
|
200
|
+
values.push(updates.template);
|
|
201
|
+
}
|
|
202
|
+
if (updates.variables !== undefined) {
|
|
203
|
+
fields.push('variables = ?');
|
|
204
|
+
values.push(JSON.stringify(updates.variables));
|
|
205
|
+
}
|
|
206
|
+
if (updates.isDefault !== undefined) {
|
|
207
|
+
fields.push('is_default = ?');
|
|
208
|
+
values.push(updates.isDefault ? 1 : 0);
|
|
209
|
+
}
|
|
210
|
+
if (fields.length === 0) {
|
|
211
|
+
return existing;
|
|
212
|
+
}
|
|
213
|
+
fields.push('updated_at = ?');
|
|
214
|
+
values.push(new Date().toISOString());
|
|
215
|
+
values.push(templateId);
|
|
216
|
+
db.prepare(`
|
|
217
|
+
UPDATE prompt_templates
|
|
218
|
+
SET ${fields.join(', ')}
|
|
219
|
+
WHERE id = ?
|
|
220
|
+
`).run(...values);
|
|
221
|
+
return getTemplateById(db, templateId);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Delete a template
|
|
225
|
+
*
|
|
226
|
+
* @param db - Database instance
|
|
227
|
+
* @param templateId - Template ID
|
|
228
|
+
* @returns True if deleted, false if not found
|
|
229
|
+
*/
|
|
230
|
+
export function deleteTemplate(db, templateId) {
|
|
231
|
+
const result = db
|
|
232
|
+
.prepare('DELETE FROM prompt_templates WHERE id = ?')
|
|
233
|
+
.run(templateId);
|
|
234
|
+
return result.changes > 0;
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=prompt-templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-templates.js","sourceRoot":"","sources":["../../src/services/prompt-templates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service layer for Relationships API
|
|
3
|
+
* Wraps CLI operations for managing relationships between specs and issues
|
|
4
|
+
*/
|
|
5
|
+
import { addRelationship, getRelationship, removeRelationship, getOutgoingRelationships, getIncomingRelationships, getAllRelationships, } from "@sudocode-ai/cli/dist/operations/relationships.js";
|
|
6
|
+
/**
|
|
7
|
+
* Create a new relationship between entities
|
|
8
|
+
*/
|
|
9
|
+
export function createRelationship(db, input) {
|
|
10
|
+
return addRelationship(db, input);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get a specific relationship
|
|
14
|
+
*/
|
|
15
|
+
export function getSpecificRelationship(db, from_id, from_type, to_id, to_type, relationship_type) {
|
|
16
|
+
return getRelationship(db, from_id, from_type, to_id, to_type, relationship_type);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Delete a relationship
|
|
20
|
+
*/
|
|
21
|
+
export function deleteRelationship(db, from_id, from_type, to_id, to_type, relationship_type) {
|
|
22
|
+
return removeRelationship(db, from_id, from_type, to_id, to_type, relationship_type);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get all outgoing relationships from an entity
|
|
26
|
+
*/
|
|
27
|
+
export function getEntityOutgoingRelationships(db, entity_id, entity_type, relationship_type) {
|
|
28
|
+
return getOutgoingRelationships(db, entity_id, entity_type, relationship_type);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get all incoming relationships to an entity
|
|
32
|
+
*/
|
|
33
|
+
export function getEntityIncomingRelationships(db, entity_id, entity_type, relationship_type) {
|
|
34
|
+
return getIncomingRelationships(db, entity_id, entity_type, relationship_type);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get all relationships for an entity (both incoming and outgoing)
|
|
38
|
+
*/
|
|
39
|
+
export function getEntityRelationships(db, entity_id, entity_type) {
|
|
40
|
+
return getAllRelationships(db, entity_id, entity_type);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=relationships.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationships.js","sourceRoot":"","sources":["../../src/services/relationships.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EACL,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,GAEpB,MAAM,mDAAmD,CAAC;AAE3D;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,EAAqB,EACrB,KAA8B;IAE9B,OAAO,eAAe,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACrC,EAAqB,EACrB,OAAe,EACf,SAAqB,EACrB,KAAa,EACb,OAAmB,EACnB,iBAAmC;IAEnC,OAAO,eAAe,CACpB,EAAE,EACF,OAAO,EACP,SAAS,EACT,KAAK,EACL,OAAO,EACP,iBAAiB,CAClB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,EAAqB,EACrB,OAAe,EACf,SAAqB,EACrB,KAAa,EACb,OAAmB,EACnB,iBAAmC;IAEnC,OAAO,kBAAkB,CACvB,EAAE,EACF,OAAO,EACP,SAAS,EACT,KAAK,EACL,OAAO,EACP,iBAAiB,CAClB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,8BAA8B,CAC5C,EAAqB,EACrB,SAAiB,EACjB,WAAuB,EACvB,iBAAoC;IAEpC,OAAO,wBAAwB,CAC7B,EAAE,EACF,SAAS,EACT,WAAW,EACX,iBAAiB,CAClB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,8BAA8B,CAC5C,EAAqB,EACrB,SAAiB,EACjB,WAAuB,EACvB,iBAAoC;IAEpC,OAAO,wBAAwB,CAC7B,EAAE,EACF,SAAS,EACT,WAAW,EACX,iBAAiB,CAClB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,EAAqB,EACrB,SAAiB,EACjB,WAAuB;IAEvB,OAAO,mBAAmB,CAAC,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Specs service - wraps CLI operations for API use
|
|
3
|
+
*/
|
|
4
|
+
import { getSpec, listSpecs, createSpec, updateSpec, deleteSpec, } from "@sudocode-ai/cli/dist/operations/index.js";
|
|
5
|
+
/**
|
|
6
|
+
* Get all specs with optional filtering
|
|
7
|
+
*/
|
|
8
|
+
export function getAllSpecs(db, options) {
|
|
9
|
+
return listSpecs(db, options || {});
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get a single spec by ID
|
|
13
|
+
*/
|
|
14
|
+
export function getSpecById(db, id) {
|
|
15
|
+
return getSpec(db, id);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create a new spec
|
|
19
|
+
*/
|
|
20
|
+
export function createNewSpec(db, input) {
|
|
21
|
+
return createSpec(db, input);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Update an existing spec
|
|
25
|
+
*/
|
|
26
|
+
export function updateExistingSpec(db, id, input) {
|
|
27
|
+
return updateSpec(db, id, input);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Delete a spec
|
|
31
|
+
*/
|
|
32
|
+
export function deleteExistingSpec(db, id) {
|
|
33
|
+
return deleteSpec(db, id);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=specs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"specs.js","sourceRoot":"","sources":["../../src/services/specs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,OAAO,EACP,SAAS,EACT,UAAU,EACV,UAAU,EACV,UAAU,GAIX,MAAM,2CAA2C,CAAC;AAGnD;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,EAAqB,EACrB,OAA0B;IAE1B,OAAO,SAAS,CAAC,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,EAAqB,EAAE,EAAU;IAC3D,OAAO,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,EAAqB,EACrB,KAAsB;IAEtB,OAAO,UAAU,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,EAAqB,EACrB,EAAU,EACV,KAAsB;IAEtB,OAAO,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAqB,EAAE,EAAU;IAClE,OAAO,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File watcher service for the server
|
|
3
|
+
* Reuses the CLI watcher with server-specific callbacks
|
|
4
|
+
*/
|
|
5
|
+
import { startWatcher as startCliWatcher, } from "@sudocode-ai/cli/dist/watcher.js";
|
|
6
|
+
/**
|
|
7
|
+
* Start the file watcher for the server
|
|
8
|
+
* This wraps the CLI watcher with server-specific logging and callbacks
|
|
9
|
+
*/
|
|
10
|
+
export function startServerWatcher(options) {
|
|
11
|
+
const { db, baseDir, debounceDelay = 2000, syncJSONLToMarkdown = false, onFileChange, } = options;
|
|
12
|
+
console.log(`[watcher] Starting file watcher for ${baseDir}`);
|
|
13
|
+
console.log(`[watcher] Debounce delay: ${debounceDelay}ms`);
|
|
14
|
+
if (syncJSONLToMarkdown) {
|
|
15
|
+
console.log(`[watcher] Reverse sync (JSONL → Markdown) enabled`);
|
|
16
|
+
}
|
|
17
|
+
// Start the CLI watcher with server-specific callbacks
|
|
18
|
+
// TODO: Migrate away from parsing messages and start a watcher directly instead of using the CLI watcher.
|
|
19
|
+
const control = startCliWatcher({
|
|
20
|
+
db,
|
|
21
|
+
baseDir,
|
|
22
|
+
debounceDelay,
|
|
23
|
+
syncJSONLToMarkdown,
|
|
24
|
+
onLog: (message) => {
|
|
25
|
+
console.log(message);
|
|
26
|
+
// Extract entity info from log messages if available
|
|
27
|
+
// Log format: "[watch] <event> <path>" or "[watch] Synced <type> <id> (<action>)"
|
|
28
|
+
if (onFileChange) {
|
|
29
|
+
// TODO: Use something more robust than regex parsing here.
|
|
30
|
+
// Match markdown sync log: "[watch] Synced issue ISSUE-001 (updated)"
|
|
31
|
+
const syncMatch = message.match(/\[watch\] Synced (spec|issue) ([A-Z]+-\d+) \((created|updated)\)/);
|
|
32
|
+
if (syncMatch) {
|
|
33
|
+
const [, entityType, entityId] = syncMatch;
|
|
34
|
+
onFileChange({
|
|
35
|
+
filePath: "", // Path not available in sync message
|
|
36
|
+
event: "change",
|
|
37
|
+
entityType: entityType,
|
|
38
|
+
entityId,
|
|
39
|
+
});
|
|
40
|
+
return; // Early return to avoid double-processing
|
|
41
|
+
}
|
|
42
|
+
// Match JSONL file change: "[watch] change issues.jsonl" or "[watch] change specs.jsonl"
|
|
43
|
+
const jsonlChangeMatch = message.match(/\[watch\] change (issues|specs)\.jsonl/);
|
|
44
|
+
if (jsonlChangeMatch) {
|
|
45
|
+
const [, entityType] = jsonlChangeMatch;
|
|
46
|
+
// For JSONL changes, we don't know which specific entity changed
|
|
47
|
+
// so we broadcast a generic update that will trigger a refetch
|
|
48
|
+
onFileChange({
|
|
49
|
+
filePath: `${entityType}.jsonl`,
|
|
50
|
+
event: "change",
|
|
51
|
+
entityType: (entityType === "issues" ? "issue" : "spec"),
|
|
52
|
+
entityId: "*", // Wildcard to indicate "any entity of this type"
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
onError: (error) => {
|
|
58
|
+
console.error(`[watcher] Error: ${error.message}`);
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
return {
|
|
62
|
+
stop: async () => {
|
|
63
|
+
console.log("[watcher] Stopping file watcher...");
|
|
64
|
+
await control.stop();
|
|
65
|
+
},
|
|
66
|
+
getStats: control.getStats,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../src/services/watcher.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,YAAY,IAAI,eAAe,GAEhC,MAAM,kCAAkC,CAAC;AA0C1C;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAA6B;IAE7B,MAAM,EACJ,EAAE,EACF,OAAO,EACP,aAAa,GAAG,IAAI,EACpB,mBAAmB,GAAG,KAAK,EAC3B,YAAY,GACb,GAAG,OAAO,CAAC;IAEZ,OAAO,CAAC,GAAG,CAAC,uCAAuC,OAAO,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,6BAA6B,aAAa,IAAI,CAAC,CAAC;IAC5D,IAAI,mBAAmB,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACnE,CAAC;IAED,uDAAuD;IACvD,0GAA0G;IAC1G,MAAM,OAAO,GAAG,eAAe,CAAC;QAC9B,EAAE;QACF,OAAO;QACP,aAAa;QACb,mBAAmB;QACnB,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE;YACjB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAErB,qDAAqD;YACrD,kFAAkF;YAClF,IAAI,YAAY,EAAE,CAAC;gBACjB,2DAA2D;gBAE3D,sEAAsE;gBACtE,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAC7B,kEAAkE,CACnE,CAAC;gBACF,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,GAAG,SAAS,CAAC;oBAC3C,YAAY,CAAC;wBACX,QAAQ,EAAE,EAAE,EAAE,qCAAqC;wBACnD,KAAK,EAAE,QAAQ;wBACf,UAAU,EAAE,UAA8B;wBAC1C,QAAQ;qBACT,CAAC,CAAC;oBACH,OAAO,CAAC,0CAA0C;gBACpD,CAAC;gBAED,yFAAyF;gBACzF,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CACpC,wCAAwC,CACzC,CAAC;gBACF,IAAI,gBAAgB,EAAE,CAAC;oBACrB,MAAM,CAAC,EAAE,UAAU,CAAC,GAAG,gBAAgB,CAAC;oBACxC,iEAAiE;oBACjE,+DAA+D;oBAC/D,YAAY,CAAC;wBACX,QAAQ,EAAE,GAAG,UAAU,QAAQ;wBAC/B,KAAK,EAAE,QAAQ;wBACf,UAAU,EAAE,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAE5C;wBACX,QAAQ,EAAE,GAAG,EAAE,iDAAiD;qBACjE,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACjB,OAAO,CAAC,KAAK,CAAC,oBAAoB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACrD,CAAC;KACF,CAAC,CAAC;IAEH,OAAO;QACL,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;YAClD,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QACvB,CAAC;QACD,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC;AACJ,CAAC"}
|