@sk8metal/michi-cli 0.4.0 → 0.7.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 (321) hide show
  1. package/CHANGELOG.md +162 -1
  2. package/README.md +2 -1
  3. package/dist/scripts/config/config-schema.d.ts +87 -0
  4. package/dist/scripts/config/config-schema.d.ts.map +1 -1
  5. package/dist/scripts/config/config-schema.js +81 -0
  6. package/dist/scripts/config/config-schema.js.map +1 -1
  7. package/dist/scripts/confluence-sync.d.ts.map +1 -1
  8. package/dist/scripts/confluence-sync.js +15 -2
  9. package/dist/scripts/confluence-sync.js.map +1 -1
  10. package/dist/scripts/github-actions-client.d.ts +79 -0
  11. package/dist/scripts/github-actions-client.d.ts.map +1 -0
  12. package/dist/scripts/github-actions-client.js +182 -0
  13. package/dist/scripts/github-actions-client.js.map +1 -0
  14. package/dist/scripts/health-check-service.d.ts +46 -0
  15. package/dist/scripts/health-check-service.d.ts.map +1 -0
  16. package/dist/scripts/health-check-service.js +114 -0
  17. package/dist/scripts/health-check-service.js.map +1 -0
  18. package/dist/scripts/markdown-to-confluence.d.ts.map +1 -1
  19. package/dist/scripts/markdown-to-confluence.js +25 -3
  20. package/dist/scripts/markdown-to-confluence.js.map +1 -1
  21. package/dist/scripts/mermaid-converter.d.ts +24 -0
  22. package/dist/scripts/mermaid-converter.d.ts.map +1 -0
  23. package/dist/scripts/mermaid-converter.js +49 -0
  24. package/dist/scripts/mermaid-converter.js.map +1 -0
  25. package/dist/scripts/pr-automation.d.ts.map +1 -1
  26. package/dist/scripts/pr-automation.js +11 -3
  27. package/dist/scripts/pr-automation.js.map +1 -1
  28. package/dist/scripts/spec-impl-workflow.d.ts.map +1 -1
  29. package/dist/scripts/spec-impl-workflow.js +22 -6
  30. package/dist/scripts/spec-impl-workflow.js.map +1 -1
  31. package/dist/scripts/template/multi-repo-renderer.d.ts +67 -0
  32. package/dist/scripts/template/multi-repo-renderer.d.ts.map +1 -0
  33. package/dist/scripts/template/multi-repo-renderer.js +123 -0
  34. package/dist/scripts/template/multi-repo-renderer.js.map +1 -0
  35. package/dist/scripts/template/renderer.d.ts +4 -0
  36. package/dist/scripts/template/renderer.d.ts.map +1 -1
  37. package/dist/scripts/template/renderer.js.map +1 -1
  38. package/dist/scripts/test-execution-generator.d.ts.map +1 -1
  39. package/dist/scripts/test-execution-generator.js +94 -11
  40. package/dist/scripts/test-execution-generator.js.map +1 -1
  41. package/dist/scripts/test-script-runner.d.ts +33 -0
  42. package/dist/scripts/test-script-runner.d.ts.map +1 -0
  43. package/dist/scripts/test-script-runner.js +77 -0
  44. package/dist/scripts/test-script-runner.js.map +1 -0
  45. package/dist/scripts/utils/config-loader.d.ts +31 -5
  46. package/dist/scripts/utils/config-loader.d.ts.map +1 -1
  47. package/dist/scripts/utils/config-loader.js +363 -50
  48. package/dist/scripts/utils/config-loader.js.map +1 -1
  49. package/dist/scripts/utils/env-config.d.ts +1 -1
  50. package/dist/scripts/utils/env-config.d.ts.map +1 -1
  51. package/dist/scripts/utils/env-config.js +2 -14
  52. package/dist/scripts/utils/env-config.js.map +1 -1
  53. package/dist/scripts/utils/multi-repo-validator.d.ts +30 -0
  54. package/dist/scripts/utils/multi-repo-validator.d.ts.map +1 -0
  55. package/dist/scripts/utils/multi-repo-validator.js +105 -0
  56. package/dist/scripts/utils/multi-repo-validator.js.map +1 -0
  57. package/dist/scripts/utils/project-meta.d.ts +9 -0
  58. package/dist/scripts/utils/project-meta.d.ts.map +1 -1
  59. package/dist/scripts/utils/project-meta.js +22 -0
  60. package/dist/scripts/utils/project-meta.js.map +1 -1
  61. package/dist/scripts/utils/security-validator.d.ts +55 -0
  62. package/dist/scripts/utils/security-validator.d.ts.map +1 -0
  63. package/dist/scripts/utils/security-validator.js +232 -0
  64. package/dist/scripts/utils/security-validator.js.map +1 -0
  65. package/dist/scripts/utils/spec-archiver.d.ts +38 -0
  66. package/dist/scripts/utils/spec-archiver.d.ts.map +1 -0
  67. package/dist/scripts/utils/spec-archiver.js +210 -0
  68. package/dist/scripts/utils/spec-archiver.js.map +1 -0
  69. package/dist/scripts/utils/spec-updater.d.ts +4 -0
  70. package/dist/scripts/utils/spec-updater.d.ts.map +1 -1
  71. package/dist/scripts/utils/spec-updater.js.map +1 -1
  72. package/dist/src/cli.d.ts.map +1 -1
  73. package/dist/src/cli.js +303 -17
  74. package/dist/src/cli.js.map +1 -1
  75. package/dist/src/commands/config-validate.d.ts +9 -0
  76. package/dist/src/commands/config-validate.d.ts.map +1 -0
  77. package/dist/src/commands/config-validate.js +90 -0
  78. package/dist/src/commands/config-validate.js.map +1 -0
  79. package/dist/src/commands/init.d.ts +1 -0
  80. package/dist/src/commands/init.d.ts.map +1 -1
  81. package/dist/src/commands/init.js +29 -6
  82. package/dist/src/commands/init.js.map +1 -1
  83. package/dist/src/commands/migrate.d.ts +25 -0
  84. package/dist/src/commands/migrate.d.ts.map +1 -0
  85. package/dist/src/commands/migrate.js +341 -0
  86. package/dist/src/commands/migrate.js.map +1 -0
  87. package/dist/src/commands/multi-repo-add-repo.d.ts +26 -0
  88. package/dist/src/commands/multi-repo-add-repo.d.ts.map +1 -0
  89. package/dist/src/commands/multi-repo-add-repo.js +56 -0
  90. package/dist/src/commands/multi-repo-add-repo.js.map +1 -0
  91. package/dist/src/commands/multi-repo-ci-status.d.ts +46 -0
  92. package/dist/src/commands/multi-repo-ci-status.d.ts.map +1 -0
  93. package/dist/src/commands/multi-repo-ci-status.js +285 -0
  94. package/dist/src/commands/multi-repo-ci-status.js.map +1 -0
  95. package/dist/src/commands/multi-repo-confluence-sync.d.ts +45 -0
  96. package/dist/src/commands/multi-repo-confluence-sync.d.ts.map +1 -0
  97. package/dist/src/commands/multi-repo-confluence-sync.js +135 -0
  98. package/dist/src/commands/multi-repo-confluence-sync.js.map +1 -0
  99. package/dist/src/commands/multi-repo-init.d.ts +26 -0
  100. package/dist/src/commands/multi-repo-init.d.ts.map +1 -0
  101. package/dist/src/commands/multi-repo-init.js +101 -0
  102. package/dist/src/commands/multi-repo-init.js.map +1 -0
  103. package/dist/src/commands/multi-repo-list.d.ts +28 -0
  104. package/dist/src/commands/multi-repo-list.d.ts.map +1 -0
  105. package/dist/src/commands/multi-repo-list.js +38 -0
  106. package/dist/src/commands/multi-repo-list.js.map +1 -0
  107. package/dist/src/commands/multi-repo-test.d.ts +56 -0
  108. package/dist/src/commands/multi-repo-test.d.ts.map +1 -0
  109. package/dist/src/commands/multi-repo-test.js +70 -0
  110. package/dist/src/commands/multi-repo-test.js.map +1 -0
  111. package/dist/src/commands/setup-existing.d.ts.map +1 -1
  112. package/dist/src/commands/setup-existing.js +0 -1
  113. package/dist/src/commands/setup-existing.js.map +1 -1
  114. package/dist/src/commands/spec-archive.d.ts +17 -0
  115. package/dist/src/commands/spec-archive.d.ts.map +1 -0
  116. package/dist/src/commands/spec-archive.js +40 -0
  117. package/dist/src/commands/spec-archive.js.map +1 -0
  118. package/dist/src/commands/spec-list.d.ts +15 -0
  119. package/dist/src/commands/spec-list.d.ts.map +1 -0
  120. package/dist/src/commands/spec-list.js +55 -0
  121. package/dist/src/commands/spec-list.js.map +1 -0
  122. package/dist/vitest.config.d.ts.map +1 -1
  123. package/dist/vitest.config.js +32 -8
  124. package/dist/vitest.config.js.map +1 -1
  125. package/docs/michi-development/design/config-unification.md +4789 -0
  126. package/docs/user-guide/getting-started/github-token-setup.md +2 -1
  127. package/docs/user-guide/getting-started/new-repository-setup.md +1 -1
  128. package/docs/user-guide/getting-started/quick-start.md +1 -1
  129. package/docs/user-guide/getting-started/setup.md +4 -11
  130. package/docs/user-guide/guides/multi-repo-guide.md +591 -0
  131. package/docs/user-guide/guides/multi-repo-migration-guide.md +516 -0
  132. package/docs/user-guide/hands-on/claude-agent-setup.md +2 -2
  133. package/docs/user-guide/hands-on/claude-setup.md +2 -2
  134. package/docs/user-guide/hands-on/cursor-setup.md +2 -2
  135. package/docs/user-guide/hands-on/workflow-walkthrough.md +4 -1
  136. package/docs/user-guide/reference/multi-repo-api.md +771 -0
  137. package/docs/user-guide/reference/quick-reference.md +22 -37
  138. package/env.example +1 -1
  139. package/package.json +2 -5
  140. package/scripts/__tests__/config-loader-multi-repo.test.ts +342 -0
  141. package/scripts/__tests__/github-actions-client.test.ts +543 -0
  142. package/scripts/__tests__/health-check-service.test.ts +142 -0
  143. package/scripts/__tests__/markdown-to-confluence.test.ts +262 -0
  144. package/scripts/__tests__/mermaid-converter.test.ts +236 -0
  145. package/scripts/__tests__/multi-repo-config-schema.test.ts +335 -0
  146. package/scripts/__tests__/multi-repo-validator.test.ts +524 -0
  147. package/scripts/__tests__/spec-archiver.test.ts +512 -0
  148. package/scripts/__tests__/spec-impl-workflow.test.ts +5 -2
  149. package/scripts/__tests__/test-script-runner.test.ts +217 -0
  150. package/scripts/config/config-schema.ts +104 -0
  151. package/scripts/confluence-sync.ts +16 -2
  152. package/scripts/github-actions-client.ts +258 -0
  153. package/scripts/health-check-service.ts +171 -0
  154. package/scripts/markdown-to-confluence.ts +37 -6
  155. package/scripts/mermaid-converter.ts +56 -0
  156. package/scripts/pr-automation.ts +15 -5
  157. package/scripts/spec-impl-workflow.ts +22 -6
  158. package/scripts/template/__tests__/multi-repo-renderer.test.ts +261 -0
  159. package/scripts/template/multi-repo-renderer.ts +172 -0
  160. package/scripts/template/renderer.ts +5 -0
  161. package/scripts/test-execution-generator.ts +104 -11
  162. package/scripts/test-script-runner.ts +130 -0
  163. package/scripts/utils/__tests__/config-loader.test.ts +149 -0
  164. package/scripts/utils/__tests__/config-validator.test.ts +106 -6
  165. package/scripts/utils/__tests__/env-config.test.ts +0 -2
  166. package/scripts/utils/__tests__/multi-repo-validator.test.ts +335 -0
  167. package/scripts/utils/__tests__/project-meta.test.ts +192 -0
  168. package/scripts/utils/__tests__/security-validator.test.ts +272 -0
  169. package/scripts/utils/config-loader.ts +429 -56
  170. package/scripts/utils/env-config.ts +2 -14
  171. package/scripts/utils/multi-repo-validator.ts +141 -0
  172. package/scripts/utils/project-meta.ts +27 -0
  173. package/scripts/utils/security-validator.ts +286 -0
  174. package/scripts/utils/spec-archiver.ts +260 -0
  175. package/scripts/utils/spec-updater.ts +4 -0
  176. package/templates/claude/agents/pr-size-monitor/AGENT.md +330 -0
  177. package/templates/claude/commands/kiro/kiro-spec-impl.md +1 -1
  178. package/templates/claude/commands/michi/spec-impl.md +208 -35
  179. package/templates/claude-agent/commands/kiro/kiro-spec-impl.md +1 -1
  180. package/templates/cursor/commands/kiro/kiro-spec-impl.md +1 -1
  181. package/templates/multi-repo/docs/ci-status.md +51 -0
  182. package/templates/multi-repo/docs/release-notes.md +99 -0
  183. package/templates/multi-repo/overview/architecture.md +102 -0
  184. package/templates/multi-repo/overview/requirements.md +68 -0
  185. package/templates/multi-repo/overview/sequence.md +79 -0
  186. package/templates/multi-repo/steering/multi-repo.md +74 -0
  187. package/templates/multi-repo/tests/strategy.md +89 -0
  188. package/dist/scripts/__tests__/create-project.test.d.ts +0 -2
  189. package/dist/scripts/__tests__/create-project.test.d.ts.map +0 -1
  190. package/dist/scripts/__tests__/create-project.test.js +0 -243
  191. package/dist/scripts/__tests__/create-project.test.js.map +0 -1
  192. package/dist/scripts/__tests__/jira-transitions.test.d.ts +0 -5
  193. package/dist/scripts/__tests__/jira-transitions.test.d.ts.map +0 -1
  194. package/dist/scripts/__tests__/jira-transitions.test.js +0 -172
  195. package/dist/scripts/__tests__/jira-transitions.test.js.map +0 -1
  196. package/dist/scripts/__tests__/multi-project-estimate.test.d.ts +0 -2
  197. package/dist/scripts/__tests__/multi-project-estimate.test.d.ts.map +0 -1
  198. package/dist/scripts/__tests__/multi-project-estimate.test.js +0 -118
  199. package/dist/scripts/__tests__/multi-project-estimate.test.js.map +0 -1
  200. package/dist/scripts/__tests__/setup-existing-project.test.d.ts +0 -2
  201. package/dist/scripts/__tests__/setup-existing-project.test.d.ts.map +0 -1
  202. package/dist/scripts/__tests__/setup-existing-project.test.js +0 -208
  203. package/dist/scripts/__tests__/setup-existing-project.test.js.map +0 -1
  204. package/dist/scripts/__tests__/setup-interactive.test.d.ts +0 -2
  205. package/dist/scripts/__tests__/setup-interactive.test.d.ts.map +0 -1
  206. package/dist/scripts/__tests__/setup-interactive.test.js +0 -166
  207. package/dist/scripts/__tests__/setup-interactive.test.js.map +0 -1
  208. package/dist/scripts/__tests__/spec-impl-workflow.test.d.ts +0 -5
  209. package/dist/scripts/__tests__/spec-impl-workflow.test.d.ts.map +0 -1
  210. package/dist/scripts/__tests__/spec-impl-workflow.test.js +0 -321
  211. package/dist/scripts/__tests__/spec-impl-workflow.test.js.map +0 -1
  212. package/dist/scripts/__tests__/spec-loader.test.d.ts +0 -5
  213. package/dist/scripts/__tests__/spec-loader.test.d.ts.map +0 -1
  214. package/dist/scripts/__tests__/spec-loader.test.js +0 -153
  215. package/dist/scripts/__tests__/spec-loader.test.js.map +0 -1
  216. package/dist/scripts/__tests__/validate-phase.test.d.ts +0 -5
  217. package/dist/scripts/__tests__/validate-phase.test.d.ts.map +0 -1
  218. package/dist/scripts/__tests__/validate-phase.test.js +0 -249
  219. package/dist/scripts/__tests__/validate-phase.test.js.map +0 -1
  220. package/dist/scripts/constants/__tests__/environments.test.d.ts +0 -2
  221. package/dist/scripts/constants/__tests__/environments.test.d.ts.map +0 -1
  222. package/dist/scripts/constants/__tests__/environments.test.js +0 -125
  223. package/dist/scripts/constants/__tests__/environments.test.js.map +0 -1
  224. package/dist/scripts/constants/__tests__/languages.test.d.ts +0 -2
  225. package/dist/scripts/constants/__tests__/languages.test.d.ts.map +0 -1
  226. package/dist/scripts/constants/__tests__/languages.test.js +0 -82
  227. package/dist/scripts/constants/__tests__/languages.test.js.map +0 -1
  228. package/dist/scripts/create-project.d.ts +0 -16
  229. package/dist/scripts/create-project.d.ts.map +0 -1
  230. package/dist/scripts/create-project.js +0 -334
  231. package/dist/scripts/create-project.js.map +0 -1
  232. package/dist/scripts/list-projects.d.ts +0 -7
  233. package/dist/scripts/list-projects.d.ts.map +0 -1
  234. package/dist/scripts/list-projects.js +0 -88
  235. package/dist/scripts/list-projects.js.map +0 -1
  236. package/dist/scripts/template/__tests__/renderer.test.d.ts +0 -2
  237. package/dist/scripts/template/__tests__/renderer.test.d.ts.map +0 -1
  238. package/dist/scripts/template/__tests__/renderer.test.js +0 -165
  239. package/dist/scripts/template/__tests__/renderer.test.js.map +0 -1
  240. package/dist/scripts/utils/__tests__/aidlc-parser.test.d.ts +0 -5
  241. package/dist/scripts/utils/__tests__/aidlc-parser.test.d.ts.map +0 -1
  242. package/dist/scripts/utils/__tests__/aidlc-parser.test.js +0 -315
  243. package/dist/scripts/utils/__tests__/aidlc-parser.test.js.map +0 -1
  244. package/dist/scripts/utils/__tests__/business-days.test.d.ts +0 -5
  245. package/dist/scripts/utils/__tests__/business-days.test.d.ts.map +0 -1
  246. package/dist/scripts/utils/__tests__/business-days.test.js +0 -171
  247. package/dist/scripts/utils/__tests__/business-days.test.js.map +0 -1
  248. package/dist/scripts/utils/__tests__/config-loader.test.d.ts +0 -5
  249. package/dist/scripts/utils/__tests__/config-loader.test.d.ts.map +0 -1
  250. package/dist/scripts/utils/__tests__/config-loader.test.js +0 -201
  251. package/dist/scripts/utils/__tests__/config-loader.test.js.map +0 -1
  252. package/dist/scripts/utils/__tests__/config-validator.test.d.ts +0 -5
  253. package/dist/scripts/utils/__tests__/config-validator.test.d.ts.map +0 -1
  254. package/dist/scripts/utils/__tests__/config-validator.test.js +0 -394
  255. package/dist/scripts/utils/__tests__/config-validator.test.js.map +0 -1
  256. package/dist/scripts/utils/__tests__/env-config.test.d.ts +0 -5
  257. package/dist/scripts/utils/__tests__/env-config.test.d.ts.map +0 -1
  258. package/dist/scripts/utils/__tests__/env-config.test.js +0 -218
  259. package/dist/scripts/utils/__tests__/env-config.test.js.map +0 -1
  260. package/dist/scripts/utils/__tests__/feature-name-validator.test.d.ts +0 -5
  261. package/dist/scripts/utils/__tests__/feature-name-validator.test.d.ts.map +0 -1
  262. package/dist/scripts/utils/__tests__/feature-name-validator.test.js +0 -106
  263. package/dist/scripts/utils/__tests__/feature-name-validator.test.js.map +0 -1
  264. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.d.ts +0 -5
  265. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.d.ts.map +0 -1
  266. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.js +0 -202
  267. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.js.map +0 -1
  268. package/dist/scripts/utils/__tests__/spec-updater.test.d.ts +0 -5
  269. package/dist/scripts/utils/__tests__/spec-updater.test.d.ts.map +0 -1
  270. package/dist/scripts/utils/__tests__/spec-updater.test.js +0 -158
  271. package/dist/scripts/utils/__tests__/spec-updater.test.js.map +0 -1
  272. package/dist/scripts/utils/__tests__/tasks-converter.test.d.ts +0 -5
  273. package/dist/scripts/utils/__tests__/tasks-converter.test.d.ts.map +0 -1
  274. package/dist/scripts/utils/__tests__/tasks-converter.test.js +0 -500
  275. package/dist/scripts/utils/__tests__/tasks-converter.test.js.map +0 -1
  276. package/dist/scripts/utils/__tests__/tasks-format-validator.test.d.ts +0 -5
  277. package/dist/scripts/utils/__tests__/tasks-format-validator.test.d.ts.map +0 -1
  278. package/dist/scripts/utils/__tests__/tasks-format-validator.test.js +0 -314
  279. package/dist/scripts/utils/__tests__/tasks-format-validator.test.js.map +0 -1
  280. package/dist/scripts/utils/__tests__/test-runner.test.d.ts +0 -5
  281. package/dist/scripts/utils/__tests__/test-runner.test.d.ts.map +0 -1
  282. package/dist/scripts/utils/__tests__/test-runner.test.js +0 -64
  283. package/dist/scripts/utils/__tests__/test-runner.test.js.map +0 -1
  284. package/dist/src/__tests__/cli.test.d.ts +0 -5
  285. package/dist/src/__tests__/cli.test.d.ts.map +0 -1
  286. package/dist/src/__tests__/cli.test.js +0 -58
  287. package/dist/src/__tests__/cli.test.js.map +0 -1
  288. package/dist/src/__tests__/integration/internationalization.test.d.ts +0 -8
  289. package/dist/src/__tests__/integration/internationalization.test.d.ts.map +0 -1
  290. package/dist/src/__tests__/integration/internationalization.test.js +0 -333
  291. package/dist/src/__tests__/integration/internationalization.test.js.map +0 -1
  292. package/dist/src/__tests__/integration/setup/claude-agent.test.d.ts +0 -5
  293. package/dist/src/__tests__/integration/setup/claude-agent.test.d.ts.map +0 -1
  294. package/dist/src/__tests__/integration/setup/claude-agent.test.js +0 -122
  295. package/dist/src/__tests__/integration/setup/claude-agent.test.js.map +0 -1
  296. package/dist/src/__tests__/integration/setup/claude.test.d.ts +0 -5
  297. package/dist/src/__tests__/integration/setup/claude.test.d.ts.map +0 -1
  298. package/dist/src/__tests__/integration/setup/claude.test.js +0 -193
  299. package/dist/src/__tests__/integration/setup/claude.test.js.map +0 -1
  300. package/dist/src/__tests__/integration/setup/cursor.test.d.ts +0 -5
  301. package/dist/src/__tests__/integration/setup/cursor.test.d.ts.map +0 -1
  302. package/dist/src/__tests__/integration/setup/cursor.test.js +0 -166
  303. package/dist/src/__tests__/integration/setup/cursor.test.js.map +0 -1
  304. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.d.ts +0 -32
  305. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.d.ts.map +0 -1
  306. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.js +0 -72
  307. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.js.map +0 -1
  308. package/dist/src/__tests__/integration/setup/helpers/test-project.d.ts +0 -38
  309. package/dist/src/__tests__/integration/setup/helpers/test-project.d.ts.map +0 -1
  310. package/dist/src/__tests__/integration/setup/helpers/test-project.js +0 -83
  311. package/dist/src/__tests__/integration/setup/helpers/test-project.js.map +0 -1
  312. package/dist/src/__tests__/integration/setup/init.test.d.ts +0 -5
  313. package/dist/src/__tests__/integration/setup/init.test.d.ts.map +0 -1
  314. package/dist/src/__tests__/integration/setup/init.test.js +0 -352
  315. package/dist/src/__tests__/integration/setup/init.test.js.map +0 -1
  316. package/dist/src/__tests__/integration/setup/validation.test.d.ts +0 -5
  317. package/dist/src/__tests__/integration/setup/validation.test.d.ts.map +0 -1
  318. package/dist/src/__tests__/integration/setup/validation.test.js +0 -301
  319. package/dist/src/__tests__/integration/setup/validation.test.js.map +0 -1
  320. package/scripts/create-project.ts +0 -386
  321. package/scripts/list-projects.ts +0 -112
@@ -0,0 +1,171 @@
1
+ /**
2
+ * ヘルスチェックサービス
3
+ * 依存サービスの状態を確認してテスト実行前の環境チェックを行う
4
+ */
5
+
6
+ import { existsSync } from 'fs';
7
+ import { join } from 'path';
8
+ import { execSync } from 'child_process';
9
+
10
+ /**
11
+ * サービスステータス
12
+ */
13
+ export interface ServiceStatus {
14
+ serviceName: string;
15
+ status: 'healthy' | 'unhealthy';
16
+ message?: string;
17
+ }
18
+
19
+ /**
20
+ * ヘルスチェック結果
21
+ */
22
+ export interface HealthCheckResult {
23
+ success: boolean;
24
+ servicesStatus: ServiceStatus[];
25
+ }
26
+
27
+ /**
28
+ * execSync実行時のエラー型
29
+ */
30
+ interface ExecError extends Error {
31
+ status?: number;
32
+ stdout?: Buffer | string;
33
+ stderr?: Buffer | string;
34
+ }
35
+
36
+ /**
37
+ * ヘルスチェックサービス
38
+ */
39
+ export class HealthCheckService {
40
+ /**
41
+ * ヘルスチェックを実行
42
+ *
43
+ * @param projectName プロジェクト名
44
+ * @param projectRoot プロジェクトルートディレクトリ(デフォルト: process.cwd())
45
+ * @returns ヘルスチェック結果
46
+ */
47
+ async runHealthCheck(
48
+ projectName: string,
49
+ projectRoot: string = process.cwd()
50
+ ): Promise<HealthCheckResult> {
51
+ // 1. ヘルスチェックスクリプトの存在確認
52
+ const scriptPath = join(
53
+ projectRoot,
54
+ 'docs',
55
+ 'michi',
56
+ projectName,
57
+ 'tests',
58
+ 'scripts',
59
+ 'health-check.sh'
60
+ );
61
+
62
+ if (!existsSync(scriptPath)) {
63
+ console.log(
64
+ `ℹ️ ヘルスチェックスクリプトが見つかりません: ${scriptPath}。ヘルスチェックをスキップします。`
65
+ );
66
+ return {
67
+ success: true,
68
+ servicesStatus: [],
69
+ };
70
+ }
71
+
72
+ // 2. ヘルスチェックスクリプトを実行
73
+ try {
74
+ console.log('🔍 ヘルスチェックを実行中...');
75
+ const output = execSync(scriptPath, {
76
+ encoding: 'utf-8',
77
+ timeout: 30000, // 30秒タイムアウト
78
+ }) as string;
79
+
80
+ // 3. スクリプト出力を解析
81
+ const servicesStatus = this.parseHealthCheckOutput(output);
82
+
83
+ // 4. unhealthyなサービスがある場合は失敗
84
+ const hasUnhealthyServices = servicesStatus.some(
85
+ (s) => s.status === 'unhealthy'
86
+ );
87
+
88
+ if (hasUnhealthyServices) {
89
+ console.log('❌ ヘルスチェックが失敗しました');
90
+ servicesStatus.forEach((s) => {
91
+ const icon = s.status === 'healthy' ? '✅' : '❌';
92
+ const message = s.message ? ` - ${s.message}` : '';
93
+ console.log(` ${icon} ${s.serviceName}: ${s.status}${message}`);
94
+ });
95
+
96
+ return {
97
+ success: false,
98
+ servicesStatus,
99
+ };
100
+ }
101
+
102
+ console.log('✅ ヘルスチェックが成功しました');
103
+ servicesStatus.forEach((s) => {
104
+ console.log(` ✅ ${s.serviceName}: ${s.status}`);
105
+ });
106
+
107
+ return {
108
+ success: true,
109
+ servicesStatus,
110
+ };
111
+ } catch (error) {
112
+ // スクリプト実行エラー
113
+ const execError = error as ExecError;
114
+ console.error('❌ ヘルスチェックスクリプトの実行に失敗しました:', execError.message);
115
+
116
+ if (execError.status !== undefined && execError.status !== 0) {
117
+ // 終了コードが非0の場合は失敗
118
+ const output = execError.stdout || execError.stderr || '';
119
+ const outputStr = Buffer.isBuffer(output) ? output.toString('utf-8') : String(output);
120
+ const servicesStatus = this.parseHealthCheckOutput(outputStr);
121
+
122
+ return {
123
+ success: false,
124
+ servicesStatus,
125
+ };
126
+ }
127
+
128
+ // その他のエラー(タイムアウト、パーミッションエラーなど)
129
+ return {
130
+ success: false,
131
+ servicesStatus: [],
132
+ };
133
+ }
134
+ }
135
+
136
+ /**
137
+ * ヘルスチェックスクリプトの出力を解析
138
+ *
139
+ * 出力形式:
140
+ * ```
141
+ * service-name: healthy
142
+ * service-name: unhealthy - error message
143
+ * ```
144
+ *
145
+ * @param output スクリプト出力
146
+ * @returns サービスステータス配列
147
+ */
148
+ private parseHealthCheckOutput(output: string): ServiceStatus[] {
149
+ const servicesStatus: ServiceStatus[] = [];
150
+ const lines = output.trim().split('\n');
151
+
152
+ for (const line of lines) {
153
+ const match = line.match(/^(\S+):\s+(healthy|unhealthy)(?:\s+-\s+(.+))?$/);
154
+ if (!match) {
155
+ continue; // 不正な形式の行はスキップ
156
+ }
157
+
158
+ const serviceName = match[1];
159
+ const status = match[2] as 'healthy' | 'unhealthy';
160
+ const message = match[3];
161
+
162
+ servicesStatus.push({
163
+ serviceName,
164
+ status,
165
+ message,
166
+ });
167
+ }
168
+
169
+ return servicesStatus;
170
+ }
171
+ }
@@ -14,14 +14,37 @@ const md = new MarkdownIt({
14
14
  * Markdown を Confluence Storage Format (HTML) に変換
15
15
  */
16
16
  export function convertMarkdownToConfluence(markdown: string): string {
17
- // MarkdownIt でHTMLに変換
18
- let html = md.render(markdown);
19
-
20
- // Confluence固有の変換
17
+ // 1. Mermaidブロックをプレースホルダーに置き換え
18
+ const mermaidBlocks: string[] = [];
19
+ const withPlaceholders = markdown.replace(
20
+ /```mermaid\n([\s\S]*?)```/g,
21
+ (match, diagram) => {
22
+ const placeholder = `<!--MERMAID_BLOCK_${mermaidBlocks.length}-->`;
23
+ mermaidBlocks.push(diagram.trim());
24
+ return placeholder;
25
+ }
26
+ );
27
+
28
+ // 2. MarkdownIt でHTMLに変換
29
+ let html = md.render(withPlaceholders);
30
+
31
+ // 3. Confluence固有の変換
21
32
  html = convertCodeBlocks(html);
22
33
  html = convertTables(html);
23
34
  html = convertInfoBoxes(html);
24
-
35
+
36
+ // 4. プレースホルダーをConfluenceマクロに戻す
37
+ html = html.replace(
38
+ /<!--MERMAID_BLOCK_(\d+)-->/g,
39
+ (match, index) => {
40
+ const diagram = mermaidBlocks[parseInt(index)];
41
+ const escapedDiagram = escapeCDATA(diagram);
42
+ return `<ac:structured-macro ac:name="mermaid">
43
+ <ac:plain-text-body><![CDATA[${escapedDiagram}]]></ac:plain-text-body>
44
+ </ac:structured-macro>`;
45
+ }
46
+ );
47
+
25
48
  return html;
26
49
  }
27
50
 
@@ -96,12 +119,20 @@ function decodeHtmlEntities(text: string): string {
96
119
  '&#39;': '\'',
97
120
  '&nbsp;': ' '
98
121
  };
99
-
122
+
100
123
  return text.replace(/&[a-z]+;|&#\d+;/g, (entity) => {
101
124
  return entities[entity] || entity;
102
125
  });
103
126
  }
104
127
 
128
+ /**
129
+ * CDATA内の ]]> をエスケープ
130
+ */
131
+ function escapeCDATA(text: string): string {
132
+ // ]]> を ]]]]><![CDATA[> に置換してエスケープ
133
+ return text.replace(/]]>/g, ']]]]><![CDATA[>');
134
+ }
135
+
105
136
  /**
106
137
  * Confluenceページテンプレートを生成
107
138
  */
@@ -0,0 +1,56 @@
1
+ /**
2
+ * MermaidダイアグラムをConfluenceマクロ形式に変換
3
+ */
4
+
5
+ /**
6
+ * MermaidConverter
7
+ * MarkdownテキストからMermaidブロックを検出し、Confluenceマクロ形式に変換
8
+ */
9
+ export class MermaidConverter {
10
+ /**
11
+ * MarkdownテキストからMermaidブロックをConfluenceマクロ形式に変換
12
+ *
13
+ * @param markdown Markdownテキスト
14
+ * @returns 変換後のテキスト
15
+ */
16
+ convertMermaidToConfluence(markdown: string): string {
17
+ // Mermaidブロックを検出する正規表現
18
+ // ```mermaid\n([\s\S]*?)\n```
19
+ const mermaidBlockRegex = /```mermaid\n([\s\S]*?)```/g;
20
+
21
+ // Mermaidブロックを検出
22
+ const matches = Array.from(markdown.matchAll(mermaidBlockRegex));
23
+
24
+ // Mermaidブロックがない場合は変更なし
25
+ if (matches.length === 0) {
26
+ return markdown;
27
+ }
28
+
29
+ // Mermaidブロックを Confluence マクロ形式に変換
30
+ const converted = markdown.replace(mermaidBlockRegex, (match, diagram) => {
31
+ // 前後の空白を削除
32
+ const trimmedDiagram = diagram.trim();
33
+
34
+ // CDATA終了マーカー ]]> をエスケープ
35
+ const escapedDiagram = this.escapeCDATA(trimmedDiagram);
36
+
37
+ // Confluenceマクロ形式に変換
38
+ return `<ac:structured-macro ac:name="mermaid">
39
+ <ac:plain-text-body><![CDATA[${escapedDiagram}]]></ac:plain-text-body>
40
+ </ac:structured-macro>`;
41
+ });
42
+
43
+ return converted;
44
+ }
45
+
46
+ /**
47
+ * CDATA内の ]]> をエスケープ
48
+ *
49
+ * @param text テキスト
50
+ * @returns エスケープ後のテキスト
51
+ */
52
+ private escapeCDATA(text: string): string {
53
+ // ]]> を ]]]]><![CDATA[> に置換してエスケープ
54
+ return text.replace(/]]>/g, ']]]]><![CDATA[>');
55
+ }
56
+ }
@@ -15,13 +15,23 @@ interface PROptions {
15
15
  }
16
16
 
17
17
  async function createPR(options: PROptions): Promise<void> {
18
+ const { getRepositoryInfo } = await import('./utils/project-meta.js');
18
19
  const token = process.env.GITHUB_TOKEN;
19
- const repo = process.env.GITHUB_REPO;
20
-
21
- if (!token || !repo) {
22
- throw new Error('Missing GitHub credentials');
20
+
21
+ if (!token) {
22
+ throw new Error('Missing GitHub credentials. Required: GITHUB_TOKEN');
23
23
  }
24
-
24
+
25
+ // .kiro/project.json から repository 情報を取得
26
+ let repo: string;
27
+ try {
28
+ repo = getRepositoryInfo();
29
+ } catch (error) {
30
+ throw new Error(
31
+ `Failed to get repository info from .kiro/project.json: ${error instanceof Error ? error.message : error}`,
32
+ );
33
+ }
34
+
25
35
  const [owner, repoName] = repo.split('/');
26
36
  const octokit = new Octokit({ auth: token });
27
37
 
@@ -258,12 +258,20 @@ ${jiraLink}
258
258
  *この PR は spec-impl ワークフローで自動作成されました*`;
259
259
 
260
260
  const { Octokit } = await import('@octokit/rest');
261
+ const { getRepositoryInfo } = await import('./utils/project-meta.js');
261
262
  const token = process.env.GITHUB_TOKEN;
262
- const repo = process.env.GITHUB_REPO;
263
263
 
264
- if (!token || !repo) {
264
+ if (!token) {
265
+ throw new Error('Missing GitHub credentials. Required: GITHUB_TOKEN');
266
+ }
267
+
268
+ // .kiro/project.json から repository 情報を取得
269
+ let repo: string;
270
+ try {
271
+ repo = getRepositoryInfo();
272
+ } catch (error) {
265
273
  throw new Error(
266
- 'Missing GitHub credentials. Required: GITHUB_TOKEN, GITHUB_REPO',
274
+ `Failed to get repository info from .kiro/project.json: ${error instanceof Error ? error.message : error}`,
267
275
  );
268
276
  }
269
277
 
@@ -393,12 +401,20 @@ export async function onSpecImplEnd(
393
401
 
394
402
  // PR 作成
395
403
  const { Octokit } = await import('@octokit/rest');
404
+ const { getRepositoryInfo } = await import('./utils/project-meta.js');
396
405
  const token = process.env.GITHUB_TOKEN;
397
- const repo = process.env.GITHUB_REPO;
398
406
 
399
- if (!token || !repo) {
407
+ if (!token) {
408
+ throw new Error('Missing GitHub credentials. Required: GITHUB_TOKEN');
409
+ }
410
+
411
+ // .kiro/project.json から repository 情報を取得
412
+ let repo: string;
413
+ try {
414
+ repo = getRepositoryInfo();
415
+ } catch (error) {
400
416
  throw new Error(
401
- 'Missing GitHub credentials. Required: GITHUB_TOKEN, GITHUB_REPO',
417
+ `Failed to get repository info from .kiro/project.json: ${error instanceof Error ? error.message : error}`,
402
418
  );
403
419
  }
404
420
 
@@ -0,0 +1,261 @@
1
+ /**
2
+ * Tests for Multi-Repo template renderer
3
+ */
4
+
5
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
6
+ import {
7
+ createMultiRepoTemplateContext,
8
+ loadMultiRepoTemplate,
9
+ renderMultiRepoTemplate,
10
+ loadAndRenderMultiRepoTemplate,
11
+ renderMultiRepoTemplates,
12
+ MULTI_REPO_TEMPLATES,
13
+ type MultiRepoTemplateContext,
14
+ } from '../multi-repo-renderer.js';
15
+ import * as fs from 'fs';
16
+
17
+ vi.mock('fs');
18
+
19
+ describe('createMultiRepoTemplateContext', () => {
20
+ it('必須フィールドを含むコンテキストを作成する', () => {
21
+ const context = createMultiRepoTemplateContext(
22
+ 'test-project',
23
+ 'TEST',
24
+ 'SPACE'
25
+ );
26
+
27
+ expect(context.PROJECT_NAME).toBe('test-project');
28
+ expect(context.JIRA_KEY).toBe('TEST');
29
+ expect(context.CONFLUENCE_SPACE).toBe('SPACE');
30
+ expect(context.CREATED_AT).toBeDefined();
31
+ });
32
+
33
+ it('CREATED_ATにカスタム値を指定できる', () => {
34
+ const customDate = '2025-12-14T10:00:00Z';
35
+ const context = createMultiRepoTemplateContext(
36
+ 'test-project',
37
+ 'TEST',
38
+ 'SPACE',
39
+ customDate
40
+ );
41
+
42
+ expect(context.CREATED_AT).toBe(customDate);
43
+ });
44
+
45
+ it('CREATED_ATが省略された場合は現在時刻を使用する', () => {
46
+ const context = createMultiRepoTemplateContext(
47
+ 'test-project',
48
+ 'TEST',
49
+ 'SPACE'
50
+ );
51
+
52
+ // ISO 8601形式であることを確認
53
+ expect(context.CREATED_AT).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/);
54
+ });
55
+ });
56
+
57
+ describe('loadMultiRepoTemplate', () => {
58
+ beforeEach(() => {
59
+ vi.clearAllMocks();
60
+ });
61
+
62
+ it('テンプレートファイルを読み込む', () => {
63
+ const mockContent = '# {{PROJECT_NAME}} - Requirements';
64
+ vi.spyOn(fs, 'readFileSync').mockReturnValue(mockContent);
65
+
66
+ const content = loadMultiRepoTemplate('overview/requirements', '/test/root');
67
+
68
+ expect(fs.readFileSync).toHaveBeenCalledWith(
69
+ '/test/root/templates/multi-repo/overview/requirements.md',
70
+ 'utf-8'
71
+ );
72
+ expect(content).toBe(mockContent);
73
+ });
74
+
75
+ it('テンプレートが存在しない場合はエラーをスロー', () => {
76
+ vi.spyOn(fs, 'readFileSync').mockImplementation(() => {
77
+ throw new Error('ENOENT: no such file or directory');
78
+ });
79
+
80
+ expect(() => loadMultiRepoTemplate('invalid/template', '/test/root')).toThrow(
81
+ 'Multi-Repo template not found: invalid/template.md'
82
+ );
83
+ });
84
+ });
85
+
86
+ describe('renderMultiRepoTemplate', () => {
87
+ it('プレースホルダーを置換する', () => {
88
+ const template = '# {{PROJECT_NAME}} - {{JIRA_KEY}}\n\nCreated: {{CREATED_AT}}';
89
+ const context: MultiRepoTemplateContext = {
90
+ PROJECT_NAME: 'test-project',
91
+ JIRA_KEY: 'TEST',
92
+ CONFLUENCE_SPACE: 'SPACE',
93
+ CREATED_AT: '2025-12-14T10:00:00Z',
94
+ };
95
+
96
+ const rendered = renderMultiRepoTemplate(template, context);
97
+
98
+ expect(rendered).toBe('# test-project - TEST\n\nCreated: 2025-12-14T10:00:00Z');
99
+ });
100
+
101
+ it('すべてのMulti-Repoプレースホルダーを置換する', () => {
102
+ const template = [
103
+ '{{PROJECT_NAME}}',
104
+ '{{JIRA_KEY}}',
105
+ '{{CONFLUENCE_SPACE}}',
106
+ '{{CREATED_AT}}',
107
+ ].join(' / ');
108
+
109
+ const context: MultiRepoTemplateContext = {
110
+ PROJECT_NAME: 'my-project',
111
+ JIRA_KEY: 'PROJ',
112
+ CONFLUENCE_SPACE: 'MYSPACE',
113
+ CREATED_AT: '2025-12-14T10:00:00Z',
114
+ };
115
+
116
+ const rendered = renderMultiRepoTemplate(template, context);
117
+
118
+ expect(rendered).toBe('my-project / PROJ / MYSPACE / 2025-12-14T10:00:00Z');
119
+ });
120
+
121
+ it('存在しないプレースホルダーはそのまま残す', () => {
122
+ const template = '{{PROJECT_NAME}} - {{UNKNOWN_PLACEHOLDER}}';
123
+ const context: MultiRepoTemplateContext = {
124
+ PROJECT_NAME: 'test-project',
125
+ JIRA_KEY: 'TEST',
126
+ CONFLUENCE_SPACE: 'SPACE',
127
+ CREATED_AT: '2025-12-14T10:00:00Z',
128
+ };
129
+
130
+ const rendered = renderMultiRepoTemplate(template, context);
131
+
132
+ expect(rendered).toBe('test-project - {{UNKNOWN_PLACEHOLDER}}');
133
+ });
134
+ });
135
+
136
+ describe('loadAndRenderMultiRepoTemplate', () => {
137
+ beforeEach(() => {
138
+ vi.clearAllMocks();
139
+ });
140
+
141
+ it('テンプレートを読み込んでレンダリングする', () => {
142
+ const mockContent = '# {{PROJECT_NAME}} Requirements\n\n**JIRA**: {{JIRA_KEY}}';
143
+ vi.spyOn(fs, 'readFileSync').mockReturnValue(mockContent);
144
+
145
+ const context: MultiRepoTemplateContext = {
146
+ PROJECT_NAME: 'test-project',
147
+ JIRA_KEY: 'TEST',
148
+ CONFLUENCE_SPACE: 'SPACE',
149
+ CREATED_AT: '2025-12-14T10:00:00Z',
150
+ };
151
+
152
+ const rendered = loadAndRenderMultiRepoTemplate(
153
+ 'overview/requirements',
154
+ context,
155
+ '/test/root'
156
+ );
157
+
158
+ expect(rendered).toBe('# test-project Requirements\n\n**JIRA**: TEST');
159
+ });
160
+ });
161
+
162
+ describe('renderMultiRepoTemplates', () => {
163
+ beforeEach(() => {
164
+ vi.clearAllMocks();
165
+ });
166
+
167
+ it('複数のテンプレートを一括レンダリングする', () => {
168
+ vi.spyOn(fs, 'readFileSync').mockImplementation((path) => {
169
+ if (path.toString().includes('requirements')) {
170
+ return '# {{PROJECT_NAME}} Requirements';
171
+ }
172
+ if (path.toString().includes('architecture')) {
173
+ return '# {{PROJECT_NAME}} Architecture';
174
+ }
175
+ return 'Template not found';
176
+ });
177
+
178
+ const context: MultiRepoTemplateContext = {
179
+ PROJECT_NAME: 'test-project',
180
+ JIRA_KEY: 'TEST',
181
+ CONFLUENCE_SPACE: 'SPACE',
182
+ CREATED_AT: '2025-12-14T10:00:00Z',
183
+ };
184
+
185
+ const rendered = renderMultiRepoTemplates(
186
+ ['overview/requirements', 'overview/architecture'],
187
+ context,
188
+ '/test/root'
189
+ );
190
+
191
+ expect(rendered['overview/requirements']).toBe('# test-project Requirements');
192
+ expect(rendered['overview/architecture']).toBe('# test-project Architecture');
193
+ });
194
+
195
+ it('空の配列を渡した場合は空のオブジェクトを返す', () => {
196
+ const context: MultiRepoTemplateContext = {
197
+ PROJECT_NAME: 'test-project',
198
+ JIRA_KEY: 'TEST',
199
+ CONFLUENCE_SPACE: 'SPACE',
200
+ CREATED_AT: '2025-12-14T10:00:00Z',
201
+ };
202
+
203
+ const rendered = renderMultiRepoTemplates([], context, '/test/root');
204
+
205
+ expect(rendered).toEqual({});
206
+ });
207
+ });
208
+
209
+ describe('MULTI_REPO_TEMPLATES', () => {
210
+ it('すべてのMulti-Repoテンプレート名を含む', () => {
211
+ expect(MULTI_REPO_TEMPLATES).toContain('overview/requirements');
212
+ expect(MULTI_REPO_TEMPLATES).toContain('overview/architecture');
213
+ expect(MULTI_REPO_TEMPLATES).toContain('overview/sequence');
214
+ expect(MULTI_REPO_TEMPLATES).toContain('steering/multi-repo');
215
+ expect(MULTI_REPO_TEMPLATES).toContain('tests/strategy');
216
+ expect(MULTI_REPO_TEMPLATES).toContain('docs/ci-status');
217
+ expect(MULTI_REPO_TEMPLATES).toContain('docs/release-notes');
218
+ });
219
+
220
+ it('テンプレート数は7つ', () => {
221
+ expect(MULTI_REPO_TEMPLATES.length).toBe(7);
222
+ });
223
+ });
224
+
225
+ describe('統合テスト', () => {
226
+ beforeEach(() => {
227
+ vi.clearAllMocks();
228
+ });
229
+
230
+ it('実際のテンプレートファイルをレンダリングできる(モック使用)', () => {
231
+ const mockRequirementsTemplate = `# {{PROJECT_NAME}} - 要件定義書
232
+
233
+ ## プロジェクト情報
234
+
235
+ - **プロジェクト名**: {{PROJECT_NAME}}
236
+ - **JIRAキー**: {{JIRA_KEY}}
237
+ - **Confluenceスペース**: {{CONFLUENCE_SPACE}}
238
+ - **作成日時**: {{CREATED_AT}}`;
239
+
240
+ vi.spyOn(fs, 'readFileSync').mockReturnValue(mockRequirementsTemplate);
241
+
242
+ const context: MultiRepoTemplateContext = {
243
+ PROJECT_NAME: 'my-awesome-project',
244
+ JIRA_KEY: 'AWESOME',
245
+ CONFLUENCE_SPACE: 'PROJ',
246
+ CREATED_AT: '2025-12-14T10:30:00Z',
247
+ };
248
+
249
+ const rendered = loadAndRenderMultiRepoTemplate(
250
+ 'overview/requirements',
251
+ context,
252
+ '/test/root'
253
+ );
254
+
255
+ expect(rendered).toContain('# my-awesome-project - 要件定義書');
256
+ expect(rendered).toContain('- **プロジェクト名**: my-awesome-project');
257
+ expect(rendered).toContain('- **JIRAキー**: AWESOME');
258
+ expect(rendered).toContain('- **Confluenceスペース**: PROJ');
259
+ expect(rendered).toContain('- **作成日時**: 2025-12-14T10:30:00Z');
260
+ });
261
+ });