@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,141 @@
1
+ /**
2
+ * multi-repo-validator.ts
3
+ * Multi-Repo機能のバリデーションユーティリティ
4
+ *
5
+ * プロジェクト名、JIRAキー、リポジトリURLのバリデーションとセキュリティチェックを行います。
6
+ */
7
+
8
+ /**
9
+ * バリデーション結果
10
+ */
11
+ export interface ValidationResult {
12
+ isValid: boolean;
13
+ errors: string[];
14
+ warnings: string[];
15
+ }
16
+
17
+ /**
18
+ * プロジェクト名のバリデーション
19
+ * セキュリティ対策: パストラバーサル、相対パス、制御文字をチェック
20
+ */
21
+ export function validateProjectName(name: string): ValidationResult {
22
+ const errors: string[] = [];
23
+ const warnings: string[] = [];
24
+
25
+ // 長さチェック: 1-100文字
26
+ if (name.length < 1 || name.length > 100) {
27
+ errors.push('Project name must be between 1 and 100 characters');
28
+ }
29
+
30
+ // パストラバーサル対策: '/', '\' 禁止
31
+ if (name.includes('/') || name.includes('\\')) {
32
+ errors.push(
33
+ 'Project name must not contain path traversal characters (/, \\)',
34
+ );
35
+ }
36
+
37
+ // 相対パス対策: '.', '..' 禁止
38
+ if (name === '.' || name === '..') {
39
+ errors.push(
40
+ 'Project name must not be relative path components (., ..)',
41
+ );
42
+ }
43
+
44
+ // 制御文字対策: \x00-\x1F, \x7F 禁止
45
+ // eslint-disable-next-line no-control-regex
46
+ const controlCharRegex = /[\x00-\x1F\x7F]/;
47
+ if (controlCharRegex.test(name)) {
48
+ errors.push('Project name must not contain control characters');
49
+ }
50
+
51
+ return {
52
+ isValid: errors.length === 0,
53
+ errors,
54
+ warnings,
55
+ };
56
+ }
57
+
58
+ /**
59
+ * JIRAキーのバリデーション
60
+ * 2-10文字の大文字英字のみ許可
61
+ */
62
+ export function validateJiraKey(key: string): ValidationResult {
63
+ const errors: string[] = [];
64
+ const warnings: string[] = [];
65
+
66
+ // 正規表現: 2-10文字の大文字英字
67
+ const jiraKeyRegex = /^[A-Z]{2,10}$/;
68
+
69
+ if (!jiraKeyRegex.test(key)) {
70
+ errors.push('JIRA key must be 2-10 uppercase letters');
71
+ }
72
+
73
+ return {
74
+ isValid: errors.length === 0,
75
+ errors,
76
+ warnings,
77
+ };
78
+ }
79
+
80
+ /**
81
+ * リポジトリURLのバリデーション
82
+ * GitHub HTTPS URL形式のみ許可
83
+ */
84
+ export function validateRepositoryUrl(url: string): ValidationResult {
85
+ const errors: string[] = [];
86
+ const warnings: string[] = [];
87
+
88
+ // 空文字列チェック
89
+ if (!url || url.trim() === '') {
90
+ errors.push('Repository URL is empty');
91
+ return { isValid: false, errors, warnings };
92
+ }
93
+
94
+ // SSH URL検出(git@github.com:形式)
95
+ if (url.startsWith('git@')) {
96
+ errors.push(
97
+ 'Repository URL must be in GitHub format: https://github.com/{owner}/{repo}',
98
+ );
99
+ return { isValid: false, errors, warnings };
100
+ }
101
+
102
+ // URL形式チェック
103
+ try {
104
+ const parsedUrl = new URL(url);
105
+
106
+ // HTTPSプロトコルチェック
107
+ if (parsedUrl.protocol !== 'https:') {
108
+ errors.push('Repository URL must use HTTPS protocol');
109
+ }
110
+
111
+ // GitHub URL形式チェック: https://github.com/{owner}/{repo}
112
+ const githubPattern = /^https:\/\/github\.com\/[^/]+\/[^/]+$/;
113
+ if (!githubPattern.test(url)) {
114
+ errors.push(
115
+ 'Repository URL must be in GitHub format: https://github.com/{owner}/{repo}',
116
+ );
117
+ }
118
+
119
+ // .git拡張子チェック
120
+ if (url.endsWith('.git')) {
121
+ errors.push('Repository URL must not include .git extension');
122
+ }
123
+
124
+ // プレースホルダー検出
125
+ if (
126
+ url.includes('your-org') ||
127
+ url.includes('your-repo') ||
128
+ url.includes('repo-name')
129
+ ) {
130
+ errors.push('Repository URL contains placeholder values');
131
+ }
132
+ } catch (_error) {
133
+ errors.push('Repository URL format is invalid');
134
+ }
135
+
136
+ return {
137
+ isValid: errors.length === 0,
138
+ errors,
139
+ warnings,
140
+ };
141
+ }
@@ -67,3 +67,30 @@ Team: ${meta.team.join(', ')}
67
67
  `.trim();
68
68
  }
69
69
 
70
+ /**
71
+ * GitHub リポジトリ情報を取得
72
+ * repository フィールドから owner/repo 形式を抽出
73
+ *
74
+ * @param projectRoot プロジェクトルートディレクトリ(デフォルト: カレントディレクトリ)
75
+ * @returns owner/repo 形式のリポジトリ情報
76
+ * @throws リポジトリ情報が見つからない、または無効な形式の場合
77
+ */
78
+ export function getRepositoryInfo(projectRoot: string = process.cwd()): string {
79
+ const meta = loadProjectMeta(projectRoot);
80
+
81
+ if (!meta.repository) {
82
+ throw new Error('Repository information not found in project.json');
83
+ }
84
+
85
+ // URL形式から owner/repo を抽出
86
+ // 例: https://github.com/owner/repo.git -> owner/repo
87
+ // 例: git@github.com:owner/repo.git -> owner/repo
88
+ const match = meta.repository.match(/github\.com[:/]([\w-]+\/[\w-]+)(\.git)?/);
89
+
90
+ if (!match) {
91
+ throw new Error(`Invalid GitHub repository format: ${meta.repository}`);
92
+ }
93
+
94
+ return match[1];
95
+ }
96
+
@@ -0,0 +1,286 @@
1
+ /**
2
+ * security-validator.ts
3
+ * セキュリティ検証ユーティリティ
4
+ *
5
+ * 環境変数やAPIトークンなど機密情報のバリデーションとセキュリティチェックを行います。
6
+ */
7
+
8
+ import { statSync } from 'fs';
9
+
10
+ /**
11
+ * バリデーション結果
12
+ */
13
+ export interface ValidationResult {
14
+ isValid: boolean;
15
+ errors: string[];
16
+ warnings: string[];
17
+ }
18
+
19
+ /**
20
+ * APIトークン形式の検証
21
+ */
22
+ export function validateAtlassianToken(token: string): ValidationResult {
23
+ const errors: string[] = [];
24
+ const warnings: string[] = [];
25
+
26
+ if (!token || token.trim() === '') {
27
+ errors.push('Atlassian API token is empty');
28
+ return { isValid: false, errors, warnings };
29
+ }
30
+
31
+ if (token.includes(' ')) {
32
+ errors.push('Atlassian API token contains spaces');
33
+ }
34
+
35
+ if (token === 'your-token-here' || token === 'test-token' || token === 'token123') {
36
+ errors.push('Atlassian API token is a placeholder value');
37
+ }
38
+
39
+ if (token.length < 20) {
40
+ warnings.push('Atlassian API token seems too short (expected >20 characters)');
41
+ }
42
+
43
+ return {
44
+ isValid: errors.length === 0,
45
+ errors,
46
+ warnings,
47
+ };
48
+ }
49
+
50
+ /**
51
+ * GitHub Personal Access Token の検証
52
+ */
53
+ export function validateGitHubToken(token: string): ValidationResult {
54
+ const errors: string[] = [];
55
+ const warnings: string[] = [];
56
+
57
+ if (!token || token.trim() === '') {
58
+ errors.push('GitHub token is empty');
59
+ } else if (token.includes(' ')) {
60
+ errors.push('GitHub token contains spaces');
61
+ } else if (!token.startsWith('ghp_') && !token.startsWith('github_pat_')) {
62
+ warnings.push('GitHub token does not start with expected prefix (ghp_ or github_pat_)');
63
+ } else if (token === 'ghp_xxx' || token === 'your-github-token' || token === 'github-token') {
64
+ errors.push('GitHub token is a placeholder value');
65
+ } else if (token.length < 30) {
66
+ warnings.push('GitHub token seems too short');
67
+ }
68
+
69
+ return {
70
+ isValid: errors.length === 0,
71
+ errors,
72
+ warnings,
73
+ };
74
+ }
75
+
76
+ /**
77
+ * メールアドレス形式の検証
78
+ */
79
+ export function validateEmail(email: string): ValidationResult {
80
+ const errors: string[] = [];
81
+ const warnings: string[] = [];
82
+
83
+ if (!email || email.trim() === '') {
84
+ errors.push('Email is empty');
85
+ } else {
86
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
87
+ if (!emailRegex.test(email)) {
88
+ errors.push('Email format is invalid');
89
+ } else if (
90
+ email === 'user@example.com' ||
91
+ email.includes('your-email') ||
92
+ email === 'test@example.com'
93
+ ) {
94
+ errors.push('Email is a placeholder value');
95
+ }
96
+ }
97
+
98
+ return {
99
+ isValid: errors.length === 0,
100
+ errors,
101
+ warnings,
102
+ };
103
+ }
104
+
105
+ /**
106
+ * URL形式の検証
107
+ */
108
+ export function validateUrl(url: string, expectedDomain?: string): ValidationResult {
109
+ const errors: string[] = [];
110
+ const warnings: string[] = [];
111
+
112
+ if (!url || url.trim() === '') {
113
+ errors.push('URL is empty');
114
+ } else {
115
+ try {
116
+ const parsedUrl = new URL(url);
117
+
118
+ if (parsedUrl.protocol !== 'https:' && parsedUrl.protocol !== 'http:') {
119
+ errors.push(`Invalid URL protocol: ${parsedUrl.protocol} (expected https: or http:)`);
120
+ }
121
+
122
+ if (parsedUrl.protocol === 'http:') {
123
+ warnings.push('URL uses insecure http:// protocol (consider using https://)');
124
+ }
125
+
126
+ if (expectedDomain && !parsedUrl.hostname.includes(expectedDomain)) {
127
+ errors.push(`URL hostname ${parsedUrl.hostname} does not contain expected domain: ${expectedDomain}`);
128
+ }
129
+
130
+ if (url === 'https://example.com' || url === 'https://your-domain.atlassian.net') {
131
+ errors.push('URL is a placeholder value');
132
+ }
133
+ } catch (error) {
134
+ errors.push(`URL parsing failed: ${error instanceof Error ? error.message : error}`);
135
+ }
136
+ }
137
+
138
+ return {
139
+ isValid: errors.length === 0,
140
+ errors,
141
+ warnings,
142
+ };
143
+ }
144
+
145
+ /**
146
+ * Atlassian URL の検証
147
+ */
148
+ export function validateAtlassianUrl(url: string): ValidationResult {
149
+ const result = validateUrl(url, 'atlassian.net');
150
+
151
+ if (result.isValid) {
152
+ try {
153
+ const parsedUrl = new URL(url);
154
+ if (!parsedUrl.hostname.endsWith('.atlassian.net')) {
155
+ result.errors.push('Atlassian URL must end with .atlassian.net');
156
+ result.isValid = false;
157
+ }
158
+ } catch {
159
+ // Already handled in validateUrl
160
+ }
161
+ }
162
+
163
+ return result;
164
+ }
165
+
166
+ /**
167
+ * GitHub リポジトリ URL の検証
168
+ */
169
+ export function validateGitHubRepositoryUrl(url: string): ValidationResult {
170
+ const errors: string[] = [];
171
+ const warnings: string[] = [];
172
+
173
+ if (!url || url.trim() === '') {
174
+ errors.push('Repository URL is empty');
175
+ } else {
176
+ // GitHub URL 形式のパターン
177
+ const httpsPattern = /^https:\/\/github\.com\/[\w-]+\/[\w-]+(\.git)?$/;
178
+ const sshPattern = /^git@github\.com:[\w-]+\/[\w-]+(\.git)?$/;
179
+
180
+ if (!httpsPattern.test(url) && !sshPattern.test(url)) {
181
+ errors.push(
182
+ 'Repository URL must be in format: https://github.com/owner/repo.git or git@github.com:owner/repo.git',
183
+ );
184
+ }
185
+
186
+ if (url.includes('your-org') || url.includes('your-repo')) {
187
+ errors.push('Repository URL contains placeholder values');
188
+ }
189
+ }
190
+
191
+ return {
192
+ isValid: errors.length === 0,
193
+ errors,
194
+ warnings,
195
+ };
196
+ }
197
+
198
+ /**
199
+ * 環境変数の包括的検証
200
+ */
201
+ export interface EnvValidationConfig {
202
+ atlassianUrl?: string;
203
+ atlassianEmail?: string;
204
+ atlassianApiToken?: string;
205
+ githubOrg?: string;
206
+ githubToken?: string;
207
+ repositoryUrl?: string;
208
+ }
209
+
210
+ export function validateEnvironmentConfig(config: EnvValidationConfig): ValidationResult {
211
+ const allErrors: string[] = [];
212
+ const allWarnings: string[] = [];
213
+
214
+ if (config.atlassianUrl !== undefined) {
215
+ const result = validateAtlassianUrl(config.atlassianUrl);
216
+ allErrors.push(...result.errors.map((e) => `ATLASSIAN_URL: ${e}`));
217
+ allWarnings.push(...result.warnings.map((w) => `ATLASSIAN_URL: ${w}`));
218
+ }
219
+
220
+ if (config.atlassianEmail !== undefined) {
221
+ const result = validateEmail(config.atlassianEmail);
222
+ allErrors.push(...result.errors.map((e) => `ATLASSIAN_EMAIL: ${e}`));
223
+ allWarnings.push(...result.warnings.map((w) => `ATLASSIAN_EMAIL: ${w}`));
224
+ }
225
+
226
+ if (config.atlassianApiToken !== undefined) {
227
+ const result = validateAtlassianToken(config.atlassianApiToken);
228
+ allErrors.push(...result.errors.map((e) => `ATLASSIAN_API_TOKEN: ${e}`));
229
+ allWarnings.push(...result.warnings.map((w) => `ATLASSIAN_API_TOKEN: ${w}`));
230
+ }
231
+
232
+ if (config.githubOrg !== undefined) {
233
+ if (!config.githubOrg || config.githubOrg.trim() === '') {
234
+ allErrors.push('GITHUB_ORG: GitHub organization is empty');
235
+ } else if (config.githubOrg.includes('your-org')) {
236
+ allErrors.push('GITHUB_ORG: GitHub organization is a placeholder value');
237
+ }
238
+ }
239
+
240
+ if (config.githubToken !== undefined) {
241
+ const result = validateGitHubToken(config.githubToken);
242
+ allErrors.push(...result.errors.map((e) => `GITHUB_TOKEN: ${e}`));
243
+ allWarnings.push(...result.warnings.map((w) => `GITHUB_TOKEN: ${w}`));
244
+ }
245
+
246
+ if (config.repositoryUrl !== undefined) {
247
+ const result = validateGitHubRepositoryUrl(config.repositoryUrl);
248
+ allErrors.push(...result.errors.map((e) => `repository: ${e}`));
249
+ allWarnings.push(...result.warnings.map((w) => `repository: ${w}`));
250
+ }
251
+
252
+ return {
253
+ isValid: allErrors.length === 0,
254
+ errors: allErrors,
255
+ warnings: allWarnings,
256
+ };
257
+ }
258
+
259
+ /**
260
+ * ファイルパーミッションの検証(Unix系のみ)
261
+ */
262
+ export function validateFilePermissions(filePath: string, expectedMode: number = 0o600): ValidationResult {
263
+ const errors: string[] = [];
264
+ const warnings: string[] = [];
265
+
266
+ try {
267
+ const stats = statSync(filePath);
268
+ const actualMode = stats.mode & 0o777;
269
+
270
+ if (actualMode !== expectedMode) {
271
+ const actualOctal = actualMode.toString(8);
272
+ const expectedOctal = expectedMode.toString(8);
273
+ warnings.push(
274
+ `File permissions are ${actualOctal} but should be ${expectedOctal} for security. Run: chmod ${expectedOctal} ${filePath}`,
275
+ );
276
+ }
277
+ } catch (error) {
278
+ errors.push(`Failed to check file permissions: ${error instanceof Error ? error.message : error}`);
279
+ }
280
+
281
+ return {
282
+ isValid: errors.length === 0,
283
+ errors,
284
+ warnings,
285
+ };
286
+ }