@hongmaple0820/scale-engine 0.33.0 → 0.39.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 (159) hide show
  1. package/README.en.md +86 -376
  2. package/README.md +95 -540
  3. package/dist/api/cli.js +293 -18
  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 +110 -0
  14. package/dist/bootstrap/DependencyBootstrap.js +829 -0
  15. package/dist/bootstrap/DependencyBootstrap.js.map +1 -0
  16. package/dist/bootstrap/DependencyBootstrapRenderer.d.ts +3 -0
  17. package/dist/bootstrap/DependencyBootstrapRenderer.js +140 -0
  18. package/dist/bootstrap/DependencyBootstrapRenderer.js.map +1 -0
  19. package/dist/capabilities/InstalledSkillsIntegration.js +14 -6
  20. package/dist/capabilities/InstalledSkillsIntegration.js.map +1 -1
  21. package/dist/cli/gateStatusCommands.d.ts +1 -0
  22. package/dist/cli/gateStatusCommands.js +52 -0
  23. package/dist/cli/gateStatusCommands.js.map +1 -0
  24. package/dist/cli/phaseCommands.js +15 -3
  25. package/dist/cli/phaseCommands.js.map +1 -1
  26. package/dist/cli/promptCommands.d.ts +1 -0
  27. package/dist/cli/promptCommands.js +57 -0
  28. package/dist/cli/promptCommands.js.map +1 -0
  29. package/dist/cli/scoreCommands.d.ts +1 -0
  30. package/dist/cli/scoreCommands.js +112 -0
  31. package/dist/cli/scoreCommands.js.map +1 -0
  32. package/dist/codegraph/CodeIntelligence.d.ts +12 -0
  33. package/dist/codegraph/CodeIntelligence.js +251 -30
  34. package/dist/codegraph/CodeIntelligence.js.map +1 -1
  35. package/dist/config/profiles.d.ts +12 -0
  36. package/dist/config/profiles.js +39 -4
  37. package/dist/config/profiles.js.map +1 -1
  38. package/dist/context/SessionStartSequence.js +13 -4
  39. package/dist/context/SessionStartSequence.js.map +1 -1
  40. package/dist/core/ExternalCommand.d.ts +9 -0
  41. package/dist/core/ExternalCommand.js +70 -0
  42. package/dist/core/ExternalCommand.js.map +1 -0
  43. package/dist/env/EnvironmentDoctor.d.ts +66 -0
  44. package/dist/env/EnvironmentDoctor.js +365 -0
  45. package/dist/env/EnvironmentDoctor.js.map +1 -0
  46. package/dist/i18n/Language.d.ts +9 -0
  47. package/dist/i18n/Language.js +38 -0
  48. package/dist/i18n/Language.js.map +1 -0
  49. package/dist/index.d.ts +2 -0
  50. package/dist/index.js +2 -0
  51. package/dist/index.js.map +1 -1
  52. package/dist/knowledge/CerebrumManager.d.ts +2 -2
  53. package/dist/knowledge/CerebrumManager.js.map +1 -1
  54. package/dist/knowledge/GraphifyKnowledgeBase.d.ts +38 -0
  55. package/dist/knowledge/GraphifyKnowledgeBase.js +409 -0
  56. package/dist/knowledge/GraphifyKnowledgeBase.js.map +1 -0
  57. package/dist/memory/MemoryFabric.js +1 -0
  58. package/dist/memory/MemoryFabric.js.map +1 -1
  59. package/dist/memory/MemoryIntelligence.d.ts +42 -0
  60. package/dist/memory/MemoryIntelligence.js +215 -0
  61. package/dist/memory/MemoryIntelligence.js.map +1 -0
  62. package/dist/memory/MemoryProviders.d.ts +22 -0
  63. package/dist/memory/MemoryProviders.js +171 -5
  64. package/dist/memory/MemoryProviders.js.map +1 -1
  65. package/dist/memory/index.d.ts +1 -0
  66. package/dist/memory/index.js +1 -0
  67. package/dist/memory/index.js.map +1 -1
  68. package/dist/prompts/PromptOptimizer.d.ts +42 -0
  69. package/dist/prompts/PromptOptimizer.js +309 -0
  70. package/dist/prompts/PromptOptimizer.js.map +1 -0
  71. package/dist/runtime/AiOsRuntime.d.ts +2 -0
  72. package/dist/runtime/AiOsRuntime.js +2 -0
  73. package/dist/runtime/AiOsRuntime.js.map +1 -1
  74. package/dist/runtime/ExecutionLedger.d.ts +46 -0
  75. package/dist/runtime/ExecutionLedger.js +71 -0
  76. package/dist/runtime/ExecutionLedger.js.map +1 -0
  77. package/dist/runtime/index.d.ts +1 -0
  78. package/dist/runtime/index.js +1 -0
  79. package/dist/runtime/index.js.map +1 -1
  80. package/dist/setup/SetupWizard.d.ts +42 -0
  81. package/dist/setup/SetupWizard.js +156 -0
  82. package/dist/setup/SetupWizard.js.map +1 -0
  83. package/dist/skills/SkillRepository.js +7 -7
  84. package/dist/skills/SkillRepository.js.map +1 -1
  85. package/dist/skills/routing/SkillPolicy.js +2 -2
  86. package/dist/skills/routing/SkillPolicy.js.map +1 -1
  87. package/dist/testing/DiffTestSelector.js +1 -1
  88. package/dist/testing/DiffTestSelector.js.map +1 -1
  89. package/dist/tools/RtkRuntime.d.ts +9 -0
  90. package/dist/tools/RtkRuntime.js +43 -0
  91. package/dist/tools/RtkRuntime.js.map +1 -0
  92. package/dist/tools/ToolCapabilityRegistry.d.ts +5 -0
  93. package/dist/tools/ToolCapabilityRegistry.js +75 -13
  94. package/dist/tools/ToolCapabilityRegistry.js.map +1 -1
  95. package/dist/tools/ToolOrchestrator.js +6 -4
  96. package/dist/tools/ToolOrchestrator.js.map +1 -1
  97. package/dist/tools/ToolPolicy.js +16 -1
  98. package/dist/tools/ToolPolicy.js.map +1 -1
  99. package/dist/workflow/AdaptiveWorkflowRouter.d.ts +1 -0
  100. package/dist/workflow/AdaptiveWorkflowRouter.js +3 -0
  101. package/dist/workflow/AdaptiveWorkflowRouter.js.map +1 -1
  102. package/dist/workflow/CommitDiscipline.d.ts +68 -0
  103. package/dist/workflow/CommitDiscipline.js +328 -0
  104. package/dist/workflow/CommitDiscipline.js.map +1 -0
  105. package/dist/workflow/CrossRepoOrchestrator.d.ts +92 -0
  106. package/dist/workflow/CrossRepoOrchestrator.js +408 -0
  107. package/dist/workflow/CrossRepoOrchestrator.js.map +1 -0
  108. package/dist/workflow/GateCatalog.d.ts +61 -0
  109. package/dist/workflow/GateCatalog.js +212 -0
  110. package/dist/workflow/GateCatalog.js.map +1 -0
  111. package/dist/workflow/GovernanceRoi.d.ts +52 -0
  112. package/dist/workflow/GovernanceRoi.js +204 -0
  113. package/dist/workflow/GovernanceRoi.js.map +1 -0
  114. package/dist/workflow/GovernanceTemplatePacks.js +19 -4
  115. package/dist/workflow/GovernanceTemplatePacks.js.map +1 -1
  116. package/dist/workflow/GovernanceTemplates.js +2 -2
  117. package/dist/workflow/McpGovernance.d.ts +63 -0
  118. package/dist/workflow/McpGovernance.js +198 -0
  119. package/dist/workflow/McpGovernance.js.map +1 -0
  120. package/dist/workflow/SessionCoordinator.d.ts +103 -0
  121. package/dist/workflow/SessionCoordinator.js +401 -0
  122. package/dist/workflow/SessionCoordinator.js.map +1 -0
  123. package/dist/workflow/SessionPreamble.js +7 -2
  124. package/dist/workflow/SessionPreamble.js.map +1 -1
  125. package/dist/workflow/TaskDependencyGraph.d.ts +73 -0
  126. package/dist/workflow/TaskDependencyGraph.js +245 -0
  127. package/dist/workflow/TaskDependencyGraph.js.map +1 -0
  128. package/dist/workflow/TaskScoreEngine.d.ts +42 -0
  129. package/dist/workflow/TaskScoreEngine.js +181 -0
  130. package/dist/workflow/TaskScoreEngine.js.map +1 -0
  131. package/dist/workflow/WorkflowTemplates.d.ts +38 -0
  132. package/dist/workflow/WorkflowTemplates.js +371 -0
  133. package/dist/workflow/WorkflowTemplates.js.map +1 -0
  134. package/dist/workflow/WorkspacePolicy.d.ts +46 -0
  135. package/dist/workflow/WorkspacePolicy.js +141 -0
  136. package/dist/workflow/WorkspacePolicy.js.map +1 -0
  137. package/dist/workflow/WorkspaceTopology.d.ts +3 -0
  138. package/dist/workflow/WorkspaceTopology.js +40 -3
  139. package/dist/workflow/WorkspaceTopology.js.map +1 -1
  140. package/dist/workflow/gates/GateSystem.js +14 -11
  141. package/dist/workflow/gates/GateSystem.js.map +1 -1
  142. package/dist/workflow/index.d.ts +9 -0
  143. package/dist/workflow/index.js +9 -0
  144. package/dist/workflow/index.js.map +1 -1
  145. package/docs/CODE_INTELLIGENCE.md +48 -6
  146. package/docs/EXTERNAL_REFERENCES.md +5 -2
  147. package/docs/MEMORY_FABRIC.md +28 -3
  148. package/docs/SKILL-REPOSITORY.md +3 -3
  149. package/docs/THIRD_PARTY_SKILLS.md +50 -1
  150. package/docs/guides/GETTING_STARTED.md +24 -0
  151. package/docs/start/quickstart.md +107 -69
  152. package/docs/workflow/GATES_AND_SCORE.md +56 -0
  153. package/docs/workflow/PROMPT_OPTIMIZATION.md +44 -0
  154. package/docs/workflow/README.md +7 -0
  155. package/docs/workflow/node-library.md +3 -3
  156. package/docs/workflow/templates/skill-plan.md +1 -1
  157. package/package.json +13 -5
  158. package/scripts/workflow/provider-rehearsal.mjs +425 -0
  159. package/scripts/workflow/setup-smoke.mjs +299 -0
@@ -1,25 +1,46 @@
1
+ import { type ProfileBootstrapPlan } from '../config/profiles.js';
2
+ import { execSync } from 'node:child_process';
3
+ import { inspectCodeIntelligence } from '../codegraph/CodeIntelligence.js';
4
+ import { inspectMemoryProviders } from '../memory/MemoryProviders.js';
5
+ import { inspectToolCapabilities } from '../tools/ToolCapabilityRegistry.js';
1
6
  export interface DiagnosticResult {
2
7
  name: string;
3
8
  status: 'ok' | 'warn' | 'fail';
4
9
  message: string;
5
10
  fix?: string;
6
11
  optional?: boolean;
7
- category?: 'governance' | 'knowledge-graph' | 'runtime';
12
+ category?: 'governance' | 'knowledge-graph' | 'runtime' | 'memory';
8
13
  }
9
14
  export interface DoctorReport {
10
15
  overall: 'healthy' | 'degraded' | 'broken';
11
16
  checks: DiagnosticResult[];
12
17
  timestamp: number;
18
+ bootstrapPlan?: ProfileBootstrapPlan;
13
19
  knowledgeGraph?: {
14
20
  available: boolean;
15
21
  pythonVersion?: string;
16
22
  graphifyInstalled?: boolean;
23
+ codegraphInstalled?: boolean;
24
+ codegraphProjectInitialized?: boolean;
17
25
  };
26
+ memoryProviders?: {
27
+ available: boolean;
28
+ gbrainAvailable: boolean;
29
+ defaultOrder: string[];
30
+ mode: string;
31
+ };
32
+ }
33
+ interface DoctorDeps {
34
+ execSyncImpl?: typeof execSync;
35
+ inspectCodeIntelligenceImpl?: typeof inspectCodeIntelligence;
36
+ inspectMemoryProvidersImpl?: typeof inspectMemoryProviders;
37
+ inspectToolCapabilitiesImpl?: typeof inspectToolCapabilities;
18
38
  }
19
39
  export declare class Doctor {
20
40
  private projectDir;
21
41
  private scaleDir;
22
- constructor(projectDir?: string, scaleDir?: string);
42
+ private deps;
43
+ constructor(projectDir?: string, scaleDir?: string, deps?: DoctorDeps);
23
44
  diagnose(): Promise<DoctorReport>;
24
45
  private checkScaleDir;
25
46
  private checkEventsDir;
@@ -41,8 +62,22 @@ export declare class Doctor {
41
62
  private skippedEngineeringStandardsForWorkspaceConflict;
42
63
  private checkGovernanceDrift;
43
64
  private checkPython;
44
- private checkGraphify;
65
+ private checkGraphifyCli;
66
+ private checkGraphifyArtifact;
67
+ private checkCodegraph;
68
+ private checkCodegraphProject;
69
+ private checkMemoryProviders;
45
70
  private checkRuntimeEvidence;
46
71
  private checkConfigHealth;
72
+ private resolveBootstrapPlan;
73
+ private readProfileId;
74
+ private inspectCodeIntelligence;
75
+ private inspectMemoryProviders;
76
+ private inspectToolCapabilities;
77
+ private runExecSync;
78
+ private knowledgeBootstrapApplyCommand;
79
+ private memoryBootstrapApplyCommand;
47
80
  formatReport(report: DoctorReport): string;
81
+ private formatReportAscii;
48
82
  }
83
+ export {};
@@ -2,7 +2,7 @@
2
2
  // 环境诊断 + 健康检查
3
3
  // Usage: scale doctor
4
4
  import { existsSync, readdirSync, statSync, readFileSync } from 'node:fs';
5
- import { getProfile } from '../config/profiles.js';
5
+ import { getBootstrapPlanForProfile, getProfile } from '../config/profiles.js';
6
6
  import { join } from 'node:path';
7
7
  import { execSync } from 'node:child_process';
8
8
  import { computeGovernanceDrift } from '../workflow/GovernanceLock.js';
@@ -10,13 +10,21 @@ import { doctorEngineeringStandards } from '../workflow/EngineeringStandards.js'
10
10
  import { doctorResourceAssets } from '../workflow/ResourceGovernance.js';
11
11
  import { doctorRuntimeEvidence } from '../runtime/RuntimeDoctor.js';
12
12
  import { inspectWorkspaceSafety } from '../workflow/WorkspaceSafety.js';
13
+ import { inspectCodeIntelligence } from '../codegraph/CodeIntelligence.js';
14
+ import { inspectMemoryProviders } from '../memory/MemoryProviders.js';
15
+ import { inspectToolCapabilities } from '../tools/ToolCapabilityRegistry.js';
13
16
  export class Doctor {
14
- constructor(projectDir = '.', scaleDir = '.scale') {
17
+ constructor(projectDir = '.', scaleDir = '.scale', deps = {}) {
15
18
  this.projectDir = projectDir;
16
19
  this.scaleDir = scaleDir;
20
+ this.deps = deps;
17
21
  }
18
22
  async diagnose() {
19
23
  const checks = [];
24
+ const bootstrapPlan = this.resolveBootstrapPlan();
25
+ const codeIntelligence = this.inspectCodeIntelligence();
26
+ const memoryProviders = this.inspectMemoryProviders();
27
+ const toolCapabilities = this.inspectToolCapabilities(['graphify', 'codegraph', 'gbrain']);
20
28
  checks.push(this.checkScaleDir());
21
29
  checks.push(this.checkEventsDir());
22
30
  checks.push(this.checkArtifactsDir());
@@ -68,14 +76,30 @@ export class Doctor {
68
76
  configHealthCheck.category = 'governance';
69
77
  checks.push(configHealthCheck);
70
78
  // Optional knowledge graph checks (non-blocking)
71
- const pythonCheck = this.checkPython();
72
- const graphifyCheck = this.checkGraphify();
79
+ const pythonCheck = this.checkPython(bootstrapPlan);
80
+ const graphifyCheck = this.checkGraphifyCli(toolCapabilities, bootstrapPlan);
81
+ const graphifyArtifactCheck = this.checkGraphifyArtifact(codeIntelligence);
82
+ const codegraphCheck = this.checkCodegraph(toolCapabilities, bootstrapPlan);
83
+ const codegraphProjectCheck = this.checkCodegraphProject(codeIntelligence);
84
+ const memoryRoutingCheck = this.checkMemoryProviders(memoryProviders, bootstrapPlan);
73
85
  pythonCheck.optional = true;
74
86
  graphifyCheck.optional = true;
87
+ graphifyArtifactCheck.optional = true;
88
+ codegraphCheck.optional = true;
89
+ codegraphProjectCheck.optional = true;
90
+ memoryRoutingCheck.optional = true;
75
91
  pythonCheck.category = 'knowledge-graph';
76
92
  graphifyCheck.category = 'knowledge-graph';
93
+ graphifyArtifactCheck.category = 'knowledge-graph';
94
+ codegraphCheck.category = 'knowledge-graph';
95
+ codegraphProjectCheck.category = 'knowledge-graph';
96
+ memoryRoutingCheck.category = 'memory';
77
97
  checks.push(pythonCheck);
78
98
  checks.push(graphifyCheck);
99
+ checks.push(graphifyArtifactCheck);
100
+ checks.push(codegraphCheck);
101
+ checks.push(codegraphProjectCheck);
102
+ checks.push(memoryRoutingCheck);
79
103
  // Calculate overall health excluding optional checks
80
104
  const coreChecks = checks.filter((c) => !c.optional);
81
105
  const fails = coreChecks.filter((c) => c.status === 'fail').length;
@@ -83,11 +107,25 @@ export class Doctor {
83
107
  const overall = fails > 0 ? 'broken' : warns > 0 ? 'degraded' : 'healthy';
84
108
  // Knowledge graph availability metadata
85
109
  const knowledgeGraph = {
86
- available: pythonCheck.status === 'ok' && graphifyCheck.status === 'ok',
110
+ available: graphifyArtifactCheck.status === 'ok' || codegraphProjectCheck.status === 'ok',
87
111
  pythonVersion: pythonCheck.status === 'ok' ? pythonCheck.message : undefined,
88
112
  graphifyInstalled: graphifyCheck.status === 'ok',
113
+ codegraphInstalled: codegraphCheck.status === 'ok',
114
+ codegraphProjectInitialized: codegraphProjectCheck.status === 'ok',
115
+ };
116
+ return {
117
+ overall,
118
+ checks,
119
+ timestamp: Date.now(),
120
+ bootstrapPlan,
121
+ knowledgeGraph,
122
+ memoryProviders: {
123
+ available: memoryProviders.availableProviderCount > 0,
124
+ gbrainAvailable: Boolean(memoryProviders.providers.find(provider => provider.id === 'gbrain')?.available),
125
+ defaultOrder: [...memoryProviders.routing.defaultOrder],
126
+ mode: memoryProviders.routing.mode,
127
+ },
89
128
  };
90
- return { overall, checks, timestamp: Date.now(), knowledgeGraph };
91
129
  }
92
130
  checkScaleDir() {
93
131
  const dir = join(this.projectDir, this.scaleDir);
@@ -159,7 +197,27 @@ export class Doctor {
159
197
  }
160
198
  try {
161
199
  const content = JSON.parse(readFileSync(found.path, 'utf-8'));
162
- const hasScaleHooks = JSON.stringify(content).includes('scale ');
200
+ const collectHookEntries = (entries) => {
201
+ const flattened = [];
202
+ for (const entry of entries) {
203
+ if (!entry || typeof entry !== 'object')
204
+ continue;
205
+ flattened.push(entry);
206
+ if (Array.isArray(entry.hooks)) {
207
+ flattened.push(...collectHookEntries(entry.hooks ?? []));
208
+ }
209
+ }
210
+ return flattened;
211
+ };
212
+ const hookEntries = collectHookEntries(Object.values(content.hooks ?? {}).flatMap((value) => Array.isArray(value) ? value : []));
213
+ const hasScaleHooks = hookEntries.some((entry) => {
214
+ const command = typeof entry.command === 'string' ? entry.command : '';
215
+ const description = typeof entry.description === 'string' ? entry.description : '';
216
+ return /(^|\s)scale\s/.test(command)
217
+ || command.includes('.claude/hooks/')
218
+ || command.includes('scripts/hooks/')
219
+ || /scale|workflow/i.test(description);
220
+ });
163
221
  if (!hasScaleHooks) {
164
222
  return {
165
223
  name: 'Agent settings',
@@ -522,9 +580,9 @@ export class Doctor {
522
580
  message: `${drift.clean.length} generated governance files clean`,
523
581
  };
524
582
  }
525
- checkPython() {
583
+ checkPython(bootstrapPlan) {
526
584
  try {
527
- const version = execSync('python3 --version', { encoding: 'utf-8', timeout: 5000 }).trim();
585
+ const version = this.runExecSync('python3 --version').trim();
528
586
  const match = version.match(/Python (\d+)\.(\d+)/);
529
587
  if (match) {
530
588
  const major = parseInt(match[1]);
@@ -539,7 +597,7 @@ export class Doctor {
539
597
  catch {
540
598
  // Try python (without 3) for Windows
541
599
  try {
542
- const version = execSync('python --version', { encoding: 'utf-8', timeout: 5000 }).trim();
600
+ const version = this.runExecSync('python --version').trim();
543
601
  return { name: 'Python version', status: 'ok', message: version };
544
602
  }
545
603
  catch {
@@ -547,35 +605,74 @@ export class Doctor {
547
605
  name: 'Python version',
548
606
  status: 'warn',
549
607
  message: 'Not installed — knowledge graph requires Python',
550
- fix: 'Install Python 3.8+ or skip with --no-knowledge-graph',
608
+ fix: `Install Python 3.8+, then run: ${this.knowledgeBootstrapApplyCommand(bootstrapPlan)}`,
551
609
  };
552
610
  }
553
611
  }
554
612
  }
555
- checkGraphify() {
556
- try {
557
- const result = execSync('pip show graphifyy', { encoding: 'utf-8', timeout: 5000 });
558
- const match = result.match(/Version: (\S+)/);
559
- if (match) {
560
- return { name: 'Graphify', status: 'ok', message: `graphifyy v${match[1]} installed` };
561
- }
562
- return { name: 'Graphify', status: 'ok', message: 'installed' };
613
+ checkGraphifyCli(toolCapabilities, bootstrapPlan) {
614
+ const graphify = toolCapabilities.tools.find(tool => tool.id === 'graphify');
615
+ if (graphify?.installed) {
616
+ return { name: 'Graphify CLI', status: 'ok', message: graphify.version ?? graphify.detectedPath ?? 'installed' };
563
617
  }
564
- catch {
565
- // Try pip3
566
- try {
567
- execSync('pip3 show graphifyy', { encoding: 'utf-8', timeout: 5000 });
568
- return { name: 'Graphify', status: 'ok', message: 'installed (pip3)' };
569
- }
570
- catch {
571
- return {
572
- name: 'Graphify',
573
- status: 'warn',
574
- message: 'Not installed code knowledge graph optional',
575
- fix: 'pip install graphifyy && graphify install',
576
- };
577
- }
618
+ return {
619
+ name: 'Graphify CLI',
620
+ status: 'warn',
621
+ message: graphify?.missingReason ?? 'Graphify CLI is not installed',
622
+ fix: `Run: ${this.knowledgeBootstrapApplyCommand(bootstrapPlan)}`,
623
+ };
624
+ }
625
+ checkGraphifyArtifact(codeIntelligence) {
626
+ const graphify = codeIntelligence.providers.find(provider => provider.id === 'graphify');
627
+ if (graphify?.available) {
628
+ return { name: 'Graphify artifact', status: 'ok', message: graphify.reason };
629
+ }
630
+ return {
631
+ name: 'Graphify artifact',
632
+ status: 'warn',
633
+ message: graphify?.reason ?? 'Graphify artifact is not available',
634
+ fix: 'Run: scale codegraph status --json and generate graphify-out/graph.json before relying on graph-backed knowledge recall',
635
+ };
636
+ }
637
+ checkCodegraph(toolCapabilities, bootstrapPlan) {
638
+ const codegraph = toolCapabilities.tools.find(tool => tool.id === 'codegraph');
639
+ if (codegraph?.installed) {
640
+ return { name: 'CodeGraph CLI', status: 'ok', message: codegraph.version ?? codegraph.detectedPath ?? 'installed' };
641
+ }
642
+ return {
643
+ name: 'CodeGraph CLI',
644
+ status: 'warn',
645
+ message: codegraph?.missingReason ?? 'CodeGraph CLI is not installed',
646
+ fix: `Run: ${this.knowledgeBootstrapApplyCommand(bootstrapPlan)}`,
647
+ };
648
+ }
649
+ checkCodegraphProject(codeIntelligence) {
650
+ if (codeIntelligence.projectIndexExists) {
651
+ return { name: 'CodeGraph project index', status: 'ok', message: `Found at ${codeIntelligence.projectIndexPath}` };
652
+ }
653
+ return {
654
+ name: 'CodeGraph project index',
655
+ status: 'warn',
656
+ message: 'Project is not initialized for CodeGraph',
657
+ fix: 'Run: scale codegraph init',
658
+ };
659
+ }
660
+ checkMemoryProviders(memoryProviders, bootstrapPlan) {
661
+ const gbrain = memoryProviders.providers.find(provider => provider.id === 'gbrain');
662
+ if (gbrain?.available) {
663
+ return {
664
+ name: 'Memory provider routing',
665
+ status: memoryProviders.warnings.length > 0 ? 'warn' : 'ok',
666
+ message: `mode=${memoryProviders.routing.mode}; order=${memoryProviders.routing.defaultOrder.join(' -> ')}; gbrain=available`,
667
+ fix: memoryProviders.warnings.length > 0 ? 'Run: scale memory provider status --json' : undefined,
668
+ };
578
669
  }
670
+ return {
671
+ name: 'Memory provider routing',
672
+ status: 'warn',
673
+ message: `mode=${memoryProviders.routing.mode}; order=${memoryProviders.routing.defaultOrder.join(' -> ')}; gbrain=unavailable`,
674
+ fix: `Run: ${this.memoryBootstrapApplyCommand(bootstrapPlan)}`,
675
+ };
579
676
  }
580
677
  checkRuntimeEvidence() {
581
678
  try {
@@ -627,21 +724,20 @@ export class Doctor {
627
724
  const profileMatch = content.match(/^profile:\s*(.+)$/m);
628
725
  const profileId = profileMatch?.[1]?.trim() || 'standard';
629
726
  const profile = getProfile(profileId);
727
+ const bootstrapPlan = getBootstrapPlanForProfile(profile.id);
630
728
  if (profile.id !== profileId) {
631
729
  issues.push(`Unknown profile "${profileId}", falling back to standard`);
632
730
  }
633
- // Check vector search config without Qdrant
731
+ // Check legacy vector-search config drift
634
732
  if (content.includes('backend: qdrant')) {
635
- try {
636
- execSync('curl -s http://localhost:6333/readyz', { timeout: 3000, stdio: 'pipe' });
637
- }
638
- catch {
639
- issues.push('Vector search configured with Qdrant, but Qdrant is not reachable at localhost:6333');
640
- }
733
+ issues.push('Legacy Qdrant backend configured; default knowledge and recall flow now expects graphify + codegraph instead of Qdrant');
734
+ recommendations.push('Update .scale/config.yaml to use graphify-backed knowledge, or rerun: scale config profile --set advanced');
641
735
  }
642
736
  // Check evolution enabled without eval setup
643
737
  if (content.includes('evolution:') && content.includes('enabled: true')) {
644
- const evalPath = join(this.projectDir, this.scaleDir, 'eval');
738
+ const evalPath = existsSync(join(this.projectDir, this.scaleDir, 'evals'))
739
+ ? join(this.projectDir, this.scaleDir, 'evals')
740
+ : join(this.projectDir, this.scaleDir, 'eval');
645
741
  if (!existsSync(evalPath)) {
646
742
  recommendations.push('Evolution enabled but no .scale/eval/ directory — run: scale eval init');
647
743
  }
@@ -662,6 +758,9 @@ export class Doctor {
662
758
  void error;
663
759
  }
664
760
  }
761
+ if (bootstrapPlan.packs.length > 0 && profile.defaults.knowledge.enabled) {
762
+ recommendations.push(`Bootstrap profile-aligned dependencies with: ${bootstrapPlan.inspectCommand}`);
763
+ }
665
764
  if (issues.length > 0) {
666
765
  return {
667
766
  name: 'Config health',
@@ -687,7 +786,55 @@ export class Doctor {
687
786
  };
688
787
  }
689
788
  }
789
+ resolveBootstrapPlan() {
790
+ return getBootstrapPlanForProfile(this.readProfileId());
791
+ }
792
+ readProfileId() {
793
+ const configPath = join(this.projectDir, this.scaleDir, 'config.yaml');
794
+ if (!existsSync(configPath))
795
+ return 'standard';
796
+ try {
797
+ const content = readFileSync(configPath, 'utf-8');
798
+ const match = content.match(/^profile:\s*(.+)$/m);
799
+ return match?.[1]?.trim() || 'standard';
800
+ }
801
+ catch {
802
+ return 'standard';
803
+ }
804
+ }
805
+ inspectCodeIntelligence() {
806
+ return (this.deps.inspectCodeIntelligenceImpl ?? inspectCodeIntelligence)({
807
+ projectDir: this.projectDir,
808
+ scaleDir: this.scaleDir,
809
+ });
810
+ }
811
+ inspectMemoryProviders() {
812
+ return (this.deps.inspectMemoryProvidersImpl ?? inspectMemoryProviders)({
813
+ projectDir: this.projectDir,
814
+ scaleDir: this.scaleDir,
815
+ });
816
+ }
817
+ inspectToolCapabilities(toolIds) {
818
+ return (this.deps.inspectToolCapabilitiesImpl ?? inspectToolCapabilities)({
819
+ projectDir: this.projectDir,
820
+ toolIds,
821
+ });
822
+ }
823
+ runExecSync(command) {
824
+ return String((this.deps.execSyncImpl ?? execSync)(command, { encoding: 'utf-8', timeout: 5000 }));
825
+ }
826
+ knowledgeBootstrapApplyCommand(bootstrapPlan) {
827
+ return bootstrapPlan.packs.includes('knowledge')
828
+ ? bootstrapPlan.applyCommand
829
+ : 'scale bootstrap deps --pack knowledge --apply';
830
+ }
831
+ memoryBootstrapApplyCommand(bootstrapPlan) {
832
+ return bootstrapPlan.packs.includes('memory')
833
+ ? bootstrapPlan.applyCommand
834
+ : 'scale bootstrap deps --pack memory --apply';
835
+ }
690
836
  formatReport(report) {
837
+ return this.formatReportAscii(report);
691
838
  const icon = { healthy: '✅', degraded: '⚠️', broken: '❌' };
692
839
  const statusIcon = { ok: '✅', warn: '⚠️', fail: '❌' };
693
840
  const lines = [
@@ -722,16 +869,33 @@ export class Doctor {
722
869
  lines.push(` 💡 Fix: ${check.fix}`);
723
870
  }
724
871
  }
872
+ const memoryChecks = report.checks.filter((c) => c.optional && c.category === 'memory');
873
+ if (memoryChecks.length > 0) {
874
+ lines.push('');
875
+ lines.push('Memory Providers (Optional):');
876
+ for (const check of memoryChecks) {
877
+ lines.push(` ${statusIcon[check.status]} ${check.name}: ${check.message}`);
878
+ if (check.fix)
879
+ lines.push(` Fix: ${check.fix}`);
880
+ }
881
+ }
725
882
  // Knowledge graph status summary
726
883
  if (report.knowledgeGraph) {
884
+ const knowledgeGraph = report.knowledgeGraph;
727
885
  lines.push('');
728
- if (report.knowledgeGraph.available) {
886
+ if (knowledgeGraph.available) {
729
887
  lines.push(' ✅ Code knowledge graph available');
730
- lines.push(' → Use: scale graphify .');
888
+ if (knowledgeGraph.codegraphProjectInitialized) {
889
+ lines.push(' → Use: scale codegraph context --symbol <Symbol>');
890
+ }
891
+ if (knowledgeGraph.graphifyInstalled) {
892
+ lines.push(' → Use: scale graphify .');
893
+ }
731
894
  }
732
895
  else {
733
896
  lines.push(' ⚠️ Code knowledge graph not available (optional feature)');
734
- lines.push(' → Install: pip install graphifyy && graphify install');
897
+ lines.push(' → Install CodeGraph: npx @colbymchenry/codegraph');
898
+ lines.push(' → Install Graphify: pip install graphify && graphify install');
735
899
  }
736
900
  lines.push(`${'─'.repeat(50)}`);
737
901
  }
@@ -753,5 +917,66 @@ export class Doctor {
753
917
  lines.push(` ${ok} passed, ${warn} warnings, ${fail} failures (${optional} optional)`);
754
918
  return lines.join('\n');
755
919
  }
920
+ formatReportAscii(report) {
921
+ const icon = { healthy: '[OK]', degraded: '[WARN]', broken: '[FAIL]' };
922
+ const statusIcon = { ok: '[OK]', warn: '[WARN]', fail: '[FAIL]' };
923
+ const divider = '-'.repeat(50);
924
+ const lines = [
925
+ '',
926
+ `${icon[report.overall]} SCALE Engine Health: ${report.overall.toUpperCase()}`,
927
+ divider,
928
+ ];
929
+ for (const check of report.checks.filter((c) => !c.optional)) {
930
+ lines.push(` ${statusIcon[check.status]} ${check.name}: ${check.message}`);
931
+ if (check.fix)
932
+ lines.push(` Fix: ${check.fix}`);
933
+ }
934
+ lines.push(divider);
935
+ const appendSection = (title, category) => {
936
+ const sectionChecks = report.checks.filter((c) => c.optional && c.category === category);
937
+ if (sectionChecks.length === 0)
938
+ return;
939
+ lines.push('');
940
+ lines.push(title);
941
+ for (const check of sectionChecks) {
942
+ lines.push(` ${statusIcon[check.status]} ${check.name}: ${check.message}`);
943
+ if (check.fix)
944
+ lines.push(` Fix: ${check.fix}`);
945
+ }
946
+ };
947
+ appendSection('Project Governance (Optional):', 'governance');
948
+ appendSection('Knowledge Graph (Optional):', 'knowledge-graph');
949
+ appendSection('Memory Providers (Optional):', 'memory');
950
+ appendSection('Runtime Evidence (Optional):', 'runtime');
951
+ if (report.knowledgeGraph) {
952
+ const knowledgeGraph = report.knowledgeGraph;
953
+ lines.push('');
954
+ if (knowledgeGraph.available) {
955
+ lines.push(' [OK] Code knowledge graph available');
956
+ if (report.knowledgeGraph.codegraphProjectInitialized) {
957
+ lines.push(' -> Use: scale codegraph context --symbol <Symbol>');
958
+ }
959
+ if (report.knowledgeGraph.graphifyInstalled) {
960
+ lines.push(' -> Use: scale graphify .');
961
+ }
962
+ }
963
+ else {
964
+ lines.push(' [WARN] Code knowledge graph not available (optional feature)');
965
+ lines.push(` -> Bootstrap inspect: ${report.bootstrapPlan?.inspectCommand ?? 'scale bootstrap deps --pack knowledge --json'}`);
966
+ lines.push(` -> Bootstrap apply: ${report.bootstrapPlan?.packs.includes('knowledge') ? report.bootstrapPlan.applyCommand : 'scale bootstrap deps --pack knowledge --apply'}`);
967
+ }
968
+ lines.push(divider);
969
+ }
970
+ if (report.memoryProviders && !report.memoryProviders.gbrainAvailable) {
971
+ lines.push(` -> Memory bootstrap: ${report.bootstrapPlan?.packs.includes('memory') ? report.bootstrapPlan.applyCommand : 'scale bootstrap deps --pack memory --apply'}`);
972
+ lines.push(divider);
973
+ }
974
+ const ok = report.checks.filter((c) => c.status === 'ok').length;
975
+ const warn = report.checks.filter((c) => c.status === 'warn').length;
976
+ const fail = report.checks.filter((c) => c.status === 'fail').length;
977
+ const optional = report.checks.filter((c) => c.optional).length;
978
+ lines.push(` ${ok} passed, ${warn} warnings, ${fail} failures (${optional} optional)`);
979
+ return lines.join('\n');
980
+ }
756
981
  }
757
982
  //# sourceMappingURL=doctor.js.map