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,354 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages AI operation permissions and takeover levels
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const { TakeoverLevel, SecurityEnvironment } = require('./models');
|
|
10
|
+
|
|
11
|
+
// Default environment policies
|
|
12
|
+
const DEFAULT_POLICIES = {
|
|
13
|
+
[SecurityEnvironment.DEVELOPMENT]: {
|
|
14
|
+
maxTakeoverLevel: TakeoverLevel.L5_FULLY_AUTONOMOUS,
|
|
15
|
+
defaultLevel: TakeoverLevel.L3_SEMI_AUTO
|
|
16
|
+
},
|
|
17
|
+
[SecurityEnvironment.TEST]: {
|
|
18
|
+
maxTakeoverLevel: TakeoverLevel.L4_AUTO,
|
|
19
|
+
defaultLevel: TakeoverLevel.L2_SUGGESTION
|
|
20
|
+
},
|
|
21
|
+
[SecurityEnvironment.PRE_PRODUCTION]: {
|
|
22
|
+
maxTakeoverLevel: TakeoverLevel.L3_SEMI_AUTO,
|
|
23
|
+
defaultLevel: TakeoverLevel.L2_SUGGESTION
|
|
24
|
+
},
|
|
25
|
+
[SecurityEnvironment.PRODUCTION]: {
|
|
26
|
+
maxTakeoverLevel: TakeoverLevel.L2_SUGGESTION,
|
|
27
|
+
defaultLevel: TakeoverLevel.L1_OBSERVATION
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
class PermissionManager {
|
|
32
|
+
constructor(projectRoot = process.cwd()) {
|
|
33
|
+
this.projectRoot = projectRoot;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get takeover level for project and environment
|
|
38
|
+
*
|
|
39
|
+
* @param {string} project - Project name
|
|
40
|
+
* @param {string} environment - Security environment
|
|
41
|
+
* @returns {Promise<string>} Current takeover level
|
|
42
|
+
*/
|
|
43
|
+
async getTakeoverLevel(project, environment) {
|
|
44
|
+
const config = await this.loadPermissionConfig(project);
|
|
45
|
+
|
|
46
|
+
if (config.environments && config.environments[environment]) {
|
|
47
|
+
return config.environments[environment].takeoverLevel;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Return default for environment
|
|
51
|
+
return DEFAULT_POLICIES[environment].defaultLevel;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Set takeover level for project and environment
|
|
56
|
+
*
|
|
57
|
+
* @param {string} project - Project name
|
|
58
|
+
* @param {string} environment - Security environment
|
|
59
|
+
* @param {string} level - New takeover level
|
|
60
|
+
* @param {string} reason - Reason for change
|
|
61
|
+
* @param {string} user - User making the change
|
|
62
|
+
* @returns {Promise<void>}
|
|
63
|
+
*/
|
|
64
|
+
async setTakeoverLevel(project, environment, level, reason, user) {
|
|
65
|
+
const config = await this.loadPermissionConfig(project);
|
|
66
|
+
|
|
67
|
+
// Validate level against environment policy
|
|
68
|
+
const policy = DEFAULT_POLICIES[environment];
|
|
69
|
+
if (!this.isLevelAllowed(level, policy.maxTakeoverLevel)) {
|
|
70
|
+
throw new Error(`Level ${level} exceeds maximum ${policy.maxTakeoverLevel} for ${environment}`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Initialize environments if needed
|
|
74
|
+
if (!config.environments) {
|
|
75
|
+
config.environments = {};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!config.environments[environment]) {
|
|
79
|
+
config.environments[environment] = {};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const oldLevel = config.environments[environment].takeoverLevel || policy.defaultLevel;
|
|
83
|
+
|
|
84
|
+
// Update level
|
|
85
|
+
config.environments[environment].takeoverLevel = level;
|
|
86
|
+
config.environments[environment].maxLevel = policy.maxTakeoverLevel;
|
|
87
|
+
|
|
88
|
+
// Record history
|
|
89
|
+
if (!config.levelHistory) {
|
|
90
|
+
config.levelHistory = [];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
config.levelHistory.push({
|
|
94
|
+
timestamp: new Date().toISOString(),
|
|
95
|
+
environment,
|
|
96
|
+
fromLevel: oldLevel,
|
|
97
|
+
toLevel: level,
|
|
98
|
+
reason,
|
|
99
|
+
user
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Save config
|
|
103
|
+
await this.savePermissionConfig(project, config);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Check if operation is permitted
|
|
108
|
+
*
|
|
109
|
+
* @param {string} project - Project name
|
|
110
|
+
* @param {string} environment - Security environment
|
|
111
|
+
* @param {string} operationType - Type of operation
|
|
112
|
+
* @returns {Promise<Object>} Permission result
|
|
113
|
+
*/
|
|
114
|
+
async checkPermission(project, environment, operationType) {
|
|
115
|
+
const level = await this.getTakeoverLevel(project, environment);
|
|
116
|
+
const policy = DEFAULT_POLICIES[environment];
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
authorized: true, // Simplified for MVP
|
|
120
|
+
level,
|
|
121
|
+
environment,
|
|
122
|
+
requiresApproval: level === TakeoverLevel.L1_OBSERVATION || level === TakeoverLevel.L2_SUGGESTION
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Load permission configuration
|
|
128
|
+
*
|
|
129
|
+
* @param {string} project - Project name
|
|
130
|
+
* @returns {Promise<Object>} Permission config
|
|
131
|
+
*/
|
|
132
|
+
async loadPermissionConfig(project) {
|
|
133
|
+
const configPath = path.join(
|
|
134
|
+
this.projectRoot,
|
|
135
|
+
'.kiro/specs',
|
|
136
|
+
project,
|
|
137
|
+
'operations/permissions.json'
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
if (await fs.pathExists(configPath)) {
|
|
141
|
+
return await fs.readJson(configPath);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Return default config
|
|
145
|
+
return {
|
|
146
|
+
project,
|
|
147
|
+
environments: {}
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Save permission configuration
|
|
153
|
+
*
|
|
154
|
+
* @param {string} project - Project name
|
|
155
|
+
* @param {Object} config - Permission config
|
|
156
|
+
* @returns {Promise<void>}
|
|
157
|
+
*/
|
|
158
|
+
async savePermissionConfig(project, config) {
|
|
159
|
+
const configPath = path.join(
|
|
160
|
+
this.projectRoot,
|
|
161
|
+
'.kiro/specs',
|
|
162
|
+
project,
|
|
163
|
+
'operations/permissions.json'
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
await fs.ensureDir(path.dirname(configPath));
|
|
167
|
+
await fs.writeJson(configPath, config, { spaces: 2 });
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Check if level is allowed
|
|
172
|
+
*
|
|
173
|
+
* @param {string} level - Requested level
|
|
174
|
+
* @param {string} maxLevel - Maximum allowed level
|
|
175
|
+
* @returns {boolean} Whether level is allowed
|
|
176
|
+
*/
|
|
177
|
+
isLevelAllowed(level, maxLevel) {
|
|
178
|
+
const levels = Object.values(TakeoverLevel);
|
|
179
|
+
const levelIndex = levels.indexOf(level);
|
|
180
|
+
const maxIndex = levels.indexOf(maxLevel);
|
|
181
|
+
|
|
182
|
+
return levelIndex <= maxIndex;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Request permission elevation
|
|
187
|
+
*
|
|
188
|
+
* @param {string} operation - Operation requiring elevation
|
|
189
|
+
* @param {string} project - Project name
|
|
190
|
+
* @param {string} environment - Security environment
|
|
191
|
+
* @param {string} reason - Reason for elevation request
|
|
192
|
+
* @param {string} user - User requesting elevation
|
|
193
|
+
* @returns {Promise<Object>} Elevation result
|
|
194
|
+
*/
|
|
195
|
+
async requestElevation(operation, project, environment, reason, user = 'system') {
|
|
196
|
+
const config = await this.loadPermissionConfig(project);
|
|
197
|
+
const currentLevel = await this.getTakeoverLevel(project, environment);
|
|
198
|
+
|
|
199
|
+
// Create elevation request
|
|
200
|
+
const request = {
|
|
201
|
+
id: `elev-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
202
|
+
operation,
|
|
203
|
+
project,
|
|
204
|
+
environment,
|
|
205
|
+
currentLevel,
|
|
206
|
+
reason,
|
|
207
|
+
requestedBy: user,
|
|
208
|
+
requestedAt: new Date().toISOString(),
|
|
209
|
+
status: 'pending',
|
|
210
|
+
outcome: null,
|
|
211
|
+
approvedBy: null,
|
|
212
|
+
approvedAt: null
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
// Initialize elevation requests array
|
|
216
|
+
if (!config.elevationRequests) {
|
|
217
|
+
config.elevationRequests = [];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Add request
|
|
221
|
+
config.elevationRequests.push(request);
|
|
222
|
+
|
|
223
|
+
// Save config
|
|
224
|
+
await this.savePermissionConfig(project, config);
|
|
225
|
+
|
|
226
|
+
return {
|
|
227
|
+
success: true,
|
|
228
|
+
requestId: request.id,
|
|
229
|
+
status: 'pending',
|
|
230
|
+
message: 'Elevation request created. Awaiting approval.',
|
|
231
|
+
request
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Approve elevation request
|
|
237
|
+
*
|
|
238
|
+
* @param {string} project - Project name
|
|
239
|
+
* @param {string} requestId - Elevation request ID
|
|
240
|
+
* @param {string} approver - User approving the request
|
|
241
|
+
* @returns {Promise<Object>} Approval result
|
|
242
|
+
*/
|
|
243
|
+
async approveElevation(project, requestId, approver) {
|
|
244
|
+
const config = await this.loadPermissionConfig(project);
|
|
245
|
+
|
|
246
|
+
if (!config.elevationRequests) {
|
|
247
|
+
throw new Error('No elevation requests found');
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const request = config.elevationRequests.find(r => r.id === requestId);
|
|
251
|
+
|
|
252
|
+
if (!request) {
|
|
253
|
+
throw new Error(`Elevation request not found: ${requestId}`);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (request.status !== 'pending') {
|
|
257
|
+
throw new Error(`Elevation request already ${request.status}`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Update request
|
|
261
|
+
request.status = 'approved';
|
|
262
|
+
request.outcome = 'approved';
|
|
263
|
+
request.approvedBy = approver;
|
|
264
|
+
request.approvedAt = new Date().toISOString();
|
|
265
|
+
|
|
266
|
+
// Save config
|
|
267
|
+
await this.savePermissionConfig(project, config);
|
|
268
|
+
|
|
269
|
+
return {
|
|
270
|
+
success: true,
|
|
271
|
+
requestId,
|
|
272
|
+
status: 'approved',
|
|
273
|
+
message: 'Elevation request approved',
|
|
274
|
+
request
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Deny elevation request
|
|
280
|
+
*
|
|
281
|
+
* @param {string} project - Project name
|
|
282
|
+
* @param {string} requestId - Elevation request ID
|
|
283
|
+
* @param {string} denier - User denying the request
|
|
284
|
+
* @param {string} reason - Reason for denial
|
|
285
|
+
* @returns {Promise<Object>} Denial result
|
|
286
|
+
*/
|
|
287
|
+
async denyElevation(project, requestId, denier, reason) {
|
|
288
|
+
const config = await this.loadPermissionConfig(project);
|
|
289
|
+
|
|
290
|
+
if (!config.elevationRequests) {
|
|
291
|
+
throw new Error('No elevation requests found');
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const request = config.elevationRequests.find(r => r.id === requestId);
|
|
295
|
+
|
|
296
|
+
if (!request) {
|
|
297
|
+
throw new Error(`Elevation request not found: ${requestId}`);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (request.status !== 'pending') {
|
|
301
|
+
throw new Error(`Elevation request already ${request.status}`);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Update request
|
|
305
|
+
request.status = 'denied';
|
|
306
|
+
request.outcome = 'denied';
|
|
307
|
+
request.deniedBy = denier;
|
|
308
|
+
request.deniedAt = new Date().toISOString();
|
|
309
|
+
request.denialReason = reason;
|
|
310
|
+
|
|
311
|
+
// Save config
|
|
312
|
+
await this.savePermissionConfig(project, config);
|
|
313
|
+
|
|
314
|
+
return {
|
|
315
|
+
success: true,
|
|
316
|
+
requestId,
|
|
317
|
+
status: 'denied',
|
|
318
|
+
message: 'Elevation request denied',
|
|
319
|
+
request
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* List elevation requests
|
|
325
|
+
*
|
|
326
|
+
* @param {string} project - Project name
|
|
327
|
+
* @param {Object} filters - Filter criteria
|
|
328
|
+
* @param {string} filters.status - Filter by status
|
|
329
|
+
* @param {string} filters.environment - Filter by environment
|
|
330
|
+
* @returns {Promise<Array>} Array of elevation requests
|
|
331
|
+
*/
|
|
332
|
+
async listElevationRequests(project, filters = {}) {
|
|
333
|
+
const config = await this.loadPermissionConfig(project);
|
|
334
|
+
|
|
335
|
+
if (!config.elevationRequests) {
|
|
336
|
+
return [];
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
let requests = config.elevationRequests;
|
|
340
|
+
|
|
341
|
+
// Apply filters
|
|
342
|
+
if (filters.status) {
|
|
343
|
+
requests = requests.filter(r => r.status === filters.status);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (filters.environment) {
|
|
347
|
+
requests = requests.filter(r => r.environment === filters.environment);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return requests;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
module.exports = PermissionManager;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads operations spec templates from the template library
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const { DocumentType } = require('./models');
|
|
10
|
+
|
|
11
|
+
class TemplateLoader {
|
|
12
|
+
constructor(templateBasePath = null) {
|
|
13
|
+
// Default to package template directory
|
|
14
|
+
this.templateBasePath = templateBasePath || path.join(__dirname, '../../template/.kiro/templates/operations');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Load a template for a specific document type
|
|
19
|
+
*
|
|
20
|
+
* @param {string} documentType - Type of document (from DocumentType enum)
|
|
21
|
+
* @param {string} templateName - Template name (default: 'default')
|
|
22
|
+
* @returns {Promise<string>} Template content
|
|
23
|
+
*/
|
|
24
|
+
async loadTemplate(documentType, templateName = 'default') {
|
|
25
|
+
// Validate document type
|
|
26
|
+
const validTypes = Object.values(DocumentType);
|
|
27
|
+
if (!validTypes.includes(documentType)) {
|
|
28
|
+
throw new Error(`Invalid document type: ${documentType}. Must be one of: ${validTypes.join(', ')}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// tools.yaml is a YAML file, others are markdown
|
|
32
|
+
const fileName = documentType === DocumentType.TOOLS ? `${documentType}.yaml` : `${documentType}.md`;
|
|
33
|
+
|
|
34
|
+
// Build template path
|
|
35
|
+
const templatePath = path.join(
|
|
36
|
+
this.templateBasePath,
|
|
37
|
+
templateName,
|
|
38
|
+
fileName
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// Check if template exists
|
|
42
|
+
const exists = await fs.pathExists(templatePath);
|
|
43
|
+
if (!exists) {
|
|
44
|
+
throw new Error(`Template not found: ${templatePath}`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Load template content
|
|
48
|
+
const content = await fs.readFile(templatePath, 'utf8');
|
|
49
|
+
return content;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Load all templates for a template set
|
|
54
|
+
*
|
|
55
|
+
* @param {string} templateName - Template name (default: 'default')
|
|
56
|
+
* @returns {Promise<Object>} Map of document type to template content
|
|
57
|
+
*/
|
|
58
|
+
async loadAllTemplates(templateName = 'default') {
|
|
59
|
+
const templates = {};
|
|
60
|
+
const documentTypes = Object.values(DocumentType);
|
|
61
|
+
|
|
62
|
+
for (const docType of documentTypes) {
|
|
63
|
+
try {
|
|
64
|
+
templates[docType] = await this.loadTemplate(docType, templateName);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
// If a template is missing, include error message
|
|
67
|
+
templates[docType] = null;
|
|
68
|
+
console.warn(`Warning: Could not load template for ${docType}: ${error.message}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return templates;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* List available template sets
|
|
77
|
+
*
|
|
78
|
+
* @returns {Promise<string[]>} Array of template set names
|
|
79
|
+
*/
|
|
80
|
+
async listTemplateSets() {
|
|
81
|
+
const exists = await fs.pathExists(this.templateBasePath);
|
|
82
|
+
if (!exists) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const entries = await fs.readdir(this.templateBasePath, { withFileTypes: true });
|
|
87
|
+
const templateSets = entries
|
|
88
|
+
.filter(entry => entry.isDirectory())
|
|
89
|
+
.map(entry => entry.name);
|
|
90
|
+
|
|
91
|
+
return templateSets;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Check if a template set is complete (has all 9 document types)
|
|
96
|
+
*
|
|
97
|
+
* @param {string} templateName - Template name to check
|
|
98
|
+
* @returns {Promise<Object>} Completeness report
|
|
99
|
+
*/
|
|
100
|
+
async checkTemplateCompleteness(templateName = 'default') {
|
|
101
|
+
const documentTypes = Object.values(DocumentType);
|
|
102
|
+
const missing = [];
|
|
103
|
+
const present = [];
|
|
104
|
+
|
|
105
|
+
for (const docType of documentTypes) {
|
|
106
|
+
// tools.yaml is a YAML file, others are markdown
|
|
107
|
+
const fileName = docType === DocumentType.TOOLS ? `${docType}.yaml` : `${docType}.md`;
|
|
108
|
+
const templatePath = path.join(
|
|
109
|
+
this.templateBasePath,
|
|
110
|
+
templateName,
|
|
111
|
+
fileName
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
const exists = await fs.pathExists(templatePath);
|
|
115
|
+
if (exists) {
|
|
116
|
+
present.push(docType);
|
|
117
|
+
} else {
|
|
118
|
+
missing.push(docType);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
complete: missing.length === 0,
|
|
124
|
+
total: documentTypes.length,
|
|
125
|
+
present: present.length,
|
|
126
|
+
missing: missing.length,
|
|
127
|
+
presentTypes: present,
|
|
128
|
+
missingTypes: missing
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Get the file name for a document type
|
|
134
|
+
*
|
|
135
|
+
* @param {string} documentType - Type of document
|
|
136
|
+
* @returns {string} File name (e.g., 'deployment.md')
|
|
137
|
+
*/
|
|
138
|
+
getFileName(documentType) {
|
|
139
|
+
return `${documentType}.md`;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
module.exports = TemplateLoader;
|