@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,429 @@
1
+ /**
2
+ * spec-impl-workflow.ts のテスト
3
+ */
4
+
5
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
6
+
7
+ // モジュールのモック
8
+ vi.mock('dotenv', () => ({ config: vi.fn() }));
9
+
10
+ // JIRAClientをモック
11
+ const mockTransitionIssue = vi.fn();
12
+ const mockAddComment = vi.fn();
13
+
14
+ class MockJIRAClient {
15
+ transitionIssue = mockTransitionIssue;
16
+ addComment = mockAddComment;
17
+ }
18
+
19
+ vi.mock('../jira-sync.js', () => ({
20
+ JIRAClient: MockJIRAClient,
21
+ }));
22
+
23
+ // config-loaderをモック
24
+ vi.mock('../utils/config-loader.js', () => ({
25
+ getConfig: vi.fn(() => ({
26
+ jira: {
27
+ statusMapping: {
28
+ inProgress: 'In Progress',
29
+ readyForReview: 'Ready for Review',
30
+ },
31
+ },
32
+ })),
33
+ }));
34
+
35
+ // spec-loaderをモック
36
+ const mockGetJiraInfoFromSpec = vi.fn();
37
+ const mockCheckJiraInfoStatus = vi.fn();
38
+
39
+ vi.mock('../utils/spec-loader.js', () => ({
40
+ getJiraInfoFromSpec: (...args: unknown[]) => mockGetJiraInfoFromSpec(...args),
41
+ checkJiraInfoStatus: (...args: unknown[]) => mockCheckJiraInfoStatus(...args),
42
+ }));
43
+
44
+ // Octokitをモック
45
+ const mockPullsCreate = vi.fn();
46
+
47
+ class MockOctokit {
48
+ pulls = {
49
+ create: mockPullsCreate,
50
+ };
51
+ }
52
+
53
+ vi.mock('@octokit/rest', () => ({
54
+ Octokit: MockOctokit,
55
+ }));
56
+
57
+ describe('spec-impl-workflow', () => {
58
+ beforeEach(() => {
59
+ vi.clearAllMocks();
60
+ // 環境変数の設定
61
+ process.env.ATLASSIAN_URL = 'https://test.atlassian.net';
62
+ process.env.ATLASSIAN_EMAIL = 'test@example.com';
63
+ process.env.ATLASSIAN_API_TOKEN = 'test-token';
64
+ process.env.GITHUB_TOKEN = 'github-token';
65
+ process.env.GITHUB_REPO = 'owner/repo';
66
+ });
67
+
68
+ afterEach(() => {
69
+ vi.restoreAllMocks();
70
+ delete process.env.ATLASSIAN_URL;
71
+ delete process.env.ATLASSIAN_EMAIL;
72
+ delete process.env.ATLASSIAN_API_TOKEN;
73
+ delete process.env.GITHUB_TOKEN;
74
+ delete process.env.GITHUB_REPO;
75
+ });
76
+
77
+ // ==========================================================================
78
+ // 新 API (runSpecImplStart, runSpecImplComplete)
79
+ // ==========================================================================
80
+
81
+ describe('runSpecImplStart', () => {
82
+ it('spec.json から JIRA 情報を取得して Epic と Story を進行中に移動', async () => {
83
+ mockGetJiraInfoFromSpec.mockReturnValue({
84
+ epicKey: 'PROJ-123',
85
+ storyKeys: ['PROJ-124'],
86
+ firstStoryKey: 'PROJ-124',
87
+ projectKey: 'PROJ',
88
+ epicUrl: 'https://test.atlassian.net/browse/PROJ-123',
89
+ });
90
+ mockCheckJiraInfoStatus.mockReturnValue({
91
+ hasJiraInfo: true,
92
+ hasEpic: true,
93
+ hasStories: true,
94
+ missing: [],
95
+ });
96
+ mockTransitionIssue.mockResolvedValue(undefined);
97
+
98
+ const { runSpecImplStart } = await import('../spec-impl-workflow.js');
99
+
100
+ const result = await runSpecImplStart({
101
+ featureName: 'user-auth',
102
+ });
103
+
104
+ expect(mockGetJiraInfoFromSpec).toHaveBeenCalledWith(
105
+ 'user-auth',
106
+ process.cwd(),
107
+ );
108
+ expect(mockTransitionIssue).toHaveBeenCalledWith(
109
+ 'PROJ-123',
110
+ 'In Progress',
111
+ );
112
+ expect(mockTransitionIssue).toHaveBeenCalledWith(
113
+ 'PROJ-124',
114
+ 'In Progress',
115
+ );
116
+ expect(result.jiraInfo).toBeTruthy();
117
+ expect(result.jiraInfo?.epicKey).toBe('PROJ-123');
118
+ });
119
+
120
+ it('skipJira=true の場合は JIRA 連携をスキップ', async () => {
121
+ mockGetJiraInfoFromSpec.mockReturnValue({
122
+ epicKey: null,
123
+ storyKeys: [],
124
+ firstStoryKey: null,
125
+ projectKey: null,
126
+ epicUrl: null,
127
+ });
128
+ mockCheckJiraInfoStatus.mockReturnValue({
129
+ hasJiraInfo: false,
130
+ hasEpic: false,
131
+ hasStories: false,
132
+ missing: ['Epic', 'Story'],
133
+ });
134
+
135
+ const { runSpecImplStart } = await import('../spec-impl-workflow.js');
136
+
137
+ const result = await runSpecImplStart({
138
+ featureName: 'user-auth',
139
+ skipJira: true,
140
+ });
141
+
142
+ expect(mockTransitionIssue).not.toHaveBeenCalled();
143
+ expect(result.jiraInfo).toBeNull();
144
+ });
145
+
146
+ it('JIRA 情報がない場合は JiraInfoNotFoundError をスロー', async () => {
147
+ mockGetJiraInfoFromSpec.mockReturnValue({
148
+ epicKey: null,
149
+ storyKeys: [],
150
+ firstStoryKey: null,
151
+ projectKey: null,
152
+ epicUrl: null,
153
+ });
154
+ mockCheckJiraInfoStatus.mockReturnValue({
155
+ hasJiraInfo: false,
156
+ hasEpic: false,
157
+ hasStories: false,
158
+ missing: ['Epic', 'Story'],
159
+ });
160
+
161
+ const { runSpecImplStart, JiraInfoNotFoundError } = await import(
162
+ '../spec-impl-workflow.js'
163
+ );
164
+
165
+ await expect(
166
+ runSpecImplStart({ featureName: 'user-auth' }),
167
+ ).rejects.toThrow(JiraInfoNotFoundError);
168
+ });
169
+ });
170
+
171
+ describe('runSpecImplComplete', () => {
172
+ beforeEach(() => {
173
+ mockPullsCreate.mockResolvedValue({
174
+ data: {
175
+ html_url: 'https://github.com/owner/repo/pull/42',
176
+ },
177
+ });
178
+ });
179
+
180
+ it('PR 作成、ステータス変更、コメント追加を実行', async () => {
181
+ mockGetJiraInfoFromSpec.mockReturnValue({
182
+ epicKey: 'PROJ-123',
183
+ storyKeys: ['PROJ-124'],
184
+ firstStoryKey: 'PROJ-124',
185
+ projectKey: 'PROJ',
186
+ epicUrl: 'https://test.atlassian.net/browse/PROJ-123',
187
+ });
188
+ mockCheckJiraInfoStatus.mockReturnValue({
189
+ hasJiraInfo: true,
190
+ hasEpic: true,
191
+ hasStories: true,
192
+ missing: [],
193
+ });
194
+ mockTransitionIssue.mockResolvedValue(undefined);
195
+ mockAddComment.mockResolvedValue(undefined);
196
+
197
+ const { runSpecImplComplete } = await import('../spec-impl-workflow.js');
198
+
199
+ const result = await runSpecImplComplete({
200
+ featureName: 'user-auth',
201
+ });
202
+
203
+ // PR 作成
204
+ expect(mockPullsCreate).toHaveBeenCalledWith({
205
+ owner: 'owner',
206
+ repo: 'repo',
207
+ title: 'feat: user-auth',
208
+ body: expect.stringContaining('PROJ-123'),
209
+ head: 'feature/user-auth',
210
+ base: 'main',
211
+ });
212
+
213
+ // ステータス変更
214
+ expect(mockTransitionIssue).toHaveBeenCalledWith(
215
+ 'PROJ-123',
216
+ 'Ready for Review',
217
+ );
218
+ expect(mockTransitionIssue).toHaveBeenCalledWith(
219
+ 'PROJ-124',
220
+ 'Ready for Review',
221
+ );
222
+
223
+ // コメント追加
224
+ expect(mockAddComment).toHaveBeenCalledWith(
225
+ 'PROJ-123',
226
+ expect.stringContaining('https://github.com/owner/repo/pull/42'),
227
+ );
228
+
229
+ expect(result.prUrl).toBe('https://github.com/owner/repo/pull/42');
230
+ });
231
+
232
+ it('skipJira=true の場合は JIRA 連携をスキップしつつ PR は作成', async () => {
233
+ mockGetJiraInfoFromSpec.mockReturnValue({
234
+ epicKey: null,
235
+ storyKeys: [],
236
+ firstStoryKey: null,
237
+ projectKey: null,
238
+ epicUrl: null,
239
+ });
240
+ mockCheckJiraInfoStatus.mockReturnValue({
241
+ hasJiraInfo: false,
242
+ hasEpic: false,
243
+ hasStories: false,
244
+ missing: ['Epic', 'Story'],
245
+ });
246
+
247
+ const { runSpecImplComplete } = await import('../spec-impl-workflow.js');
248
+
249
+ const result = await runSpecImplComplete({
250
+ featureName: 'user-auth',
251
+ skipJira: true,
252
+ });
253
+
254
+ expect(mockPullsCreate).toHaveBeenCalled();
255
+ expect(mockTransitionIssue).not.toHaveBeenCalled();
256
+ expect(mockAddComment).not.toHaveBeenCalled();
257
+ expect(result.prUrl).toBe('https://github.com/owner/repo/pull/42');
258
+ });
259
+
260
+ it('カスタムブランチ名を使用できる', async () => {
261
+ mockGetJiraInfoFromSpec.mockReturnValue({
262
+ epicKey: 'PROJ-123',
263
+ storyKeys: [],
264
+ firstStoryKey: null,
265
+ projectKey: 'PROJ',
266
+ epicUrl: null,
267
+ });
268
+ mockCheckJiraInfoStatus.mockReturnValue({
269
+ hasJiraInfo: true,
270
+ hasEpic: true,
271
+ hasStories: false,
272
+ missing: ['Story'],
273
+ });
274
+ mockTransitionIssue.mockResolvedValue(undefined);
275
+
276
+ const { runSpecImplComplete } = await import('../spec-impl-workflow.js');
277
+
278
+ await runSpecImplComplete({
279
+ featureName: 'user-auth',
280
+ branchName: 'custom/branch-name',
281
+ });
282
+
283
+ expect(mockPullsCreate).toHaveBeenCalledWith(
284
+ expect.objectContaining({
285
+ head: 'custom/branch-name',
286
+ }),
287
+ );
288
+ });
289
+ });
290
+
291
+ describe('JiraInfoNotFoundError', () => {
292
+ it('正しいエラーメッセージを持つ', async () => {
293
+ const { JiraInfoNotFoundError } = await import(
294
+ '../spec-impl-workflow.js'
295
+ );
296
+
297
+ const error = new JiraInfoNotFoundError('user-auth', ['Epic', 'Story']);
298
+
299
+ expect(error.name).toBe('JiraInfoNotFoundError');
300
+ expect(error.featureName).toBe('user-auth');
301
+ expect(error.missing).toEqual(['Epic', 'Story']);
302
+ expect(error.message).toContain('user-auth');
303
+ expect(error.message).toContain('Epic, Story');
304
+ expect(error.message).toContain('michi jira:sync');
305
+ });
306
+ });
307
+
308
+ // ==========================================================================
309
+ // 旧 API(後方互換性のため維持、非推奨)
310
+ // ==========================================================================
311
+
312
+ describe('onSpecImplStart (deprecated)', () => {
313
+ it('JIRAを進行中に移動する', async () => {
314
+ mockTransitionIssue.mockResolvedValueOnce(undefined);
315
+
316
+ const { onSpecImplStart } = await import('../spec-impl-workflow.js');
317
+
318
+ await onSpecImplStart({
319
+ featureName: 'user-auth',
320
+ jiraKey: 'PROJ-123',
321
+ });
322
+
323
+ expect(mockTransitionIssue).toHaveBeenCalledWith(
324
+ 'PROJ-123',
325
+ 'In Progress',
326
+ );
327
+ });
328
+
329
+ it('JIRA認証情報が不足している場合はエラー', async () => {
330
+ delete process.env.ATLASSIAN_API_TOKEN;
331
+
332
+ // モジュールを再インポート
333
+ vi.resetModules();
334
+ const { onSpecImplStart } = await import('../spec-impl-workflow.js');
335
+
336
+ await expect(
337
+ onSpecImplStart({
338
+ featureName: 'user-auth',
339
+ jiraKey: 'PROJ-123',
340
+ }),
341
+ ).rejects.toThrow(/Missing JIRA credentials/);
342
+ });
343
+ });
344
+
345
+ describe('onSpecImplEnd', () => {
346
+ beforeEach(() => {
347
+ // PRの作成をモック
348
+ mockPullsCreate.mockResolvedValue({
349
+ data: {
350
+ html_url: 'https://github.com/owner/repo/pull/42',
351
+ },
352
+ });
353
+ });
354
+
355
+ it('PR作成、ステータス変更、コメント追加を実行', async () => {
356
+ mockTransitionIssue.mockResolvedValueOnce(undefined);
357
+ mockAddComment.mockResolvedValueOnce(undefined);
358
+
359
+ const { onSpecImplEnd } = await import('../spec-impl-workflow.js');
360
+
361
+ const result = await onSpecImplEnd({
362
+ featureName: 'user-auth',
363
+ jiraKey: 'PROJ-123',
364
+ });
365
+
366
+ // PR URLが返される
367
+ expect(result.prUrl).toBe('https://github.com/owner/repo/pull/42');
368
+
369
+ // PR作成の検証
370
+ expect(mockPullsCreate).toHaveBeenCalledWith({
371
+ owner: 'owner',
372
+ repo: 'repo',
373
+ title: 'feat: user-auth',
374
+ body: expect.stringContaining('PROJ-123'),
375
+ head: 'feature/user-auth',
376
+ base: 'main',
377
+ });
378
+
379
+ // JIRAステータス変更の検証
380
+ expect(mockTransitionIssue).toHaveBeenCalledWith(
381
+ 'PROJ-123',
382
+ 'Ready for Review',
383
+ );
384
+
385
+ // コメント追加の検証
386
+ expect(mockAddComment).toHaveBeenCalledWith(
387
+ 'PROJ-123',
388
+ expect.stringContaining('https://github.com/owner/repo/pull/42'),
389
+ );
390
+ });
391
+
392
+ it('カスタムブランチ名を使用できる', async () => {
393
+ mockTransitionIssue.mockResolvedValueOnce(undefined);
394
+ mockAddComment.mockResolvedValueOnce(undefined);
395
+
396
+ const { onSpecImplEnd } = await import('../spec-impl-workflow.js');
397
+
398
+ await onSpecImplEnd({
399
+ featureName: 'user-auth',
400
+ jiraKey: 'PROJ-123',
401
+ branchName: 'custom/branch-name',
402
+ });
403
+
404
+ expect(mockPullsCreate).toHaveBeenCalledWith(
405
+ expect.objectContaining({
406
+ head: 'custom/branch-name',
407
+ }),
408
+ );
409
+ });
410
+
411
+ it('GitHub認証情報が不足している場合はエラー', async () => {
412
+ delete process.env.GITHUB_TOKEN;
413
+
414
+ vi.resetModules();
415
+ const { onSpecImplEnd } = await import('../spec-impl-workflow.js');
416
+
417
+ await expect(
418
+ onSpecImplEnd({
419
+ featureName: 'user-auth',
420
+ jiraKey: 'PROJ-123',
421
+ }),
422
+ ).rejects.toThrow(/Missing GitHub credentials/);
423
+ });
424
+
425
+ // 注意: 旧 API (onSpecImplEnd) は JIRA エラーをキャッチせずスローします。
426
+ // 新 API (runSpecImplComplete) は JIRA エラーを警告として扱い、PR URL を返します。
427
+ // 旧 API を使用する場合は、呼び出し側でエラーハンドリングが必要です。
428
+ });
429
+ });
@@ -0,0 +1,199 @@
1
+ /**
2
+ * spec-loader.ts のテスト
3
+ */
4
+
5
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
6
+
7
+ // spec-updater をモック
8
+ vi.mock('../utils/spec-updater.js', () => ({
9
+ loadSpecJson: vi.fn(),
10
+ }));
11
+
12
+ import { loadSpecJson } from '../utils/spec-updater.js';
13
+ import {
14
+ getJiraInfoFromSpec,
15
+ checkJiraInfoStatus,
16
+ canIntegrateWithJira,
17
+ type JiraInfo,
18
+ type JiraInfoStatus,
19
+ } from '../utils/spec-loader.js';
20
+
21
+ const mockLoadSpecJson = vi.mocked(loadSpecJson);
22
+
23
+ describe('spec-loader', () => {
24
+ beforeEach(() => {
25
+ vi.clearAllMocks();
26
+ });
27
+
28
+ describe('getJiraInfoFromSpec', () => {
29
+ it('すべての JIRA 情報がある場合に正しく取得する', () => {
30
+ mockLoadSpecJson.mockReturnValue({
31
+ jira: {
32
+ epicKey: 'PROJ-123',
33
+ storyKeys: ['PROJ-124', 'PROJ-125'],
34
+ projectKey: 'PROJ',
35
+ epicUrl: 'https://test.atlassian.net/browse/PROJ-123',
36
+ },
37
+ });
38
+
39
+ const result = getJiraInfoFromSpec('user-auth');
40
+
41
+ expect(mockLoadSpecJson).toHaveBeenCalledWith('user-auth', process.cwd());
42
+ expect(result).toEqual<JiraInfo>({
43
+ epicKey: 'PROJ-123',
44
+ storyKeys: ['PROJ-124', 'PROJ-125'],
45
+ firstStoryKey: 'PROJ-124',
46
+ projectKey: 'PROJ',
47
+ epicUrl: 'https://test.atlassian.net/browse/PROJ-123',
48
+ });
49
+ });
50
+
51
+ it('JIRA 情報がない場合は null を返す', () => {
52
+ mockLoadSpecJson.mockReturnValue({});
53
+
54
+ const result = getJiraInfoFromSpec('user-auth');
55
+
56
+ expect(result).toEqual<JiraInfo>({
57
+ epicKey: null,
58
+ storyKeys: [],
59
+ firstStoryKey: null,
60
+ projectKey: null,
61
+ epicUrl: null,
62
+ });
63
+ });
64
+
65
+ it('Story のみの場合', () => {
66
+ mockLoadSpecJson.mockReturnValue({
67
+ jira: {
68
+ storyKeys: ['PROJ-124'],
69
+ },
70
+ });
71
+
72
+ const result = getJiraInfoFromSpec('user-auth');
73
+
74
+ expect(result).toEqual<JiraInfo>({
75
+ epicKey: null,
76
+ storyKeys: ['PROJ-124'],
77
+ firstStoryKey: 'PROJ-124',
78
+ projectKey: null,
79
+ epicUrl: null,
80
+ });
81
+ });
82
+
83
+ it('Epic のみの場合', () => {
84
+ mockLoadSpecJson.mockReturnValue({
85
+ jira: {
86
+ epicKey: 'PROJ-123',
87
+ },
88
+ });
89
+
90
+ const result = getJiraInfoFromSpec('user-auth');
91
+
92
+ expect(result).toEqual<JiraInfo>({
93
+ epicKey: 'PROJ-123',
94
+ storyKeys: [],
95
+ firstStoryKey: null,
96
+ projectKey: null,
97
+ epicUrl: null,
98
+ });
99
+ });
100
+
101
+ it('カスタム projectRoot を指定できる', () => {
102
+ mockLoadSpecJson.mockReturnValue({ jira: { epicKey: 'PROJ-123' } });
103
+
104
+ getJiraInfoFromSpec('user-auth', '/custom/path');
105
+
106
+ expect(mockLoadSpecJson).toHaveBeenCalledWith(
107
+ 'user-auth',
108
+ '/custom/path',
109
+ );
110
+ });
111
+ });
112
+
113
+ describe('checkJiraInfoStatus', () => {
114
+ it('すべての JIRA 情報がある場合', () => {
115
+ mockLoadSpecJson.mockReturnValue({
116
+ jira: {
117
+ epicKey: 'PROJ-123',
118
+ storyKeys: ['PROJ-124'],
119
+ },
120
+ });
121
+
122
+ const result = checkJiraInfoStatus('user-auth');
123
+
124
+ expect(result).toEqual<JiraInfoStatus>({
125
+ hasJiraInfo: true,
126
+ hasEpic: true,
127
+ hasStories: true,
128
+ missing: [],
129
+ });
130
+ });
131
+
132
+ it('JIRA 情報がまったくない場合', () => {
133
+ mockLoadSpecJson.mockReturnValue({});
134
+
135
+ const result = checkJiraInfoStatus('user-auth');
136
+
137
+ expect(result).toEqual<JiraInfoStatus>({
138
+ hasJiraInfo: false,
139
+ hasEpic: false,
140
+ hasStories: false,
141
+ missing: ['Epic', 'Story'],
142
+ });
143
+ });
144
+
145
+ it('Epic のみがある場合', () => {
146
+ mockLoadSpecJson.mockReturnValue({
147
+ jira: { epicKey: 'PROJ-123' },
148
+ });
149
+
150
+ const result = checkJiraInfoStatus('user-auth');
151
+
152
+ expect(result).toEqual<JiraInfoStatus>({
153
+ hasJiraInfo: true,
154
+ hasEpic: true,
155
+ hasStories: false,
156
+ missing: ['Story'],
157
+ });
158
+ });
159
+
160
+ it('Story のみがある場合', () => {
161
+ mockLoadSpecJson.mockReturnValue({
162
+ jira: { storyKeys: ['PROJ-124'] },
163
+ });
164
+
165
+ const result = checkJiraInfoStatus('user-auth');
166
+
167
+ expect(result).toEqual<JiraInfoStatus>({
168
+ hasJiraInfo: true,
169
+ hasEpic: false,
170
+ hasStories: true,
171
+ missing: ['Epic'],
172
+ });
173
+ });
174
+ });
175
+
176
+ describe('canIntegrateWithJira', () => {
177
+ it('Epic がある場合は連携可能', () => {
178
+ mockLoadSpecJson.mockReturnValue({
179
+ jira: { epicKey: 'PROJ-123' },
180
+ });
181
+
182
+ expect(canIntegrateWithJira('user-auth')).toBe(true);
183
+ });
184
+
185
+ it('Epic がない場合は連携不可', () => {
186
+ mockLoadSpecJson.mockReturnValue({
187
+ jira: { storyKeys: ['PROJ-124'] },
188
+ });
189
+
190
+ expect(canIntegrateWithJira('user-auth')).toBe(false);
191
+ });
192
+
193
+ it('JIRA 情報がない場合は連携不可', () => {
194
+ mockLoadSpecJson.mockReturnValue({});
195
+
196
+ expect(canIntegrateWithJira('user-auth')).toBe(false);
197
+ });
198
+ });
199
+ });