kiro-spec-engine 1.2.2 → 1.3.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/CHANGELOG.md +91 -0
- package/README.md +172 -0
- package/bin/kiro-spec-engine.js +62 -0
- package/docs/adoption-guide.md +506 -0
- package/docs/agent-hooks-analysis.md +815 -0
- package/docs/architecture.md +706 -0
- package/docs/cross-tool-guide.md +554 -0
- package/docs/developer-guide.md +615 -0
- package/docs/manual-workflows-guide.md +417 -0
- package/docs/steering-strategy-guide.md +196 -0
- package/docs/upgrade-guide.md +632 -0
- package/lib/adoption/detection-engine.js +14 -4
- package/lib/commands/adopt.js +117 -3
- package/lib/commands/context.js +99 -0
- package/lib/commands/prompt.js +105 -0
- package/lib/commands/status.js +225 -0
- package/lib/commands/task.js +199 -0
- package/lib/commands/watch.js +569 -0
- package/lib/commands/workflows.js +240 -0
- package/lib/commands/workspace.js +189 -0
- package/lib/context/context-exporter.js +378 -0
- package/lib/context/prompt-generator.js +482 -0
- package/lib/steering/adoption-config.js +164 -0
- package/lib/steering/steering-manager.js +289 -0
- package/lib/task/task-claimer.js +430 -0
- package/lib/utils/tool-detector.js +383 -0
- package/lib/watch/action-executor.js +458 -0
- package/lib/watch/event-debouncer.js +323 -0
- package/lib/watch/execution-logger.js +550 -0
- package/lib/watch/file-watcher.js +499 -0
- package/lib/watch/presets.js +266 -0
- package/lib/watch/watch-manager.js +533 -0
- package/lib/workspace/workspace-manager.js +370 -0
- package/lib/workspace/workspace-sync.js +356 -0
- package/package.json +4 -1
- package/template/.kiro/tools/backup_manager.py +295 -0
- package/template/.kiro/tools/configuration_manager.py +218 -0
- package/template/.kiro/tools/document_evaluator.py +550 -0
- package/template/.kiro/tools/enhancement_logger.py +168 -0
- package/template/.kiro/tools/error_handler.py +335 -0
- package/template/.kiro/tools/improvement_identifier.py +444 -0
- package/template/.kiro/tools/modification_applicator.py +737 -0
- package/template/.kiro/tools/quality_gate_enforcer.py +207 -0
- package/template/.kiro/tools/quality_scorer.py +305 -0
- package/template/.kiro/tools/report_generator.py +154 -0
- package/template/.kiro/tools/ultrawork_enhancer_refactored.py +0 -0
- package/template/.kiro/tools/ultrawork_enhancer_v2.py +463 -0
- package/template/.kiro/tools/ultrawork_enhancer_v3.py +606 -0
- package/template/.kiro/tools/workflow_quality_gate.py +100 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Watch Mode Presets
|
|
3
|
+
*
|
|
4
|
+
* Pre-configured watch patterns and actions for common workflows
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Auto-sync preset
|
|
9
|
+
* Watches tasks.md and automatically syncs workspace
|
|
10
|
+
*/
|
|
11
|
+
const autoSyncPreset = {
|
|
12
|
+
name: 'auto-sync',
|
|
13
|
+
description: 'Automatically sync workspace when tasks are updated',
|
|
14
|
+
patterns: ['**/tasks.md'],
|
|
15
|
+
actions: {
|
|
16
|
+
'**/tasks.md': {
|
|
17
|
+
command: 'kse workspace sync',
|
|
18
|
+
debounce: 2000,
|
|
19
|
+
retry: true,
|
|
20
|
+
description: 'Sync workspace when tasks are updated'
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
debounce: {
|
|
24
|
+
default: 2000
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Prompt regeneration preset
|
|
30
|
+
* Watches requirements.md and design.md, regenerates prompts
|
|
31
|
+
*/
|
|
32
|
+
const promptRegenPreset = {
|
|
33
|
+
name: 'prompt-regen',
|
|
34
|
+
description: 'Regenerate prompts when requirements or design changes',
|
|
35
|
+
patterns: [
|
|
36
|
+
'**/.kiro/specs/*/requirements.md',
|
|
37
|
+
'**/.kiro/specs/*/design.md'
|
|
38
|
+
],
|
|
39
|
+
actions: {
|
|
40
|
+
'**/.kiro/specs/*/requirements.md': {
|
|
41
|
+
command: 'kse prompt regenerate ${spec}',
|
|
42
|
+
debounce: 5000,
|
|
43
|
+
retry: true,
|
|
44
|
+
description: 'Regenerate prompts when requirements change'
|
|
45
|
+
},
|
|
46
|
+
'**/.kiro/specs/*/design.md': {
|
|
47
|
+
command: 'kse prompt regenerate ${spec}',
|
|
48
|
+
debounce: 5000,
|
|
49
|
+
retry: true,
|
|
50
|
+
description: 'Regenerate prompts when design changes'
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
debounce: {
|
|
54
|
+
default: 5000,
|
|
55
|
+
perPattern: {
|
|
56
|
+
'**/.kiro/specs/*/requirements.md': 5000,
|
|
57
|
+
'**/.kiro/specs/*/design.md': 5000
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Context export preset
|
|
64
|
+
* Watches for completion markers and exports context
|
|
65
|
+
*/
|
|
66
|
+
const contextExportPreset = {
|
|
67
|
+
name: 'context-export',
|
|
68
|
+
description: 'Export context when work is complete',
|
|
69
|
+
patterns: ['**/.kiro/specs/*/.complete'],
|
|
70
|
+
actions: {
|
|
71
|
+
'**/.kiro/specs/*/.complete': {
|
|
72
|
+
command: 'kse context export ${spec}',
|
|
73
|
+
debounce: 1000,
|
|
74
|
+
retry: true,
|
|
75
|
+
description: 'Export context when completion marker is created'
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
debounce: {
|
|
79
|
+
default: 1000
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Test runner preset
|
|
85
|
+
* Watches source files and runs relevant tests
|
|
86
|
+
*/
|
|
87
|
+
const testRunnerPreset = {
|
|
88
|
+
name: 'test-runner',
|
|
89
|
+
description: 'Run tests when source files change',
|
|
90
|
+
patterns: [
|
|
91
|
+
'**/lib/**/*.js',
|
|
92
|
+
'**/src/**/*.js',
|
|
93
|
+
'**/lib/**/*.ts',
|
|
94
|
+
'**/src/**/*.ts'
|
|
95
|
+
],
|
|
96
|
+
actions: {
|
|
97
|
+
'**/lib/**/*.js': {
|
|
98
|
+
command: 'npm test -- ${file}.test.js',
|
|
99
|
+
debounce: 3000,
|
|
100
|
+
retry: false,
|
|
101
|
+
condition: 'test_file_exists',
|
|
102
|
+
description: 'Run tests when lib files change'
|
|
103
|
+
},
|
|
104
|
+
'**/src/**/*.js': {
|
|
105
|
+
command: 'npm test -- ${file}.test.js',
|
|
106
|
+
debounce: 3000,
|
|
107
|
+
retry: false,
|
|
108
|
+
condition: 'test_file_exists',
|
|
109
|
+
description: 'Run tests when src files change'
|
|
110
|
+
},
|
|
111
|
+
'**/lib/**/*.ts': {
|
|
112
|
+
command: 'npm test -- ${file}.test.ts',
|
|
113
|
+
debounce: 3000,
|
|
114
|
+
retry: false,
|
|
115
|
+
condition: 'test_file_exists',
|
|
116
|
+
description: 'Run tests when lib TypeScript files change'
|
|
117
|
+
},
|
|
118
|
+
'**/src/**/*.ts': {
|
|
119
|
+
command: 'npm test -- ${file}.test.ts',
|
|
120
|
+
debounce: 3000,
|
|
121
|
+
retry: false,
|
|
122
|
+
condition: 'test_file_exists',
|
|
123
|
+
description: 'Run tests when src TypeScript files change'
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
debounce: {
|
|
127
|
+
default: 3000
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* All available presets
|
|
133
|
+
*/
|
|
134
|
+
const presets = {
|
|
135
|
+
'auto-sync': autoSyncPreset,
|
|
136
|
+
'prompt-regen': promptRegenPreset,
|
|
137
|
+
'context-export': contextExportPreset,
|
|
138
|
+
'test-runner': testRunnerPreset
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Get a preset by name
|
|
143
|
+
*
|
|
144
|
+
* @param {string} name - Preset name
|
|
145
|
+
* @returns {Object|null} Preset configuration or null if not found
|
|
146
|
+
*/
|
|
147
|
+
function getPreset(name) {
|
|
148
|
+
return presets[name] || null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* List all available presets
|
|
153
|
+
*
|
|
154
|
+
* @returns {Array} Array of preset names and descriptions
|
|
155
|
+
*/
|
|
156
|
+
function listPresets() {
|
|
157
|
+
return Object.keys(presets).map(name => ({
|
|
158
|
+
name,
|
|
159
|
+
description: presets[name].description
|
|
160
|
+
}));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Merge preset with existing configuration
|
|
165
|
+
*
|
|
166
|
+
* @param {Object} existingConfig - Existing watch configuration
|
|
167
|
+
* @param {string} presetName - Preset name to merge
|
|
168
|
+
* @returns {Object} Merged configuration
|
|
169
|
+
*/
|
|
170
|
+
function mergePreset(existingConfig, presetName) {
|
|
171
|
+
const preset = getPreset(presetName);
|
|
172
|
+
|
|
173
|
+
if (!preset) {
|
|
174
|
+
throw new Error(`Preset not found: ${presetName}`);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Deep clone existing config
|
|
178
|
+
const merged = JSON.parse(JSON.stringify(existingConfig));
|
|
179
|
+
|
|
180
|
+
// Merge patterns (avoid duplicates)
|
|
181
|
+
const existingPatterns = new Set(merged.patterns || []);
|
|
182
|
+
for (const pattern of preset.patterns) {
|
|
183
|
+
existingPatterns.add(pattern);
|
|
184
|
+
}
|
|
185
|
+
merged.patterns = Array.from(existingPatterns);
|
|
186
|
+
|
|
187
|
+
// Merge actions
|
|
188
|
+
merged.actions = merged.actions || {};
|
|
189
|
+
for (const [pattern, action] of Object.entries(preset.actions)) {
|
|
190
|
+
// Don't overwrite existing actions
|
|
191
|
+
if (!merged.actions[pattern]) {
|
|
192
|
+
merged.actions[pattern] = action;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Merge debounce settings
|
|
197
|
+
merged.debounce = merged.debounce || {};
|
|
198
|
+
if (preset.debounce.default && !merged.debounce.default) {
|
|
199
|
+
merged.debounce.default = preset.debounce.default;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (preset.debounce.perPattern) {
|
|
203
|
+
merged.debounce.perPattern = merged.debounce.perPattern || {};
|
|
204
|
+
for (const [pattern, delay] of Object.entries(preset.debounce.perPattern)) {
|
|
205
|
+
if (!merged.debounce.perPattern[pattern]) {
|
|
206
|
+
merged.debounce.perPattern[pattern] = delay;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return merged;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Validate preset configuration
|
|
216
|
+
*
|
|
217
|
+
* @param {string} presetName - Preset name
|
|
218
|
+
* @returns {Object} Validation result
|
|
219
|
+
*/
|
|
220
|
+
function validatePreset(presetName) {
|
|
221
|
+
const preset = getPreset(presetName);
|
|
222
|
+
|
|
223
|
+
if (!preset) {
|
|
224
|
+
return {
|
|
225
|
+
valid: false,
|
|
226
|
+
errors: [`Preset not found: ${presetName}`]
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const errors = [];
|
|
231
|
+
|
|
232
|
+
// Validate patterns
|
|
233
|
+
if (!preset.patterns || preset.patterns.length === 0) {
|
|
234
|
+
errors.push('Preset must have at least one pattern');
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Validate actions
|
|
238
|
+
if (!preset.actions || Object.keys(preset.actions).length === 0) {
|
|
239
|
+
errors.push('Preset must have at least one action');
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Validate each action
|
|
243
|
+
for (const [pattern, action] of Object.entries(preset.actions || {})) {
|
|
244
|
+
if (!action.command) {
|
|
245
|
+
errors.push(`Action for pattern "${pattern}" must have a command`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
valid: errors.length === 0,
|
|
251
|
+
errors
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
module.exports = {
|
|
256
|
+
presets,
|
|
257
|
+
getPreset,
|
|
258
|
+
listPresets,
|
|
259
|
+
mergePreset,
|
|
260
|
+
validatePreset,
|
|
261
|
+
// Export individual presets for testing
|
|
262
|
+
autoSyncPreset,
|
|
263
|
+
promptRegenPreset,
|
|
264
|
+
contextExportPreset,
|
|
265
|
+
testRunnerPreset
|
|
266
|
+
};
|