@hongmaple0820/scale-engine 0.33.0 → 0.38.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 (108) hide show
  1. package/README.en.md +86 -376
  2. package/README.md +89 -549
  3. package/dist/api/cli.js +185 -12
  4. package/dist/api/cli.js.map +1 -1
  5. package/dist/api/doctor.d.ts +38 -3
  6. package/dist/api/doctor.js +269 -44
  7. package/dist/api/doctor.js.map +1 -1
  8. package/dist/api/mcp.js +2 -2
  9. package/dist/api/mcp.js.map +1 -1
  10. package/dist/api/quickstart.d.ts +34 -4
  11. package/dist/api/quickstart.js +90 -73
  12. package/dist/api/quickstart.js.map +1 -1
  13. package/dist/bootstrap/DependencyBootstrap.d.ts +89 -0
  14. package/dist/bootstrap/DependencyBootstrap.js +441 -0
  15. package/dist/bootstrap/DependencyBootstrap.js.map +1 -0
  16. package/dist/capabilities/InstalledSkillsIntegration.js +14 -6
  17. package/dist/capabilities/InstalledSkillsIntegration.js.map +1 -1
  18. package/dist/codegraph/CodeIntelligence.d.ts +12 -0
  19. package/dist/codegraph/CodeIntelligence.js +251 -30
  20. package/dist/codegraph/CodeIntelligence.js.map +1 -1
  21. package/dist/config/profiles.d.ts +12 -0
  22. package/dist/config/profiles.js +39 -4
  23. package/dist/config/profiles.js.map +1 -1
  24. package/dist/core/ExternalCommand.d.ts +9 -0
  25. package/dist/core/ExternalCommand.js +56 -0
  26. package/dist/core/ExternalCommand.js.map +1 -0
  27. package/dist/index.d.ts +1 -0
  28. package/dist/index.js +1 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/knowledge/CerebrumManager.d.ts +2 -2
  31. package/dist/knowledge/CerebrumManager.js.map +1 -1
  32. package/dist/knowledge/GraphifyKnowledgeBase.d.ts +38 -0
  33. package/dist/knowledge/GraphifyKnowledgeBase.js +409 -0
  34. package/dist/knowledge/GraphifyKnowledgeBase.js.map +1 -0
  35. package/dist/memory/MemoryFabric.js +1 -0
  36. package/dist/memory/MemoryFabric.js.map +1 -1
  37. package/dist/memory/MemoryIntelligence.d.ts +42 -0
  38. package/dist/memory/MemoryIntelligence.js +215 -0
  39. package/dist/memory/MemoryIntelligence.js.map +1 -0
  40. package/dist/memory/MemoryProviders.d.ts +22 -0
  41. package/dist/memory/MemoryProviders.js +138 -5
  42. package/dist/memory/MemoryProviders.js.map +1 -1
  43. package/dist/memory/index.d.ts +1 -0
  44. package/dist/memory/index.js +1 -0
  45. package/dist/memory/index.js.map +1 -1
  46. package/dist/runtime/AiOsRuntime.d.ts +2 -0
  47. package/dist/runtime/AiOsRuntime.js +2 -0
  48. package/dist/runtime/AiOsRuntime.js.map +1 -1
  49. package/dist/runtime/ExecutionLedger.d.ts +46 -0
  50. package/dist/runtime/ExecutionLedger.js +71 -0
  51. package/dist/runtime/ExecutionLedger.js.map +1 -0
  52. package/dist/runtime/index.d.ts +1 -0
  53. package/dist/runtime/index.js +1 -0
  54. package/dist/runtime/index.js.map +1 -1
  55. package/dist/skills/SkillRepository.js +5 -5
  56. package/dist/skills/SkillRepository.js.map +1 -1
  57. package/dist/skills/routing/SkillPolicy.js +2 -2
  58. package/dist/skills/routing/SkillPolicy.js.map +1 -1
  59. package/dist/tools/RtkRuntime.d.ts +9 -0
  60. package/dist/tools/RtkRuntime.js +43 -0
  61. package/dist/tools/RtkRuntime.js.map +1 -0
  62. package/dist/tools/ToolCapabilityRegistry.d.ts +1 -0
  63. package/dist/tools/ToolCapabilityRegistry.js +68 -11
  64. package/dist/tools/ToolCapabilityRegistry.js.map +1 -1
  65. package/dist/tools/ToolOrchestrator.js +6 -4
  66. package/dist/tools/ToolOrchestrator.js.map +1 -1
  67. package/dist/tools/ToolPolicy.js +16 -1
  68. package/dist/tools/ToolPolicy.js.map +1 -1
  69. package/dist/workflow/AdaptiveWorkflowRouter.d.ts +1 -0
  70. package/dist/workflow/AdaptiveWorkflowRouter.js +3 -0
  71. package/dist/workflow/AdaptiveWorkflowRouter.js.map +1 -1
  72. package/dist/workflow/CommitDiscipline.d.ts +68 -0
  73. package/dist/workflow/CommitDiscipline.js +327 -0
  74. package/dist/workflow/CommitDiscipline.js.map +1 -0
  75. package/dist/workflow/CrossRepoOrchestrator.d.ts +92 -0
  76. package/dist/workflow/CrossRepoOrchestrator.js +400 -0
  77. package/dist/workflow/CrossRepoOrchestrator.js.map +1 -0
  78. package/dist/workflow/GovernanceRoi.d.ts +52 -0
  79. package/dist/workflow/GovernanceRoi.js +204 -0
  80. package/dist/workflow/GovernanceRoi.js.map +1 -0
  81. package/dist/workflow/GovernanceTemplates.js +2 -2
  82. package/dist/workflow/McpGovernance.d.ts +63 -0
  83. package/dist/workflow/McpGovernance.js +198 -0
  84. package/dist/workflow/McpGovernance.js.map +1 -0
  85. package/dist/workflow/SessionCoordinator.d.ts +103 -0
  86. package/dist/workflow/SessionCoordinator.js +401 -0
  87. package/dist/workflow/SessionCoordinator.js.map +1 -0
  88. package/dist/workflow/TaskDependencyGraph.d.ts +73 -0
  89. package/dist/workflow/TaskDependencyGraph.js +245 -0
  90. package/dist/workflow/TaskDependencyGraph.js.map +1 -0
  91. package/dist/workflow/WorkflowTemplates.d.ts +38 -0
  92. package/dist/workflow/WorkflowTemplates.js +371 -0
  93. package/dist/workflow/WorkflowTemplates.js.map +1 -0
  94. package/dist/workflow/WorkspacePolicy.d.ts +46 -0
  95. package/dist/workflow/WorkspacePolicy.js +141 -0
  96. package/dist/workflow/WorkspacePolicy.js.map +1 -0
  97. package/dist/workflow/gates/GateSystem.js +12 -9
  98. package/dist/workflow/gates/GateSystem.js.map +1 -1
  99. package/dist/workflow/index.d.ts +7 -0
  100. package/dist/workflow/index.js +7 -0
  101. package/dist/workflow/index.js.map +1 -1
  102. package/docs/CODE_INTELLIGENCE.md +22 -5
  103. package/docs/EXTERNAL_REFERENCES.md +5 -2
  104. package/docs/MEMORY_FABRIC.md +7 -3
  105. package/docs/SKILL-REPOSITORY.md +3 -3
  106. package/docs/start/quickstart.md +11 -0
  107. package/docs/workflow/templates/skill-plan.md +1 -1
  108. package/package.json +3 -2
package/dist/api/cli.js CHANGED
@@ -10,7 +10,7 @@ import { Gateway } from '../guardrails/Gateway.js';
10
10
  import { BruteRetryDetector, PrematureDoneDetector, BlameShiftDetector } from '../guardrails/detectors.js';
11
11
  import { DangerousCommandDetector, SecretLeakDetector, RoleGateDetector, ScopeCreepDetector, BUILT_IN_ROLES } from '../guardrails/advancedDetectors.js';
12
12
  import { auditDependencies } from '../guardrails/DependencyAuditor.js';
13
- import { SQLiteKnowledgeBase } from '../knowledge/SQLiteKnowledgeBase.js';
13
+ import { GraphifyKnowledgeBase } from '../knowledge/GraphifyKnowledgeBase.js';
14
14
  import { ContextBuilder } from '../context/ContextBuilder.js';
15
15
  import { ProjectAnatomy } from '../context/ProjectAnatomy.js';
16
16
  import { buildContextPack, doctorContextBudget, scanContextBudget, writeContextBudgetReport, } from '../context/ContextBudget.js';
@@ -28,6 +28,7 @@ import { createAdapter, SUPPORTED_AGENTS } from '../adapters/index.js';
28
28
  import { LessonExtractor, RuleProposer, HookGenerator, EvolutionEngine } from '../evolution/EvolutionEngine.js';
29
29
  import { Doctor } from './doctor.js';
30
30
  import { quickStart, detectPlatform, governanceNextSteps } from './quickstart.js';
31
+ import { bootstrapDependencies } from '../bootstrap/DependencyBootstrap.js';
31
32
  import { SkillDiscovery } from '../skills/SkillDiscovery.js';
32
33
  import { inspectRequiredWorkflowSkills, inspectWorkflowSkills } from '../skills/SkillDoctor.js';
33
34
  import { evaluateSkillInstallSafety, listSkillRepositoryEntries, recommendSkillWorkflow, renderSkillRepositoryMarkdown, } from '../skills/SkillRepository.js';
@@ -40,7 +41,7 @@ import { ReviewStore } from '../workflow/ReviewStore.js';
40
41
  import { WorkflowEngine } from '../workflow/WorkflowEngine.js';
41
42
  import { resolveVerificationTargets, } from '../workflow/VerificationProfile.js';
42
43
  import { writeGovernanceTemplates } from '../workflow/GovernanceTemplates.js';
43
- import { getProfile as getConfigProfile, generateConfigForProfile, listProfiles as listConfigProfiles } from '../config/profiles.js';
44
+ import { getBootstrapPlanForProfile, getProfile as getConfigProfile, generateConfigForProfile, listProfiles as listConfigProfiles, } from '../config/profiles.js';
44
45
  import { computeGovernanceDrift } from '../workflow/GovernanceLock.js';
45
46
  import { applyUpgradePlan, createThirdPartyUpdateReport, createUpgradeCheckReport, createUpgradePlanReport, rollbackLatestUpgrade, writeUpgradePlanHtml, } from '../workflow/UpgradeManager.js';
46
47
  import { createGovernanceRoiReport } from '../governance/GovernanceRoi.js';
@@ -66,7 +67,7 @@ import { renderGovernanceDashboard } from '../output/GovernanceDashboard.js';
66
67
  import { cleanupWorkspaceLifecycle, inspectWorkspaceLifecycle, } from '../workflow/WorkspaceLifecycle.js';
67
68
  import { inspectWorkspaceSafety } from '../workflow/WorkspaceSafety.js';
68
69
  import { RuntimeEvidenceLedger, SessionLedger, createAiOsAdoption, createAiOsBenchmark, createAiOsDashboard, createAiOsDoctor, createAiOsMigration, createAiOsPlan, createAiOsRun, createAiOsStatus, doctorRuntimeEvidence, evaluateFinalReportReadiness, } from '../runtime/index.js';
69
- import { MemoryFabric, MemoryBrain, doctorMemoryFabric, renderContextPackMarkdown, renderMemoryLearningCandidateMarkdown, inspectMemoryProviders, recallMemoryProviders, settleMemoryLearning, writeMemoryProvidersConfig, } from '../memory/index.js';
70
+ import { MemoryFabric, MemoryBrain, doctorMemoryFabric, renderContextPackMarkdown, renderMemoryLearningCandidateMarkdown, inspectMemoryProviders, recallMemoryProviders, settleMemoryLearning, useMemoryProvider, writeMemoryProvidersConfig, } from '../memory/index.js';
70
71
  import { resolveWorkspaceTopology, workspaceTopologyPath, workspaceTopologyTemplate, } from '../workflow/WorkspaceTopology.js';
71
72
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
72
73
  import { dirname, isAbsolute, join, resolve } from 'node:path';
@@ -220,7 +221,7 @@ function createEngine() {
220
221
  gateway.registerDetector(new ScopeCreepDetector(), 'preTool');
221
222
  gateway.registerDetector(new PrematureDoneDetector(), 'beforeStop');
222
223
  gateway.registerDetector(new BlameShiftDetector(), 'postTool');
223
- const kb = new SQLiteKnowledgeBase(eventBus, { dbPath: join(SCALE_DIR, 'knowledge.db') });
224
+ const kb = new GraphifyKnowledgeBase(eventBus, { projectDir: PROJECT_DIR, scaleDir: SCALE_DIR });
224
225
  const ctx = new ContextBuilder(store, kb, eventBus);
225
226
  const fsmAgentBridge = new FSMAgentBridge(fsm, store);
226
227
  const capabilityRegistry = new CapabilityRegistry(eventBus);
@@ -1197,8 +1198,18 @@ const codegraphStatus = defineCommand({
1197
1198
  }
1198
1199
  console.log('SCALE Code Intelligence Status');
1199
1200
  console.log(` Config: ${report.configPath} (${report.configExists ? 'found' : 'default'})`);
1201
+ console.log(` Project index: ${report.projectIndexExists ? report.projectIndexPath : `${report.projectIndexPath} (not initialized)`}`);
1200
1202
  for (const provider of report.providers) {
1201
1203
  console.log(` [${provider.available ? 'AVAILABLE' : 'UNAVAILABLE'}] ${provider.id} (${provider.type}): ${provider.reason}`);
1204
+ if (provider.source)
1205
+ console.log(` source: ${provider.source}`);
1206
+ if (!provider.available && provider.installHint)
1207
+ console.log(` install: ${provider.installHint}`);
1208
+ if (provider.available && provider.projectInitHint && provider.id === 'codegraph' && !report.projectIndexExists) {
1209
+ console.log(` init: ${provider.projectInitHint}`);
1210
+ }
1211
+ if (provider.serveCommand)
1212
+ console.log(` mcp: ${provider.serveCommand}`);
1202
1213
  }
1203
1214
  console.log(` Fallback: ${report.fallback.available ? 'available' : 'disabled'} (${report.fallback.tools.join(', ')})`);
1204
1215
  for (const recommendation of report.recommendations)
@@ -2528,7 +2539,7 @@ const status = defineCommand({
2528
2539
  // init command
2529
2540
  // ============================================================================
2530
2541
  const init = defineCommand({
2531
- meta: { name: 'init', description: 'Initialize SCALE Engine in current project (one-click install)' },
2542
+ meta: { name: 'init', description: 'Initialize SCALE Engine governance in current project (one-click bootstrap, not third-party auto-install)' },
2532
2543
  args: {
2533
2544
  agent: { type: 'string', default: '', description: `Agent type (${SUPPORTED_AGENTS.join('/')}) - auto-detected if not specified` },
2534
2545
  dir: { type: 'string', default: '.', description: 'Project directory' },
@@ -2626,16 +2637,22 @@ const init = defineCommand({
2626
2637
  console.log(` Scenario: ${scenarioMode}`);
2627
2638
  console.log(` Profile: ${profileId}`);
2628
2639
  console.log(`\n📋 Next steps:`);
2629
- for (const step of governanceNextSteps())
2640
+ for (const step of governanceNextSteps({
2641
+ profileId,
2642
+ governancePack: String(args['governance-pack']),
2643
+ }))
2630
2644
  console.log(` → ${step}`);
2631
2645
  return;
2632
2646
  }
2633
2647
  // One-click quick start mode
2634
2648
  if (!args.agent) {
2635
- const qsResult = await quickStart(args.dir, { governancePack: args['governance-pack'] });
2649
+ const profileId = args.profile || profileFromScenario(args.scenario);
2650
+ const qsResult = await quickStart(args.dir, {
2651
+ governancePack: args['governance-pack'],
2652
+ profileId,
2653
+ });
2636
2654
  // Generate config.yaml from profile
2637
2655
  if (qsResult.success) {
2638
- const profileId = args.profile || profileFromScenario(args.scenario);
2639
2656
  const projectName = args.dir.split(/[/\\]/).pop() || 'Project';
2640
2657
  const detectedAgent = qsResult.platform ? [qsResult.platform] : [];
2641
2658
  const configPath = writeConfigYaml(args.dir, profileId, projectName, detectedAgent);
@@ -2650,8 +2667,10 @@ const init = defineCommand({
2650
2667
  created: qsResult.created,
2651
2668
  skipped: qsResult.skipped,
2652
2669
  constraintsApplied: qsResult.constraintsApplied,
2670
+ workflowCapabilities: qsResult.workflowCapabilities,
2653
2671
  capabilitiesEnabled: qsResult.capabilitiesEnabled,
2654
2672
  knowledgeGraph: qsResult.knowledgeGraph,
2673
+ dependencyBootstrapCommand: qsResult.dependencyBootstrapCommand,
2655
2674
  nextSteps: qsResult.nextSteps,
2656
2675
  suggestions: detection?.suggestions ?? [],
2657
2676
  }, null, 2));
@@ -2671,7 +2690,8 @@ const init = defineCommand({
2671
2690
  console.log(` - ${f}`);
2672
2691
  }
2673
2692
  console.log(`\n🔒 Physical constraints applied: ${qsResult.constraintsApplied}`);
2674
- console.log(`\n🚀 Capabilities enabled: ${qsResult.capabilitiesEnabled.join(', ')}`);
2693
+ console.log(`\n🧭 Workflow capability plan: ${qsResult.workflowCapabilities.join(', ')}`);
2694
+ console.log(`\n🧰 Dependency bootstrap: ${qsResult.dependencyBootstrapCommand}`);
2675
2695
  console.log(`\n📋 Next steps:`);
2676
2696
  for (const step of qsResult.nextSteps)
2677
2697
  console.log(` → ${step}`);
@@ -2713,7 +2733,10 @@ const init = defineCommand({
2713
2733
  scaleDir: result.scaleDir,
2714
2734
  created: result.created,
2715
2735
  skipped: result.skipped,
2716
- nextSteps: governanceNextSteps(),
2736
+ nextSteps: governanceNextSteps({
2737
+ profileId,
2738
+ governancePack: String(args['governance-pack']),
2739
+ }),
2717
2740
  }, null, 2));
2718
2741
  return;
2719
2742
  }
@@ -2731,10 +2754,85 @@ const init = defineCommand({
2731
2754
  console.log(`\n📄 Config: ${configPath}`);
2732
2755
  console.log(`\n📂 Data dir: ${result.scaleDir}`);
2733
2756
  console.log(`\n📋 Next steps:`);
2734
- for (const step of governanceNextSteps())
2757
+ for (const step of governanceNextSteps({
2758
+ profileId,
2759
+ governancePack: String(args['governance-pack']),
2760
+ }))
2735
2761
  console.log(` → ${step}`);
2736
2762
  },
2737
2763
  });
2764
+ const bootstrapDepsCommand = defineCommand({
2765
+ meta: { name: 'deps', description: 'Plan or install third-party skills, CLI dependencies, and project post-configuration' },
2766
+ args: {
2767
+ dir: { type: 'string', default: PROJECT_DIR, description: 'Project directory' },
2768
+ pack: { type: 'string', default: '', description: 'Comma-separated packs: ui,memory,knowledge,external-cli,full. Defaults to full unless --profile is supplied.' },
2769
+ profile: { type: 'string', description: 'Resolve recommended packs from profile: minimal, standard, advanced' },
2770
+ 'governance-pack': { type: 'string', description: 'Optional governance pack hint, for example frontend-app -> ui' },
2771
+ include: { type: 'string', description: 'Additional dependency ids to include explicitly' },
2772
+ apply: { type: 'boolean', default: false, description: 'Run install commands for ready dependencies' },
2773
+ json: { type: 'boolean', default: false, description: 'Output bootstrap plan as JSON' },
2774
+ },
2775
+ async run({ args }) {
2776
+ const projectDir = resolve(String(args.dir ?? PROJECT_DIR));
2777
+ const explicitPacks = parseCommaList(args.pack);
2778
+ const recommendedPacks = args.profile
2779
+ ? getBootstrapPlanForProfile(String(args.profile), args['governance-pack'] ? String(args['governance-pack']) : undefined).packs
2780
+ : [];
2781
+ const report = await bootstrapDependencies({
2782
+ projectDir,
2783
+ scaleDir: SCALE_DIR,
2784
+ packIds: explicitPacks.length > 0 ? uniqueStrings([...recommendedPacks, ...explicitPacks]) : recommendedPacks,
2785
+ includeIds: parseCommaList(args.include),
2786
+ apply: isTruthyFlag(args.apply),
2787
+ });
2788
+ if (args.json) {
2789
+ console.log(JSON.stringify(report, null, 2));
2790
+ if (isTruthyFlag(args.apply) && !report.ok)
2791
+ process.exitCode = 1;
2792
+ return;
2793
+ }
2794
+ console.log('\nSCALE Dependency Bootstrap');
2795
+ console.log(` Project: ${report.projectDir}`);
2796
+ console.log(` Packs: ${report.packIds.join(', ')}`);
2797
+ console.log(` Apply: ${report.apply}`);
2798
+ console.log(` Complete: ${report.complete}`);
2799
+ for (const item of report.items) {
2800
+ console.log(` [${item.status.toUpperCase()}] ${item.id} (${item.kind})`);
2801
+ console.log(` source: ${item.source}`);
2802
+ console.log(` detected: ${item.detectedBy}`);
2803
+ if (!item.installed && item.installCommand)
2804
+ console.log(` install: ${item.installCommand}`);
2805
+ if (!item.installed && item.manualReason)
2806
+ console.log(` reason: ${item.manualReason}`);
2807
+ if (!item.installed && item.prerequisites.length > 0) {
2808
+ console.log(` prereqs: ${item.prerequisites.map(req => `${req.command}=${req.present ? 'ok' : 'missing'}`).join(', ')}`);
2809
+ }
2810
+ if (item.error)
2811
+ console.log(` error: ${item.error}`);
2812
+ }
2813
+ for (const action of report.postActions)
2814
+ console.log(` [POST] ${action}`);
2815
+ if (report.postChecks.length > 0) {
2816
+ console.log(` Post-checks: passed=${report.postCheckSummary.passed}, warned=${report.postCheckSummary.warned}, failed=${report.postCheckSummary.failed}`);
2817
+ for (const check of report.postChecks) {
2818
+ console.log(` [POSTCHECK ${check.status.toUpperCase()}] ${check.label}: ${check.summary}`);
2819
+ console.log(` command: ${check.command}`);
2820
+ }
2821
+ }
2822
+ for (const command of report.postCheckCommands)
2823
+ console.log(` [CHECK] ${command}`);
2824
+ for (const hint of report.rollbackHints)
2825
+ console.log(` [ROLLBACK] ${hint}`);
2826
+ for (const recommendation of report.recommendations)
2827
+ console.log(` [NEXT] ${recommendation}`);
2828
+ if (report.apply && !report.ok)
2829
+ process.exitCode = 1;
2830
+ },
2831
+ });
2832
+ const bootstrap = defineCommand({
2833
+ meta: { name: 'bootstrap', description: 'Bootstrap third-party workflow dependencies with explicit install intent' },
2834
+ subCommands: { deps: bootstrapDepsCommand },
2835
+ });
2738
2836
  // ============================================================================
2739
2837
  // config command — Configuration profile management
2740
2838
  // ============================================================================
@@ -2742,6 +2840,7 @@ const configProfile = defineCommand({
2742
2840
  meta: { name: 'profile', description: 'View or switch configuration profile' },
2743
2841
  args: {
2744
2842
  set: { type: 'string', default: '', description: 'Switch to profile (minimal/standard/advanced)' },
2843
+ 'governance-pack': { type: 'string', description: 'Optional governance pack hint for bootstrap suggestions, for example frontend-app' },
2745
2844
  list: { type: 'boolean', default: false, description: 'List all available profiles' },
2746
2845
  json: { type: 'boolean', default: false, description: 'Output as JSON' },
2747
2846
  },
@@ -2765,12 +2864,27 @@ const configProfile = defineCommand({
2765
2864
  console.log(`\n⚠️ Profile "${args.set}" not found. Available: minimal, standard, advanced`);
2766
2865
  return;
2767
2866
  }
2867
+ const bootstrapPlan = getBootstrapPlanForProfile(profile.id, args['governance-pack'] ? String(args['governance-pack']) : undefined);
2768
2868
  // Update config.yaml
2769
2869
  const configPath = join('.scale', 'config.yaml');
2770
2870
  const projectName = process.cwd().split(/[/\\]/).pop() || 'Project';
2771
2871
  const content = generateConfigForProfile(args.set, { name: projectName });
2772
2872
  ensureDir('.scale');
2773
2873
  writeFileSync(configPath, content, 'utf-8');
2874
+ if (args.json) {
2875
+ console.log(JSON.stringify({
2876
+ ok: true,
2877
+ profile: profile.id,
2878
+ name: profile.name,
2879
+ description: profile.description,
2880
+ sections: profile.sections,
2881
+ bootstrapPacks: bootstrapPlan.packs,
2882
+ dependencyBootstrapCommand: bootstrapPlan.inspectCommand,
2883
+ dependencyBootstrapApplyCommand: bootstrapPlan.applyCommand,
2884
+ configPath,
2885
+ }, null, 2));
2886
+ return;
2887
+ }
2774
2888
  console.log(`\n✅ Profile switched to: ${profile.name}`);
2775
2889
  console.log(` ${profile.description}`);
2776
2890
  console.log(`\n📄 Config updated: ${configPath}`);
@@ -2786,13 +2900,24 @@ const configProfile = defineCommand({
2786
2900
  const match = content.match(/^profile:\s*(.+)$/m);
2787
2901
  const currentProfile = match?.[1]?.trim() || 'standard';
2788
2902
  const profile = getConfigProfile(currentProfile);
2903
+ const bootstrapPlan = getBootstrapPlanForProfile(profile.id, args['governance-pack'] ? String(args['governance-pack']) : undefined);
2789
2904
  if (args.json) {
2790
- console.log(JSON.stringify({ profile: profile.id, name: profile.name, description: profile.description, sections: profile.sections }, null, 2));
2905
+ console.log(JSON.stringify({
2906
+ profile: profile.id,
2907
+ name: profile.name,
2908
+ description: profile.description,
2909
+ sections: profile.sections,
2910
+ bootstrapPacks: bootstrapPlan.packs,
2911
+ dependencyBootstrapCommand: bootstrapPlan.inspectCommand,
2912
+ dependencyBootstrapApplyCommand: bootstrapPlan.applyCommand,
2913
+ }, null, 2));
2791
2914
  return;
2792
2915
  }
2793
2916
  console.log(`\nCurrent profile: ${profile.name} (${profile.id})`);
2794
2917
  console.log(` ${profile.description}`);
2795
2918
  console.log(`\nSections: ${profile.sections.join(', ')}`);
2919
+ console.log(`Bootstrap packs: ${bootstrapPlan.packs.join(', ')}`);
2920
+ console.log(`Dependency bootstrap: ${bootstrapPlan.inspectCommand}`);
2796
2921
  console.log(`\nUse: scale config profile --set <id> to switch`);
2797
2922
  },
2798
2923
  });
@@ -4924,12 +5049,57 @@ const memoryProviderRecall = defineCommand({
4924
5049
  console.log(` [WARN] ${warning}`);
4925
5050
  },
4926
5051
  });
5052
+ const memoryProviderUse = defineCommand({
5053
+ meta: { name: 'use', description: 'Promote one memory provider to the front of routing and persist the selection' },
5054
+ args: {
5055
+ provider: { type: 'positional', required: true, description: 'Provider id: gbrain, agentmemory, or scale-local' },
5056
+ mode: { type: 'string', description: 'Optional routing mode override: auto, local-only, external-first' },
5057
+ endpoint: { type: 'string', description: 'Optional provider endpoint to persist while switching' },
5058
+ 'write-mode': { type: 'string', description: 'Optional provider write mode: disabled, candidate-only, enabled' },
5059
+ 'allow-external-write': { type: 'boolean', default: false, description: 'Persist external write allowance when explicitly switching' },
5060
+ json: { type: 'boolean', default: false },
5061
+ },
5062
+ run({ args }) {
5063
+ const mode = args.mode ? String(args.mode) : undefined;
5064
+ const writeMode = args['write-mode']
5065
+ ? String(args['write-mode'])
5066
+ : undefined;
5067
+ const report = useMemoryProvider({
5068
+ projectDir: PROJECT_DIR,
5069
+ scaleDir: SCALE_DIR,
5070
+ provider: String(args.provider),
5071
+ mode: mode,
5072
+ endpoint: args.endpoint ? String(args.endpoint) : undefined,
5073
+ writeMode,
5074
+ allowExternalWrite: isTruthyFlag(args['allow-external-write']) ? true : undefined,
5075
+ });
5076
+ if (args.json) {
5077
+ console.log(JSON.stringify(report, null, 2));
5078
+ if (!report.ok)
5079
+ process.exitCode = 1;
5080
+ return;
5081
+ }
5082
+ console.log('\nSCALE Memory Provider Switch');
5083
+ console.log(` Provider: ${report.provider}`);
5084
+ console.log(` Mode: ${report.mode}`);
5085
+ console.log(` Config: ${report.path}`);
5086
+ console.log(` Order: ${report.previousOrder.join(' -> ')} -> ${report.nextOrder.join(' -> ')}`);
5087
+ if (report.providerStatus) {
5088
+ console.log(` Status: ${report.providerStatus.available ? 'available' : 'not-ready'} (${report.providerStatus.reason})`);
5089
+ }
5090
+ for (const warning of report.warnings)
5091
+ console.log(` [WARN] ${warning}`);
5092
+ if (!report.ok)
5093
+ process.exitCode = 1;
5094
+ },
5095
+ });
4927
5096
  const memoryProvider = defineCommand({
4928
5097
  meta: { name: 'provider', description: 'Manage autonomous memory provider routing for agentmemory, gbrain, and scale-local' },
4929
5098
  subCommands: {
4930
5099
  init: memoryProviderInit,
4931
5100
  status: memoryProviderStatus,
4932
5101
  recall: memoryProviderRecall,
5102
+ use: memoryProviderUse,
4933
5103
  },
4934
5104
  });
4935
5105
  const memory = defineCommand({
@@ -5524,6 +5694,8 @@ const toolDoctorCommand = defineCommand({
5524
5694
  console.log(` version: ${entry.version}`);
5525
5695
  if (entry.missingReason)
5526
5696
  console.log(` reason: ${entry.missingReason}`);
5697
+ if (!entry.installed && entry.installHint)
5698
+ console.log(` install: ${entry.installHint}`);
5527
5699
  }
5528
5700
  }
5529
5701
  if (!report.ok)
@@ -5848,6 +6020,7 @@ const main = defineCommand({
5848
6020
  run: runCommand,
5849
6021
  // Original commands (preserved)
5850
6022
  init,
6023
+ bootstrap,
5851
6024
  doctor,
5852
6025
  session,
5853
6026
  gate,