kiro-spec-engine 1.2.3 → 1.4.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 +135 -0
- package/README.md +239 -213
- package/README.zh.md +0 -330
- package/bin/kiro-spec-engine.js +62 -0
- package/docs/README.md +223 -0
- package/docs/agent-hooks-analysis.md +815 -0
- package/docs/command-reference.md +252 -0
- package/docs/cross-tool-guide.md +554 -0
- package/docs/examples/add-export-command/design.md +194 -0
- package/docs/examples/add-export-command/requirements.md +110 -0
- package/docs/examples/add-export-command/tasks.md +88 -0
- package/docs/examples/add-rest-api/design.md +855 -0
- package/docs/examples/add-rest-api/requirements.md +323 -0
- package/docs/examples/add-rest-api/tasks.md +355 -0
- package/docs/examples/add-user-dashboard/design.md +192 -0
- package/docs/examples/add-user-dashboard/requirements.md +143 -0
- package/docs/examples/add-user-dashboard/tasks.md +91 -0
- package/docs/faq.md +696 -0
- package/docs/integration-modes.md +525 -0
- package/docs/integration-philosophy.md +313 -0
- package/docs/manual-workflows-guide.md +417 -0
- package/docs/quick-start-with-ai-tools.md +374 -0
- package/docs/quick-start.md +711 -0
- package/docs/spec-workflow.md +453 -0
- package/docs/steering-strategy-guide.md +196 -0
- package/docs/tools/claude-guide.md +653 -0
- package/docs/tools/cursor-guide.md +705 -0
- package/docs/tools/generic-guide.md +445 -0
- package/docs/tools/kiro-guide.md +308 -0
- package/docs/tools/vscode-guide.md +444 -0
- package/docs/tools/windsurf-guide.md +390 -0
- package/docs/troubleshooting.md +795 -0
- package/docs/zh/README.md +275 -0
- package/docs/zh/quick-start.md +711 -0
- package/docs/zh/tools/claude-guide.md +348 -0
- package/docs/zh/tools/cursor-guide.md +280 -0
- package/docs/zh/tools/generic-guide.md +498 -0
- package/docs/zh/tools/kiro-guide.md +342 -0
- package/docs/zh/tools/vscode-guide.md +448 -0
- package/docs/zh/tools/windsurf-guide.md +377 -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 +3 -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,383 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects which IDE/editor the user is using
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Detect the current IDE/editor environment
|
|
12
|
+
*
|
|
13
|
+
* @param {string} projectPath - Project root path
|
|
14
|
+
* @returns {Promise<Object>} Detection result
|
|
15
|
+
*/
|
|
16
|
+
async function detectTool(projectPath) {
|
|
17
|
+
const detections = {
|
|
18
|
+
kiro: await detectKiroIDE(projectPath),
|
|
19
|
+
vscode: await detectVSCode(projectPath),
|
|
20
|
+
cursor: await detectCursor(projectPath),
|
|
21
|
+
other: null
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// Determine primary tool
|
|
25
|
+
let primaryTool = 'unknown';
|
|
26
|
+
let confidence = 'low';
|
|
27
|
+
|
|
28
|
+
if (detections.kiro.detected) {
|
|
29
|
+
primaryTool = 'kiro';
|
|
30
|
+
confidence = detections.kiro.confidence;
|
|
31
|
+
} else if (detections.cursor.detected && detections.cursor.confidence === 'high') {
|
|
32
|
+
// Only use Cursor if we have high confidence (Cursor-specific indicators)
|
|
33
|
+
primaryTool = 'cursor';
|
|
34
|
+
confidence = detections.cursor.confidence;
|
|
35
|
+
} else if (detections.vscode.detected) {
|
|
36
|
+
primaryTool = 'vscode';
|
|
37
|
+
confidence = detections.vscode.confidence;
|
|
38
|
+
} else if (detections.cursor.detected) {
|
|
39
|
+
// Fallback to Cursor if VS Code not detected
|
|
40
|
+
primaryTool = 'cursor';
|
|
41
|
+
confidence = detections.cursor.confidence;
|
|
42
|
+
} else {
|
|
43
|
+
primaryTool = 'other';
|
|
44
|
+
confidence = 'low';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
primaryTool,
|
|
49
|
+
confidence,
|
|
50
|
+
detections,
|
|
51
|
+
recommendations: getRecommendations(primaryTool, detections)
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Detect Kiro IDE
|
|
57
|
+
*
|
|
58
|
+
* @param {string} projectPath - Project root path
|
|
59
|
+
* @returns {Promise<Object>} Detection result
|
|
60
|
+
*/
|
|
61
|
+
async function detectKiroIDE(projectPath) {
|
|
62
|
+
const indicators = [];
|
|
63
|
+
let detected = false;
|
|
64
|
+
let confidence = 'low';
|
|
65
|
+
|
|
66
|
+
// Check for .kiro directory
|
|
67
|
+
const kiroDir = path.join(projectPath, '.kiro');
|
|
68
|
+
if (await fs.pathExists(kiroDir)) {
|
|
69
|
+
indicators.push('.kiro directory exists');
|
|
70
|
+
detected = true;
|
|
71
|
+
confidence = 'medium';
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Check for Kiro-specific files
|
|
75
|
+
const kiroFiles = [
|
|
76
|
+
'.kiro/steering',
|
|
77
|
+
'.kiro/specs',
|
|
78
|
+
'.kiro/tools'
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
for (const file of kiroFiles) {
|
|
82
|
+
const filePath = path.join(projectPath, file);
|
|
83
|
+
if (await fs.pathExists(filePath)) {
|
|
84
|
+
indicators.push(`${file} exists`);
|
|
85
|
+
confidence = 'high';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Check for environment variables (if running in Kiro)
|
|
90
|
+
if (process.env.KIRO_IDE === 'true' || process.env.KIRO_VERSION) {
|
|
91
|
+
indicators.push('Kiro environment variables detected');
|
|
92
|
+
detected = true;
|
|
93
|
+
confidence = 'high';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
detected,
|
|
98
|
+
confidence,
|
|
99
|
+
indicators,
|
|
100
|
+
features: detected ? ['agent-hooks', 'native-integration'] : []
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Detect VS Code
|
|
106
|
+
*
|
|
107
|
+
* @param {string} projectPath - Project root path
|
|
108
|
+
* @returns {Promise<Object>} Detection result
|
|
109
|
+
*/
|
|
110
|
+
async function detectVSCode(projectPath) {
|
|
111
|
+
const indicators = [];
|
|
112
|
+
let detected = false;
|
|
113
|
+
let confidence = 'low';
|
|
114
|
+
|
|
115
|
+
// Check for .vscode directory
|
|
116
|
+
const vscodeDir = path.join(projectPath, '.vscode');
|
|
117
|
+
if (await fs.pathExists(vscodeDir)) {
|
|
118
|
+
indicators.push('.vscode directory exists');
|
|
119
|
+
detected = true;
|
|
120
|
+
confidence = 'medium';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Check for VS Code specific files
|
|
124
|
+
const vscodeFiles = [
|
|
125
|
+
'.vscode/settings.json',
|
|
126
|
+
'.vscode/launch.json',
|
|
127
|
+
'.vscode/tasks.json'
|
|
128
|
+
];
|
|
129
|
+
|
|
130
|
+
for (const file of vscodeFiles) {
|
|
131
|
+
const filePath = path.join(projectPath, file);
|
|
132
|
+
if (await fs.pathExists(filePath)) {
|
|
133
|
+
indicators.push(`${file} exists`);
|
|
134
|
+
confidence = 'high';
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Check for environment variables
|
|
139
|
+
if (process.env.VSCODE_PID || process.env.TERM_PROGRAM === 'vscode') {
|
|
140
|
+
indicators.push('VS Code environment detected');
|
|
141
|
+
detected = true;
|
|
142
|
+
confidence = 'high';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
detected,
|
|
147
|
+
confidence,
|
|
148
|
+
indicators,
|
|
149
|
+
features: detected ? ['watch-mode', 'manual-workflows'] : []
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Detect Cursor
|
|
155
|
+
*
|
|
156
|
+
* @param {string} projectPath - Project root path
|
|
157
|
+
* @returns {Promise<Object>} Detection result
|
|
158
|
+
*/
|
|
159
|
+
async function detectCursor(projectPath) {
|
|
160
|
+
const indicators = [];
|
|
161
|
+
let detected = false;
|
|
162
|
+
let confidence = 'low';
|
|
163
|
+
|
|
164
|
+
// Cursor uses similar structure to VS Code
|
|
165
|
+
const vscodeDir = path.join(projectPath, '.vscode');
|
|
166
|
+
if (await fs.pathExists(vscodeDir)) {
|
|
167
|
+
indicators.push('.vscode directory exists (Cursor compatible)');
|
|
168
|
+
detected = true;
|
|
169
|
+
confidence = 'low'; // Could be VS Code or Cursor
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Check for Cursor-specific indicators
|
|
173
|
+
if (process.env.CURSOR_VERSION || process.env.TERM_PROGRAM === 'cursor') {
|
|
174
|
+
indicators.push('Cursor environment detected');
|
|
175
|
+
detected = true;
|
|
176
|
+
confidence = 'high';
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Check for Cursor-specific settings
|
|
180
|
+
const settingsPath = path.join(projectPath, '.vscode/settings.json');
|
|
181
|
+
if (await fs.pathExists(settingsPath)) {
|
|
182
|
+
try {
|
|
183
|
+
const settings = await fs.readJson(settingsPath);
|
|
184
|
+
if (settings['cursor.aiEnabled'] !== undefined ||
|
|
185
|
+
settings['cursor.chat'] !== undefined) {
|
|
186
|
+
indicators.push('Cursor-specific settings found');
|
|
187
|
+
confidence = 'high';
|
|
188
|
+
}
|
|
189
|
+
} catch (error) {
|
|
190
|
+
// Ignore JSON parse errors
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
detected,
|
|
196
|
+
confidence,
|
|
197
|
+
indicators,
|
|
198
|
+
features: detected ? ['watch-mode', 'manual-workflows', 'ai-integration'] : []
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Get recommendations based on detected tool
|
|
204
|
+
*
|
|
205
|
+
* @param {string} primaryTool - Primary tool name
|
|
206
|
+
* @param {Object} detections - All detections
|
|
207
|
+
* @returns {Array} Recommendations
|
|
208
|
+
*/
|
|
209
|
+
function getRecommendations(primaryTool, detections) {
|
|
210
|
+
const recommendations = [];
|
|
211
|
+
|
|
212
|
+
switch (primaryTool) {
|
|
213
|
+
case 'kiro':
|
|
214
|
+
recommendations.push({
|
|
215
|
+
type: 'native',
|
|
216
|
+
title: 'Use Kiro Agent Hooks',
|
|
217
|
+
description: 'You can use native Kiro agent hooks for seamless automation',
|
|
218
|
+
action: 'Configure hooks in .kiro/hooks/'
|
|
219
|
+
});
|
|
220
|
+
recommendations.push({
|
|
221
|
+
type: 'optional',
|
|
222
|
+
title: 'Watch Mode Available',
|
|
223
|
+
description: 'Watch mode is also available as a fallback option',
|
|
224
|
+
action: 'Run: kse watch init'
|
|
225
|
+
});
|
|
226
|
+
break;
|
|
227
|
+
|
|
228
|
+
case 'vscode':
|
|
229
|
+
case 'cursor':
|
|
230
|
+
recommendations.push({
|
|
231
|
+
type: 'primary',
|
|
232
|
+
title: 'Use Watch Mode',
|
|
233
|
+
description: 'Watch mode provides automated file monitoring for your IDE',
|
|
234
|
+
action: 'Run: kse watch init && kse watch install auto-sync'
|
|
235
|
+
});
|
|
236
|
+
recommendations.push({
|
|
237
|
+
type: 'preset',
|
|
238
|
+
title: 'Install Presets',
|
|
239
|
+
description: 'Pre-configured automation patterns for common workflows',
|
|
240
|
+
action: 'Run: kse watch presets'
|
|
241
|
+
});
|
|
242
|
+
break;
|
|
243
|
+
|
|
244
|
+
case 'other':
|
|
245
|
+
default:
|
|
246
|
+
recommendations.push({
|
|
247
|
+
type: 'manual',
|
|
248
|
+
title: 'Manual Workflows',
|
|
249
|
+
description: 'Follow documented manual workflows for your tool',
|
|
250
|
+
action: 'See: docs/cross-tool-guide.md'
|
|
251
|
+
});
|
|
252
|
+
recommendations.push({
|
|
253
|
+
type: 'watch',
|
|
254
|
+
title: 'Try Watch Mode',
|
|
255
|
+
description: 'Watch mode works with most editors and IDEs',
|
|
256
|
+
action: 'Run: kse watch init'
|
|
257
|
+
});
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return recommendations;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Get automation suggestions based on tool
|
|
266
|
+
*
|
|
267
|
+
* @param {string} tool - Tool name
|
|
268
|
+
* @returns {Array} Suggestions
|
|
269
|
+
*/
|
|
270
|
+
function getAutomationSuggestions(tool) {
|
|
271
|
+
const suggestions = {
|
|
272
|
+
kiro: [
|
|
273
|
+
'Configure agent hooks for automatic task sync',
|
|
274
|
+
'Set up prompt regeneration on spec changes',
|
|
275
|
+
'Enable context export on task completion'
|
|
276
|
+
],
|
|
277
|
+
vscode: [
|
|
278
|
+
'Install auto-sync preset for task synchronization',
|
|
279
|
+
'Use watch mode for automated workflows',
|
|
280
|
+
'Configure VS Code tasks for manual triggers'
|
|
281
|
+
],
|
|
282
|
+
cursor: [
|
|
283
|
+
'Install auto-sync preset for task synchronization',
|
|
284
|
+
'Use watch mode for automated workflows',
|
|
285
|
+
'Leverage Cursor AI for enhanced productivity'
|
|
286
|
+
],
|
|
287
|
+
other: [
|
|
288
|
+
'Follow manual workflow documentation',
|
|
289
|
+
'Consider using watch mode for automation',
|
|
290
|
+
'Set up shell aliases for common commands'
|
|
291
|
+
]
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
return suggestions[tool] || suggestions.other;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Generate auto-configuration for detected tool
|
|
299
|
+
*
|
|
300
|
+
* @param {Object} detection - Detection result from detectTool
|
|
301
|
+
* @param {string} projectPath - Project root path
|
|
302
|
+
* @returns {Promise<Object>} Auto-configuration result
|
|
303
|
+
*/
|
|
304
|
+
async function generateAutoConfig(detection, projectPath) {
|
|
305
|
+
const { primaryTool, confidence } = detection;
|
|
306
|
+
|
|
307
|
+
const config = {
|
|
308
|
+
tool: primaryTool,
|
|
309
|
+
confidence,
|
|
310
|
+
suggestedPresets: [],
|
|
311
|
+
suggestedCommands: [],
|
|
312
|
+
configPath: null,
|
|
313
|
+
notes: []
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
switch (primaryTool) {
|
|
317
|
+
case 'kiro':
|
|
318
|
+
config.suggestedPresets = [];
|
|
319
|
+
config.suggestedCommands = [
|
|
320
|
+
'Use native Kiro agent hooks (see .kiro/hooks/)',
|
|
321
|
+
'Optional: kse watch init (for watch mode fallback)'
|
|
322
|
+
];
|
|
323
|
+
config.notes.push('Kiro IDE detected - native hooks are recommended');
|
|
324
|
+
config.notes.push('Watch mode available as fallback option');
|
|
325
|
+
break;
|
|
326
|
+
|
|
327
|
+
case 'vscode':
|
|
328
|
+
case 'cursor':
|
|
329
|
+
config.suggestedPresets = ['auto-sync', 'prompt-regen', 'context-export'];
|
|
330
|
+
config.suggestedCommands = [
|
|
331
|
+
'kse watch init',
|
|
332
|
+
'kse watch install auto-sync',
|
|
333
|
+
'kse watch start'
|
|
334
|
+
];
|
|
335
|
+
config.configPath = path.join(projectPath, '.kiro/watch-config.json');
|
|
336
|
+
config.notes.push(`${primaryTool === 'vscode' ? 'VS Code' : 'Cursor'} detected - watch mode recommended`);
|
|
337
|
+
config.notes.push('Run suggested commands to set up automation');
|
|
338
|
+
break;
|
|
339
|
+
|
|
340
|
+
case 'other':
|
|
341
|
+
default:
|
|
342
|
+
config.suggestedPresets = ['auto-sync'];
|
|
343
|
+
config.suggestedCommands = [
|
|
344
|
+
'kse watch init',
|
|
345
|
+
'kse watch install auto-sync',
|
|
346
|
+
'See: docs/cross-tool-guide.md for manual workflows'
|
|
347
|
+
];
|
|
348
|
+
config.notes.push('No specific IDE detected');
|
|
349
|
+
config.notes.push('Watch mode available for basic automation');
|
|
350
|
+
config.notes.push('Manual workflows documented in docs/');
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return config;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Offer to install presets interactively
|
|
359
|
+
*
|
|
360
|
+
* @param {Object} detection - Detection result from detectTool
|
|
361
|
+
* @param {string} projectPath - Project root path
|
|
362
|
+
* @returns {Promise<Object>} Installation result
|
|
363
|
+
*/
|
|
364
|
+
async function offerPresetInstallation(detection, projectPath) {
|
|
365
|
+
const config = await generateAutoConfig(detection, projectPath);
|
|
366
|
+
|
|
367
|
+
return {
|
|
368
|
+
success: true,
|
|
369
|
+
config,
|
|
370
|
+
message: 'Auto-configuration generated successfully'
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
module.exports = {
|
|
375
|
+
detectTool,
|
|
376
|
+
detectKiroIDE,
|
|
377
|
+
detectVSCode,
|
|
378
|
+
detectCursor,
|
|
379
|
+
getRecommendations,
|
|
380
|
+
getAutomationSuggestions,
|
|
381
|
+
generateAutoConfig,
|
|
382
|
+
offerPresetInstallation
|
|
383
|
+
};
|