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.
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 +158 -146
  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 +241 -126
  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 +77 -81
  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 +48 -46
  87. package/src/monitoring/incident-manager.js +116 -106
  88. package/src/monitoring/index.js +144 -134
  89. package/src/monitoring/observability.js +75 -62
  90. package/src/monitoring/quality-dashboard.js +45 -41
  91. package/src/monitoring/release-manager.js +63 -53
  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,13 +1,13 @@
1
1
  /**
2
2
  * OpenAPI Parser
3
- *
3
+ *
4
4
  * Convert OpenAPI/Swagger specifications to MUSUBI requirements
5
5
  */
6
6
 
7
7
  'use strict';
8
8
 
9
9
  const fs = require('fs-extra');
10
- const path = require('path');
10
+ const _path = require('path');
11
11
  const yaml = require('js-yaml');
12
12
  const { createEmptyProjectIR, createEmptyFeatureIR } = require('../ir/types');
13
13
 
@@ -18,47 +18,47 @@ const { createEmptyProjectIR, createEmptyFeatureIR } = require('../ir/types');
18
18
  */
19
19
  async function parseOpenAPISpec(specPath) {
20
20
  const content = await fs.readFile(specPath, 'utf-8');
21
-
21
+
22
22
  let spec;
23
23
  if (specPath.endsWith('.yaml') || specPath.endsWith('.yml')) {
24
24
  spec = yaml.load(content);
25
25
  } else {
26
26
  spec = JSON.parse(content);
27
27
  }
28
-
28
+
29
29
  // Detect OpenAPI version
30
30
  const version = spec.openapi || spec.swagger;
31
31
  if (!version) {
32
32
  throw new Error('Not a valid OpenAPI/Swagger specification');
33
33
  }
34
-
34
+
35
35
  const ir = createEmptyProjectIR();
36
36
  ir.metadata.name = spec.info?.title || 'API Project';
37
37
  ir.metadata.description = spec.info?.description || '';
38
38
  ir.metadata.version = spec.info?.version || '1.0.0';
39
39
  ir.metadata.sourceFormat = 'openapi';
40
-
40
+
41
41
  // Group paths by tags
42
42
  const tagGroups = groupPathsByTag(spec.paths, spec.tags);
43
-
43
+
44
44
  // Convert each tag group to a feature
45
45
  for (const [tag, endpoints] of Object.entries(tagGroups)) {
46
46
  const feature = await createFeatureFromEndpoints(tag, endpoints, spec);
47
47
  ir.features.push(feature);
48
48
  }
49
-
49
+
50
50
  // If no tags, create a single feature
51
51
  if (ir.features.length === 0) {
52
52
  const feature = await createFeatureFromEndpoints('api', spec.paths, spec);
53
53
  ir.features.push(feature);
54
54
  }
55
-
55
+
56
56
  // Add security requirements
57
57
  if (spec.security || spec.securityDefinitions || spec.components?.securitySchemes) {
58
58
  const securityFeature = createSecurityFeature(spec);
59
59
  ir.features.push(securityFeature);
60
60
  }
61
-
61
+
62
62
  return ir;
63
63
  }
64
64
 
@@ -68,14 +68,14 @@ async function parseOpenAPISpec(specPath) {
68
68
  * @param {Array} tags - OpenAPI tags array
69
69
  * @returns {Object} Grouped paths
70
70
  */
71
- function groupPathsByTag(paths, tags = []) {
71
+ function groupPathsByTag(paths, _tags = []) {
72
72
  const groups = {};
73
-
73
+
74
74
  for (const [pathUrl, pathItem] of Object.entries(paths || {})) {
75
75
  for (const [method, operation] of Object.entries(pathItem)) {
76
76
  if (['get', 'post', 'put', 'patch', 'delete', 'head', 'options'].includes(method)) {
77
77
  const operationTags = operation.tags || ['default'];
78
-
78
+
79
79
  for (const tag of operationTags) {
80
80
  if (!groups[tag]) {
81
81
  groups[tag] = {};
@@ -88,7 +88,7 @@ function groupPathsByTag(paths, tags = []) {
88
88
  }
89
89
  }
90
90
  }
91
-
91
+
92
92
  return groups;
93
93
  }
94
94
 
@@ -102,13 +102,13 @@ function groupPathsByTag(paths, tags = []) {
102
102
  async function createFeatureFromEndpoints(tag, endpoints, spec) {
103
103
  const featureId = tag.toLowerCase().replace(/\s+/g, '-');
104
104
  const feature = createEmptyFeatureIR(featureId, tag);
105
-
105
+
106
106
  feature.specification.description = getTagDescription(spec.tags, tag);
107
107
  feature.design = [];
108
108
  feature.tests = [];
109
-
109
+
110
110
  let reqIndex = 1;
111
-
111
+
112
112
  for (const [pathUrl, pathItem] of Object.entries(endpoints)) {
113
113
  for (const [method, operation] of Object.entries(pathItem)) {
114
114
  if (['get', 'post', 'put', 'patch', 'delete', 'head', 'options'].includes(method)) {
@@ -121,7 +121,7 @@ async function createFeatureFromEndpoints(tag, endpoints, spec) {
121
121
  );
122
122
  feature.specification.requirements.push(requirement);
123
123
  reqIndex++;
124
-
124
+
125
125
  // Create design decision for each operation
126
126
  const decision = createDesignFromOperation(
127
127
  `ADR-${featureId.toUpperCase()}-${String(feature.design.length + 1).padStart(3, '0')}`,
@@ -130,14 +130,14 @@ async function createFeatureFromEndpoints(tag, endpoints, spec) {
130
130
  operation
131
131
  );
132
132
  feature.design.push(decision);
133
-
133
+
134
134
  // Create test case
135
135
  const testCase = createTestFromOperation(method, pathUrl, operation);
136
136
  feature.tests.push(testCase);
137
137
  }
138
138
  }
139
139
  }
140
-
140
+
141
141
  return feature;
142
142
  }
143
143
 
@@ -161,18 +161,19 @@ function getTagDescription(tags, tagName) {
161
161
  * @returns {Object} Requirement object
162
162
  */
163
163
  function createRequirementFromOperation(id, method, path, operation) {
164
- const methodVerb = {
165
- get: 'retrieves',
166
- post: 'creates',
167
- put: 'updates',
168
- patch: 'partially updates',
169
- delete: 'deletes',
170
- head: 'checks',
171
- options: 'returns options for',
172
- }[method.toLowerCase()] || method;
173
-
164
+ const methodVerb =
165
+ {
166
+ get: 'retrieves',
167
+ post: 'creates',
168
+ put: 'updates',
169
+ patch: 'partially updates',
170
+ delete: 'deletes',
171
+ head: 'checks',
172
+ options: 'returns options for',
173
+ }[method.toLowerCase()] || method;
174
+
174
175
  const summary = operation.summary || operation.operationId || `${method.toUpperCase()} ${path}`;
175
-
176
+
176
177
  // Generate EARS pattern based on method
177
178
  let earsStatement;
178
179
  if (operation.security?.length > 0) {
@@ -182,7 +183,7 @@ function createRequirementFromOperation(id, method, path, operation) {
182
183
  // Ubiquitous
183
184
  earsStatement = `The system shall provide a ${method.toUpperCase()} ${path} endpoint that ${methodVerb} ${getResourceFromPath(path)}.`;
184
185
  }
185
-
186
+
186
187
  return {
187
188
  id,
188
189
  type: 'functional',
@@ -222,26 +223,34 @@ function getResourceFromPath(path) {
222
223
  */
223
224
  function generateAcceptanceCriteria(method, path, operation) {
224
225
  const criteria = [];
225
-
226
+
226
227
  // Add response status criteria
227
228
  for (const [status, response] of Object.entries(operation.responses || {})) {
228
229
  if (status === '200' || status === '201') {
229
- criteria.push(`Given valid request, When ${method.toUpperCase()} ${path}, Then return ${status} with ${response.description || 'success response'}`);
230
+ criteria.push(
231
+ `Given valid request, When ${method.toUpperCase()} ${path}, Then return ${status} with ${response.description || 'success response'}`
232
+ );
230
233
  } else if (status.startsWith('4')) {
231
- criteria.push(`Given invalid request, When ${method.toUpperCase()} ${path}, Then return ${status} with error details`);
234
+ criteria.push(
235
+ `Given invalid request, When ${method.toUpperCase()} ${path}, Then return ${status} with error details`
236
+ );
232
237
  }
233
238
  }
234
-
239
+
235
240
  // Add parameter validation criteria
236
241
  if (operation.parameters?.some(p => p.required)) {
237
- criteria.push(`Given missing required parameters, When ${method.toUpperCase()} ${path}, Then return 400 Bad Request`);
242
+ criteria.push(
243
+ `Given missing required parameters, When ${method.toUpperCase()} ${path}, Then return 400 Bad Request`
244
+ );
238
245
  }
239
-
246
+
240
247
  // Add security criteria
241
248
  if (operation.security?.length > 0) {
242
- criteria.push(`Given unauthenticated request, When ${method.toUpperCase()} ${path}, Then return 401 Unauthorized`);
249
+ criteria.push(
250
+ `Given unauthenticated request, When ${method.toUpperCase()} ${path}, Then return 401 Unauthorized`
251
+ );
243
252
  }
244
-
253
+
245
254
  return criteria;
246
255
  }
247
256
 
@@ -293,16 +302,24 @@ function createTestFromOperation(method, path, operation) {
293
302
  status: Object.keys(operation.responses || {})[0] || '200',
294
303
  description: operation.responses?.['200']?.description || 'Should succeed',
295
304
  },
296
- ...(operation.responses?.['400'] ? [{
297
- name: 'Invalid request',
298
- status: '400',
299
- description: operation.responses['400'].description,
300
- }] : []),
301
- ...(operation.security?.length > 0 ? [{
302
- name: 'Unauthorized',
303
- status: '401',
304
- description: 'Should reject unauthenticated request',
305
- }] : []),
305
+ ...(operation.responses?.['400']
306
+ ? [
307
+ {
308
+ name: 'Invalid request',
309
+ status: '400',
310
+ description: operation.responses['400'].description,
311
+ },
312
+ ]
313
+ : []),
314
+ ...(operation.security?.length > 0
315
+ ? [
316
+ {
317
+ name: 'Unauthorized',
318
+ status: '401',
319
+ description: 'Should reject unauthenticated request',
320
+ },
321
+ ]
322
+ : []),
306
323
  ],
307
324
  };
308
325
  }
@@ -315,9 +332,9 @@ function createTestFromOperation(method, path, operation) {
315
332
  function createSecurityFeature(spec) {
316
333
  const feature = createEmptyFeatureIR('security', 'Security');
317
334
  feature.specification.description = 'API Security Requirements';
318
-
335
+
319
336
  const schemes = spec.components?.securitySchemes || spec.securityDefinitions || {};
320
-
337
+
321
338
  let reqIndex = 1;
322
339
  for (const [name, scheme] of Object.entries(schemes)) {
323
340
  const requirement = {
@@ -337,7 +354,7 @@ function createSecurityFeature(spec) {
337
354
  feature.specification.requirements.push(requirement);
338
355
  reqIndex++;
339
356
  }
340
-
357
+
341
358
  return feature;
342
359
  }
343
360