musubi-sdd 5.1.0 → 5.6.1
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.
- package/README.ja.md +106 -48
- package/README.md +110 -32
- package/bin/musubi-analyze.js +74 -67
- package/bin/musubi-browser.js +27 -26
- package/bin/musubi-change.js +48 -47
- package/bin/musubi-checkpoint.js +10 -7
- package/bin/musubi-convert.js +25 -25
- package/bin/musubi-costs.js +27 -10
- package/bin/musubi-gui.js +52 -46
- package/bin/musubi-init.js +1952 -10
- package/bin/musubi-orchestrate.js +327 -239
- package/bin/musubi-remember.js +69 -56
- package/bin/musubi-resolve.js +53 -45
- package/bin/musubi-trace.js +51 -22
- package/bin/musubi-validate.js +39 -30
- package/bin/musubi-workflow.js +33 -34
- package/bin/musubi.js +39 -2
- package/package.json +1 -1
- package/src/agents/agent-loop.js +94 -95
- package/src/agents/agentic/code-generator.js +119 -109
- package/src/agents/agentic/code-reviewer.js +105 -108
- package/src/agents/agentic/index.js +4 -4
- package/src/agents/browser/action-executor.js +13 -13
- package/src/agents/browser/ai-comparator.js +11 -10
- package/src/agents/browser/context-manager.js +6 -6
- package/src/agents/browser/index.js +5 -5
- package/src/agents/browser/nl-parser.js +31 -46
- package/src/agents/browser/screenshot.js +2 -2
- package/src/agents/browser/test-generator.js +6 -4
- package/src/agents/function-tool.js +71 -65
- package/src/agents/index.js +7 -7
- package/src/agents/schema-generator.js +98 -94
- package/src/analyzers/ast-extractor.js +158 -146
- package/src/analyzers/codegraph-auto-update.js +858 -0
- package/src/analyzers/complexity-analyzer.js +536 -0
- package/src/analyzers/context-optimizer.js +241 -126
- package/src/analyzers/impact-analyzer.js +1 -1
- package/src/analyzers/large-project-analyzer.js +766 -0
- package/src/analyzers/repository-map.js +77 -81
- package/src/analyzers/security-analyzer.js +19 -11
- package/src/analyzers/stuck-detector.js +19 -17
- package/src/converters/index.js +78 -57
- package/src/converters/ir/types.js +12 -12
- package/src/converters/parsers/musubi-parser.js +134 -126
- package/src/converters/parsers/openapi-parser.js +70 -53
- package/src/converters/parsers/speckit-parser.js +239 -175
- package/src/converters/writers/musubi-writer.js +123 -118
- package/src/converters/writers/speckit-writer.js +124 -113
- package/src/generators/rust-migration-generator.js +512 -0
- package/src/gui/public/index.html +1365 -1211
- package/src/gui/server.js +41 -40
- package/src/gui/services/file-watcher.js +23 -8
- package/src/gui/services/project-scanner.js +26 -20
- package/src/gui/services/replanning-service.js +27 -23
- package/src/gui/services/traceability-service.js +8 -8
- package/src/gui/services/workflow-service.js +14 -7
- package/src/index.js +151 -0
- package/src/integrations/cicd.js +90 -104
- package/src/integrations/codegraph-mcp.js +643 -0
- package/src/integrations/documentation.js +142 -103
- package/src/integrations/examples.js +95 -80
- package/src/integrations/github-client.js +17 -17
- package/src/integrations/index.js +5 -5
- package/src/integrations/mcp/index.js +21 -21
- package/src/integrations/mcp/mcp-context-provider.js +76 -78
- package/src/integrations/mcp/mcp-discovery.js +74 -72
- package/src/integrations/mcp/mcp-tool-registry.js +99 -94
- package/src/integrations/mcp-connector.js +70 -66
- package/src/integrations/platforms.js +50 -49
- package/src/integrations/tool-discovery.js +37 -31
- package/src/llm-providers/anthropic-provider.js +11 -11
- package/src/llm-providers/base-provider.js +16 -18
- package/src/llm-providers/copilot-provider.js +22 -19
- package/src/llm-providers/index.js +26 -25
- package/src/llm-providers/ollama-provider.js +11 -11
- package/src/llm-providers/openai-provider.js +12 -12
- package/src/managers/agent-memory.js +36 -24
- package/src/managers/checkpoint-manager.js +4 -8
- package/src/managers/delta-spec.js +19 -19
- package/src/managers/index.js +13 -4
- package/src/managers/memory-condenser.js +35 -45
- package/src/managers/repo-skill-manager.js +57 -31
- package/src/managers/skill-loader.js +25 -22
- package/src/managers/skill-tools.js +36 -72
- package/src/managers/workflow.js +30 -22
- package/src/monitoring/cost-tracker.js +48 -46
- package/src/monitoring/incident-manager.js +116 -106
- package/src/monitoring/index.js +144 -134
- package/src/monitoring/observability.js +75 -62
- package/src/monitoring/quality-dashboard.js +45 -41
- package/src/monitoring/release-manager.js +63 -53
- package/src/orchestration/agent-skill-binding.js +39 -47
- package/src/orchestration/error-handler.js +65 -107
- package/src/orchestration/guardrails/base-guardrail.js +26 -24
- package/src/orchestration/guardrails/guardrail-rules.js +50 -64
- package/src/orchestration/guardrails/index.js +5 -5
- package/src/orchestration/guardrails/input-guardrail.js +58 -45
- package/src/orchestration/guardrails/output-guardrail.js +104 -81
- package/src/orchestration/guardrails/safety-check.js +79 -79
- package/src/orchestration/index.js +38 -55
- package/src/orchestration/mcp-tool-adapters.js +96 -99
- package/src/orchestration/orchestration-engine.js +21 -21
- package/src/orchestration/pattern-registry.js +60 -45
- package/src/orchestration/patterns/auto.js +34 -47
- package/src/orchestration/patterns/group-chat.js +59 -65
- package/src/orchestration/patterns/handoff.js +67 -65
- package/src/orchestration/patterns/human-in-loop.js +51 -72
- package/src/orchestration/patterns/nested.js +25 -40
- package/src/orchestration/patterns/sequential.js +35 -34
- package/src/orchestration/patterns/swarm.js +63 -56
- package/src/orchestration/patterns/triage.js +150 -109
- package/src/orchestration/reasoning/index.js +9 -9
- package/src/orchestration/reasoning/planning-engine.js +143 -140
- package/src/orchestration/reasoning/reasoning-engine.js +206 -144
- package/src/orchestration/reasoning/self-correction.js +121 -128
- package/src/orchestration/replanning/adaptive-goal-modifier.js +107 -112
- package/src/orchestration/replanning/alternative-generator.js +37 -42
- package/src/orchestration/replanning/config.js +63 -59
- package/src/orchestration/replanning/goal-progress-tracker.js +98 -100
- package/src/orchestration/replanning/index.js +24 -20
- package/src/orchestration/replanning/plan-evaluator.js +49 -50
- package/src/orchestration/replanning/plan-monitor.js +32 -28
- package/src/orchestration/replanning/proactive-path-optimizer.js +175 -178
- package/src/orchestration/replanning/replan-history.js +33 -26
- package/src/orchestration/replanning/replanning-engine.js +106 -108
- package/src/orchestration/skill-executor.js +107 -109
- package/src/orchestration/skill-registry.js +85 -89
- package/src/orchestration/workflow-examples.js +228 -231
- package/src/orchestration/workflow-executor.js +65 -68
- package/src/orchestration/workflow-orchestrator.js +72 -73
- package/src/phase4-integration.js +47 -40
- package/src/phase5-integration.js +89 -30
- package/src/reporters/coverage-report.js +82 -30
- package/src/reporters/hierarchical-reporter.js +498 -0
- package/src/reporters/traceability-matrix-report.js +29 -20
- package/src/resolvers/issue-resolver.js +43 -31
- package/src/steering/advanced-validation.js +133 -124
- package/src/steering/auto-updater.js +60 -73
- package/src/steering/index.js +6 -6
- package/src/steering/quality-metrics.js +41 -35
- package/src/steering/steering-auto-update.js +83 -86
- package/src/steering/steering-validator.js +98 -106
- package/src/steering/template-constraints.js +53 -54
- package/src/templates/agents/claude-code/CLAUDE.md +32 -32
- package/src/templates/agents/claude-code/skills/agent-assistant/SKILL.md +13 -5
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/mlops-guide.md +23 -23
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/model-card-template.md +60 -41
- package/src/templates/agents/claude-code/skills/api-designer/api-patterns.md +27 -19
- package/src/templates/agents/claude-code/skills/api-designer/openapi-template.md +11 -7
- package/src/templates/agents/claude-code/skills/bug-hunter/SKILL.md +4 -3
- package/src/templates/agents/claude-code/skills/bug-hunter/root-cause-analysis.md +37 -15
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/dependency-graph-patterns.md +36 -42
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/impact-analysis-template.md +69 -60
- package/src/templates/agents/claude-code/skills/cloud-architect/aws-patterns.md +31 -38
- package/src/templates/agents/claude-code/skills/cloud-architect/azure-patterns.md +28 -23
- package/src/templates/agents/claude-code/skills/code-reviewer/SKILL.md +61 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/best-practices.md +27 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/review-checklist.md +29 -10
- package/src/templates/agents/claude-code/skills/code-reviewer/review-standards.md +29 -24
- package/src/templates/agents/claude-code/skills/constitution-enforcer/SKILL.md +8 -6
- package/src/templates/agents/claude-code/skills/constitution-enforcer/constitutional-articles.md +62 -26
- package/src/templates/agents/claude-code/skills/constitution-enforcer/phase-minus-one-gates.md +35 -16
- package/src/templates/agents/claude-code/skills/database-administrator/backup-recovery.md +27 -17
- package/src/templates/agents/claude-code/skills/database-administrator/tuning-guide.md +25 -20
- package/src/templates/agents/claude-code/skills/database-schema-designer/schema-patterns.md +39 -22
- package/src/templates/agents/claude-code/skills/devops-engineer/ci-cd-templates.md +25 -22
- package/src/templates/agents/claude-code/skills/issue-resolver/SKILL.md +24 -21
- package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +148 -63
- package/src/templates/agents/claude-code/skills/orchestrator/patterns.md +35 -16
- package/src/templates/agents/claude-code/skills/orchestrator/selection-matrix.md +69 -64
- package/src/templates/agents/claude-code/skills/performance-engineer/optimization-playbook.md +47 -47
- package/src/templates/agents/claude-code/skills/performance-optimizer/SKILL.md +69 -0
- package/src/templates/agents/claude-code/skills/performance-optimizer/benchmark-template.md +63 -45
- package/src/templates/agents/claude-code/skills/performance-optimizer/optimization-patterns.md +33 -35
- package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +7 -6
- package/src/templates/agents/claude-code/skills/project-manager/agile-ceremonies.md +47 -28
- package/src/templates/agents/claude-code/skills/project-manager/project-templates.md +94 -78
- package/src/templates/agents/claude-code/skills/quality-assurance/SKILL.md +20 -17
- package/src/templates/agents/claude-code/skills/quality-assurance/qa-plan-template.md +63 -49
- package/src/templates/agents/claude-code/skills/release-coordinator/SKILL.md +5 -5
- package/src/templates/agents/claude-code/skills/release-coordinator/feature-flag-guide.md +30 -26
- package/src/templates/agents/claude-code/skills/release-coordinator/release-plan-template.md +67 -35
- package/src/templates/agents/claude-code/skills/requirements-analyst/ears-format.md +54 -42
- package/src/templates/agents/claude-code/skills/requirements-analyst/validation-rules.md +36 -33
- package/src/templates/agents/claude-code/skills/security-auditor/SKILL.md +77 -19
- package/src/templates/agents/claude-code/skills/security-auditor/audit-checklists.md +24 -24
- package/src/templates/agents/claude-code/skills/security-auditor/owasp-top-10.md +61 -20
- package/src/templates/agents/claude-code/skills/security-auditor/vulnerability-patterns.md +43 -11
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/incident-response-template.md +55 -25
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/observability-patterns.md +78 -68
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/slo-sli-guide.md +73 -53
- package/src/templates/agents/claude-code/skills/software-developer/solid-principles.md +83 -37
- package/src/templates/agents/claude-code/skills/software-developer/test-first-workflow.md +38 -31
- package/src/templates/agents/claude-code/skills/steering/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/steering/auto-update-rules.md +31 -0
- package/src/templates/agents/claude-code/skills/system-architect/adr-template.md +25 -7
- package/src/templates/agents/claude-code/skills/system-architect/c4-model-guide.md +74 -61
- package/src/templates/agents/claude-code/skills/technical-writer/doc-templates/documentation-templates.md +70 -52
- package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +2 -0
- package/src/templates/agents/claude-code/skills/test-engineer/ears-test-mapping.md +75 -71
- package/src/templates/agents/claude-code/skills/test-engineer/test-types.md +85 -63
- package/src/templates/agents/claude-code/skills/traceability-auditor/coverage-matrix-template.md +39 -36
- package/src/templates/agents/claude-code/skills/traceability-auditor/gap-detection-rules.md +22 -17
- package/src/templates/agents/claude-code/skills/ui-ux-designer/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/ui-ux-designer/accessibility-guidelines.md +49 -75
- package/src/templates/agents/claude-code/skills/ui-ux-designer/design-system-components.md +71 -59
- package/src/templates/agents/codex/AGENTS.md +74 -42
- package/src/templates/agents/cursor/AGENTS.md +74 -42
- package/src/templates/agents/gemini-cli/GEMINI.md +74 -42
- package/src/templates/agents/github-copilot/AGENTS.md +83 -51
- package/src/templates/agents/qwen-code/QWEN.md +74 -42
- package/src/templates/agents/windsurf/AGENTS.md +74 -42
- package/src/templates/architectures/README.md +41 -0
- package/src/templates/architectures/clean-architecture/README.md +113 -0
- package/src/templates/architectures/event-driven/README.md +162 -0
- package/src/templates/architectures/hexagonal/README.md +130 -0
- package/src/templates/index.js +6 -1
- package/src/templates/locale-manager.js +16 -16
- package/src/templates/shared/delta-spec-template.md +20 -13
- package/src/templates/shared/github-actions/musubi-issue-resolver.yml +5 -5
- package/src/templates/shared/github-actions/musubi-security-check.yml +3 -3
- package/src/templates/shared/github-actions/musubi-validate.yml +4 -4
- package/src/templates/shared/steering/structure.md +95 -0
- package/src/templates/skills/browser-agent.md +21 -16
- package/src/templates/skills/web-gui.md +8 -0
- package/src/templates/template-constraints.js +50 -53
- package/src/validators/advanced-validation.js +30 -36
- package/src/validators/constitutional-validator.js +77 -73
- package/src/validators/critic-system.js +49 -59
- package/src/validators/delta-format.js +59 -55
- package/src/validators/traceability-validator.js +7 -11
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Steering Auto-Update Module
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Automatically updates steering files based on agent work:
|
|
5
5
|
* - Detects project changes
|
|
6
6
|
* - Updates structure.md, tech.md, product.md
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - Supports domain-specific custom rules
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
const
|
|
11
|
+
const _fs = require('fs');
|
|
12
12
|
const path = require('path');
|
|
13
13
|
const { EventEmitter } = require('events');
|
|
14
14
|
|
|
@@ -21,7 +21,7 @@ const SteeringFileType = {
|
|
|
21
21
|
PRODUCT: 'product',
|
|
22
22
|
PROJECT: 'project',
|
|
23
23
|
RULES: 'rules',
|
|
24
|
-
CUSTOM: 'custom'
|
|
24
|
+
CUSTOM: 'custom',
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
/**
|
|
@@ -34,7 +34,7 @@ const UpdateTrigger = {
|
|
|
34
34
|
DEPENDENCY_ADDED: 'dependency-added',
|
|
35
35
|
DEPENDENCY_REMOVED: 'dependency-removed',
|
|
36
36
|
CONFIG_CHANGED: 'config-changed',
|
|
37
|
-
MANUAL: 'manual'
|
|
37
|
+
MANUAL: 'manual',
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
/**
|
|
@@ -43,25 +43,16 @@ const UpdateTrigger = {
|
|
|
43
43
|
class ChangeDetector {
|
|
44
44
|
constructor(options = {}) {
|
|
45
45
|
this.patterns = options.patterns || {
|
|
46
|
-
structure: [
|
|
47
|
-
/^src\//,
|
|
48
|
-
/^lib\//,
|
|
49
|
-
/^packages\//,
|
|
50
|
-
/^components\//
|
|
51
|
-
],
|
|
46
|
+
structure: [/^src\//, /^lib\//, /^packages\//, /^components\//],
|
|
52
47
|
tech: [
|
|
53
48
|
/package\.json$/,
|
|
54
49
|
/requirements\.txt$/,
|
|
55
50
|
/Gemfile$/,
|
|
56
51
|
/go\.mod$/,
|
|
57
52
|
/Cargo\.toml$/,
|
|
58
|
-
/\.config\.(js|ts|json)
|
|
53
|
+
/\.config\.(js|ts|json)$/,
|
|
59
54
|
],
|
|
60
|
-
product: [
|
|
61
|
-
/README\.md$/,
|
|
62
|
-
/docs\//,
|
|
63
|
-
/\.env\.example$/
|
|
64
|
-
]
|
|
55
|
+
product: [/README\.md$/, /docs\//, /\.env\.example$/],
|
|
65
56
|
};
|
|
66
57
|
}
|
|
67
58
|
|
|
@@ -95,7 +86,7 @@ class ChangeDetector {
|
|
|
95
86
|
deletedFiles: [],
|
|
96
87
|
addedDependencies: [],
|
|
97
88
|
removedDependencies: [],
|
|
98
|
-
affectedSteering: []
|
|
89
|
+
affectedSteering: [],
|
|
99
90
|
};
|
|
100
91
|
|
|
101
92
|
for (const change of changes) {
|
|
@@ -108,11 +99,7 @@ class ChangeDetector {
|
|
|
108
99
|
}
|
|
109
100
|
}
|
|
110
101
|
|
|
111
|
-
const allFiles = [
|
|
112
|
-
...analysis.addedFiles,
|
|
113
|
-
...analysis.modifiedFiles,
|
|
114
|
-
...analysis.deletedFiles
|
|
115
|
-
];
|
|
102
|
+
const allFiles = [...analysis.addedFiles, ...analysis.modifiedFiles, ...analysis.deletedFiles];
|
|
116
103
|
|
|
117
104
|
analysis.affectedSteering = this.detectAffectedSteering(allFiles);
|
|
118
105
|
|
|
@@ -149,7 +136,7 @@ class SteeringUpdater {
|
|
|
149
136
|
updates.push({
|
|
150
137
|
section: 'directories',
|
|
151
138
|
action: 'add',
|
|
152
|
-
content: [...newDirs].map(d => `- \`${d}/\` - [TODO: Add description]`)
|
|
139
|
+
content: [...newDirs].map(d => `- \`${d}/\` - [TODO: Add description]`),
|
|
153
140
|
});
|
|
154
141
|
}
|
|
155
142
|
|
|
@@ -166,7 +153,7 @@ class SteeringUpdater {
|
|
|
166
153
|
updates.push({
|
|
167
154
|
section: 'directories',
|
|
168
155
|
action: 'review',
|
|
169
|
-
content: [...removedDirs].map(d => `- \`${d}/\` may need removal or update`)
|
|
156
|
+
content: [...removedDirs].map(d => `- \`${d}/\` may need removal or update`),
|
|
170
157
|
});
|
|
171
158
|
}
|
|
172
159
|
|
|
@@ -188,8 +175,8 @@ class SteeringUpdater {
|
|
|
188
175
|
action: 'sync',
|
|
189
176
|
content: {
|
|
190
177
|
runtime: Object.keys(deps),
|
|
191
|
-
development: Object.keys(devDeps)
|
|
192
|
-
}
|
|
178
|
+
development: Object.keys(devDeps),
|
|
179
|
+
},
|
|
193
180
|
});
|
|
194
181
|
|
|
195
182
|
// Detect framework
|
|
@@ -206,7 +193,7 @@ class SteeringUpdater {
|
|
|
206
193
|
updates.push({
|
|
207
194
|
section: 'frameworks',
|
|
208
195
|
action: 'update',
|
|
209
|
-
content: frameworks
|
|
196
|
+
content: frameworks,
|
|
210
197
|
});
|
|
211
198
|
}
|
|
212
199
|
}
|
|
@@ -227,7 +214,7 @@ class SteeringUpdater {
|
|
|
227
214
|
updates.push({
|
|
228
215
|
section: 'name',
|
|
229
216
|
action: 'sync',
|
|
230
|
-
content: titleMatch[1]
|
|
217
|
+
content: titleMatch[1],
|
|
231
218
|
});
|
|
232
219
|
}
|
|
233
220
|
|
|
@@ -237,7 +224,7 @@ class SteeringUpdater {
|
|
|
237
224
|
updates.push({
|
|
238
225
|
section: 'description',
|
|
239
226
|
action: 'sync',
|
|
240
|
-
content: descMatch[1].trim()
|
|
227
|
+
content: descMatch[1].trim(),
|
|
241
228
|
});
|
|
242
229
|
}
|
|
243
230
|
}
|
|
@@ -257,7 +244,7 @@ class SteeringUpdater {
|
|
|
257
244
|
section: update.section,
|
|
258
245
|
action: update.action,
|
|
259
246
|
applied: !this.dryRun,
|
|
260
|
-
content: update.content
|
|
247
|
+
content: update.content,
|
|
261
248
|
});
|
|
262
249
|
}
|
|
263
250
|
|
|
@@ -283,29 +270,29 @@ class ProjectYmlSync {
|
|
|
283
270
|
description: '',
|
|
284
271
|
tech_stack: [],
|
|
285
272
|
features: [],
|
|
286
|
-
agents: []
|
|
273
|
+
agents: [],
|
|
287
274
|
};
|
|
288
275
|
|
|
289
276
|
// Simple YAML-like parsing
|
|
290
277
|
const lines = content.split('\n');
|
|
291
278
|
let currentKey = null;
|
|
292
|
-
let
|
|
279
|
+
let _inList = false;
|
|
293
280
|
|
|
294
281
|
for (const line of lines) {
|
|
295
282
|
const trimmed = line.trim();
|
|
296
|
-
|
|
283
|
+
|
|
297
284
|
if (trimmed.startsWith('#') || trimmed === '') continue;
|
|
298
285
|
|
|
299
286
|
const keyMatch = line.match(/^(\w+):\s*(.*)$/);
|
|
300
287
|
if (keyMatch) {
|
|
301
288
|
currentKey = keyMatch[1];
|
|
302
289
|
const value = keyMatch[2].trim();
|
|
303
|
-
|
|
290
|
+
|
|
304
291
|
if (value && !value.startsWith('-')) {
|
|
305
292
|
data[currentKey] = value;
|
|
306
|
-
|
|
293
|
+
_inList = false;
|
|
307
294
|
} else {
|
|
308
|
-
|
|
295
|
+
_inList = true;
|
|
309
296
|
if (!Array.isArray(data[currentKey])) {
|
|
310
297
|
data[currentKey] = [];
|
|
311
298
|
}
|
|
@@ -374,20 +361,20 @@ class ProjectYmlSync {
|
|
|
374
361
|
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
375
362
|
|
|
376
363
|
const techMapping = {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
364
|
+
react: 'React',
|
|
365
|
+
vue: 'Vue.js',
|
|
366
|
+
angular: 'Angular',
|
|
367
|
+
next: 'Next.js',
|
|
368
|
+
express: 'Express',
|
|
369
|
+
fastify: 'Fastify',
|
|
370
|
+
typescript: 'TypeScript',
|
|
371
|
+
jest: 'Jest',
|
|
372
|
+
mocha: 'Mocha',
|
|
373
|
+
webpack: 'Webpack',
|
|
374
|
+
vite: 'Vite',
|
|
375
|
+
tailwindcss: 'Tailwind CSS',
|
|
376
|
+
prisma: 'Prisma',
|
|
377
|
+
mongoose: 'Mongoose',
|
|
391
378
|
};
|
|
392
379
|
|
|
393
380
|
for (const [dep, tech] of Object.entries(techMapping)) {
|
|
@@ -418,17 +405,17 @@ class CustomSteeringRules {
|
|
|
418
405
|
// Parse custom rules from markdown format
|
|
419
406
|
const rules = [];
|
|
420
407
|
const rulePattern = /## Rule: (.+)\n([\s\S]*?)(?=## Rule:|$)/g;
|
|
421
|
-
|
|
408
|
+
|
|
422
409
|
let match;
|
|
423
410
|
while ((match = rulePattern.exec(content)) !== null) {
|
|
424
411
|
const name = match[1].trim();
|
|
425
412
|
const body = match[2].trim();
|
|
426
|
-
|
|
413
|
+
|
|
427
414
|
const rule = {
|
|
428
415
|
name,
|
|
429
416
|
pattern: null,
|
|
430
417
|
action: 'warn',
|
|
431
|
-
message: ''
|
|
418
|
+
message: '',
|
|
432
419
|
};
|
|
433
420
|
|
|
434
421
|
// Parse pattern
|
|
@@ -476,7 +463,7 @@ class CustomSteeringRules {
|
|
|
476
463
|
rule: name,
|
|
477
464
|
file: change.path,
|
|
478
465
|
action: rule.action,
|
|
479
|
-
message: rule.message
|
|
466
|
+
message: rule.message,
|
|
480
467
|
});
|
|
481
468
|
}
|
|
482
469
|
}
|
|
@@ -495,18 +482,18 @@ class SteeringAutoUpdater extends EventEmitter {
|
|
|
495
482
|
this.projectRoot = options.projectRoot || process.cwd();
|
|
496
483
|
this.steeringDir = options.steeringDir || 'steering';
|
|
497
484
|
this.dryRun = options.dryRun || false;
|
|
498
|
-
|
|
485
|
+
|
|
499
486
|
this.detector = new ChangeDetector(options.detectorOptions);
|
|
500
487
|
this.updater = new SteeringUpdater({
|
|
501
488
|
steeringDir: this.steeringDir,
|
|
502
489
|
dryRun: this.dryRun,
|
|
503
|
-
backup: options.backup
|
|
490
|
+
backup: options.backup,
|
|
504
491
|
});
|
|
505
492
|
this.projectSync = new ProjectYmlSync({
|
|
506
|
-
path: path.join(this.steeringDir, 'project.yml')
|
|
493
|
+
path: path.join(this.steeringDir, 'project.yml'),
|
|
507
494
|
});
|
|
508
495
|
this.customRules = new CustomSteeringRules({
|
|
509
|
-
rulesDir: path.join(this.steeringDir, 'custom')
|
|
496
|
+
rulesDir: path.join(this.steeringDir, 'custom'),
|
|
510
497
|
});
|
|
511
498
|
|
|
512
499
|
this.updateHistory = [];
|
|
@@ -517,13 +504,13 @@ class SteeringAutoUpdater extends EventEmitter {
|
|
|
517
504
|
*/
|
|
518
505
|
analyze(changes, context = {}) {
|
|
519
506
|
const analysis = this.detector.analyzeChanges(changes);
|
|
520
|
-
|
|
507
|
+
|
|
521
508
|
const suggestions = {
|
|
522
509
|
structure: [],
|
|
523
510
|
tech: [],
|
|
524
511
|
product: [],
|
|
525
512
|
project: [],
|
|
526
|
-
custom: []
|
|
513
|
+
custom: [],
|
|
527
514
|
};
|
|
528
515
|
|
|
529
516
|
// Generate structure updates
|
|
@@ -547,9 +534,9 @@ class SteeringAutoUpdater extends EventEmitter {
|
|
|
547
534
|
return {
|
|
548
535
|
analysis,
|
|
549
536
|
suggestions,
|
|
550
|
-
affectedFiles: analysis.affectedSteering.map(type =>
|
|
537
|
+
affectedFiles: analysis.affectedSteering.map(type =>
|
|
551
538
|
path.join(this.steeringDir, `${type}.md`)
|
|
552
|
-
)
|
|
539
|
+
),
|
|
553
540
|
};
|
|
554
541
|
}
|
|
555
542
|
|
|
@@ -560,7 +547,7 @@ class SteeringAutoUpdater extends EventEmitter {
|
|
|
560
547
|
const results = {
|
|
561
548
|
applied: [],
|
|
562
549
|
skipped: [],
|
|
563
|
-
errors: []
|
|
550
|
+
errors: [],
|
|
564
551
|
};
|
|
565
552
|
|
|
566
553
|
for (const [type, updates] of Object.entries(suggestions)) {
|
|
@@ -575,7 +562,7 @@ class SteeringAutoUpdater extends EventEmitter {
|
|
|
575
562
|
} catch (error) {
|
|
576
563
|
results.errors.push({
|
|
577
564
|
type,
|
|
578
|
-
error: error.message
|
|
565
|
+
error: error.message,
|
|
579
566
|
});
|
|
580
567
|
}
|
|
581
568
|
}
|
|
@@ -583,7 +570,7 @@ class SteeringAutoUpdater extends EventEmitter {
|
|
|
583
570
|
// Record in history
|
|
584
571
|
this.updateHistory.push({
|
|
585
572
|
timestamp: new Date(),
|
|
586
|
-
results
|
|
573
|
+
results,
|
|
587
574
|
});
|
|
588
575
|
|
|
589
576
|
return results;
|
|
@@ -594,10 +581,10 @@ class SteeringAutoUpdater extends EventEmitter {
|
|
|
594
581
|
*/
|
|
595
582
|
syncProjectYml(projectData, packageJson) {
|
|
596
583
|
const updated = this.projectSync.syncWithPackageJson(projectData, packageJson);
|
|
597
|
-
|
|
584
|
+
|
|
598
585
|
this.emit('projectSynced', {
|
|
599
586
|
before: projectData,
|
|
600
|
-
after: updated
|
|
587
|
+
after: updated,
|
|
601
588
|
});
|
|
602
589
|
|
|
603
590
|
return updated;
|
|
@@ -632,16 +619,16 @@ class SteeringAutoUpdater extends EventEmitter {
|
|
|
632
619
|
type: 'missing',
|
|
633
620
|
file,
|
|
634
621
|
severity: 'error',
|
|
635
|
-
message: `Required steering file ${file} is missing
|
|
622
|
+
message: `Required steering file ${file} is missing`,
|
|
636
623
|
});
|
|
637
624
|
}
|
|
638
625
|
}
|
|
639
626
|
|
|
640
627
|
// Check for empty sections (would require file content)
|
|
641
|
-
|
|
628
|
+
|
|
642
629
|
return {
|
|
643
630
|
valid: issues.filter(i => i.severity === 'error').length === 0,
|
|
644
|
-
issues
|
|
631
|
+
issues,
|
|
645
632
|
};
|
|
646
633
|
}
|
|
647
634
|
}
|
|
@@ -660,11 +647,11 @@ module.exports = {
|
|
|
660
647
|
ProjectYmlSync,
|
|
661
648
|
CustomSteeringRules,
|
|
662
649
|
SteeringAutoUpdater,
|
|
663
|
-
|
|
650
|
+
|
|
664
651
|
// Constants
|
|
665
652
|
SteeringFileType,
|
|
666
653
|
UpdateTrigger,
|
|
667
|
-
|
|
654
|
+
|
|
668
655
|
// Factory
|
|
669
|
-
createSteeringAutoUpdater
|
|
656
|
+
createSteeringAutoUpdater,
|
|
670
657
|
};
|
package/src/steering/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Steering Module - Main Entry Point
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Provides comprehensive steering file management:
|
|
5
5
|
* - Auto-Update: Automatic steering file updates
|
|
6
6
|
* - Template Constraints: LLM-constraining syntax
|
|
@@ -17,7 +17,7 @@ const {
|
|
|
17
17
|
SteeringAutoUpdater,
|
|
18
18
|
SteeringFileType,
|
|
19
19
|
UpdateTrigger,
|
|
20
|
-
createSteeringAutoUpdater
|
|
20
|
+
createSteeringAutoUpdater,
|
|
21
21
|
} = require('./auto-updater');
|
|
22
22
|
|
|
23
23
|
// Template Constraints Module
|
|
@@ -32,7 +32,7 @@ const {
|
|
|
32
32
|
ConstraintType,
|
|
33
33
|
UncertaintyMarker,
|
|
34
34
|
Severity: ConstraintSeverity,
|
|
35
|
-
createTemplateConstraintEngine
|
|
35
|
+
createTemplateConstraintEngine,
|
|
36
36
|
} = require('./template-constraints');
|
|
37
37
|
|
|
38
38
|
// Quality Metrics Module
|
|
@@ -47,7 +47,7 @@ const {
|
|
|
47
47
|
MetricCategory,
|
|
48
48
|
HealthStatus,
|
|
49
49
|
TrendDirection,
|
|
50
|
-
createQualityDashboard
|
|
50
|
+
createQualityDashboard,
|
|
51
51
|
} = require('./quality-metrics');
|
|
52
52
|
|
|
53
53
|
// Advanced Validation Module
|
|
@@ -63,7 +63,7 @@ const {
|
|
|
63
63
|
ValidationType,
|
|
64
64
|
Severity: ValidationSeverity,
|
|
65
65
|
ArtifactType,
|
|
66
|
-
createAdvancedValidator
|
|
66
|
+
createAdvancedValidator,
|
|
67
67
|
} = require('./advanced-validation');
|
|
68
68
|
|
|
69
69
|
module.exports = {
|
|
@@ -115,5 +115,5 @@ module.exports = {
|
|
|
115
115
|
ValidationType,
|
|
116
116
|
ValidationSeverity,
|
|
117
117
|
ArtifactType,
|
|
118
|
-
createAdvancedValidator
|
|
118
|
+
createAdvancedValidator,
|
|
119
119
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Quality Metrics Dashboard Module
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Provides:
|
|
5
5
|
* - Coverage metrics (code, test, documentation)
|
|
6
6
|
* - Compliance scoring (steering, constitutional)
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
const EventEmitter = require('events');
|
|
12
|
-
const
|
|
12
|
+
const _path = require('path');
|
|
13
13
|
|
|
14
14
|
// Metric Categories
|
|
15
15
|
const MetricCategory = {
|
|
@@ -17,7 +17,7 @@ const MetricCategory = {
|
|
|
17
17
|
COMPLIANCE: 'compliance',
|
|
18
18
|
QUALITY: 'quality',
|
|
19
19
|
HEALTH: 'health',
|
|
20
|
-
TREND: 'trend'
|
|
20
|
+
TREND: 'trend',
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
// Health Status
|
|
@@ -25,7 +25,7 @@ const HealthStatus = {
|
|
|
25
25
|
HEALTHY: 'healthy',
|
|
26
26
|
WARNING: 'warning',
|
|
27
27
|
CRITICAL: 'critical',
|
|
28
|
-
UNKNOWN: 'unknown'
|
|
28
|
+
UNKNOWN: 'unknown',
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
// Trend Direction
|
|
@@ -33,7 +33,7 @@ const TrendDirection = {
|
|
|
33
33
|
UP: 'up',
|
|
34
34
|
DOWN: 'down',
|
|
35
35
|
STABLE: 'stable',
|
|
36
|
-
UNKNOWN: 'unknown'
|
|
36
|
+
UNKNOWN: 'unknown',
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
/**
|
|
@@ -77,7 +77,7 @@ class Metric {
|
|
|
77
77
|
target: this.target,
|
|
78
78
|
progress: this.getProgress(),
|
|
79
79
|
onTarget: this.isOnTarget(),
|
|
80
|
-
timestamp: this.timestamp.toISOString()
|
|
80
|
+
timestamp: this.timestamp.toISOString(),
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
83
|
}
|
|
@@ -104,7 +104,7 @@ class CoverageMetric extends Metric {
|
|
|
104
104
|
return {
|
|
105
105
|
...super.toJSON(),
|
|
106
106
|
covered: this.coveredItems,
|
|
107
|
-
total: this.totalItems
|
|
107
|
+
total: this.totalItems,
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
110
|
}
|
|
@@ -127,7 +127,7 @@ class ComplianceMetric extends Metric {
|
|
|
127
127
|
addViolation(violation) {
|
|
128
128
|
this.violations.push({
|
|
129
129
|
...violation,
|
|
130
|
-
timestamp: new Date()
|
|
130
|
+
timestamp: new Date(),
|
|
131
131
|
});
|
|
132
132
|
this.recalculate();
|
|
133
133
|
return this;
|
|
@@ -144,7 +144,7 @@ class ComplianceMetric extends Metric {
|
|
|
144
144
|
this.value = 100;
|
|
145
145
|
return;
|
|
146
146
|
}
|
|
147
|
-
|
|
147
|
+
|
|
148
148
|
const violatedRules = new Set(this.violations.map(v => v.rule));
|
|
149
149
|
const compliantCount = this.rules.length - violatedRules.size;
|
|
150
150
|
this.value = (compliantCount / this.rules.length) * 100;
|
|
@@ -156,7 +156,7 @@ class ComplianceMetric extends Metric {
|
|
|
156
156
|
...super.toJSON(),
|
|
157
157
|
rules: this.rules.length,
|
|
158
158
|
violations: this.violations.length,
|
|
159
|
-
violatedRules: [...new Set(this.violations.map(v => v.rule))]
|
|
159
|
+
violatedRules: [...new Set(this.violations.map(v => v.rule))],
|
|
160
160
|
};
|
|
161
161
|
}
|
|
162
162
|
}
|
|
@@ -204,7 +204,7 @@ class HealthIndicator {
|
|
|
204
204
|
status: this.status,
|
|
205
205
|
message: this.message,
|
|
206
206
|
lastCheck: this.lastCheck?.toISOString(),
|
|
207
|
-
healthy: this.isHealthy()
|
|
207
|
+
healthy: this.isHealthy(),
|
|
208
208
|
};
|
|
209
209
|
}
|
|
210
210
|
}
|
|
@@ -221,7 +221,7 @@ class TrendAnalyzer {
|
|
|
221
221
|
|
|
222
222
|
addDataPoint(value, timestamp = new Date()) {
|
|
223
223
|
this.dataPoints.push({ value, timestamp });
|
|
224
|
-
|
|
224
|
+
|
|
225
225
|
// Keep only maxPoints
|
|
226
226
|
if (this.dataPoints.length > this.maxPoints) {
|
|
227
227
|
this.dataPoints = this.dataPoints.slice(-this.maxPoints);
|
|
@@ -256,7 +256,7 @@ class TrendAnalyzer {
|
|
|
256
256
|
percentChange,
|
|
257
257
|
first,
|
|
258
258
|
last,
|
|
259
|
-
dataPoints: recent.length
|
|
259
|
+
dataPoints: recent.length,
|
|
260
260
|
};
|
|
261
261
|
}
|
|
262
262
|
|
|
@@ -282,7 +282,7 @@ class TrendAnalyzer {
|
|
|
282
282
|
average: this.getAverage(),
|
|
283
283
|
min: this.getMin(),
|
|
284
284
|
max: this.getMax(),
|
|
285
|
-
dataPoints: this.dataPoints.length
|
|
285
|
+
dataPoints: this.dataPoints.length,
|
|
286
286
|
};
|
|
287
287
|
}
|
|
288
288
|
}
|
|
@@ -296,7 +296,7 @@ class QualityScoreCalculator {
|
|
|
296
296
|
coverage: 0.3,
|
|
297
297
|
compliance: 0.3,
|
|
298
298
|
health: 0.2,
|
|
299
|
-
trends: 0.2
|
|
299
|
+
trends: 0.2,
|
|
300
300
|
};
|
|
301
301
|
}
|
|
302
302
|
|
|
@@ -305,18 +305,18 @@ class QualityScoreCalculator {
|
|
|
305
305
|
coverage: this.calculateCoverageScore(metrics.coverage || []),
|
|
306
306
|
compliance: this.calculateComplianceScore(metrics.compliance || []),
|
|
307
307
|
health: this.calculateHealthScore(metrics.health || []),
|
|
308
|
-
trends: this.calculateTrendScore(metrics.trends || [])
|
|
308
|
+
trends: this.calculateTrendScore(metrics.trends || []),
|
|
309
309
|
};
|
|
310
310
|
|
|
311
311
|
const overall = Object.entries(this.weights).reduce((acc, [key, weight]) => {
|
|
312
|
-
return acc +
|
|
312
|
+
return acc + scores[key] * weight;
|
|
313
313
|
}, 0);
|
|
314
314
|
|
|
315
315
|
return {
|
|
316
316
|
overall: Math.round(overall * 100) / 100,
|
|
317
317
|
breakdown: scores,
|
|
318
318
|
grade: this.getGrade(overall),
|
|
319
|
-
weights: this.weights
|
|
319
|
+
weights: this.weights,
|
|
320
320
|
};
|
|
321
321
|
}
|
|
322
322
|
|
|
@@ -334,15 +334,17 @@ class QualityScoreCalculator {
|
|
|
334
334
|
|
|
335
335
|
calculateHealthScore(healthIndicators) {
|
|
336
336
|
if (healthIndicators.length === 0) return 100;
|
|
337
|
-
|
|
337
|
+
|
|
338
338
|
const statusScores = {
|
|
339
339
|
[HealthStatus.HEALTHY]: 100,
|
|
340
340
|
[HealthStatus.WARNING]: 60,
|
|
341
341
|
[HealthStatus.CRITICAL]: 0,
|
|
342
|
-
[HealthStatus.UNKNOWN]: 50
|
|
342
|
+
[HealthStatus.UNKNOWN]: 50,
|
|
343
343
|
};
|
|
344
344
|
|
|
345
|
-
const avg =
|
|
345
|
+
const avg =
|
|
346
|
+
healthIndicators.reduce((acc, h) => acc + statusScores[h.status], 0) /
|
|
347
|
+
healthIndicators.length;
|
|
346
348
|
return avg;
|
|
347
349
|
}
|
|
348
350
|
|
|
@@ -353,7 +355,7 @@ class QualityScoreCalculator {
|
|
|
353
355
|
[TrendDirection.UP]: 100,
|
|
354
356
|
[TrendDirection.STABLE]: 70,
|
|
355
357
|
[TrendDirection.DOWN]: 30,
|
|
356
|
-
[TrendDirection.UNKNOWN]: 50
|
|
358
|
+
[TrendDirection.UNKNOWN]: 50,
|
|
357
359
|
};
|
|
358
360
|
|
|
359
361
|
const avg = trends.reduce((acc, t) => acc + directionScores[t.direction], 0) / trends.length;
|
|
@@ -469,7 +471,7 @@ class QualityMetricsDashboard extends EventEmitter {
|
|
|
469
471
|
coverage: this.getMetricsByCategory(MetricCategory.COVERAGE),
|
|
470
472
|
compliance: this.getMetricsByCategory(MetricCategory.COMPLIANCE),
|
|
471
473
|
health: [...this.healthIndicators.values()],
|
|
472
|
-
trends: Object.values(this.getTrends())
|
|
474
|
+
trends: Object.values(this.getTrends()),
|
|
473
475
|
};
|
|
474
476
|
|
|
475
477
|
const score = this.scoreCalculator.calculate(data);
|
|
@@ -483,7 +485,7 @@ class QualityMetricsDashboard extends EventEmitter {
|
|
|
483
485
|
type,
|
|
484
486
|
name,
|
|
485
487
|
value,
|
|
486
|
-
timestamp: new Date()
|
|
488
|
+
timestamp: new Date(),
|
|
487
489
|
});
|
|
488
490
|
|
|
489
491
|
if (this.history.length > this.maxHistory) {
|
|
@@ -532,8 +534,8 @@ class QualityMetricsDashboard extends EventEmitter {
|
|
|
532
534
|
totalMetrics: metrics.length,
|
|
533
535
|
healthyIndicators: health.filter(h => h.healthy).length,
|
|
534
536
|
totalIndicators: health.length,
|
|
535
|
-
metricsOnTarget: metrics.filter(m => m.onTarget).length
|
|
536
|
-
}
|
|
537
|
+
metricsOnTarget: metrics.filter(m => m.onTarget).length,
|
|
538
|
+
},
|
|
537
539
|
};
|
|
538
540
|
}
|
|
539
541
|
|
|
@@ -558,12 +560,14 @@ class QualityMetricsDashboard extends EventEmitter {
|
|
|
558
560
|
`| Trends | ${summary.score.breakdown.trends.toFixed(1)}% |`,
|
|
559
561
|
'',
|
|
560
562
|
'## Metrics',
|
|
561
|
-
''
|
|
563
|
+
'',
|
|
562
564
|
];
|
|
563
565
|
|
|
564
566
|
for (const metric of summary.metrics) {
|
|
565
|
-
const status = metric.onTarget ? '✅' :
|
|
566
|
-
lines.push(
|
|
567
|
+
const status = metric.onTarget ? '✅' : metric.onTarget === false ? '⚠️' : '➖';
|
|
568
|
+
lines.push(
|
|
569
|
+
`- ${status} **${metric.name}**: ${metric.value.toFixed(1)}${metric.unit === 'percent' ? '%' : ` ${metric.unit}`}`
|
|
570
|
+
);
|
|
567
571
|
if (metric.target) {
|
|
568
572
|
lines.push(` - Target: ${metric.target}%`);
|
|
569
573
|
}
|
|
@@ -572,7 +576,7 @@ class QualityMetricsDashboard extends EventEmitter {
|
|
|
572
576
|
lines.push('', '## Health Indicators', '');
|
|
573
577
|
|
|
574
578
|
for (const indicator of summary.health) {
|
|
575
|
-
const icon = indicator.healthy ? '🟢' :
|
|
579
|
+
const icon = indicator.healthy ? '🟢' : indicator.status === 'warning' ? '🟡' : '🔴';
|
|
576
580
|
lines.push(`- ${icon} **${indicator.name}**: ${indicator.status}`);
|
|
577
581
|
if (indicator.message) {
|
|
578
582
|
lines.push(` - ${indicator.message}`);
|
|
@@ -582,8 +586,10 @@ class QualityMetricsDashboard extends EventEmitter {
|
|
|
582
586
|
lines.push('', '## Trends', '');
|
|
583
587
|
|
|
584
588
|
for (const [name, trend] of Object.entries(summary.trends)) {
|
|
585
|
-
const icon = trend.direction === 'up' ? '📈' :
|
|
586
|
-
lines.push(
|
|
589
|
+
const icon = trend.direction === 'up' ? '📈' : trend.direction === 'down' ? '📉' : '➡️';
|
|
590
|
+
lines.push(
|
|
591
|
+
`- ${icon} **${name}**: ${trend.direction} (${trend.percentChange?.toFixed(1) || 0}%)`
|
|
592
|
+
);
|
|
587
593
|
}
|
|
588
594
|
|
|
589
595
|
return lines.join('\n');
|
|
@@ -635,7 +641,7 @@ module.exports = {
|
|
|
635
641
|
MetricCategory,
|
|
636
642
|
HealthStatus,
|
|
637
643
|
TrendDirection,
|
|
638
|
-
|
|
644
|
+
|
|
639
645
|
// Classes
|
|
640
646
|
Metric,
|
|
641
647
|
CoverageMetric,
|
|
@@ -644,7 +650,7 @@ module.exports = {
|
|
|
644
650
|
TrendAnalyzer,
|
|
645
651
|
QualityScoreCalculator,
|
|
646
652
|
QualityMetricsDashboard,
|
|
647
|
-
|
|
653
|
+
|
|
648
654
|
// Factory
|
|
649
|
-
createQualityDashboard
|
|
655
|
+
createQualityDashboard,
|
|
650
656
|
};
|