@hongmaple0820/scale-engine 0.12.2 → 0.13.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.
Files changed (116) hide show
  1. package/README.md +30 -2
  2. package/dist/adapters/ClaudeCodeAdapter.d.ts +1 -0
  3. package/dist/adapters/ClaudeCodeAdapter.js.map +1 -1
  4. package/dist/adapters/KiroAdapter.d.ts +14 -0
  5. package/dist/adapters/KiroAdapter.js +180 -0
  6. package/dist/adapters/KiroAdapter.js.map +1 -0
  7. package/dist/adapters/index.d.ts +1 -0
  8. package/dist/adapters/index.js +3 -0
  9. package/dist/adapters/index.js.map +1 -1
  10. package/dist/api/cli.js +396 -5
  11. package/dist/api/cli.js.map +1 -1
  12. package/dist/api/doctor.d.ts +12 -0
  13. package/dist/api/doctor.js +232 -5
  14. package/dist/api/doctor.js.map +1 -1
  15. package/dist/api/quickstart.d.ts +19 -1
  16. package/dist/api/quickstart.js +103 -2
  17. package/dist/api/quickstart.js.map +1 -1
  18. package/dist/artifact/types.d.ts +16 -2
  19. package/dist/artifact/types.js.map +1 -1
  20. package/dist/cli/phaseCommands.d.ts +61 -0
  21. package/dist/cli/phaseCommands.js +559 -39
  22. package/dist/cli/phaseCommands.js.map +1 -1
  23. package/dist/cli/vibeCommands.d.ts +44 -0
  24. package/dist/cli/vibeCommands.js +244 -0
  25. package/dist/cli/vibeCommands.js.map +1 -0
  26. package/dist/guardrails/detectors.d.ts +9 -0
  27. package/dist/guardrails/detectors.js +102 -0
  28. package/dist/guardrails/detectors.js.map +1 -1
  29. package/dist/hooks/HookGeneratorEnhanced.js +29 -0
  30. package/dist/hooks/HookGeneratorEnhanced.js.map +1 -1
  31. package/dist/hooks/WorkflowHooksManager.js +20 -1
  32. package/dist/hooks/WorkflowHooksManager.js.map +1 -1
  33. package/dist/index.d.ts +6 -0
  34. package/dist/index.js +4 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/output/BrandThemeLoader.d.ts +54 -0
  37. package/dist/output/BrandThemeLoader.js +340 -0
  38. package/dist/output/BrandThemeLoader.js.map +1 -0
  39. package/dist/output/HTMLDocumentRenderer.d.ts +83 -0
  40. package/dist/output/HTMLDocumentRenderer.js +717 -0
  41. package/dist/output/HTMLDocumentRenderer.js.map +1 -0
  42. package/dist/output/UIPrototypeRenderer.d.ts +61 -0
  43. package/dist/output/UIPrototypeRenderer.js +500 -0
  44. package/dist/output/UIPrototypeRenderer.js.map +1 -0
  45. package/dist/output/index.d.ts +6 -0
  46. package/dist/output/index.js +6 -0
  47. package/dist/output/index.js.map +1 -0
  48. package/dist/prompts/PhasePromptRegistry.d.ts +53 -0
  49. package/dist/prompts/PhasePromptRegistry.js +517 -0
  50. package/dist/prompts/PhasePromptRegistry.js.map +1 -0
  51. package/dist/skills/SkillDiscovery.js +2 -1
  52. package/dist/skills/SkillDiscovery.js.map +1 -1
  53. package/dist/skills/index.d.ts +1 -0
  54. package/dist/skills/index.js +1 -0
  55. package/dist/skills/index.js.map +1 -1
  56. package/dist/skills/routing/SkillGate.d.ts +11 -0
  57. package/dist/skills/routing/SkillGate.js +76 -0
  58. package/dist/skills/routing/SkillGate.js.map +1 -0
  59. package/dist/skills/routing/SkillPlanner.d.ts +8 -0
  60. package/dist/skills/routing/SkillPlanner.js +91 -0
  61. package/dist/skills/routing/SkillPlanner.js.map +1 -0
  62. package/dist/skills/routing/SkillPolicy.d.ts +6 -0
  63. package/dist/skills/routing/SkillPolicy.js +146 -0
  64. package/dist/skills/routing/SkillPolicy.js.map +1 -0
  65. package/dist/skills/routing/SkillRoutingTypes.d.ts +72 -0
  66. package/dist/skills/routing/SkillRoutingTypes.js +2 -0
  67. package/dist/skills/routing/SkillRoutingTypes.js.map +1 -0
  68. package/dist/skills/routing/TaskIntentClassifier.d.ts +6 -0
  69. package/dist/skills/routing/TaskIntentClassifier.js +79 -0
  70. package/dist/skills/routing/TaskIntentClassifier.js.map +1 -0
  71. package/dist/skills/routing/index.d.ts +5 -0
  72. package/dist/skills/routing/index.js +6 -0
  73. package/dist/skills/routing/index.js.map +1 -0
  74. package/dist/workflow/GovernanceTemplates.d.ts +12 -0
  75. package/dist/workflow/GovernanceTemplates.js +515 -0
  76. package/dist/workflow/GovernanceTemplates.js.map +1 -0
  77. package/dist/workflow/PhaseMarkerTracker.d.ts +63 -0
  78. package/dist/workflow/PhaseMarkerTracker.js +291 -0
  79. package/dist/workflow/PhaseMarkerTracker.js.map +1 -0
  80. package/dist/workflow/SessionStateTracker.d.ts +74 -0
  81. package/dist/workflow/SessionStateTracker.js +270 -0
  82. package/dist/workflow/SessionStateTracker.js.map +1 -0
  83. package/dist/workflow/TaskArtifactScaffolder.d.ts +47 -0
  84. package/dist/workflow/TaskArtifactScaffolder.js +237 -0
  85. package/dist/workflow/TaskArtifactScaffolder.js.map +1 -0
  86. package/dist/workflow/TaskMetricsStore.d.ts +49 -0
  87. package/dist/workflow/TaskMetricsStore.js +149 -0
  88. package/dist/workflow/TaskMetricsStore.js.map +1 -0
  89. package/dist/workflow/VerificationCommands.d.ts +2 -0
  90. package/dist/workflow/VerificationCommands.js +7 -4
  91. package/dist/workflow/VerificationCommands.js.map +1 -1
  92. package/dist/workflow/VerificationProfile.d.ts +55 -0
  93. package/dist/workflow/VerificationProfile.js +133 -0
  94. package/dist/workflow/VerificationProfile.js.map +1 -0
  95. package/dist/workflow/WorkflowArtifactWriter.d.ts +113 -0
  96. package/dist/workflow/WorkflowArtifactWriter.js +241 -0
  97. package/dist/workflow/WorkflowArtifactWriter.js.map +1 -0
  98. package/dist/workflow/WorkflowEngine.d.ts +20 -2
  99. package/dist/workflow/WorkflowEngine.js +37 -8
  100. package/dist/workflow/WorkflowEngine.js.map +1 -1
  101. package/dist/workflow/autonomous/AutonomousDevLoop.d.ts +88 -0
  102. package/dist/workflow/autonomous/AutonomousDevLoop.js +381 -0
  103. package/dist/workflow/autonomous/AutonomousDevLoop.js.map +1 -0
  104. package/dist/workflow/autonomous/WorklogManager.d.ts +50 -0
  105. package/dist/workflow/autonomous/WorklogManager.js +264 -0
  106. package/dist/workflow/autonomous/WorklogManager.js.map +1 -0
  107. package/dist/workflow/autonomous/index.d.ts +2 -0
  108. package/dist/workflow/autonomous/index.js +4 -0
  109. package/dist/workflow/autonomous/index.js.map +1 -0
  110. package/dist/workflow/gates/GateSystem.d.ts +12 -3
  111. package/dist/workflow/gates/GateSystem.js +185 -41
  112. package/dist/workflow/gates/GateSystem.js.map +1 -1
  113. package/dist/workflow/index.d.ts +7 -0
  114. package/dist/workflow/index.js +7 -0
  115. package/dist/workflow/index.js.map +1 -1
  116. package/package.json +3 -3
package/dist/api/cli.js CHANGED
@@ -12,6 +12,11 @@ import { DangerousCommandDetector, SecretLeakDetector, RoleGateDetector, ScopeCr
12
12
  import { SQLiteKnowledgeBase } from '../knowledge/SQLiteKnowledgeBase.js';
13
13
  import { ContextBuilder } from '../context/ContextBuilder.js';
14
14
  import { FSMAgentBridge } from '../fsm/FSMAgentBridge.js';
15
+ import { CapabilityRegistry } from '../capabilities/CapabilityRegistry.js';
16
+ import { SkillRegistry } from '../skills/SkillRegistry.js';
17
+ import { registerCoreSkills } from '../skills/coreSkills.js';
18
+ import { registerExternalSkills } from '../skills/ExternalSkills.js';
19
+ import { createSkillPlan, evaluateSkillGate, loadSkillRoutingPolicy, skillPlanMarkdown } from '../skills/routing/index.js';
15
20
  import { createAdapter, SUPPORTED_AGENTS } from '../adapters/index.js';
16
21
  import { LessonExtractor, RuleProposer, HookGenerator, EvolutionEngine } from '../evolution/EvolutionEngine.js';
17
22
  import { Doctor } from './doctor.js';
@@ -21,17 +26,34 @@ import { listWorkflowPresets, getPresetsByScenario } from '../workflows/presets.
21
26
  import { EvidenceStore } from '../workflow/EvidenceStore.js';
22
27
  import { OutOfScopeStore } from '../workflow/OutOfScopeStore.js';
23
28
  import { ReviewStore } from '../workflow/ReviewStore.js';
24
- import { existsSync, mkdirSync, readFileSync } from 'node:fs';
25
- import { join } from 'node:path';
29
+ import { WorkflowEngine } from '../workflow/WorkflowEngine.js';
30
+ import { resolveVerificationTargets } from '../workflow/VerificationProfile.js';
31
+ import { writeGovernanceTemplates } from '../workflow/GovernanceTemplates.js';
32
+ import { TaskMetricsStore } from '../workflow/TaskMetricsStore.js';
33
+ import { checkTaskArtifactCompleteness } from '../workflow/TaskArtifactScaffolder.js';
34
+ import { WorkflowArtifactWriter } from '../workflow/WorkflowArtifactWriter.js';
35
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
36
+ import { join, resolve } from 'node:path';
26
37
  // ============================================================================
27
38
  // Engine bootstrap (单例 + lazy init)
28
39
  // ============================================================================
29
40
  const SCALE_DIR = process.env.SCALE_DIR ?? '.scale';
41
+ const PROJECT_DIR = process.env.SCALE_PROJECT_DIR ?? process.cwd();
30
42
  const DB_PATH = join(SCALE_DIR, 'scale.db');
43
+ function governanceModeFromScenario(scenario) {
44
+ if (scenario === 'critical')
45
+ return 'critical';
46
+ if (scenario === 'sandbox')
47
+ return 'minimal';
48
+ return 'standard';
49
+ }
31
50
  function ensureDir(dir) {
32
51
  if (!existsSync(dir))
33
52
  mkdirSync(dir, { recursive: true });
34
53
  }
54
+ function isTruthyFlag(value) {
55
+ return value === true || value === '' || value === 'true' || value === '1';
56
+ }
35
57
  let _engine = null;
36
58
  function getEngine() {
37
59
  if (!_engine)
@@ -60,7 +82,17 @@ function createEngine() {
60
82
  const kb = new SQLiteKnowledgeBase(eventBus, { dbPath: join(SCALE_DIR, 'knowledge.db') });
61
83
  const ctx = new ContextBuilder(store, kb, eventBus);
62
84
  const fsmAgentBridge = new FSMAgentBridge(fsm, store);
63
- return { eventBus, store, fsm, gateway, roleGate, kb, ctx, fsmAgentBridge };
85
+ const capabilityRegistry = new CapabilityRegistry(eventBus);
86
+ const skillRegistry = new SkillRegistry(eventBus);
87
+ registerCoreSkills(skillRegistry);
88
+ registerExternalSkills(skillRegistry, eventBus);
89
+ const workflowEngine = new WorkflowEngine({
90
+ eventBus,
91
+ capabilityRegistry,
92
+ skillRegistry,
93
+ scaleDir: SCALE_DIR,
94
+ });
95
+ return { eventBus, store, fsm, gateway, roleGate, kb, ctx, fsmAgentBridge, workflowEngine };
64
96
  }
65
97
  // ============================================================================
66
98
  // session commands
@@ -699,6 +731,161 @@ const stats = defineCommand({
699
731
  console.log(JSON.stringify({ ...s, eventCount: events.length }, null, 2));
700
732
  },
701
733
  });
734
+ const metricsList = defineCommand({
735
+ meta: { name: 'list', description: 'List M/L task workflow metrics' },
736
+ args: {
737
+ json: { type: 'boolean', default: false },
738
+ },
739
+ async run({ args }) {
740
+ const store = new TaskMetricsStore(SCALE_DIR);
741
+ const records = store.list();
742
+ const summary = store.summarize();
743
+ if (args.json) {
744
+ console.log(JSON.stringify({ summary, records }, null, 2));
745
+ return;
746
+ }
747
+ console.log('\nWorkflow Metrics');
748
+ console.log(` Total tasks: ${summary.total}`);
749
+ console.log(` First-pass verification rate: ${(summary.firstPassRate * 100).toFixed(1)}%`);
750
+ console.log(` Average fix iterations: ${summary.averageFixIterations.toFixed(2)}`);
751
+ console.log(` Artifact completeness: ${(summary.artifactCompletenessRate * 100).toFixed(1)}%`);
752
+ for (const record of records.slice(-10)) {
753
+ console.log(` - ${record.date} ${record.level} ${record.taskName}: ${record.finalGateStatus}`);
754
+ }
755
+ },
756
+ });
757
+ const metrics = defineCommand({
758
+ meta: { name: 'metrics', description: 'Inspect workflow task metrics' },
759
+ subCommands: { list: metricsList },
760
+ });
761
+ function normalizeTaskArtifactLevel(value) {
762
+ const normalized = String(value ?? 'M').trim().toUpperCase();
763
+ if (normalized === 'S' || normalized === 'M' || normalized === 'L' || normalized === 'CRITICAL') {
764
+ return normalized;
765
+ }
766
+ throw new Error(`Invalid task level "${String(value)}"; expected S, M, L, or CRITICAL.`);
767
+ }
768
+ const taskArtifactsCheck = defineCommand({
769
+ meta: { name: 'check', description: 'Check task artifact completeness' },
770
+ args: {
771
+ dir: { type: 'string', description: 'Task artifact directory; defaults to .scale/state/current.json artifactsDir' },
772
+ level: { type: 'string', description: 'Task level: S, M, L, or CRITICAL; defaults to current state level or M' },
773
+ 'warn-only': { type: 'boolean', default: false, description: 'Return zero even when artifacts are incomplete' },
774
+ json: { type: 'boolean', default: false },
775
+ },
776
+ run({ args }) {
777
+ const state = new WorkflowArtifactWriter(SCALE_DIR).readCurrentState();
778
+ let level;
779
+ try {
780
+ level = normalizeTaskArtifactLevel(args.level ?? state?.level ?? 'M');
781
+ }
782
+ catch (e) {
783
+ console.error(e.message);
784
+ process.exit(1);
785
+ }
786
+ const result = checkTaskArtifactCompleteness({
787
+ projectDir: PROJECT_DIR,
788
+ artifactsDir: args.dir ?? state?.artifactsDir,
789
+ level,
790
+ skillRequiredArtifacts: state?.requiredSkillArtifacts,
791
+ });
792
+ if (args.json) {
793
+ console.log(JSON.stringify(result, null, 2));
794
+ }
795
+ else {
796
+ console.log(`\nTask Artifacts: ${result.complete ? 'COMPLETE' : 'INCOMPLETE'}`);
797
+ if (result.artifactsDir)
798
+ console.log(` Directory: ${result.artifactsDir}`);
799
+ console.log(` Required: ${result.required.join(', ') || 'none'}`);
800
+ for (const file of result.missing)
801
+ console.log(` [MISSING] ${file}`);
802
+ for (const item of result.incomplete)
803
+ console.log(` [INCOMPLETE] ${item.file}: ${item.reason}`);
804
+ }
805
+ if (!result.complete && !args['warn-only'])
806
+ process.exitCode = 1;
807
+ },
808
+ });
809
+ const taskArtifacts = defineCommand({
810
+ meta: { name: 'task-artifacts', description: 'Inspect task artifact completeness' },
811
+ subCommands: { check: taskArtifactsCheck },
812
+ });
813
+ const preflight = defineCommand({
814
+ meta: { name: 'preflight', description: 'Run service-aware verification without a task artifact' },
815
+ args: {
816
+ 'build-cmd': { type: 'string', description: 'Override build command' },
817
+ 'lint-cmd': { type: 'string', description: 'Override lint command' },
818
+ 'test-cmd': { type: 'string', description: 'Override test command' },
819
+ 'coverage-cmd': { type: 'string', description: 'Override coverage command' },
820
+ profile: { type: 'string', description: 'Verification profile from .scale/verification.json' },
821
+ service: { type: 'string', description: 'Service name from .scale/verification.json; use all for required services' },
822
+ 'tdd-evidence': { type: 'string', description: 'Path to JSON TDD evidence with red/green/refactor/testFirst=true' },
823
+ 'tdd-strict': { type: 'boolean', default: false, description: 'Require TDD evidence before other gates' },
824
+ json: { type: 'boolean', default: false },
825
+ },
826
+ async run({ args }) {
827
+ const { workflowEngine } = getEngine();
828
+ const resolved = resolveVerificationTargets({
829
+ projectDir: PROJECT_DIR,
830
+ scaleDir: SCALE_DIR,
831
+ profile: args.profile,
832
+ service: args.service,
833
+ });
834
+ const targetResults = [];
835
+ if (!args.json) {
836
+ console.log('\nSCALE Preflight');
837
+ for (const warning of resolved.warnings)
838
+ console.log(` [WARN] ${warning}`);
839
+ console.log(` Profile: ${resolved.profileName}`);
840
+ }
841
+ for (const target of resolved.targets) {
842
+ if (!args.json) {
843
+ const label = target.service ? `${target.service.name} (${target.service.path})` : 'root';
844
+ console.log(`\n Target: ${label}`);
845
+ }
846
+ const gates = await workflowEngine.verify({
847
+ cwd: target.config.cwd,
848
+ build: args['build-cmd'] ?? target.config.build,
849
+ lint: args['lint-cmd'] ?? target.config.lint,
850
+ test: args['test-cmd'] ?? target.config.test,
851
+ coverage: args['coverage-cmd'] ?? target.config.coverage,
852
+ tddEvidence: args['tdd-evidence'],
853
+ tddStrict: isTruthyFlag(args['tdd-strict']),
854
+ });
855
+ const passed = gates.every(gate => gate.passed);
856
+ targetResults.push({
857
+ service: target.service?.name,
858
+ cwd: target.config.cwd ?? PROJECT_DIR,
859
+ gates,
860
+ passed,
861
+ });
862
+ if (!args.json) {
863
+ for (const gate of gates) {
864
+ console.log(` ${gate.passed ? '[PASS]' : '[FAIL]'} ${gate.gate}: ${gate.evidence.slice(0, 80)}`);
865
+ for (const blocker of gate.blockers)
866
+ console.log(` [BLOCKER] ${blocker.slice(0, 120)}`);
867
+ }
868
+ }
869
+ }
870
+ const passed = targetResults.length > 0 && targetResults.every(target => target.passed);
871
+ const result = {
872
+ phase: 'PREFLIGHT',
873
+ profile: resolved.profileName,
874
+ services: targetResults.map(target => target.service).filter(Boolean),
875
+ policy: resolved.policy,
876
+ targets: targetResults,
877
+ passed,
878
+ };
879
+ if (args.json) {
880
+ console.log(JSON.stringify(result, null, 2));
881
+ }
882
+ else {
883
+ console.log(`\nPREFLIGHT: ${passed ? 'PASSED' : 'FAILED'}\n`);
884
+ }
885
+ if (!passed)
886
+ process.exitCode = 1;
887
+ },
888
+ });
702
889
  const status = defineCommand({
703
890
  meta: { name: 'status', description: 'Show current SCALE workflow status' },
704
891
  args: {
@@ -821,8 +1008,88 @@ const init = defineCommand({
821
1008
  dir: { type: 'string', default: '.', description: 'Project directory' },
822
1009
  scenario: { type: 'string', default: 'standard', description: 'Scenario mode (sandbox/standard/critical)' },
823
1010
  quick: { type: 'boolean', default: false, description: 'Quick start with auto-detection' },
1011
+ interactive: { type: 'boolean', default: false, description: 'Interactive configuration mode with prompts' },
1012
+ 'coverage-threshold': { type: 'string', default: '80', description: 'Coverage threshold (default 80%)' },
1013
+ 'retry-threshold': { type: 'string', default: '3', description: 'Brute retry threshold (default 3)' },
1014
+ 'block-severity': { type: 'string', default: 'CRITICAL', description: 'Block severity level (CRITICAL/HIGH/MEDIUM)' },
824
1015
  },
825
1016
  async run({ args }) {
1017
+ // Interactive configuration mode
1018
+ if (args.interactive) {
1019
+ console.log('\n🔧 SCALE Engine Interactive Configuration\n');
1020
+ console.log('='.repeat(50));
1021
+ // Step 1: Detect and suggest agent platform
1022
+ const detection = detectPlatform(args.dir);
1023
+ console.log('\n📋 Step 1: Agent Platform Selection');
1024
+ console.log(` Detected suggestions: ${detection.suggestions.join(', ') || 'none'}`);
1025
+ const agentType = args.agent || detection.suggestions[0] || 'claude-code';
1026
+ console.log(` Using: ${agentType}`);
1027
+ // Step 2: Scenario mode
1028
+ console.log('\n📋 Step 2: Scenario Mode');
1029
+ console.log(' sandbox - No quality gates (POC/prototype)');
1030
+ console.log(' standard - Default quality gates');
1031
+ console.log(' critical - Hardened gates + manual approval');
1032
+ const scenarioMode = args.scenario;
1033
+ console.log(` Using: ${scenarioMode}`);
1034
+ // Step 3: Quality Gate Thresholds (quantified)
1035
+ console.log('\n📋 Step 3: Quality Gate Thresholds');
1036
+ const coverageThreshold = parseInt(args['coverage-threshold'], 10) || 80;
1037
+ const retryThreshold = parseInt(args['retry-threshold'], 10) || 3;
1038
+ const blockSeverity = args['block-severity'] || 'CRITICAL';
1039
+ console.log(` Coverage threshold: ${coverageThreshold}%`);
1040
+ console.log(` Retry threshold: ${retryThreshold} (brute retry block)`);
1041
+ console.log(` Block severity: ${blockSeverity}`);
1042
+ // Step 4: Write thresholds to .scale/thresholds.json
1043
+ const thresholdsPath = join(args.dir, '.scale', 'thresholds.json');
1044
+ ensureDir(join(args.dir, '.scale'));
1045
+ writeFileSync(thresholdsPath, JSON.stringify({
1046
+ coverage: { minimum: coverageThreshold, unit: 'percent' },
1047
+ retry: { bruteMaximum: retryThreshold, unit: 'count' },
1048
+ severity: { blockLevel: blockSeverity },
1049
+ gates: {
1050
+ G3_build: { required: scenarioMode !== 'sandbox', exitCode: 0 },
1051
+ G4_lint: { required: scenarioMode !== 'sandbox', exitCode: 0 },
1052
+ G5_tests: { required: scenarioMode !== 'sandbox', allPass: true },
1053
+ G6_coverage: { required: scenarioMode !== 'sandbox', minimum: coverageThreshold },
1054
+ G7_security: { required: scenarioMode === 'critical', noCritical: true },
1055
+ },
1056
+ }, null, 2));
1057
+ console.log(`\n ✓ Thresholds written to: ${thresholdsPath}`);
1058
+ // Initialize with adapter
1059
+ const adapter = createAdapter(agentType);
1060
+ const result = await adapter.init({
1061
+ projectDir: args.dir,
1062
+ agentType: agentType,
1063
+ scenarioMode,
1064
+ thresholdsPath,
1065
+ });
1066
+ const projectName = args.dir.split(/[/\\]/).pop() || 'Project';
1067
+ const governance = writeGovernanceTemplates(args.dir, {
1068
+ mode: governanceModeFromScenario(scenarioMode),
1069
+ projectName,
1070
+ });
1071
+ result.created.push(...governance.created);
1072
+ result.skipped.push(...governance.skipped);
1073
+ console.log(`\n✅ SCALE Engine initialized for ${agentType} (interactive mode)`);
1074
+ console.log(`\n📁 Created:`);
1075
+ for (const f of result.created)
1076
+ console.log(` + ${f}`);
1077
+ if (result.skipped.length > 0) {
1078
+ console.log(`\n⏭️ Skipped (already exist):`);
1079
+ for (const f of result.skipped)
1080
+ console.log(` - ${f}`);
1081
+ }
1082
+ console.log(`\n🔧 Configuration Summary:`);
1083
+ console.log(` Settings: ${result.settingsPath}`);
1084
+ console.log(` Knowledge: ${result.knowledgeDocPath}`);
1085
+ console.log(` Thresholds: ${thresholdsPath}`);
1086
+ console.log(` Data dir: ${result.scaleDir}`);
1087
+ console.log(` Scenario: ${scenarioMode}`);
1088
+ console.log(`\n📋 Next steps:`);
1089
+ console.log(` → scale doctor`);
1090
+ console.log(` → scale create Spec "<feature name>"`);
1091
+ return;
1092
+ }
826
1093
  // One-click quick start mode
827
1094
  if (args.quick || !args.agent) {
828
1095
  const qsResult = await quickStart(args.dir);
@@ -853,6 +1120,13 @@ const init = defineCommand({
853
1120
  // Manual agent specification mode
854
1121
  const adapter = createAdapter(args.agent);
855
1122
  const result = await adapter.init({ projectDir: args.dir, agentType: args.agent, scenarioMode: args.scenario });
1123
+ const projectName = args.dir.split(/[/\\]/).pop() || 'Project';
1124
+ const governance = writeGovernanceTemplates(args.dir, {
1125
+ mode: governanceModeFromScenario(args.scenario),
1126
+ projectName,
1127
+ });
1128
+ result.created.push(...governance.created);
1129
+ result.skipped.push(...governance.skipped);
856
1130
  console.log(`\n✅ SCALE Engine initialized for ${args.agent} (scenario: ${args.scenario})`);
857
1131
  console.log(`\n📁 Created:`);
858
1132
  for (const f of result.created)
@@ -1115,9 +1389,117 @@ const skillScan = defineCommand({
1115
1389
  }
1116
1390
  },
1117
1391
  });
1392
+ const skillPlanCommand = defineCommand({
1393
+ meta: { name: 'plan', description: 'Create or refresh a task skill plan' },
1394
+ args: {
1395
+ 'task-id': { type: 'positional', required: true },
1396
+ dir: { type: 'string', description: 'Task artifact directory; defaults to current state artifactsDir' },
1397
+ json: { type: 'boolean', default: false },
1398
+ },
1399
+ async run({ args }) {
1400
+ const { store } = getEngine();
1401
+ const task = await store.get(args['task-id']);
1402
+ if (!task || task.type !== 'Task') {
1403
+ console.error(`Task not found: ${args['task-id']}`);
1404
+ process.exit(1);
1405
+ }
1406
+ const payload = task.payload;
1407
+ const level = normalizeTaskArtifactLevel(payload.workflowLevel ?? 'M');
1408
+ const policy = loadSkillRoutingPolicy(PROJECT_DIR, SCALE_DIR);
1409
+ const plan = createSkillPlan({
1410
+ taskId: task.id,
1411
+ taskName: task.title,
1412
+ description: payload.description,
1413
+ level,
1414
+ services: payload.servicesTouched ?? [],
1415
+ files: payload.filesInvolved ?? [],
1416
+ policy,
1417
+ });
1418
+ const updatedPayload = {
1419
+ ...payload,
1420
+ skillIntents: plan.intents.map(intent => intent.domain),
1421
+ skillRoutingMode: plan.mode,
1422
+ skillPlanRequired: plan.required,
1423
+ requiredSkills: plan.requiredSkills,
1424
+ recommendedSkills: plan.recommendedSkills,
1425
+ requiredSkillArtifacts: plan.requiredArtifacts,
1426
+ requiredSkillVerification: plan.requiredVerification,
1427
+ };
1428
+ await store.update(task.id, { payload: updatedPayload });
1429
+ const state = new WorkflowArtifactWriter(SCALE_DIR).readCurrentState();
1430
+ const artifactsDir = args.dir ?? (state?.taskId === task.id ? state.artifactsDir : undefined);
1431
+ let writtenPath;
1432
+ if (artifactsDir) {
1433
+ const dir = resolve(PROJECT_DIR, artifactsDir);
1434
+ ensureDir(dir);
1435
+ writtenPath = join(dir, 'skill-plan.md');
1436
+ writeFileSync(writtenPath, skillPlanMarkdown(plan), 'utf-8');
1437
+ }
1438
+ new WorkflowArtifactWriter(SCALE_DIR).updateCurrentState({
1439
+ taskId: task.id,
1440
+ level,
1441
+ phase: 'plan',
1442
+ artifactsDir,
1443
+ skillIntents: plan.intents.map(intent => intent.domain),
1444
+ skillRoutingMode: plan.mode,
1445
+ skillPlanRequired: plan.required,
1446
+ skillPlanPath: writtenPath,
1447
+ requiredSkills: plan.requiredSkills,
1448
+ recommendedSkills: plan.recommendedSkills,
1449
+ requiredSkillArtifacts: plan.requiredArtifacts,
1450
+ requiredSkillVerification: plan.requiredVerification,
1451
+ });
1452
+ if (args.json) {
1453
+ console.log(JSON.stringify({ plan, writtenPath }, null, 2));
1454
+ return;
1455
+ }
1456
+ console.log('\nSkill Plan');
1457
+ console.log(` Task: ${task.id}`);
1458
+ console.log(` Intents: ${plan.intents.map(intent => intent.domain).join(', ') || 'none'}`);
1459
+ console.log(` Required skills: ${plan.requiredSkills.join(', ') || 'none'}`);
1460
+ console.log(` Recommended skills: ${plan.recommendedSkills.join(', ') || 'none'}`);
1461
+ console.log(` Required artifacts: ${plan.requiredArtifacts.join(', ') || 'none'}`);
1462
+ if (writtenPath)
1463
+ console.log(` Written: ${writtenPath}`);
1464
+ },
1465
+ });
1466
+ const skillCheckCommand = defineCommand({
1467
+ meta: { name: 'check', description: 'Check required skill evidence artifacts' },
1468
+ args: {
1469
+ dir: { type: 'string', description: 'Task artifact directory; defaults to current state artifactsDir' },
1470
+ level: { type: 'string', description: 'Task level: S, M, L, or CRITICAL; defaults to current state level or M' },
1471
+ json: { type: 'boolean', default: false },
1472
+ },
1473
+ run({ args }) {
1474
+ const state = new WorkflowArtifactWriter(SCALE_DIR).readCurrentState();
1475
+ const level = normalizeTaskArtifactLevel(args.level ?? state?.level ?? 'M');
1476
+ const policy = loadSkillRoutingPolicy(PROJECT_DIR, SCALE_DIR);
1477
+ const result = evaluateSkillGate({
1478
+ projectDir: PROJECT_DIR,
1479
+ artifactsDir: args.dir ?? state?.artifactsDir,
1480
+ level,
1481
+ requiredArtifacts: state?.requiredSkillArtifacts,
1482
+ mode: state?.skillRoutingMode ?? policy.policy.mode,
1483
+ enforceLevels: policy.policy.enforceLevels,
1484
+ });
1485
+ if (args.json) {
1486
+ console.log(JSON.stringify(result, null, 2));
1487
+ return;
1488
+ }
1489
+ console.log(`\nSkill Gate: ${result.complete ? 'COMPLETE' : 'INCOMPLETE'}`);
1490
+ console.log(` Mode: ${result.mode}`);
1491
+ console.log(` Required: ${result.required.join(', ') || 'none'}`);
1492
+ for (const file of result.missing)
1493
+ console.log(` [MISSING] ${file}`);
1494
+ for (const item of result.incomplete)
1495
+ console.log(` [INCOMPLETE] ${item.file}: ${item.reason}`);
1496
+ if (result.blocked)
1497
+ process.exitCode = 1;
1498
+ },
1499
+ });
1118
1500
  const skill = defineCommand({
1119
1501
  meta: { name: 'skill', description: 'Skill discovery and management' },
1120
- subCommands: { scan: skillScan },
1502
+ subCommands: { scan: skillScan, plan: skillPlanCommand, check: skillCheckCommand },
1121
1503
  });
1122
1504
  // ============================================================================
1123
1505
  // agent commands — Multi-Agent 协作系统 (Phase 9)
@@ -1242,11 +1624,16 @@ const team = defineCommand({
1242
1624
  // ============================================================================
1243
1625
  import * as phaseCommands from '../cli/phaseCommands.js';
1244
1626
  import * as liteCommands from '../cli/liteCommands.js';
1627
+ import * as vibeCommands from '../cli/vibeCommands.js';
1245
1628
  const main = defineCommand({
1246
- meta: { name: 'scale', version: '0.10.1', description: 'SCALE Engine v0.10.1 CLI - hardened phase workflow gates: define/plan/build/verify/review/ship; Lite Mode: scale lite; 11 agents; 10 workflows; 9 detectors' },
1629
+ meta: { name: 'scale', version: '0.13.0', description: 'SCALE Engine v0.13.0 CLI - hardened phase workflow gates: define/plan/build/verify/review/ship; Vibe templates: scale vibe; 16 platform adapters; 12 agents; 10 workflows; 19 detectors' },
1247
1630
  subCommands: {
1248
1631
  // Lite Mode (agent-skills style interactive entry)
1249
1632
  lite: liteCommands.liteCommand,
1633
+ // Vibe Templates (one-click prompt workflow)
1634
+ vibe: vibeCommands.vibeCommand,
1635
+ 'vibe-next': vibeCommands.vibeNextCommand,
1636
+ 'vibe-index': vibeCommands.vibeIndexCommand,
1250
1637
  // Phase-Aligned Commands (agent-skills style)
1251
1638
  define: phaseCommands.phaseDefine,
1252
1639
  plan: phaseCommands.phasePlan,
@@ -1269,10 +1656,14 @@ const main = defineCommand({
1269
1656
  context,
1270
1657
  evolve,
1271
1658
  stats,
1659
+ preflight,
1660
+ metrics,
1661
+ 'task-artifacts': taskArtifacts,
1272
1662
  status,
1273
1663
  workflow,
1274
1664
  evidence,
1275
1665
  skill,
1666
+ skills: skill,
1276
1667
  agent,
1277
1668
  team,
1278
1669
  'create-prd': createPRD,