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
|
@@ -196,9 +196,7 @@ class CheckpointManager extends EventEmitter {
|
|
|
196
196
|
|
|
197
197
|
// Filter by tags
|
|
198
198
|
if (options.tags && options.tags.length > 0) {
|
|
199
|
-
checkpoints = checkpoints.filter(cp =>
|
|
200
|
-
options.tags.some(tag => cp.tags.includes(tag))
|
|
201
|
-
);
|
|
199
|
+
checkpoints = checkpoints.filter(cp => options.tags.some(tag => cp.tags.includes(tag)));
|
|
202
200
|
}
|
|
203
201
|
|
|
204
202
|
// Filter by state
|
|
@@ -489,7 +487,7 @@ class CheckpointManager extends EventEmitter {
|
|
|
489
487
|
*/
|
|
490
488
|
async _getFileList(checkpointId) {
|
|
491
489
|
const filesDir = path.join(this.storageDir, checkpointId, 'files');
|
|
492
|
-
if (!await fs.pathExists(filesDir)) {
|
|
490
|
+
if (!(await fs.pathExists(filesDir))) {
|
|
493
491
|
return [];
|
|
494
492
|
}
|
|
495
493
|
return this._getFilesInDir(filesDir);
|
|
@@ -501,7 +499,7 @@ class CheckpointManager extends EventEmitter {
|
|
|
501
499
|
*/
|
|
502
500
|
async _getFileHash(checkpointId, file) {
|
|
503
501
|
const filePath = path.join(this.storageDir, checkpointId, 'files', file);
|
|
504
|
-
if (!await fs.pathExists(filePath)) {
|
|
502
|
+
if (!(await fs.pathExists(filePath))) {
|
|
505
503
|
return null;
|
|
506
504
|
}
|
|
507
505
|
|
|
@@ -517,9 +515,7 @@ class CheckpointManager extends EventEmitter {
|
|
|
517
515
|
const checkpoints = this.list();
|
|
518
516
|
|
|
519
517
|
// Keep archived checkpoints separate
|
|
520
|
-
const activeCheckpoints = checkpoints.filter(
|
|
521
|
-
cp => cp.state !== CheckpointState.ARCHIVED
|
|
522
|
-
);
|
|
518
|
+
const activeCheckpoints = checkpoints.filter(cp => cp.state !== CheckpointState.ARCHIVED);
|
|
523
519
|
|
|
524
520
|
if (activeCheckpoints.length > this.config.maxCheckpoints) {
|
|
525
521
|
const toDelete = activeCheckpoints.slice(this.config.maxCheckpoints);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Delta Specification Manager
|
|
3
3
|
* Handles ADDED/MODIFIED/REMOVED/RENAMED delta specifications for brownfield projects
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
5
|
* @module managers/delta-spec
|
|
6
6
|
*/
|
|
7
7
|
|
|
@@ -15,7 +15,7 @@ const DeltaType = {
|
|
|
15
15
|
ADDED: 'ADDED',
|
|
16
16
|
MODIFIED: 'MODIFIED',
|
|
17
17
|
REMOVED: 'REMOVED',
|
|
18
|
-
RENAMED: 'RENAMED'
|
|
18
|
+
RENAMED: 'RENAMED',
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -68,7 +68,7 @@ class DeltaSpecManager {
|
|
|
68
68
|
rationale,
|
|
69
69
|
impactedAreas = [],
|
|
70
70
|
before = null,
|
|
71
|
-
after = null
|
|
71
|
+
after = null,
|
|
72
72
|
} = options;
|
|
73
73
|
|
|
74
74
|
// Validate required fields
|
|
@@ -99,7 +99,7 @@ class DeltaSpecManager {
|
|
|
99
99
|
after,
|
|
100
100
|
status: 'proposed',
|
|
101
101
|
createdAt: now,
|
|
102
|
-
updatedAt: now
|
|
102
|
+
updatedAt: now,
|
|
103
103
|
};
|
|
104
104
|
|
|
105
105
|
// Save delta spec
|
|
@@ -114,7 +114,7 @@ class DeltaSpecManager {
|
|
|
114
114
|
*/
|
|
115
115
|
save(deltaSpec) {
|
|
116
116
|
this.init();
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
const changeDir = path.join(this.changesDir, deltaSpec.id);
|
|
119
119
|
if (!fs.existsSync(changeDir)) {
|
|
120
120
|
fs.mkdirSync(changeDir, { recursive: true });
|
|
@@ -206,7 +206,7 @@ class DeltaSpecManager {
|
|
|
206
206
|
*/
|
|
207
207
|
list(options = {}) {
|
|
208
208
|
const { status, type } = options;
|
|
209
|
-
|
|
209
|
+
|
|
210
210
|
if (!fs.existsSync(this.changesDir)) {
|
|
211
211
|
return [];
|
|
212
212
|
}
|
|
@@ -285,7 +285,7 @@ class DeltaSpecManager {
|
|
|
285
285
|
return {
|
|
286
286
|
archived: true,
|
|
287
287
|
id,
|
|
288
|
-
archivePath: archiveFile
|
|
288
|
+
archivePath: archiveFile,
|
|
289
289
|
};
|
|
290
290
|
}
|
|
291
291
|
|
|
@@ -306,7 +306,7 @@ class DeltaSpecManager {
|
|
|
306
306
|
type,
|
|
307
307
|
id,
|
|
308
308
|
description: description.trim(),
|
|
309
|
-
line: content.substring(0, match.index).split('\n').length
|
|
309
|
+
line: content.substring(0, match.index).split('\n').length,
|
|
310
310
|
});
|
|
311
311
|
}
|
|
312
312
|
}
|
|
@@ -363,7 +363,7 @@ class DeltaSpecManager {
|
|
|
363
363
|
return {
|
|
364
364
|
valid: errors.length === 0,
|
|
365
365
|
errors,
|
|
366
|
-
warnings
|
|
366
|
+
warnings,
|
|
367
367
|
};
|
|
368
368
|
}
|
|
369
369
|
|
|
@@ -386,7 +386,7 @@ class DeltaSpecManager {
|
|
|
386
386
|
impactedAreas: delta.impactedAreas,
|
|
387
387
|
status: delta.status,
|
|
388
388
|
affectedFiles: this.findAffectedFiles(delta),
|
|
389
|
-
recommendations: this.generateRecommendations(delta)
|
|
389
|
+
recommendations: this.generateRecommendations(delta),
|
|
390
390
|
};
|
|
391
391
|
}
|
|
392
392
|
|
|
@@ -401,16 +401,16 @@ class DeltaSpecManager {
|
|
|
401
401
|
const affected = [];
|
|
402
402
|
const targetPattern = new RegExp(delta.target.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g');
|
|
403
403
|
|
|
404
|
-
const scanDir =
|
|
404
|
+
const scanDir = dir => {
|
|
405
405
|
if (!fs.existsSync(dir)) return;
|
|
406
|
-
|
|
406
|
+
|
|
407
407
|
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
408
408
|
for (const entry of entries) {
|
|
409
409
|
const fullPath = path.join(dir, entry.name);
|
|
410
|
-
|
|
410
|
+
|
|
411
411
|
// Skip node_modules and hidden directories
|
|
412
412
|
if (entry.name.startsWith('.') || entry.name === 'node_modules') continue;
|
|
413
|
-
|
|
413
|
+
|
|
414
414
|
if (entry.isDirectory()) {
|
|
415
415
|
scanDir(fullPath);
|
|
416
416
|
} else if (entry.isFile() && /\.(js|ts|md|json)$/.test(entry.name)) {
|
|
@@ -428,7 +428,7 @@ class DeltaSpecManager {
|
|
|
428
428
|
|
|
429
429
|
scanDir(path.join(this.projectRoot, 'src'));
|
|
430
430
|
scanDir(path.join(this.projectRoot, 'storage'));
|
|
431
|
-
|
|
431
|
+
|
|
432
432
|
return affected;
|
|
433
433
|
}
|
|
434
434
|
|
|
@@ -446,19 +446,19 @@ class DeltaSpecManager {
|
|
|
446
446
|
recommendations.push('Update traceability matrix');
|
|
447
447
|
recommendations.push('Add test cases for new functionality');
|
|
448
448
|
break;
|
|
449
|
-
|
|
449
|
+
|
|
450
450
|
case DeltaType.MODIFIED:
|
|
451
451
|
recommendations.push('Review existing tests for compatibility');
|
|
452
452
|
recommendations.push('Update design documents if architecture affected');
|
|
453
453
|
recommendations.push('Check for breaking changes in APIs');
|
|
454
454
|
break;
|
|
455
|
-
|
|
455
|
+
|
|
456
456
|
case DeltaType.REMOVED:
|
|
457
457
|
recommendations.push('Remove obsolete test cases');
|
|
458
458
|
recommendations.push('Update documentation to reflect removal');
|
|
459
459
|
recommendations.push('Check for orphaned code dependencies');
|
|
460
460
|
break;
|
|
461
|
-
|
|
461
|
+
|
|
462
462
|
case DeltaType.RENAMED:
|
|
463
463
|
recommendations.push('Update all references to renamed entity');
|
|
464
464
|
recommendations.push('Update import statements');
|
|
@@ -480,5 +480,5 @@ class DeltaSpecManager {
|
|
|
480
480
|
|
|
481
481
|
module.exports = {
|
|
482
482
|
DeltaSpecManager,
|
|
483
|
-
DeltaType
|
|
483
|
+
DeltaType,
|
|
484
484
|
};
|
package/src/managers/index.js
CHANGED
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
7
|
-
const {
|
|
7
|
+
const {
|
|
8
|
+
CheckpointManager,
|
|
9
|
+
CheckpointState,
|
|
10
|
+
DEFAULT_CONFIG: CheckpointConfig,
|
|
11
|
+
} = require('./checkpoint-manager');
|
|
8
12
|
const AgentMemory = require('./agent-memory');
|
|
9
13
|
const ChangeManager = require('./change');
|
|
10
14
|
const DeltaSpecManager = require('./delta-spec');
|
|
@@ -12,20 +16,25 @@ const MemoryCondenser = require('./memory-condenser');
|
|
|
12
16
|
const RepoSkillManager = require('./repo-skill-manager');
|
|
13
17
|
const SkillLoader = require('./skill-loader');
|
|
14
18
|
const WorkflowManager = require('./workflow');
|
|
15
|
-
const {
|
|
19
|
+
const {
|
|
20
|
+
SkillToolsManager,
|
|
21
|
+
SkillToolConfig,
|
|
22
|
+
RestrictionLevel,
|
|
23
|
+
DEFAULT_TOOL_SETS,
|
|
24
|
+
} = require('./skill-tools');
|
|
16
25
|
|
|
17
26
|
module.exports = {
|
|
18
27
|
// Checkpoint
|
|
19
28
|
CheckpointManager,
|
|
20
29
|
CheckpointState,
|
|
21
30
|
CheckpointConfig,
|
|
22
|
-
|
|
31
|
+
|
|
23
32
|
// Skill Tools (Sprint 3.4)
|
|
24
33
|
SkillToolsManager,
|
|
25
34
|
SkillToolConfig,
|
|
26
35
|
RestrictionLevel,
|
|
27
36
|
DEFAULT_TOOL_SETS,
|
|
28
|
-
|
|
37
|
+
|
|
29
38
|
// Other managers
|
|
30
39
|
AgentMemory,
|
|
31
40
|
ChangeManager,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MUSUBI Memory Condenser
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* 長いセッション履歴を圧縮してコンテキストウィンドウ内に収める
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
6
|
* @module src/managers/memory-condenser
|
|
7
7
|
* @see REQ-P0-B004
|
|
8
8
|
* @inspired-by OpenHands openhands/memory/condenser/condenser.py
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
* コンデンサータイプ
|
|
13
13
|
*/
|
|
14
14
|
const CondenserType = {
|
|
15
|
-
LLM: 'llm',
|
|
16
|
-
RECENT: 'recent',
|
|
15
|
+
LLM: 'llm', // LLMで要約
|
|
16
|
+
RECENT: 'recent', // 最新N件を保持
|
|
17
17
|
AMORTIZED: 'amortized', // 分割統治方式
|
|
18
|
-
NOOP: 'noop',
|
|
18
|
+
NOOP: 'noop', // 圧縮なし
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -60,8 +60,8 @@ class MemoryEvent {
|
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* 要約イベントを作成
|
|
63
|
-
* @param {string} summary
|
|
64
|
-
* @param {MemoryEvent[]} originalEvents
|
|
63
|
+
* @param {string} summary
|
|
64
|
+
* @param {MemoryEvent[]} originalEvents
|
|
65
65
|
* @returns {MemoryEvent}
|
|
66
66
|
*/
|
|
67
67
|
static createSummary(summary, originalEvents) {
|
|
@@ -102,9 +102,7 @@ class CondensedView {
|
|
|
102
102
|
originalCount: stats.originalCount || 0,
|
|
103
103
|
condensedCount: events.length,
|
|
104
104
|
summaryCount: events.filter(e => e.type === MemoryEventType.SUMMARY).length,
|
|
105
|
-
compressionRatio: stats.originalCount
|
|
106
|
-
? (1 - events.length / stats.originalCount)
|
|
107
|
-
: 0,
|
|
105
|
+
compressionRatio: stats.originalCount ? 1 - events.length / stats.originalCount : 0,
|
|
108
106
|
totalTokens: events.reduce((sum, e) => sum + e.tokens, 0),
|
|
109
107
|
};
|
|
110
108
|
}
|
|
@@ -114,12 +112,14 @@ class CondensedView {
|
|
|
114
112
|
* @returns {string}
|
|
115
113
|
*/
|
|
116
114
|
toPrompt() {
|
|
117
|
-
return this.events
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
115
|
+
return this.events
|
|
116
|
+
.map(e => {
|
|
117
|
+
if (e.type === MemoryEventType.SUMMARY) {
|
|
118
|
+
return `[Previous conversation summary]\n${e.content}`;
|
|
119
|
+
}
|
|
120
|
+
return e.content;
|
|
121
|
+
})
|
|
122
|
+
.join('\n\n');
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
|
|
@@ -142,16 +142,16 @@ class BaseCondenser {
|
|
|
142
142
|
|
|
143
143
|
/**
|
|
144
144
|
* イベントを圧縮
|
|
145
|
-
* @param {MemoryEvent[]} events
|
|
145
|
+
* @param {MemoryEvent[]} events
|
|
146
146
|
* @returns {Promise<CondensedView>}
|
|
147
147
|
*/
|
|
148
|
-
async condense(
|
|
148
|
+
async condense(_events) {
|
|
149
149
|
throw new Error('Must implement condense()');
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
/**
|
|
153
153
|
* 保持すべきイベントかチェック
|
|
154
|
-
* @param {MemoryEvent} event
|
|
154
|
+
* @param {MemoryEvent} event
|
|
155
155
|
* @returns {boolean}
|
|
156
156
|
*/
|
|
157
157
|
shouldPreserve(event) {
|
|
@@ -161,9 +161,7 @@ class BaseCondenser {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
// パターンマッチング
|
|
164
|
-
return this.preservePatterns.some(pattern =>
|
|
165
|
-
event.content.includes(pattern)
|
|
166
|
-
);
|
|
164
|
+
return this.preservePatterns.some(pattern => event.content.includes(pattern));
|
|
167
165
|
}
|
|
168
166
|
}
|
|
169
167
|
|
|
@@ -202,7 +200,7 @@ class RecentEventsCondenser extends BaseCondenser {
|
|
|
202
200
|
|
|
203
201
|
const firstEvents = events.slice(0, this.keepFirst);
|
|
204
202
|
const recentEvents = events.slice(-this.keepRecent);
|
|
205
|
-
|
|
203
|
+
|
|
206
204
|
// 中間イベントから保持すべきものを抽出
|
|
207
205
|
const middleEvents = events.slice(this.keepFirst, -this.keepRecent);
|
|
208
206
|
const preservedMiddle = middleEvents.filter(e => this.shouldPreserve(e));
|
|
@@ -214,12 +212,7 @@ class RecentEventsCondenser extends BaseCondenser {
|
|
|
214
212
|
middleEvents.filter(e => !this.shouldPreserve(e))
|
|
215
213
|
);
|
|
216
214
|
|
|
217
|
-
const condensedEvents = [
|
|
218
|
-
...firstEvents,
|
|
219
|
-
summaryEvent,
|
|
220
|
-
...preservedMiddle,
|
|
221
|
-
...recentEvents,
|
|
222
|
-
];
|
|
215
|
+
const condensedEvents = [...firstEvents, summaryEvent, ...preservedMiddle, ...recentEvents];
|
|
223
216
|
|
|
224
217
|
return new CondensedView(condensedEvents, {
|
|
225
218
|
originalCount: events.length,
|
|
@@ -247,7 +240,7 @@ class LLMCondenser extends BaseCondenser {
|
|
|
247
240
|
|
|
248
241
|
async condense(events) {
|
|
249
242
|
const totalTokens = events.reduce((sum, e) => sum + e.tokens, 0);
|
|
250
|
-
|
|
243
|
+
|
|
251
244
|
if (totalTokens <= this.maxTokens) {
|
|
252
245
|
return new CondensedView(events, {
|
|
253
246
|
originalCount: events.length,
|
|
@@ -257,7 +250,7 @@ class LLMCondenser extends BaseCondenser {
|
|
|
257
250
|
// 最初のイベントは保持
|
|
258
251
|
const preserved = events.slice(0, this.keepFirst);
|
|
259
252
|
let remaining = events.slice(this.keepFirst);
|
|
260
|
-
|
|
253
|
+
|
|
261
254
|
// 重要なイベントを抽出
|
|
262
255
|
const importantEvents = remaining.filter(e => this.shouldPreserve(e));
|
|
263
256
|
const regularEvents = remaining.filter(e => !this.shouldPreserve(e));
|
|
@@ -268,16 +261,12 @@ class LLMCondenser extends BaseCondenser {
|
|
|
268
261
|
|
|
269
262
|
for (const chunk of chunks) {
|
|
270
263
|
if (chunk.length === 0) continue;
|
|
271
|
-
|
|
264
|
+
|
|
272
265
|
const summaryText = await this.summarizer(chunk);
|
|
273
266
|
summaries.push(MemoryEvent.createSummary(summaryText, chunk));
|
|
274
267
|
}
|
|
275
268
|
|
|
276
|
-
const condensedEvents = [
|
|
277
|
-
...preserved,
|
|
278
|
-
...summaries,
|
|
279
|
-
...importantEvents,
|
|
280
|
-
];
|
|
269
|
+
const condensedEvents = [...preserved, ...summaries, ...importantEvents];
|
|
281
270
|
|
|
282
271
|
return new CondensedView(condensedEvents, {
|
|
283
272
|
originalCount: events.length,
|
|
@@ -286,7 +275,7 @@ class LLMCondenser extends BaseCondenser {
|
|
|
286
275
|
|
|
287
276
|
/**
|
|
288
277
|
* イベントをチャンク化
|
|
289
|
-
* @param {MemoryEvent[]} events
|
|
278
|
+
* @param {MemoryEvent[]} events
|
|
290
279
|
* @returns {MemoryEvent[][]}
|
|
291
280
|
*/
|
|
292
281
|
_chunkEvents(events) {
|
|
@@ -299,7 +288,7 @@ class LLMCondenser extends BaseCondenser {
|
|
|
299
288
|
|
|
300
289
|
/**
|
|
301
290
|
* デフォルト要約関数(LLM未使用、簡易版)
|
|
302
|
-
* @param {MemoryEvent[]} events
|
|
291
|
+
* @param {MemoryEvent[]} events
|
|
303
292
|
* @returns {Promise<string>}
|
|
304
293
|
*/
|
|
305
294
|
async _defaultSummarizer(events) {
|
|
@@ -342,19 +331,20 @@ class AmortizedCondenser extends BaseCondenser {
|
|
|
342
331
|
|
|
343
332
|
// ユーザーメッセージの位置を特定(境界として使用)
|
|
344
333
|
const userMessageIndices = events
|
|
345
|
-
.map((e, i) => e.type === MemoryEventType.USER_MESSAGE ? i : -1)
|
|
334
|
+
.map((e, i) => (e.type === MemoryEventType.USER_MESSAGE ? i : -1))
|
|
346
335
|
.filter(i => i !== -1);
|
|
347
336
|
|
|
348
337
|
// 最初と最新のユーザーメッセージ周辺は保持
|
|
349
338
|
const preserveStart = userMessageIndices[0] !== undefined ? userMessageIndices[0] : 0;
|
|
350
|
-
const preserveEnd =
|
|
351
|
-
|
|
352
|
-
|
|
339
|
+
const preserveEnd =
|
|
340
|
+
userMessageIndices.length > 1
|
|
341
|
+
? userMessageIndices[userMessageIndices.length - 1]
|
|
342
|
+
: events.length;
|
|
353
343
|
|
|
354
344
|
// 圧縮対象を特定
|
|
355
345
|
const toCondense = events.slice(preserveStart + 1, preserveEnd);
|
|
356
346
|
const condensedCount = events.length - this.targetSize;
|
|
357
|
-
|
|
347
|
+
|
|
358
348
|
if (condensedCount <= 0 || toCondense.length === 0) {
|
|
359
349
|
return new CondensedView(events, {
|
|
360
350
|
originalCount: events.length,
|
|
@@ -364,7 +354,7 @@ class AmortizedCondenser extends BaseCondenser {
|
|
|
364
354
|
// 要約を作成
|
|
365
355
|
const summaryText = await this.summarizer(toCondense.slice(0, condensedCount));
|
|
366
356
|
const summaryEvent = MemoryEvent.createSummary(
|
|
367
|
-
summaryText,
|
|
357
|
+
summaryText,
|
|
368
358
|
toCondense.slice(0, condensedCount)
|
|
369
359
|
);
|
|
370
360
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MUSUBI Repository Skill Manager
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* リポジトリ固有スキル(.musubi/skills/)の管理と自動生成
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
6
|
* @module src/managers/repo-skill-manager
|
|
7
7
|
* @see REQ-P0-B003
|
|
8
8
|
* @inspired-by OpenHands openhands/microagent/microagent.py
|
|
@@ -80,9 +80,11 @@ ${analysis.description || 'Repository information for AI assistants.'}
|
|
|
80
80
|
|
|
81
81
|
## General Setup
|
|
82
82
|
|
|
83
|
-
${
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
${
|
|
84
|
+
analysis.setupCommands.length > 0
|
|
85
|
+
? analysis.setupCommands.map(cmd => `- \`${cmd}\``).join('\n')
|
|
86
|
+
: '- Check the README for setup instructions'
|
|
87
|
+
}
|
|
86
88
|
|
|
87
89
|
## Repository Structure
|
|
88
90
|
|
|
@@ -90,10 +92,14 @@ ${analysis.setupCommands.length > 0
|
|
|
90
92
|
${analysis.structureTree}
|
|
91
93
|
\`\`\`
|
|
92
94
|
|
|
93
|
-
${
|
|
95
|
+
${
|
|
96
|
+
analysis.patterns.length > 0
|
|
97
|
+
? `### Detected Patterns
|
|
94
98
|
|
|
95
99
|
${analysis.patterns.map(p => `- **${p.name}**: ${p.description}`).join('\n')}
|
|
96
|
-
`
|
|
100
|
+
`
|
|
101
|
+
: ''
|
|
102
|
+
}
|
|
97
103
|
|
|
98
104
|
## Common Commands
|
|
99
105
|
|
|
@@ -101,15 +107,23 @@ ${analysis.patterns.map(p => `- **${p.name}**: ${p.description}`).join('\n')}
|
|
|
101
107
|
|---------|-------------|
|
|
102
108
|
${analysis.commands.map(c => `| \`${c.cmd}\` | ${c.desc} |`).join('\n')}
|
|
103
109
|
|
|
104
|
-
${
|
|
110
|
+
${
|
|
111
|
+
analysis.testingInfo
|
|
112
|
+
? `## Testing
|
|
105
113
|
|
|
106
114
|
${analysis.testingInfo}
|
|
107
|
-
`
|
|
115
|
+
`
|
|
116
|
+
: ''
|
|
117
|
+
}
|
|
108
118
|
|
|
109
|
-
${
|
|
119
|
+
${
|
|
120
|
+
analysis.cicdInfo
|
|
121
|
+
? `## CI/CD Workflows
|
|
110
122
|
|
|
111
123
|
${analysis.cicdInfo}
|
|
112
|
-
`
|
|
124
|
+
`
|
|
125
|
+
: ''
|
|
126
|
+
}
|
|
113
127
|
|
|
114
128
|
## Important Conventions
|
|
115
129
|
|
|
@@ -145,26 +159,26 @@ ${analysis.conventions.map(c => `- ${c}`).join('\n')}
|
|
|
145
159
|
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
146
160
|
analysis.name = pkg.name || analysis.name;
|
|
147
161
|
analysis.description = pkg.description || '';
|
|
148
|
-
|
|
162
|
+
|
|
149
163
|
// セットアップコマンド
|
|
150
164
|
analysis.setupCommands.push('npm install');
|
|
151
|
-
|
|
165
|
+
|
|
152
166
|
// スクリプト
|
|
153
167
|
if (pkg.scripts) {
|
|
154
168
|
const scriptMapping = {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
169
|
+
start: 'Start the application',
|
|
170
|
+
dev: 'Start in development mode',
|
|
171
|
+
build: 'Build the application',
|
|
172
|
+
test: 'Run tests',
|
|
173
|
+
lint: 'Run linter',
|
|
174
|
+
format: 'Format code',
|
|
161
175
|
};
|
|
162
|
-
|
|
176
|
+
|
|
163
177
|
for (const [script, desc] of Object.entries(scriptMapping)) {
|
|
164
178
|
if (pkg.scripts[script]) {
|
|
165
|
-
analysis.commands.push({
|
|
166
|
-
cmd: `npm run ${script}`,
|
|
167
|
-
desc
|
|
179
|
+
analysis.commands.push({
|
|
180
|
+
cmd: `npm run ${script}`,
|
|
181
|
+
desc,
|
|
168
182
|
});
|
|
169
183
|
}
|
|
170
184
|
}
|
|
@@ -177,7 +191,7 @@ ${analysis.conventions.map(c => `- ${c}`).join('\n')}
|
|
|
177
191
|
name: 'Testing',
|
|
178
192
|
description: deps['jest'] ? 'Jest' : 'Vitest',
|
|
179
193
|
});
|
|
180
|
-
analysis.testingInfo = deps['jest']
|
|
194
|
+
analysis.testingInfo = deps['jest']
|
|
181
195
|
? '- Run `npm test` to execute Jest tests'
|
|
182
196
|
: '- Run `npm test` to execute Vitest tests';
|
|
183
197
|
}
|
|
@@ -215,7 +229,10 @@ ${analysis.conventions.map(c => `- ${c}`).join('\n')}
|
|
|
215
229
|
const pyprojectPath = path.join(this.projectRoot, 'pyproject.toml');
|
|
216
230
|
if (fs.existsSync(requirementsPath)) {
|
|
217
231
|
analysis.setupCommands.push('pip install -r requirements.txt');
|
|
218
|
-
analysis.commands.push({
|
|
232
|
+
analysis.commands.push({
|
|
233
|
+
cmd: 'pip install -r requirements.txt',
|
|
234
|
+
desc: 'Install dependencies',
|
|
235
|
+
});
|
|
219
236
|
}
|
|
220
237
|
if (fs.existsSync(pyprojectPath)) {
|
|
221
238
|
analysis.setupCommands.push('pip install -e .');
|
|
@@ -229,7 +246,7 @@ ${analysis.conventions.map(c => `- ${c}`).join('\n')}
|
|
|
229
246
|
{ path: 'Jenkinsfile', desc: 'Jenkins pipeline' },
|
|
230
247
|
{ path: '.circleci/config.yml', desc: 'CircleCI configuration' },
|
|
231
248
|
];
|
|
232
|
-
|
|
249
|
+
|
|
233
250
|
for (const ci of cicdPaths) {
|
|
234
251
|
const ciPath = path.join(this.projectRoot, ci.path);
|
|
235
252
|
if (fs.existsSync(ciPath)) {
|
|
@@ -245,8 +262,10 @@ ${analysis.conventions.map(c => `- ${c}`).join('\n')}
|
|
|
245
262
|
if (fs.existsSync(path.join(this.projectRoot, '.editorconfig'))) {
|
|
246
263
|
analysis.conventions.push('Follow .editorconfig settings');
|
|
247
264
|
}
|
|
248
|
-
if (
|
|
249
|
-
|
|
265
|
+
if (
|
|
266
|
+
fs.existsSync(path.join(this.projectRoot, '.prettierrc')) ||
|
|
267
|
+
fs.existsSync(path.join(this.projectRoot, '.prettierrc.json'))
|
|
268
|
+
) {
|
|
250
269
|
analysis.conventions.push('Use Prettier for code formatting');
|
|
251
270
|
}
|
|
252
271
|
if (fs.existsSync(path.join(this.projectRoot, 'steering'))) {
|
|
@@ -264,8 +283,15 @@ ${analysis.conventions.map(c => `- ${c}`).join('\n')}
|
|
|
264
283
|
const maxDepth = 2;
|
|
265
284
|
const maxItems = 15;
|
|
266
285
|
const ignoreDirs = [
|
|
267
|
-
'node_modules',
|
|
268
|
-
'
|
|
286
|
+
'node_modules',
|
|
287
|
+
'.git',
|
|
288
|
+
'.next',
|
|
289
|
+
'dist',
|
|
290
|
+
'build',
|
|
291
|
+
'coverage',
|
|
292
|
+
'__pycache__',
|
|
293
|
+
'.venv',
|
|
294
|
+
'venv',
|
|
269
295
|
];
|
|
270
296
|
|
|
271
297
|
const lines = [];
|
|
@@ -386,7 +412,7 @@ ${options.content || '<!-- Add skill content here -->'}
|
|
|
386
412
|
|
|
387
413
|
/**
|
|
388
414
|
* スキルを削除
|
|
389
|
-
* @param {string} name
|
|
415
|
+
* @param {string} name
|
|
390
416
|
* @returns {boolean}
|
|
391
417
|
*/
|
|
392
418
|
removeSkill(name) {
|