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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @file steering-auto-update.js
|
|
3
3
|
* @description Automatic steering file update engine
|
|
4
4
|
* @version 1.0.0
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
6
|
* Part of MUSUBI v5.0.0 - Phase 5 Advanced Features
|
|
7
7
|
*/
|
|
8
8
|
|
|
@@ -22,7 +22,7 @@ const TRIGGER = {
|
|
|
22
22
|
DEPENDENCY_UPDATE: 'dependency-update',
|
|
23
23
|
CONFIG_CHANGE: 'config-change',
|
|
24
24
|
MANUAL: 'manual',
|
|
25
|
-
SCHEDULED: 'scheduled'
|
|
25
|
+
SCHEDULED: 'scheduled',
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
/**
|
|
@@ -34,7 +34,7 @@ const STEERING_TYPE = {
|
|
|
34
34
|
TECH: 'tech',
|
|
35
35
|
PRODUCT: 'product',
|
|
36
36
|
RULES: 'rules',
|
|
37
|
-
CUSTOM: 'custom'
|
|
37
|
+
CUSTOM: 'custom',
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
/**
|
|
@@ -76,10 +76,10 @@ const DEFAULT_RULES = [
|
|
|
76
76
|
trigger: TRIGGER.DEPENDENCY_UPDATE,
|
|
77
77
|
target: STEERING_TYPE.TECH,
|
|
78
78
|
priority: 10,
|
|
79
|
-
condition:
|
|
79
|
+
condition: context => context.packageJsonChanged,
|
|
80
80
|
update: async (steering, context) => {
|
|
81
81
|
const changes = [];
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
if (context.newDependencies?.length > 0) {
|
|
84
84
|
changes.push(`Added dependencies: ${context.newDependencies.join(', ')}`);
|
|
85
85
|
}
|
|
@@ -89,9 +89,9 @@ const DEFAULT_RULES = [
|
|
|
89
89
|
if (context.updatedDependencies?.length > 0) {
|
|
90
90
|
changes.push(`Updated dependencies: ${context.updatedDependencies.join(', ')}`);
|
|
91
91
|
}
|
|
92
|
-
|
|
92
|
+
|
|
93
93
|
return { section: 'dependencies', changes };
|
|
94
|
-
}
|
|
94
|
+
},
|
|
95
95
|
},
|
|
96
96
|
{
|
|
97
97
|
id: 'structure-dirs-update',
|
|
@@ -99,11 +99,11 @@ const DEFAULT_RULES = [
|
|
|
99
99
|
trigger: TRIGGER.CODE_CHANGE,
|
|
100
100
|
target: STEERING_TYPE.STRUCTURE,
|
|
101
101
|
priority: 5,
|
|
102
|
-
condition:
|
|
102
|
+
condition: context => context.newDirectories?.length > 0,
|
|
103
103
|
update: async (steering, context) => {
|
|
104
104
|
const changes = context.newDirectories.map(dir => `Added directory: ${dir}`);
|
|
105
105
|
return { section: 'directories', changes };
|
|
106
|
-
}
|
|
106
|
+
},
|
|
107
107
|
},
|
|
108
108
|
{
|
|
109
109
|
id: 'structure-files-update',
|
|
@@ -111,7 +111,7 @@ const DEFAULT_RULES = [
|
|
|
111
111
|
trigger: TRIGGER.CODE_CHANGE,
|
|
112
112
|
target: STEERING_TYPE.STRUCTURE,
|
|
113
113
|
priority: 4,
|
|
114
|
-
condition:
|
|
114
|
+
condition: context => context.significantFileChanges,
|
|
115
115
|
update: async (steering, context) => {
|
|
116
116
|
const changes = [];
|
|
117
117
|
if (context.newEntryPoints?.length > 0) {
|
|
@@ -121,7 +121,7 @@ const DEFAULT_RULES = [
|
|
|
121
121
|
changes.push(`New modules: ${context.newModules.join(', ')}`);
|
|
122
122
|
}
|
|
123
123
|
return { section: 'files', changes };
|
|
124
|
-
}
|
|
124
|
+
},
|
|
125
125
|
},
|
|
126
126
|
{
|
|
127
127
|
id: 'product-features-update',
|
|
@@ -129,14 +129,14 @@ const DEFAULT_RULES = [
|
|
|
129
129
|
trigger: TRIGGER.AGENT_WORK,
|
|
130
130
|
target: STEERING_TYPE.PRODUCT,
|
|
131
131
|
priority: 8,
|
|
132
|
-
condition:
|
|
132
|
+
condition: context => context.featureCompleted,
|
|
133
133
|
update: async (steering, context) => {
|
|
134
134
|
const changes = [`Completed feature: ${context.featureName}`];
|
|
135
135
|
if (context.featureDescription) {
|
|
136
136
|
changes.push(`Description: ${context.featureDescription}`);
|
|
137
137
|
}
|
|
138
138
|
return { section: 'features', changes };
|
|
139
|
-
}
|
|
139
|
+
},
|
|
140
140
|
},
|
|
141
141
|
{
|
|
142
142
|
id: 'rules-patterns-update',
|
|
@@ -144,12 +144,12 @@ const DEFAULT_RULES = [
|
|
|
144
144
|
trigger: TRIGGER.AGENT_WORK,
|
|
145
145
|
target: STEERING_TYPE.RULES,
|
|
146
146
|
priority: 3,
|
|
147
|
-
condition:
|
|
147
|
+
condition: context => context.newPatterns?.length > 0,
|
|
148
148
|
update: async (steering, context) => {
|
|
149
149
|
const changes = context.newPatterns.map(p => `New pattern: ${p}`);
|
|
150
150
|
return { section: 'patterns', changes };
|
|
151
|
-
}
|
|
152
|
-
}
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
153
|
];
|
|
154
154
|
|
|
155
155
|
/**
|
|
@@ -163,22 +163,22 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
163
163
|
*/
|
|
164
164
|
constructor(options = {}) {
|
|
165
165
|
super();
|
|
166
|
-
|
|
166
|
+
|
|
167
167
|
this.steeringPath = options.steeringPath || 'steering';
|
|
168
168
|
this.autoSave = options.autoSave !== false;
|
|
169
169
|
this.backup = options.backup !== false;
|
|
170
170
|
this.rules = [...DEFAULT_RULES, ...(options.rules || [])];
|
|
171
|
-
|
|
171
|
+
|
|
172
172
|
// Sort rules by priority
|
|
173
173
|
this.rules.sort((a, b) => (b.priority || 0) - (a.priority || 0));
|
|
174
|
-
|
|
174
|
+
|
|
175
175
|
// State
|
|
176
176
|
this.updates = new Map();
|
|
177
177
|
this.updateCounter = 0;
|
|
178
178
|
this.steering = new Map();
|
|
179
179
|
this.pendingChanges = new Map();
|
|
180
180
|
}
|
|
181
|
-
|
|
181
|
+
|
|
182
182
|
/**
|
|
183
183
|
* Load steering files
|
|
184
184
|
* @param {string} [basePath='.'] - Base path
|
|
@@ -186,14 +186,14 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
186
186
|
*/
|
|
187
187
|
async loadSteering(basePath = '.') {
|
|
188
188
|
const steeringDir = path.join(basePath, this.steeringPath);
|
|
189
|
-
|
|
189
|
+
|
|
190
190
|
const files = {
|
|
191
191
|
[STEERING_TYPE.STRUCTURE]: 'structure.md',
|
|
192
192
|
[STEERING_TYPE.TECH]: 'tech.md',
|
|
193
193
|
[STEERING_TYPE.PRODUCT]: 'product.md',
|
|
194
|
-
[STEERING_TYPE.RULES]: 'rules/constitution.md'
|
|
194
|
+
[STEERING_TYPE.RULES]: 'rules/constitution.md',
|
|
195
195
|
};
|
|
196
|
-
|
|
196
|
+
|
|
197
197
|
for (const [type, file] of Object.entries(files)) {
|
|
198
198
|
const filePath = path.join(steeringDir, file);
|
|
199
199
|
try {
|
|
@@ -203,14 +203,14 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
203
203
|
path: filePath,
|
|
204
204
|
content,
|
|
205
205
|
parsed: this.parseMarkdown(content),
|
|
206
|
-
lastModified: fs.statSync(filePath).mtime
|
|
206
|
+
lastModified: fs.statSync(filePath).mtime,
|
|
207
207
|
});
|
|
208
208
|
}
|
|
209
209
|
} catch (error) {
|
|
210
210
|
this.emit('error', { type, file, error });
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
|
-
|
|
213
|
+
|
|
214
214
|
// Load custom steering files
|
|
215
215
|
const customDir = path.join(steeringDir, 'custom');
|
|
216
216
|
if (fs.existsSync(customDir)) {
|
|
@@ -222,15 +222,15 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
222
222
|
path: filePath,
|
|
223
223
|
content,
|
|
224
224
|
parsed: this.parseMarkdown(content),
|
|
225
|
-
lastModified: fs.statSync(filePath).mtime
|
|
225
|
+
lastModified: fs.statSync(filePath).mtime,
|
|
226
226
|
});
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
|
-
|
|
229
|
+
|
|
230
230
|
this.emit('steering:loaded', { count: this.steering.size });
|
|
231
231
|
return this.steering;
|
|
232
232
|
}
|
|
233
|
-
|
|
233
|
+
|
|
234
234
|
/**
|
|
235
235
|
* Parse markdown into sections
|
|
236
236
|
* @private
|
|
@@ -240,7 +240,7 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
240
240
|
const lines = content.split('\n');
|
|
241
241
|
let currentSection = 'header';
|
|
242
242
|
let currentContent = [];
|
|
243
|
-
|
|
243
|
+
|
|
244
244
|
for (const line of lines) {
|
|
245
245
|
const headerMatch = line.match(/^(#{1,6})\s+(.+)$/);
|
|
246
246
|
if (headerMatch) {
|
|
@@ -254,15 +254,15 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
254
254
|
currentContent.push(line);
|
|
255
255
|
}
|
|
256
256
|
}
|
|
257
|
-
|
|
257
|
+
|
|
258
258
|
// Save last section
|
|
259
259
|
if (currentContent.length > 0) {
|
|
260
260
|
sections.set(currentSection, currentContent.join('\n'));
|
|
261
261
|
}
|
|
262
|
-
|
|
262
|
+
|
|
263
263
|
return sections;
|
|
264
264
|
}
|
|
265
|
-
|
|
265
|
+
|
|
266
266
|
/**
|
|
267
267
|
* Process an update trigger
|
|
268
268
|
* @param {string} trigger - Trigger type
|
|
@@ -272,9 +272,9 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
272
272
|
async processTrigger(trigger, context = {}) {
|
|
273
273
|
const id = this.generateId();
|
|
274
274
|
this.emit('trigger:received', { id, trigger, context });
|
|
275
|
-
|
|
275
|
+
|
|
276
276
|
const results = [];
|
|
277
|
-
|
|
277
|
+
|
|
278
278
|
// Find applicable rules
|
|
279
279
|
const applicableRules = this.rules.filter(rule => {
|
|
280
280
|
if (rule.trigger !== trigger) return false;
|
|
@@ -285,20 +285,20 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
285
285
|
return false;
|
|
286
286
|
}
|
|
287
287
|
});
|
|
288
|
-
|
|
288
|
+
|
|
289
289
|
// Apply each rule
|
|
290
290
|
for (const rule of applicableRules) {
|
|
291
291
|
try {
|
|
292
292
|
this.emit('rule:applying', { rule: rule.id, target: rule.target });
|
|
293
|
-
|
|
293
|
+
|
|
294
294
|
const steering = this.steering.get(rule.target);
|
|
295
295
|
if (!steering) {
|
|
296
296
|
this.emit('rule:skipped', { rule: rule.id, reason: 'target not found' });
|
|
297
297
|
continue;
|
|
298
298
|
}
|
|
299
|
-
|
|
299
|
+
|
|
300
300
|
const updateResult = await rule.update(steering, context);
|
|
301
|
-
|
|
301
|
+
|
|
302
302
|
if (updateResult && updateResult.changes?.length > 0) {
|
|
303
303
|
// Queue changes
|
|
304
304
|
if (!this.pendingChanges.has(rule.target)) {
|
|
@@ -308,9 +308,9 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
308
308
|
rule: rule.id,
|
|
309
309
|
section: updateResult.section,
|
|
310
310
|
changes: updateResult.changes,
|
|
311
|
-
timestamp: Date.now()
|
|
311
|
+
timestamp: Date.now(),
|
|
312
312
|
});
|
|
313
|
-
|
|
313
|
+
|
|
314
314
|
const result = {
|
|
315
315
|
id: `update-${++this.updateCounter}`,
|
|
316
316
|
success: true,
|
|
@@ -318,12 +318,12 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
318
318
|
trigger,
|
|
319
319
|
rule: rule.id,
|
|
320
320
|
changes: updateResult.changes,
|
|
321
|
-
timestamp: Date.now()
|
|
321
|
+
timestamp: Date.now(),
|
|
322
322
|
};
|
|
323
|
-
|
|
323
|
+
|
|
324
324
|
results.push(result);
|
|
325
325
|
this.updates.set(result.id, result);
|
|
326
|
-
|
|
326
|
+
|
|
327
327
|
this.emit('rule:applied', { rule: rule.id, changes: updateResult.changes });
|
|
328
328
|
}
|
|
329
329
|
} catch (error) {
|
|
@@ -334,77 +334,74 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
334
334
|
trigger,
|
|
335
335
|
rule: rule.id,
|
|
336
336
|
error: error.message,
|
|
337
|
-
timestamp: Date.now()
|
|
337
|
+
timestamp: Date.now(),
|
|
338
338
|
};
|
|
339
|
-
|
|
339
|
+
|
|
340
340
|
results.push(result);
|
|
341
341
|
this.emit('rule:failed', { rule: rule.id, error });
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
|
-
|
|
344
|
+
|
|
345
345
|
// Auto-save if enabled
|
|
346
346
|
if (this.autoSave && results.some(r => r.success)) {
|
|
347
347
|
await this.applyPendingChanges();
|
|
348
348
|
}
|
|
349
|
-
|
|
349
|
+
|
|
350
350
|
this.emit('trigger:processed', { id, results });
|
|
351
351
|
return results;
|
|
352
352
|
}
|
|
353
|
-
|
|
353
|
+
|
|
354
354
|
/**
|
|
355
355
|
* Apply pending changes to files
|
|
356
356
|
* @returns {Promise<Object>} Apply result
|
|
357
357
|
*/
|
|
358
358
|
async applyPendingChanges() {
|
|
359
359
|
const applied = [];
|
|
360
|
-
|
|
360
|
+
|
|
361
361
|
for (const [target, changes] of this.pendingChanges.entries()) {
|
|
362
362
|
const steering = this.steering.get(target);
|
|
363
363
|
if (!steering) continue;
|
|
364
|
-
|
|
364
|
+
|
|
365
365
|
try {
|
|
366
366
|
// Create backup
|
|
367
367
|
if (this.backup) {
|
|
368
368
|
const backupPath = `${steering.path}.backup`;
|
|
369
369
|
fs.writeFileSync(backupPath, steering.content);
|
|
370
370
|
}
|
|
371
|
-
|
|
371
|
+
|
|
372
372
|
// Generate changelog section
|
|
373
373
|
const changelog = this.generateChangelog(changes);
|
|
374
|
-
|
|
374
|
+
|
|
375
375
|
// Update content
|
|
376
376
|
let newContent = steering.content;
|
|
377
|
-
|
|
377
|
+
|
|
378
378
|
// Add or update changelog section
|
|
379
379
|
if (newContent.includes('## Changelog')) {
|
|
380
|
-
newContent = newContent.replace(
|
|
381
|
-
/## Changelog\n/,
|
|
382
|
-
`## Changelog\n\n${changelog}\n`
|
|
383
|
-
);
|
|
380
|
+
newContent = newContent.replace(/## Changelog\n/, `## Changelog\n\n${changelog}\n`);
|
|
384
381
|
} else {
|
|
385
382
|
newContent += `\n\n## Changelog\n\n${changelog}`;
|
|
386
383
|
}
|
|
387
|
-
|
|
384
|
+
|
|
388
385
|
// Write file
|
|
389
386
|
fs.writeFileSync(steering.path, newContent);
|
|
390
|
-
|
|
387
|
+
|
|
391
388
|
// Update in-memory state
|
|
392
389
|
steering.content = newContent;
|
|
393
390
|
steering.parsed = this.parseMarkdown(newContent);
|
|
394
391
|
steering.lastModified = new Date();
|
|
395
|
-
|
|
392
|
+
|
|
396
393
|
applied.push({ target, changesCount: changes.length });
|
|
397
|
-
|
|
394
|
+
|
|
398
395
|
this.emit('changes:applied', { target, changes });
|
|
399
396
|
} catch (error) {
|
|
400
397
|
this.emit('changes:failed', { target, error });
|
|
401
398
|
}
|
|
402
399
|
}
|
|
403
|
-
|
|
400
|
+
|
|
404
401
|
this.pendingChanges.clear();
|
|
405
402
|
return { applied };
|
|
406
403
|
}
|
|
407
|
-
|
|
404
|
+
|
|
408
405
|
/**
|
|
409
406
|
* Generate changelog entry
|
|
410
407
|
* @private
|
|
@@ -412,16 +409,16 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
412
409
|
generateChangelog(changes) {
|
|
413
410
|
const date = new Date().toISOString().split('T')[0];
|
|
414
411
|
const entries = [];
|
|
415
|
-
|
|
412
|
+
|
|
416
413
|
for (const change of changes) {
|
|
417
414
|
for (const item of change.changes) {
|
|
418
415
|
entries.push(`- ${item}`);
|
|
419
416
|
}
|
|
420
417
|
}
|
|
421
|
-
|
|
418
|
+
|
|
422
419
|
return `### ${date}\n${entries.join('\n')}`;
|
|
423
420
|
}
|
|
424
|
-
|
|
421
|
+
|
|
425
422
|
/**
|
|
426
423
|
* Add custom rule
|
|
427
424
|
* @param {UpdateRule} rule - Rule to add
|
|
@@ -430,13 +427,13 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
430
427
|
if (!rule.id || !rule.trigger || !rule.target) {
|
|
431
428
|
throw new Error('Rule must have id, trigger, and target');
|
|
432
429
|
}
|
|
433
|
-
|
|
430
|
+
|
|
434
431
|
this.rules.push(rule);
|
|
435
432
|
this.rules.sort((a, b) => (b.priority || 0) - (a.priority || 0));
|
|
436
|
-
|
|
433
|
+
|
|
437
434
|
this.emit('rule:added', { ruleId: rule.id });
|
|
438
435
|
}
|
|
439
|
-
|
|
436
|
+
|
|
440
437
|
/**
|
|
441
438
|
* Remove rule
|
|
442
439
|
* @param {string} ruleId - Rule ID to remove
|
|
@@ -448,7 +445,7 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
448
445
|
this.emit('rule:removed', { ruleId });
|
|
449
446
|
}
|
|
450
447
|
}
|
|
451
|
-
|
|
448
|
+
|
|
452
449
|
/**
|
|
453
450
|
* Get update history
|
|
454
451
|
* @param {Object} [filter={}] - Filter options
|
|
@@ -456,7 +453,7 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
456
453
|
*/
|
|
457
454
|
getHistory(filter = {}) {
|
|
458
455
|
let results = Array.from(this.updates.values());
|
|
459
|
-
|
|
456
|
+
|
|
460
457
|
if (filter.trigger) {
|
|
461
458
|
results = results.filter(r => r.trigger === filter.trigger);
|
|
462
459
|
}
|
|
@@ -466,17 +463,17 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
466
463
|
if (filter.success !== undefined) {
|
|
467
464
|
results = results.filter(r => r.success === filter.success);
|
|
468
465
|
}
|
|
469
|
-
|
|
466
|
+
|
|
470
467
|
return results.sort((a, b) => b.timestamp - a.timestamp);
|
|
471
468
|
}
|
|
472
|
-
|
|
469
|
+
|
|
473
470
|
/**
|
|
474
471
|
* Get statistics
|
|
475
472
|
* @returns {Object}
|
|
476
473
|
*/
|
|
477
474
|
getStats() {
|
|
478
475
|
const updates = Array.from(this.updates.values());
|
|
479
|
-
|
|
476
|
+
|
|
480
477
|
return {
|
|
481
478
|
totalUpdates: updates.length,
|
|
482
479
|
successful: updates.filter(u => u.success).length,
|
|
@@ -487,10 +484,10 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
487
484
|
}, {}),
|
|
488
485
|
rulesCount: this.rules.length,
|
|
489
486
|
steeringFilesLoaded: this.steering.size,
|
|
490
|
-
pendingChanges: this.pendingChanges.size
|
|
487
|
+
pendingChanges: this.pendingChanges.size,
|
|
491
488
|
};
|
|
492
489
|
}
|
|
493
|
-
|
|
490
|
+
|
|
494
491
|
/**
|
|
495
492
|
* Generate unique ID
|
|
496
493
|
* @private
|
|
@@ -498,47 +495,47 @@ class SteeringAutoUpdate extends EventEmitter {
|
|
|
498
495
|
generateId() {
|
|
499
496
|
return `trigger-${Date.now().toString(36)}-${Math.random().toString(36).substr(2, 6)}`;
|
|
500
497
|
}
|
|
501
|
-
|
|
498
|
+
|
|
502
499
|
/**
|
|
503
500
|
* Clear history
|
|
504
501
|
*/
|
|
505
502
|
clearHistory() {
|
|
506
503
|
this.updates.clear();
|
|
507
504
|
}
|
|
508
|
-
|
|
505
|
+
|
|
509
506
|
/**
|
|
510
507
|
* Validate steering consistency
|
|
511
508
|
* @returns {Object} Validation result
|
|
512
509
|
*/
|
|
513
510
|
validateConsistency() {
|
|
514
511
|
const issues = [];
|
|
515
|
-
|
|
512
|
+
|
|
516
513
|
// Check cross-file references
|
|
517
514
|
const structure = this.steering.get(STEERING_TYPE.STRUCTURE);
|
|
518
515
|
const tech = this.steering.get(STEERING_TYPE.TECH);
|
|
519
|
-
|
|
516
|
+
|
|
520
517
|
if (structure && tech) {
|
|
521
518
|
// Check if tech references match structure
|
|
522
519
|
const structureDirs = this.extractDirectories(structure.content);
|
|
523
520
|
const techDirs = this.extractDirectories(tech.content);
|
|
524
|
-
|
|
521
|
+
|
|
525
522
|
for (const dir of techDirs) {
|
|
526
523
|
if (!structureDirs.includes(dir)) {
|
|
527
524
|
issues.push({
|
|
528
525
|
type: 'mismatch',
|
|
529
526
|
file: STEERING_TYPE.TECH,
|
|
530
|
-
message: `Directory "${dir}" referenced in tech.md but not in structure.md
|
|
527
|
+
message: `Directory "${dir}" referenced in tech.md but not in structure.md`,
|
|
531
528
|
});
|
|
532
529
|
}
|
|
533
530
|
}
|
|
534
531
|
}
|
|
535
|
-
|
|
532
|
+
|
|
536
533
|
return {
|
|
537
534
|
valid: issues.length === 0,
|
|
538
|
-
issues
|
|
535
|
+
issues,
|
|
539
536
|
};
|
|
540
537
|
}
|
|
541
|
-
|
|
538
|
+
|
|
542
539
|
/**
|
|
543
540
|
* Extract directories from content
|
|
544
541
|
* @private
|
|
@@ -568,5 +565,5 @@ module.exports = {
|
|
|
568
565
|
createSteeringAutoUpdate,
|
|
569
566
|
TRIGGER,
|
|
570
567
|
STEERING_TYPE,
|
|
571
|
-
DEFAULT_RULES
|
|
568
|
+
DEFAULT_RULES,
|
|
572
569
|
};
|