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,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Management CLI Commands
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const KnowledgeManager = require('../knowledge/knowledge-manager');
|
|
6
|
+
const chalk = require('chalk');
|
|
7
|
+
const Table = require('cli-table3');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Register knowledge commands
|
|
11
|
+
* @param {Object} program - Commander program
|
|
12
|
+
*/
|
|
13
|
+
function registerKnowledgeCommands(program) {
|
|
14
|
+
const knowledge = program
|
|
15
|
+
.command('knowledge')
|
|
16
|
+
.alias('kb')
|
|
17
|
+
.description('Manage personal knowledge base');
|
|
18
|
+
|
|
19
|
+
// kse knowledge init
|
|
20
|
+
knowledge
|
|
21
|
+
.command('init')
|
|
22
|
+
.description('Initialize knowledge base')
|
|
23
|
+
.action(async () => {
|
|
24
|
+
try {
|
|
25
|
+
const manager = new KnowledgeManager(process.cwd());
|
|
26
|
+
|
|
27
|
+
if (await manager.isInitialized()) {
|
|
28
|
+
console.log(chalk.yellow('⚠ Knowledge base already initialized'));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
console.log(chalk.blue('Initializing knowledge base...'));
|
|
33
|
+
await manager.initialize();
|
|
34
|
+
|
|
35
|
+
console.log(chalk.green('✓ Knowledge base initialized'));
|
|
36
|
+
console.log(chalk.gray('\nDirectory: .kiro/knowledge/'));
|
|
37
|
+
console.log(chalk.gray('\nNext steps:'));
|
|
38
|
+
console.log(chalk.gray(' kse knowledge add pattern "My First Pattern"'));
|
|
39
|
+
console.log(chalk.gray(' kse knowledge list'));
|
|
40
|
+
console.log(chalk.gray(' kse knowledge --help'));
|
|
41
|
+
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// kse knowledge add
|
|
49
|
+
knowledge
|
|
50
|
+
.command('add <type> <title>')
|
|
51
|
+
.description('Add new knowledge entry')
|
|
52
|
+
.option('-t, --tags <tags>', 'Comma-separated tags')
|
|
53
|
+
.option('-c, --category <category>', 'Entry category')
|
|
54
|
+
.action(async (type, title, options) => {
|
|
55
|
+
try {
|
|
56
|
+
const manager = new KnowledgeManager(process.cwd());
|
|
57
|
+
|
|
58
|
+
const tags = options.tags ? options.tags.split(',').map(t => t.trim()) : [];
|
|
59
|
+
|
|
60
|
+
console.log(chalk.blue(`Creating ${type} entry: ${title}`));
|
|
61
|
+
|
|
62
|
+
const result = await manager.addEntry(type, title, {
|
|
63
|
+
tags,
|
|
64
|
+
category: options.category
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
console.log(chalk.green('✓ Entry created'));
|
|
68
|
+
console.log(chalk.gray(`ID: ${result.id}`));
|
|
69
|
+
console.log(chalk.gray(`File: ${result.file}`));
|
|
70
|
+
|
|
71
|
+
if (tags.length > 0) {
|
|
72
|
+
console.log(chalk.gray(`Tags: ${tags.join(', ')}`));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console.log(chalk.gray('\nEdit the file to add content:'));
|
|
76
|
+
console.log(chalk.gray(` ${result.path}`));
|
|
77
|
+
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// kse knowledge list
|
|
85
|
+
knowledge
|
|
86
|
+
.command('list')
|
|
87
|
+
.description('List all knowledge entries')
|
|
88
|
+
.option('-t, --type <type>', 'Filter by type')
|
|
89
|
+
.option('--tag <tag>', 'Filter by tag')
|
|
90
|
+
.option('--status <status>', 'Filter by status')
|
|
91
|
+
.option('-s, --sort <field>', 'Sort by field (e.g., created:desc)')
|
|
92
|
+
.action(async (options) => {
|
|
93
|
+
try {
|
|
94
|
+
const manager = new KnowledgeManager(process.cwd());
|
|
95
|
+
|
|
96
|
+
if (!await manager.isInitialized()) {
|
|
97
|
+
console.log(chalk.yellow('Knowledge base not initialized. Run: kse knowledge init'));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const entries = await manager.listEntries({
|
|
102
|
+
type: options.type,
|
|
103
|
+
tag: options.tag,
|
|
104
|
+
status: options.status,
|
|
105
|
+
sort: options.sort || 'created:desc'
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
if (entries.length === 0) {
|
|
109
|
+
console.log(chalk.gray('No entries found'));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const table = new Table({
|
|
114
|
+
head: ['ID', 'Type', 'Title', 'Tags', 'Created'].map(h => chalk.cyan(h)),
|
|
115
|
+
colWidths: [20, 12, 40, 25, 12]
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
for (const entry of entries) {
|
|
119
|
+
table.push([
|
|
120
|
+
entry.id.substring(0, 18) + '...',
|
|
121
|
+
entry.type,
|
|
122
|
+
entry.title.length > 37 ? entry.title.substring(0, 37) + '...' : entry.title,
|
|
123
|
+
entry.tags.slice(0, 2).join(', '),
|
|
124
|
+
new Date(entry.created).toLocaleDateString()
|
|
125
|
+
]);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
console.log(table.toString());
|
|
129
|
+
console.log(chalk.gray(`\nTotal: ${entries.length} entries`));
|
|
130
|
+
|
|
131
|
+
const stats = await manager.getStats();
|
|
132
|
+
console.log(chalk.gray(`By type: ${Object.entries(stats.byType).map(([k, v]) => `${k}(${v})`).join(', ')}`));
|
|
133
|
+
|
|
134
|
+
} catch (error) {
|
|
135
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// kse knowledge search
|
|
141
|
+
knowledge
|
|
142
|
+
.command('search <keyword>')
|
|
143
|
+
.description('Search knowledge entries')
|
|
144
|
+
.option('-f, --full-text', 'Search in file content')
|
|
145
|
+
.action(async (keyword, options) => {
|
|
146
|
+
try {
|
|
147
|
+
const manager = new KnowledgeManager(process.cwd());
|
|
148
|
+
|
|
149
|
+
if (!await manager.isInitialized()) {
|
|
150
|
+
console.log(chalk.yellow('Knowledge base not initialized. Run: kse knowledge init'));
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
console.log(chalk.blue(`Searching for: ${keyword}`));
|
|
155
|
+
|
|
156
|
+
const results = await manager.search(keyword, {
|
|
157
|
+
fullText: options.fullText
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
if (results.length === 0) {
|
|
161
|
+
console.log(chalk.gray('No results found'));
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
console.log(chalk.green(`\n✓ Found ${results.length} results\n`));
|
|
166
|
+
|
|
167
|
+
for (const result of results) {
|
|
168
|
+
console.log(chalk.cyan(`${result.title}`));
|
|
169
|
+
console.log(chalk.gray(` ID: ${result.id}`));
|
|
170
|
+
console.log(chalk.gray(` Type: ${result.type}`));
|
|
171
|
+
|
|
172
|
+
if (result.matches) {
|
|
173
|
+
console.log(chalk.gray(' Matches:'));
|
|
174
|
+
for (const match of result.matches) {
|
|
175
|
+
console.log(chalk.gray(` ${match.trim()}`));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
console.log();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// kse knowledge show
|
|
189
|
+
knowledge
|
|
190
|
+
.command('show <id>')
|
|
191
|
+
.description('Show knowledge entry')
|
|
192
|
+
.option('--raw', 'Show raw markdown')
|
|
193
|
+
.action(async (id, options) => {
|
|
194
|
+
try {
|
|
195
|
+
const manager = new KnowledgeManager(process.cwd());
|
|
196
|
+
|
|
197
|
+
const data = await manager.getEntry(id);
|
|
198
|
+
|
|
199
|
+
if (options.raw) {
|
|
200
|
+
console.log(data.content);
|
|
201
|
+
} else {
|
|
202
|
+
console.log(chalk.cyan.bold(`\n${data.metadata.title}\n`));
|
|
203
|
+
console.log(chalk.gray(`ID: ${data.metadata.id}`));
|
|
204
|
+
console.log(chalk.gray(`Type: ${data.metadata.type}`));
|
|
205
|
+
console.log(chalk.gray(`Created: ${new Date(data.metadata.created).toLocaleString()}`));
|
|
206
|
+
console.log(chalk.gray(`Updated: ${new Date(data.metadata.updated).toLocaleString()}`));
|
|
207
|
+
|
|
208
|
+
if (data.metadata.tags.length > 0) {
|
|
209
|
+
console.log(chalk.gray(`Tags: ${data.metadata.tags.join(', ')}`));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
console.log('\n' + data.content);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
} catch (error) {
|
|
216
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// kse knowledge delete
|
|
222
|
+
knowledge
|
|
223
|
+
.command('delete <id>')
|
|
224
|
+
.description('Delete knowledge entry')
|
|
225
|
+
.option('-f, --force', 'Skip confirmation')
|
|
226
|
+
.option('--no-backup', 'Skip backup')
|
|
227
|
+
.action(async (id, options) => {
|
|
228
|
+
try {
|
|
229
|
+
const manager = new KnowledgeManager(process.cwd());
|
|
230
|
+
|
|
231
|
+
const entry = await manager.indexManager.findById(id);
|
|
232
|
+
if (!entry) {
|
|
233
|
+
console.log(chalk.red(`Entry not found: ${id}`));
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (!options.force) {
|
|
238
|
+
console.log(chalk.yellow(`⚠ Delete entry: ${entry.title}?`));
|
|
239
|
+
console.log(chalk.gray('Use --force to skip confirmation'));
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const result = await manager.deleteEntry(id, {
|
|
244
|
+
backup: options.backup !== false
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
console.log(chalk.green('✓ Entry deleted'));
|
|
248
|
+
console.log(chalk.gray(`Title: ${result.title}`));
|
|
249
|
+
|
|
250
|
+
if (options.backup !== false) {
|
|
251
|
+
console.log(chalk.gray('Backup created in .kiro/knowledge/.backups/'));
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
} catch (error) {
|
|
255
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
256
|
+
process.exit(1);
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
// kse knowledge stats
|
|
261
|
+
knowledge
|
|
262
|
+
.command('stats')
|
|
263
|
+
.description('Show knowledge base statistics')
|
|
264
|
+
.action(async () => {
|
|
265
|
+
try {
|
|
266
|
+
const manager = new KnowledgeManager(process.cwd());
|
|
267
|
+
|
|
268
|
+
if (!await manager.isInitialized()) {
|
|
269
|
+
console.log(chalk.yellow('Knowledge base not initialized. Run: kse knowledge init'));
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const stats = await manager.getStats();
|
|
274
|
+
|
|
275
|
+
console.log(chalk.cyan.bold('\nKnowledge Base Statistics\n'));
|
|
276
|
+
|
|
277
|
+
console.log(chalk.white(`Total Entries: ${stats.totalEntries}`));
|
|
278
|
+
|
|
279
|
+
console.log(chalk.white('\nBy Type:'));
|
|
280
|
+
for (const [type, count] of Object.entries(stats.byType)) {
|
|
281
|
+
console.log(chalk.gray(` ${type}: ${count}`));
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
console.log(chalk.white('\nBy Status:'));
|
|
285
|
+
for (const [status, count] of Object.entries(stats.byStatus)) {
|
|
286
|
+
console.log(chalk.gray(` ${status}: ${count}`));
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (Object.keys(stats.byTag).length > 0) {
|
|
290
|
+
console.log(chalk.white('\nTop Tags:'));
|
|
291
|
+
const sortedTags = Object.entries(stats.byTag)
|
|
292
|
+
.sort((a, b) => b[1] - a[1])
|
|
293
|
+
.slice(0, 10);
|
|
294
|
+
|
|
295
|
+
for (const [tag, count] of sortedTags) {
|
|
296
|
+
console.log(chalk.gray(` ${tag}: ${count}`));
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
console.log();
|
|
301
|
+
|
|
302
|
+
} catch (error) {
|
|
303
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
304
|
+
process.exit(1);
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
module.exports = { registerKnowledgeCommands };
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lock commands for Spec locking mechanism
|
|
3
|
+
* @module lib/commands/lock
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const chalk = require('chalk');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const { LockManager } = require('../lock/lock-manager');
|
|
9
|
+
const { MachineIdentifier } = require('../lock/machine-identifier');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Register lock commands
|
|
13
|
+
* @param {import('commander').Command} program
|
|
14
|
+
*/
|
|
15
|
+
function registerLockCommands(program) {
|
|
16
|
+
const lockCmd = program
|
|
17
|
+
.command('lock')
|
|
18
|
+
.description('Manage Spec locks for multi-user collaboration');
|
|
19
|
+
|
|
20
|
+
// kse lock <spec-name>
|
|
21
|
+
lockCmd
|
|
22
|
+
.command('acquire <spec-name>')
|
|
23
|
+
.alias('get')
|
|
24
|
+
.description('Acquire a lock on a Spec')
|
|
25
|
+
.option('-r, --reason <reason>', 'Reason for acquiring the lock')
|
|
26
|
+
.option('-t, --timeout <hours>', 'Lock timeout in hours', '24')
|
|
27
|
+
.action(async (specName, options) => {
|
|
28
|
+
await acquireLock(specName, options);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// kse lock release <spec-name>
|
|
32
|
+
lockCmd
|
|
33
|
+
.command('release <spec-name>')
|
|
34
|
+
.description('Release a lock on a Spec')
|
|
35
|
+
.option('-f, --force', 'Force release regardless of ownership')
|
|
36
|
+
.action(async (specName, options) => {
|
|
37
|
+
await releaseLock(specName, options);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// kse lock status [spec-name]
|
|
41
|
+
lockCmd
|
|
42
|
+
.command('status [spec-name]')
|
|
43
|
+
.description('Show lock status for Specs')
|
|
44
|
+
.action(async (specName) => {
|
|
45
|
+
await showLockStatus(specName);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// kse lock cleanup
|
|
49
|
+
lockCmd
|
|
50
|
+
.command('cleanup')
|
|
51
|
+
.description('Remove all stale locks')
|
|
52
|
+
.action(async () => {
|
|
53
|
+
await cleanupStaleLocks();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// kse lock whoami
|
|
57
|
+
lockCmd
|
|
58
|
+
.command('whoami')
|
|
59
|
+
.description('Display current machine identifier')
|
|
60
|
+
.action(async () => {
|
|
61
|
+
await showMachineInfo();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// kse unlock <spec-name> (alias)
|
|
65
|
+
program
|
|
66
|
+
.command('unlock <spec-name>')
|
|
67
|
+
.description('Release a lock on a Spec (alias for lock release)')
|
|
68
|
+
.option('-f, --force', 'Force release regardless of ownership')
|
|
69
|
+
.action(async (specName, options) => {
|
|
70
|
+
await releaseLock(specName, options);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Acquire a lock on a Spec
|
|
77
|
+
*/
|
|
78
|
+
async function acquireLock(specName, options) {
|
|
79
|
+
const workspaceRoot = process.cwd();
|
|
80
|
+
const lockManager = new LockManager(workspaceRoot);
|
|
81
|
+
|
|
82
|
+
const timeout = parseInt(options.timeout, 10) || 24;
|
|
83
|
+
const result = await lockManager.acquireLock(specName, {
|
|
84
|
+
reason: options.reason,
|
|
85
|
+
timeout
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
if (result.success) {
|
|
89
|
+
console.log(chalk.green('✓') + ` Lock acquired on ${chalk.cyan(specName)}`);
|
|
90
|
+
console.log(` Owner: ${result.lock.owner}`);
|
|
91
|
+
console.log(` Machine: ${result.lock.hostname}`);
|
|
92
|
+
if (result.lock.reason) {
|
|
93
|
+
console.log(` Reason: ${result.lock.reason}`);
|
|
94
|
+
}
|
|
95
|
+
console.log(` Timeout: ${result.lock.timeout}h`);
|
|
96
|
+
} else {
|
|
97
|
+
console.log(chalk.red('✗') + ` Failed to acquire lock: ${result.error}`);
|
|
98
|
+
if (result.existingLock) {
|
|
99
|
+
console.log(chalk.yellow('\nCurrent lock holder:'));
|
|
100
|
+
console.log(` Owner: ${result.existingLock.owner}`);
|
|
101
|
+
console.log(` Machine: ${result.existingLock.hostname}`);
|
|
102
|
+
console.log(` Since: ${result.existingLock.timestamp}`);
|
|
103
|
+
if (result.existingLock.reason) {
|
|
104
|
+
console.log(` Reason: ${result.existingLock.reason}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
process.exitCode = 1;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Release a lock on a Spec
|
|
113
|
+
*/
|
|
114
|
+
async function releaseLock(specName, options) {
|
|
115
|
+
const workspaceRoot = process.cwd();
|
|
116
|
+
const lockManager = new LockManager(workspaceRoot);
|
|
117
|
+
|
|
118
|
+
const result = await lockManager.releaseLock(specName, {
|
|
119
|
+
force: options.force
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
if (result.success) {
|
|
123
|
+
if (result.message) {
|
|
124
|
+
console.log(chalk.yellow('ℹ') + ` ${result.message}`);
|
|
125
|
+
} else {
|
|
126
|
+
const forceMsg = result.forced ? ' (forced)' : '';
|
|
127
|
+
console.log(chalk.green('✓') + ` Lock released on ${chalk.cyan(specName)}${forceMsg}`);
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
console.log(chalk.red('✗') + ` Failed to release lock: ${result.error}`);
|
|
131
|
+
if (result.existingLock) {
|
|
132
|
+
console.log(chalk.yellow('\nLock is owned by:'));
|
|
133
|
+
console.log(` Owner: ${result.existingLock.owner}`);
|
|
134
|
+
console.log(` Machine: ${result.existingLock.hostname}`);
|
|
135
|
+
console.log(chalk.dim('\nUse --force to override'));
|
|
136
|
+
}
|
|
137
|
+
process.exitCode = 1;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Show lock status
|
|
143
|
+
*/
|
|
144
|
+
async function showLockStatus(specName) {
|
|
145
|
+
const workspaceRoot = process.cwd();
|
|
146
|
+
const lockManager = new LockManager(workspaceRoot);
|
|
147
|
+
|
|
148
|
+
if (specName) {
|
|
149
|
+
const status = await lockManager.getLockStatus(specName);
|
|
150
|
+
displaySingleStatus(status);
|
|
151
|
+
} else {
|
|
152
|
+
const statuses = await lockManager.getLockStatus();
|
|
153
|
+
if (statuses.length === 0) {
|
|
154
|
+
console.log(chalk.dim('No Specs are currently locked'));
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
console.log(chalk.bold(`Locked Specs (${statuses.length}):\n`));
|
|
159
|
+
for (const status of statuses) {
|
|
160
|
+
displaySingleStatus(status);
|
|
161
|
+
console.log();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Display single lock status
|
|
168
|
+
*/
|
|
169
|
+
function displaySingleStatus(status) {
|
|
170
|
+
const { specName, locked, lock, isStale, isOwnedByMe, duration } = status;
|
|
171
|
+
|
|
172
|
+
if (!locked) {
|
|
173
|
+
console.log(`${chalk.cyan(specName)}: ${chalk.dim('unlocked')}`);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const staleIndicator = isStale ? chalk.red(' [STALE]') : '';
|
|
178
|
+
const ownerIndicator = isOwnedByMe ? chalk.green(' (you)') : '';
|
|
179
|
+
|
|
180
|
+
console.log(`${chalk.cyan(specName)}: ${chalk.yellow('locked')}${staleIndicator}${ownerIndicator}`);
|
|
181
|
+
console.log(` Owner: ${lock.owner}`);
|
|
182
|
+
console.log(` Machine: ${lock.hostname}`);
|
|
183
|
+
console.log(` Duration: ${duration}`);
|
|
184
|
+
if (lock.reason) {
|
|
185
|
+
console.log(` Reason: ${lock.reason}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Cleanup stale locks
|
|
192
|
+
*/
|
|
193
|
+
async function cleanupStaleLocks() {
|
|
194
|
+
const workspaceRoot = process.cwd();
|
|
195
|
+
const lockManager = new LockManager(workspaceRoot);
|
|
196
|
+
|
|
197
|
+
const result = await lockManager.cleanupStaleLocks();
|
|
198
|
+
|
|
199
|
+
if (result.cleaned === 0) {
|
|
200
|
+
console.log(chalk.dim('No stale locks found'));
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
console.log(chalk.green('✓') + ` Cleaned ${result.cleaned} stale lock(s):`);
|
|
205
|
+
for (const { specName, lock } of result.cleanedLocks) {
|
|
206
|
+
console.log(` - ${chalk.cyan(specName)} (was locked by ${lock.owner})`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (result.errors.length > 0) {
|
|
210
|
+
console.log(chalk.yellow('\nErrors encountered:'));
|
|
211
|
+
for (const { specName, error } of result.errors) {
|
|
212
|
+
console.log(` - ${specName}: ${error}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Show machine info
|
|
219
|
+
*/
|
|
220
|
+
async function showMachineInfo() {
|
|
221
|
+
const workspaceRoot = process.cwd();
|
|
222
|
+
const configDir = path.join(workspaceRoot, '.kiro', 'config');
|
|
223
|
+
const machineIdentifier = new MachineIdentifier(configDir);
|
|
224
|
+
|
|
225
|
+
const info = await machineIdentifier.getMachineInfo();
|
|
226
|
+
|
|
227
|
+
console.log(chalk.bold('Machine Identifier:'));
|
|
228
|
+
console.log(` ID: ${info.id}`);
|
|
229
|
+
console.log(` Hostname: ${info.hostname}`);
|
|
230
|
+
console.log(` Platform: ${info.platform}`);
|
|
231
|
+
console.log(` User: ${info.user}`);
|
|
232
|
+
console.log(` Created: ${info.createdAt}`);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
module.exports = { registerLockCommands };
|