musubi-sdd 5.0.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.
Files changed (232) hide show
  1. package/README.ja.md +106 -48
  2. package/README.md +110 -32
  3. package/bin/musubi-analyze.js +74 -67
  4. package/bin/musubi-browser.js +27 -26
  5. package/bin/musubi-change.js +48 -47
  6. package/bin/musubi-checkpoint.js +10 -7
  7. package/bin/musubi-convert.js +25 -25
  8. package/bin/musubi-costs.js +27 -10
  9. package/bin/musubi-gui.js +52 -46
  10. package/bin/musubi-init.js +1952 -10
  11. package/bin/musubi-orchestrate.js +327 -239
  12. package/bin/musubi-remember.js +69 -56
  13. package/bin/musubi-resolve.js +53 -45
  14. package/bin/musubi-trace.js +51 -22
  15. package/bin/musubi-validate.js +39 -30
  16. package/bin/musubi-workflow.js +33 -34
  17. package/bin/musubi.js +39 -2
  18. package/package.json +1 -1
  19. package/src/agents/agent-loop.js +94 -95
  20. package/src/agents/agentic/code-generator.js +119 -109
  21. package/src/agents/agentic/code-reviewer.js +105 -108
  22. package/src/agents/agentic/index.js +4 -4
  23. package/src/agents/browser/action-executor.js +13 -13
  24. package/src/agents/browser/ai-comparator.js +11 -10
  25. package/src/agents/browser/context-manager.js +6 -6
  26. package/src/agents/browser/index.js +5 -5
  27. package/src/agents/browser/nl-parser.js +31 -46
  28. package/src/agents/browser/screenshot.js +2 -2
  29. package/src/agents/browser/test-generator.js +6 -4
  30. package/src/agents/function-tool.js +71 -65
  31. package/src/agents/index.js +7 -7
  32. package/src/agents/schema-generator.js +98 -94
  33. package/src/analyzers/ast-extractor.js +164 -145
  34. package/src/analyzers/codegraph-auto-update.js +858 -0
  35. package/src/analyzers/complexity-analyzer.js +536 -0
  36. package/src/analyzers/context-optimizer.js +247 -125
  37. package/src/analyzers/impact-analyzer.js +1 -1
  38. package/src/analyzers/large-project-analyzer.js +766 -0
  39. package/src/analyzers/repository-map.js +83 -80
  40. package/src/analyzers/security-analyzer.js +19 -11
  41. package/src/analyzers/stuck-detector.js +19 -17
  42. package/src/converters/index.js +78 -57
  43. package/src/converters/ir/types.js +12 -12
  44. package/src/converters/parsers/musubi-parser.js +134 -126
  45. package/src/converters/parsers/openapi-parser.js +70 -53
  46. package/src/converters/parsers/speckit-parser.js +239 -175
  47. package/src/converters/writers/musubi-writer.js +123 -118
  48. package/src/converters/writers/speckit-writer.js +124 -113
  49. package/src/generators/rust-migration-generator.js +512 -0
  50. package/src/gui/public/index.html +1365 -1211
  51. package/src/gui/server.js +41 -40
  52. package/src/gui/services/file-watcher.js +23 -8
  53. package/src/gui/services/project-scanner.js +26 -20
  54. package/src/gui/services/replanning-service.js +27 -23
  55. package/src/gui/services/traceability-service.js +8 -8
  56. package/src/gui/services/workflow-service.js +14 -7
  57. package/src/index.js +151 -0
  58. package/src/integrations/cicd.js +90 -104
  59. package/src/integrations/codegraph-mcp.js +643 -0
  60. package/src/integrations/documentation.js +142 -103
  61. package/src/integrations/examples.js +95 -80
  62. package/src/integrations/github-client.js +17 -17
  63. package/src/integrations/index.js +5 -5
  64. package/src/integrations/mcp/index.js +21 -21
  65. package/src/integrations/mcp/mcp-context-provider.js +76 -78
  66. package/src/integrations/mcp/mcp-discovery.js +74 -72
  67. package/src/integrations/mcp/mcp-tool-registry.js +99 -94
  68. package/src/integrations/mcp-connector.js +70 -66
  69. package/src/integrations/platforms.js +50 -49
  70. package/src/integrations/tool-discovery.js +37 -31
  71. package/src/llm-providers/anthropic-provider.js +11 -11
  72. package/src/llm-providers/base-provider.js +16 -18
  73. package/src/llm-providers/copilot-provider.js +22 -19
  74. package/src/llm-providers/index.js +26 -25
  75. package/src/llm-providers/ollama-provider.js +11 -11
  76. package/src/llm-providers/openai-provider.js +12 -12
  77. package/src/managers/agent-memory.js +36 -24
  78. package/src/managers/checkpoint-manager.js +4 -8
  79. package/src/managers/delta-spec.js +19 -19
  80. package/src/managers/index.js +13 -4
  81. package/src/managers/memory-condenser.js +35 -45
  82. package/src/managers/repo-skill-manager.js +57 -31
  83. package/src/managers/skill-loader.js +25 -22
  84. package/src/managers/skill-tools.js +36 -72
  85. package/src/managers/workflow.js +30 -22
  86. package/src/monitoring/cost-tracker.js +53 -44
  87. package/src/monitoring/incident-manager.js +123 -103
  88. package/src/monitoring/index.js +144 -134
  89. package/src/monitoring/observability.js +82 -59
  90. package/src/monitoring/quality-dashboard.js +51 -39
  91. package/src/monitoring/release-manager.js +70 -50
  92. package/src/orchestration/agent-skill-binding.js +39 -47
  93. package/src/orchestration/error-handler.js +65 -107
  94. package/src/orchestration/guardrails/base-guardrail.js +26 -24
  95. package/src/orchestration/guardrails/guardrail-rules.js +50 -64
  96. package/src/orchestration/guardrails/index.js +5 -5
  97. package/src/orchestration/guardrails/input-guardrail.js +58 -45
  98. package/src/orchestration/guardrails/output-guardrail.js +104 -81
  99. package/src/orchestration/guardrails/safety-check.js +79 -79
  100. package/src/orchestration/index.js +38 -55
  101. package/src/orchestration/mcp-tool-adapters.js +96 -99
  102. package/src/orchestration/orchestration-engine.js +21 -21
  103. package/src/orchestration/pattern-registry.js +60 -45
  104. package/src/orchestration/patterns/auto.js +34 -47
  105. package/src/orchestration/patterns/group-chat.js +59 -65
  106. package/src/orchestration/patterns/handoff.js +67 -65
  107. package/src/orchestration/patterns/human-in-loop.js +51 -72
  108. package/src/orchestration/patterns/nested.js +25 -40
  109. package/src/orchestration/patterns/sequential.js +35 -34
  110. package/src/orchestration/patterns/swarm.js +63 -56
  111. package/src/orchestration/patterns/triage.js +150 -109
  112. package/src/orchestration/reasoning/index.js +9 -9
  113. package/src/orchestration/reasoning/planning-engine.js +143 -140
  114. package/src/orchestration/reasoning/reasoning-engine.js +206 -144
  115. package/src/orchestration/reasoning/self-correction.js +121 -128
  116. package/src/orchestration/replanning/adaptive-goal-modifier.js +107 -112
  117. package/src/orchestration/replanning/alternative-generator.js +37 -42
  118. package/src/orchestration/replanning/config.js +63 -59
  119. package/src/orchestration/replanning/goal-progress-tracker.js +98 -100
  120. package/src/orchestration/replanning/index.js +24 -20
  121. package/src/orchestration/replanning/plan-evaluator.js +49 -50
  122. package/src/orchestration/replanning/plan-monitor.js +32 -28
  123. package/src/orchestration/replanning/proactive-path-optimizer.js +175 -178
  124. package/src/orchestration/replanning/replan-history.js +33 -26
  125. package/src/orchestration/replanning/replanning-engine.js +106 -108
  126. package/src/orchestration/skill-executor.js +107 -109
  127. package/src/orchestration/skill-registry.js +85 -89
  128. package/src/orchestration/workflow-examples.js +228 -231
  129. package/src/orchestration/workflow-executor.js +65 -68
  130. package/src/orchestration/workflow-orchestrator.js +72 -73
  131. package/src/phase4-integration.js +47 -40
  132. package/src/phase5-integration.js +89 -30
  133. package/src/reporters/coverage-report.js +82 -30
  134. package/src/reporters/hierarchical-reporter.js +498 -0
  135. package/src/reporters/traceability-matrix-report.js +29 -20
  136. package/src/resolvers/issue-resolver.js +43 -31
  137. package/src/steering/advanced-validation.js +133 -124
  138. package/src/steering/auto-updater.js +60 -73
  139. package/src/steering/index.js +6 -6
  140. package/src/steering/quality-metrics.js +41 -35
  141. package/src/steering/steering-auto-update.js +83 -86
  142. package/src/steering/steering-validator.js +98 -106
  143. package/src/steering/template-constraints.js +53 -54
  144. package/src/templates/agents/claude-code/CLAUDE.md +32 -32
  145. package/src/templates/agents/claude-code/skills/agent-assistant/SKILL.md +13 -5
  146. package/src/templates/agents/claude-code/skills/ai-ml-engineer/mlops-guide.md +23 -23
  147. package/src/templates/agents/claude-code/skills/ai-ml-engineer/model-card-template.md +60 -41
  148. package/src/templates/agents/claude-code/skills/api-designer/api-patterns.md +27 -19
  149. package/src/templates/agents/claude-code/skills/api-designer/openapi-template.md +11 -7
  150. package/src/templates/agents/claude-code/skills/bug-hunter/SKILL.md +4 -3
  151. package/src/templates/agents/claude-code/skills/bug-hunter/root-cause-analysis.md +37 -15
  152. package/src/templates/agents/claude-code/skills/change-impact-analyzer/dependency-graph-patterns.md +36 -42
  153. package/src/templates/agents/claude-code/skills/change-impact-analyzer/impact-analysis-template.md +69 -60
  154. package/src/templates/agents/claude-code/skills/cloud-architect/aws-patterns.md +31 -38
  155. package/src/templates/agents/claude-code/skills/cloud-architect/azure-patterns.md +28 -23
  156. package/src/templates/agents/claude-code/skills/code-reviewer/SKILL.md +61 -0
  157. package/src/templates/agents/claude-code/skills/code-reviewer/best-practices.md +27 -0
  158. package/src/templates/agents/claude-code/skills/code-reviewer/review-checklist.md +29 -10
  159. package/src/templates/agents/claude-code/skills/code-reviewer/review-standards.md +29 -24
  160. package/src/templates/agents/claude-code/skills/constitution-enforcer/SKILL.md +8 -6
  161. package/src/templates/agents/claude-code/skills/constitution-enforcer/constitutional-articles.md +62 -26
  162. package/src/templates/agents/claude-code/skills/constitution-enforcer/phase-minus-one-gates.md +35 -16
  163. package/src/templates/agents/claude-code/skills/database-administrator/backup-recovery.md +27 -17
  164. package/src/templates/agents/claude-code/skills/database-administrator/tuning-guide.md +25 -20
  165. package/src/templates/agents/claude-code/skills/database-schema-designer/schema-patterns.md +39 -22
  166. package/src/templates/agents/claude-code/skills/devops-engineer/ci-cd-templates.md +25 -22
  167. package/src/templates/agents/claude-code/skills/issue-resolver/SKILL.md +24 -21
  168. package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +148 -63
  169. package/src/templates/agents/claude-code/skills/orchestrator/patterns.md +35 -16
  170. package/src/templates/agents/claude-code/skills/orchestrator/selection-matrix.md +69 -64
  171. package/src/templates/agents/claude-code/skills/performance-engineer/optimization-playbook.md +47 -47
  172. package/src/templates/agents/claude-code/skills/performance-optimizer/SKILL.md +69 -0
  173. package/src/templates/agents/claude-code/skills/performance-optimizer/benchmark-template.md +63 -45
  174. package/src/templates/agents/claude-code/skills/performance-optimizer/optimization-patterns.md +33 -35
  175. package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +7 -6
  176. package/src/templates/agents/claude-code/skills/project-manager/agile-ceremonies.md +47 -28
  177. package/src/templates/agents/claude-code/skills/project-manager/project-templates.md +94 -78
  178. package/src/templates/agents/claude-code/skills/quality-assurance/SKILL.md +20 -17
  179. package/src/templates/agents/claude-code/skills/quality-assurance/qa-plan-template.md +63 -49
  180. package/src/templates/agents/claude-code/skills/release-coordinator/SKILL.md +5 -5
  181. package/src/templates/agents/claude-code/skills/release-coordinator/feature-flag-guide.md +30 -26
  182. package/src/templates/agents/claude-code/skills/release-coordinator/release-plan-template.md +67 -35
  183. package/src/templates/agents/claude-code/skills/requirements-analyst/ears-format.md +54 -42
  184. package/src/templates/agents/claude-code/skills/requirements-analyst/validation-rules.md +36 -33
  185. package/src/templates/agents/claude-code/skills/security-auditor/SKILL.md +77 -19
  186. package/src/templates/agents/claude-code/skills/security-auditor/audit-checklists.md +24 -24
  187. package/src/templates/agents/claude-code/skills/security-auditor/owasp-top-10.md +61 -20
  188. package/src/templates/agents/claude-code/skills/security-auditor/vulnerability-patterns.md +43 -11
  189. package/src/templates/agents/claude-code/skills/site-reliability-engineer/SKILL.md +1 -0
  190. package/src/templates/agents/claude-code/skills/site-reliability-engineer/incident-response-template.md +55 -25
  191. package/src/templates/agents/claude-code/skills/site-reliability-engineer/observability-patterns.md +78 -68
  192. package/src/templates/agents/claude-code/skills/site-reliability-engineer/slo-sli-guide.md +73 -53
  193. package/src/templates/agents/claude-code/skills/software-developer/solid-principles.md +83 -37
  194. package/src/templates/agents/claude-code/skills/software-developer/test-first-workflow.md +38 -31
  195. package/src/templates/agents/claude-code/skills/steering/SKILL.md +1 -0
  196. package/src/templates/agents/claude-code/skills/steering/auto-update-rules.md +31 -0
  197. package/src/templates/agents/claude-code/skills/system-architect/adr-template.md +25 -7
  198. package/src/templates/agents/claude-code/skills/system-architect/c4-model-guide.md +74 -61
  199. package/src/templates/agents/claude-code/skills/technical-writer/doc-templates/documentation-templates.md +70 -52
  200. package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +2 -0
  201. package/src/templates/agents/claude-code/skills/test-engineer/ears-test-mapping.md +75 -71
  202. package/src/templates/agents/claude-code/skills/test-engineer/test-types.md +85 -63
  203. package/src/templates/agents/claude-code/skills/traceability-auditor/coverage-matrix-template.md +39 -36
  204. package/src/templates/agents/claude-code/skills/traceability-auditor/gap-detection-rules.md +22 -17
  205. package/src/templates/agents/claude-code/skills/ui-ux-designer/SKILL.md +1 -0
  206. package/src/templates/agents/claude-code/skills/ui-ux-designer/accessibility-guidelines.md +49 -75
  207. package/src/templates/agents/claude-code/skills/ui-ux-designer/design-system-components.md +71 -59
  208. package/src/templates/agents/codex/AGENTS.md +74 -42
  209. package/src/templates/agents/cursor/AGENTS.md +74 -42
  210. package/src/templates/agents/gemini-cli/GEMINI.md +74 -42
  211. package/src/templates/agents/github-copilot/AGENTS.md +83 -51
  212. package/src/templates/agents/qwen-code/QWEN.md +74 -42
  213. package/src/templates/agents/windsurf/AGENTS.md +74 -42
  214. package/src/templates/architectures/README.md +41 -0
  215. package/src/templates/architectures/clean-architecture/README.md +113 -0
  216. package/src/templates/architectures/event-driven/README.md +162 -0
  217. package/src/templates/architectures/hexagonal/README.md +130 -0
  218. package/src/templates/index.js +6 -1
  219. package/src/templates/locale-manager.js +16 -16
  220. package/src/templates/shared/delta-spec-template.md +20 -13
  221. package/src/templates/shared/github-actions/musubi-issue-resolver.yml +5 -5
  222. package/src/templates/shared/github-actions/musubi-security-check.yml +3 -3
  223. package/src/templates/shared/github-actions/musubi-validate.yml +4 -4
  224. package/src/templates/shared/steering/structure.md +95 -0
  225. package/src/templates/skills/browser-agent.md +21 -16
  226. package/src/templates/skills/web-gui.md +8 -0
  227. package/src/templates/template-constraints.js +50 -53
  228. package/src/validators/advanced-validation.js +30 -36
  229. package/src/validators/constitutional-validator.js +77 -73
  230. package/src/validators/critic-system.js +49 -59
  231. package/src/validators/delta-format.js +59 -55
  232. package/src/validators/traceability-validator.js +7 -11
@@ -1,11 +1,21 @@
1
1
  /**
2
2
  * Release Manager - Release coordination and management
3
- *
3
+ *
4
4
  * Provides release management capabilities:
5
5
  * - Release planning and tracking
6
6
  * - Feature flag management
7
7
  * - Rollback procedures
8
8
  * - Release notes generation
9
+ *
10
+ * Part of MUSUBI v5.0.0 - Production Readiness
11
+ *
12
+ * @module monitoring/release-manager
13
+ * @version 1.0.0
14
+ *
15
+ * @traceability
16
+ * - Requirement: REQ-P5-003 (Release Automation)
17
+ * - Design: docs/design/tdd-musubi-v5.0.0.md#3.3
18
+ * - Test: tests/monitoring/release-manager.test.js
9
19
  */
10
20
 
11
21
  const { EventEmitter } = require('events');
@@ -22,7 +32,7 @@ const ReleaseState = {
22
32
  PRODUCTION: 'production',
23
33
  ROLLBACK: 'rollback',
24
34
  COMPLETED: 'completed',
25
- CANCELLED: 'cancelled'
35
+ CANCELLED: 'cancelled',
26
36
  };
27
37
 
28
38
  /**
@@ -33,7 +43,7 @@ const ReleaseType = {
33
43
  MINOR: 'minor',
34
44
  PATCH: 'patch',
35
45
  HOTFIX: 'hotfix',
36
- CANARY: 'canary'
46
+ CANARY: 'canary',
37
47
  };
38
48
 
39
49
  /**
@@ -43,7 +53,7 @@ const FeatureFlagStatus = {
43
53
  ENABLED: 'enabled',
44
54
  DISABLED: 'disabled',
45
55
  PERCENTAGE: 'percentage',
46
- USER_LIST: 'user-list'
56
+ USER_LIST: 'user-list',
47
57
  };
48
58
 
49
59
  /**
@@ -61,35 +71,35 @@ class Release {
61
71
  this.createdAt = options.createdAt || new Date();
62
72
  this.updatedAt = options.updatedAt || new Date();
63
73
  this.completedAt = null;
64
-
74
+
65
75
  this.features = options.features || [];
66
76
  this.bugFixes = options.bugFixes || [];
67
77
  this.breakingChanges = options.breakingChanges || [];
68
78
  this.dependencies = options.dependencies || [];
69
-
79
+
70
80
  this.rolloutStrategy = options.rolloutStrategy || {
71
81
  type: 'percentage',
72
82
  stages: [
73
83
  { percentage: 1, duration: '1h' },
74
84
  { percentage: 10, duration: '2h' },
75
85
  { percentage: 50, duration: '4h' },
76
- { percentage: 100, duration: null }
77
- ]
86
+ { percentage: 100, duration: null },
87
+ ],
78
88
  };
79
-
89
+
80
90
  this.rollbackPlan = options.rollbackPlan || {
81
91
  automatic: true,
82
92
  triggers: ['error_rate > 5%', 'latency_p99 > 2s'],
83
- procedure: []
93
+ procedure: [],
84
94
  };
85
-
95
+
86
96
  this.metrics = {
87
97
  errorsBefore: null,
88
98
  errorsAfter: null,
89
99
  latencyBefore: null,
90
- latencyAfter: null
100
+ latencyAfter: null,
91
101
  };
92
-
102
+
93
103
  this.history = [];
94
104
  this._addHistory('created', { version: this.version });
95
105
  }
@@ -101,13 +111,22 @@ class Release {
101
111
  const validTransitions = {
102
112
  [ReleaseState.PLANNING]: [ReleaseState.DEVELOPMENT, ReleaseState.CANCELLED],
103
113
  [ReleaseState.DEVELOPMENT]: [ReleaseState.TESTING, ReleaseState.CANCELLED],
104
- [ReleaseState.TESTING]: [ReleaseState.STAGING, ReleaseState.DEVELOPMENT, ReleaseState.CANCELLED],
105
- [ReleaseState.STAGING]: [ReleaseState.CANARY, ReleaseState.PRODUCTION, ReleaseState.TESTING, ReleaseState.CANCELLED],
114
+ [ReleaseState.TESTING]: [
115
+ ReleaseState.STAGING,
116
+ ReleaseState.DEVELOPMENT,
117
+ ReleaseState.CANCELLED,
118
+ ],
119
+ [ReleaseState.STAGING]: [
120
+ ReleaseState.CANARY,
121
+ ReleaseState.PRODUCTION,
122
+ ReleaseState.TESTING,
123
+ ReleaseState.CANCELLED,
124
+ ],
106
125
  [ReleaseState.CANARY]: [ReleaseState.PRODUCTION, ReleaseState.ROLLBACK],
107
126
  [ReleaseState.PRODUCTION]: [ReleaseState.COMPLETED, ReleaseState.ROLLBACK],
108
127
  [ReleaseState.ROLLBACK]: [ReleaseState.TESTING, ReleaseState.CANCELLED],
109
128
  [ReleaseState.COMPLETED]: [],
110
- [ReleaseState.CANCELLED]: []
129
+ [ReleaseState.CANCELLED]: [],
111
130
  };
112
131
 
113
132
  const allowed = validTransitions[this.state] || [];
@@ -118,15 +137,15 @@ class Release {
118
137
  const previousState = this.state;
119
138
  this.state = newState;
120
139
  this.updatedAt = new Date();
121
-
140
+
122
141
  if (newState === ReleaseState.COMPLETED) {
123
142
  this.completedAt = new Date();
124
143
  }
125
144
 
126
- this._addHistory('transition', {
127
- from: previousState,
145
+ this._addHistory('transition', {
146
+ from: previousState,
128
147
  to: newState,
129
- ...metadata
148
+ ...metadata,
130
149
  });
131
150
 
132
151
  return this;
@@ -141,7 +160,7 @@ class Release {
141
160
  title: feature.title,
142
161
  description: feature.description || '',
143
162
  jiraId: feature.jiraId || null,
144
- breaking: feature.breaking || false
163
+ breaking: feature.breaking || false,
145
164
  });
146
165
  this._addHistory('featureAdded', { feature: feature.title });
147
166
  return this;
@@ -156,7 +175,7 @@ class Release {
156
175
  title: bugFix.title,
157
176
  description: bugFix.description || '',
158
177
  jiraId: bugFix.jiraId || null,
159
- severity: bugFix.severity || 'medium'
178
+ severity: bugFix.severity || 'medium',
160
179
  });
161
180
  this._addHistory('bugFixAdded', { bugFix: bugFix.title });
162
181
  return this;
@@ -171,7 +190,7 @@ class Release {
171
190
  date: this.completedAt || new Date(),
172
191
  features: this.features,
173
192
  bugFixes: this.bugFixes,
174
- breakingChanges: this.breakingChanges
193
+ breakingChanges: this.breakingChanges,
175
194
  };
176
195
 
177
196
  if (format === 'markdown') {
@@ -237,7 +256,7 @@ class Release {
237
256
  this.history.push({
238
257
  action,
239
258
  timestamp: new Date(),
240
- data
259
+ data,
241
260
  });
242
261
  }
243
262
 
@@ -266,7 +285,7 @@ class Release {
266
285
  breakingChanges: this.breakingChanges,
267
286
  rolloutStrategy: this.rolloutStrategy,
268
287
  rollbackPlan: this.rollbackPlan,
269
- history: this.history
288
+ history: this.history,
270
289
  };
271
290
  }
272
291
  }
@@ -327,18 +346,19 @@ class FeatureFlag {
327
346
  switch (this.status) {
328
347
  case FeatureFlagStatus.ENABLED:
329
348
  return true;
330
-
349
+
331
350
  case FeatureFlagStatus.DISABLED:
332
351
  return false;
333
-
352
+
334
353
  case FeatureFlagStatus.USER_LIST:
335
354
  return this.userList.includes(userId);
336
-
337
- case FeatureFlagStatus.PERCENTAGE:
355
+
356
+ case FeatureFlagStatus.PERCENTAGE: {
338
357
  // Consistent hashing based on userId
339
358
  const hash = this._hashString(`${this.key}:${userId}`);
340
- return (hash % 100) < this.percentage;
341
-
359
+ return hash % 100 < this.percentage;
360
+ }
361
+
342
362
  default:
343
363
  return false;
344
364
  }
@@ -352,7 +372,7 @@ class FeatureFlag {
352
372
  let hash = 0;
353
373
  for (let i = 0; i < str.length; i++) {
354
374
  const char = str.charCodeAt(i);
355
- hash = ((hash << 5) - hash) + char;
375
+ hash = (hash << 5) - hash + char;
356
376
  hash = hash & hash;
357
377
  }
358
378
  return Math.abs(hash);
@@ -368,7 +388,7 @@ class FeatureFlag {
368
388
  userList: this.userList,
369
389
  createdAt: this.createdAt,
370
390
  updatedAt: this.updatedAt,
371
- metadata: this.metadata
391
+ metadata: this.metadata,
372
392
  };
373
393
  }
374
394
  }
@@ -383,7 +403,7 @@ class ReleaseManager extends EventEmitter {
383
403
  this.featureFlags = new Map();
384
404
  this.options = {
385
405
  autoGenerateNotes: options.autoGenerateNotes !== false,
386
- ...options
406
+ ...options,
387
407
  };
388
408
  }
389
409
 
@@ -421,14 +441,14 @@ class ReleaseManager extends EventEmitter {
421
441
  */
422
442
  listReleases(filter = {}) {
423
443
  let releases = [...this.releases.values()];
424
-
444
+
425
445
  if (filter.state) {
426
446
  releases = releases.filter(r => r.state === filter.state);
427
447
  }
428
448
  if (filter.type) {
429
449
  releases = releases.filter(r => r.type === filter.type);
430
450
  }
431
-
451
+
432
452
  return releases.map(r => r.toJSON());
433
453
  }
434
454
 
@@ -440,7 +460,7 @@ class ReleaseManager extends EventEmitter {
440
460
  if (!release) {
441
461
  throw new Error(`Release not found: ${releaseId}`);
442
462
  }
443
-
463
+
444
464
  release.transitionTo(newState, metadata);
445
465
  this.emit('releaseTransitioned', { release, newState });
446
466
  return release;
@@ -476,7 +496,7 @@ class ReleaseManager extends EventEmitter {
476
496
  isFeatureEnabled(flagKey, userId = null) {
477
497
  const flag = this.featureFlags.get(flagKey);
478
498
  if (!flag) return false;
479
-
499
+
480
500
  if (userId) {
481
501
  return flag.isEnabledFor(userId);
482
502
  }
@@ -531,41 +551,41 @@ class ReleaseManager extends EventEmitter {
531
551
  order: 1,
532
552
  action: 'notify',
533
553
  description: 'Notify team of rollback initiation',
534
- command: null
554
+ command: null,
535
555
  },
536
556
  {
537
557
  order: 2,
538
558
  action: 'disable-flags',
539
559
  description: 'Disable all new feature flags',
540
- command: 'musubi release disable-flags --version ' + release.version
560
+ command: 'musubi release disable-flags --version ' + release.version,
541
561
  },
542
562
  {
543
563
  order: 3,
544
564
  action: 'scale-down',
545
565
  description: 'Scale down new deployment',
546
- command: 'kubectl scale deployment app-v' + release.version + ' --replicas=0'
566
+ command: 'kubectl scale deployment app-v' + release.version + ' --replicas=0',
547
567
  },
548
568
  {
549
569
  order: 4,
550
570
  action: 'traffic-shift',
551
571
  description: 'Shift traffic to previous version',
552
- command: 'kubectl rollout undo deployment/app'
572
+ command: 'kubectl rollout undo deployment/app',
553
573
  },
554
574
  {
555
575
  order: 5,
556
576
  action: 'verify',
557
577
  description: 'Verify rollback success',
558
- command: 'curl -f http://app/health'
578
+ command: 'curl -f http://app/health',
559
579
  },
560
580
  {
561
581
  order: 6,
562
582
  action: 'notify-complete',
563
583
  description: 'Notify team of rollback completion',
564
- command: null
565
- }
584
+ command: null,
585
+ },
566
586
  ],
567
587
  automaticTriggers: release.rollbackPlan.triggers,
568
- estimatedDuration: '5-10 minutes'
588
+ estimatedDuration: '5-10 minutes',
569
589
  };
570
590
  }
571
591
 
@@ -583,7 +603,7 @@ class ReleaseManager extends EventEmitter {
583
603
  totalFeatureFlags: flags.length,
584
604
  enabledFlags: flags.filter(f => f.status === FeatureFlagStatus.ENABLED).length,
585
605
  disabledFlags: flags.filter(f => f.status === FeatureFlagStatus.DISABLED).length,
586
- percentageFlags: flags.filter(f => f.status === FeatureFlagStatus.PERCENTAGE).length
606
+ percentageFlags: flags.filter(f => f.status === FeatureFlagStatus.PERCENTAGE).length,
587
607
  };
588
608
  }
589
609
 
@@ -611,12 +631,12 @@ module.exports = {
611
631
  Release,
612
632
  FeatureFlag,
613
633
  ReleaseManager,
614
-
634
+
615
635
  // Constants
616
636
  ReleaseState,
617
637
  ReleaseType,
618
638
  FeatureFlagStatus,
619
-
639
+
620
640
  // Factory
621
- createReleaseManager
641
+ createReleaseManager,
622
642
  };
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Agent-Skill Binding - Dynamic capability-based skill assignment
3
3
  * Sprint 3.3: Skill System Architecture
4
- *
4
+ *
5
5
  * Features:
6
6
  * - Agent capability scoring
7
7
  * - Dynamic skill-agent matching
@@ -19,7 +19,7 @@ const AgentStatus = {
19
19
  AVAILABLE: 'available',
20
20
  BUSY: 'busy',
21
21
  OFFLINE: 'offline',
22
- MAINTENANCE: 'maintenance'
22
+ MAINTENANCE: 'maintenance',
23
23
  };
24
24
 
25
25
  /**
@@ -40,22 +40,22 @@ class AgentDefinition {
40
40
 
41
41
  validate() {
42
42
  const errors = [];
43
-
43
+
44
44
  if (!this.id) {
45
45
  errors.push('Agent ID is required');
46
46
  }
47
-
47
+
48
48
  if (!this.name) {
49
49
  errors.push('Agent name is required');
50
50
  }
51
-
51
+
52
52
  if (!Array.isArray(this.capabilities)) {
53
53
  errors.push('Capabilities must be an array');
54
54
  }
55
-
55
+
56
56
  return {
57
57
  valid: errors.length === 0,
58
- errors
58
+ errors,
59
59
  };
60
60
  }
61
61
 
@@ -69,7 +69,7 @@ class AgentDefinition {
69
69
  maxConcurrentTasks: this.maxConcurrentTasks,
70
70
  priority: this.priority,
71
71
  tags: this.tags,
72
- metadata: this.metadata
72
+ metadata: this.metadata,
73
73
  };
74
74
  }
75
75
  }
@@ -93,16 +93,12 @@ class BindingRecord {
93
93
  updateStats(success, executionTime) {
94
94
  this.executionCount++;
95
95
  const successWeight = success ? 1 : 0;
96
- this.successRate = (
97
- (this.successRate * (this.executionCount - 1) + successWeight) /
98
- this.executionCount
99
- );
100
- this.averageExecutionTime = (
101
- (this.averageExecutionTime * (this.executionCount - 1) + executionTime) /
102
- this.executionCount
103
- );
96
+ this.successRate =
97
+ (this.successRate * (this.executionCount - 1) + successWeight) / this.executionCount;
98
+ this.averageExecutionTime =
99
+ (this.averageExecutionTime * (this.executionCount - 1) + executionTime) / this.executionCount;
104
100
  this.lastExecutedAt = new Date().toISOString();
105
-
101
+
106
102
  // Update affinity based on performance
107
103
  this.affinity = this._calculateAffinity();
108
104
  }
@@ -111,10 +107,10 @@ class BindingRecord {
111
107
  // Affinity increases with success rate and execution count
112
108
  const successFactor = this.successRate * 50;
113
109
  const experienceFactor = Math.min(this.executionCount / 10, 30);
114
- const recencyFactor = this.lastExecutedAt
110
+ const recencyFactor = this.lastExecutedAt
115
111
  ? Math.max(0, 20 - (Date.now() - new Date(this.lastExecutedAt).getTime()) / 86400000)
116
112
  : 0;
117
-
113
+
118
114
  return Math.round(successFactor + experienceFactor + recencyFactor);
119
115
  }
120
116
 
@@ -127,7 +123,7 @@ class BindingRecord {
127
123
  executionCount: this.executionCount,
128
124
  successRate: this.successRate,
129
125
  averageExecutionTime: this.averageExecutionTime,
130
- lastExecutedAt: this.lastExecutedAt
126
+ lastExecutedAt: this.lastExecutedAt,
131
127
  };
132
128
  }
133
129
  }
@@ -215,13 +211,13 @@ class AgentSkillBinding extends EventEmitter {
215
211
  this.agentLoad = new Map();
216
212
  this.bindings = new Map(); // Map<agentId, Map<skillId, BindingRecord>>
217
213
  this.matcher = new CapabilityMatcher();
218
-
214
+
219
215
  // Options
220
216
  this.options = {
221
217
  autoBinding: options.autoBinding !== false,
222
218
  minMatchScore: options.minMatchScore || 50,
223
219
  enableLoadBalancing: options.enableLoadBalancing !== false,
224
- affinityWeight: options.affinityWeight || 0.3
220
+ affinityWeight: options.affinityWeight || 0.3,
225
221
  };
226
222
 
227
223
  // Listen to skill registry events
@@ -238,9 +234,7 @@ class AgentSkillBinding extends EventEmitter {
238
234
  * Register an agent
239
235
  */
240
236
  registerAgent(agentDef) {
241
- const agent = agentDef instanceof AgentDefinition
242
- ? agentDef
243
- : new AgentDefinition(agentDef);
237
+ const agent = agentDef instanceof AgentDefinition ? agentDef : new AgentDefinition(agentDef);
244
238
 
245
239
  const validation = agent.validate();
246
240
  if (!validation.valid) {
@@ -262,7 +256,7 @@ class AgentSkillBinding extends EventEmitter {
262
256
  }
263
257
 
264
258
  this.emit('agent-registered', { agentId: agent.id, agent });
265
-
259
+
266
260
  return agent;
267
261
  }
268
262
 
@@ -280,7 +274,7 @@ class AgentSkillBinding extends EventEmitter {
280
274
  this.bindings.delete(agentId);
281
275
 
282
276
  this.emit('agent-unregistered', { agentId });
283
-
277
+
284
278
  return true;
285
279
  }
286
280
 
@@ -348,19 +342,19 @@ class AgentSkillBinding extends EventEmitter {
348
342
 
349
343
  // Check permissions
350
344
  if (skill.permissions && skill.permissions.length > 0) {
351
- const hasPermission = skill.permissions.every(
352
- p => agent.permissions.includes(p)
353
- );
345
+ const hasPermission = skill.permissions.every(p => agent.permissions.includes(p));
354
346
  if (!hasPermission) {
355
347
  throw new Error(`Agent '${agentId}' lacks required permissions for skill '${skillId}'`);
356
348
  }
357
349
  }
358
350
 
359
351
  // Calculate score
360
- const score = options.score || this.matcher.calculateScore(
361
- agent.capabilities,
362
- skill.tags // Use tags as capability requirements
363
- );
352
+ const score =
353
+ options.score ||
354
+ this.matcher.calculateScore(
355
+ agent.capabilities,
356
+ skill.tags // Use tags as capability requirements
357
+ );
364
358
 
365
359
  const record = new BindingRecord(agentId, skillId, { score });
366
360
  this.bindings.get(agentId).set(skillId, record);
@@ -405,7 +399,7 @@ class AgentSkillBinding extends EventEmitter {
405
399
  /**
406
400
  * Find best agent for a skill
407
401
  */
408
- findBestAgentForSkill(skillId, options = {}) {
402
+ findBestAgentForSkill(skillId, _options = {}) {
409
403
  const skill = this.skillRegistry?.getSkill(skillId);
410
404
  if (!skill) {
411
405
  return null;
@@ -427,9 +421,7 @@ class AgentSkillBinding extends EventEmitter {
427
421
 
428
422
  // Check permissions
429
423
  if (skill.permissions && skill.permissions.length > 0) {
430
- const hasPermission = skill.permissions.every(
431
- p => agent.permissions.includes(p)
432
- );
424
+ const hasPermission = skill.permissions.every(p => agent.permissions.includes(p));
433
425
  if (!hasPermission) {
434
426
  continue;
435
427
  }
@@ -454,7 +446,7 @@ class AgentSkillBinding extends EventEmitter {
454
446
  agent,
455
447
  binding,
456
448
  finalScore,
457
- load
449
+ load,
458
450
  });
459
451
  }
460
452
  }
@@ -487,7 +479,7 @@ class AgentSkillBinding extends EventEmitter {
487
479
  agent,
488
480
  score,
489
481
  status: this.agentStatus.get(agentId),
490
- load: this.agentLoad.get(agentId) || 0
482
+ load: this.agentLoad.get(agentId) || 0,
491
483
  });
492
484
  }
493
485
  }
@@ -516,7 +508,7 @@ class AgentSkillBinding extends EventEmitter {
516
508
  }
517
509
 
518
510
  this.emit('agent-acquired', { agentId, currentLoad: load + 1 });
519
-
511
+
520
512
  return true;
521
513
  }
522
514
 
@@ -541,7 +533,7 @@ class AgentSkillBinding extends EventEmitter {
541
533
  }
542
534
 
543
535
  this.emit('agent-released', { agentId, currentLoad: load - 1 });
544
-
536
+
545
537
  return true;
546
538
  }
547
539
 
@@ -578,7 +570,7 @@ class AgentSkillBinding extends EventEmitter {
578
570
  [AgentStatus.AVAILABLE]: 0,
579
571
  [AgentStatus.BUSY]: 0,
580
572
  [AgentStatus.OFFLINE]: 0,
581
- [AgentStatus.MAINTENANCE]: 0
573
+ [AgentStatus.MAINTENANCE]: 0,
582
574
  };
583
575
 
584
576
  let totalBindings = 0;
@@ -586,8 +578,8 @@ class AgentSkillBinding extends EventEmitter {
586
578
 
587
579
  for (const [agentId, status] of this.agentStatus) {
588
580
  statusCounts[status]++;
589
- totalBindings += (this.bindings.get(agentId)?.size || 0);
590
- totalLoad += (this.agentLoad.get(agentId) || 0);
581
+ totalBindings += this.bindings.get(agentId)?.size || 0;
582
+ totalLoad += this.agentLoad.get(agentId) || 0;
591
583
  }
592
584
 
593
585
  return {
@@ -595,7 +587,7 @@ class AgentSkillBinding extends EventEmitter {
595
587
  statusCounts,
596
588
  totalBindings,
597
589
  totalLoad,
598
- averageLoad: this.agents.size > 0 ? totalLoad / this.agents.size : 0
590
+ averageLoad: this.agents.size > 0 ? totalLoad / this.agents.size : 0,
599
591
  };
600
592
  }
601
593
 
@@ -651,5 +643,5 @@ module.exports = {
651
643
  AgentDefinition,
652
644
  BindingRecord,
653
645
  CapabilityMatcher,
654
- AgentStatus
646
+ AgentStatus,
655
647
  };