@sk8metal/michi-cli 0.0.8 → 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 (433) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +420 -49
  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 +146 -5
  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.d.ts +2 -0
  36. package/dist/scripts/constants/__tests__/environments.test.d.ts.map +1 -0
  37. package/dist/scripts/constants/__tests__/environments.test.js +125 -0
  38. package/dist/scripts/constants/__tests__/environments.test.js.map +1 -0
  39. package/dist/scripts/constants/__tests__/languages.test.d.ts +2 -0
  40. package/dist/scripts/constants/__tests__/languages.test.d.ts.map +1 -0
  41. package/dist/scripts/constants/__tests__/languages.test.js +82 -0
  42. package/dist/scripts/constants/__tests__/languages.test.js.map +1 -0
  43. package/dist/scripts/constants/environments.d.ts +33 -0
  44. package/dist/scripts/constants/environments.d.ts.map +1 -0
  45. package/dist/scripts/constants/environments.js +64 -0
  46. package/dist/scripts/constants/environments.js.map +1 -0
  47. package/dist/scripts/constants/languages.d.ts +23 -0
  48. package/dist/scripts/constants/languages.d.ts.map +1 -0
  49. package/dist/scripts/constants/languages.js +53 -0
  50. package/dist/scripts/constants/languages.js.map +1 -0
  51. package/dist/scripts/constants/test-commands.d.ts +36 -0
  52. package/dist/scripts/constants/test-commands.d.ts.map +1 -0
  53. package/dist/scripts/constants/test-commands.js +70 -0
  54. package/dist/scripts/constants/test-commands.js.map +1 -0
  55. package/dist/scripts/create-project.d.ts +4 -0
  56. package/dist/scripts/create-project.d.ts.map +1 -1
  57. package/dist/scripts/create-project.js +51 -22
  58. package/dist/scripts/create-project.js.map +1 -1
  59. package/dist/scripts/jira-sync.d.ts +89 -3
  60. package/dist/scripts/jira-sync.d.ts.map +1 -1
  61. package/dist/scripts/jira-sync.js +366 -96
  62. package/dist/scripts/jira-sync.js.map +1 -1
  63. package/dist/scripts/markdown-to-confluence.js +1 -1
  64. package/dist/scripts/markdown-to-confluence.js.map +1 -1
  65. package/dist/scripts/phase-runner.d.ts +1 -1
  66. package/dist/scripts/phase-runner.d.ts.map +1 -1
  67. package/dist/scripts/phase-runner.js +809 -13
  68. package/dist/scripts/phase-runner.js.map +1 -1
  69. package/dist/scripts/pr-automation.d.ts.map +1 -1
  70. package/dist/scripts/pr-automation.js.map +1 -1
  71. package/dist/scripts/pre-flight-check.js +1 -1
  72. package/dist/scripts/pre-flight-check.js.map +1 -1
  73. package/dist/scripts/setup-existing-project.d.ts +3 -1
  74. package/dist/scripts/setup-existing-project.d.ts.map +1 -1
  75. package/dist/scripts/setup-existing-project.js +165 -78
  76. package/dist/scripts/setup-existing-project.js.map +1 -1
  77. package/dist/scripts/setup-interactive.js +3 -3
  78. package/dist/scripts/setup-interactive.js.map +1 -1
  79. package/dist/scripts/spec-impl-workflow.d.ts +94 -0
  80. package/dist/scripts/spec-impl-workflow.d.ts.map +1 -0
  81. package/dist/scripts/spec-impl-workflow.js +354 -0
  82. package/dist/scripts/spec-impl-workflow.js.map +1 -0
  83. package/dist/scripts/template/__tests__/renderer.test.d.ts +2 -0
  84. package/dist/scripts/template/__tests__/renderer.test.d.ts.map +1 -0
  85. package/dist/scripts/template/__tests__/renderer.test.js +165 -0
  86. package/dist/scripts/template/__tests__/renderer.test.js.map +1 -0
  87. package/dist/scripts/template/renderer.d.ts +70 -0
  88. package/dist/scripts/template/renderer.d.ts.map +1 -0
  89. package/dist/scripts/template/renderer.js +99 -0
  90. package/dist/scripts/template/renderer.js.map +1 -0
  91. package/dist/scripts/test-execution-generator.d.ts +52 -0
  92. package/dist/scripts/test-execution-generator.d.ts.map +1 -0
  93. package/dist/scripts/test-execution-generator.js +576 -0
  94. package/dist/scripts/test-execution-generator.js.map +1 -0
  95. package/dist/scripts/test-interactive.d.ts +10 -0
  96. package/dist/scripts/test-interactive.d.ts.map +1 -0
  97. package/dist/scripts/test-interactive.js +627 -0
  98. package/dist/scripts/test-interactive.js.map +1 -0
  99. package/dist/scripts/test-new-features.d.ts +5 -0
  100. package/dist/scripts/test-new-features.d.ts.map +1 -0
  101. package/dist/scripts/test-new-features.js +145 -0
  102. package/dist/scripts/test-new-features.js.map +1 -0
  103. package/dist/scripts/test-spec-generator.d.ts +29 -0
  104. package/dist/scripts/test-spec-generator.d.ts.map +1 -0
  105. package/dist/scripts/test-spec-generator.js +494 -0
  106. package/dist/scripts/test-spec-generator.js.map +1 -0
  107. package/dist/scripts/test-workflow-stages.d.ts +6 -0
  108. package/dist/scripts/test-workflow-stages.d.ts.map +1 -0
  109. package/dist/scripts/test-workflow-stages.js +43 -0
  110. package/dist/scripts/test-workflow-stages.js.map +1 -0
  111. package/dist/scripts/utils/__tests__/aidlc-parser.test.d.ts +5 -0
  112. package/dist/scripts/utils/__tests__/aidlc-parser.test.d.ts.map +1 -0
  113. package/dist/scripts/utils/__tests__/aidlc-parser.test.js +315 -0
  114. package/dist/scripts/utils/__tests__/aidlc-parser.test.js.map +1 -0
  115. package/dist/scripts/utils/__tests__/business-days.test.d.ts +5 -0
  116. package/dist/scripts/utils/__tests__/business-days.test.d.ts.map +1 -0
  117. package/dist/scripts/utils/__tests__/business-days.test.js +171 -0
  118. package/dist/scripts/utils/__tests__/business-days.test.js.map +1 -0
  119. package/dist/scripts/utils/__tests__/config-loader.test.js +1 -1
  120. package/dist/scripts/utils/__tests__/config-loader.test.js.map +1 -1
  121. package/dist/scripts/utils/__tests__/config-validator.test.js +164 -35
  122. package/dist/scripts/utils/__tests__/config-validator.test.js.map +1 -1
  123. package/dist/scripts/utils/__tests__/env-config.test.d.ts +5 -0
  124. package/dist/scripts/utils/__tests__/env-config.test.d.ts.map +1 -0
  125. package/dist/scripts/utils/__tests__/env-config.test.js +218 -0
  126. package/dist/scripts/utils/__tests__/env-config.test.js.map +1 -0
  127. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.d.ts +5 -0
  128. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.d.ts.map +1 -0
  129. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.js +202 -0
  130. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.js.map +1 -0
  131. package/dist/scripts/utils/__tests__/tasks-converter.test.d.ts +5 -0
  132. package/dist/scripts/utils/__tests__/tasks-converter.test.d.ts.map +1 -0
  133. package/dist/scripts/utils/__tests__/tasks-converter.test.js +500 -0
  134. package/dist/scripts/utils/__tests__/tasks-converter.test.js.map +1 -0
  135. package/dist/scripts/utils/__tests__/tasks-format-validator.test.d.ts +5 -0
  136. package/dist/scripts/utils/__tests__/tasks-format-validator.test.d.ts.map +1 -0
  137. package/dist/scripts/utils/__tests__/tasks-format-validator.test.js +314 -0
  138. package/dist/scripts/utils/__tests__/tasks-format-validator.test.js.map +1 -0
  139. package/dist/scripts/utils/__tests__/test-runner.test.d.ts +5 -0
  140. package/dist/scripts/utils/__tests__/test-runner.test.d.ts.map +1 -0
  141. package/dist/scripts/utils/__tests__/test-runner.test.js +64 -0
  142. package/dist/scripts/utils/__tests__/test-runner.test.js.map +1 -0
  143. package/dist/scripts/utils/aidlc-parser.d.ts +86 -0
  144. package/dist/scripts/utils/aidlc-parser.d.ts.map +1 -0
  145. package/dist/scripts/utils/aidlc-parser.js +208 -0
  146. package/dist/scripts/utils/aidlc-parser.js.map +1 -0
  147. package/dist/scripts/utils/business-days.d.ts +52 -0
  148. package/dist/scripts/utils/business-days.d.ts.map +1 -0
  149. package/dist/scripts/utils/business-days.js +98 -0
  150. package/dist/scripts/utils/business-days.js.map +1 -0
  151. package/dist/scripts/utils/ci-generator.d.ts +14 -0
  152. package/dist/scripts/utils/ci-generator.d.ts.map +1 -0
  153. package/dist/scripts/utils/ci-generator.js +61 -0
  154. package/dist/scripts/utils/ci-generator.js.map +1 -0
  155. package/dist/scripts/utils/config-loader.js +2 -2
  156. package/dist/scripts/utils/config-loader.js.map +1 -1
  157. package/dist/scripts/utils/config-validator.d.ts +7 -1
  158. package/dist/scripts/utils/config-validator.d.ts.map +1 -1
  159. package/dist/scripts/utils/config-validator.js +136 -23
  160. package/dist/scripts/utils/config-validator.js.map +1 -1
  161. package/dist/scripts/utils/confluence-approval.d.ts +46 -0
  162. package/dist/scripts/utils/confluence-approval.d.ts.map +1 -0
  163. package/dist/scripts/utils/confluence-approval.js +118 -0
  164. package/dist/scripts/utils/confluence-approval.js.map +1 -0
  165. package/dist/scripts/utils/confluence-hierarchy.d.ts.map +1 -1
  166. package/dist/scripts/utils/confluence-hierarchy.js +1 -1
  167. package/dist/scripts/utils/confluence-hierarchy.js.map +1 -1
  168. package/dist/scripts/utils/docker-generator.d.ts +9 -0
  169. package/dist/scripts/utils/docker-generator.d.ts.map +1 -0
  170. package/dist/scripts/utils/docker-generator.js +132 -0
  171. package/dist/scripts/utils/docker-generator.js.map +1 -0
  172. package/dist/scripts/utils/docker-requirement-detector.d.ts +15 -0
  173. package/dist/scripts/utils/docker-requirement-detector.d.ts.map +1 -0
  174. package/dist/scripts/utils/docker-requirement-detector.js +124 -0
  175. package/dist/scripts/utils/docker-requirement-detector.js.map +1 -0
  176. package/dist/scripts/utils/env-config.d.ts +54 -0
  177. package/dist/scripts/utils/env-config.d.ts.map +1 -0
  178. package/dist/scripts/utils/env-config.js +414 -0
  179. package/dist/scripts/utils/env-config.js.map +1 -0
  180. package/dist/scripts/utils/jira-issue-type-fetcher.d.ts +70 -0
  181. package/dist/scripts/utils/jira-issue-type-fetcher.d.ts.map +1 -0
  182. package/dist/scripts/utils/jira-issue-type-fetcher.js +147 -0
  183. package/dist/scripts/utils/jira-issue-type-fetcher.js.map +1 -0
  184. package/dist/scripts/utils/language-detector.d.ts +14 -0
  185. package/dist/scripts/utils/language-detector.d.ts.map +1 -0
  186. package/dist/scripts/utils/language-detector.js +119 -0
  187. package/dist/scripts/utils/language-detector.js.map +1 -0
  188. package/dist/scripts/utils/markdown-parser.d.ts +55 -0
  189. package/dist/scripts/utils/markdown-parser.d.ts.map +1 -0
  190. package/dist/scripts/utils/markdown-parser.js +289 -0
  191. package/dist/scripts/utils/markdown-parser.js.map +1 -0
  192. package/dist/scripts/utils/project-detector.d.ts +17 -0
  193. package/dist/scripts/utils/project-detector.d.ts.map +1 -0
  194. package/dist/scripts/utils/project-detector.js +166 -0
  195. package/dist/scripts/utils/project-detector.js.map +1 -0
  196. package/dist/scripts/utils/project-finder.js +2 -2
  197. package/dist/scripts/utils/project-finder.js.map +1 -1
  198. package/dist/scripts/utils/release-notes-generator.d.ts +56 -0
  199. package/dist/scripts/utils/release-notes-generator.d.ts.map +1 -0
  200. package/dist/scripts/utils/release-notes-generator.js +162 -0
  201. package/dist/scripts/utils/release-notes-generator.js.map +1 -0
  202. package/dist/scripts/utils/spec-loader.d.ts +79 -0
  203. package/dist/scripts/utils/spec-loader.d.ts.map +1 -0
  204. package/dist/scripts/utils/spec-loader.js +80 -0
  205. package/dist/scripts/utils/spec-loader.js.map +1 -0
  206. package/dist/scripts/utils/spec-updater.d.ts +7 -0
  207. package/dist/scripts/utils/spec-updater.d.ts.map +1 -1
  208. package/dist/scripts/utils/spec-updater.js.map +1 -1
  209. package/dist/scripts/utils/tasks-converter.d.ts +57 -0
  210. package/dist/scripts/utils/tasks-converter.d.ts.map +1 -0
  211. package/dist/scripts/utils/tasks-converter.js +322 -0
  212. package/dist/scripts/utils/tasks-converter.js.map +1 -0
  213. package/dist/scripts/utils/tasks-format-validator.d.ts +36 -0
  214. package/dist/scripts/utils/tasks-format-validator.d.ts.map +1 -0
  215. package/dist/scripts/utils/tasks-format-validator.js +158 -0
  216. package/dist/scripts/utils/tasks-format-validator.js.map +1 -0
  217. package/dist/scripts/utils/template-applier.d.ts +37 -0
  218. package/dist/scripts/utils/template-applier.d.ts.map +1 -0
  219. package/dist/scripts/utils/template-applier.js +129 -0
  220. package/dist/scripts/utils/template-applier.js.map +1 -0
  221. package/dist/scripts/utils/template-finder.d.ts +37 -0
  222. package/dist/scripts/utils/template-finder.d.ts.map +1 -0
  223. package/dist/scripts/utils/template-finder.js +63 -0
  224. package/dist/scripts/utils/template-finder.js.map +1 -0
  225. package/dist/scripts/utils/test-config-generator.d.ts +12 -0
  226. package/dist/scripts/utils/test-config-generator.d.ts.map +1 -0
  227. package/dist/scripts/utils/test-config-generator.js +185 -0
  228. package/dist/scripts/utils/test-config-generator.js.map +1 -0
  229. package/dist/scripts/utils/test-runner.d.ts +31 -0
  230. package/dist/scripts/utils/test-runner.d.ts.map +1 -0
  231. package/dist/scripts/utils/test-runner.js +103 -0
  232. package/dist/scripts/utils/test-runner.js.map +1 -0
  233. package/dist/scripts/validate-phase.d.ts +1 -1
  234. package/dist/scripts/validate-phase.d.ts.map +1 -1
  235. package/dist/scripts/validate-phase.js +153 -5
  236. package/dist/scripts/validate-phase.js.map +1 -1
  237. package/dist/scripts/workflow-orchestrator.d.ts +8 -0
  238. package/dist/scripts/workflow-orchestrator.d.ts.map +1 -1
  239. package/dist/scripts/workflow-orchestrator.js +108 -7
  240. package/dist/scripts/workflow-orchestrator.js.map +1 -1
  241. package/dist/src/__tests__/integration/internationalization.test.d.ts +8 -0
  242. package/dist/src/__tests__/integration/internationalization.test.d.ts.map +1 -0
  243. package/dist/src/__tests__/integration/internationalization.test.js +333 -0
  244. package/dist/src/__tests__/integration/internationalization.test.js.map +1 -0
  245. package/dist/src/__tests__/integration/setup/claude-agent.test.d.ts +5 -0
  246. package/dist/src/__tests__/integration/setup/claude-agent.test.d.ts.map +1 -0
  247. package/dist/src/__tests__/integration/setup/claude-agent.test.js +122 -0
  248. package/dist/src/__tests__/integration/setup/claude-agent.test.js.map +1 -0
  249. package/dist/src/__tests__/integration/setup/claude.test.d.ts +5 -0
  250. package/dist/src/__tests__/integration/setup/claude.test.d.ts.map +1 -0
  251. package/dist/src/__tests__/integration/setup/claude.test.js +111 -0
  252. package/dist/src/__tests__/integration/setup/claude.test.js.map +1 -0
  253. package/dist/src/__tests__/integration/setup/cursor.test.d.ts +5 -0
  254. package/dist/src/__tests__/integration/setup/cursor.test.d.ts.map +1 -0
  255. package/dist/src/__tests__/integration/setup/cursor.test.js +166 -0
  256. package/dist/src/__tests__/integration/setup/cursor.test.js.map +1 -0
  257. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.d.ts +32 -0
  258. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.d.ts.map +1 -0
  259. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.js +72 -0
  260. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.js.map +1 -0
  261. package/dist/src/__tests__/integration/setup/helpers/test-project.d.ts +38 -0
  262. package/dist/src/__tests__/integration/setup/helpers/test-project.d.ts.map +1 -0
  263. package/dist/src/__tests__/integration/setup/helpers/test-project.js +83 -0
  264. package/dist/src/__tests__/integration/setup/helpers/test-project.js.map +1 -0
  265. package/dist/src/__tests__/integration/setup/validation.test.d.ts +5 -0
  266. package/dist/src/__tests__/integration/setup/validation.test.d.ts.map +1 -0
  267. package/dist/src/__tests__/integration/setup/validation.test.js +301 -0
  268. package/dist/src/__tests__/integration/setup/validation.test.js.map +1 -0
  269. package/dist/src/cli.d.ts.map +1 -1
  270. package/dist/src/cli.js +228 -18
  271. package/dist/src/cli.js.map +1 -1
  272. package/dist/src/commands/setup-existing.d.ts +25 -0
  273. package/dist/src/commands/setup-existing.d.ts.map +1 -0
  274. package/dist/src/commands/setup-existing.js +695 -0
  275. package/dist/src/commands/setup-existing.js.map +1 -0
  276. package/dist/vitest.config.d.ts.map +1 -1
  277. package/dist/vitest.config.js +4 -3
  278. package/dist/vitest.config.js.map +1 -1
  279. package/docs/README.md +3 -1
  280. package/docs/context.md +59 -0
  281. package/docs/design-issue-55.md +240 -0
  282. package/docs/design-issue-56.md +181 -0
  283. package/docs/michi-development/testing/manual-verification-flow.md +2242 -0
  284. package/docs/michi-development/testing/pre-publish-checklist.md +560 -0
  285. package/docs/plan.md +275 -0
  286. package/docs/user-guide/getting-started/github-token-setup.md +509 -0
  287. package/docs/{getting-started → user-guide/getting-started}/new-repository-setup.md +108 -28
  288. package/docs/{getting-started → user-guide/getting-started}/quick-start.md +73 -6
  289. package/docs/{getting-started → user-guide/getting-started}/setup.md +278 -3
  290. package/docs/{guides → user-guide/guides}/customization.md +3 -3
  291. package/docs/user-guide/guides/internationalization.md +540 -0
  292. package/docs/{guides → user-guide/guides}/multi-project.md +2 -2
  293. package/docs/{guides → user-guide/guides}/phase-automation.md +67 -9
  294. package/docs/user-guide/guides/workflow.md +582 -0
  295. package/docs/user-guide/hands-on/README.md +142 -0
  296. package/docs/user-guide/hands-on/claude-agent-setup.md +455 -0
  297. package/docs/user-guide/hands-on/claude-setup.md +398 -0
  298. package/docs/user-guide/hands-on/cursor-setup.md +352 -0
  299. package/docs/user-guide/hands-on/troubleshooting.md +964 -0
  300. package/docs/user-guide/hands-on/verification-checklist.md +438 -0
  301. package/docs/user-guide/hands-on/workflow-walkthrough.md +906 -0
  302. package/docs/user-guide/reference/config.md +564 -0
  303. package/docs/{reference → user-guide/reference}/quick-reference.md +75 -53
  304. package/docs/user-guide/release/ci-setup.md +541 -0
  305. package/docs/user-guide/release/release-flow.md +476 -0
  306. package/docs/user-guide/templates/test-specs/README.md +173 -0
  307. package/docs/user-guide/templates/test-specs/e2e-test-spec-template.md +547 -0
  308. package/docs/user-guide/templates/test-specs/integration-test-spec-template.md +435 -0
  309. package/docs/user-guide/templates/test-specs/performance-test-spec-template.md +454 -0
  310. package/docs/user-guide/templates/test-specs/security-test-spec-template.md +664 -0
  311. package/docs/user-guide/templates/test-specs/unit-test-spec-template.md +328 -0
  312. package/docs/user-guide/testing/integration-tests.md +312 -0
  313. package/docs/user-guide/testing/tdd-cycle.md +349 -0
  314. package/docs/user-guide/testing/test-execution-flow.md +396 -0
  315. package/docs/user-guide/testing/test-failure-handling.md +521 -0
  316. package/docs/user-guide/testing/test-planning-flow.md +181 -0
  317. package/docs/user-guide/testing-strategy.md +185 -0
  318. package/docs/verification-guide.md +518 -0
  319. package/package.json +13 -3
  320. package/scripts/__tests__/create-project.test.ts +67 -49
  321. package/scripts/__tests__/jira-transitions.test.ts +225 -0
  322. package/scripts/__tests__/multi-project-estimate.test.ts +36 -30
  323. package/scripts/__tests__/setup-existing-project.test.ts +171 -6
  324. package/scripts/__tests__/setup-interactive.test.ts +52 -46
  325. package/scripts/__tests__/spec-impl-workflow.test.ts +429 -0
  326. package/scripts/__tests__/spec-loader.test.ts +199 -0
  327. package/scripts/__tests__/validate-phase.test.ts +78 -54
  328. package/scripts/config/config-schema.ts +89 -50
  329. package/scripts/config-interactive.ts +191 -136
  330. package/scripts/confluence-sync.ts +0 -12
  331. package/scripts/constants/__tests__/environments.test.ts +146 -0
  332. package/scripts/constants/__tests__/languages.test.ts +100 -0
  333. package/scripts/constants/environments.ts +81 -0
  334. package/scripts/constants/languages.ts +70 -0
  335. package/scripts/constants/test-commands.ts +96 -0
  336. package/scripts/create-project.ts +52 -22
  337. package/scripts/jira-sync.ts +767 -232
  338. package/scripts/markdown-to-confluence.ts +1 -1
  339. package/scripts/phase-runner.ts +1056 -63
  340. package/scripts/pr-automation.ts +0 -1
  341. package/scripts/pre-flight-check.ts +1 -1
  342. package/scripts/pre-publish-check.sh +311 -0
  343. package/scripts/quick-verify.sh +115 -0
  344. package/scripts/setup-existing-project.ts +306 -143
  345. package/scripts/setup-interactive.ts +4 -4
  346. package/scripts/spec-impl-workflow.ts +505 -0
  347. package/scripts/template/__tests__/renderer.test.ts +206 -0
  348. package/scripts/template/renderer.ts +133 -0
  349. package/scripts/test-execution-generator.ts +695 -0
  350. package/scripts/test-interactive.ts +779 -0
  351. package/scripts/test-new-features.ts +168 -0
  352. package/scripts/test-npm-package.sh +345 -0
  353. package/scripts/test-spec-generator.ts +574 -0
  354. package/scripts/test-workflow-stages.ts +53 -0
  355. package/scripts/utils/__tests__/aidlc-parser.test.ts +349 -0
  356. package/scripts/utils/__tests__/business-days.test.ts +214 -0
  357. package/scripts/utils/__tests__/config-loader.test.ts +1 -1
  358. package/scripts/utils/__tests__/config-validator.test.ts +309 -88
  359. package/scripts/utils/__tests__/env-config.test.ts +259 -0
  360. package/scripts/utils/__tests__/jira-issue-type-fetcher.test.ts +272 -0
  361. package/scripts/utils/__tests__/tasks-converter.test.ts +582 -0
  362. package/scripts/utils/__tests__/tasks-format-validator.test.ts +338 -0
  363. package/scripts/utils/__tests__/test-runner.test.ts +77 -0
  364. package/scripts/utils/aidlc-parser.ts +289 -0
  365. package/scripts/utils/business-days.ts +115 -0
  366. package/scripts/utils/ci-generator.ts +84 -0
  367. package/scripts/utils/config-loader.ts +2 -2
  368. package/scripts/utils/config-validator.ts +304 -117
  369. package/scripts/utils/confluence-approval.ts +167 -0
  370. package/scripts/utils/confluence-hierarchy.ts +2 -4
  371. package/scripts/utils/docker-generator.ts +151 -0
  372. package/scripts/utils/docker-requirement-detector.ts +153 -0
  373. package/scripts/utils/env-config.ts +526 -0
  374. package/scripts/utils/jira-issue-type-fetcher.ts +199 -0
  375. package/scripts/utils/language-detector.ts +139 -0
  376. package/scripts/utils/markdown-parser.ts +376 -0
  377. package/scripts/utils/project-detector.ts +192 -0
  378. package/scripts/utils/project-finder.ts +2 -2
  379. package/scripts/utils/release-notes-generator.ts +210 -0
  380. package/scripts/utils/spec-loader.ts +125 -0
  381. package/scripts/utils/spec-updater.ts +8 -1
  382. package/scripts/utils/tasks-converter.ts +601 -0
  383. package/scripts/utils/tasks-format-validator.ts +193 -0
  384. package/scripts/utils/template-applier.ts +202 -0
  385. package/scripts/utils/template-finder.ts +75 -0
  386. package/scripts/utils/test-config-generator.ts +210 -0
  387. package/scripts/utils/test-runner.ts +133 -0
  388. package/scripts/validate-phase.ts +186 -9
  389. package/scripts/workflow-orchestrator.ts +130 -12
  390. package/templates/ci/github-actions/java.yml +54 -0
  391. package/templates/ci/github-actions/nodejs.yml +46 -0
  392. package/templates/ci/github-actions/php.yml +52 -0
  393. package/templates/ci/screwdriver/java.yaml +17 -0
  394. package/templates/ci/screwdriver/nodejs.yaml +17 -0
  395. package/templates/ci/screwdriver/php.yaml +20 -0
  396. package/templates/claude/commands/kiro/kiro-spec-impl.md +244 -0
  397. package/templates/claude/commands/kiro/kiro-spec-tasks.md +354 -0
  398. package/templates/claude/commands/michi/confluence-sync.md +38 -0
  399. package/templates/claude/commands/michi/project-switch.md +36 -0
  400. package/templates/claude/rules/atlassian-integration.md +35 -0
  401. package/templates/claude/rules/michi-core.md +54 -0
  402. package/templates/claude-agent/README.md +31 -0
  403. package/templates/claude-agent/agents/.gitkeep +0 -0
  404. package/templates/claude-agent/agents/designer.md +79 -0
  405. package/templates/claude-agent/agents/developer.md +68 -0
  406. package/templates/claude-agent/agents/manager-agent.md +59 -0
  407. package/templates/claude-agent/agents/tester.md +101 -0
  408. package/templates/claude-agent/commands/kiro/.gitkeep +0 -0
  409. package/templates/claude-agent/commands/kiro/kiro-spec-impl.md +244 -0
  410. package/templates/claude-agent/commands/kiro/kiro-spec-tasks.md +354 -0
  411. package/templates/cline/rules/atlassian-integration.md +36 -0
  412. package/templates/cline/rules/michi-core.md +56 -0
  413. package/templates/codex/AGENTS.override.md +277 -0
  414. package/templates/codex/prompts/confluence-sync.md +177 -0
  415. package/templates/codex/rules/README.md +210 -0
  416. package/templates/common/.kiro/project.json.template +21 -0
  417. package/templates/cursor/commands/kiro/kiro-spec-impl.md +244 -0
  418. package/templates/cursor/commands/kiro/kiro-spec-tasks.md +354 -0
  419. package/templates/cursor/commands/michi/confluence-sync.md +76 -0
  420. package/templates/cursor/commands/michi/project-switch.md +69 -0
  421. package/templates/cursor/rules/atlassian-mcp.mdc +188 -0
  422. package/templates/cursor/rules/github-ssot.mdc +151 -0
  423. package/templates/cursor/rules/multi-project.mdc +81 -0
  424. package/templates/gemini/commands/README.md +41 -0
  425. package/templates/gemini/rules/GEMINI.md +80 -0
  426. package/docs/guides/workflow.md +0 -342
  427. package/docs/reference/config.md +0 -545
  428. package/scripts/setup-env.sh +0 -52
  429. package/scripts/setup-existing.sh +0 -152
  430. /package/docs/{contributing → michi-development/contributing}/development.md +0 -0
  431. /package/docs/{contributing → michi-development/contributing}/release.md +0 -0
  432. /package/docs/{testing-strategy.md → michi-development/testing-strategy.md} +0 -0
  433. /package/docs/{reference → user-guide/reference}/tasks-template.md +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sk8metal/michi-cli",
3
- "version": "0.0.8",
3
+ "version": "0.1.0",
4
4
  "description": "Managed Intelligent Comprehensive Hub for Integration - AI-driven development workflow automation",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -34,6 +34,7 @@
34
34
  "files": [
35
35
  "dist",
36
36
  "scripts",
37
+ "templates",
37
38
  "docs",
38
39
  "README.md",
39
40
  "CHANGELOG.md",
@@ -45,8 +46,10 @@
45
46
  "build": "tsc && node scripts/copy-static-assets.js",
46
47
  "postbuild": "node scripts/set-permissions.js",
47
48
  "prepare": "husky",
48
- "setup:env": "bash scripts/setup-env.sh",
49
49
  "setup:interactive": "tsx scripts/setup-interactive.ts",
50
+ "michi:setup:cursor": "tsx src/cli.ts setup-existing --cursor",
51
+ "michi:setup:claude": "tsx src/cli.ts setup-existing --claude",
52
+ "michi:setup:claude-agent": "tsx src/cli.ts setup-existing --claude-agent",
50
53
  "create-project": "tsx scripts/create-project.ts",
51
54
  "setup-existing": "tsx scripts/setup-existing-project.ts",
52
55
  "confluence:sync": "tsx scripts/confluence-sync.ts",
@@ -61,12 +64,17 @@
61
64
  "validate:phase": "tsx scripts/validate-phase.ts",
62
65
  "phase:run": "tsx scripts/phase-runner.ts",
63
66
  "preflight": "tsx scripts/pre-flight-check.ts",
67
+ "pre-publish": "bash scripts/pre-publish-check.sh",
68
+ "test:package": "bash scripts/test-npm-package.sh",
64
69
  "config:interactive": "tsx scripts/config-interactive.ts",
65
70
  "config:validate": "tsx scripts/utils/config-validator.ts",
71
+ "test:interactive": "tsx scripts/test-interactive.ts",
66
72
  "test": "vitest",
67
73
  "test:run": "vitest --run",
68
74
  "test:ui": "vitest --ui",
69
75
  "test:coverage": "vitest --run --coverage",
76
+ "test:integration:setup": "vitest --run src/__tests__/integration/setup",
77
+ "test:coverage:setup": "vitest --run --coverage src/__tests__/integration/setup",
70
78
  "lint": "eslint .",
71
79
  "lint:fix": "eslint . --fix",
72
80
  "format": "prettier --write .",
@@ -76,9 +84,10 @@
76
84
  "@octokit/rest": "^22.0.1",
77
85
  "axios": "^1.13.1",
78
86
  "commander": "^14.0.2",
79
- "dotenv": "^16.3.1",
87
+ "dotenv": "^17.2.3",
80
88
  "exceljs": "^4.4.0",
81
89
  "googleapis": "^166.0.0",
90
+ "inquirer": "^9.2.12",
82
91
  "jira-client": "^8.2.2",
83
92
  "markdown-it": "^14.0.0",
84
93
  "turndown": "^7.1.2",
@@ -86,6 +95,7 @@
86
95
  },
87
96
  "devDependencies": {
88
97
  "@eslint/js": "^9.39.1",
98
+ "@types/inquirer": "^9.0.7",
89
99
  "@types/markdown-it": "^14.1.2",
90
100
  "@types/node": "^24.10.1",
91
101
  "@types/turndown": "^5.0.4",
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
- import { execSync } from 'child_process';
2
+ import { execSync, type ExecSyncOptions } from 'child_process';
3
3
  import { join } from 'path';
4
4
 
5
5
  // モジュールのモック
@@ -8,7 +8,7 @@ vi.mock('fs', () => ({
8
8
  existsSync: vi.fn(() => true),
9
9
  mkdirSync: vi.fn(),
10
10
  cpSync: vi.fn(),
11
- writeFileSync: vi.fn()
11
+ writeFileSync: vi.fn(),
12
12
  }));
13
13
  vi.mock('dotenv', () => ({ config: vi.fn() }));
14
14
 
@@ -27,8 +27,14 @@ describe('create-project.ts パス問題', () => {
27
27
  expect(cursorRulesPath).not.toContain(join(projectDir, '.cursor'));
28
28
 
29
29
  // .cursor/commands のコピー先パスを検証
30
- const cursorCommandsPath = join(actualProjectDir, '.cursor/commands/kiro', 'test.md');
31
- expect(cursorCommandsPath).toContain('projects/test-project/.cursor/commands');
30
+ const cursorCommandsPath = join(
31
+ actualProjectDir,
32
+ '.cursor/commands/kiro',
33
+ 'test.md',
34
+ );
35
+ expect(cursorCommandsPath).toContain(
36
+ 'projects/test-project/.cursor/commands',
37
+ );
32
38
 
33
39
  // .kiro/steering のコピー先パスを検証
34
40
  const kiroSteeringPath = join(actualProjectDir, '.kiro/steering');
@@ -61,11 +67,11 @@ describe('create-project.ts パス問題', () => {
61
67
  join(actualProjectDir, '.cursor/commands/kiro'),
62
68
  join(actualProjectDir, '.kiro/steering'),
63
69
  join(actualProjectDir, '.kiro/settings/templates'),
64
- join(actualProjectDir, 'scripts/utils')
70
+ join(actualProjectDir, 'scripts/utils'),
65
71
  ];
66
72
 
67
73
  // すべてのディレクトリが actualProjectDir 配下にあることを確認
68
- directories.forEach(dir => {
74
+ directories.forEach((dir) => {
69
75
  expect(dir).toContain('projects/test-project');
70
76
  expect(dir.startsWith(actualProjectDir)).toBe(true);
71
77
  });
@@ -98,7 +104,7 @@ describe('create-project.ts jj/git 依存性', () => {
98
104
  try {
99
105
  const jjVersion = execSync('jj --version', {
100
106
  encoding: 'utf-8',
101
- stdio: ['pipe', 'pipe', 'pipe']
107
+ stdio: ['pipe', 'pipe', 'pipe'],
102
108
  }).trim();
103
109
  return { vcs: 'jj' as const, version: jjVersion };
104
110
  } catch {
@@ -110,7 +116,7 @@ describe('create-project.ts jj/git 依存性', () => {
110
116
  expect(result.vcs).toBe('jj');
111
117
  expect(mockExecSync).toHaveBeenCalledWith(
112
118
  'jj --version',
113
- expect.objectContaining({ encoding: 'utf-8' })
119
+ expect.objectContaining({ encoding: 'utf-8' }),
114
120
  );
115
121
  });
116
122
 
@@ -131,14 +137,14 @@ describe('create-project.ts jj/git 依存性', () => {
131
137
  try {
132
138
  const jjVersion = execSync('jj --version', {
133
139
  encoding: 'utf-8',
134
- stdio: ['pipe', 'pipe', 'pipe']
140
+ stdio: ['pipe', 'pipe', 'pipe'],
135
141
  }).trim();
136
142
  return { vcs: 'jj' as const, version: jjVersion };
137
143
  } catch {
138
144
  try {
139
145
  const gitVersion = execSync('git --version', {
140
146
  encoding: 'utf-8',
141
- stdio: ['pipe', 'pipe', 'pipe']
147
+ stdio: ['pipe', 'pipe', 'pipe'],
142
148
  }).trim();
143
149
  return { vcs: 'git' as const, version: gitVersion };
144
150
  } catch {
@@ -150,8 +156,16 @@ describe('create-project.ts jj/git 依存性', () => {
150
156
  const result = checkDeps();
151
157
  expect(result.vcs).toBe('git');
152
158
  expect(mockExecSync).toHaveBeenCalledTimes(2);
153
- expect(mockExecSync).toHaveBeenNthCalledWith(1, 'jj --version', expect.anything());
154
- expect(mockExecSync).toHaveBeenNthCalledWith(2, 'git --version', expect.anything());
159
+ expect(mockExecSync).toHaveBeenNthCalledWith(
160
+ 1,
161
+ 'jj --version',
162
+ expect.anything(),
163
+ );
164
+ expect(mockExecSync).toHaveBeenNthCalledWith(
165
+ 2,
166
+ 'git --version',
167
+ expect.anything(),
168
+ );
155
169
  });
156
170
 
157
171
  it('jj も git も未インストール時はエラーを投げる', () => {
@@ -165,14 +179,14 @@ describe('create-project.ts jj/git 依存性', () => {
165
179
  try {
166
180
  const jjVersion = execSync('jj --version', {
167
181
  encoding: 'utf-8',
168
- stdio: ['pipe', 'pipe', 'pipe']
182
+ stdio: ['pipe', 'pipe', 'pipe'],
169
183
  }).trim();
170
184
  return { vcs: 'jj' as const, version: jjVersion };
171
185
  } catch {
172
186
  try {
173
187
  const gitVersion = execSync('git --version', {
174
188
  encoding: 'utf-8',
175
- stdio: ['pipe', 'pipe', 'pipe']
189
+ stdio: ['pipe', 'pipe', 'pipe'],
176
190
  }).trim();
177
191
  return { vcs: 'git' as const, version: gitVersion };
178
192
  } catch {
@@ -189,18 +203,26 @@ describe('create-project.ts jj/git 依存性', () => {
189
203
  const projectDir = '/test/repo';
190
204
 
191
205
  // jj の場合
192
- const jjDeps: { vcs: 'jj' | 'git'; version: string } = { vcs: 'jj', version: 'jj 0.15.0' };
193
- const jjCommand = jjDeps.vcs === 'jj'
194
- ? `jj git clone ${repoUrl} ${projectDir}`
195
- : `git clone ${repoUrl} ${projectDir}`;
206
+ const jjDeps: { vcs: 'jj' | 'git'; version: string } = {
207
+ vcs: 'jj',
208
+ version: 'jj 0.15.0',
209
+ };
210
+ const jjCommand =
211
+ jjDeps.vcs === 'jj'
212
+ ? `jj git clone ${repoUrl} ${projectDir}`
213
+ : `git clone ${repoUrl} ${projectDir}`;
196
214
 
197
215
  expect(jjCommand).toBe(`jj git clone ${repoUrl} ${projectDir}`);
198
216
 
199
217
  // git の場合
200
- const gitDeps: { vcs: 'jj' | 'git'; version: string } = { vcs: 'git', version: 'git version 2.40' };
201
- const gitCommand = gitDeps.vcs === 'jj'
202
- ? `jj git clone ${repoUrl} ${projectDir}`
203
- : `git clone ${repoUrl} ${projectDir}`;
218
+ const gitDeps: { vcs: 'jj' | 'git'; version: string } = {
219
+ vcs: 'git',
220
+ version: 'git version 2.40',
221
+ };
222
+ const gitCommand =
223
+ gitDeps.vcs === 'jj'
224
+ ? `jj git clone ${repoUrl} ${projectDir}`
225
+ : `git clone ${repoUrl} ${projectDir}`;
204
226
 
205
227
  expect(gitCommand).toBe(`git clone ${repoUrl} ${projectDir}`);
206
228
  });
@@ -210,28 +232,20 @@ describe('create-project.ts jj/git 依存性', () => {
210
232
 
211
233
  // jj の場合のコマンド群
212
234
  const jjDeps: { vcs: 'jj' | 'git' } = { vcs: 'jj' };
213
- const jjCommands = jjDeps.vcs === 'jj' ? [
214
- `jj commit -m "${message}"`,
215
- 'jj bookmark create main -r "@-"'
216
- ] : [
217
- 'git add .',
218
- `git commit -m "${message}"`,
219
- 'git branch -M main'
220
- ];
235
+ const jjCommands =
236
+ jjDeps.vcs === 'jj'
237
+ ? [`jj commit -m "${message}"`, 'jj bookmark create main -r "@-"']
238
+ : ['git add .', `git commit -m "${message}"`, 'git branch -M main'];
221
239
 
222
240
  expect(jjCommands).toContain('jj commit -m "chore: initial commit"');
223
241
  expect(jjCommands).toContain('jj bookmark create main -r "@-"');
224
242
 
225
243
  // git の場合のコマンド群
226
244
  const gitDeps: { vcs: 'jj' | 'git' } = { vcs: 'git' };
227
- const gitCommands = gitDeps.vcs === 'jj' ? [
228
- `jj commit -m "${message}"`,
229
- 'jj bookmark create main -r "@-"'
230
- ] : [
231
- 'git add .',
232
- `git commit -m "${message}"`,
233
- 'git branch -M main'
234
- ];
245
+ const gitCommands =
246
+ gitDeps.vcs === 'jj'
247
+ ? [`jj commit -m "${message}"`, 'jj bookmark create main -r "@-"']
248
+ : ['git add .', `git commit -m "${message}"`, 'git branch -M main'];
235
249
 
236
250
  expect(gitCommands).toContain('git add .');
237
251
  expect(gitCommands).toContain('git commit -m "chore: initial commit"');
@@ -256,22 +270,24 @@ describe('create-project.ts .env作成時のcwd修正', () => {
256
270
  const actualProjectDir = '/test/repo/projects/test-project';
257
271
 
258
272
  // execSync の呼び出しをモック
259
- mockExecSync.mockImplementation((command: string, options?: any) => {
260
- if (command === 'npm run setup:env') {
261
- // cwd actualProjectDir であることを確認
262
- expect(options?.cwd).toBe(actualProjectDir);
263
- expect(options?.cwd).not.toBe(projectDir);
264
- return '';
265
- }
266
- return '';
267
- });
273
+ mockExecSync.mockImplementation(
274
+ (command: string, options?: ExecSyncOptions) => {
275
+ if (command === 'npm run setup:env') {
276
+ // cwdactualProjectDir であることを確認
277
+ expect(options?.cwd).toBe(actualProjectDir);
278
+ expect(options?.cwd).not.toBe(projectDir);
279
+ return Buffer.from('');
280
+ }
281
+ return Buffer.from('');
282
+ },
283
+ );
268
284
 
269
285
  // .env作成のロジックを再現
270
286
  execSync('npm run setup:env', { cwd: actualProjectDir, stdio: 'inherit' });
271
287
 
272
288
  expect(mockExecSync).toHaveBeenCalledWith(
273
289
  'npm run setup:env',
274
- expect.objectContaining({ cwd: actualProjectDir })
290
+ expect.objectContaining({ cwd: actualProjectDir }),
275
291
  );
276
292
  });
277
293
 
@@ -287,6 +303,8 @@ describe('create-project.ts .env作成時のcwd修正', () => {
287
303
  expect(envPathInActualProjectDir).toContain('projects/test-project/.env');
288
304
  expect(envPathInActualProjectDir).not.toBe(envPathInProjectDir);
289
305
  expect(envPathInProjectDir).toBe('/test/repo/.env');
290
- expect(envPathInActualProjectDir).toBe('/test/repo/projects/test-project/.env');
306
+ expect(envPathInActualProjectDir).toBe(
307
+ '/test/repo/projects/test-project/.env',
308
+ );
291
309
  });
292
310
  });
@@ -0,0 +1,225 @@
1
+ /**
2
+ * JIRAClient transitionIssue() と addComment() のテスト
3
+ */
4
+
5
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
6
+ import axios from 'axios';
7
+
8
+ // axiosをモック
9
+ vi.mock('axios');
10
+
11
+ // dotenvをモック
12
+ vi.mock('dotenv', () => ({ config: vi.fn() }));
13
+
14
+ describe('JIRAClient transitions', () => {
15
+ const mockAxiosGet = vi.mocked(axios.get);
16
+ const mockAxiosPost = vi.mocked(axios.post);
17
+ const mockAxiosIsAxiosError = vi.mocked(axios.isAxiosError);
18
+
19
+ beforeEach(() => {
20
+ vi.clearAllMocks();
21
+ // isAxiosError をデフォルトでtrueに
22
+ mockAxiosIsAxiosError.mockReturnValue(true);
23
+ });
24
+
25
+ afterEach(() => {
26
+ vi.restoreAllMocks();
27
+ });
28
+
29
+ describe('transitionIssue', () => {
30
+ it('利用可能なトランジションを取得してステータスを変更できる', async () => {
31
+ // トランジション一覧のモック
32
+ mockAxiosGet.mockResolvedValueOnce({
33
+ data: {
34
+ transitions: [
35
+ { id: '21', name: 'In Progress' },
36
+ { id: '31', name: 'Done' },
37
+ { id: '41', name: 'Ready for Review' },
38
+ ],
39
+ },
40
+ });
41
+
42
+ // トランジション実行のモック
43
+ mockAxiosPost.mockResolvedValueOnce({
44
+ data: {},
45
+ });
46
+
47
+ // JIRAClientをインポート(モック設定後)
48
+ const { JIRAClient } = await import('../jira-sync.js');
49
+ const client = new JIRAClient({
50
+ url: 'https://test.atlassian.net',
51
+ email: 'test@example.com',
52
+ apiToken: 'test-token',
53
+ });
54
+
55
+ await client.transitionIssue('PROJ-123', 'In Progress');
56
+
57
+ // GETリクエストの検証
58
+ expect(mockAxiosGet).toHaveBeenCalledWith(
59
+ 'https://test.atlassian.net/rest/api/3/issue/PROJ-123/transitions',
60
+ expect.objectContaining({
61
+ headers: expect.objectContaining({
62
+ 'Content-Type': 'application/json',
63
+ }),
64
+ }),
65
+ );
66
+
67
+ // POSTリクエストの検証
68
+ expect(mockAxiosPost).toHaveBeenCalledWith(
69
+ 'https://test.atlassian.net/rest/api/3/issue/PROJ-123/transitions',
70
+ { transition: { id: '21' } },
71
+ expect.objectContaining({
72
+ headers: expect.objectContaining({
73
+ 'Content-Type': 'application/json',
74
+ }),
75
+ }),
76
+ );
77
+ });
78
+
79
+ it('部分一致でトランジションを検索できる', async () => {
80
+ mockAxiosGet.mockResolvedValueOnce({
81
+ data: {
82
+ transitions: [
83
+ { id: '21', name: 'Start Progress' },
84
+ { id: '31', name: 'Complete' },
85
+ ],
86
+ },
87
+ });
88
+
89
+ mockAxiosPost.mockResolvedValueOnce({
90
+ data: {},
91
+ });
92
+
93
+ const { JIRAClient } = await import('../jira-sync.js');
94
+ const client = new JIRAClient({
95
+ url: 'https://test.atlassian.net',
96
+ email: 'test@example.com',
97
+ apiToken: 'test-token',
98
+ });
99
+
100
+ // "Progress" で部分一致
101
+ await client.transitionIssue('PROJ-123', 'Progress');
102
+
103
+ expect(mockAxiosPost).toHaveBeenCalledWith(
104
+ expect.any(String),
105
+ { transition: { id: '21' } },
106
+ expect.any(Object),
107
+ );
108
+ });
109
+
110
+ it('トランジションが見つからない場合はエラーをスロー', async () => {
111
+ mockAxiosGet.mockResolvedValueOnce({
112
+ data: {
113
+ transitions: [
114
+ { id: '21', name: 'In Progress' },
115
+ { id: '31', name: 'Done' },
116
+ ],
117
+ },
118
+ });
119
+
120
+ const { JIRAClient } = await import('../jira-sync.js');
121
+ const client = new JIRAClient({
122
+ url: 'https://test.atlassian.net',
123
+ email: 'test@example.com',
124
+ apiToken: 'test-token',
125
+ });
126
+
127
+ await expect(
128
+ client.transitionIssue('PROJ-123', 'NonExistent'),
129
+ ).rejects.toThrow(/Transition "NonExistent" not found/);
130
+ });
131
+
132
+ it('利用可能なトランジションがない場合もエラーをスロー', async () => {
133
+ mockAxiosGet.mockResolvedValueOnce({
134
+ data: {
135
+ transitions: [],
136
+ },
137
+ });
138
+
139
+ const { JIRAClient } = await import('../jira-sync.js');
140
+ const client = new JIRAClient({
141
+ url: 'https://test.atlassian.net',
142
+ email: 'test@example.com',
143
+ apiToken: 'test-token',
144
+ });
145
+
146
+ await expect(
147
+ client.transitionIssue('PROJ-123', 'In Progress'),
148
+ ).rejects.toThrow(/Available transitions: none/);
149
+ });
150
+ });
151
+
152
+ describe('addComment', () => {
153
+ it('コメントを追加できる', async () => {
154
+ mockAxiosPost.mockResolvedValueOnce({
155
+ data: {
156
+ id: 'comment-123',
157
+ },
158
+ });
159
+
160
+ const { JIRAClient } = await import('../jira-sync.js');
161
+ const client = new JIRAClient({
162
+ url: 'https://test.atlassian.net',
163
+ email: 'test@example.com',
164
+ apiToken: 'test-token',
165
+ });
166
+
167
+ await client.addComment(
168
+ 'PROJ-123',
169
+ 'PRを作成しました: https://github.com/...',
170
+ );
171
+
172
+ expect(mockAxiosPost).toHaveBeenCalledWith(
173
+ 'https://test.atlassian.net/rest/api/3/issue/PROJ-123/comment',
174
+ {
175
+ body: {
176
+ type: 'doc',
177
+ version: 1,
178
+ content: [
179
+ {
180
+ type: 'paragraph',
181
+ content: [
182
+ {
183
+ type: 'text',
184
+ text: 'PRを作成しました: https://github.com/...',
185
+ },
186
+ ],
187
+ },
188
+ ],
189
+ },
190
+ },
191
+ expect.objectContaining({
192
+ headers: expect.objectContaining({
193
+ 'Content-Type': 'application/json',
194
+ }),
195
+ }),
196
+ );
197
+ });
198
+
199
+ it('APIエラー時は適切なエラーメッセージを表示', async () => {
200
+ mockAxiosPost.mockRejectedValueOnce({
201
+ response: {
202
+ status: 404,
203
+ data: {
204
+ errorMessages: ['Issue Does Not Exist'],
205
+ },
206
+ },
207
+ });
208
+
209
+ const { JIRAClient } = await import('../jira-sync.js');
210
+ const client = new JIRAClient({
211
+ url: 'https://test.atlassian.net',
212
+ email: 'test@example.com',
213
+ apiToken: 'test-token',
214
+ });
215
+
216
+ await expect(
217
+ client.addComment('PROJ-999', 'test comment'),
218
+ ).rejects.toMatchObject({
219
+ response: {
220
+ status: 404,
221
+ },
222
+ });
223
+ });
224
+ });
225
+ });
@@ -1,5 +1,4 @@
1
1
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
- import type { Octokit } from '@octokit/rest';
3
2
 
4
3
  // モジュールのモック
5
4
  vi.mock('@octokit/rest');
@@ -7,11 +6,17 @@ vi.mock('dotenv', () => ({ config: vi.fn() }));
7
6
  vi.mock('fs', () => ({
8
7
  existsSync: vi.fn(),
9
8
  writeFileSync: vi.fn(),
10
- mkdirSync: vi.fn()
9
+ mkdirSync: vi.fn(),
11
10
  }));
12
11
 
13
12
  describe('multi-project-estimate pagination', () => {
14
- let mockOctokit: any;
13
+ let mockOctokit: {
14
+ paginate: ReturnType<typeof vi.fn>;
15
+ repos: {
16
+ listForOrg: ReturnType<typeof vi.fn>;
17
+ getContent: ReturnType<typeof vi.fn>;
18
+ };
19
+ };
15
20
  let originalEnv: NodeJS.ProcessEnv;
16
21
 
17
22
  beforeEach(() => {
@@ -25,8 +30,8 @@ describe('multi-project-estimate pagination', () => {
25
30
  paginate: vi.fn(),
26
31
  repos: {
27
32
  listForOrg: vi.fn(),
28
- getContent: vi.fn()
29
- }
33
+ getContent: vi.fn(),
34
+ },
30
35
  };
31
36
 
32
37
  vi.clearAllMocks();
@@ -41,12 +46,12 @@ describe('multi-project-estimate pagination', () => {
41
46
  // 150リポジトリをシミュレート
42
47
  const mockRepos = Array.from({ length: 150 }, (_, i) => ({
43
48
  name: `repo-${i}`,
44
- owner: { login: 'test-org' }
49
+ owner: { login: 'test-org' },
45
50
  }));
46
51
 
47
52
  mockOctokit.paginate
48
- .mockResolvedValueOnce(mockRepos) // repos.listForOrg
49
- .mockResolvedValue([]); // その後の呼び出しは空配列
53
+ .mockResolvedValueOnce(mockRepos) // repos.listForOrg
54
+ .mockResolvedValue([]); // その後の呼び出しは空配列
50
55
 
51
56
  // 検証: paginateが正しいパラメータで呼ばれることを確認
52
57
  // 実際のテストでは、multi-project-estimate.tsのaggregateEstimates関数を
@@ -60,13 +65,13 @@ describe('multi-project-estimate pagination', () => {
60
65
  // 50個のprojectsをシミュレート
61
66
  const mockProjects = Array.from({ length: 50 }, (_, i) => ({
62
67
  name: `project-${i}`,
63
- type: 'dir' as const
68
+ type: 'dir' as const,
64
69
  }));
65
70
 
66
71
  mockOctokit.paginate
67
- .mockResolvedValueOnce([{ name: 'test-repo' }]) // repos
68
- .mockResolvedValueOnce(mockProjects) // projects
69
- .mockResolvedValue([]); // その後の呼び出し
72
+ .mockResolvedValueOnce([{ name: 'test-repo' }]) // repos
73
+ .mockResolvedValueOnce(mockProjects) // projects
74
+ .mockResolvedValue([]); // その後の呼び出し
70
75
 
71
76
  // pagination が 'GET /repos/{owner}/{repo}/contents/{path}' 形式で
72
77
  // 呼ばれることを確認するためのアサーション用意
@@ -77,13 +82,13 @@ describe('multi-project-estimate pagination', () => {
77
82
  // 50個のspecsをシミュレート
78
83
  const mockSpecs = Array.from({ length: 50 }, (_, i) => ({
79
84
  name: `spec-${i}`,
80
- type: 'dir' as const
85
+ type: 'dir' as const,
81
86
  }));
82
87
 
83
88
  mockOctokit.paginate
84
- .mockResolvedValueOnce([{ name: 'test-repo' }]) // repos
85
- .mockResolvedValueOnce([{ name: 'project-1', type: 'dir' }]) // projects
86
- .mockResolvedValueOnce(mockSpecs); // specs
89
+ .mockResolvedValueOnce([{ name: 'test-repo' }]) // repos
90
+ .mockResolvedValueOnce([{ name: 'project-1', type: 'dir' }]) // projects
91
+ .mockResolvedValueOnce(mockSpecs); // specs
87
92
 
88
93
  // specsの取得で pagination が使われることを確認
89
94
  expect(mockSpecs.length).toBe(50);
@@ -92,19 +97,23 @@ describe('multi-project-estimate pagination', () => {
92
97
  it('型ガードが正しく機能してunknown型を処理する', () => {
93
98
  const validEntry = {
94
99
  type: 'dir' as const,
95
- name: 'test-project'
100
+ name: 'test-project',
96
101
  };
97
102
 
98
103
  const invalidEntry = {
99
104
  type: 'file' as const,
100
- name: 'test.txt'
105
+ name: 'test.txt',
101
106
  };
102
107
 
103
108
  // 型ガードのロジック(multi-project-estimate.ts と同じ)
104
- const isValidDir = (entry: any): boolean => {
105
- return typeof entry === 'object' && entry !== null &&
106
- 'type' in entry && entry.type === 'dir' &&
107
- 'name' in entry;
109
+ const isValidDir = (entry: unknown): boolean => {
110
+ return (
111
+ typeof entry === 'object' &&
112
+ entry !== null &&
113
+ 'type' in entry &&
114
+ (entry as { type: string }).type === 'dir' &&
115
+ 'name' in entry
116
+ );
108
117
  };
109
118
 
110
119
  expect(isValidDir(validEntry)).toBe(true);
@@ -127,16 +136,13 @@ describe('multi-project-estimate pagination', () => {
127
136
  });
128
137
 
129
138
  it('エラー発生時にスキップして処理を継続する', async () => {
130
- const mockRepos = [
131
- { name: 'valid-repo' },
132
- { name: 'invalid-repo' }
133
- ];
139
+ const mockRepos = [{ name: 'valid-repo' }, { name: 'invalid-repo' }];
134
140
 
135
141
  mockOctokit.paginate
136
- .mockResolvedValueOnce(mockRepos) // repos
137
- .mockResolvedValueOnce([{ name: 'project-1', type: 'dir' }]) // valid-repo の projects
138
- .mockRejectedValueOnce(new Error('Not found')) // invalid-repo で失敗
139
- .mockResolvedValue([]); // その後の呼び出し
142
+ .mockResolvedValueOnce(mockRepos) // repos
143
+ .mockResolvedValueOnce([{ name: 'project-1', type: 'dir' }]) // valid-repo の projects
144
+ .mockRejectedValueOnce(new Error('Not found')) // invalid-repo で失敗
145
+ .mockResolvedValue([]); // その後の呼び出し
140
146
 
141
147
  // エラーが発生しても処理が継続されることを確認
142
148
  // 実装では try-catch で continue を使用