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,273 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const pythonChecker = require('../python-checker');
|
|
3
|
+
const { getI18n } = require('../i18n');
|
|
4
|
+
const DiagnosticEngine = require('../governance/diagnostic-engine');
|
|
5
|
+
const ConfigManager = require('../governance/config-manager');
|
|
6
|
+
const GitignoreIntegration = require('../gitignore/gitignore-integration');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* CLI Doctor Command Component
|
|
11
|
+
*
|
|
12
|
+
* Verifies system requirements and provides diagnostics.
|
|
13
|
+
* Checks Node.js version, Python availability, and document compliance.
|
|
14
|
+
*
|
|
15
|
+
* Requirements: 7.5, 10.2
|
|
16
|
+
*/
|
|
17
|
+
async function doctorCommand(options = {}) {
|
|
18
|
+
const i18n = getI18n();
|
|
19
|
+
|
|
20
|
+
// Handle --fix-gitignore flag
|
|
21
|
+
if (options.fixGitignore) {
|
|
22
|
+
return await fixGitignoreCommand();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
console.log(chalk.red('🔥') + ' ' + i18n.t('cli.commands.doctor.title'));
|
|
26
|
+
console.log();
|
|
27
|
+
console.log(i18n.t('cli.commands.doctor.checking'));
|
|
28
|
+
console.log();
|
|
29
|
+
|
|
30
|
+
// Check Node.js version
|
|
31
|
+
const nodeVersion = process.version;
|
|
32
|
+
const nodeStatus = chalk.green('✓');
|
|
33
|
+
console.log(`${nodeStatus} ${i18n.t('cli.commands.doctor.nodejs')}: ${chalk.cyan(nodeVersion)}`);
|
|
34
|
+
|
|
35
|
+
// Check Python availability
|
|
36
|
+
const pythonStatus = pythonChecker.checkPython();
|
|
37
|
+
|
|
38
|
+
if (pythonStatus.available) {
|
|
39
|
+
const pythonOk = chalk.green('✓');
|
|
40
|
+
console.log(`${pythonOk} ${i18n.t('cli.commands.doctor.python')}: ${chalk.cyan(pythonStatus.version)}`);
|
|
41
|
+
} else {
|
|
42
|
+
const pythonFail = chalk.red('✗');
|
|
43
|
+
console.log(`${pythonFail} ${i18n.t('cli.commands.doctor.python')}: ${chalk.yellow(pythonStatus.message)}`);
|
|
44
|
+
console.log();
|
|
45
|
+
console.log(chalk.yellow(i18n.t('cli.commands.doctor.python_note')));
|
|
46
|
+
console.log();
|
|
47
|
+
console.log(chalk.blue(i18n.t('python.install_header')));
|
|
48
|
+
console.log(pythonChecker.getInstallInstructions());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.log();
|
|
52
|
+
console.log(chalk.blue('─'.repeat(60)));
|
|
53
|
+
console.log();
|
|
54
|
+
|
|
55
|
+
// Check document compliance
|
|
56
|
+
await checkDocumentCompliance(options);
|
|
57
|
+
|
|
58
|
+
console.log();
|
|
59
|
+
console.log(chalk.blue('─'.repeat(60)));
|
|
60
|
+
console.log();
|
|
61
|
+
|
|
62
|
+
// Summary
|
|
63
|
+
if (pythonStatus.available) {
|
|
64
|
+
console.log(chalk.green('✅ ' + i18n.t('cli.commands.doctor.all_good')));
|
|
65
|
+
console.log(i18n.t('cli.commands.doctor.ready'));
|
|
66
|
+
} else {
|
|
67
|
+
console.log(chalk.yellow('⚠️ ' + i18n.t('cli.commands.doctor.python_missing')));
|
|
68
|
+
console.log(i18n.t('cli.commands.doctor.basic_features'));
|
|
69
|
+
console.log(i18n.t('cli.commands.doctor.ultrawork_unavailable'));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.log();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Check document compliance
|
|
77
|
+
*
|
|
78
|
+
* @param {Object} options - Command options
|
|
79
|
+
* @param {boolean} options.docs - Whether to show detailed diagnostics
|
|
80
|
+
*/
|
|
81
|
+
async function checkDocumentCompliance(options = {}) {
|
|
82
|
+
try {
|
|
83
|
+
const projectPath = process.cwd();
|
|
84
|
+
|
|
85
|
+
// Load configuration
|
|
86
|
+
const configManager = new ConfigManager(projectPath);
|
|
87
|
+
const config = await configManager.load();
|
|
88
|
+
|
|
89
|
+
// Run diagnostic scan
|
|
90
|
+
const diagnosticEngine = new DiagnosticEngine(projectPath, config);
|
|
91
|
+
const report = await diagnosticEngine.scan();
|
|
92
|
+
|
|
93
|
+
// Display results based on options
|
|
94
|
+
if (options.docs) {
|
|
95
|
+
// Detailed diagnostics mode
|
|
96
|
+
displayDetailedDiagnostics(report);
|
|
97
|
+
} else {
|
|
98
|
+
// Brief compliance status
|
|
99
|
+
displayBriefCompliance(report);
|
|
100
|
+
}
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.log(chalk.yellow('⚠️ Document compliance check failed:'), error.message);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Display brief document compliance status
|
|
108
|
+
*
|
|
109
|
+
* @param {Object} report - Diagnostic report
|
|
110
|
+
*/
|
|
111
|
+
function displayBriefCompliance(report) {
|
|
112
|
+
console.log(chalk.bold('Document Compliance:'));
|
|
113
|
+
|
|
114
|
+
if (report.compliant) {
|
|
115
|
+
console.log(chalk.green(' ✓ All documents follow lifecycle management rules'));
|
|
116
|
+
} else {
|
|
117
|
+
const errorCount = report.summary.bySeverity.error || 0;
|
|
118
|
+
const warningCount = report.summary.bySeverity.warning || 0;
|
|
119
|
+
|
|
120
|
+
if (errorCount > 0) {
|
|
121
|
+
console.log(chalk.red(` ✗ ${errorCount} error(s) found`));
|
|
122
|
+
}
|
|
123
|
+
if (warningCount > 0) {
|
|
124
|
+
console.log(chalk.yellow(` ⚠ ${warningCount} warning(s) found`));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
console.log(chalk.cyan(` → Run 'kse doctor --docs' for detailed diagnostics`));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Display detailed document diagnostics
|
|
133
|
+
*
|
|
134
|
+
* @param {Object} report - Diagnostic report
|
|
135
|
+
*/
|
|
136
|
+
function displayDetailedDiagnostics(report) {
|
|
137
|
+
console.log(chalk.bold.cyan('Document Governance Diagnostic:'));
|
|
138
|
+
console.log();
|
|
139
|
+
|
|
140
|
+
if (report.compliant) {
|
|
141
|
+
console.log(chalk.green(' ✅ Project is compliant'));
|
|
142
|
+
console.log(' All documents follow the lifecycle management rules.');
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
console.log(chalk.yellow(` ⚠️ Found ${report.violations.length} violation(s)`));
|
|
147
|
+
console.log();
|
|
148
|
+
|
|
149
|
+
// Group violations by type
|
|
150
|
+
const byType = groupBy(report.violations, 'type');
|
|
151
|
+
|
|
152
|
+
for (const [type, violations] of Object.entries(byType)) {
|
|
153
|
+
console.log(chalk.blue(` ${formatType(type)} (${violations.length})`));
|
|
154
|
+
|
|
155
|
+
for (const violation of violations) {
|
|
156
|
+
const icon = violation.severity === 'error' ? '❌' : '⚠️';
|
|
157
|
+
const relativePath = path.relative(process.cwd(), violation.path);
|
|
158
|
+
console.log(` ${icon} ${chalk.gray(relativePath)}`);
|
|
159
|
+
console.log(` ${violation.description}`);
|
|
160
|
+
console.log(` ${chalk.cyan('→ ' + violation.recommendation)}`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
console.log();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Display recommendations
|
|
167
|
+
if (report.recommendations && report.recommendations.length > 0) {
|
|
168
|
+
console.log(chalk.blue(' 💡 Recommended Actions:'));
|
|
169
|
+
report.recommendations.forEach(rec => {
|
|
170
|
+
console.log(` • ${rec}`);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Helper: Group array by property
|
|
177
|
+
*
|
|
178
|
+
* @param {Array} array - Array to group
|
|
179
|
+
* @param {string} property - Property to group by
|
|
180
|
+
* @returns {Object} - Grouped object
|
|
181
|
+
*/
|
|
182
|
+
function groupBy(array, property) {
|
|
183
|
+
return array.reduce((acc, item) => {
|
|
184
|
+
const key = item[property];
|
|
185
|
+
if (!acc[key]) acc[key] = [];
|
|
186
|
+
acc[key].push(item);
|
|
187
|
+
return acc;
|
|
188
|
+
}, {});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Helper: Format violation type
|
|
193
|
+
*
|
|
194
|
+
* @param {string} type - Violation type
|
|
195
|
+
* @returns {string} - Formatted type
|
|
196
|
+
*/
|
|
197
|
+
function formatType(type) {
|
|
198
|
+
return type.split('_').map(word =>
|
|
199
|
+
word.charAt(0).toUpperCase() + word.slice(1)
|
|
200
|
+
).join(' ');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Fix .gitignore for team collaboration
|
|
205
|
+
*
|
|
206
|
+
* Standalone command to check and fix .gitignore configuration.
|
|
207
|
+
* Replaces old blanket .kiro/ exclusion with layered strategy.
|
|
208
|
+
*/
|
|
209
|
+
async function fixGitignoreCommand() {
|
|
210
|
+
console.log(chalk.cyan('🔧 Checking .gitignore configuration...'));
|
|
211
|
+
console.log();
|
|
212
|
+
|
|
213
|
+
try {
|
|
214
|
+
const projectPath = process.cwd();
|
|
215
|
+
const gitignoreIntegration = new GitignoreIntegration();
|
|
216
|
+
|
|
217
|
+
const result = await gitignoreIntegration.runDoctor(projectPath);
|
|
218
|
+
|
|
219
|
+
if (result.success) {
|
|
220
|
+
if (result.action === 'skipped') {
|
|
221
|
+
console.log(chalk.green('✅ .gitignore is already configured correctly'));
|
|
222
|
+
console.log();
|
|
223
|
+
console.log('Your .gitignore uses the layered strategy for team collaboration.');
|
|
224
|
+
console.log('No changes needed.');
|
|
225
|
+
} else {
|
|
226
|
+
console.log(chalk.green(`✅ .gitignore ${result.action} successfully`));
|
|
227
|
+
console.log();
|
|
228
|
+
console.log(result.message);
|
|
229
|
+
|
|
230
|
+
if (result.backupId) {
|
|
231
|
+
console.log();
|
|
232
|
+
console.log(chalk.blue('💾 Backup created:'), chalk.gray(result.backupId));
|
|
233
|
+
console.log(chalk.gray(' You can restore with: kse rollback ' + result.backupId));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (result.added && result.added.length > 0) {
|
|
237
|
+
console.log();
|
|
238
|
+
console.log(chalk.blue('Added rules:'));
|
|
239
|
+
result.added.forEach(rule => {
|
|
240
|
+
console.log(chalk.gray(' + ' + rule));
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (result.removed && result.removed.length > 0) {
|
|
245
|
+
console.log();
|
|
246
|
+
console.log(chalk.blue('Removed rules:'));
|
|
247
|
+
result.removed.forEach(rule => {
|
|
248
|
+
console.log(chalk.gray(' - ' + rule));
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
console.log();
|
|
254
|
+
console.log(chalk.cyan('📖 Learn more:'), 'docs/team-collaboration-guide.md');
|
|
255
|
+
} else {
|
|
256
|
+
console.log(chalk.red('❌ Failed to fix .gitignore'));
|
|
257
|
+
console.log();
|
|
258
|
+
console.log(chalk.yellow(result.message));
|
|
259
|
+
console.log();
|
|
260
|
+
console.log(chalk.cyan('💡 Manual fix:'));
|
|
261
|
+
console.log(' See docs/team-collaboration-guide.md for instructions');
|
|
262
|
+
}
|
|
263
|
+
} catch (error) {
|
|
264
|
+
console.log(chalk.red('❌ Error:'), error.message);
|
|
265
|
+
console.log();
|
|
266
|
+
console.log(chalk.cyan('💡 Manual fix:'));
|
|
267
|
+
console.log(' See docs/team-collaboration-guide.md for instructions');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
console.log();
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
module.exports = doctorCommand;
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const EnvironmentManager = require('../environment/environment-manager');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Environment CLI
|
|
8
|
+
*
|
|
9
|
+
* Command-line interface for environment management operations.
|
|
10
|
+
*/
|
|
11
|
+
class EnvironmentCLI {
|
|
12
|
+
/**
|
|
13
|
+
* Handle env command
|
|
14
|
+
* @param {Array} args - Command arguments
|
|
15
|
+
* @returns {Promise<number>} Exit code
|
|
16
|
+
*/
|
|
17
|
+
static async handleCommand(args) {
|
|
18
|
+
const subcommand = args[0];
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
switch (subcommand) {
|
|
22
|
+
case 'list':
|
|
23
|
+
return await this.handleList(args.slice(1));
|
|
24
|
+
case 'switch':
|
|
25
|
+
return await this.handleSwitch(args.slice(1));
|
|
26
|
+
case 'info':
|
|
27
|
+
return await this.handleInfo(args.slice(1));
|
|
28
|
+
case 'register':
|
|
29
|
+
return await this.handleRegister(args.slice(1));
|
|
30
|
+
case 'unregister':
|
|
31
|
+
return await this.handleUnregister(args.slice(1));
|
|
32
|
+
case 'rollback':
|
|
33
|
+
return await this.handleRollback(args.slice(1));
|
|
34
|
+
case 'verify':
|
|
35
|
+
return await this.handleVerify(args.slice(1));
|
|
36
|
+
case 'run':
|
|
37
|
+
return await this.handleRun(args.slice(1));
|
|
38
|
+
default:
|
|
39
|
+
this.displayHelp();
|
|
40
|
+
return 1;
|
|
41
|
+
}
|
|
42
|
+
} catch (error) {
|
|
43
|
+
this.displayError(error);
|
|
44
|
+
return 1;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Handle list command
|
|
50
|
+
* @param {Array} args - Command arguments
|
|
51
|
+
* @returns {Promise<number>} Exit code
|
|
52
|
+
*/
|
|
53
|
+
static async handleList(args) {
|
|
54
|
+
const projectRoot = process.cwd();
|
|
55
|
+
const manager = new EnvironmentManager(projectRoot);
|
|
56
|
+
|
|
57
|
+
const environments = await manager.listEnvironments();
|
|
58
|
+
|
|
59
|
+
if (environments.length === 0) {
|
|
60
|
+
console.log(chalk.yellow('\nNo environments registered.'));
|
|
61
|
+
console.log(chalk.gray('\nTo register an environment, create a configuration file and run:'));
|
|
62
|
+
console.log(chalk.gray(' kse env register <config-file>'));
|
|
63
|
+
console.log();
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
console.log(chalk.bold('\nRegistered Environments:\n'));
|
|
68
|
+
|
|
69
|
+
for (const env of environments) {
|
|
70
|
+
const prefix = env.isActive ? chalk.green('● ') : chalk.gray('○ ');
|
|
71
|
+
const name = env.isActive ? chalk.green.bold(env.name) : chalk.white(env.name);
|
|
72
|
+
const status = env.isActive ? chalk.green(' (active)') : '';
|
|
73
|
+
|
|
74
|
+
console.log(`${prefix}${name}${status}`);
|
|
75
|
+
console.log(chalk.gray(` ${env.description}`));
|
|
76
|
+
console.log(chalk.gray(` Config files: ${env.configFilesCount}`));
|
|
77
|
+
if (env.hasVerification) {
|
|
78
|
+
console.log(chalk.gray(` Verification: enabled`));
|
|
79
|
+
}
|
|
80
|
+
console.log();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Handle switch command
|
|
88
|
+
* @param {Array} args - Command arguments
|
|
89
|
+
* @returns {Promise<number>} Exit code
|
|
90
|
+
*/
|
|
91
|
+
static async handleSwitch(args) {
|
|
92
|
+
const environmentName = args[0];
|
|
93
|
+
|
|
94
|
+
if (!environmentName) {
|
|
95
|
+
console.log(chalk.red('\nError: Environment name is required'));
|
|
96
|
+
console.log(chalk.gray('\nUsage: kse env switch <name>'));
|
|
97
|
+
console.log();
|
|
98
|
+
return 1;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const projectRoot = process.cwd();
|
|
102
|
+
const manager = new EnvironmentManager(projectRoot);
|
|
103
|
+
|
|
104
|
+
console.log(chalk.gray(`\nSwitching to environment: ${environmentName}...`));
|
|
105
|
+
|
|
106
|
+
const result = await manager.switchEnvironment(environmentName);
|
|
107
|
+
|
|
108
|
+
if (result.success) {
|
|
109
|
+
console.log(chalk.green('\n✓ Environment switched successfully!'));
|
|
110
|
+
console.log();
|
|
111
|
+
console.log(chalk.gray(` Previous: ${result.previous_environment || 'none'}`));
|
|
112
|
+
console.log(chalk.gray(` Current: ${result.new_environment}`));
|
|
113
|
+
console.log(chalk.gray(` Files copied: ${result.files_copied}`));
|
|
114
|
+
if (result.backup_created) {
|
|
115
|
+
console.log(chalk.gray(` Backup created: ${result.backup_location}`));
|
|
116
|
+
}
|
|
117
|
+
console.log();
|
|
118
|
+
return 0;
|
|
119
|
+
} else {
|
|
120
|
+
console.log(chalk.red('\n✗ Environment switch failed:'));
|
|
121
|
+
for (const error of result.errors) {
|
|
122
|
+
console.log(chalk.red(` ${error}`));
|
|
123
|
+
}
|
|
124
|
+
console.log();
|
|
125
|
+
return 1;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Handle info command
|
|
131
|
+
* @param {Array} args - Command arguments
|
|
132
|
+
* @returns {Promise<number>} Exit code
|
|
133
|
+
*/
|
|
134
|
+
static async handleInfo(args) {
|
|
135
|
+
const projectRoot = process.cwd();
|
|
136
|
+
const manager = new EnvironmentManager(projectRoot);
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
const env = await manager.getActiveEnvironment();
|
|
140
|
+
|
|
141
|
+
console.log(chalk.bold('\nActive Environment:\n'));
|
|
142
|
+
console.log(chalk.green.bold(` ${env.name}`));
|
|
143
|
+
console.log(chalk.gray(` ${env.description}`));
|
|
144
|
+
console.log();
|
|
145
|
+
|
|
146
|
+
console.log(chalk.bold('Configuration Files:'));
|
|
147
|
+
for (const mapping of env.config_files) {
|
|
148
|
+
console.log(chalk.gray(` ${mapping.source} → ${mapping.target}`));
|
|
149
|
+
}
|
|
150
|
+
console.log();
|
|
151
|
+
|
|
152
|
+
if (env.verification) {
|
|
153
|
+
console.log(chalk.bold('Verification:'));
|
|
154
|
+
console.log(chalk.gray(` Command: ${env.verification.command}`));
|
|
155
|
+
console.log(chalk.gray(` Expected: ${env.verification.expected_output}`));
|
|
156
|
+
console.log();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return 0;
|
|
160
|
+
} catch (error) {
|
|
161
|
+
if (error.message.includes('No active environment')) {
|
|
162
|
+
console.log(chalk.yellow('\nNo active environment.'));
|
|
163
|
+
console.log(chalk.gray('\nTo activate an environment, run:'));
|
|
164
|
+
console.log(chalk.gray(' kse env switch <name>'));
|
|
165
|
+
console.log();
|
|
166
|
+
return 0;
|
|
167
|
+
}
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Handle register command
|
|
174
|
+
* @param {Array} args - Command arguments
|
|
175
|
+
* @returns {Promise<number>} Exit code
|
|
176
|
+
*/
|
|
177
|
+
static async handleRegister(args) {
|
|
178
|
+
const configFile = args[0];
|
|
179
|
+
|
|
180
|
+
if (!configFile) {
|
|
181
|
+
console.log(chalk.red('\nError: Configuration file is required'));
|
|
182
|
+
console.log(chalk.gray('\nUsage: kse env register <config-file>'));
|
|
183
|
+
console.log();
|
|
184
|
+
return 1;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const projectRoot = process.cwd();
|
|
188
|
+
const configPath = path.resolve(projectRoot, configFile);
|
|
189
|
+
|
|
190
|
+
if (!await fs.pathExists(configPath)) {
|
|
191
|
+
console.log(chalk.red(`\nError: Configuration file not found: ${configFile}`));
|
|
192
|
+
console.log();
|
|
193
|
+
return 1;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
const configContent = await fs.readFile(configPath, 'utf8');
|
|
198
|
+
const config = JSON.parse(configContent);
|
|
199
|
+
|
|
200
|
+
const manager = new EnvironmentManager(projectRoot);
|
|
201
|
+
const result = await manager.registerEnvironment(config);
|
|
202
|
+
|
|
203
|
+
console.log(chalk.green(`\n✓ ${result.message}`));
|
|
204
|
+
console.log();
|
|
205
|
+
return 0;
|
|
206
|
+
} catch (error) {
|
|
207
|
+
if (error.name === 'SyntaxError') {
|
|
208
|
+
console.log(chalk.red('\nError: Invalid JSON in configuration file'));
|
|
209
|
+
console.log(chalk.red(` ${error.message}`));
|
|
210
|
+
console.log();
|
|
211
|
+
return 1;
|
|
212
|
+
}
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Handle unregister command
|
|
219
|
+
* @param {Array} args - Command arguments
|
|
220
|
+
* @returns {Promise<number>} Exit code
|
|
221
|
+
*/
|
|
222
|
+
static async handleUnregister(args) {
|
|
223
|
+
const environmentName = args[0];
|
|
224
|
+
const force = args.includes('--force') || args.includes('-f');
|
|
225
|
+
|
|
226
|
+
if (!environmentName) {
|
|
227
|
+
console.log(chalk.red('\nError: Environment name is required'));
|
|
228
|
+
console.log(chalk.gray('\nUsage: kse env unregister <name> [--force]'));
|
|
229
|
+
console.log();
|
|
230
|
+
return 1;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (!force) {
|
|
234
|
+
console.log(chalk.yellow(`\nAre you sure you want to unregister "${environmentName}"?`));
|
|
235
|
+
console.log(chalk.gray('This action cannot be undone.'));
|
|
236
|
+
console.log(chalk.gray('\nUse --force to skip this confirmation.'));
|
|
237
|
+
console.log();
|
|
238
|
+
return 1;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const projectRoot = process.cwd();
|
|
242
|
+
const manager = new EnvironmentManager(projectRoot);
|
|
243
|
+
|
|
244
|
+
const result = await manager.unregisterEnvironment(environmentName);
|
|
245
|
+
|
|
246
|
+
console.log(chalk.green(`\n✓ ${result.message}`));
|
|
247
|
+
console.log();
|
|
248
|
+
return 0;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Handle rollback command
|
|
253
|
+
* @param {Array} args - Command arguments
|
|
254
|
+
* @returns {Promise<number>} Exit code
|
|
255
|
+
*/
|
|
256
|
+
static async handleRollback(args) {
|
|
257
|
+
const projectRoot = process.cwd();
|
|
258
|
+
const manager = new EnvironmentManager(projectRoot);
|
|
259
|
+
|
|
260
|
+
console.log(chalk.gray('\nRestoring from backup...'));
|
|
261
|
+
|
|
262
|
+
try {
|
|
263
|
+
const result = await manager.rollbackEnvironment();
|
|
264
|
+
|
|
265
|
+
console.log(chalk.green('\n✓ Rollback successful!'));
|
|
266
|
+
console.log();
|
|
267
|
+
console.log(chalk.gray(` Environment: ${result.environment_name}`));
|
|
268
|
+
console.log(chalk.gray(` Files restored: ${result.files_restored}`));
|
|
269
|
+
console.log(chalk.gray(` Backup timestamp: ${result.backup_timestamp}`));
|
|
270
|
+
console.log();
|
|
271
|
+
return 0;
|
|
272
|
+
} catch (error) {
|
|
273
|
+
console.log(chalk.red('\n✗ Rollback failed:'));
|
|
274
|
+
console.log(chalk.red(` ${error.message}`));
|
|
275
|
+
console.log();
|
|
276
|
+
return 1;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Handle verify command
|
|
282
|
+
* @param {Array} args - Command arguments
|
|
283
|
+
* @returns {Promise<number>} Exit code
|
|
284
|
+
*/
|
|
285
|
+
static async handleVerify(args) {
|
|
286
|
+
const projectRoot = process.cwd();
|
|
287
|
+
const manager = new EnvironmentManager(projectRoot);
|
|
288
|
+
|
|
289
|
+
console.log(chalk.gray('\nVerifying environment configuration...'));
|
|
290
|
+
|
|
291
|
+
try {
|
|
292
|
+
const result = await manager.verifyEnvironment();
|
|
293
|
+
|
|
294
|
+
if (result.success) {
|
|
295
|
+
console.log(chalk.green('\n✓ Environment verification passed!'));
|
|
296
|
+
console.log();
|
|
297
|
+
console.log(chalk.gray(` Environment: ${result.environment_name}`));
|
|
298
|
+
if (result.command) {
|
|
299
|
+
console.log(chalk.gray(` Command: ${result.command}`));
|
|
300
|
+
console.log(chalk.gray(` Expected: ${result.expected_output}`));
|
|
301
|
+
console.log(chalk.gray(` Actual: ${result.actual_output}`));
|
|
302
|
+
} else {
|
|
303
|
+
console.log(chalk.gray(' No verification rules configured'));
|
|
304
|
+
}
|
|
305
|
+
console.log();
|
|
306
|
+
return 0;
|
|
307
|
+
} else {
|
|
308
|
+
console.log(chalk.red('\n✗ Environment verification failed!'));
|
|
309
|
+
console.log();
|
|
310
|
+
console.log(chalk.gray(` Environment: ${result.environment_name}`));
|
|
311
|
+
console.log(chalk.gray(` Command: ${result.command}`));
|
|
312
|
+
console.log(chalk.red(` Expected: ${result.expected_output}`));
|
|
313
|
+
console.log(chalk.red(` Actual: ${result.actual_output}`));
|
|
314
|
+
if (result.error) {
|
|
315
|
+
console.log(chalk.red(` Error: ${result.error}`));
|
|
316
|
+
}
|
|
317
|
+
console.log();
|
|
318
|
+
return 1;
|
|
319
|
+
}
|
|
320
|
+
} catch (error) {
|
|
321
|
+
console.log(chalk.red('\n✗ Verification failed:'));
|
|
322
|
+
console.log(chalk.red(` ${error.message}`));
|
|
323
|
+
console.log();
|
|
324
|
+
return 1;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Handle run command
|
|
330
|
+
* @param {Array} args - Command arguments
|
|
331
|
+
* @returns {Promise<number>} Exit code
|
|
332
|
+
*/
|
|
333
|
+
static async handleRun(args) {
|
|
334
|
+
const command = args.join(' ');
|
|
335
|
+
|
|
336
|
+
if (!command) {
|
|
337
|
+
console.log(chalk.red('\nError: Command is required'));
|
|
338
|
+
console.log(chalk.gray('\nUsage: kse env run "<command>"'));
|
|
339
|
+
console.log();
|
|
340
|
+
return 1;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const projectRoot = process.cwd();
|
|
344
|
+
const manager = new EnvironmentManager(projectRoot);
|
|
345
|
+
|
|
346
|
+
try {
|
|
347
|
+
const env = await manager.getActiveEnvironment();
|
|
348
|
+
console.log(chalk.gray(`\nRunning command in environment: ${env.name}`));
|
|
349
|
+
console.log(chalk.gray(`Command: ${command}\n`));
|
|
350
|
+
|
|
351
|
+
const result = await manager.runInEnvironment(command);
|
|
352
|
+
|
|
353
|
+
if (result.output) {
|
|
354
|
+
console.log(result.output);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (result.success) {
|
|
358
|
+
console.log(chalk.green(`\n✓ Command completed successfully (exit code: ${result.exit_code})`));
|
|
359
|
+
console.log();
|
|
360
|
+
return 0;
|
|
361
|
+
} else {
|
|
362
|
+
console.log(chalk.red(`\n✗ Command failed (exit code: ${result.exit_code})`));
|
|
363
|
+
if (result.error) {
|
|
364
|
+
console.log(chalk.red(`Error: ${result.error}`));
|
|
365
|
+
}
|
|
366
|
+
console.log();
|
|
367
|
+
return 1;
|
|
368
|
+
}
|
|
369
|
+
} catch (error) {
|
|
370
|
+
console.log(chalk.red('\n✗ Command execution failed:'));
|
|
371
|
+
console.log(chalk.red(` ${error.message}`));
|
|
372
|
+
console.log();
|
|
373
|
+
return 1;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Display help message
|
|
379
|
+
*/
|
|
380
|
+
static displayHelp() {
|
|
381
|
+
console.log(chalk.bold('\nEnvironment Management Commands:\n'));
|
|
382
|
+
console.log(chalk.white(' kse env list') + chalk.gray(' List all environments'));
|
|
383
|
+
console.log(chalk.white(' kse env switch <name>') + chalk.gray(' Switch to environment'));
|
|
384
|
+
console.log(chalk.white(' kse env info') + chalk.gray(' Show active environment details'));
|
|
385
|
+
console.log(chalk.white(' kse env register <config-file>') + chalk.gray(' Register new environment'));
|
|
386
|
+
console.log(chalk.white(' kse env unregister <name>') + chalk.gray(' Remove environment'));
|
|
387
|
+
console.log(chalk.white(' kse env rollback') + chalk.gray(' Restore from backup'));
|
|
388
|
+
console.log(chalk.white(' kse env verify') + chalk.gray(' Verify environment configuration'));
|
|
389
|
+
console.log(chalk.white(' kse env run "<command>"') + chalk.gray(' Run command in environment'));
|
|
390
|
+
console.log();
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Display error message
|
|
395
|
+
* @param {Error} error - Error object
|
|
396
|
+
*/
|
|
397
|
+
static displayError(error) {
|
|
398
|
+
console.log(chalk.red('\n✗ Error:'));
|
|
399
|
+
console.log(chalk.red(` ${error.message}`));
|
|
400
|
+
console.log();
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Display success message
|
|
405
|
+
* @param {string} message - Success message
|
|
406
|
+
* @param {Object} details - Optional details object
|
|
407
|
+
*/
|
|
408
|
+
static displaySuccess(message, details = {}) {
|
|
409
|
+
console.log(chalk.green(`\n✓ ${message}`));
|
|
410
|
+
if (Object.keys(details).length > 0) {
|
|
411
|
+
console.log();
|
|
412
|
+
for (const [key, value] of Object.entries(details)) {
|
|
413
|
+
console.log(chalk.gray(` ${key}: ${value}`));
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
console.log();
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
module.exports = EnvironmentCLI;
|