@sk8metal/michi-cli 0.0.9 → 0.1.0

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 (371) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +235 -57
  3. package/dist/scripts/__tests__/create-project.test.js +24 -28
  4. package/dist/scripts/__tests__/create-project.test.js.map +1 -1
  5. package/dist/scripts/__tests__/jira-transitions.test.d.ts +5 -0
  6. package/dist/scripts/__tests__/jira-transitions.test.d.ts.map +1 -0
  7. package/dist/scripts/__tests__/jira-transitions.test.js +172 -0
  8. package/dist/scripts/__tests__/jira-transitions.test.js.map +1 -0
  9. package/dist/scripts/__tests__/multi-project-estimate.test.js +14 -15
  10. package/dist/scripts/__tests__/multi-project-estimate.test.js.map +1 -1
  11. package/dist/scripts/__tests__/setup-existing-project.test.js +79 -0
  12. package/dist/scripts/__tests__/setup-existing-project.test.js.map +1 -1
  13. package/dist/scripts/__tests__/setup-interactive.test.js +23 -17
  14. package/dist/scripts/__tests__/setup-interactive.test.js.map +1 -1
  15. package/dist/scripts/__tests__/spec-impl-workflow.test.d.ts +5 -0
  16. package/dist/scripts/__tests__/spec-impl-workflow.test.d.ts.map +1 -0
  17. package/dist/scripts/__tests__/spec-impl-workflow.test.js +321 -0
  18. package/dist/scripts/__tests__/spec-impl-workflow.test.js.map +1 -0
  19. package/dist/scripts/__tests__/spec-loader.test.d.ts +5 -0
  20. package/dist/scripts/__tests__/spec-loader.test.d.ts.map +1 -0
  21. package/dist/scripts/__tests__/spec-loader.test.js +153 -0
  22. package/dist/scripts/__tests__/spec-loader.test.js.map +1 -0
  23. package/dist/scripts/__tests__/validate-phase.test.js +26 -22
  24. package/dist/scripts/__tests__/validate-phase.test.js.map +1 -1
  25. package/dist/scripts/config/config-schema.d.ts +17 -0
  26. package/dist/scripts/config/config-schema.d.ts.map +1 -1
  27. package/dist/scripts/config/config-schema.js +55 -26
  28. package/dist/scripts/config/config-schema.js.map +1 -1
  29. package/dist/scripts/config-interactive.d.ts.map +1 -1
  30. package/dist/scripts/config-interactive.js +53 -38
  31. package/dist/scripts/config-interactive.js.map +1 -1
  32. package/dist/scripts/confluence-sync.d.ts.map +1 -1
  33. package/dist/scripts/confluence-sync.js +0 -11
  34. package/dist/scripts/confluence-sync.js.map +1 -1
  35. package/dist/scripts/constants/__tests__/environments.test.js +39 -5
  36. package/dist/scripts/constants/__tests__/environments.test.js.map +1 -1
  37. package/dist/scripts/constants/environments.d.ts +1 -1
  38. package/dist/scripts/constants/environments.d.ts.map +1 -1
  39. package/dist/scripts/constants/environments.js +22 -7
  40. package/dist/scripts/constants/environments.js.map +1 -1
  41. package/dist/scripts/constants/test-commands.d.ts +36 -0
  42. package/dist/scripts/constants/test-commands.d.ts.map +1 -0
  43. package/dist/scripts/constants/test-commands.js +70 -0
  44. package/dist/scripts/constants/test-commands.js.map +1 -0
  45. package/dist/scripts/jira-sync.d.ts +89 -3
  46. package/dist/scripts/jira-sync.d.ts.map +1 -1
  47. package/dist/scripts/jira-sync.js +366 -96
  48. package/dist/scripts/jira-sync.js.map +1 -1
  49. package/dist/scripts/markdown-to-confluence.js +1 -1
  50. package/dist/scripts/markdown-to-confluence.js.map +1 -1
  51. package/dist/scripts/phase-runner.d.ts +1 -1
  52. package/dist/scripts/phase-runner.d.ts.map +1 -1
  53. package/dist/scripts/phase-runner.js +809 -13
  54. package/dist/scripts/phase-runner.js.map +1 -1
  55. package/dist/scripts/pr-automation.d.ts.map +1 -1
  56. package/dist/scripts/pr-automation.js.map +1 -1
  57. package/dist/scripts/pre-flight-check.js +1 -1
  58. package/dist/scripts/pre-flight-check.js.map +1 -1
  59. package/dist/scripts/setup-existing-project.js +61 -29
  60. package/dist/scripts/setup-existing-project.js.map +1 -1
  61. package/dist/scripts/setup-interactive.js +3 -3
  62. package/dist/scripts/setup-interactive.js.map +1 -1
  63. package/dist/scripts/spec-impl-workflow.d.ts +94 -0
  64. package/dist/scripts/spec-impl-workflow.d.ts.map +1 -0
  65. package/dist/scripts/spec-impl-workflow.js +354 -0
  66. package/dist/scripts/spec-impl-workflow.js.map +1 -0
  67. package/dist/scripts/template/__tests__/renderer.test.js.map +1 -1
  68. package/dist/scripts/test-execution-generator.d.ts +52 -0
  69. package/dist/scripts/test-execution-generator.d.ts.map +1 -0
  70. package/dist/scripts/test-execution-generator.js +576 -0
  71. package/dist/scripts/test-execution-generator.js.map +1 -0
  72. package/dist/scripts/test-interactive.d.ts +10 -0
  73. package/dist/scripts/test-interactive.d.ts.map +1 -0
  74. package/dist/scripts/test-interactive.js +627 -0
  75. package/dist/scripts/test-interactive.js.map +1 -0
  76. package/dist/scripts/test-new-features.d.ts +5 -0
  77. package/dist/scripts/test-new-features.d.ts.map +1 -0
  78. package/dist/scripts/test-new-features.js +145 -0
  79. package/dist/scripts/test-new-features.js.map +1 -0
  80. package/dist/scripts/test-spec-generator.d.ts +29 -0
  81. package/dist/scripts/test-spec-generator.d.ts.map +1 -0
  82. package/dist/scripts/test-spec-generator.js +494 -0
  83. package/dist/scripts/test-spec-generator.js.map +1 -0
  84. package/dist/scripts/test-workflow-stages.d.ts +6 -0
  85. package/dist/scripts/test-workflow-stages.d.ts.map +1 -0
  86. package/dist/scripts/test-workflow-stages.js +43 -0
  87. package/dist/scripts/test-workflow-stages.js.map +1 -0
  88. package/dist/scripts/utils/__tests__/aidlc-parser.test.d.ts +5 -0
  89. package/dist/scripts/utils/__tests__/aidlc-parser.test.d.ts.map +1 -0
  90. package/dist/scripts/utils/__tests__/aidlc-parser.test.js +315 -0
  91. package/dist/scripts/utils/__tests__/aidlc-parser.test.js.map +1 -0
  92. package/dist/scripts/utils/__tests__/business-days.test.d.ts +5 -0
  93. package/dist/scripts/utils/__tests__/business-days.test.d.ts.map +1 -0
  94. package/dist/scripts/utils/__tests__/business-days.test.js +171 -0
  95. package/dist/scripts/utils/__tests__/business-days.test.js.map +1 -0
  96. package/dist/scripts/utils/__tests__/config-loader.test.js +1 -1
  97. package/dist/scripts/utils/__tests__/config-loader.test.js.map +1 -1
  98. package/dist/scripts/utils/__tests__/config-validator.test.js +164 -35
  99. package/dist/scripts/utils/__tests__/config-validator.test.js.map +1 -1
  100. package/dist/scripts/utils/__tests__/env-config.test.d.ts +5 -0
  101. package/dist/scripts/utils/__tests__/env-config.test.d.ts.map +1 -0
  102. package/dist/scripts/utils/__tests__/env-config.test.js +218 -0
  103. package/dist/scripts/utils/__tests__/env-config.test.js.map +1 -0
  104. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.d.ts +5 -0
  105. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.d.ts.map +1 -0
  106. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.js +202 -0
  107. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.js.map +1 -0
  108. package/dist/scripts/utils/__tests__/tasks-converter.test.d.ts +5 -0
  109. package/dist/scripts/utils/__tests__/tasks-converter.test.d.ts.map +1 -0
  110. package/dist/scripts/utils/__tests__/tasks-converter.test.js +500 -0
  111. package/dist/scripts/utils/__tests__/tasks-converter.test.js.map +1 -0
  112. package/dist/scripts/utils/__tests__/tasks-format-validator.test.d.ts +5 -0
  113. package/dist/scripts/utils/__tests__/tasks-format-validator.test.d.ts.map +1 -0
  114. package/dist/scripts/utils/__tests__/tasks-format-validator.test.js +314 -0
  115. package/dist/scripts/utils/__tests__/tasks-format-validator.test.js.map +1 -0
  116. package/dist/scripts/utils/__tests__/test-runner.test.d.ts +5 -0
  117. package/dist/scripts/utils/__tests__/test-runner.test.d.ts.map +1 -0
  118. package/dist/scripts/utils/__tests__/test-runner.test.js +64 -0
  119. package/dist/scripts/utils/__tests__/test-runner.test.js.map +1 -0
  120. package/dist/scripts/utils/aidlc-parser.d.ts +86 -0
  121. package/dist/scripts/utils/aidlc-parser.d.ts.map +1 -0
  122. package/dist/scripts/utils/aidlc-parser.js +208 -0
  123. package/dist/scripts/utils/aidlc-parser.js.map +1 -0
  124. package/dist/scripts/utils/business-days.d.ts +52 -0
  125. package/dist/scripts/utils/business-days.d.ts.map +1 -0
  126. package/dist/scripts/utils/business-days.js +98 -0
  127. package/dist/scripts/utils/business-days.js.map +1 -0
  128. package/dist/scripts/utils/ci-generator.d.ts +14 -0
  129. package/dist/scripts/utils/ci-generator.d.ts.map +1 -0
  130. package/dist/scripts/utils/ci-generator.js +61 -0
  131. package/dist/scripts/utils/ci-generator.js.map +1 -0
  132. package/dist/scripts/utils/config-loader.js +2 -2
  133. package/dist/scripts/utils/config-loader.js.map +1 -1
  134. package/dist/scripts/utils/config-validator.d.ts +7 -1
  135. package/dist/scripts/utils/config-validator.d.ts.map +1 -1
  136. package/dist/scripts/utils/config-validator.js +136 -23
  137. package/dist/scripts/utils/config-validator.js.map +1 -1
  138. package/dist/scripts/utils/confluence-approval.d.ts +46 -0
  139. package/dist/scripts/utils/confluence-approval.d.ts.map +1 -0
  140. package/dist/scripts/utils/confluence-approval.js +118 -0
  141. package/dist/scripts/utils/confluence-approval.js.map +1 -0
  142. package/dist/scripts/utils/confluence-hierarchy.d.ts.map +1 -1
  143. package/dist/scripts/utils/confluence-hierarchy.js +1 -1
  144. package/dist/scripts/utils/confluence-hierarchy.js.map +1 -1
  145. package/dist/scripts/utils/docker-generator.d.ts +9 -0
  146. package/dist/scripts/utils/docker-generator.d.ts.map +1 -0
  147. package/dist/scripts/utils/docker-generator.js +132 -0
  148. package/dist/scripts/utils/docker-generator.js.map +1 -0
  149. package/dist/scripts/utils/docker-requirement-detector.d.ts +15 -0
  150. package/dist/scripts/utils/docker-requirement-detector.d.ts.map +1 -0
  151. package/dist/scripts/utils/docker-requirement-detector.js +124 -0
  152. package/dist/scripts/utils/docker-requirement-detector.js.map +1 -0
  153. package/dist/scripts/utils/env-config.d.ts +54 -0
  154. package/dist/scripts/utils/env-config.d.ts.map +1 -0
  155. package/dist/scripts/utils/env-config.js +414 -0
  156. package/dist/scripts/utils/env-config.js.map +1 -0
  157. package/dist/scripts/utils/jira-issue-type-fetcher.d.ts +70 -0
  158. package/dist/scripts/utils/jira-issue-type-fetcher.d.ts.map +1 -0
  159. package/dist/scripts/utils/jira-issue-type-fetcher.js +147 -0
  160. package/dist/scripts/utils/jira-issue-type-fetcher.js.map +1 -0
  161. package/dist/scripts/utils/language-detector.d.ts +14 -0
  162. package/dist/scripts/utils/language-detector.d.ts.map +1 -0
  163. package/dist/scripts/utils/language-detector.js +119 -0
  164. package/dist/scripts/utils/language-detector.js.map +1 -0
  165. package/dist/scripts/utils/markdown-parser.d.ts +55 -0
  166. package/dist/scripts/utils/markdown-parser.d.ts.map +1 -0
  167. package/dist/scripts/utils/markdown-parser.js +289 -0
  168. package/dist/scripts/utils/markdown-parser.js.map +1 -0
  169. package/dist/scripts/utils/project-detector.d.ts +17 -0
  170. package/dist/scripts/utils/project-detector.d.ts.map +1 -0
  171. package/dist/scripts/utils/project-detector.js +166 -0
  172. package/dist/scripts/utils/project-detector.js.map +1 -0
  173. package/dist/scripts/utils/project-finder.js +2 -2
  174. package/dist/scripts/utils/project-finder.js.map +1 -1
  175. package/dist/scripts/utils/release-notes-generator.d.ts +56 -0
  176. package/dist/scripts/utils/release-notes-generator.d.ts.map +1 -0
  177. package/dist/scripts/utils/release-notes-generator.js +162 -0
  178. package/dist/scripts/utils/release-notes-generator.js.map +1 -0
  179. package/dist/scripts/utils/spec-loader.d.ts +79 -0
  180. package/dist/scripts/utils/spec-loader.d.ts.map +1 -0
  181. package/dist/scripts/utils/spec-loader.js +80 -0
  182. package/dist/scripts/utils/spec-loader.js.map +1 -0
  183. package/dist/scripts/utils/spec-updater.d.ts +7 -0
  184. package/dist/scripts/utils/spec-updater.d.ts.map +1 -1
  185. package/dist/scripts/utils/spec-updater.js.map +1 -1
  186. package/dist/scripts/utils/tasks-converter.d.ts +57 -0
  187. package/dist/scripts/utils/tasks-converter.d.ts.map +1 -0
  188. package/dist/scripts/utils/tasks-converter.js +322 -0
  189. package/dist/scripts/utils/tasks-converter.js.map +1 -0
  190. package/dist/scripts/utils/tasks-format-validator.d.ts +36 -0
  191. package/dist/scripts/utils/tasks-format-validator.d.ts.map +1 -0
  192. package/dist/scripts/utils/tasks-format-validator.js +158 -0
  193. package/dist/scripts/utils/tasks-format-validator.js.map +1 -0
  194. package/dist/scripts/utils/template-applier.d.ts +37 -0
  195. package/dist/scripts/utils/template-applier.d.ts.map +1 -0
  196. package/dist/scripts/utils/template-applier.js +129 -0
  197. package/dist/scripts/utils/template-applier.js.map +1 -0
  198. package/dist/scripts/utils/test-config-generator.d.ts +12 -0
  199. package/dist/scripts/utils/test-config-generator.d.ts.map +1 -0
  200. package/dist/scripts/utils/test-config-generator.js +185 -0
  201. package/dist/scripts/utils/test-config-generator.js.map +1 -0
  202. package/dist/scripts/utils/test-runner.d.ts +31 -0
  203. package/dist/scripts/utils/test-runner.d.ts.map +1 -0
  204. package/dist/scripts/utils/test-runner.js +103 -0
  205. package/dist/scripts/utils/test-runner.js.map +1 -0
  206. package/dist/scripts/validate-phase.d.ts +1 -1
  207. package/dist/scripts/validate-phase.d.ts.map +1 -1
  208. package/dist/scripts/validate-phase.js +153 -5
  209. package/dist/scripts/validate-phase.js.map +1 -1
  210. package/dist/scripts/workflow-orchestrator.d.ts +8 -0
  211. package/dist/scripts/workflow-orchestrator.d.ts.map +1 -1
  212. package/dist/scripts/workflow-orchestrator.js +108 -7
  213. package/dist/scripts/workflow-orchestrator.js.map +1 -1
  214. package/dist/src/__tests__/integration/internationalization.test.d.ts +8 -0
  215. package/dist/src/__tests__/integration/internationalization.test.d.ts.map +1 -0
  216. package/dist/src/__tests__/integration/internationalization.test.js +333 -0
  217. package/dist/src/__tests__/integration/internationalization.test.js.map +1 -0
  218. package/dist/src/__tests__/integration/setup/claude-agent.test.d.ts +1 -1
  219. package/dist/src/__tests__/integration/setup/claude-agent.test.js +17 -20
  220. package/dist/src/__tests__/integration/setup/claude-agent.test.js.map +1 -1
  221. package/dist/src/__tests__/integration/setup/cursor.test.js +23 -19
  222. package/dist/src/__tests__/integration/setup/cursor.test.js.map +1 -1
  223. package/dist/src/__tests__/integration/setup/validation.test.js +41 -58
  224. package/dist/src/__tests__/integration/setup/validation.test.js.map +1 -1
  225. package/dist/src/cli.d.ts.map +1 -1
  226. package/dist/src/cli.js +208 -18
  227. package/dist/src/cli.js.map +1 -1
  228. package/dist/src/commands/setup-existing.d.ts +3 -0
  229. package/dist/src/commands/setup-existing.d.ts.map +1 -1
  230. package/dist/src/commands/setup-existing.js +334 -47
  231. package/dist/src/commands/setup-existing.js.map +1 -1
  232. package/docs/README.md +3 -1
  233. package/docs/context.md +59 -0
  234. package/docs/design-issue-55.md +240 -0
  235. package/docs/design-issue-56.md +181 -0
  236. package/docs/michi-development/testing/manual-verification-flow.md +2242 -0
  237. package/docs/michi-development/testing/pre-publish-checklist.md +560 -0
  238. package/docs/plan.md +275 -0
  239. package/docs/user-guide/getting-started/github-token-setup.md +509 -0
  240. package/docs/{getting-started → user-guide/getting-started}/quick-start.md +16 -0
  241. package/docs/{getting-started → user-guide/getting-started}/setup.md +28 -1
  242. package/docs/user-guide/guides/internationalization.md +540 -0
  243. package/docs/{guides → user-guide/guides}/multi-project.md +1 -1
  244. package/docs/{guides → user-guide/guides}/phase-automation.md +67 -9
  245. package/docs/user-guide/guides/workflow.md +582 -0
  246. package/docs/user-guide/hands-on/README.md +142 -0
  247. package/docs/user-guide/hands-on/claude-agent-setup.md +455 -0
  248. package/docs/user-guide/hands-on/claude-setup.md +398 -0
  249. package/docs/user-guide/hands-on/cursor-setup.md +352 -0
  250. package/docs/user-guide/hands-on/troubleshooting.md +964 -0
  251. package/docs/user-guide/hands-on/verification-checklist.md +438 -0
  252. package/docs/user-guide/hands-on/workflow-walkthrough.md +906 -0
  253. package/docs/user-guide/reference/config.md +564 -0
  254. package/docs/{reference → user-guide/reference}/quick-reference.md +53 -40
  255. package/docs/user-guide/release/ci-setup.md +541 -0
  256. package/docs/user-guide/release/release-flow.md +476 -0
  257. package/docs/user-guide/templates/test-specs/README.md +173 -0
  258. package/docs/user-guide/templates/test-specs/e2e-test-spec-template.md +547 -0
  259. package/docs/user-guide/templates/test-specs/integration-test-spec-template.md +435 -0
  260. package/docs/user-guide/templates/test-specs/performance-test-spec-template.md +454 -0
  261. package/docs/user-guide/templates/test-specs/security-test-spec-template.md +664 -0
  262. package/docs/user-guide/templates/test-specs/unit-test-spec-template.md +328 -0
  263. package/docs/{testing → user-guide/testing}/integration-tests.md +24 -9
  264. package/docs/user-guide/testing/tdd-cycle.md +349 -0
  265. package/docs/user-guide/testing/test-execution-flow.md +396 -0
  266. package/docs/user-guide/testing/test-failure-handling.md +521 -0
  267. package/docs/user-guide/testing/test-planning-flow.md +181 -0
  268. package/docs/user-guide/testing-strategy.md +185 -0
  269. package/docs/verification-guide.md +518 -0
  270. package/package.json +7 -2
  271. package/scripts/__tests__/create-project.test.ts +67 -49
  272. package/scripts/__tests__/jira-transitions.test.ts +225 -0
  273. package/scripts/__tests__/multi-project-estimate.test.ts +36 -30
  274. package/scripts/__tests__/setup-existing-project.test.ts +98 -1
  275. package/scripts/__tests__/setup-interactive.test.ts +52 -46
  276. package/scripts/__tests__/spec-impl-workflow.test.ts +429 -0
  277. package/scripts/__tests__/spec-loader.test.ts +199 -0
  278. package/scripts/__tests__/validate-phase.test.ts +78 -54
  279. package/scripts/config/config-schema.ts +89 -50
  280. package/scripts/config-interactive.ts +191 -136
  281. package/scripts/confluence-sync.ts +0 -12
  282. package/scripts/constants/__tests__/environments.test.ts +42 -6
  283. package/scripts/constants/environments.ts +33 -13
  284. package/scripts/constants/test-commands.ts +96 -0
  285. package/scripts/jira-sync.ts +767 -232
  286. package/scripts/markdown-to-confluence.ts +1 -1
  287. package/scripts/phase-runner.ts +1056 -63
  288. package/scripts/pr-automation.ts +0 -1
  289. package/scripts/pre-flight-check.ts +1 -1
  290. package/scripts/pre-publish-check.sh +311 -0
  291. package/scripts/quick-verify.sh +115 -0
  292. package/scripts/setup-existing-project.ts +201 -117
  293. package/scripts/setup-interactive.ts +4 -4
  294. package/scripts/spec-impl-workflow.ts +505 -0
  295. package/scripts/template/__tests__/renderer.test.ts +1 -2
  296. package/scripts/test-execution-generator.ts +695 -0
  297. package/scripts/test-interactive.ts +779 -0
  298. package/scripts/test-new-features.ts +168 -0
  299. package/scripts/test-npm-package.sh +345 -0
  300. package/scripts/test-spec-generator.ts +574 -0
  301. package/scripts/test-workflow-stages.ts +53 -0
  302. package/scripts/utils/__tests__/aidlc-parser.test.ts +349 -0
  303. package/scripts/utils/__tests__/business-days.test.ts +214 -0
  304. package/scripts/utils/__tests__/config-loader.test.ts +1 -1
  305. package/scripts/utils/__tests__/config-validator.test.ts +309 -88
  306. package/scripts/utils/__tests__/env-config.test.ts +259 -0
  307. package/scripts/utils/__tests__/jira-issue-type-fetcher.test.ts +272 -0
  308. package/scripts/utils/__tests__/tasks-converter.test.ts +582 -0
  309. package/scripts/utils/__tests__/tasks-format-validator.test.ts +338 -0
  310. package/scripts/utils/__tests__/test-runner.test.ts +77 -0
  311. package/scripts/utils/aidlc-parser.ts +289 -0
  312. package/scripts/utils/business-days.ts +115 -0
  313. package/scripts/utils/ci-generator.ts +84 -0
  314. package/scripts/utils/config-loader.ts +2 -2
  315. package/scripts/utils/config-validator.ts +304 -117
  316. package/scripts/utils/confluence-approval.ts +167 -0
  317. package/scripts/utils/confluence-hierarchy.ts +2 -4
  318. package/scripts/utils/docker-generator.ts +151 -0
  319. package/scripts/utils/docker-requirement-detector.ts +153 -0
  320. package/scripts/utils/env-config.ts +526 -0
  321. package/scripts/utils/jira-issue-type-fetcher.ts +199 -0
  322. package/scripts/utils/language-detector.ts +139 -0
  323. package/scripts/utils/markdown-parser.ts +376 -0
  324. package/scripts/utils/project-detector.ts +192 -0
  325. package/scripts/utils/project-finder.ts +2 -2
  326. package/scripts/utils/release-notes-generator.ts +210 -0
  327. package/scripts/utils/spec-loader.ts +125 -0
  328. package/scripts/utils/spec-updater.ts +8 -1
  329. package/scripts/utils/tasks-converter.ts +601 -0
  330. package/scripts/utils/tasks-format-validator.ts +193 -0
  331. package/scripts/utils/template-applier.ts +202 -0
  332. package/scripts/utils/test-config-generator.ts +210 -0
  333. package/scripts/utils/test-runner.ts +133 -0
  334. package/scripts/validate-phase.ts +186 -9
  335. package/scripts/workflow-orchestrator.ts +130 -12
  336. package/templates/ci/github-actions/java.yml +54 -0
  337. package/templates/ci/github-actions/nodejs.yml +46 -0
  338. package/templates/ci/github-actions/php.yml +52 -0
  339. package/templates/ci/screwdriver/java.yaml +17 -0
  340. package/templates/ci/screwdriver/nodejs.yaml +17 -0
  341. package/templates/ci/screwdriver/php.yaml +20 -0
  342. package/templates/claude/commands/kiro/kiro-spec-impl.md +244 -0
  343. package/templates/claude/commands/kiro/kiro-spec-tasks.md +354 -0
  344. package/templates/claude-agent/README.md +7 -1
  345. package/templates/claude-agent/agents/.gitkeep +0 -0
  346. package/templates/claude-agent/agents/designer.md +79 -0
  347. package/templates/claude-agent/agents/developer.md +68 -0
  348. package/templates/claude-agent/agents/manager-agent.md +59 -0
  349. package/templates/claude-agent/agents/tester.md +101 -0
  350. package/templates/claude-agent/commands/kiro/.gitkeep +0 -0
  351. package/templates/claude-agent/commands/kiro/kiro-spec-impl.md +244 -0
  352. package/templates/claude-agent/commands/kiro/kiro-spec-tasks.md +354 -0
  353. package/templates/cline/rules/atlassian-integration.md +36 -0
  354. package/templates/cline/rules/michi-core.md +56 -0
  355. package/templates/codex/AGENTS.override.md +277 -0
  356. package/templates/codex/prompts/confluence-sync.md +177 -0
  357. package/templates/codex/rules/README.md +210 -0
  358. package/templates/common/.kiro/project.json.template +21 -0
  359. package/templates/cursor/commands/kiro/kiro-spec-impl.md +244 -0
  360. package/templates/cursor/commands/kiro/kiro-spec-tasks.md +354 -0
  361. package/templates/gemini/commands/README.md +41 -0
  362. package/templates/gemini/rules/GEMINI.md +80 -0
  363. package/docs/guides/workflow.md +0 -342
  364. package/docs/reference/config.md +0 -545
  365. package/scripts/setup-existing.sh +0 -279
  366. /package/docs/{contributing → michi-development/contributing}/development.md +0 -0
  367. /package/docs/{contributing → michi-development/contributing}/release.md +0 -0
  368. /package/docs/{testing-strategy.md → michi-development/testing-strategy.md} +0 -0
  369. /package/docs/{getting-started → user-guide/getting-started}/new-repository-setup.md +0 -0
  370. /package/docs/{guides → user-guide/guides}/customization.md +0 -0
  371. /package/docs/{reference → user-guide/reference}/tasks-template.md +0 -0
@@ -0,0 +1,199 @@
1
+ /**
2
+ * JIRA Issue Types取得ユーティリティ
3
+ *
4
+ * JIRA APIからプロジェクトのIssue Typesを取得する機能を提供
5
+ */
6
+
7
+ import axios from 'axios';
8
+
9
+ /**
10
+ * Issue Type情報
11
+ */
12
+ export interface IssueTypeInfo {
13
+ id: string;
14
+ name: string;
15
+ description?: string;
16
+ iconUrl?: string;
17
+ subtask?: boolean;
18
+ }
19
+
20
+ /**
21
+ * JIRA認証情報
22
+ */
23
+ export interface JIRACredentials {
24
+ url: string;
25
+ email: string;
26
+ apiToken: string;
27
+ }
28
+
29
+ /**
30
+ * 認証情報が設定されているかチェック
31
+ */
32
+ export function hasJiraCredentials(): boolean {
33
+ return !!(
34
+ process.env.ATLASSIAN_URL &&
35
+ process.env.ATLASSIAN_EMAIL &&
36
+ process.env.ATLASSIAN_API_TOKEN
37
+ );
38
+ }
39
+
40
+ /**
41
+ * 環境変数からJIRA認証情報を取得
42
+ */
43
+ export function getJiraCredentials(): JIRACredentials | null {
44
+ const url = process.env.ATLASSIAN_URL;
45
+ const email = process.env.ATLASSIAN_EMAIL;
46
+ const apiToken = process.env.ATLASSIAN_API_TOKEN;
47
+
48
+ if (!url || !email || !apiToken) {
49
+ return null;
50
+ }
51
+
52
+ return { url, email, apiToken };
53
+ }
54
+
55
+ /**
56
+ * リクエスト間の待機時間(ミリ秒)
57
+ * 環境変数 ATLASSIAN_REQUEST_DELAY で調整可能(デフォルト: 500ms)
58
+ */
59
+ function getRequestDelay(): number {
60
+ return parseInt(process.env.ATLASSIAN_REQUEST_DELAY || '500', 10);
61
+ }
62
+
63
+ /**
64
+ * リクエスト間のスリープ処理(レートリミット対策)
65
+ */
66
+ function sleep(ms: number): Promise<void> {
67
+ return new Promise(resolve => setTimeout(resolve, ms));
68
+ }
69
+
70
+ /**
71
+ * JIRA APIからプロジェクトのIssue Typesを取得
72
+ *
73
+ * @param projectKey プロジェクトキー(例: "PC")
74
+ * @param credentials JIRA認証情報(省略時は環境変数から取得)
75
+ * @returns Issue Typesのリスト、取得失敗時はnull
76
+ */
77
+ export async function getProjectIssueTypes(
78
+ projectKey: string,
79
+ credentials?: JIRACredentials
80
+ ): Promise<IssueTypeInfo[] | null> {
81
+ const creds = credentials || getJiraCredentials();
82
+
83
+ if (!creds) {
84
+ return null;
85
+ }
86
+
87
+ const baseUrl = `${creds.url}/rest/api/3`;
88
+ const auth = Buffer.from(`${creds.email}:${creds.apiToken}`).toString('base64');
89
+
90
+ // レートリミット対策: リクエスト前に待機
91
+ await sleep(getRequestDelay());
92
+
93
+ try {
94
+ const response = await axios.get(`${baseUrl}/project/${projectKey}`, {
95
+ headers: {
96
+ 'Authorization': `Basic ${auth}`,
97
+ 'Content-Type': 'application/json'
98
+ },
99
+ timeout: 10000 // 10秒タイムアウト
100
+ });
101
+
102
+ const issueTypes = response.data.issueTypes || [];
103
+
104
+ return issueTypes.map((it: any) => ({
105
+ id: it.id,
106
+ name: it.name,
107
+ description: it.description || undefined,
108
+ iconUrl: it.iconUrl || undefined,
109
+ subtask: it.subtask || false
110
+ }));
111
+ } catch (error: any) {
112
+ // エラーをログに記録(デバッグ用)
113
+ if (error.response) {
114
+ // HTTPエラー(4xx, 5xx)
115
+ const status = error.response.status;
116
+ const statusText = error.response.statusText;
117
+
118
+ if (status === 401) {
119
+ console.error('❌ JIRA認証に失敗しました。認証情報を確認してください。');
120
+ } else if (status === 403) {
121
+ console.error('❌ JIRAへのアクセス権限がありません。');
122
+ } else if (status === 404) {
123
+ console.error(`❌ JIRAプロジェクト "${projectKey}" が見つかりません。`);
124
+ } else {
125
+ console.error(`❌ JIRA APIエラー: ${status} ${statusText}`);
126
+ }
127
+ } else if (error.request) {
128
+ // ネットワークエラー
129
+ console.error('❌ JIRA APIへの接続に失敗しました。ネットワークを確認してください。');
130
+ } else {
131
+ // その他のエラー
132
+ console.error(`❌ エラー: ${error.message}`);
133
+ }
134
+
135
+ return null;
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Issue Type名からIDを取得
141
+ *
142
+ * @param issueTypes Issue Typesのリスト
143
+ * @param name Issue Type名(例: "Story", "ストーリー")
144
+ * @returns Issue Type ID、見つからない場合はnull
145
+ */
146
+ export function findIssueTypeIdByName(
147
+ issueTypes: IssueTypeInfo[],
148
+ name: string
149
+ ): string | null {
150
+ const normalizedName = name.toLowerCase().trim();
151
+
152
+ const found = issueTypes.find(it =>
153
+ it.name.toLowerCase() === normalizedName ||
154
+ it.name === name
155
+ );
156
+
157
+ return found ? found.id : null;
158
+ }
159
+
160
+ /**
161
+ * Issue Type IDが存在するかチェック
162
+ *
163
+ * @param issueTypes Issue Typesのリスト
164
+ * @param id Issue Type ID
165
+ * @returns 存在する場合はtrue
166
+ */
167
+ export function hasIssueTypeId(
168
+ issueTypes: IssueTypeInfo[],
169
+ id: string
170
+ ): boolean {
171
+ return issueTypes.some(it => it.id === id);
172
+ }
173
+
174
+ /**
175
+ * StoryタイプのIssue Typesをフィルタリング
176
+ *
177
+ * @param issueTypes Issue Typesのリスト
178
+ * @returns Storyタイプのリスト
179
+ */
180
+ export function filterStoryTypes(issueTypes: IssueTypeInfo[]): IssueTypeInfo[] {
181
+ return issueTypes.filter(it =>
182
+ !it.subtask &&
183
+ (it.name.toLowerCase().includes('story') || it.name.includes('ストーリー')) &&
184
+ !it.name.toLowerCase().includes('epic') &&
185
+ !it.name.includes('エピック')
186
+ );
187
+ }
188
+
189
+ /**
190
+ * SubtaskタイプのIssue Typesをフィルタリング
191
+ *
192
+ * @param issueTypes Issue Typesのリスト
193
+ * @returns Subtaskタイプのリスト
194
+ */
195
+ export function filterSubtaskTypes(issueTypes: IssueTypeInfo[]): IssueTypeInfo[] {
196
+ return issueTypes.filter(it => it.subtask === true);
197
+ }
198
+
199
+
@@ -0,0 +1,139 @@
1
+ /**
2
+ * 実装言語検出ユーティリティ
3
+ * design.md、requirements.mdから実装言語を自動推論
4
+ */
5
+
6
+ import { readFileSync, existsSync } from 'fs';
7
+ import { join } from 'path';
8
+ import { extractSection } from './markdown-parser.js';
9
+
10
+ export interface LanguageRecommendation {
11
+ language: string; // 'Node.js/TypeScript', 'Java', etc.
12
+ confidence: 'high' | 'medium' | 'low';
13
+ reasons: string[];
14
+ }
15
+
16
+ /**
17
+ * 実装言語を分析
18
+ */
19
+ export function analyzeLanguage(feature: string, projectRoot: string = process.cwd()): LanguageRecommendation {
20
+ const reasons: string[] = [];
21
+ const scores: Record<string, number> = {
22
+ 'Node.js/TypeScript': 0,
23
+ 'Java': 0,
24
+ 'PHP': 0,
25
+ 'Python': 0,
26
+ 'Go': 0,
27
+ 'Rust': 0
28
+ };
29
+
30
+ // design.mdを解析
31
+ const designPath = join(projectRoot, '.kiro', 'specs', feature, 'design.md');
32
+ if (existsSync(designPath)) {
33
+ const design = readFileSync(designPath, 'utf-8');
34
+
35
+ // Technology Stackセクションを確認
36
+ const techStack = extractSection(design, 'Technology Stack');
37
+
38
+ // Node.js/TypeScript
39
+ if (techStack.match(/Node\.js|TypeScript|npm|pnpm|yarn/i)) {
40
+ scores['Node.js/TypeScript'] += 5;
41
+ reasons.push('Technology StackにNode.js/TypeScriptが含まれている');
42
+ }
43
+
44
+ if (techStack.match(/React|Next\.js|Express|NestJS/i)) {
45
+ scores['Node.js/TypeScript'] += 3;
46
+ reasons.push('Node.jsフレームワーク(React/Next.js/Express等)が含まれている');
47
+ }
48
+
49
+ // Java
50
+ if (techStack.match(/Java|JDK|Spring|Gradle|Maven/i)) {
51
+ scores['Java'] += 5;
52
+ reasons.push('Technology StackにJavaが含まれている');
53
+ }
54
+
55
+ if (techStack.match(/Spring Boot|Spring Framework|Hibernate/i)) {
56
+ scores['Java'] += 3;
57
+ reasons.push('Javaフレームワーク(Spring等)が含まれている');
58
+ }
59
+
60
+ // PHP
61
+ if (techStack.match(/PHP|Composer|Laravel|Symfony/i)) {
62
+ scores['PHP'] += 5;
63
+ reasons.push('Technology StackにPHPが含まれている');
64
+ }
65
+
66
+ // Python
67
+ if (techStack.match(/Python|Django|Flask|FastAPI|pip|poetry/i)) {
68
+ scores['Python'] += 5;
69
+ reasons.push('Technology StackにPythonが含まれている');
70
+ }
71
+
72
+ // Go
73
+ if (techStack.match(/\bGo\b|Golang|go mod/i)) {
74
+ scores['Go'] += 5;
75
+ reasons.push('Technology StackにGoが含まれている');
76
+ }
77
+
78
+ // Rust
79
+ if (techStack.match(/Rust|Cargo|Actix|Rocket/i)) {
80
+ scores['Rust'] += 5;
81
+ reasons.push('Technology StackにRustが含まれている');
82
+ }
83
+
84
+ // Runtimeセクションも確認
85
+ const runtime = design.toLowerCase();
86
+ if (runtime.includes('node.js')) {
87
+ scores['Node.js/TypeScript'] += 2;
88
+ }
89
+ if (runtime.includes('jvm') || runtime.includes('java')) {
90
+ scores['Java'] += 2;
91
+ }
92
+ }
93
+
94
+ // requirements.mdを解析
95
+ const requirementsPath = join(projectRoot, '.kiro', 'specs', feature, 'requirements.md');
96
+ if (existsSync(requirementsPath)) {
97
+ const requirements = readFileSync(requirementsPath, 'utf-8');
98
+
99
+ // APIやWebアプリケーションの言及
100
+ if (requirements.match(/REST API|GraphQL API/i)) {
101
+ // API系はNode.js、Java、Go、Pythonが一般的
102
+ if (scores['Node.js/TypeScript'] > 0) scores['Node.js/TypeScript'] += 1;
103
+ if (scores['Java'] > 0) scores['Java'] += 1;
104
+ if (scores['Go'] > 0) scores['Go'] += 1;
105
+ if (scores['Python'] > 0) scores['Python'] += 1;
106
+ }
107
+
108
+ if (requirements.match(/Web.*アプリケーション|UI|フロントエンド/i)) {
109
+ // Webアプリケーションは主にNode.js、PHP、Python
110
+ if (scores['Node.js/TypeScript'] > 0) scores['Node.js/TypeScript'] += 1;
111
+ if (scores['PHP'] > 0) scores['PHP'] += 1;
112
+ if (scores['Python'] > 0) scores['Python'] += 1;
113
+ }
114
+ }
115
+
116
+ // 最高スコアの言語を選択
117
+ let maxScore = 0;
118
+ let recommendedLanguage = 'その他';
119
+
120
+ for (const [lang, score] of Object.entries(scores)) {
121
+ if (score > maxScore) {
122
+ maxScore = score;
123
+ recommendedLanguage = lang;
124
+ }
125
+ }
126
+
127
+ // 信頼度を判定
128
+ const confidence: 'high' | 'medium' | 'low' =
129
+ maxScore >= 5 ? 'high' :
130
+ maxScore >= 3 ? 'medium' :
131
+ 'low';
132
+
133
+ return {
134
+ language: recommendedLanguage,
135
+ confidence,
136
+ reasons
137
+ };
138
+ }
139
+
@@ -0,0 +1,376 @@
1
+ /**
2
+ * Markdown解析ユーティリティ
3
+ * requirements.mdとdesign.mdから構造化データを抽出
4
+ */
5
+
6
+ export interface Component {
7
+ name: string;
8
+ domain: string;
9
+ intent: string;
10
+ requirements: string[];
11
+ methods: Method[];
12
+ }
13
+
14
+ export interface Method {
15
+ name: string;
16
+ signature: string;
17
+ parameters: Parameter[];
18
+ returnType: string;
19
+ description?: string;
20
+ }
21
+
22
+ export interface Parameter {
23
+ name: string;
24
+ type: string;
25
+ }
26
+
27
+ export interface Flow {
28
+ name: string;
29
+ type: 'sequence' | 'process' | 'data';
30
+ mermaidCode: string;
31
+ description?: string;
32
+ }
33
+
34
+ export interface Requirement {
35
+ id: string;
36
+ title: string;
37
+ objective: string;
38
+ acceptanceCriteria: string[];
39
+ }
40
+
41
+ /**
42
+ * Markdownから特定の見出しセクションを抽出
43
+ */
44
+ export function extractSection(content: string, heading: string): string {
45
+ const lines = content.split('\n');
46
+ const headingRegex = new RegExp(`^#+\\s+${heading}`, 'i');
47
+
48
+ let startIndex = -1;
49
+ let endIndex = lines.length;
50
+ let headingLevel = 0;
51
+
52
+ // 開始位置を検索
53
+ for (let i = 0; i < lines.length; i++) {
54
+ if (headingRegex.test(lines[i])) {
55
+ startIndex = i;
56
+ const match = lines[i].match(/^(#+)/);
57
+ headingLevel = match ? match[1].length : 0;
58
+ break;
59
+ }
60
+ }
61
+
62
+ if (startIndex === -1) {
63
+ return '';
64
+ }
65
+
66
+ // 同じレベルまたは上位レベルの見出しまで抽出
67
+ for (let i = startIndex + 1; i < lines.length; i++) {
68
+ const match = lines[i].match(/^(#+)\s/);
69
+ if (match && match[1].length <= headingLevel) {
70
+ endIndex = i;
71
+ break;
72
+ }
73
+ }
74
+
75
+ return lines.slice(startIndex, endIndex).join('\n');
76
+ }
77
+
78
+ /**
79
+ * design.mdからコンポーネント情報を抽出
80
+ */
81
+ export function extractComponents(designMd: string): Component[] {
82
+ const components: Component[] = [];
83
+ const componentsSection = extractSection(designMd, 'Components and Interfaces');
84
+
85
+ if (!componentsSection) {
86
+ return components;
87
+ }
88
+
89
+ // コンポーネントサマリーテーブルを解析
90
+ const summaryTableMatch = componentsSection.match(/\|\s*Component\s*\|.*?\n\|[-\s|]+\n((?:\|.*?\n)+)/i);
91
+ if (summaryTableMatch) {
92
+ const rows = summaryTableMatch[1].trim().split('\n');
93
+ for (const row of rows) {
94
+ const cells = row.split('|').map(c => c.trim()).filter(c => c);
95
+ if (cells.length >= 3) {
96
+ components.push({
97
+ name: cells[0],
98
+ domain: cells[1] || '',
99
+ intent: cells[2] || '',
100
+ requirements: [],
101
+ methods: []
102
+ });
103
+ }
104
+ }
105
+ }
106
+
107
+ // 各コンポーネントの詳細セクションからインターフェースを抽出
108
+ const lines = componentsSection.split('\n');
109
+ let currentComponent: Component | null = null;
110
+
111
+ for (let i = 0; i < lines.length; i++) {
112
+ const line = lines[i];
113
+
114
+ // コンポーネント見出しを検索(#### Component Name)
115
+ const componentMatch = line.match(/^####\s+(.+)/);
116
+ if (componentMatch) {
117
+ const componentName = componentMatch[1].trim();
118
+ currentComponent = components.find(c => c.name === componentName) || null;
119
+ continue;
120
+ }
121
+
122
+ // Service Interfaceセクションを検索
123
+ if (line.includes('##### Service Interface') && currentComponent) {
124
+ // TypeScriptコードブロックを抽出
125
+ let inCodeBlock = false;
126
+ let codeContent = '';
127
+
128
+ for (let j = i + 1; j < lines.length; j++) {
129
+ if (lines[j].startsWith('```typescript') || lines[j].startsWith('```ts')) {
130
+ inCodeBlock = true;
131
+ continue;
132
+ }
133
+ if (lines[j].startsWith('```') && inCodeBlock) {
134
+ break;
135
+ }
136
+ if (inCodeBlock) {
137
+ codeContent += lines[j] + '\n';
138
+ }
139
+ }
140
+
141
+ // インターフェースからメソッドを抽出
142
+ const methods = extractMethodsFromInterface(codeContent);
143
+ currentComponent.methods = methods;
144
+ }
145
+ }
146
+
147
+ return components;
148
+ }
149
+
150
+ /**
151
+ * TypeScriptインターフェースからメソッドを抽出
152
+ */
153
+ function extractMethodsFromInterface(interfaceCode: string): Method[] {
154
+ const methods: Method[] = [];
155
+ const lines = interfaceCode.split('\n');
156
+
157
+ for (const line of lines) {
158
+ // メソッドシグネチャを検索(例: methodName(param: Type): ReturnType)
159
+ const methodMatch = line.match(/^\s*(\w+)\s*\(([^)]*)\)\s*:\s*(.+?)\s*;?\s*$/);
160
+ if (methodMatch) {
161
+ const methodName = methodMatch[1];
162
+ const paramsStr = methodMatch[2];
163
+ const returnType = methodMatch[3];
164
+
165
+ // パラメータを解析
166
+ const parameters: Parameter[] = [];
167
+ if (paramsStr.trim()) {
168
+ const paramParts = paramsStr.split(',');
169
+ for (const part of paramParts) {
170
+ const paramMatch = part.trim().match(/(\w+)\??:\s*(.+)/);
171
+ if (paramMatch) {
172
+ parameters.push({
173
+ name: paramMatch[1],
174
+ type: paramMatch[2].trim()
175
+ });
176
+ }
177
+ }
178
+ }
179
+
180
+ methods.push({
181
+ name: methodName,
182
+ signature: line.trim(),
183
+ parameters,
184
+ returnType: returnType.trim()
185
+ });
186
+ }
187
+ }
188
+
189
+ return methods;
190
+ }
191
+
192
+ /**
193
+ * design.mdからシステムフローを抽出
194
+ */
195
+ export function extractFlows(designMd: string): Flow[] {
196
+ const flows: Flow[] = [];
197
+ const flowsSection = extractSection(designMd, 'System Flows');
198
+
199
+ if (!flowsSection) {
200
+ return flows;
201
+ }
202
+
203
+ const lines = flowsSection.split('\n');
204
+ let currentFlowName = '';
205
+ let currentFlowType: 'sequence' | 'process' | 'data' = 'sequence';
206
+
207
+ for (let i = 0; i < lines.length; i++) {
208
+ const line = lines[i];
209
+
210
+ // フロー見出しを検索(### Flow Name)
211
+ const flowMatch = line.match(/^###\s+(.+)/);
212
+ if (flowMatch) {
213
+ currentFlowName = flowMatch[1].trim();
214
+ continue;
215
+ }
216
+
217
+ // Mermaidコードブロックを検索
218
+ if (line.startsWith('```mermaid') && currentFlowName) {
219
+ let mermaidCode = '';
220
+
221
+ for (let j = i + 1; j < lines.length; j++) {
222
+ if (lines[j].startsWith('```')) {
223
+ break;
224
+ }
225
+ mermaidCode += lines[j] + '\n';
226
+ }
227
+
228
+ // フロータイプを判定
229
+ if (mermaidCode.includes('sequenceDiagram')) {
230
+ currentFlowType = 'sequence';
231
+ } else if (mermaidCode.includes('graph') || mermaidCode.includes('flowchart')) {
232
+ currentFlowType = 'process';
233
+ }
234
+
235
+ flows.push({
236
+ name: currentFlowName,
237
+ type: currentFlowType,
238
+ mermaidCode: mermaidCode.trim()
239
+ });
240
+
241
+ currentFlowName = '';
242
+ }
243
+ }
244
+
245
+ return flows;
246
+ }
247
+
248
+ /**
249
+ * requirements.mdから要件を抽出
250
+ */
251
+ export function extractRequirements(requirementsMd: string): Requirement[] {
252
+ const requirements: Requirement[] = [];
253
+ const lines = requirementsMd.split('\n');
254
+
255
+ let currentRequirement: Requirement | null = null;
256
+ let inAcceptanceCriteria = false;
257
+
258
+ for (let i = 0; i < lines.length; i++) {
259
+ const line = lines[i];
260
+
261
+ // 要件見出しを検索(### Requirement N: Title)
262
+ const reqMatch = line.match(/^###\s+Requirement\s+(\d+):\s+(.+)/i);
263
+ if (reqMatch) {
264
+ // 前の要件を保存
265
+ if (currentRequirement) {
266
+ requirements.push(currentRequirement);
267
+ }
268
+
269
+ currentRequirement = {
270
+ id: reqMatch[1],
271
+ title: reqMatch[2].trim(),
272
+ objective: '',
273
+ acceptanceCriteria: []
274
+ };
275
+ inAcceptanceCriteria = false;
276
+ continue;
277
+ }
278
+
279
+ // NFR(非機能要件)も同様に抽出
280
+ const nfrMatch = line.match(/^###\s+(NFR-\d+):\s+(.+)/i);
281
+ if (nfrMatch) {
282
+ if (currentRequirement) {
283
+ requirements.push(currentRequirement);
284
+ }
285
+
286
+ currentRequirement = {
287
+ id: nfrMatch[1],
288
+ title: nfrMatch[2].trim(),
289
+ objective: '',
290
+ acceptanceCriteria: []
291
+ };
292
+ inAcceptanceCriteria = false;
293
+ continue;
294
+ }
295
+
296
+ // Objectiveを抽出
297
+ if (currentRequirement && line.includes('**Objective:**')) {
298
+ const objectiveMatch = line.match(/\*\*Objective:\*\*\s*(.+)/);
299
+ if (objectiveMatch) {
300
+ currentRequirement.objective = objectiveMatch[1].trim();
301
+ }
302
+ continue;
303
+ }
304
+
305
+ // Acceptance Criteriaセクションの開始
306
+ if (currentRequirement && line.includes('#### Acceptance Criteria')) {
307
+ inAcceptanceCriteria = true;
308
+ continue;
309
+ }
310
+
311
+ // Acceptance Criteriaを抽出
312
+ if (currentRequirement && inAcceptanceCriteria) {
313
+ const criteriaMatch = line.match(/^\d+\.\s+(.+)/);
314
+ if (criteriaMatch) {
315
+ currentRequirement.acceptanceCriteria.push(criteriaMatch[1].trim());
316
+ }
317
+
318
+ // 次のセクションに到達したら終了
319
+ if (line.match(/^##[#]?\s+/)) {
320
+ inAcceptanceCriteria = false;
321
+ }
322
+ }
323
+ }
324
+
325
+ // 最後の要件を保存
326
+ if (currentRequirement) {
327
+ requirements.push(currentRequirement);
328
+ }
329
+
330
+ return requirements;
331
+ }
332
+
333
+ /**
334
+ * design.mdからインターフェース定義を抽出
335
+ */
336
+ export function extractInterfaces(designMd: string): Record<string, string> {
337
+ const interfaces: Record<string, string> = {};
338
+ const lines = designMd.split('\n');
339
+
340
+ let inCodeBlock = false;
341
+ let currentInterface = '';
342
+ let interfaceCode = '';
343
+
344
+ for (let i = 0; i < lines.length; i++) {
345
+ const line = lines[i];
346
+
347
+ if (line.startsWith('```typescript') || line.startsWith('```ts')) {
348
+ inCodeBlock = true;
349
+ interfaceCode = '';
350
+ continue;
351
+ }
352
+
353
+ if (line.startsWith('```') && inCodeBlock) {
354
+ inCodeBlock = false;
355
+ if (currentInterface && interfaceCode) {
356
+ interfaces[currentInterface] = interfaceCode.trim();
357
+ }
358
+ currentInterface = '';
359
+ interfaceCode = '';
360
+ continue;
361
+ }
362
+
363
+ if (inCodeBlock) {
364
+ interfaceCode += line + '\n';
365
+
366
+ // インターフェース名を抽出
367
+ const interfaceMatch = line.match(/interface\s+(\w+)/);
368
+ if (interfaceMatch && !currentInterface) {
369
+ currentInterface = interfaceMatch[1];
370
+ }
371
+ }
372
+ }
373
+
374
+ return interfaces;
375
+ }
376
+