@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
@@ -0,0 +1,204 @@
1
+ // SCALE Engine — Governance ROI Report (v0.35.0)
2
+ // End-to-end governance ROI metrics: token cost vs quality vs gate friction
3
+ import { existsSync, readFileSync } from 'node:fs';
4
+ import { isAbsolute, join, resolve } from 'node:path';
5
+ import { TaskMetricsStore } from './TaskMetricsStore.js';
6
+ import { ModelUsageLedger } from '../runtime/ModelUsageLedger.js';
7
+ import { EvidenceStore } from './EvidenceStore.js';
8
+ export function collectGovernanceRoi(input = {}) {
9
+ const projectDir = resolve(input.projectDir ?? process.cwd());
10
+ const scaleRoot = isAbsolute(input.scaleDir ?? '')
11
+ ? input.scaleDir
12
+ : join(projectDir, input.scaleDir ?? '.scale');
13
+ const taskMetrics = collectTaskMetrics(scaleRoot);
14
+ const costMetrics = collectCostMetrics(scaleRoot);
15
+ const frictionMetrics = collectFrictionMetrics(scaleRoot, taskMetrics.records);
16
+ const quality = {
17
+ firstPassRate: taskMetrics.summary.total > 0 ? taskMetrics.summary.firstPassRate : 0,
18
+ averageFixIterations: taskMetrics.summary.averageFixIterations,
19
+ gatePassRate: frictionMetrics.totalGateChecks > 0
20
+ ? (frictionMetrics.totalGateChecks - frictionMetrics.gateBlocks) / frictionMetrics.totalGateChecks
21
+ : 0,
22
+ evidenceCompletenessRate: taskMetrics.summary.artifactCompletenessRate,
23
+ securityFindingsCount: 0,
24
+ resolvedSecurityFindings: 0,
25
+ };
26
+ // Check security audit results
27
+ const securityPath = join(scaleRoot, 'security-audit.json');
28
+ if (existsSync(securityPath)) {
29
+ try {
30
+ const audit = JSON.parse(readFileSync(securityPath, 'utf-8'));
31
+ quality.securityFindingsCount = audit.findings?.length ?? 0;
32
+ quality.resolvedSecurityFindings = audit.findings?.filter((f) => f.resolved).length ?? 0;
33
+ }
34
+ catch { /* ignore */ }
35
+ }
36
+ const tokenEfficiency = costMetrics.totalTokensUsed > 0
37
+ ? quality.firstPassRate / (costMetrics.totalTokensUsed / 10000)
38
+ : 0;
39
+ const gateEfficiency = frictionMetrics.gateBlocks > 0
40
+ ? quality.gatePassRate / (frictionMetrics.gateBlocks / Math.max(1, frictionMetrics.totalGateChecks))
41
+ : quality.gatePassRate;
42
+ const overallScore = round(Math.min(100, quality.firstPassRate * 30 +
43
+ quality.gatePassRate * 20 +
44
+ quality.evidenceCompletenessRate * 20 +
45
+ (1 - Math.min(1, frictionMetrics.gateBlocks / Math.max(1, frictionMetrics.totalGateChecks))) * 15 +
46
+ (costMetrics.contextCompilerSavings > 0 ? 10 : 0) +
47
+ (quality.averageFixIterations < 2 ? 5 : 0)));
48
+ const recommendations = buildRecommendations(quality, frictionMetrics, costMetrics);
49
+ return {
50
+ cost: costMetrics,
51
+ quality,
52
+ friction: frictionMetrics,
53
+ roi: {
54
+ tokenEfficiency: round(tokenEfficiency),
55
+ gateEfficiency: round(gateEfficiency),
56
+ overallScore,
57
+ },
58
+ recommendations,
59
+ };
60
+ }
61
+ export function summarizeGovernanceRoi(summary) {
62
+ const lines = [
63
+ '## Governance ROI Report',
64
+ '',
65
+ `**Overall Score:** ${summary.roi.overallScore}/100`,
66
+ '',
67
+ '### Cost',
68
+ `- Total Tokens: ${summary.cost.totalTokensUsed.toLocaleString()}`,
69
+ `- Context Compiler Savings: ${summary.cost.contextCompilerSavings.toLocaleString()}`,
70
+ `- Cache Hit Savings: ${summary.cost.cacheHitSavings.toLocaleString()}`,
71
+ ];
72
+ if (summary.cost.estimatedCostUsd !== undefined) {
73
+ lines.push(`- Estimated Cost: $${summary.cost.estimatedCostUsd.toFixed(4)}`);
74
+ }
75
+ lines.push('', '### Quality', `- First Pass Rate: ${(summary.quality.firstPassRate * 100).toFixed(0)}%`, `- Average Fix Iterations: ${summary.quality.averageFixIterations.toFixed(1)}`, `- Gate Pass Rate: ${(summary.quality.gatePassRate * 100).toFixed(0)}%`, `- Evidence Completeness: ${(summary.quality.evidenceCompletenessRate * 100).toFixed(0)}%`, `- Security Findings: ${summary.quality.securityFindingsCount} (${summary.quality.resolvedSecurityFindings} resolved)`, '', '### Friction', `- Gate Checks: ${summary.friction.totalGateChecks}`, `- Gate Blocks: ${summary.friction.gateBlocks}`, `- Skipped Phases: ${summary.friction.skippedPhases}`, `- Manual Overrides: ${summary.friction.manualOverrides}`, '', '### ROI', `- Token Efficiency: ${summary.roi.tokenEfficiency}`, `- Gate Efficiency: ${summary.roi.gateEfficiency}`);
76
+ if (summary.recommendations.length > 0) {
77
+ lines.push('', '### Recommendations');
78
+ for (const r of summary.recommendations)
79
+ lines.push(`- ${r}`);
80
+ }
81
+ return lines.join('\n');
82
+ }
83
+ export function compareRoiReports(baseline, current) {
84
+ const costDelta = {
85
+ totalTokensUsed: current.cost.totalTokensUsed - baseline.cost.totalTokensUsed,
86
+ contextCompilerSavings: current.cost.contextCompilerSavings - baseline.cost.contextCompilerSavings,
87
+ cacheHitSavings: current.cost.cacheHitSavings - baseline.cost.cacheHitSavings,
88
+ };
89
+ const qualityDelta = {
90
+ firstPassRate: round(current.quality.firstPassRate - baseline.quality.firstPassRate),
91
+ averageFixIterations: round(current.quality.averageFixIterations - baseline.quality.averageFixIterations),
92
+ gatePassRate: round(current.quality.gatePassRate - baseline.quality.gatePassRate),
93
+ };
94
+ const frictionDelta = {
95
+ totalGateChecks: current.friction.totalGateChecks - baseline.friction.totalGateChecks,
96
+ gateBlocks: current.friction.gateBlocks - baseline.friction.gateBlocks,
97
+ skippedPhases: current.friction.skippedPhases - baseline.friction.skippedPhases,
98
+ };
99
+ const roiDelta = {
100
+ tokenEfficiencyChange: round(current.roi.tokenEfficiency - baseline.roi.tokenEfficiency),
101
+ gateEfficiencyChange: round(current.roi.gateEfficiency - baseline.roi.gateEfficiency),
102
+ overallScoreChange: current.roi.overallScore - baseline.roi.overallScore,
103
+ };
104
+ const improving = roiDelta.overallScoreChange > 0;
105
+ const summary = improving
106
+ ? `Governance ROI improved by ${roiDelta.overallScoreChange} points.`
107
+ : roiDelta.overallScoreChange < 0
108
+ ? `Governance ROI decreased by ${Math.abs(roiDelta.overallScoreChange)} points.`
109
+ : 'Governance ROI unchanged.';
110
+ return { costDelta, qualityDelta, frictionDelta, roiDelta, summary };
111
+ }
112
+ function collectTaskMetrics(scaleDir) {
113
+ try {
114
+ const store = new TaskMetricsStore(scaleDir);
115
+ const records = store.list();
116
+ return { records, summary: store.summarize() };
117
+ }
118
+ catch {
119
+ return {
120
+ records: [],
121
+ summary: {
122
+ total: 0,
123
+ firstPassRate: 0,
124
+ averageFixIterations: 0,
125
+ artifactCompletenessRate: 0,
126
+ residualRiskClarityRate: 0,
127
+ },
128
+ };
129
+ }
130
+ }
131
+ function collectCostMetrics(scaleDir) {
132
+ try {
133
+ const ledger = new ModelUsageLedger(scaleDir);
134
+ const summary = ledger.summarize();
135
+ return {
136
+ totalTokensUsed: summary.totalTokens,
137
+ tokensByPhase: {},
138
+ estimatedCostUsd: summary.estimatedCostUsd,
139
+ contextCompilerSavings: 0,
140
+ cacheHitSavings: summary.cacheSavingsTokens,
141
+ };
142
+ }
143
+ catch {
144
+ return {
145
+ totalTokensUsed: 0,
146
+ tokensByPhase: {},
147
+ contextCompilerSavings: 0,
148
+ cacheHitSavings: 0,
149
+ };
150
+ }
151
+ }
152
+ function collectFrictionMetrics(scaleDir, _records) {
153
+ try {
154
+ const evidenceStore = new EvidenceStore(scaleDir);
155
+ const gates = evidenceStore.listGateResults(1000);
156
+ const totalGateChecks = gates.length;
157
+ const gateBlocks = gates.filter(g => g.status === 'FAILED').length;
158
+ return {
159
+ totalGateChecks,
160
+ gateBlocks,
161
+ averageGateLatencyMs: 0,
162
+ skippedPhases: 0,
163
+ manualOverrides: 0,
164
+ };
165
+ }
166
+ catch {
167
+ return {
168
+ totalGateChecks: 0,
169
+ gateBlocks: 0,
170
+ averageGateLatencyMs: 0,
171
+ skippedPhases: 0,
172
+ manualOverrides: 0,
173
+ };
174
+ }
175
+ }
176
+ function buildRecommendations(quality, friction, cost) {
177
+ const recs = [];
178
+ if (quality.firstPassRate < 0.6) {
179
+ recs.push('First pass rate is below 60%. Improve test coverage and pre-verification checks.');
180
+ }
181
+ if (quality.averageFixIterations > 3) {
182
+ recs.push('Average fix iterations is high. Consider adding more specific error guidance.');
183
+ }
184
+ if (quality.gatePassRate < 0.8 && friction.totalGateChecks > 0) {
185
+ recs.push('Gate pass rate is below 80%. Review gate configurations for false positives.');
186
+ }
187
+ if (friction.gateBlocks > friction.totalGateChecks * 0.3 && friction.totalGateChecks > 0) {
188
+ recs.push('High gate block rate. Consider adjusting thresholds or adding advisory gates.');
189
+ }
190
+ if (cost.totalTokensUsed > 0 && cost.contextCompilerSavings === 0) {
191
+ recs.push('No context compiler savings recorded. Enable context budgeting to reduce token usage.');
192
+ }
193
+ if (quality.securityFindingsCount > quality.resolvedSecurityFindings) {
194
+ recs.push(`${quality.securityFindingsCount - quality.resolvedSecurityFindings} unresolved security finding(s).`);
195
+ }
196
+ if (recs.length === 0) {
197
+ recs.push('Governance metrics look healthy. Continue monitoring.');
198
+ }
199
+ return recs;
200
+ }
201
+ function round(n) {
202
+ return Math.round(n * 100) / 100;
203
+ }
204
+ //# sourceMappingURL=GovernanceRoi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GovernanceRoi.js","sourceRoot":"","sources":["../../src/workflow/GovernanceRoi.ts"],"names":[],"mappings":"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"}
@@ -276,7 +276,7 @@ SCALE plans required skills from task description, service selection, and change
276
276
 
277
277
  Tool orchestration is part of the workflow contract:
278
278
 
279
- - UI/UX work requires \`frontend-design\` and \`ui-ux-pro-max\`, and should consider \`awesome-design-md\`, browser screenshots, responsive checks, and visual review evidence.
279
+ - UI/UX work requires \`awesome-design-md\` and \`ui-ux-pro-max\`, and should use \`frontend-design\` as an implementation companion alongside browser screenshots, responsive checks, and visual review evidence.
280
280
  - Web research, logged-in pages, and dynamic browser work require \`web-access\` evidence, source citations, and browser/network/console evidence when available.
281
281
  - Browser E2E work should combine \`webapp-testing\`, Playwright, Agent Browser, web-access, or Chrome DevTools MCP according to the target and record screenshots plus console/network findings.
282
282
  - Desktop or client-side GUI automation uses CUA/computer-use only with explicit operator-safety notes, desktop screenshots, and a side-effect boundary.
@@ -465,7 +465,7 @@ function skillPlanTemplate() {
465
465
 
466
466
  | Capability | Primary Tool Or Skill | Fallback | Required Evidence |
467
467
  | --- | --- | --- | --- |
468
- | UI/UX design | frontend-design, ui-ux-pro-max | awesome-design-md | design-system, ui-spec.md, visual-review.md |
468
+ | UI/UX design | awesome-design-md, ui-ux-pro-max | frontend-design | design-system, ui-spec.md, visual-review.md |
469
469
  | Web research or logged-in pages | web-access | agent-browser, Chrome DevTools MCP | source citations, browser evidence |
470
470
  | Browser E2E | webapp-testing, Playwright | agent-browser, web-access | screenshot, console, network evidence |
471
471
  | Desktop GUI automation | CUA/computer-use | manual verification | desktop screenshot, operator-safety notes |
@@ -0,0 +1,63 @@
1
+ export type McpServerStatus = 'unknown' | 'healthy' | 'degraded' | 'unhealthy' | 'blocked';
2
+ export type McpSecurityLevel = 'trusted' | 'review' | 'untrusted';
3
+ export interface McpServerRegistration {
4
+ id: string;
5
+ name: string;
6
+ transport: 'stdio' | 'sse' | 'streamable-http';
7
+ command?: string;
8
+ url?: string;
9
+ version?: string;
10
+ securityLevel: McpSecurityLevel;
11
+ capabilities: string[];
12
+ registeredAt: string;
13
+ lastHealthCheck?: string;
14
+ status: McpServerStatus;
15
+ }
16
+ export interface McpHealthCheckResult {
17
+ serverId: string;
18
+ status: McpServerStatus;
19
+ latency?: number;
20
+ toolCount?: number;
21
+ error?: string;
22
+ checkedAt: string;
23
+ }
24
+ export interface McpGovernanceConfig {
25
+ autoHealthCheck: boolean;
26
+ healthCheckIntervalMs: number;
27
+ blockUntrusted: boolean;
28
+ requiredCapabilities: string[];
29
+ maxLatencyMs: number;
30
+ }
31
+ export interface McpSecurityScanResult {
32
+ serverId: string;
33
+ findings: McpSecurityFinding[];
34
+ riskLevel: 'low' | 'medium' | 'high' | 'critical';
35
+ scannedAt: string;
36
+ }
37
+ export interface McpSecurityFinding {
38
+ id: string;
39
+ severity: 'low' | 'medium' | 'high' | 'critical';
40
+ title: string;
41
+ description: string;
42
+ recommendation: string;
43
+ }
44
+ export declare class McpGovernor {
45
+ private servers;
46
+ private config;
47
+ private now;
48
+ constructor(config?: McpGovernanceConfig, now?: () => Date);
49
+ register(server: Omit<McpServerRegistration, 'registeredAt' | 'status'>): McpServerRegistration;
50
+ unregister(id: string): void;
51
+ getServer(id: string): McpServerRegistration | undefined;
52
+ listServers(): McpServerRegistration[];
53
+ checkHealth(id: string): McpHealthCheckResult;
54
+ checkAllHealth(): McpHealthCheckResult[];
55
+ scanSecurity(id: string): McpSecurityScanResult;
56
+ isAllowed(id: string, toolName: string): {
57
+ allowed: boolean;
58
+ reason?: string;
59
+ };
60
+ getConfig(): McpGovernanceConfig;
61
+ updateConfig(patch: Partial<McpGovernanceConfig>): void;
62
+ loadFromProject(projectDir?: string): void;
63
+ }
@@ -0,0 +1,198 @@
1
+ // SCALE Engine — MCP Lifecycle Governance (v0.34.0)
2
+ // MCP server lifecycle management with health checks, security scanning, and policy enforcement
3
+ import { existsSync, readFileSync } from 'node:fs';
4
+ import { join, resolve } from 'node:path';
5
+ import yaml from 'js-yaml';
6
+ import { randomUUID } from 'node:crypto';
7
+ const DEFAULT_GOVERNANCE_CONFIG = {
8
+ autoHealthCheck: true,
9
+ healthCheckIntervalMs: 30000,
10
+ blockUntrusted: false,
11
+ requiredCapabilities: [],
12
+ maxLatencyMs: 5000,
13
+ };
14
+ export class McpGovernor {
15
+ constructor(config, now) {
16
+ this.servers = new Map();
17
+ this.config = config ?? { ...DEFAULT_GOVERNANCE_CONFIG };
18
+ this.now = now ?? (() => new Date());
19
+ }
20
+ register(server) {
21
+ const existing = this.servers.get(server.id);
22
+ const registration = {
23
+ ...server,
24
+ registeredAt: existing?.registeredAt ?? this.now().toISOString(),
25
+ status: existing?.status ?? 'unknown',
26
+ lastHealthCheck: existing?.lastHealthCheck,
27
+ };
28
+ this.servers.set(server.id, registration);
29
+ return registration;
30
+ }
31
+ unregister(id) {
32
+ this.servers.delete(id);
33
+ }
34
+ getServer(id) {
35
+ return this.servers.get(id);
36
+ }
37
+ listServers() {
38
+ return [...this.servers.values()];
39
+ }
40
+ checkHealth(id) {
41
+ const server = this.servers.get(id);
42
+ if (!server) {
43
+ return {
44
+ serverId: id,
45
+ status: 'unhealthy',
46
+ error: 'Server not registered',
47
+ checkedAt: this.now().toISOString(),
48
+ };
49
+ }
50
+ // Blocked servers stay blocked
51
+ if (server.status === 'blocked') {
52
+ return {
53
+ serverId: id,
54
+ status: 'blocked',
55
+ error: 'Server is blocked by governance policy',
56
+ checkedAt: this.now().toISOString(),
57
+ };
58
+ }
59
+ // Check security level against policy
60
+ if (this.config.blockUntrusted && server.securityLevel === 'untrusted') {
61
+ server.status = 'blocked';
62
+ return {
63
+ serverId: id,
64
+ status: 'blocked',
65
+ error: 'Untrusted server blocked by governance policy',
66
+ checkedAt: this.now().toISOString(),
67
+ };
68
+ }
69
+ // Simulate health check based on registration data
70
+ const latency = server.transport === 'stdio' ? 50 : 200;
71
+ const status = latency > this.config.maxLatencyMs ? 'degraded' : 'healthy';
72
+ server.status = status;
73
+ server.lastHealthCheck = this.now().toISOString();
74
+ return {
75
+ serverId: id,
76
+ status,
77
+ latency,
78
+ toolCount: server.capabilities.length,
79
+ checkedAt: server.lastHealthCheck,
80
+ };
81
+ }
82
+ checkAllHealth() {
83
+ return [...this.servers.keys()].map(id => this.checkHealth(id));
84
+ }
85
+ scanSecurity(id) {
86
+ const server = this.servers.get(id);
87
+ const scannedAt = this.now().toISOString();
88
+ if (!server) {
89
+ return {
90
+ serverId: id,
91
+ findings: [{
92
+ id: `MCP-SEC-${randomUUID().slice(0, 8)}`,
93
+ severity: 'high',
94
+ title: 'Unregistered server',
95
+ description: `Server "${id}" is not registered in the governance system`,
96
+ recommendation: 'Register the server before use',
97
+ }],
98
+ riskLevel: 'high',
99
+ scannedAt,
100
+ };
101
+ }
102
+ const findings = [];
103
+ // Check security level
104
+ if (server.securityLevel === 'untrusted') {
105
+ findings.push({
106
+ id: `MCP-SEC-${randomUUID().slice(0, 8)}`,
107
+ severity: 'high',
108
+ title: 'Untrusted security level',
109
+ description: `Server "${server.name}" has untrusted security level`,
110
+ recommendation: 'Review server source and upgrade to "review" or "trusted" after validation',
111
+ });
112
+ }
113
+ // Check required capabilities
114
+ for (const cap of this.config.requiredCapabilities) {
115
+ if (!server.capabilities.includes(cap)) {
116
+ findings.push({
117
+ id: `MCP-SEC-${randomUUID().slice(0, 8)}`,
118
+ severity: 'medium',
119
+ title: 'Missing required capability',
120
+ description: `Server "${server.name}" is missing required capability "${cap}"`,
121
+ recommendation: `Add "${cap}" capability to the server configuration`,
122
+ });
123
+ }
124
+ }
125
+ // Check transport security
126
+ if (server.transport === 'sse' && !server.url?.startsWith('https://')) {
127
+ findings.push({
128
+ id: `MCP-SEC-${randomUUID().slice(0, 8)}`,
129
+ severity: 'medium',
130
+ title: 'Insecure transport',
131
+ description: `Server "${server.name}" uses SSE without HTTPS`,
132
+ recommendation: 'Use HTTPS for SSE transport to prevent MITM attacks',
133
+ });
134
+ }
135
+ // Check for stdio with command injection risk
136
+ if (server.transport === 'stdio' && server.command) {
137
+ if (server.command.includes('&&') || server.command.includes('|') || server.command.includes(';')) {
138
+ findings.push({
139
+ id: `MCP-SEC-${randomUUID().slice(0, 8)}`,
140
+ severity: 'critical',
141
+ title: 'Potential command injection',
142
+ description: `Server "${server.name}" command contains shell operators`,
143
+ recommendation: 'Remove shell operators from the command; use separate arguments',
144
+ });
145
+ }
146
+ }
147
+ const riskLevel = findings.some(f => f.severity === 'critical')
148
+ ? 'critical'
149
+ : findings.some(f => f.severity === 'high')
150
+ ? 'high'
151
+ : findings.some(f => f.severity === 'medium')
152
+ ? 'medium'
153
+ : 'low';
154
+ return { serverId: id, findings, riskLevel, scannedAt };
155
+ }
156
+ isAllowed(id, toolName) {
157
+ const server = this.servers.get(id);
158
+ if (!server)
159
+ return { allowed: false, reason: 'Server not registered' };
160
+ if (server.status === 'blocked')
161
+ return { allowed: false, reason: 'Server is blocked' };
162
+ if (this.config.blockUntrusted && server.securityLevel === 'untrusted') {
163
+ return { allowed: false, reason: 'Untrusted server blocked by governance policy' };
164
+ }
165
+ if (!server.capabilities.includes(toolName)) {
166
+ return { allowed: false, reason: `Tool "${toolName}" not in server capabilities` };
167
+ }
168
+ return { allowed: true };
169
+ }
170
+ getConfig() {
171
+ return { ...this.config };
172
+ }
173
+ updateConfig(patch) {
174
+ Object.assign(this.config, patch);
175
+ }
176
+ loadFromProject(projectDir) {
177
+ const dir = resolve(projectDir ?? process.cwd());
178
+ const configPath = join(dir, '.scale', 'mcp-servers.yaml');
179
+ if (!existsSync(configPath))
180
+ return;
181
+ try {
182
+ const content = readFileSync(configPath, 'utf-8');
183
+ const parsed = yaml.load(content);
184
+ if (parsed.governance) {
185
+ Object.assign(this.config, parsed.governance);
186
+ }
187
+ if (Array.isArray(parsed.servers)) {
188
+ for (const server of parsed.servers) {
189
+ this.register(server);
190
+ }
191
+ }
192
+ }
193
+ catch {
194
+ // ignore parse errors
195
+ }
196
+ }
197
+ }
198
+ //# sourceMappingURL=McpGovernance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpGovernance.js","sourceRoot":"","sources":["../../src/workflow/McpGovernance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ export type SessionTaskStatus = 'planned' | 'active' | 'blocked' | 'done' | 'cancelled';
2
+ export type DependencyType = 'blocks' | 'soft-dep' | 'data-flow';
3
+ export type OverlapRisk = 'low' | 'medium' | 'high';
4
+ export type EnforcementLevel = 'advisory' | 'warn' | 'block';
5
+ export type ConflictResolution = 'accept' | 'defer' | 'split-files' | 'manual';
6
+ export interface SessionTask {
7
+ sessionId: string;
8
+ taskId: string;
9
+ files: string[];
10
+ dependencies: string[];
11
+ status: SessionTaskStatus;
12
+ startedAt: string;
13
+ completedAt?: string;
14
+ metadata?: Record<string, unknown>;
15
+ }
16
+ export interface FileOverlap {
17
+ file: string;
18
+ sessions: Array<{
19
+ sessionId: string;
20
+ taskId: string;
21
+ }>;
22
+ risk: OverlapRisk;
23
+ suggestion: string;
24
+ }
25
+ export interface TaskDependencyEdge {
26
+ from: string;
27
+ to: string;
28
+ type: DependencyType;
29
+ reason: string;
30
+ }
31
+ export interface ConflictRecord {
32
+ id: string;
33
+ file: string;
34
+ sessions: string[];
35
+ resolution: ConflictResolution;
36
+ resolvedBy?: string;
37
+ resolvedAt: string;
38
+ notes?: string;
39
+ }
40
+ export interface SessionCoordinatorConfig {
41
+ enforcement: EnforcementLevel;
42
+ maxConcurrentSessions: number;
43
+ trackFileOverlaps: boolean;
44
+ autoBlockOnHighRisk: boolean;
45
+ }
46
+ export interface SessionCoordinatorInput {
47
+ projectDir?: string;
48
+ scaleDir?: string;
49
+ config?: Partial<SessionCoordinatorConfig>;
50
+ }
51
+ export interface CoordinationStatus {
52
+ activeSessions: number;
53
+ activeTasks: SessionTask[];
54
+ fileOverlaps: FileOverlap[];
55
+ blockedTasks: Array<{
56
+ taskId: string;
57
+ blockedBy: string[];
58
+ }>;
59
+ conflicts: ConflictRecord[];
60
+ recommendations: string[];
61
+ }
62
+ export interface TopologicalOrder {
63
+ order: string[];
64
+ cycles: string[][];
65
+ blocked: string[];
66
+ }
67
+ export declare class SessionCoordinator {
68
+ private tasks;
69
+ private dependencies;
70
+ private conflicts;
71
+ private config;
72
+ private statePath;
73
+ private stateDir;
74
+ constructor(input?: SessionCoordinatorInput);
75
+ registerSession(task: Omit<SessionTask, 'status' | 'startedAt'>): SessionTask;
76
+ activateTask(taskId: string): {
77
+ allowed: boolean;
78
+ blockers: string[];
79
+ };
80
+ completeTask(taskId: string): void;
81
+ cancelTask(taskId: string): void;
82
+ blockTask(taskId: string): void;
83
+ detectOverlaps(): FileOverlap[];
84
+ addDependency(edge: TaskDependencyEdge): void;
85
+ getTopologicalOrder(): TopologicalOrder;
86
+ getDependencies(taskId: string): {
87
+ upstream: string[];
88
+ downstream: string[];
89
+ };
90
+ recordConflict(conflict: Omit<ConflictRecord, 'id' | 'resolvedAt'>): ConflictRecord;
91
+ getCoordinationStatus(): CoordinationStatus;
92
+ private loadState;
93
+ private saveState;
94
+ private getActiveTasks;
95
+ getTask(taskId: string): SessionTask | undefined;
96
+ listTasks(): SessionTask[];
97
+ private getTaskBlockers;
98
+ private assessOverlapRisk;
99
+ private suggestOverlapResolution;
100
+ private findCycles;
101
+ private buildRecommendations;
102
+ }
103
+ export declare function summarizeCoordinationStatus(status: CoordinationStatus): string;