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,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TemplateApplicator - Applies templates to create new Specs
|
|
3
|
+
*
|
|
4
|
+
* Handles file copying, variable substitution, and frontmatter removal.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const { FileSystemError } = require('./template-error');
|
|
10
|
+
|
|
11
|
+
class TemplateApplicator {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.requiredFiles = ['requirements.md', 'design.md', 'tasks.md'];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Applies a template to create a new Spec
|
|
18
|
+
*
|
|
19
|
+
* @param {string} specName - Spec name (e.g., 'user-authentication')
|
|
20
|
+
* @param {string} templatePath - Path to template directory
|
|
21
|
+
* @param {string} targetDir - Target Spec directory
|
|
22
|
+
* @param {Object} options - Application options
|
|
23
|
+
* @param {boolean} options.force - Overwrite existing files
|
|
24
|
+
* @param {Object} options.variables - Custom variables
|
|
25
|
+
* @returns {Promise<Object>} Application result
|
|
26
|
+
*/
|
|
27
|
+
async applyTemplate(specName, templatePath, targetDir, options = {}) {
|
|
28
|
+
const { force = false, variables = {} } = options;
|
|
29
|
+
|
|
30
|
+
const result = {
|
|
31
|
+
success: true,
|
|
32
|
+
filesCreated: [],
|
|
33
|
+
filesSkipped: [],
|
|
34
|
+
errors: []
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Check if template exists
|
|
38
|
+
if (!await fs.pathExists(templatePath)) {
|
|
39
|
+
throw new FileSystemError(
|
|
40
|
+
'Template directory does not exist',
|
|
41
|
+
{ templatePath }
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Check if target directory exists
|
|
46
|
+
if (await fs.pathExists(targetDir) && !force) {
|
|
47
|
+
throw new FileSystemError(
|
|
48
|
+
'Target directory already exists',
|
|
49
|
+
{
|
|
50
|
+
targetDir,
|
|
51
|
+
suggestion: 'Use --force to overwrite or choose a different name'
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Create target directory
|
|
57
|
+
await fs.ensureDir(targetDir);
|
|
58
|
+
|
|
59
|
+
// Prepare variables
|
|
60
|
+
const allVariables = this._prepareVariables(specName, variables);
|
|
61
|
+
|
|
62
|
+
// Copy and transform files
|
|
63
|
+
for (const file of this.requiredFiles) {
|
|
64
|
+
const sourcePath = path.join(templatePath, file);
|
|
65
|
+
const targetPath = path.join(targetDir, file);
|
|
66
|
+
|
|
67
|
+
if (!await fs.pathExists(sourcePath)) {
|
|
68
|
+
result.errors.push(`Template missing file: ${file}`);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
// Read source file
|
|
74
|
+
let content = await fs.readFile(sourcePath, 'utf8');
|
|
75
|
+
|
|
76
|
+
// Remove frontmatter
|
|
77
|
+
content = this.removeFrontmatter(content);
|
|
78
|
+
|
|
79
|
+
// Transform variables
|
|
80
|
+
content = this.transformVariables(content, allVariables);
|
|
81
|
+
|
|
82
|
+
// Normalize line endings
|
|
83
|
+
content = this.normalizeLineEndings(content);
|
|
84
|
+
|
|
85
|
+
// Write target file
|
|
86
|
+
await fs.writeFile(targetPath, content, 'utf8');
|
|
87
|
+
|
|
88
|
+
result.filesCreated.push(file);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
result.errors.push(`Failed to process ${file}: ${error.message}`);
|
|
91
|
+
result.success = false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Prepares variables for substitution
|
|
100
|
+
*
|
|
101
|
+
* @param {string} specName - Spec name
|
|
102
|
+
* @param {Object} customVariables - Custom variables
|
|
103
|
+
* @returns {Object} All variables
|
|
104
|
+
* @private
|
|
105
|
+
*/
|
|
106
|
+
_prepareVariables(specName, customVariables = {}) {
|
|
107
|
+
const now = new Date();
|
|
108
|
+
|
|
109
|
+
// Convert kebab-case to Title Case (preserve hyphens for numbers)
|
|
110
|
+
const specNameTitle = specName
|
|
111
|
+
.split('-')
|
|
112
|
+
.map(word => {
|
|
113
|
+
// If word is all digits, keep it as is
|
|
114
|
+
if (/^\d+$/.test(word)) {
|
|
115
|
+
return word;
|
|
116
|
+
}
|
|
117
|
+
// Otherwise capitalize first letter
|
|
118
|
+
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
119
|
+
})
|
|
120
|
+
.join(' ');
|
|
121
|
+
|
|
122
|
+
const defaultVariables = {
|
|
123
|
+
SPEC_NAME: specName,
|
|
124
|
+
SPEC_NAME_TITLE: specNameTitle,
|
|
125
|
+
DATE: now.toISOString().split('T')[0],
|
|
126
|
+
YEAR: now.getFullYear().toString(),
|
|
127
|
+
AUTHOR: this._getAuthorName(),
|
|
128
|
+
PROJECT_NAME: this._getProjectName()
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
return { ...defaultVariables, ...customVariables };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Gets author name from Git config
|
|
136
|
+
*
|
|
137
|
+
* @returns {string} Author name
|
|
138
|
+
* @private
|
|
139
|
+
*/
|
|
140
|
+
_getAuthorName() {
|
|
141
|
+
try {
|
|
142
|
+
const { execSync } = require('child_process');
|
|
143
|
+
const name = execSync('git config user.name', { encoding: 'utf8' }).trim();
|
|
144
|
+
return name || 'Unknown';
|
|
145
|
+
} catch (error) {
|
|
146
|
+
return 'Unknown';
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Gets project name from package.json or directory
|
|
152
|
+
*
|
|
153
|
+
* @returns {string} Project name
|
|
154
|
+
* @private
|
|
155
|
+
*/
|
|
156
|
+
_getProjectName() {
|
|
157
|
+
try {
|
|
158
|
+
const packagePath = path.join(process.cwd(), 'package.json');
|
|
159
|
+
if (fs.existsSync(packagePath)) {
|
|
160
|
+
const pkg = require(packagePath);
|
|
161
|
+
return pkg.name || path.basename(process.cwd());
|
|
162
|
+
}
|
|
163
|
+
} catch (error) {
|
|
164
|
+
// Ignore
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return path.basename(process.cwd());
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Removes YAML frontmatter from content
|
|
172
|
+
*
|
|
173
|
+
* @param {string} content - File content
|
|
174
|
+
* @returns {string} Content without frontmatter
|
|
175
|
+
*/
|
|
176
|
+
removeFrontmatter(content) {
|
|
177
|
+
// Normalize line endings first
|
|
178
|
+
const normalized = content.replace(/\r\n/g, '\n');
|
|
179
|
+
// Remove frontmatter
|
|
180
|
+
return normalized.replace(/^---\n[\s\S]*?\n---\n/, '');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Transforms variables in content
|
|
185
|
+
*
|
|
186
|
+
* @param {string} content - File content
|
|
187
|
+
* @param {Object} variables - Variables to substitute
|
|
188
|
+
* @returns {string} Transformed content
|
|
189
|
+
*/
|
|
190
|
+
transformVariables(content, variables) {
|
|
191
|
+
let result = content;
|
|
192
|
+
|
|
193
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
194
|
+
const placeholder = `{{${key}}}`;
|
|
195
|
+
result = result.split(placeholder).join(value);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return result;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Normalizes line endings to LF
|
|
203
|
+
*
|
|
204
|
+
* @param {string} content - File content
|
|
205
|
+
* @returns {string} Content with LF line endings
|
|
206
|
+
*/
|
|
207
|
+
normalizeLineEndings(content) {
|
|
208
|
+
return content.replace(/\r\n/g, '\n');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Handles file conflict
|
|
213
|
+
*
|
|
214
|
+
* @param {string} targetPath - Target file path
|
|
215
|
+
* @param {string} strategy - Conflict strategy ('overwrite', 'skip', 'rename')
|
|
216
|
+
* @returns {Promise<string>} Resolved target path
|
|
217
|
+
*/
|
|
218
|
+
async handleConflict(targetPath, strategy = 'skip') {
|
|
219
|
+
if (!await fs.pathExists(targetPath)) {
|
|
220
|
+
return targetPath;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
switch (strategy) {
|
|
224
|
+
case 'overwrite':
|
|
225
|
+
return targetPath;
|
|
226
|
+
|
|
227
|
+
case 'skip':
|
|
228
|
+
return null;
|
|
229
|
+
|
|
230
|
+
case 'rename':
|
|
231
|
+
let counter = 1;
|
|
232
|
+
let newPath = targetPath;
|
|
233
|
+
const ext = path.extname(targetPath);
|
|
234
|
+
const base = targetPath.slice(0, -ext.length);
|
|
235
|
+
|
|
236
|
+
while (await fs.pathExists(newPath)) {
|
|
237
|
+
newPath = `${base}-${counter}${ext}`;
|
|
238
|
+
counter++;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return newPath;
|
|
242
|
+
|
|
243
|
+
default:
|
|
244
|
+
return targetPath;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
module.exports = TemplateApplicator;
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TemplateCreator - Main orchestrator for template creation workflow
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const SpecReader = require('./spec-reader');
|
|
6
|
+
const ContentGeneralizer = require('./content-generalizer');
|
|
7
|
+
const MetadataCollector = require('./metadata-collector');
|
|
8
|
+
const FrontmatterGenerator = require('./frontmatter-generator');
|
|
9
|
+
const TemplateValidator = require('./template-validator');
|
|
10
|
+
const TemplateExporter = require('./template-exporter');
|
|
11
|
+
|
|
12
|
+
class TemplateCreator {
|
|
13
|
+
constructor(options = {}) {
|
|
14
|
+
this.options = options;
|
|
15
|
+
this.specReader = new SpecReader();
|
|
16
|
+
this.contentGeneralizer = new ContentGeneralizer();
|
|
17
|
+
this.metadataCollector = new MetadataCollector(options);
|
|
18
|
+
this.frontmatterGenerator = new FrontmatterGenerator();
|
|
19
|
+
this.templateValidator = new TemplateValidator();
|
|
20
|
+
this.templateExporter = new TemplateExporter();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Creates a template from an existing Spec
|
|
25
|
+
* @param {Object} options - Creation options
|
|
26
|
+
* @returns {Promise<Object>} Creation result
|
|
27
|
+
*/
|
|
28
|
+
async createTemplate(options) {
|
|
29
|
+
const {
|
|
30
|
+
spec,
|
|
31
|
+
output,
|
|
32
|
+
preview = false,
|
|
33
|
+
dryRun = false,
|
|
34
|
+
interactive = true
|
|
35
|
+
} = options;
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
console.log('🚀 Starting template creation...\n');
|
|
39
|
+
|
|
40
|
+
// Step 1: Read and validate Spec
|
|
41
|
+
console.log('📖 Step 1: Reading Spec...');
|
|
42
|
+
const specInfo = await this.specReader.findSpec(spec);
|
|
43
|
+
console.log(` Found: ${specInfo.name}`);
|
|
44
|
+
|
|
45
|
+
const validation = await this.specReader.validateSpecStructure(specInfo.path);
|
|
46
|
+
if (!validation.valid) {
|
|
47
|
+
throw new Error(`Missing required files: ${validation.missingFiles.join(', ')}`);
|
|
48
|
+
}
|
|
49
|
+
console.log(` ✓ All required files present\n`);
|
|
50
|
+
|
|
51
|
+
const fileContents = await this.specReader.readSpecFiles(specInfo.path);
|
|
52
|
+
const specMetadata = this.specReader.extractSpecMetadata(specInfo.path, fileContents);
|
|
53
|
+
|
|
54
|
+
// Step 2: Generalize content
|
|
55
|
+
console.log('🔄 Step 2: Generalizing content...');
|
|
56
|
+
const generalizationResult = this.contentGeneralizer.generalize(fileContents, specMetadata);
|
|
57
|
+
console.log(` Replacements: ${generalizationResult.summary.totalReplacements}`);
|
|
58
|
+
console.log(` Flags: ${generalizationResult.summary.totalFlags}\n`);
|
|
59
|
+
|
|
60
|
+
// Step 3: Collect metadata
|
|
61
|
+
console.log('📝 Step 3: Collecting metadata...');
|
|
62
|
+
const metadata = await this.metadataCollector.collectMetadata(specMetadata, interactive);
|
|
63
|
+
console.log(` ✓ Metadata collected\n`);
|
|
64
|
+
|
|
65
|
+
// Step 4: Generate frontmatter
|
|
66
|
+
console.log('📄 Step 4: Generating frontmatter...');
|
|
67
|
+
const frontmatter = this.frontmatterGenerator.generateFrontmatter(metadata);
|
|
68
|
+
const filesWithFrontmatter = {};
|
|
69
|
+
|
|
70
|
+
for (const [filename, fileData] of Object.entries(generalizationResult.files)) {
|
|
71
|
+
if (fileData.generalized) {
|
|
72
|
+
filesWithFrontmatter[filename] = this.frontmatterGenerator.addFrontmatter(
|
|
73
|
+
fileData.generalized,
|
|
74
|
+
frontmatter
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
console.log(` ✓ Frontmatter added to all files\n`);
|
|
79
|
+
|
|
80
|
+
// Step 5: Validate template
|
|
81
|
+
console.log('✅ Step 5: Validating template...');
|
|
82
|
+
const validationResult = await this.validateTemplate(filesWithFrontmatter, metadata);
|
|
83
|
+
console.log(` Quality Score: ${validationResult.score}/100`);
|
|
84
|
+
console.log(` Errors: ${validationResult.errors.length}`);
|
|
85
|
+
console.log(` Warnings: ${validationResult.warnings.length}\n`);
|
|
86
|
+
|
|
87
|
+
if (validationResult.errors.length > 0) {
|
|
88
|
+
console.log('❌ Validation Errors:');
|
|
89
|
+
validationResult.errors.forEach(error => console.log(` - ${error}`));
|
|
90
|
+
console.log('');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (validationResult.warnings.length > 0) {
|
|
94
|
+
console.log('⚠️ Validation Warnings:');
|
|
95
|
+
validationResult.warnings.forEach(warning => console.log(` - ${warning}`));
|
|
96
|
+
console.log('');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Step 6: Preview (if requested)
|
|
100
|
+
if (preview) {
|
|
101
|
+
console.log('👀 Preview:');
|
|
102
|
+
this.showPreview(fileContents, generalizationResult);
|
|
103
|
+
console.log('');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Step 7: Export template
|
|
107
|
+
if (dryRun) {
|
|
108
|
+
console.log('🏃 Dry run mode - skipping export\n');
|
|
109
|
+
return {
|
|
110
|
+
success: true,
|
|
111
|
+
dryRun: true,
|
|
112
|
+
metadata,
|
|
113
|
+
validationResult
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
console.log('📦 Step 6: Exporting template...');
|
|
118
|
+
const exportResult = await this.templateExporter.exportTemplate(
|
|
119
|
+
{
|
|
120
|
+
metadata,
|
|
121
|
+
files: filesWithFrontmatter,
|
|
122
|
+
validationResult,
|
|
123
|
+
generalizationResult
|
|
124
|
+
},
|
|
125
|
+
output
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
console.log(` ✓ Template exported to: ${exportResult.outputDir}\n`);
|
|
129
|
+
|
|
130
|
+
// Final summary
|
|
131
|
+
console.log('✨ Template creation complete!\n');
|
|
132
|
+
console.log('📁 Files created:');
|
|
133
|
+
exportResult.filesCreated.forEach(file => console.log(` - ${file}`));
|
|
134
|
+
console.log('');
|
|
135
|
+
console.log('📖 Next steps:');
|
|
136
|
+
console.log(` 1. Review the template in: ${exportResult.outputDir}`);
|
|
137
|
+
console.log(` 2. Check REVIEW_CHECKLIST.md for items to verify`);
|
|
138
|
+
console.log(` 3. Test the template: kse spec create test --template ${metadata.name}`);
|
|
139
|
+
console.log(` 4. Follow SUBMISSION_GUIDE.md to submit to repository`);
|
|
140
|
+
console.log('');
|
|
141
|
+
|
|
142
|
+
return exportResult;
|
|
143
|
+
|
|
144
|
+
} catch (error) {
|
|
145
|
+
console.error(`\n❌ Error: ${error.message}\n`);
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Validates template
|
|
152
|
+
* @param {Object} files - Template files
|
|
153
|
+
* @param {Object} metadata - Template metadata
|
|
154
|
+
* @returns {Promise<Object>} Validation result
|
|
155
|
+
*/
|
|
156
|
+
async validateTemplate(files, metadata) {
|
|
157
|
+
const errors = [];
|
|
158
|
+
const warnings = [];
|
|
159
|
+
let score = 100;
|
|
160
|
+
|
|
161
|
+
// Validate frontmatter in each file
|
|
162
|
+
for (const [filename, content] of Object.entries(files)) {
|
|
163
|
+
if (!content) continue;
|
|
164
|
+
|
|
165
|
+
// Check for frontmatter
|
|
166
|
+
if (!content.trim().startsWith('---')) {
|
|
167
|
+
errors.push(`${filename}: Missing YAML frontmatter`);
|
|
168
|
+
score -= 10;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Validate YAML syntax
|
|
173
|
+
const yamlValidation = this.frontmatterGenerator.validateYaml(
|
|
174
|
+
content.split('---')[1]
|
|
175
|
+
);
|
|
176
|
+
if (!yamlValidation.valid) {
|
|
177
|
+
errors.push(`${filename}: Invalid YAML frontmatter - ${yamlValidation.errors.join(', ')}`);
|
|
178
|
+
score -= 10;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Check for remaining project-specific content (high confidence patterns)
|
|
182
|
+
const projectSpecificPatterns = [
|
|
183
|
+
/\.kiro\/specs\/\d+-\d+-[a-z-]+/g, // Specific spec paths
|
|
184
|
+
/kiro-spec-engine/g, // Project name (unless it's the template itself)
|
|
185
|
+
];
|
|
186
|
+
|
|
187
|
+
projectSpecificPatterns.forEach(pattern => {
|
|
188
|
+
const matches = content.match(pattern);
|
|
189
|
+
if (matches && matches.length > 3) { // Allow a few occurrences
|
|
190
|
+
warnings.push(`${filename}: Possible project-specific content: ${matches[0]}`);
|
|
191
|
+
score -= 2;
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Check for template variable syntax
|
|
196
|
+
const malformedVariables = content.match(/\{\{[^}]*\}\}(?!\})/g);
|
|
197
|
+
if (malformedVariables) {
|
|
198
|
+
malformedVariables.forEach(v => {
|
|
199
|
+
if (!/^\{\{[A-Z_]+\}\}$/.test(v)) {
|
|
200
|
+
warnings.push(`${filename}: Malformed template variable: ${v}`);
|
|
201
|
+
score -= 1;
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Validate metadata
|
|
208
|
+
const metadataValidation = this.metadataCollector.validateMetadata(metadata);
|
|
209
|
+
if (!metadataValidation.valid) {
|
|
210
|
+
errors.push(...metadataValidation.errors);
|
|
211
|
+
score -= 15;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Ensure score doesn't go below 0
|
|
215
|
+
score = Math.max(0, score);
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
valid: errors.length === 0,
|
|
219
|
+
score,
|
|
220
|
+
errors,
|
|
221
|
+
warnings,
|
|
222
|
+
breakdown: {
|
|
223
|
+
structure: errors.length === 0 ? 30 : 15,
|
|
224
|
+
frontmatter: errors.filter(e => e.includes('frontmatter')).length === 0 ? 20 : 10,
|
|
225
|
+
variables: warnings.filter(w => w.includes('variable')).length === 0 ? 20 : 15,
|
|
226
|
+
content: warnings.filter(w => w.includes('project-specific')).length === 0 ? 20 : 15,
|
|
227
|
+
references: 10
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Shows preview of changes
|
|
234
|
+
* @param {Object} originalContent - Original Spec content
|
|
235
|
+
* @param {Object} generalizationResult - Generalization result
|
|
236
|
+
*/
|
|
237
|
+
showPreview(originalContent, generalizationResult) {
|
|
238
|
+
for (const [filename, fileData] of Object.entries(generalizationResult.files)) {
|
|
239
|
+
console.log(`\n📄 ${filename}:`);
|
|
240
|
+
console.log(` Replacements: ${fileData.replacements.length}`);
|
|
241
|
+
|
|
242
|
+
fileData.replacements.forEach(r => {
|
|
243
|
+
console.log(` - ${r.pattern} → ${r.variable} (${r.count} times)`);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
if (fileData.flags.length > 0) {
|
|
247
|
+
console.log(` Flags: ${fileData.flags.length}`);
|
|
248
|
+
fileData.flags.forEach(f => {
|
|
249
|
+
console.log(` - Line ${f.line}: ${f.message} - "${f.content}"`);
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
module.exports = TemplateCreator;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Error Classes
|
|
3
|
+
*
|
|
4
|
+
* Provides specialized error types for template operations with
|
|
5
|
+
* context-specific error messages and troubleshooting suggestions.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Base error class for all template-related errors
|
|
10
|
+
*/
|
|
11
|
+
class TemplateError extends Error {
|
|
12
|
+
constructor(type, message, details = {}) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'TemplateError';
|
|
15
|
+
this.type = type;
|
|
16
|
+
this.details = details;
|
|
17
|
+
this.suggestions = this.generateSuggestions();
|
|
18
|
+
|
|
19
|
+
// Maintain proper stack trace
|
|
20
|
+
if (Error.captureStackTrace) {
|
|
21
|
+
Error.captureStackTrace(this, this.constructor);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Generate context-specific troubleshooting suggestions
|
|
27
|
+
* @returns {string[]} Array of suggestion strings
|
|
28
|
+
*/
|
|
29
|
+
generateSuggestions() {
|
|
30
|
+
switch (this.type) {
|
|
31
|
+
case 'network':
|
|
32
|
+
return [
|
|
33
|
+
'Check your internet connection',
|
|
34
|
+
'Verify the repository URL is correct',
|
|
35
|
+
'Try again later if the service is temporarily unavailable',
|
|
36
|
+
'Check if you need to configure proxy settings'
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
case 'validation':
|
|
40
|
+
return [
|
|
41
|
+
'Review the template structure requirements',
|
|
42
|
+
'Check the YAML frontmatter syntax',
|
|
43
|
+
'Ensure all required fields are present',
|
|
44
|
+
'Refer to CONTRIBUTING.md for template format'
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
case 'filesystem':
|
|
48
|
+
return [
|
|
49
|
+
'Check file permissions',
|
|
50
|
+
'Ensure sufficient disk space',
|
|
51
|
+
'Verify the path is correct',
|
|
52
|
+
'Try running with elevated permissions if needed'
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
case 'git':
|
|
56
|
+
return [
|
|
57
|
+
'Ensure Git is installed and in PATH',
|
|
58
|
+
'Check repository URL is accessible',
|
|
59
|
+
'Verify Git credentials if repository is private',
|
|
60
|
+
'Try clearing the cache and re-downloading'
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
default:
|
|
64
|
+
return [
|
|
65
|
+
'Check the error details above',
|
|
66
|
+
'Refer to documentation for troubleshooting',
|
|
67
|
+
'Report this issue if the problem persists'
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Format error for display to user
|
|
74
|
+
* @returns {string} Formatted error message
|
|
75
|
+
*/
|
|
76
|
+
format() {
|
|
77
|
+
let output = `\n❌ ${this.message}\n`;
|
|
78
|
+
|
|
79
|
+
if (Object.keys(this.details).length > 0) {
|
|
80
|
+
output += '\nDetails:\n';
|
|
81
|
+
for (const [key, value] of Object.entries(this.details)) {
|
|
82
|
+
output += ` ${key}: ${value}\n`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (this.suggestions.length > 0) {
|
|
87
|
+
output += '\nSuggestions:\n';
|
|
88
|
+
this.suggestions.forEach((suggestion, index) => {
|
|
89
|
+
output += ` ${index + 1}. ${suggestion}\n`;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return output;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Network-related errors (download, clone, pull)
|
|
99
|
+
*/
|
|
100
|
+
class NetworkError extends TemplateError {
|
|
101
|
+
constructor(message, details = {}) {
|
|
102
|
+
super('network', message, details);
|
|
103
|
+
this.name = 'NetworkError';
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Template validation errors
|
|
109
|
+
*/
|
|
110
|
+
class ValidationError extends TemplateError {
|
|
111
|
+
constructor(message, details = {}) {
|
|
112
|
+
super('validation', message, details);
|
|
113
|
+
this.name = 'ValidationError';
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* File system operation errors
|
|
119
|
+
*/
|
|
120
|
+
class FileSystemError extends TemplateError {
|
|
121
|
+
constructor(message, details = {}) {
|
|
122
|
+
super('filesystem', message, details);
|
|
123
|
+
this.name = 'FileSystemError';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Git operation errors
|
|
129
|
+
*/
|
|
130
|
+
class GitError extends TemplateError {
|
|
131
|
+
constructor(message, details = {}) {
|
|
132
|
+
super('git', message, details);
|
|
133
|
+
this.name = 'GitError';
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
module.exports = {
|
|
138
|
+
TemplateError,
|
|
139
|
+
NetworkError,
|
|
140
|
+
ValidationError,
|
|
141
|
+
FileSystemError,
|
|
142
|
+
GitError
|
|
143
|
+
};
|