scene-capability-engine 3.0.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 +2513 -0
- package/LICENSE +21 -0
- package/README.md +765 -0
- package/README.zh.md +630 -0
- package/bin/kiro-spec-engine.js +796 -0
- package/bin/kse.js +3 -0
- package/bin/sce.js +3 -0
- package/bin/sco.js +3 -0
- package/docs/331-poc-adaptation-roadmap.md +156 -0
- package/docs/331-poc-dual-track-integration-guide.md +120 -0
- package/docs/331-poc-weekly-delivery-checklist.md +52 -0
- package/docs/OFFLINE_INSTALL.md +96 -0
- package/docs/README.md +279 -0
- package/docs/adopt-migration-guide.md +599 -0
- package/docs/adoption-guide.md +616 -0
- package/docs/agent-hooks-analysis.md +815 -0
- package/docs/architecture.md +733 -0
- package/docs/articles/ai-driven-development-philosophy-and-practice-review.md +208 -0
- package/docs/articles/ai-driven-development-philosophy-and-practice.en.md +459 -0
- package/docs/articles/ai-driven-development-philosophy-and-practice.md +492 -0
- package/docs/autonomous-control-guide.md +851 -0
- package/docs/command-reference.md +1368 -0
- package/docs/community.md +115 -0
- package/docs/cross-tool-guide.md +555 -0
- package/docs/developer-guide.md +619 -0
- package/docs/document-governance.md +865 -0
- package/docs/environment-management-guide.md +526 -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 +697 -0
- package/docs/handoffs/evidence/ontology/moqui-template-baseline-2026-02-17-232922.json +156 -0
- package/docs/handoffs/evidence/ontology/moqui-template-baseline-2026-02-17-232922.md +24 -0
- package/docs/images/wechat-qr.png +0 -0
- package/docs/integration-modes.md +529 -0
- package/docs/integration-philosophy.md +313 -0
- package/docs/knowledge-management-guide.md +263 -0
- package/docs/manual-workflows-guide.md +418 -0
- package/docs/moqui-capability-matrix.md +73 -0
- package/docs/moqui-template-core-library-playbook.md +109 -0
- package/docs/multi-agent-coordination-guide.md +553 -0
- package/docs/multi-repo-management-guide.md +1344 -0
- package/docs/quick-start-with-ai-tools.md +375 -0
- package/docs/quick-start.md +146 -0
- package/docs/release-checklist.md +121 -0
- package/docs/releases/README.md +13 -0
- package/docs/releases/v1.46.2-validation.md +45 -0
- package/docs/releases/v1.46.2.md +50 -0
- package/docs/scene-runtime-guide.md +347 -0
- package/docs/spec-collaboration-guide.md +369 -0
- package/docs/spec-locking-guide.md +225 -0
- package/docs/spec-numbering-guide.md +348 -0
- package/docs/spec-workflow.md +519 -0
- package/docs/steering-strategy-guide.md +196 -0
- package/docs/team-collaboration-guide.md +465 -0
- package/docs/testing-strategy.md +272 -0
- package/docs/tools/claude-guide.md +654 -0
- package/docs/tools/cursor-guide.md +706 -0
- package/docs/tools/generic-guide.md +446 -0
- package/docs/tools/kiro-guide.md +308 -0
- package/docs/tools/vscode-guide.md +445 -0
- package/docs/tools/windsurf-guide.md +391 -0
- package/docs/troubleshooting.md +1135 -0
- package/docs/upgrade-guide.md +639 -0
- package/docs/value-observability-guide.md +127 -0
- package/docs/zh/README.md +341 -0
- package/docs/zh/quick-start.md +764 -0
- package/docs/zh/release-checklist.md +121 -0
- package/docs/zh/releases/README.md +13 -0
- package/docs/zh/releases/v1.46.2-validation.md +45 -0
- package/docs/zh/releases/v1.46.2.md +50 -0
- package/docs/zh/spec-numbering-guide.md +348 -0
- package/docs/zh/tools/claude-guide.md +349 -0
- package/docs/zh/tools/cursor-guide.md +281 -0
- package/docs/zh/tools/generic-guide.md +499 -0
- package/docs/zh/tools/kiro-guide.md +342 -0
- package/docs/zh/tools/vscode-guide.md +449 -0
- package/docs/zh/tools/windsurf-guide.md +378 -0
- package/docs/zh/value-observability-guide.md +127 -0
- package/docs//344/272/244/344/273/230/346/270/205/345/215/225.md +75 -0
- package/lib/adoption/adoption-logger.js +487 -0
- package/lib/adoption/adoption-strategy.js +538 -0
- package/lib/adoption/backup-manager.js +420 -0
- package/lib/adoption/conflict-resolver.js +410 -0
- package/lib/adoption/detection-engine.js +275 -0
- package/lib/adoption/diff-viewer.js +226 -0
- package/lib/adoption/error-formatter.js +509 -0
- package/lib/adoption/file-classifier.js +385 -0
- package/lib/adoption/progress-reporter.js +534 -0
- package/lib/adoption/smart-orchestrator.js +470 -0
- package/lib/adoption/strategy-selector.js +218 -0
- package/lib/adoption/summary-generator.js +493 -0
- package/lib/adoption/template-sync.js +605 -0
- package/lib/auto/autonomous-engine.js +485 -0
- package/lib/auto/checkpoint-manager.js +300 -0
- package/lib/auto/close-loop-runner.js +2476 -0
- package/lib/auto/config-schema.js +176 -0
- package/lib/auto/decision-engine.js +344 -0
- package/lib/auto/error-recovery-manager.js +580 -0
- package/lib/auto/goal-decomposer.js +278 -0
- package/lib/auto/progress-tracker.js +502 -0
- package/lib/auto/safety-manager.js +186 -0
- package/lib/auto/semantic-decomposer.js +137 -0
- package/lib/auto/state-manager.js +126 -0
- package/lib/auto/task-queue-manager.js +340 -0
- package/lib/backup/backup-system.js +372 -0
- package/lib/backup/selective-backup.js +207 -0
- package/lib/collab/agent-registry.js +240 -0
- package/lib/collab/collab-manager.js +285 -0
- package/lib/collab/contract-manager.js +320 -0
- package/lib/collab/coordinator.js +370 -0
- package/lib/collab/dependency-manager.js +280 -0
- package/lib/collab/index.js +20 -0
- package/lib/collab/integration-manager.js +202 -0
- package/lib/collab/merge-coordinator.js +252 -0
- package/lib/collab/metadata-manager.js +233 -0
- package/lib/collab/multi-agent-config.js +120 -0
- package/lib/collab/spec-lifecycle-manager.js +304 -0
- package/lib/collab/sync-barrier.js +88 -0
- package/lib/collab/visualizer.js +208 -0
- package/lib/commands/adopt.js +749 -0
- package/lib/commands/auto.js +19559 -0
- package/lib/commands/collab.js +275 -0
- package/lib/commands/context.js +99 -0
- package/lib/commands/docs.js +808 -0
- package/lib/commands/doctor.js +273 -0
- package/lib/commands/env.js +420 -0
- package/lib/commands/knowledge.js +309 -0
- package/lib/commands/lock.js +235 -0
- package/lib/commands/ops.js +409 -0
- package/lib/commands/orchestrate.js +446 -0
- package/lib/commands/prompt.js +105 -0
- package/lib/commands/repo.js +118 -0
- package/lib/commands/rollback.js +219 -0
- package/lib/commands/scene.js +15549 -0
- package/lib/commands/spec-bootstrap.js +147 -0
- package/lib/commands/spec-gate.js +157 -0
- package/lib/commands/spec-pipeline.js +205 -0
- package/lib/commands/status.js +321 -0
- package/lib/commands/task.js +199 -0
- package/lib/commands/templates.js +654 -0
- package/lib/commands/upgrade.js +231 -0
- package/lib/commands/value.js +569 -0
- package/lib/commands/watch.js +684 -0
- package/lib/commands/workflows.js +240 -0
- package/lib/commands/workspace-multi.js +325 -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/data/moqui-capability-lexicon.json +45 -0
- package/lib/environment/backup-system.js +189 -0
- package/lib/environment/environment-manager.js +379 -0
- package/lib/environment/environment-registry.js +168 -0
- package/lib/gitignore/gitignore-backup.js +229 -0
- package/lib/gitignore/gitignore-detector.js +239 -0
- package/lib/gitignore/gitignore-integration.js +267 -0
- package/lib/gitignore/gitignore-transformer.js +193 -0
- package/lib/gitignore/layered-rules-template.js +42 -0
- package/lib/governance/archive-tool.js +284 -0
- package/lib/governance/cleanup-tool.js +237 -0
- package/lib/governance/config-manager.js +186 -0
- package/lib/governance/diagnostic-engine.js +271 -0
- package/lib/governance/doc-reference-checker.js +200 -0
- package/lib/governance/execution-logger.js +243 -0
- package/lib/governance/file-scanner.js +285 -0
- package/lib/governance/hooks-manager.js +333 -0
- package/lib/governance/reporter.js +337 -0
- package/lib/governance/validation-engine.js +181 -0
- package/lib/i18n.js +79 -0
- package/lib/knowledge/entry-manager.js +208 -0
- package/lib/knowledge/index-manager.js +261 -0
- package/lib/knowledge/knowledge-manager.js +273 -0
- package/lib/knowledge/template-manager.js +191 -0
- package/lib/lock/index.js +21 -0
- package/lib/lock/lock-file.js +192 -0
- package/lib/lock/lock-manager.js +321 -0
- package/lib/lock/machine-identifier.js +135 -0
- package/lib/lock/steering-file-lock.js +207 -0
- package/lib/lock/task-lock-manager.js +345 -0
- package/lib/operations/audit-logger.js +293 -0
- package/lib/operations/feedback-manager.js +1147 -0
- package/lib/operations/index.js +23 -0
- package/lib/operations/models/index.js +170 -0
- package/lib/operations/operations-manager.js +151 -0
- package/lib/operations/operations-validator.js +280 -0
- package/lib/operations/permission-manager.js +354 -0
- package/lib/operations/template-loader.js +143 -0
- package/lib/orchestrator/agent-spawner.js +629 -0
- package/lib/orchestrator/bootstrap-prompt-builder.js +236 -0
- package/lib/orchestrator/index.js +19 -0
- package/lib/orchestrator/orchestration-engine.js +1270 -0
- package/lib/orchestrator/orchestrator-config.js +173 -0
- package/lib/orchestrator/status-monitor.js +591 -0
- package/lib/python-checker.js +209 -0
- package/lib/repo/config-manager.js +580 -0
- package/lib/repo/errors/config-error.js +13 -0
- package/lib/repo/errors/git-error.js +15 -0
- package/lib/repo/errors/repo-error.js +14 -0
- package/lib/repo/git-operations.js +181 -0
- package/lib/repo/handlers/.gitkeep +1 -0
- package/lib/repo/handlers/exec-handler.js +155 -0
- package/lib/repo/handlers/health-handler.js +169 -0
- package/lib/repo/handlers/init-handler.js +197 -0
- package/lib/repo/handlers/status-handler.js +176 -0
- package/lib/repo/output-formatter.js +184 -0
- package/lib/repo/path-resolver.js +178 -0
- package/lib/repo/repo-manager.js +514 -0
- package/lib/scene-runtime/audit-emitter.js +59 -0
- package/lib/scene-runtime/binding-plugin-loader.js +351 -0
- package/lib/scene-runtime/binding-registry.js +349 -0
- package/lib/scene-runtime/eval-bridge.js +44 -0
- package/lib/scene-runtime/index.js +19 -0
- package/lib/scene-runtime/moqui-adapter.js +620 -0
- package/lib/scene-runtime/moqui-client.js +606 -0
- package/lib/scene-runtime/moqui-extractor.js +2029 -0
- package/lib/scene-runtime/plan-compiler.js +208 -0
- package/lib/scene-runtime/policy-gate.js +58 -0
- package/lib/scene-runtime/runtime-executor.js +358 -0
- package/lib/scene-runtime/scene-loader.js +96 -0
- package/lib/scene-runtime/scene-ontology.js +959 -0
- package/lib/scene-runtime/scene-template-linter.js +852 -0
- package/lib/scene-runtime/templates/scene-template-erp-query-v0.1.yaml +28 -0
- package/lib/scene-runtime/templates/scene-template-hybrid-shadow-v0.1.yaml +34 -0
- package/lib/spec/bootstrap/context-collector.js +48 -0
- package/lib/spec/bootstrap/draft-generator.js +158 -0
- package/lib/spec/bootstrap/questionnaire-engine.js +70 -0
- package/lib/spec/bootstrap/trace-emitter.js +59 -0
- package/lib/spec/multi-spec-orchestrate.js +93 -0
- package/lib/spec/pipeline/constants.js +6 -0
- package/lib/spec/pipeline/stage-adapters.js +118 -0
- package/lib/spec/pipeline/stage-runner.js +146 -0
- package/lib/spec/pipeline/state-store.js +119 -0
- package/lib/spec-gate/engine/gate-engine.js +165 -0
- package/lib/spec-gate/policy/default-policy.js +22 -0
- package/lib/spec-gate/policy/policy-loader.js +103 -0
- package/lib/spec-gate/result-emitter.js +81 -0
- package/lib/spec-gate/rules/default-rules.js +156 -0
- package/lib/spec-gate/rules/rule-registry.js +51 -0
- package/lib/steering/adoption-config.js +164 -0
- package/lib/steering/compliance-auto-fixer.js +204 -0
- package/lib/steering/compliance-cache.js +99 -0
- package/lib/steering/compliance-error-reporter.js +70 -0
- package/lib/steering/context-sync-manager.js +273 -0
- package/lib/steering/index.js +92 -0
- package/lib/steering/spec-steering.js +230 -0
- package/lib/steering/steering-compliance-checker.js +73 -0
- package/lib/steering/steering-loader.js +144 -0
- package/lib/steering/steering-manager.js +289 -0
- package/lib/task/index.js +12 -0
- package/lib/task/task-claimer.js +489 -0
- package/lib/task/task-status-store.js +418 -0
- package/lib/templates/cache-manager.js +440 -0
- package/lib/templates/content-generalizer.js +247 -0
- package/lib/templates/frontmatter-generator.js +128 -0
- package/lib/templates/git-handler.js +471 -0
- package/lib/templates/metadata-collector.js +328 -0
- package/lib/templates/path-utils.js +144 -0
- package/lib/templates/registry-parser.js +505 -0
- package/lib/templates/spec-reader.js +216 -0
- package/lib/templates/template-applicator.js +249 -0
- package/lib/templates/template-creator.js +256 -0
- package/lib/templates/template-error.js +143 -0
- package/lib/templates/template-exporter.js +502 -0
- package/lib/templates/template-manager.js +782 -0
- package/lib/templates/template-validator.js +361 -0
- package/lib/upgrade/migration-engine.js +382 -0
- package/lib/upgrade/migrations/.gitkeep +52 -0
- package/lib/upgrade/migrations/1.0.0-to-1.1.0.js +78 -0
- package/lib/utils/file-diff.js +177 -0
- package/lib/utils/fs-utils.js +274 -0
- package/lib/utils/tool-detector.js +383 -0
- package/lib/utils/validation.js +324 -0
- package/lib/value/gate-summary-emitter.js +99 -0
- package/lib/value/metric-contract-loader.js +210 -0
- package/lib/value/risk-evaluator.js +117 -0
- package/lib/value/weekly-snapshot-builder.js +61 -0
- package/lib/version/version-checker.js +156 -0
- package/lib/version/version-manager.js +327 -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/multi/global-config.js +150 -0
- package/lib/workspace/multi/index.js +22 -0
- package/lib/workspace/multi/path-utils.js +173 -0
- package/lib/workspace/multi/workspace-context-resolver.js +244 -0
- package/lib/workspace/multi/workspace-registry.js +196 -0
- package/lib/workspace/multi/workspace-state-manager.js +537 -0
- package/lib/workspace/multi/workspace.js +90 -0
- package/lib/workspace/workspace-manager.js +370 -0
- package/lib/workspace/workspace-sync.js +356 -0
- package/locales/en.json +114 -0
- package/locales/zh.json +114 -0
- package/package.json +102 -0
- package/template/.kiro/README.md +247 -0
- package/template/.kiro/hooks/check-spec-on-create.kiro.hook +17 -0
- package/template/.kiro/hooks/run-tests-on-save.kiro.hook +13 -0
- package/template/.kiro/hooks/sync-tasks-on-edit.kiro.hook +16 -0
- package/template/.kiro/specs/SPEC_WORKFLOW_GUIDE.md +134 -0
- package/template/.kiro/steering/CORE_PRINCIPLES.md +133 -0
- package/template/.kiro/steering/CURRENT_CONTEXT.md +30 -0
- package/template/.kiro/steering/ENVIRONMENT.md +35 -0
- package/template/.kiro/steering/RULES_GUIDE.md +46 -0
- package/template/.kiro/templates/operations/default/change-impact.md +112 -0
- package/template/.kiro/templates/operations/default/deployment.md +91 -0
- package/template/.kiro/templates/operations/default/feedback-response.md +269 -0
- package/template/.kiro/templates/operations/default/migration-plan.md +172 -0
- package/template/.kiro/templates/operations/default/monitoring.md +135 -0
- package/template/.kiro/templates/operations/default/operations.md +135 -0
- package/template/.kiro/templates/operations/default/rollback.md +143 -0
- package/template/.kiro/templates/operations/default/tools.yaml +364 -0
- package/template/.kiro/templates/operations/default/troubleshooting.md +123 -0
- 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.py +676 -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
- package/template/README.md +111 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File System Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides safe, atomic file operations for the adoption/upgrade system.
|
|
5
|
+
* Implements path validation, atomic writes, and error handling.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs-extra');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Validates that a file path is within the project directory
|
|
14
|
+
* Prevents path traversal attacks
|
|
15
|
+
*
|
|
16
|
+
* @param {string} projectPath - Absolute path to project root
|
|
17
|
+
* @param {string} filePath - Relative or absolute file path to validate
|
|
18
|
+
* @returns {string} - Validated absolute path
|
|
19
|
+
* @throws {Error} - If path traversal is detected
|
|
20
|
+
*/
|
|
21
|
+
function validatePath(projectPath, filePath) {
|
|
22
|
+
const resolvedProject = path.resolve(projectPath);
|
|
23
|
+
const resolvedFile = path.resolve(projectPath, filePath);
|
|
24
|
+
|
|
25
|
+
if (!resolvedFile.startsWith(resolvedProject)) {
|
|
26
|
+
throw new Error(`Path traversal detected: ${filePath} is outside project directory`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return resolvedFile;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Atomically writes content to a file
|
|
34
|
+
* Uses temp file + rename for atomicity
|
|
35
|
+
*
|
|
36
|
+
* @param {string} filePath - Absolute path to target file
|
|
37
|
+
* @param {string} content - Content to write
|
|
38
|
+
* @returns {Promise<void>}
|
|
39
|
+
*/
|
|
40
|
+
async function atomicWrite(filePath, content) {
|
|
41
|
+
const tempPath = `${filePath}.tmp.${Date.now()}.${Math.random().toString(36).substr(2, 9)}`;
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
// Write to temp file
|
|
45
|
+
await fs.writeFile(tempPath, content, 'utf8');
|
|
46
|
+
|
|
47
|
+
// Atomic rename (on most systems)
|
|
48
|
+
await fs.rename(tempPath, filePath);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
// Clean up temp file if it exists
|
|
51
|
+
try {
|
|
52
|
+
await fs.unlink(tempPath);
|
|
53
|
+
} catch (cleanupError) {
|
|
54
|
+
// Ignore cleanup errors
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
throw new Error(`Failed to write file atomically: ${error.message}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Safely copies a file with error handling
|
|
63
|
+
* Creates parent directories if needed
|
|
64
|
+
*
|
|
65
|
+
* @param {string} sourcePath - Absolute path to source file
|
|
66
|
+
* @param {string} destPath - Absolute path to destination file
|
|
67
|
+
* @param {Object} options - Copy options
|
|
68
|
+
* @param {boolean} options.overwrite - Whether to overwrite existing file (default: false)
|
|
69
|
+
* @returns {Promise<void>}
|
|
70
|
+
*/
|
|
71
|
+
async function safeCopy(sourcePath, destPath, options = {}) {
|
|
72
|
+
const { overwrite = false } = options;
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
// Check if source exists
|
|
76
|
+
const sourceExists = await fs.pathExists(sourcePath);
|
|
77
|
+
if (!sourceExists) {
|
|
78
|
+
throw new Error(`Source file does not exist: ${sourcePath}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Check if destination exists
|
|
82
|
+
const destExists = await fs.pathExists(destPath);
|
|
83
|
+
if (destExists && !overwrite) {
|
|
84
|
+
throw new Error(`Destination file already exists: ${destPath}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Ensure parent directory exists
|
|
88
|
+
const parentDir = path.dirname(destPath);
|
|
89
|
+
await fs.ensureDir(parentDir);
|
|
90
|
+
|
|
91
|
+
// Copy file
|
|
92
|
+
await fs.copy(sourcePath, destPath, { overwrite });
|
|
93
|
+
} catch (error) {
|
|
94
|
+
throw new Error(`Failed to copy file: ${error.message}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Recursively creates a directory
|
|
100
|
+
* Safe to call even if directory already exists
|
|
101
|
+
*
|
|
102
|
+
* @param {string} dirPath - Absolute path to directory
|
|
103
|
+
* @returns {Promise<void>}
|
|
104
|
+
*/
|
|
105
|
+
async function ensureDirectory(dirPath) {
|
|
106
|
+
try {
|
|
107
|
+
await fs.ensureDir(dirPath);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
throw new Error(`Failed to create directory: ${error.message}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Recursively copies a directory
|
|
115
|
+
*
|
|
116
|
+
* @param {string} sourceDir - Absolute path to source directory
|
|
117
|
+
* @param {string} destDir - Absolute path to destination directory
|
|
118
|
+
* @param {Object} options - Copy options
|
|
119
|
+
* @param {boolean} options.overwrite - Whether to overwrite existing files (default: false)
|
|
120
|
+
* @param {Function} options.filter - Filter function (path) => boolean
|
|
121
|
+
* @returns {Promise<void>}
|
|
122
|
+
*/
|
|
123
|
+
async function copyDirectory(sourceDir, destDir, options = {}) {
|
|
124
|
+
const { overwrite = false, filter = null } = options;
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
await fs.copy(sourceDir, destDir, {
|
|
128
|
+
overwrite,
|
|
129
|
+
filter: filter || (() => true)
|
|
130
|
+
});
|
|
131
|
+
} catch (error) {
|
|
132
|
+
throw new Error(`Failed to copy directory: ${error.message}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Checks if a path exists
|
|
138
|
+
*
|
|
139
|
+
* @param {string} filePath - Path to check
|
|
140
|
+
* @returns {Promise<boolean>}
|
|
141
|
+
*/
|
|
142
|
+
async function pathExists(filePath) {
|
|
143
|
+
return fs.pathExists(filePath);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Reads a JSON file safely
|
|
148
|
+
*
|
|
149
|
+
* @param {string} filePath - Absolute path to JSON file
|
|
150
|
+
* @returns {Promise<Object>} - Parsed JSON object
|
|
151
|
+
* @throws {Error} - If file doesn't exist or JSON is invalid
|
|
152
|
+
*/
|
|
153
|
+
async function readJSON(filePath) {
|
|
154
|
+
try {
|
|
155
|
+
return await fs.readJSON(filePath);
|
|
156
|
+
} catch (error) {
|
|
157
|
+
throw new Error(`Failed to read JSON file: ${error.message}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Writes a JSON file atomically
|
|
163
|
+
*
|
|
164
|
+
* @param {string} filePath - Absolute path to JSON file
|
|
165
|
+
* @param {Object} data - Data to write
|
|
166
|
+
* @param {Object} options - Write options
|
|
167
|
+
* @param {number} options.spaces - Number of spaces for indentation (default: 2)
|
|
168
|
+
* @returns {Promise<void>}
|
|
169
|
+
*/
|
|
170
|
+
async function writeJSON(filePath, data, options = {}) {
|
|
171
|
+
const { spaces = 2 } = options;
|
|
172
|
+
const content = JSON.stringify(data, null, spaces);
|
|
173
|
+
await atomicWrite(filePath, content);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Removes a file or directory
|
|
178
|
+
*
|
|
179
|
+
* @param {string} targetPath - Path to remove
|
|
180
|
+
* @returns {Promise<void>}
|
|
181
|
+
*/
|
|
182
|
+
async function remove(targetPath) {
|
|
183
|
+
try {
|
|
184
|
+
await fs.remove(targetPath);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
throw new Error(`Failed to remove path: ${error.message}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Gets file stats
|
|
192
|
+
*
|
|
193
|
+
* @param {string} filePath - Path to file
|
|
194
|
+
* @returns {Promise<fs.Stats>}
|
|
195
|
+
*/
|
|
196
|
+
async function getStats(filePath) {
|
|
197
|
+
try {
|
|
198
|
+
return await fs.stat(filePath);
|
|
199
|
+
} catch (error) {
|
|
200
|
+
throw new Error(`Failed to get file stats: ${error.message}`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Lists files in a directory
|
|
206
|
+
*
|
|
207
|
+
* @param {string} dirPath - Path to directory
|
|
208
|
+
* @returns {Promise<string[]>} - Array of file names
|
|
209
|
+
*/
|
|
210
|
+
async function listFiles(dirPath) {
|
|
211
|
+
try {
|
|
212
|
+
return await fs.readdir(dirPath);
|
|
213
|
+
} catch (error) {
|
|
214
|
+
throw new Error(`Failed to list directory: ${error.message}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Recursively lists all files in a directory
|
|
220
|
+
*
|
|
221
|
+
* @param {string} dirPath - Path to directory
|
|
222
|
+
* @param {string[]} fileList - Accumulator for recursive calls
|
|
223
|
+
* @returns {Promise<string[]>} - Array of absolute file paths
|
|
224
|
+
*/
|
|
225
|
+
async function listFilesRecursive(dirPath, fileList = []) {
|
|
226
|
+
const files = await fs.readdir(dirPath);
|
|
227
|
+
|
|
228
|
+
for (const file of files) {
|
|
229
|
+
const filePath = path.join(dirPath, file);
|
|
230
|
+
const stat = await fs.stat(filePath);
|
|
231
|
+
|
|
232
|
+
if (stat.isDirectory()) {
|
|
233
|
+
await listFilesRecursive(filePath, fileList);
|
|
234
|
+
} else {
|
|
235
|
+
fileList.push(filePath);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return fileList;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Calculates total size of a directory
|
|
244
|
+
*
|
|
245
|
+
* @param {string} dirPath - Path to directory
|
|
246
|
+
* @returns {Promise<number>} - Total size in bytes
|
|
247
|
+
*/
|
|
248
|
+
async function getDirectorySize(dirPath) {
|
|
249
|
+
const files = await listFilesRecursive(dirPath);
|
|
250
|
+
let totalSize = 0;
|
|
251
|
+
|
|
252
|
+
for (const file of files) {
|
|
253
|
+
const stats = await fs.stat(file);
|
|
254
|
+
totalSize += stats.size;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return totalSize;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
module.exports = {
|
|
261
|
+
validatePath,
|
|
262
|
+
atomicWrite,
|
|
263
|
+
safeCopy,
|
|
264
|
+
ensureDirectory,
|
|
265
|
+
copyDirectory,
|
|
266
|
+
pathExists,
|
|
267
|
+
readJSON,
|
|
268
|
+
writeJSON,
|
|
269
|
+
remove,
|
|
270
|
+
getStats,
|
|
271
|
+
listFiles,
|
|
272
|
+
listFilesRecursive,
|
|
273
|
+
getDirectorySize
|
|
274
|
+
};
|
|
@@ -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
|
+
};
|