@hongmaple0820/scale-engine 0.46.0 → 0.48.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 (83) hide show
  1. package/README.en.md +8 -2
  2. package/README.md +9 -3
  3. package/dist/api/cli.js +977 -6096
  4. package/dist/api/cli.js.map +1 -1
  5. package/dist/api/onboard.d.ts +34 -0
  6. package/dist/api/onboard.js +192 -0
  7. package/dist/api/onboard.js.map +1 -0
  8. package/dist/api/quickstart.js +1 -0
  9. package/dist/api/quickstart.js.map +1 -1
  10. package/dist/cli/artifactCrudCommands.d.ts +67 -0
  11. package/dist/cli/artifactCrudCommands.js +182 -0
  12. package/dist/cli/artifactCrudCommands.js.map +1 -0
  13. package/dist/cli/codegraphCommands.d.ts +1 -0
  14. package/dist/cli/codegraphCommands.js +241 -0
  15. package/dist/cli/codegraphCommands.js.map +1 -0
  16. package/dist/cli/contextCommands.d.ts +1 -0
  17. package/dist/cli/contextCommands.js +415 -0
  18. package/dist/cli/contextCommands.js.map +1 -0
  19. package/dist/cli/dependencyTddCommands.d.ts +92 -0
  20. package/dist/cli/dependencyTddCommands.js +174 -0
  21. package/dist/cli/dependencyTddCommands.js.map +1 -0
  22. package/dist/cli/diagnoseHuntCommands.d.ts +135 -0
  23. package/dist/cli/diagnoseHuntCommands.js +224 -0
  24. package/dist/cli/diagnoseHuntCommands.js.map +1 -0
  25. package/dist/cli/engineBootstrap.d.ts +39 -0
  26. package/dist/cli/engineBootstrap.js +129 -0
  27. package/dist/cli/engineBootstrap.js.map +1 -0
  28. package/dist/cli/evalCommands.d.ts +1 -0
  29. package/dist/cli/evalCommands.js +262 -0
  30. package/dist/cli/evalCommands.js.map +1 -0
  31. package/dist/cli/evolveDoctorCommands.d.ts +18 -0
  32. package/dist/cli/evolveDoctorCommands.js +59 -0
  33. package/dist/cli/evolveDoctorCommands.js.map +1 -0
  34. package/dist/cli/gateInlineCommands.d.ts +43 -0
  35. package/dist/cli/gateInlineCommands.js +74 -0
  36. package/dist/cli/gateInlineCommands.js.map +1 -0
  37. package/dist/cli/initConfigCommands.d.ts +138 -0
  38. package/dist/cli/initConfigCommands.js +602 -0
  39. package/dist/cli/initConfigCommands.js.map +1 -0
  40. package/dist/cli/metaGovernanceCommands.d.ts +11 -0
  41. package/dist/cli/metaGovernanceCommands.js +55 -0
  42. package/dist/cli/metaGovernanceCommands.js.map +1 -0
  43. package/dist/cli/onboardCommands.d.ts +22 -0
  44. package/dist/cli/onboardCommands.js +42 -0
  45. package/dist/cli/onboardCommands.js.map +1 -0
  46. package/dist/cli/runtimeSkillCommands.d.ts +6 -0
  47. package/dist/cli/runtimeSkillCommands.js +1515 -0
  48. package/dist/cli/runtimeSkillCommands.js.map +1 -0
  49. package/dist/cli/sessionCommands.d.ts +17 -0
  50. package/dist/cli/sessionCommands.js +38 -0
  51. package/dist/cli/sessionCommands.js.map +1 -0
  52. package/dist/cli/toolAgentCommands.d.ts +3 -0
  53. package/dist/cli/toolAgentCommands.js +441 -0
  54. package/dist/cli/toolAgentCommands.js.map +1 -0
  55. package/dist/cli/transitionCommands.d.ts +62 -0
  56. package/dist/cli/transitionCommands.js +174 -0
  57. package/dist/cli/transitionCommands.js.map +1 -0
  58. package/dist/cli/upgradeAssetsCommands.d.ts +44 -0
  59. package/dist/cli/upgradeAssetsCommands.js +933 -0
  60. package/dist/cli/upgradeAssetsCommands.js.map +1 -0
  61. package/dist/cli/workflowEvidenceCommands.d.ts +34 -0
  62. package/dist/cli/workflowEvidenceCommands.js +130 -0
  63. package/dist/cli/workflowEvidenceCommands.js.map +1 -0
  64. package/dist/skills/ExternalSkills.js +4 -0
  65. package/dist/skills/ExternalSkills.js.map +1 -1
  66. package/dist/skills/SkillInstaller.js +4 -0
  67. package/dist/skills/SkillInstaller.js.map +1 -1
  68. package/dist/version.d.ts +1 -1
  69. package/dist/version.js +1 -1
  70. package/dist/workflow/GateCatalog.d.ts +2 -1
  71. package/dist/workflow/GateCatalog.js +6 -2
  72. package/dist/workflow/GateCatalog.js.map +1 -1
  73. package/dist/workflow/UpgradeManager.d.ts +25 -0
  74. package/dist/workflow/UpgradeManager.js +81 -0
  75. package/dist/workflow/UpgradeManager.js.map +1 -1
  76. package/dist/workflow/gates/EnhancedGates.js +49 -4
  77. package/dist/workflow/gates/EnhancedGates.js.map +1 -1
  78. package/dist/workflow/gates/MetaGovernanceGates.js +42 -5
  79. package/dist/workflow/gates/MetaGovernanceGates.js.map +1 -1
  80. package/docs/guides/FAST_COMMIT_GUIDE.md +136 -0
  81. package/docs/guides/LEARNING_PATH.md +237 -0
  82. package/docs/guides/UPGRADE_AUTOMATION.md +199 -0
  83. package/package.json +2 -1
@@ -0,0 +1,602 @@
1
+ // SCALE Engine — Init, Bootstrap, Setup, and Config CLI Commands
2
+ // Extracted from src/api/cli.ts for modular CLI architecture.
3
+ import { defineCommand } from 'citty';
4
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
5
+ import { join, resolve } from 'node:path';
6
+ import { SCALE_DIR, PROJECT_DIR, isTruthyFlag, ensureDir, governanceModeFromScenario, profileFromScenario, writeConfigYaml, } from './engineBootstrap.js';
7
+ import { createAdapter, SUPPORTED_AGENTS } from '../adapters/index.js';
8
+ import { quickStart, detectPlatform, governanceNextSteps } from '../api/quickstart.js';
9
+ import { bootstrapDependencies } from '../bootstrap/DependencyBootstrap.js';
10
+ import { renderDependencyBootstrapReport } from '../bootstrap/DependencyBootstrapRenderer.js';
11
+ import { runSetupWizard } from '../setup/SetupWizard.js';
12
+ import { verifySetup } from '../setup/SetupVerification.js';
13
+ import { resolveCliLanguage } from '../i18n/Language.js';
14
+ import { getBootstrapPlanForProfile, getProfile as getConfigProfile, generateConfigForProfile, listProfiles as listConfigProfiles, } from '../config/profiles.js';
15
+ import { writeGovernanceTemplates } from '../workflow/GovernanceTemplates.js';
16
+ // ============================================================================
17
+ // Helper utilities
18
+ // ============================================================================
19
+ function parseToolIds(value) {
20
+ const raw = String(value ?? '').trim();
21
+ if (!raw)
22
+ return undefined;
23
+ return raw.split(',').map(item => item.trim()).filter(Boolean);
24
+ }
25
+ function parseCommaList(value) {
26
+ return parseToolIds(value) ?? [];
27
+ }
28
+ function uniqueStrings(items) {
29
+ return [...new Set(items)];
30
+ }
31
+ function normalizeMemoryModeArg(value) {
32
+ const normalized = String(value ?? '').trim().toLowerCase();
33
+ if (normalized === 'auto' || normalized === 'local-only' || normalized === 'external-first')
34
+ return normalized;
35
+ return undefined;
36
+ }
37
+ function normalizeMemoryWriteModeArg(value) {
38
+ const normalized = String(value ?? '').trim().toLowerCase();
39
+ if (normalized === 'disabled' || normalized === 'candidate-only' || normalized === 'enabled')
40
+ return normalized;
41
+ return undefined;
42
+ }
43
+ function resolveSetupPacks(args) {
44
+ const explicitPacks = parseCommaList(args.pack);
45
+ const recommendedPacks = args.profile
46
+ ? getBootstrapPlanForProfile(String(args.profile), args['governance-pack'] ? String(args['governance-pack']) : undefined).packs
47
+ : [];
48
+ return { explicitPacks, recommendedPacks };
49
+ }
50
+ function renderSetupVerifyReport(report, lang) {
51
+ if (lang === 'zh') {
52
+ console.log('\nSCALE 安装验收');
53
+ console.log(` 项目: ${report.projectDir}`);
54
+ console.log(` 依赖包: ${report.packIds.join(', ') || 'full'}`);
55
+ console.log(` 结论: ${report.ok ? '通过' : '未通过'}`);
56
+ console.log(` 阻塞项: ${report.summary.blockingIssues.length}`);
57
+ console.log(` 受管能力: ${report.summary.installedTools}/${report.summary.totalTools}`);
58
+ console.log(` 记忆供应商: ${report.summary.availableMemoryProviders}`);
59
+ console.log(` 代码图谱供应商: ${report.summary.availableCodeProviders}`);
60
+ if (report.summary.blockingIssues.length > 0) {
61
+ console.log(' 阻塞详情:');
62
+ for (const issue of report.summary.blockingIssues)
63
+ console.log(` - ${issue}`);
64
+ }
65
+ if (report.warnings.length > 0) {
66
+ console.log(` 警告${report.warnings.length > 12 ? ` (显示前 12 条,共 ${report.warnings.length} 条)` : ''}:`);
67
+ for (const warning of report.warnings.slice(0, 12))
68
+ console.log(` - ${warning}`);
69
+ }
70
+ if (report.recommendations.length > 0) {
71
+ console.log(' 下一步:');
72
+ for (const command of report.recommendations.slice(0, 12))
73
+ console.log(` ${command}`);
74
+ }
75
+ return;
76
+ }
77
+ console.log('\nSCALE Setup Verification');
78
+ console.log(` Project: ${report.projectDir}`);
79
+ console.log(` Packs: ${report.packIds.join(', ') || 'full'}`);
80
+ console.log(` Result: ${report.ok ? 'passed' : 'failed'}`);
81
+ console.log(` Blocking issues: ${report.summary.blockingIssues.length}`);
82
+ console.log(` Governed capabilities: ${report.summary.installedTools}/${report.summary.totalTools}`);
83
+ console.log(` Memory providers: ${report.summary.availableMemoryProviders}`);
84
+ console.log(` Code providers: ${report.summary.availableCodeProviders}`);
85
+ if (report.summary.blockingIssues.length > 0) {
86
+ console.log(' Blockers:');
87
+ for (const issue of report.summary.blockingIssues)
88
+ console.log(` - ${issue}`);
89
+ }
90
+ if (report.warnings.length > 0) {
91
+ console.log(` Warnings${report.warnings.length > 12 ? ` (showing first 12 of ${report.warnings.length})` : ''}:`);
92
+ for (const warning of report.warnings.slice(0, 12))
93
+ console.log(` - ${warning}`);
94
+ }
95
+ if (report.recommendations.length > 0) {
96
+ console.log(' Next:');
97
+ for (const command of report.recommendations.slice(0, 12))
98
+ console.log(` ${command}`);
99
+ }
100
+ }
101
+ // ============================================================================
102
+ // init command
103
+ // ============================================================================
104
+ export const initCommand = defineCommand({
105
+ meta: { name: 'init', description: 'Initialize SCALE Engine governance in current project (use --with-deps to also install third-party skills, CLIs, memory, and knowledge providers)' },
106
+ args: {
107
+ agent: { type: 'string', default: '', description: `Agent type (${SUPPORTED_AGENTS.join('/')}) - auto-detected if not specified` },
108
+ dir: { type: 'string', default: '.', description: 'Project directory' },
109
+ json: { type: 'boolean', default: false, description: 'Output initialization result as JSON' },
110
+ scenario: { type: 'string', default: 'standard', description: 'Scenario mode (sandbox/standard/critical)' },
111
+ 'governance-pack': {
112
+ type: 'string',
113
+ default: 'standard',
114
+ description: 'Governance template pack (standard/project-scaffold/scale-engine-repo/moe-workspace/resource-governance/go-service-matrix/node-library/frontend-app)',
115
+ },
116
+ quick: { type: 'boolean', default: false, description: 'Quick start with auto-detection' },
117
+ interactive: { type: 'boolean', default: false, description: 'Interactive configuration mode with prompts' },
118
+ profile: { type: 'string', default: '', description: 'Configuration profile (minimal/standard/advanced). Auto-mapped from scenario if not specified' },
119
+ 'coverage-threshold': { type: 'string', default: '80', description: 'Coverage threshold (default 80%)' },
120
+ 'retry-threshold': { type: 'string', default: '3', description: 'Brute retry threshold (default 3)' },
121
+ 'block-severity': { type: 'string', default: 'CRITICAL', description: 'Block severity level (CRITICAL/HIGH/MEDIUM)' },
122
+ 'with-deps': { type: 'boolean', default: false, description: 'Also install third-party skills, CLIs, memory, and knowledge providers after governance init' },
123
+ },
124
+ async run({ args }) {
125
+ // Interactive configuration mode
126
+ if (args.interactive) {
127
+ console.log('\n🔧 SCALE Engine Interactive Configuration\n');
128
+ console.log('='.repeat(50));
129
+ // Step 1: Detect and suggest agent platform
130
+ const detection = detectPlatform(args.dir);
131
+ console.log('\n📋 Step 1: Agent Platform Selection');
132
+ console.log(` Detected suggestions: ${detection.suggestions.join(', ') || 'none'}`);
133
+ const agentType = args.agent || detection.suggestions[0] || 'claude-code';
134
+ console.log(` Using: ${agentType}`);
135
+ // Step 2: Scenario mode
136
+ console.log('\n📋 Step 2: Scenario Mode');
137
+ console.log(' sandbox - No quality gates (POC/prototype)');
138
+ console.log(' standard - Default quality gates');
139
+ console.log(' critical - Hardened gates + manual approval');
140
+ const scenarioMode = args.scenario;
141
+ console.log(` Using: ${scenarioMode}`);
142
+ // Step 3: Quality Gate Thresholds (quantified)
143
+ console.log('\n📋 Step 3: Quality Gate Thresholds');
144
+ const coverageThreshold = parseInt(args['coverage-threshold'], 10) || 80;
145
+ const retryThreshold = parseInt(args['retry-threshold'], 10) || 3;
146
+ const blockSeverity = args['block-severity'] || 'CRITICAL';
147
+ console.log(` Coverage threshold: ${coverageThreshold}%`);
148
+ console.log(` Retry threshold: ${retryThreshold} (brute retry block)`);
149
+ console.log(` Block severity: ${blockSeverity}`);
150
+ // Step 4: Write thresholds to .scale/thresholds.json
151
+ const thresholdsPath = join(args.dir, '.scale', 'thresholds.json');
152
+ ensureDir(join(args.dir, '.scale'));
153
+ writeFileSync(thresholdsPath, JSON.stringify({
154
+ coverage: { minimum: coverageThreshold, unit: 'percent' },
155
+ retry: { bruteMaximum: retryThreshold, unit: 'count' },
156
+ severity: { blockLevel: blockSeverity },
157
+ gates: {
158
+ G3_build: { required: scenarioMode !== 'sandbox', exitCode: 0 },
159
+ G4_lint: { required: scenarioMode !== 'sandbox', exitCode: 0 },
160
+ G5_tests: { required: scenarioMode !== 'sandbox', allPass: true },
161
+ G6_coverage: { required: scenarioMode !== 'sandbox', minimum: coverageThreshold },
162
+ G7_security: { required: scenarioMode === 'critical', noCritical: true },
163
+ },
164
+ }, null, 2));
165
+ console.log(`\n ✓ Thresholds written to: ${thresholdsPath}`);
166
+ // Initialize with adapter
167
+ const adapter = createAdapter(agentType);
168
+ const result = await adapter.init({
169
+ projectDir: args.dir,
170
+ agentType: agentType,
171
+ scenarioMode,
172
+ thresholdsPath,
173
+ });
174
+ const projectName = args.dir.split(/[/\\]/).pop() || 'Project';
175
+ const governance = writeGovernanceTemplates(args.dir, {
176
+ mode: governanceModeFromScenario(scenarioMode),
177
+ projectName,
178
+ pack: args['governance-pack'],
179
+ });
180
+ result.created.push(...governance.created);
181
+ result.skipped.push(...governance.skipped);
182
+ // Generate config.yaml from profile
183
+ const profileId = args.profile || profileFromScenario(scenarioMode);
184
+ const configPath = writeConfigYaml(args.dir, profileId, projectName, [agentType]);
185
+ result.created.push(configPath);
186
+ console.log(`\n✅ SCALE Engine initialized for ${agentType} (interactive mode, profile: ${profileId})`);
187
+ console.log(`\n📁 Created:`);
188
+ for (const f of result.created)
189
+ console.log(` + ${f}`);
190
+ if (result.skipped.length > 0) {
191
+ console.log(`\n⏭️ Skipped (already exist):`);
192
+ for (const f of result.skipped)
193
+ console.log(` - ${f}`);
194
+ }
195
+ console.log(`\n🔧 Configuration Summary:`);
196
+ console.log(` Settings: ${result.settingsPath}`);
197
+ console.log(` Knowledge: ${result.knowledgeDocPath}`);
198
+ console.log(` Thresholds: ${thresholdsPath}`);
199
+ console.log(` Config: ${configPath}`);
200
+ console.log(` Data dir: ${result.scaleDir}`);
201
+ console.log(` Scenario: ${scenarioMode}`);
202
+ console.log(` Profile: ${profileId}`);
203
+ console.log(`\n📋 Next steps:`);
204
+ for (const step of governanceNextSteps({
205
+ profileId,
206
+ governancePack: String(args['governance-pack']),
207
+ }))
208
+ console.log(` → ${step}`);
209
+ // Auto-install third-party deps if --with-deps
210
+ if (args['with-deps']) {
211
+ console.log(`\n🧰 Installing third-party dependencies (full pack)...`);
212
+ const depReport = await bootstrapDependencies({
213
+ projectDir: resolve(args.dir),
214
+ scaleDir: join(resolve(args.dir), '.scale'),
215
+ packIds: ['full'],
216
+ includeIds: [],
217
+ apply: true,
218
+ });
219
+ console.log(` ✓ ${depReport.summary.installed}/${depReport.summary.total} dependencies installed`);
220
+ if (depReport.summary.needsInit > 0)
221
+ console.log(` ⚠ ${depReport.summary.needsInit} need manual init`);
222
+ if (depReport.summary.failed > 0)
223
+ console.log(` ✗ ${depReport.summary.failed} failed`);
224
+ }
225
+ return;
226
+ }
227
+ // One-click quick start mode
228
+ if (!args.agent) {
229
+ const profileId = args.profile || profileFromScenario(args.scenario);
230
+ const qsResult = await quickStart(args.dir, {
231
+ governancePack: args['governance-pack'],
232
+ profileId,
233
+ });
234
+ // Generate config.yaml from profile
235
+ if (qsResult.success) {
236
+ const projectName = args.dir.split(/[/\\]/).pop() || 'Project';
237
+ const detectedAgent = qsResult.platform ? [qsResult.platform] : [];
238
+ const configPath = writeConfigYaml(args.dir, profileId, projectName, detectedAgent);
239
+ qsResult.created.push(configPath);
240
+ }
241
+ if (args.json) {
242
+ const detection = qsResult.success ? undefined : detectPlatform(args.dir);
243
+ console.log(JSON.stringify({
244
+ ok: qsResult.success,
245
+ mode: qsResult.success && !qsResult.platform ? 'governance-only' : 'quick',
246
+ platform: qsResult.platform,
247
+ created: qsResult.created,
248
+ skipped: qsResult.skipped,
249
+ constraintsApplied: qsResult.constraintsApplied,
250
+ workflowCapabilities: qsResult.workflowCapabilities,
251
+ capabilitiesEnabled: qsResult.capabilitiesEnabled,
252
+ knowledgeGraph: qsResult.knowledgeGraph,
253
+ dependencyBootstrapCommand: qsResult.dependencyBootstrapCommand,
254
+ nextSteps: qsResult.nextSteps,
255
+ suggestions: detection?.suggestions ?? [],
256
+ }, null, 2));
257
+ return;
258
+ }
259
+ if (qsResult.success) {
260
+ if (!qsResult.platform)
261
+ console.log(`\nSCALE governance templates initialized`);
262
+ else
263
+ console.log(`\n✅ SCALE Engine Quick Start completed for ${qsResult.platform}`);
264
+ console.log(`\n📁 Created (${qsResult.created.length}):`);
265
+ for (const f of qsResult.created)
266
+ console.log(` + ${f}`);
267
+ if (qsResult.skipped.length > 0) {
268
+ console.log(`\n⏭️ Skipped (${qsResult.skipped.length}):`);
269
+ for (const f of qsResult.skipped)
270
+ console.log(` - ${f}`);
271
+ }
272
+ console.log(`\n🔒 Physical constraints applied: ${qsResult.constraintsApplied}`);
273
+ console.log(`\n🧭 Workflow capability plan: ${qsResult.workflowCapabilities.join(', ')}`);
274
+ console.log(`\n🧰 Dependency bootstrap: ${qsResult.dependencyBootstrapCommand}`);
275
+ console.log(`\n📋 Next steps:`);
276
+ for (const step of qsResult.nextSteps)
277
+ console.log(` → ${step}`);
278
+ // Auto-install third-party deps if --with-deps
279
+ if (args['with-deps']) {
280
+ console.log(`\n🧰 Installing third-party dependencies (full pack)...`);
281
+ const depReport = await bootstrapDependencies({
282
+ projectDir: resolve(args.dir),
283
+ scaleDir: join(resolve(args.dir), '.scale'),
284
+ packIds: ['full'],
285
+ includeIds: [],
286
+ apply: true,
287
+ });
288
+ console.log(` ✓ ${depReport.summary.installed}/${depReport.summary.total} dependencies installed`);
289
+ if (depReport.summary.needsInit > 0)
290
+ console.log(` ⚠ ${depReport.summary.needsInit} need manual init`);
291
+ if (depReport.summary.failed > 0)
292
+ console.log(` ✗ ${depReport.summary.failed} failed`);
293
+ }
294
+ }
295
+ else {
296
+ console.log(`\n⚠️ No agent platform detected`);
297
+ const detection = detectPlatform(args.dir);
298
+ console.log(`\n📋 Suggested platforms: ${detection.suggestions.join(', ')}`);
299
+ console.log(`\n→ Run: scale init --agent <platform>`);
300
+ }
301
+ return;
302
+ }
303
+ // Manual agent specification mode
304
+ const adapter = createAdapter(args.agent);
305
+ const result = await adapter.init({ projectDir: args.dir, agentType: args.agent, scenarioMode: args.scenario });
306
+ const projectName = args.dir.split(/[/\\]/).pop() || 'Project';
307
+ const governance = writeGovernanceTemplates(args.dir, {
308
+ mode: governanceModeFromScenario(args.scenario),
309
+ projectName,
310
+ pack: args['governance-pack'],
311
+ });
312
+ result.created.push(...governance.created);
313
+ result.skipped.push(...governance.skipped);
314
+ // Generate config.yaml from profile
315
+ const profileId = args.profile || profileFromScenario(args.scenario);
316
+ const configPath = writeConfigYaml(args.dir, profileId, projectName, [args.agent]);
317
+ result.created.push(configPath);
318
+ if (args.json) {
319
+ console.log(JSON.stringify({
320
+ ok: true,
321
+ mode: args.quick ? 'quick-agent' : 'manual',
322
+ agent: args.agent,
323
+ scenario: args.scenario,
324
+ profile: profileId,
325
+ governancePack: args['governance-pack'],
326
+ settingsPath: result.settingsPath,
327
+ knowledgeDocPath: result.knowledgeDocPath,
328
+ configPath,
329
+ scaleDir: result.scaleDir,
330
+ created: result.created,
331
+ skipped: result.skipped,
332
+ nextSteps: governanceNextSteps({
333
+ profileId,
334
+ governancePack: String(args['governance-pack']),
335
+ }),
336
+ }, null, 2));
337
+ return;
338
+ }
339
+ console.log(`\n✅ SCALE Engine initialized for ${args.agent} (scenario: ${args.scenario}, profile: ${profileId})`);
340
+ console.log(`\n📁 Created:`);
341
+ for (const f of result.created)
342
+ console.log(` + ${f}`);
343
+ if (result.skipped.length > 0) {
344
+ console.log(`\n⏭️ Skipped (already exist):`);
345
+ for (const f of result.skipped)
346
+ console.log(` - ${f}`);
347
+ }
348
+ console.log(`\n🔧 Settings: ${result.settingsPath}`);
349
+ console.log(`\n📖 Knowledge: ${result.knowledgeDocPath}`);
350
+ console.log(`\n📄 Config: ${configPath}`);
351
+ console.log(`\n📂 Data dir: ${result.scaleDir}`);
352
+ console.log(`\n📋 Next steps:`);
353
+ for (const step of governanceNextSteps({
354
+ profileId,
355
+ governancePack: String(args['governance-pack']),
356
+ }))
357
+ console.log(` → ${step}`);
358
+ // Auto-install third-party deps if --with-deps
359
+ if (args['with-deps']) {
360
+ console.log(`\n🧰 Installing third-party dependencies (full pack)...`);
361
+ const depReport = await bootstrapDependencies({
362
+ projectDir: resolve(args.dir),
363
+ scaleDir: join(resolve(args.dir), '.scale'),
364
+ packIds: ['full'],
365
+ includeIds: [],
366
+ apply: true,
367
+ });
368
+ console.log(` ✓ ${depReport.summary.installed}/${depReport.summary.total} dependencies installed`);
369
+ if (depReport.summary.needsInit > 0)
370
+ console.log(` ⚠ ${depReport.summary.needsInit} need manual init`);
371
+ if (depReport.summary.failed > 0)
372
+ console.log(` ✗ ${depReport.summary.failed} failed`);
373
+ }
374
+ },
375
+ });
376
+ // ============================================================================
377
+ // bootstrap command
378
+ // ============================================================================
379
+ const bootstrapDepsCommand = defineCommand({
380
+ meta: { name: 'deps', description: 'Plan or install third-party skills, CLI dependencies, and project post-configuration' },
381
+ args: {
382
+ dir: { type: 'string', default: PROJECT_DIR, description: 'Project directory' },
383
+ pack: { type: 'string', default: '', description: 'Comma-separated packs: ui,memory,knowledge,external-cli,full. Defaults to full unless --profile is supplied.' },
384
+ profile: { type: 'string', description: 'Resolve recommended packs from profile: minimal, standard, advanced' },
385
+ 'governance-pack': { type: 'string', description: 'Optional governance pack hint, for example frontend-app -> ui' },
386
+ include: { type: 'string', description: 'Additional dependency ids to include explicitly' },
387
+ apply: { type: 'boolean', default: false, description: 'Run install commands for ready dependencies' },
388
+ lang: { type: 'string', description: 'Output language zh/en. Defaults to zh, then SCALE_LANG, then .scale/config.yaml locale.' },
389
+ json: { type: 'boolean', default: false, description: 'Output bootstrap plan as JSON' },
390
+ },
391
+ async run({ args }) {
392
+ const projectDir = resolve(String(args.dir ?? PROJECT_DIR));
393
+ const lang = resolveCliLanguage({ lang: args.lang, projectDir, scaleDir: SCALE_DIR });
394
+ const explicitPacks = parseCommaList(args.pack);
395
+ const recommendedPacks = args.profile
396
+ ? getBootstrapPlanForProfile(String(args.profile), args['governance-pack'] ? String(args['governance-pack']) : undefined).packs
397
+ : [];
398
+ const report = await bootstrapDependencies({
399
+ projectDir,
400
+ scaleDir: SCALE_DIR,
401
+ packIds: explicitPacks.length > 0 ? uniqueStrings([...recommendedPacks, ...explicitPacks]) : recommendedPacks,
402
+ includeIds: parseCommaList(args.include),
403
+ apply: isTruthyFlag(args.apply),
404
+ });
405
+ if (args.json) {
406
+ console.log(JSON.stringify(report, null, 2));
407
+ if (isTruthyFlag(args.apply) && !report.ok)
408
+ process.exitCode = 1;
409
+ return;
410
+ }
411
+ console.log(renderDependencyBootstrapReport(report, lang));
412
+ if (report.apply && !report.ok)
413
+ process.exitCode = 1;
414
+ },
415
+ });
416
+ export const bootstrapCommand = defineCommand({
417
+ meta: { name: 'bootstrap', description: 'Bootstrap third-party workflow dependencies with explicit install intent' },
418
+ subCommands: { deps: bootstrapDepsCommand },
419
+ });
420
+ // ============================================================================
421
+ // setup command
422
+ // ============================================================================
423
+ export const setupCommand = defineCommand({
424
+ meta: { name: 'setup', description: 'Interactive SCALE setup for third-party skills, CLIs, memory, and knowledge providers' },
425
+ args: {
426
+ dir: { type: 'string', default: PROJECT_DIR, description: 'Project directory' },
427
+ pack: { type: 'string', default: '', description: 'Comma-separated packs: ui,memory,knowledge,external-cli,full. Defaults to full unless --profile is supplied.' },
428
+ profile: { type: 'string', description: 'Resolve recommended packs from profile: minimal, standard, advanced' },
429
+ 'governance-pack': { type: 'string', description: 'Optional governance pack hint, for example frontend-app -> ui' },
430
+ include: { type: 'string', description: 'Additional dependency ids to include explicitly' },
431
+ apply: { type: 'boolean', default: false, description: 'Run install commands for ready dependencies' },
432
+ yes: { type: 'boolean', default: false, description: 'Confirm installation without prompting' },
433
+ verify: { type: 'boolean', default: false, description: 'Verify governed setup and dependency readiness instead of running the setup wizard' },
434
+ interactive: { type: 'boolean', default: true, description: 'Prompt before installation when dependencies are ready' },
435
+ lang: { type: 'string', description: 'Output language zh/en. Defaults to zh, then SCALE_LANG, then .scale/config.yaml locale.' },
436
+ 'memory-provider': { type: 'string', description: 'Switch memory provider during setup: gbrain, agentmemory, or scale-local' },
437
+ 'memory-mode': { type: 'string', description: 'Memory routing mode: auto, local-only, external-first' },
438
+ 'memory-endpoint': { type: 'string', description: 'Optional endpoint to persist for the selected memory provider' },
439
+ 'memory-write-mode': { type: 'string', description: 'Memory write mode: disabled, candidate-only, enabled' },
440
+ 'allow-external-write': { type: 'boolean', default: false, description: 'Explicitly allow external memory writes in provider routing' },
441
+ json: { type: 'boolean', default: false, description: 'Output setup report as JSON' },
442
+ },
443
+ async run({ args }) {
444
+ const projectDir = resolve(String(args.dir ?? PROJECT_DIR));
445
+ const lang = resolveCliLanguage({ lang: args.lang, projectDir, scaleDir: SCALE_DIR });
446
+ const { explicitPacks, recommendedPacks } = resolveSetupPacks(args);
447
+ if (isTruthyFlag(args.verify)) {
448
+ const verification = await verifySetup({
449
+ projectDir,
450
+ scaleDir: SCALE_DIR,
451
+ packIds: explicitPacks.length > 0 ? uniqueStrings([...recommendedPacks, ...explicitPacks]) : recommendedPacks,
452
+ includeIds: parseCommaList(args.include),
453
+ });
454
+ if (args.json) {
455
+ console.log(JSON.stringify(verification, null, 2));
456
+ }
457
+ else {
458
+ renderSetupVerifyReport(verification, lang);
459
+ }
460
+ if (!verification.ok)
461
+ process.exitCode = 1;
462
+ return;
463
+ }
464
+ const report = await runSetupWizard({
465
+ projectDir,
466
+ scaleDir: SCALE_DIR,
467
+ packIds: explicitPacks.length > 0 ? uniqueStrings([...recommendedPacks, ...explicitPacks]) : recommendedPacks,
468
+ includeIds: parseCommaList(args.include),
469
+ promptPacks: explicitPacks.length === 0 && recommendedPacks.length === 0 && !args.include,
470
+ apply: isTruthyFlag(args.apply),
471
+ yes: isTruthyFlag(args.yes),
472
+ interactive: isTruthyFlag(args.interactive) && !isTruthyFlag(args.json),
473
+ lang,
474
+ memoryProvider: args['memory-provider'] ? String(args['memory-provider']) : undefined,
475
+ memoryMode: normalizeMemoryModeArg(args['memory-mode']),
476
+ memoryEndpoint: args['memory-endpoint'] ? String(args['memory-endpoint']) : undefined,
477
+ memoryWriteMode: normalizeMemoryWriteModeArg(args['memory-write-mode']),
478
+ allowExternalWrite: isTruthyFlag(args['allow-external-write']) ? true : undefined,
479
+ promptLanguage: isTruthyFlag(args.interactive) && !args.lang,
480
+ });
481
+ if (!args.json) {
482
+ console.log(lang === 'zh' ? '\nSCALE 交互式安装' : '\nSCALE Interactive Setup');
483
+ console.log(lang === 'zh'
484
+ ? ` 已执行安装: ${report.applied ? '是' : '否'}`
485
+ : ` Applied: ${report.applied}`);
486
+ if (report.memoryProviderSwitch) {
487
+ const switched = report.memoryProviderSwitch;
488
+ console.log(lang === 'zh' ? ' 记忆供应商:' : ' Memory provider:');
489
+ console.log(` provider=${switched.provider}; mode=${switched.mode}; config=${switched.path}`);
490
+ console.log(` order=${switched.previousOrder.join(' -> ')} => ${switched.nextOrder.join(' -> ')}`);
491
+ if (switched.providerStatus) {
492
+ console.log(` status=${switched.providerStatus.available ? 'available' : 'not-ready'}; reason=${switched.providerStatus.reason}`);
493
+ }
494
+ for (const warning of switched.warnings)
495
+ console.log(lang === 'zh' ? ` [警告] ${warning}` : ` [WARN] ${warning}`);
496
+ }
497
+ console.log(renderDependencyBootstrapReport(report.final, lang));
498
+ if (!report.ok)
499
+ process.exitCode = 1;
500
+ return;
501
+ }
502
+ if (args.json) {
503
+ console.log(JSON.stringify(report, null, 2));
504
+ if (!report.ok)
505
+ process.exitCode = 1;
506
+ return;
507
+ }
508
+ },
509
+ });
510
+ // ============================================================================
511
+ // config command — Configuration profile management
512
+ // ============================================================================
513
+ const configProfile = defineCommand({
514
+ meta: { name: 'profile', description: 'View or switch configuration profile' },
515
+ args: {
516
+ set: { type: 'string', default: '', description: 'Switch to profile (minimal/standard/advanced)' },
517
+ 'governance-pack': { type: 'string', description: 'Optional governance pack hint for bootstrap suggestions, for example frontend-app' },
518
+ list: { type: 'boolean', default: false, description: 'List all available profiles' },
519
+ json: { type: 'boolean', default: false, description: 'Output as JSON' },
520
+ },
521
+ async run({ args }) {
522
+ if (args.list) {
523
+ const profiles = listConfigProfiles();
524
+ if (args.json) {
525
+ console.log(JSON.stringify(profiles, null, 2));
526
+ return;
527
+ }
528
+ console.log('\nAvailable profiles:\n');
529
+ for (const p of profiles) {
530
+ console.log(` ${p.id.padEnd(12)} ${p.name} — ${p.description}`);
531
+ }
532
+ console.log(`\nUse: scale config profile --set <id>`);
533
+ return;
534
+ }
535
+ if (args.set) {
536
+ const profile = getConfigProfile(args.set);
537
+ if (profile.id !== args.set) {
538
+ console.log(`\n⚠️ Profile "${args.set}" not found. Available: minimal, standard, advanced`);
539
+ return;
540
+ }
541
+ const bootstrapPlan = getBootstrapPlanForProfile(profile.id, args['governance-pack'] ? String(args['governance-pack']) : undefined);
542
+ // Update config.yaml
543
+ const configPath = join('.scale', 'config.yaml');
544
+ const projectName = process.cwd().split(/[/\\]/).pop() || 'Project';
545
+ const content = generateConfigForProfile(args.set, { name: projectName });
546
+ ensureDir('.scale');
547
+ writeFileSync(configPath, content, 'utf-8');
548
+ if (args.json) {
549
+ console.log(JSON.stringify({
550
+ ok: true,
551
+ profile: profile.id,
552
+ name: profile.name,
553
+ description: profile.description,
554
+ sections: profile.sections,
555
+ bootstrapPacks: bootstrapPlan.packs,
556
+ dependencyBootstrapCommand: bootstrapPlan.inspectCommand,
557
+ dependencyBootstrapApplyCommand: bootstrapPlan.applyCommand,
558
+ configPath,
559
+ }, null, 2));
560
+ return;
561
+ }
562
+ console.log(`\n✅ Profile switched to: ${profile.name}`);
563
+ console.log(` ${profile.description}`);
564
+ console.log(`\n📄 Config updated: ${configPath}`);
565
+ return;
566
+ }
567
+ // Show current profile
568
+ const configPath = join('.scale', 'config.yaml');
569
+ if (!existsSync(configPath)) {
570
+ console.log('\n⚠️ No config.yaml found. Run: scale init');
571
+ return;
572
+ }
573
+ const content = readFileSync(configPath, 'utf-8');
574
+ const match = content.match(/^profile:\s*(.+)$/m);
575
+ const currentProfile = match?.[1]?.trim() || 'standard';
576
+ const profile = getConfigProfile(currentProfile);
577
+ const bootstrapPlan = getBootstrapPlanForProfile(profile.id, args['governance-pack'] ? String(args['governance-pack']) : undefined);
578
+ if (args.json) {
579
+ console.log(JSON.stringify({
580
+ profile: profile.id,
581
+ name: profile.name,
582
+ description: profile.description,
583
+ sections: profile.sections,
584
+ bootstrapPacks: bootstrapPlan.packs,
585
+ dependencyBootstrapCommand: bootstrapPlan.inspectCommand,
586
+ dependencyBootstrapApplyCommand: bootstrapPlan.applyCommand,
587
+ }, null, 2));
588
+ return;
589
+ }
590
+ console.log(`\nCurrent profile: ${profile.name} (${profile.id})`);
591
+ console.log(` ${profile.description}`);
592
+ console.log(`\nSections: ${profile.sections.join(', ')}`);
593
+ console.log(`Bootstrap packs: ${bootstrapPlan.packs.join(', ')}`);
594
+ console.log(`Dependency bootstrap: ${bootstrapPlan.inspectCommand}`);
595
+ console.log(`\nUse: scale config profile --set <id> to switch`);
596
+ },
597
+ });
598
+ export const configCommand = defineCommand({
599
+ meta: { name: 'config', description: 'Configuration management' },
600
+ subCommands: { profile: configProfile },
601
+ });
602
+ //# sourceMappingURL=initConfigCommands.js.map