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,377 @@
|
|
|
1
|
+
# 在 Windsurf 中使用 kse
|
|
2
|
+
|
|
3
|
+
> 将 kse 与 Windsurf IDE 集成进行 AI 辅助开发的完整指南
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**版本**: 1.0.0
|
|
8
|
+
**最后更新**: 2026-01-23
|
|
9
|
+
**工具**: Windsurf IDE
|
|
10
|
+
**集成模式**: 原生 + Watch 模式
|
|
11
|
+
**预计设置时间**: 2 分钟
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 概述
|
|
16
|
+
|
|
17
|
+
**Windsurf** 是一个 AI 驱动的 IDE,具有强大的命令执行能力。它可以直接运行 shell 命令,使其成为 kse 的理想选择。
|
|
18
|
+
|
|
19
|
+
**kse 与 Windsurf 的集成**支持**原生模式**和**Watch 模式**,实现最无缝的体验。
|
|
20
|
+
|
|
21
|
+
### 为什么在 Windsurf 中使用 kse?
|
|
22
|
+
|
|
23
|
+
- ✅ **原生命令执行** - Windsurf 可以直接运行 kse 命令
|
|
24
|
+
- ✅ **自动化工作流** - 无需手动导出/粘贴
|
|
25
|
+
- ✅ **Watch 模式支持** - 自动上下文更新
|
|
26
|
+
- ✅ **完全集成** - 最无缝的 kse 体验
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 集成模式
|
|
31
|
+
|
|
32
|
+
**模式:** 原生 + Watch 模式
|
|
33
|
+
|
|
34
|
+
**工作原理:**
|
|
35
|
+
1. 你在 kse 中创建 Spec(需求、设计、任务)
|
|
36
|
+
2. 你告诉 Windsurf:"使用 kse 检查 spec 并实现任务 1.1"
|
|
37
|
+
3. Windsurf 自动运行 `kse context export`
|
|
38
|
+
4. Windsurf 读取导出的上下文
|
|
39
|
+
5. Windsurf 生成代码
|
|
40
|
+
6. Windsurf 可以更新 tasks.md 中的任务状态
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 设置
|
|
45
|
+
|
|
46
|
+
### 前置条件
|
|
47
|
+
|
|
48
|
+
- 已安装 **Windsurf IDE**([下载](https://windsurf.ai/))
|
|
49
|
+
- 已全局安装 **kse**(`npm install -g kiro-spec-engine`)
|
|
50
|
+
- 项目已被 kse **采用**(`kse adopt`)
|
|
51
|
+
|
|
52
|
+
### 步骤 1:验证 kse 可访问
|
|
53
|
+
|
|
54
|
+
在 Windsurf 终端中:
|
|
55
|
+
```bash
|
|
56
|
+
kse --version
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
应显示版本号(例如 1.3.0)。
|
|
60
|
+
|
|
61
|
+
### 步骤 2:启用 Watch 模式(可选但推荐)
|
|
62
|
+
|
|
63
|
+
Watch 模式在文件更改时自动更新上下文:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
kse watch start
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
这会在后台启动文件监视器。
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 使用方法
|
|
74
|
+
|
|
75
|
+
### 方法 1:直接命令(推荐)
|
|
76
|
+
|
|
77
|
+
**最简单的方法** - 只需告诉 Windsurf 使用 kse!
|
|
78
|
+
|
|
79
|
+
**步骤:**
|
|
80
|
+
|
|
81
|
+
1. **在 Windsurf 中打开聊天**
|
|
82
|
+
|
|
83
|
+
2. **告诉 Windsurf:**
|
|
84
|
+
```
|
|
85
|
+
使用 kse 检查 01-00-user-login 的 spec 并实现任务 1.1
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
3. **Windsurf 将:**
|
|
89
|
+
- 运行 `kse context export 01-00-user-login`
|
|
90
|
+
- 读取导出的上下文
|
|
91
|
+
- 理解需求和设计
|
|
92
|
+
- 生成代码
|
|
93
|
+
- 创建或修改文件
|
|
94
|
+
- 可选:更新 tasks.md
|
|
95
|
+
|
|
96
|
+
### 方法 2:分步命令
|
|
97
|
+
|
|
98
|
+
**更多控制** - 明确告诉 Windsurf 每一步做什么。
|
|
99
|
+
|
|
100
|
+
**步骤:**
|
|
101
|
+
|
|
102
|
+
1. **导出上下文:**
|
|
103
|
+
```
|
|
104
|
+
请运行:kse context export 01-00-user-login
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
2. **读取上下文:**
|
|
108
|
+
```
|
|
109
|
+
请读取 .kiro/specs/01-00-user-login/context-export.md
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
3. **实现任务:**
|
|
113
|
+
```
|
|
114
|
+
现在请实现任务 1.1:"设置项目依赖"
|
|
115
|
+
严格遵循 design.md 中的架构。
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
4. **更新任务状态:**
|
|
119
|
+
```
|
|
120
|
+
请在 .kiro/specs/01-00-user-login/tasks.md 中将任务 1.1 标记为完成
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 方法 3:Watch 模式 + 自动更新
|
|
124
|
+
|
|
125
|
+
**最自动化** - 文件更改时自动更新上下文。
|
|
126
|
+
|
|
127
|
+
**步骤:**
|
|
128
|
+
|
|
129
|
+
1. **启动 Watch 模式:**
|
|
130
|
+
```bash
|
|
131
|
+
kse watch start
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
2. **配置 Watch 模式以在更改时导出:**
|
|
135
|
+
```bash
|
|
136
|
+
kse watch add --pattern ".kiro/specs/*/requirements.md" --action "kse context export {spec}"
|
|
137
|
+
kse watch add --pattern ".kiro/specs/*/design.md" --action "kse context export {spec}"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
3. **现在,当你更新 Spec 文件时:**
|
|
141
|
+
- Watch 模式自动重新导出上下文
|
|
142
|
+
- Windsurf 始终拥有最新的上下文
|
|
143
|
+
- 无需手动重新导出!
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 工作流示例
|
|
148
|
+
|
|
149
|
+
### 完整功能实现工作流
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# 1. 创建 Spec
|
|
153
|
+
kse create-spec 01-00-user-login
|
|
154
|
+
|
|
155
|
+
# 2. 编写 requirements.md、design.md、tasks.md
|
|
156
|
+
|
|
157
|
+
# 3. 在 Windsurf 中告诉 AI:
|
|
158
|
+
"使用 kse 检查 01-00-user-login 的 spec 并实现任务 1.1"
|
|
159
|
+
|
|
160
|
+
# 4. Windsurf 自动:
|
|
161
|
+
# - 导出上下文
|
|
162
|
+
# - 读取 Spec
|
|
163
|
+
# - 生成代码
|
|
164
|
+
# - 更新任务状态
|
|
165
|
+
|
|
166
|
+
# 5. 审查更改
|
|
167
|
+
|
|
168
|
+
# 6. 对下一个任务重复
|
|
169
|
+
"现在请实现任务 1.2"
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 使用 Watch 模式的迭代开发
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# 1. 启动 Watch 模式
|
|
176
|
+
kse watch start
|
|
177
|
+
|
|
178
|
+
# 2. 在 Windsurf 中实现任务
|
|
179
|
+
"使用 kse 实现 01-00-user-login 的任务 1.1"
|
|
180
|
+
|
|
181
|
+
# 3. 如果需要,更新 design.md
|
|
182
|
+
# Watch 模式自动重新导出上下文
|
|
183
|
+
|
|
184
|
+
# 4. 继续下一个任务
|
|
185
|
+
"现在请实现任务 1.2"
|
|
186
|
+
# Windsurf 使用更新的上下文
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 最佳实践
|
|
192
|
+
|
|
193
|
+
### 1. 使用自然语言
|
|
194
|
+
|
|
195
|
+
Windsurf 理解自然语言。只需说:
|
|
196
|
+
```
|
|
197
|
+
"使用 kse 检查 user-login spec 并实现下一个任务"
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### 2. 让 Windsurf 管理任务
|
|
201
|
+
|
|
202
|
+
Windsurf 可以更新任务状态:
|
|
203
|
+
```
|
|
204
|
+
"实现任务 1.1 并在 tasks.md 中标记为完成"
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### 3. 使用 Watch 模式进行活跃开发
|
|
208
|
+
|
|
209
|
+
在活跃开发期间启动 Watch 模式:
|
|
210
|
+
```bash
|
|
211
|
+
kse watch start
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
完成后停止:
|
|
215
|
+
```bash
|
|
216
|
+
kse watch stop
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### 4. 批量实现任务
|
|
220
|
+
|
|
221
|
+
Windsurf 可以实现多个任务:
|
|
222
|
+
```
|
|
223
|
+
"使用 kse 实现 01-00-user-login 的任务 1.1、1.2 和 1.3"
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### 5. 要求验证
|
|
227
|
+
|
|
228
|
+
让 Windsurf 验证实现:
|
|
229
|
+
```
|
|
230
|
+
"实现任务 1.1 并运行测试以验证它是否有效"
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## 示例提示
|
|
236
|
+
|
|
237
|
+
### 实现新功能
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
使用 kse 检查 .kiro/specs/01-00-user-login/ 中的 spec 并实现任务 1.1:"设置项目依赖"。
|
|
241
|
+
|
|
242
|
+
严格遵循 design.md 中的架构。
|
|
243
|
+
完成后在 tasks.md 中标记任务为完成。
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### 实现多个任务
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
使用 kse 检查 01-00-user-login spec 并实现阶段 1 的所有任务(1.1 和 1.2)。
|
|
250
|
+
|
|
251
|
+
对于每个任务:
|
|
252
|
+
1. 实现代码
|
|
253
|
+
2. 编写测试
|
|
254
|
+
3. 在 tasks.md 中标记为完成
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### 调试问题
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
我正在实现 01-00-user-login spec。
|
|
261
|
+
|
|
262
|
+
任务 2.1 已完成,但测试失败。请:
|
|
263
|
+
1. 使用 kse 检查 spec
|
|
264
|
+
2. 审查我的代码
|
|
265
|
+
3. 识别问题
|
|
266
|
+
4. 修复它
|
|
267
|
+
5. 运行测试以验证
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Watch 模式配置
|
|
273
|
+
|
|
274
|
+
### 基本 Watch 配置
|
|
275
|
+
|
|
276
|
+
在 Spec 更改时自动导出上下文:
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# 监视 requirements.md 更改
|
|
280
|
+
kse watch add --pattern ".kiro/specs/*/requirements.md" --action "kse context export {spec}"
|
|
281
|
+
|
|
282
|
+
# 监视 design.md 更改
|
|
283
|
+
kse watch add --pattern ".kiro/specs/*/design.md" --action "kse context export {spec}"
|
|
284
|
+
|
|
285
|
+
# 监视 tasks.md 更改
|
|
286
|
+
kse watch add --pattern ".kiro/specs/*/tasks.md" --action "kse context export {spec}"
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### 高级 Watch 配置
|
|
290
|
+
|
|
291
|
+
在 Spec 更改时运行测试:
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# 在任务更新时运行测试
|
|
295
|
+
kse watch add --pattern ".kiro/specs/*/tasks.md" --action "npm test"
|
|
296
|
+
|
|
297
|
+
# 在设计更改时运行 linter
|
|
298
|
+
kse watch add --pattern ".kiro/specs/*/design.md" --action "npm run lint"
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### 检查 Watch 状态
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
# 查看 Watch 模式是否正在运行
|
|
305
|
+
kse watch status
|
|
306
|
+
|
|
307
|
+
# 列出所有 watch 规则
|
|
308
|
+
kse watch list
|
|
309
|
+
|
|
310
|
+
# 停止 Watch 模式
|
|
311
|
+
kse watch stop
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## 故障排除
|
|
317
|
+
|
|
318
|
+
### 问题:Windsurf 找不到 kse 命令
|
|
319
|
+
|
|
320
|
+
**解决方案:**
|
|
321
|
+
1. 验证 kse 已全局安装:
|
|
322
|
+
```bash
|
|
323
|
+
npm list -g kiro-spec-engine
|
|
324
|
+
```
|
|
325
|
+
2. 重启 Windsurf
|
|
326
|
+
3. 检查 PATH 是否包含 npm 全局 bin
|
|
327
|
+
|
|
328
|
+
### 问题:Watch 模式未触发
|
|
329
|
+
|
|
330
|
+
**解决方案:**
|
|
331
|
+
1. 检查 Watch 模式是否正在运行:
|
|
332
|
+
```bash
|
|
333
|
+
kse watch status
|
|
334
|
+
```
|
|
335
|
+
2. 验证文件模式是否正确:
|
|
336
|
+
```bash
|
|
337
|
+
kse watch list
|
|
338
|
+
```
|
|
339
|
+
3. 重启 Watch 模式:
|
|
340
|
+
```bash
|
|
341
|
+
kse watch stop
|
|
342
|
+
kse watch start
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### 问题:Windsurf 不遵循设计
|
|
346
|
+
|
|
347
|
+
**解决方案:**
|
|
348
|
+
1. 使你的 design.md 更详细
|
|
349
|
+
2. 在提示中明确:"严格遵循 design.md"
|
|
350
|
+
3. 要求 Windsurf 先读取设计:
|
|
351
|
+
```
|
|
352
|
+
首先读取 .kiro/specs/01-00-user-login/design.md
|
|
353
|
+
然后实现任务 1.1
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## 相关文档
|
|
359
|
+
|
|
360
|
+
- 📖 [快速入门指南](../quick-start.md) - 开始使用 kse
|
|
361
|
+
- 🔌 [集成模式](../integration-modes.md) - 理解原生和 Watch 模式
|
|
362
|
+
- 📋 [Spec 工作流](../spec-workflow.md) - 创建有效的 Spec
|
|
363
|
+
- 🔧 [故障排除](../troubleshooting.md) - 常见问题
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## 下一步
|
|
368
|
+
|
|
369
|
+
- 尝试使用 Windsurf 的原生命令实现你的第一个任务
|
|
370
|
+
- 设置 Watch 模式进行自动上下文更新
|
|
371
|
+
- 探索批量任务实现
|
|
372
|
+
- 查看 [API 示例](../examples/add-rest-api/) 获取完整的 Spec 示例
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
**版本**: 1.0.0
|
|
377
|
+
**最后更新**: 2026-01-23
|
|
@@ -11,6 +11,7 @@ const {
|
|
|
11
11
|
listFiles,
|
|
12
12
|
readJSON
|
|
13
13
|
} = require('../utils/fs-utils');
|
|
14
|
+
const SteeringManager = require('../steering/steering-manager');
|
|
14
15
|
|
|
15
16
|
class DetectionEngine {
|
|
16
17
|
constructor() {
|
|
@@ -19,6 +20,7 @@ class DetectionEngine {
|
|
|
19
20
|
this.specsDir = 'specs';
|
|
20
21
|
this.steeringDir = 'steering';
|
|
21
22
|
this.toolsDir = 'tools';
|
|
23
|
+
this.steeringManager = new SteeringManager();
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
/**
|
|
@@ -37,6 +39,7 @@ class DetectionEngine {
|
|
|
37
39
|
let hasSteering = false;
|
|
38
40
|
let hasTools = false;
|
|
39
41
|
let existingVersion = null;
|
|
42
|
+
let steeringDetection = null;
|
|
40
43
|
|
|
41
44
|
if (hasKiroDir) {
|
|
42
45
|
// Check for version.json
|
|
@@ -57,9 +60,9 @@ class DetectionEngine {
|
|
|
57
60
|
const specsPath = path.join(kiroPath, this.specsDir);
|
|
58
61
|
hasSpecs = await pathExists(specsPath);
|
|
59
62
|
|
|
60
|
-
// Check for steering/
|
|
61
|
-
|
|
62
|
-
hasSteering =
|
|
63
|
+
// Check for steering/ using SteeringManager
|
|
64
|
+
steeringDetection = await this.steeringManager.detectSteering(projectPath);
|
|
65
|
+
hasSteering = steeringDetection.hasExistingSteering;
|
|
63
66
|
|
|
64
67
|
// Check for tools/
|
|
65
68
|
const toolsPath = path.join(kiroPath, this.toolsDir);
|
|
@@ -80,7 +83,8 @@ class DetectionEngine {
|
|
|
80
83
|
hasTools,
|
|
81
84
|
projectType,
|
|
82
85
|
existingVersion,
|
|
83
|
-
conflicts
|
|
86
|
+
conflicts,
|
|
87
|
+
steeringDetection // Add steering detection details
|
|
84
88
|
};
|
|
85
89
|
} catch (error) {
|
|
86
90
|
throw new Error(`Failed to analyze project: ${error.message}`);
|
|
@@ -225,6 +229,12 @@ class DetectionEngine {
|
|
|
225
229
|
}
|
|
226
230
|
lines.push(` specs/: ${result.hasSpecs ? 'Yes' : 'No'}`);
|
|
227
231
|
lines.push(` steering/: ${result.hasSteering ? 'Yes' : 'No'}`);
|
|
232
|
+
|
|
233
|
+
// Show steering details if available
|
|
234
|
+
if (result.steeringDetection && result.steeringDetection.hasExistingSteering) {
|
|
235
|
+
lines.push(` Files: ${result.steeringDetection.count} file(s)`);
|
|
236
|
+
}
|
|
237
|
+
|
|
228
238
|
lines.push(` tools/: ${result.hasTools ? 'Yes' : 'No'}`);
|
|
229
239
|
|
|
230
240
|
if (result.conflicts.length > 0) {
|
package/lib/commands/adopt.js
CHANGED
|
@@ -12,6 +12,9 @@ const DetectionEngine = require('../adoption/detection-engine');
|
|
|
12
12
|
const { getAdoptionStrategy } = require('../adoption/adoption-strategy');
|
|
13
13
|
const BackupSystem = require('../backup/backup-system');
|
|
14
14
|
const VersionManager = require('../version/version-manager');
|
|
15
|
+
const SteeringManager = require('../steering/steering-manager');
|
|
16
|
+
const AdoptionConfig = require('../steering/adoption-config');
|
|
17
|
+
const { detectTool, generateAutoConfig } = require('../utils/tool-detector');
|
|
15
18
|
|
|
16
19
|
/**
|
|
17
20
|
* Executes the adopt command
|
|
@@ -134,7 +137,54 @@ async function adoptCommand(options = {}) {
|
|
|
134
137
|
|
|
135
138
|
console.log();
|
|
136
139
|
|
|
137
|
-
// 7.
|
|
140
|
+
// 7. Handle steering strategy if conflicts detected
|
|
141
|
+
let steeringStrategy = null;
|
|
142
|
+
let steeringBackupId = null;
|
|
143
|
+
|
|
144
|
+
if (detection.steeringDetection && detection.steeringDetection.hasExistingSteering) {
|
|
145
|
+
console.log(chalk.blue('🎯 Handling steering files...'));
|
|
146
|
+
const steeringManager = new SteeringManager();
|
|
147
|
+
|
|
148
|
+
// Prompt for strategy
|
|
149
|
+
steeringStrategy = await steeringManager.promptStrategy(detection.steeringDetection);
|
|
150
|
+
|
|
151
|
+
if (steeringStrategy === 'use-kse') {
|
|
152
|
+
// Backup existing steering files
|
|
153
|
+
console.log(chalk.blue('📦 Backing up existing steering files...'));
|
|
154
|
+
const backupResult = await steeringManager.backupSteering(projectPath);
|
|
155
|
+
|
|
156
|
+
if (backupResult.success) {
|
|
157
|
+
steeringBackupId = backupResult.backupId;
|
|
158
|
+
console.log(chalk.green(`✅ Steering backup created: ${steeringBackupId}`));
|
|
159
|
+
|
|
160
|
+
// Install kse steering files
|
|
161
|
+
console.log(chalk.blue('📝 Installing kse steering files...'));
|
|
162
|
+
const installResult = await steeringManager.installKseSteering(projectPath);
|
|
163
|
+
|
|
164
|
+
if (installResult.success) {
|
|
165
|
+
console.log(chalk.green(`✅ Installed ${installResult.filesInstalled} kse steering file(s)`));
|
|
166
|
+
} else {
|
|
167
|
+
console.log(chalk.red(`❌ Failed to install kse steering: ${installResult.error}`));
|
|
168
|
+
console.log(chalk.yellow('Aborting adoption'));
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
} else {
|
|
172
|
+
console.log(chalk.red(`❌ Failed to backup steering: ${backupResult.error}`));
|
|
173
|
+
console.log(chalk.yellow('Aborting adoption for safety'));
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
} else if (steeringStrategy === 'use-project') {
|
|
177
|
+
console.log(chalk.blue('✅ Keeping existing steering files'));
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Save steering strategy to adoption config
|
|
181
|
+
const adoptionConfig = new AdoptionConfig(projectPath);
|
|
182
|
+
await adoptionConfig.updateSteeringStrategy(steeringStrategy, steeringBackupId);
|
|
183
|
+
|
|
184
|
+
console.log();
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// 8. Create backup if needed
|
|
138
188
|
let backupId = null;
|
|
139
189
|
if (detection.hasKiroDir && (strategy === 'partial' || strategy === 'full')) {
|
|
140
190
|
console.log(chalk.blue('📦 Creating backup...'));
|
|
@@ -153,7 +203,7 @@ async function adoptCommand(options = {}) {
|
|
|
153
203
|
|
|
154
204
|
console.log();
|
|
155
205
|
|
|
156
|
-
//
|
|
206
|
+
// 9. Execute adoption
|
|
157
207
|
console.log(chalk.blue('🚀 Executing adoption...'));
|
|
158
208
|
const adoptionStrategy = getAdoptionStrategy(strategy);
|
|
159
209
|
const packageJson = require('../../package.json');
|
|
@@ -166,11 +216,19 @@ async function adoptCommand(options = {}) {
|
|
|
166
216
|
|
|
167
217
|
console.log();
|
|
168
218
|
|
|
169
|
-
//
|
|
219
|
+
// 10. Report results
|
|
170
220
|
if (result.success) {
|
|
171
221
|
console.log(chalk.green('✅ Adoption completed successfully!'));
|
|
172
222
|
console.log();
|
|
173
223
|
|
|
224
|
+
if (steeringStrategy) {
|
|
225
|
+
console.log(chalk.blue('Steering Strategy:'), steeringStrategy);
|
|
226
|
+
if (steeringBackupId) {
|
|
227
|
+
console.log(chalk.gray(' Backup:'), steeringBackupId);
|
|
228
|
+
}
|
|
229
|
+
console.log();
|
|
230
|
+
}
|
|
231
|
+
|
|
174
232
|
if (result.filesCreated.length > 0) {
|
|
175
233
|
console.log(chalk.blue('Files created:'));
|
|
176
234
|
result.filesCreated.forEach(file => console.log(` + ${file}`));
|
|
@@ -198,6 +256,62 @@ async function adoptCommand(options = {}) {
|
|
|
198
256
|
console.log(chalk.gray(' Run'), chalk.cyan('kse rollback'), chalk.gray('if you need to undo changes'));
|
|
199
257
|
}
|
|
200
258
|
|
|
259
|
+
console.log();
|
|
260
|
+
|
|
261
|
+
// 11. Detect tool and offer automation setup
|
|
262
|
+
console.log(chalk.blue('🔍 Detecting your development environment...'));
|
|
263
|
+
try {
|
|
264
|
+
const toolDetection = await detectTool(projectPath);
|
|
265
|
+
const autoConfig = await generateAutoConfig(toolDetection, projectPath);
|
|
266
|
+
|
|
267
|
+
console.log();
|
|
268
|
+
console.log(chalk.blue('Tool Detected:'), chalk.cyan(toolDetection.primaryTool));
|
|
269
|
+
console.log(chalk.blue('Confidence:'), autoConfig.confidence);
|
|
270
|
+
|
|
271
|
+
if (autoConfig.notes.length > 0) {
|
|
272
|
+
console.log();
|
|
273
|
+
autoConfig.notes.forEach(note => console.log(chalk.gray(` ℹ️ ${note}`)));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Offer automation setup (unless --auto)
|
|
277
|
+
if (!auto && autoConfig.suggestedPresets.length > 0) {
|
|
278
|
+
console.log();
|
|
279
|
+
const { setupAutomation } = await inquirer.prompt([
|
|
280
|
+
{
|
|
281
|
+
type: 'confirm',
|
|
282
|
+
name: 'setupAutomation',
|
|
283
|
+
message: 'Would you like to set up automation for this tool?',
|
|
284
|
+
default: true
|
|
285
|
+
}
|
|
286
|
+
]);
|
|
287
|
+
|
|
288
|
+
if (setupAutomation) {
|
|
289
|
+
console.log();
|
|
290
|
+
console.log(chalk.blue('📋 Recommended automation setup:'));
|
|
291
|
+
console.log();
|
|
292
|
+
console.log(chalk.gray('Suggested presets:'));
|
|
293
|
+
autoConfig.suggestedPresets.forEach(preset => {
|
|
294
|
+
console.log(` - ${preset}`);
|
|
295
|
+
});
|
|
296
|
+
console.log();
|
|
297
|
+
console.log(chalk.gray('Run these commands to set up:'));
|
|
298
|
+
autoConfig.suggestedCommands.forEach(cmd => {
|
|
299
|
+
console.log(chalk.cyan(` ${cmd}`));
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
} else if (autoConfig.suggestedCommands.length > 0) {
|
|
303
|
+
console.log();
|
|
304
|
+
console.log(chalk.blue('💡 Automation setup:'));
|
|
305
|
+
autoConfig.suggestedCommands.forEach(cmd => {
|
|
306
|
+
console.log(chalk.gray(` ${cmd}`));
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
} catch (toolError) {
|
|
310
|
+
// Tool detection is optional, don't fail adoption if it errors
|
|
311
|
+
console.log(chalk.yellow('⚠️ Could not detect development tool'));
|
|
312
|
+
console.log(chalk.gray(' You can manually set up automation later'));
|
|
313
|
+
}
|
|
314
|
+
|
|
201
315
|
console.log();
|
|
202
316
|
console.log(chalk.blue('💡 Next steps:'));
|
|
203
317
|
console.log(' 1. Review the .kiro/ directory structure');
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Command
|
|
3
|
+
*
|
|
4
|
+
* Exports spec context for cross-tool usage
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const chalk = require('chalk');
|
|
8
|
+
const ContextExporter = require('../context/context-exporter');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Export spec context
|
|
12
|
+
*
|
|
13
|
+
* @param {string} specName - Spec name
|
|
14
|
+
* @param {Object} options - Command options
|
|
15
|
+
* @param {boolean} options.requirements - Include requirements (default: true)
|
|
16
|
+
* @param {boolean} options.design - Include design (default: true)
|
|
17
|
+
* @param {boolean} options.tasks - Include tasks (default: true)
|
|
18
|
+
* @param {boolean} options.steering - Include steering rules
|
|
19
|
+
* @param {string} options.steeringFiles - Comma-separated list of steering files
|
|
20
|
+
* @returns {Promise<void>}
|
|
21
|
+
*/
|
|
22
|
+
async function exportContext(specName, options = {}) {
|
|
23
|
+
const projectPath = process.cwd();
|
|
24
|
+
const exporter = new ContextExporter();
|
|
25
|
+
|
|
26
|
+
console.log(chalk.red('🔥') + ' Exporting Context');
|
|
27
|
+
console.log();
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
console.log(`Spec: ${chalk.cyan(specName)}`);
|
|
31
|
+
console.log();
|
|
32
|
+
|
|
33
|
+
// Parse options
|
|
34
|
+
const exportOptions = {
|
|
35
|
+
includeRequirements: options.requirements !== false,
|
|
36
|
+
includeDesign: options.design !== false,
|
|
37
|
+
includeTasks: options.tasks !== false,
|
|
38
|
+
includeSteering: options.steering === true,
|
|
39
|
+
steeringFiles: options.steeringFiles
|
|
40
|
+
? options.steeringFiles.split(',').map(f => f.trim())
|
|
41
|
+
: []
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
console.log('Export options:');
|
|
45
|
+
console.log(` Requirements: ${exportOptions.includeRequirements ? chalk.green('✓') : chalk.gray('✗')}`);
|
|
46
|
+
console.log(` Design: ${exportOptions.includeDesign ? chalk.green('✓') : chalk.gray('✗')}`);
|
|
47
|
+
console.log(` Tasks: ${exportOptions.includeTasks ? chalk.green('✓') : chalk.gray('✗')}`);
|
|
48
|
+
console.log(` Steering: ${exportOptions.includeSteering ? chalk.green('✓') : chalk.gray('✗')}`);
|
|
49
|
+
|
|
50
|
+
if (exportOptions.includeSteering && exportOptions.steeringFiles.length > 0) {
|
|
51
|
+
console.log(` Steering files: ${chalk.gray(exportOptions.steeringFiles.join(', '))}`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
console.log();
|
|
55
|
+
console.log('Exporting...');
|
|
56
|
+
console.log();
|
|
57
|
+
|
|
58
|
+
const result = await exporter.exportContext(
|
|
59
|
+
projectPath,
|
|
60
|
+
specName,
|
|
61
|
+
exportOptions
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
if (result.success) {
|
|
65
|
+
console.log(chalk.green('✅ Context exported successfully'));
|
|
66
|
+
console.log();
|
|
67
|
+
console.log(`Export file: ${chalk.cyan(result.exportPath)}`);
|
|
68
|
+
console.log(`Sections: ${chalk.gray(result.sections)}`);
|
|
69
|
+
console.log(`Size: ${chalk.gray(formatBytes(result.size))}`);
|
|
70
|
+
console.log();
|
|
71
|
+
console.log('Usage:');
|
|
72
|
+
console.log(' 1. Copy the exported file to your AI coding assistant');
|
|
73
|
+
console.log(' 2. Reference specific sections when working on tasks');
|
|
74
|
+
console.log(' 3. Update task status in the original tasks.md after completion');
|
|
75
|
+
} else {
|
|
76
|
+
console.log(chalk.red('❌ Export failed'));
|
|
77
|
+
console.log();
|
|
78
|
+
console.log(`Error: ${result.error}`);
|
|
79
|
+
}
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.log(chalk.red('❌ Error:'), error.message);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Format bytes to human-readable string
|
|
87
|
+
*
|
|
88
|
+
* @param {number} bytes - Bytes
|
|
89
|
+
* @returns {string} Formatted string
|
|
90
|
+
*/
|
|
91
|
+
function formatBytes(bytes) {
|
|
92
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
93
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
94
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
module.exports = {
|
|
98
|
+
exportContext
|
|
99
|
+
};
|