@shirokuma-library/shirokuma-docs 0.1.0-alpha.10

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.

Potentially problematic release.


This version of @shirokuma-library/shirokuma-docs might be problematic. Click here for more details.

Files changed (761) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +346 -0
  3. package/README.md +346 -0
  4. package/THIRD_PARTY_NOTICES.md +18 -0
  5. package/bin/shirokuma-docs +2 -0
  6. package/dist/analyzers/details-test-analysis.d.ts +31 -0
  7. package/dist/analyzers/details-test-analysis.d.ts.map +1 -0
  8. package/dist/analyzers/details-test-analysis.js +174 -0
  9. package/dist/analyzers/details-test-analysis.js.map +1 -0
  10. package/dist/analyzers/feature-map-builder.d.ts +20 -0
  11. package/dist/analyzers/feature-map-builder.d.ts.map +1 -0
  12. package/dist/analyzers/feature-map-builder.js +154 -0
  13. package/dist/analyzers/feature-map-builder.js.map +1 -0
  14. package/dist/analyzers/feature-map-references.d.ts +34 -0
  15. package/dist/analyzers/feature-map-references.d.ts.map +1 -0
  16. package/dist/analyzers/feature-map-references.js +249 -0
  17. package/dist/analyzers/feature-map-references.js.map +1 -0
  18. package/dist/analyzers/reference-analyzer.d.ts +95 -0
  19. package/dist/analyzers/reference-analyzer.d.ts.map +1 -0
  20. package/dist/analyzers/reference-analyzer.js +372 -0
  21. package/dist/analyzers/reference-analyzer.js.map +1 -0
  22. package/dist/commands/adr.d.ts +26 -0
  23. package/dist/commands/adr.d.ts.map +1 -0
  24. package/dist/commands/adr.js +129 -0
  25. package/dist/commands/adr.js.map +1 -0
  26. package/dist/commands/api-tools.d.ts +83 -0
  27. package/dist/commands/api-tools.d.ts.map +1 -0
  28. package/dist/commands/api-tools.js +775 -0
  29. package/dist/commands/api-tools.js.map +1 -0
  30. package/dist/commands/coverage.d.ts +139 -0
  31. package/dist/commands/coverage.d.ts.map +1 -0
  32. package/dist/commands/coverage.js +481 -0
  33. package/dist/commands/coverage.js.map +1 -0
  34. package/dist/commands/deps.d.ts +24 -0
  35. package/dist/commands/deps.d.ts.map +1 -0
  36. package/dist/commands/deps.js +211 -0
  37. package/dist/commands/deps.js.map +1 -0
  38. package/dist/commands/details-context.d.ts +38 -0
  39. package/dist/commands/details-context.d.ts.map +1 -0
  40. package/dist/commands/details-context.js +195 -0
  41. package/dist/commands/details-context.js.map +1 -0
  42. package/dist/commands/details-types.d.ts +315 -0
  43. package/dist/commands/details-types.d.ts.map +1 -0
  44. package/dist/commands/details-types.js +7 -0
  45. package/dist/commands/details-types.js.map +1 -0
  46. package/dist/commands/details.d.ts +24 -0
  47. package/dist/commands/details.d.ts.map +1 -0
  48. package/dist/commands/details.js +299 -0
  49. package/dist/commands/details.js.map +1 -0
  50. package/dist/commands/discussion-templates.d.ts +26 -0
  51. package/dist/commands/discussion-templates.d.ts.map +1 -0
  52. package/dist/commands/discussion-templates.js +270 -0
  53. package/dist/commands/discussion-templates.js.map +1 -0
  54. package/dist/commands/discussions.d.ts +31 -0
  55. package/dist/commands/discussions.d.ts.map +1 -0
  56. package/dist/commands/discussions.js +744 -0
  57. package/dist/commands/discussions.js.map +1 -0
  58. package/dist/commands/feature-map-types.d.ts +294 -0
  59. package/dist/commands/feature-map-types.d.ts.map +1 -0
  60. package/dist/commands/feature-map-types.js +8 -0
  61. package/dist/commands/feature-map-types.js.map +1 -0
  62. package/dist/commands/feature-map.d.ts +30 -0
  63. package/dist/commands/feature-map.d.ts.map +1 -0
  64. package/dist/commands/feature-map.js +137 -0
  65. package/dist/commands/feature-map.js.map +1 -0
  66. package/dist/commands/generate.d.ts +16 -0
  67. package/dist/commands/generate.d.ts.map +1 -0
  68. package/dist/commands/generate.js +88 -0
  69. package/dist/commands/generate.js.map +1 -0
  70. package/dist/commands/gh-discussions.d.ts +31 -0
  71. package/dist/commands/gh-discussions.d.ts.map +1 -0
  72. package/dist/commands/gh-discussions.js +743 -0
  73. package/dist/commands/gh-discussions.js.map +1 -0
  74. package/dist/commands/gh-issues-pr.d.ts +74 -0
  75. package/dist/commands/gh-issues-pr.d.ts.map +1 -0
  76. package/dist/commands/gh-issues-pr.js +417 -0
  77. package/dist/commands/gh-issues-pr.js.map +1 -0
  78. package/dist/commands/gh-issues.d.ts +90 -0
  79. package/dist/commands/gh-issues.d.ts.map +1 -0
  80. package/dist/commands/gh-issues.js +1297 -0
  81. package/dist/commands/gh-issues.js.map +1 -0
  82. package/dist/commands/gh-projects.d.ts +54 -0
  83. package/dist/commands/gh-projects.d.ts.map +1 -0
  84. package/dist/commands/gh-projects.js +966 -0
  85. package/dist/commands/gh-projects.js.map +1 -0
  86. package/dist/commands/gh-repo.d.ts +18 -0
  87. package/dist/commands/gh-repo.d.ts.map +1 -0
  88. package/dist/commands/gh-repo.js +253 -0
  89. package/dist/commands/gh-repo.js.map +1 -0
  90. package/dist/commands/github-data.d.ts +67 -0
  91. package/dist/commands/github-data.d.ts.map +1 -0
  92. package/dist/commands/github-data.js +361 -0
  93. package/dist/commands/github-data.js.map +1 -0
  94. package/dist/commands/i18n.d.ts +102 -0
  95. package/dist/commands/i18n.d.ts.map +1 -0
  96. package/dist/commands/i18n.js +829 -0
  97. package/dist/commands/i18n.js.map +1 -0
  98. package/dist/commands/impact.d.ts +14 -0
  99. package/dist/commands/impact.d.ts.map +1 -0
  100. package/dist/commands/impact.js +263 -0
  101. package/dist/commands/impact.js.map +1 -0
  102. package/dist/commands/init.d.ts +53 -0
  103. package/dist/commands/init.d.ts.map +1 -0
  104. package/dist/commands/init.js +468 -0
  105. package/dist/commands/init.js.map +1 -0
  106. package/dist/commands/issues-pr.d.ts +83 -0
  107. package/dist/commands/issues-pr.d.ts.map +1 -0
  108. package/dist/commands/issues-pr.js +572 -0
  109. package/dist/commands/issues-pr.js.map +1 -0
  110. package/dist/commands/issues.d.ts +78 -0
  111. package/dist/commands/issues.d.ts.map +1 -0
  112. package/dist/commands/issues.js +1541 -0
  113. package/dist/commands/issues.js.map +1 -0
  114. package/dist/commands/link-docs.d.ts +21 -0
  115. package/dist/commands/link-docs.d.ts.map +1 -0
  116. package/dist/commands/link-docs.js +990 -0
  117. package/dist/commands/link-docs.js.map +1 -0
  118. package/dist/commands/lint-annotations.d.ts +28 -0
  119. package/dist/commands/lint-annotations.d.ts.map +1 -0
  120. package/dist/commands/lint-annotations.js +511 -0
  121. package/dist/commands/lint-annotations.js.map +1 -0
  122. package/dist/commands/lint-code.d.ts +26 -0
  123. package/dist/commands/lint-code.d.ts.map +1 -0
  124. package/dist/commands/lint-code.js +428 -0
  125. package/dist/commands/lint-code.js.map +1 -0
  126. package/dist/commands/lint-coverage.d.ts +33 -0
  127. package/dist/commands/lint-coverage.d.ts.map +1 -0
  128. package/dist/commands/lint-coverage.js +379 -0
  129. package/dist/commands/lint-coverage.js.map +1 -0
  130. package/dist/commands/lint-docs.d.ts +23 -0
  131. package/dist/commands/lint-docs.d.ts.map +1 -0
  132. package/dist/commands/lint-docs.js +338 -0
  133. package/dist/commands/lint-docs.js.map +1 -0
  134. package/dist/commands/lint-structure.d.ts +38 -0
  135. package/dist/commands/lint-structure.d.ts.map +1 -0
  136. package/dist/commands/lint-structure.js +350 -0
  137. package/dist/commands/lint-structure.js.map +1 -0
  138. package/dist/commands/lint-tests.d.ts +25 -0
  139. package/dist/commands/lint-tests.d.ts.map +1 -0
  140. package/dist/commands/lint-tests.js +105 -0
  141. package/dist/commands/lint-tests.js.map +1 -0
  142. package/dist/commands/lint-workflow.d.ts +36 -0
  143. package/dist/commands/lint-workflow.d.ts.map +1 -0
  144. package/dist/commands/lint-workflow.js +255 -0
  145. package/dist/commands/lint-workflow.js.map +1 -0
  146. package/dist/commands/overview.d.ts +21 -0
  147. package/dist/commands/overview.d.ts.map +1 -0
  148. package/dist/commands/overview.js +1300 -0
  149. package/dist/commands/overview.js.map +1 -0
  150. package/dist/commands/packages.d.ts +107 -0
  151. package/dist/commands/packages.d.ts.map +1 -0
  152. package/dist/commands/packages.js +308 -0
  153. package/dist/commands/packages.js.map +1 -0
  154. package/dist/commands/portal-nextjs.d.ts +23 -0
  155. package/dist/commands/portal-nextjs.d.ts.map +1 -0
  156. package/dist/commands/portal-nextjs.js +336 -0
  157. package/dist/commands/portal-nextjs.js.map +1 -0
  158. package/dist/commands/portal.d.ts +24 -0
  159. package/dist/commands/portal.d.ts.map +1 -0
  160. package/dist/commands/portal.js +16 -0
  161. package/dist/commands/portal.js.map +1 -0
  162. package/dist/commands/projects.d.ts +54 -0
  163. package/dist/commands/projects.d.ts.map +1 -0
  164. package/dist/commands/projects.js +1191 -0
  165. package/dist/commands/projects.js.map +1 -0
  166. package/dist/commands/repo-pairs.d.ts +19 -0
  167. package/dist/commands/repo-pairs.d.ts.map +1 -0
  168. package/dist/commands/repo-pairs.js +529 -0
  169. package/dist/commands/repo-pairs.js.map +1 -0
  170. package/dist/commands/repo.d.ts +18 -0
  171. package/dist/commands/repo.d.ts.map +1 -0
  172. package/dist/commands/repo.js +253 -0
  173. package/dist/commands/repo.js.map +1 -0
  174. package/dist/commands/schema.d.ts +49 -0
  175. package/dist/commands/schema.d.ts.map +1 -0
  176. package/dist/commands/schema.js +830 -0
  177. package/dist/commands/schema.js.map +1 -0
  178. package/dist/commands/screenshots.d.ts +203 -0
  179. package/dist/commands/screenshots.d.ts.map +1 -0
  180. package/dist/commands/screenshots.js +1234 -0
  181. package/dist/commands/screenshots.js.map +1 -0
  182. package/dist/commands/search-index.d.ts +83 -0
  183. package/dist/commands/search-index.d.ts.map +1 -0
  184. package/dist/commands/search-index.js +389 -0
  185. package/dist/commands/search-index.js.map +1 -0
  186. package/dist/commands/search.d.ts +24 -0
  187. package/dist/commands/search.d.ts.map +1 -0
  188. package/dist/commands/search.js +254 -0
  189. package/dist/commands/search.js.map +1 -0
  190. package/dist/commands/session.d.ts +159 -0
  191. package/dist/commands/session.d.ts.map +1 -0
  192. package/dist/commands/session.js +1274 -0
  193. package/dist/commands/session.js.map +1 -0
  194. package/dist/commands/test-cases-types.d.ts +154 -0
  195. package/dist/commands/test-cases-types.d.ts.map +1 -0
  196. package/dist/commands/test-cases-types.js +7 -0
  197. package/dist/commands/test-cases-types.js.map +1 -0
  198. package/dist/commands/test-cases.d.ts +28 -0
  199. package/dist/commands/test-cases.d.ts.map +1 -0
  200. package/dist/commands/test-cases.js +192 -0
  201. package/dist/commands/test-cases.js.map +1 -0
  202. package/dist/commands/typedoc.d.ts +21 -0
  203. package/dist/commands/typedoc.d.ts.map +1 -0
  204. package/dist/commands/typedoc.js +192 -0
  205. package/dist/commands/typedoc.js.map +1 -0
  206. package/dist/commands/update-skills.d.ts +56 -0
  207. package/dist/commands/update-skills.d.ts.map +1 -0
  208. package/dist/commands/update-skills.js +626 -0
  209. package/dist/commands/update-skills.js.map +1 -0
  210. package/dist/generators/details-entity-pages.d.ts +40 -0
  211. package/dist/generators/details-entity-pages.d.ts.map +1 -0
  212. package/dist/generators/details-entity-pages.js +301 -0
  213. package/dist/generators/details-entity-pages.js.map +1 -0
  214. package/dist/generators/details-html.d.ts +23 -0
  215. package/dist/generators/details-html.d.ts.map +1 -0
  216. package/dist/generators/details-html.js +324 -0
  217. package/dist/generators/details-html.js.map +1 -0
  218. package/dist/generators/details-module-page.d.ts +33 -0
  219. package/dist/generators/details-module-page.d.ts.map +1 -0
  220. package/dist/generators/details-module-page.js +408 -0
  221. package/dist/generators/details-module-page.js.map +1 -0
  222. package/dist/generators/details-styles.d.ts +39 -0
  223. package/dist/generators/details-styles.d.ts.map +1 -0
  224. package/dist/generators/details-styles.js +409 -0
  225. package/dist/generators/details-styles.js.map +1 -0
  226. package/dist/generators/feature-map-html.d.ts +66 -0
  227. package/dist/generators/feature-map-html.d.ts.map +1 -0
  228. package/dist/generators/feature-map-html.js +569 -0
  229. package/dist/generators/feature-map-html.js.map +1 -0
  230. package/dist/generators/feature-map-styles.d.ts +39 -0
  231. package/dist/generators/feature-map-styles.d.ts.map +1 -0
  232. package/dist/generators/feature-map-styles.js +449 -0
  233. package/dist/generators/feature-map-styles.js.map +1 -0
  234. package/dist/generators/test-cases-hierarchy.d.ts +21 -0
  235. package/dist/generators/test-cases-hierarchy.d.ts.map +1 -0
  236. package/dist/generators/test-cases-hierarchy.js +336 -0
  237. package/dist/generators/test-cases-hierarchy.js.map +1 -0
  238. package/dist/generators/test-cases-main.d.ts +20 -0
  239. package/dist/generators/test-cases-main.d.ts.map +1 -0
  240. package/dist/generators/test-cases-main.js +439 -0
  241. package/dist/generators/test-cases-main.js.map +1 -0
  242. package/dist/generators/test-cases-styles.d.ts +64 -0
  243. package/dist/generators/test-cases-styles.d.ts.map +1 -0
  244. package/dist/generators/test-cases-styles.js +1277 -0
  245. package/dist/generators/test-cases-styles.js.map +1 -0
  246. package/dist/index.d.ts +13 -0
  247. package/dist/index.d.ts.map +1 -0
  248. package/dist/index.js +600 -0
  249. package/dist/index.js.map +1 -0
  250. package/dist/lint/annotation-lint.d.ts +198 -0
  251. package/dist/lint/annotation-lint.d.ts.map +1 -0
  252. package/dist/lint/annotation-lint.js +510 -0
  253. package/dist/lint/annotation-lint.js.map +1 -0
  254. package/dist/lint/annotation-types.d.ts +161 -0
  255. package/dist/lint/annotation-types.d.ts.map +1 -0
  256. package/dist/lint/annotation-types.js +31 -0
  257. package/dist/lint/annotation-types.js.map +1 -0
  258. package/dist/lint/code-types.d.ts +135 -0
  259. package/dist/lint/code-types.d.ts.map +1 -0
  260. package/dist/lint/code-types.js +25 -0
  261. package/dist/lint/code-types.js.map +1 -0
  262. package/dist/lint/coverage-types.d.ts +128 -0
  263. package/dist/lint/coverage-types.d.ts.map +1 -0
  264. package/dist/lint/coverage-types.js +24 -0
  265. package/dist/lint/coverage-types.js.map +1 -0
  266. package/dist/lint/docs-types.d.ts +214 -0
  267. package/dist/lint/docs-types.d.ts.map +1 -0
  268. package/dist/lint/docs-types.js +18 -0
  269. package/dist/lint/docs-types.js.map +1 -0
  270. package/dist/lint/formatters/index.d.ts +14 -0
  271. package/dist/lint/formatters/index.d.ts.map +1 -0
  272. package/dist/lint/formatters/index.js +28 -0
  273. package/dist/lint/formatters/index.js.map +1 -0
  274. package/dist/lint/formatters/json.d.ts +11 -0
  275. package/dist/lint/formatters/json.d.ts.map +1 -0
  276. package/dist/lint/formatters/json.js +12 -0
  277. package/dist/lint/formatters/json.js.map +1 -0
  278. package/dist/lint/formatters/summary.d.ts +11 -0
  279. package/dist/lint/formatters/summary.d.ts.map +1 -0
  280. package/dist/lint/formatters/summary.js +37 -0
  281. package/dist/lint/formatters/summary.js.map +1 -0
  282. package/dist/lint/formatters/terminal.d.ts +11 -0
  283. package/dist/lint/formatters/terminal.d.ts.map +1 -0
  284. package/dist/lint/formatters/terminal.js +99 -0
  285. package/dist/lint/formatters/terminal.js.map +1 -0
  286. package/dist/lint/index.d.ts +18 -0
  287. package/dist/lint/index.d.ts.map +1 -0
  288. package/dist/lint/index.js +103 -0
  289. package/dist/lint/index.js.map +1 -0
  290. package/dist/lint/rules/annotation-required.d.ts +35 -0
  291. package/dist/lint/rules/annotation-required.d.ts.map +1 -0
  292. package/dist/lint/rules/annotation-required.js +127 -0
  293. package/dist/lint/rules/annotation-required.js.map +1 -0
  294. package/dist/lint/rules/code-rules.d.ts +12 -0
  295. package/dist/lint/rules/code-rules.d.ts.map +1 -0
  296. package/dist/lint/rules/code-rules.js +11 -0
  297. package/dist/lint/rules/code-rules.js.map +1 -0
  298. package/dist/lint/rules/describe-coverage.d.ts +8 -0
  299. package/dist/lint/rules/describe-coverage.d.ts.map +1 -0
  300. package/dist/lint/rules/describe-coverage.js +43 -0
  301. package/dist/lint/rules/describe-coverage.js.map +1 -0
  302. package/dist/lint/rules/duplicate-testdoc.d.ts +8 -0
  303. package/dist/lint/rules/duplicate-testdoc.d.ts.map +1 -0
  304. package/dist/lint/rules/duplicate-testdoc.js +38 -0
  305. package/dist/lint/rules/duplicate-testdoc.js.map +1 -0
  306. package/dist/lint/rules/index.d.ts +29 -0
  307. package/dist/lint/rules/index.d.ts.map +1 -0
  308. package/dist/lint/rules/index.js +55 -0
  309. package/dist/lint/rules/index.js.map +1 -0
  310. package/dist/lint/rules/server-action-structure.d.ts +37 -0
  311. package/dist/lint/rules/server-action-structure.d.ts.map +1 -0
  312. package/dist/lint/rules/server-action-structure.js +152 -0
  313. package/dist/lint/rules/server-action-structure.js.map +1 -0
  314. package/dist/lint/rules/skipped-test-report.d.ts +11 -0
  315. package/dist/lint/rules/skipped-test-report.d.ts.map +1 -0
  316. package/dist/lint/rules/skipped-test-report.js +31 -0
  317. package/dist/lint/rules/skipped-test-report.js.map +1 -0
  318. package/dist/lint/rules/structure-rules.d.ts +67 -0
  319. package/dist/lint/rules/structure-rules.d.ts.map +1 -0
  320. package/dist/lint/rules/structure-rules.js +617 -0
  321. package/dist/lint/rules/structure-rules.js.map +1 -0
  322. package/dist/lint/rules/testdoc-japanese.d.ts +8 -0
  323. package/dist/lint/rules/testdoc-japanese.d.ts.map +1 -0
  324. package/dist/lint/rules/testdoc-japanese.js +31 -0
  325. package/dist/lint/rules/testdoc-japanese.js.map +1 -0
  326. package/dist/lint/rules/testdoc-min-length.d.ts +8 -0
  327. package/dist/lint/rules/testdoc-min-length.d.ts.map +1 -0
  328. package/dist/lint/rules/testdoc-min-length.js +31 -0
  329. package/dist/lint/rules/testdoc-min-length.js.map +1 -0
  330. package/dist/lint/rules/testdoc-required.d.ts +8 -0
  331. package/dist/lint/rules/testdoc-required.d.ts.map +1 -0
  332. package/dist/lint/rules/testdoc-required.js +27 -0
  333. package/dist/lint/rules/testdoc-required.js.map +1 -0
  334. package/dist/lint/rules/workflow-branch-naming.d.ts +20 -0
  335. package/dist/lint/rules/workflow-branch-naming.d.ts.map +1 -0
  336. package/dist/lint/rules/workflow-branch-naming.js +85 -0
  337. package/dist/lint/rules/workflow-branch-naming.js.map +1 -0
  338. package/dist/lint/rules/workflow-commit-format.d.ts +27 -0
  339. package/dist/lint/rules/workflow-commit-format.d.ts.map +1 -0
  340. package/dist/lint/rules/workflow-commit-format.js +92 -0
  341. package/dist/lint/rules/workflow-commit-format.js.map +1 -0
  342. package/dist/lint/rules/workflow-issue-fields.d.ts +24 -0
  343. package/dist/lint/rules/workflow-issue-fields.d.ts.map +1 -0
  344. package/dist/lint/rules/workflow-issue-fields.js +89 -0
  345. package/dist/lint/rules/workflow-issue-fields.js.map +1 -0
  346. package/dist/lint/rules/workflow-main-protection.d.ts +32 -0
  347. package/dist/lint/rules/workflow-main-protection.d.ts.map +1 -0
  348. package/dist/lint/rules/workflow-main-protection.js +114 -0
  349. package/dist/lint/rules/workflow-main-protection.js.map +1 -0
  350. package/dist/lint/structure-types.d.ts +216 -0
  351. package/dist/lint/structure-types.d.ts.map +1 -0
  352. package/dist/lint/structure-types.js +96 -0
  353. package/dist/lint/structure-types.js.map +1 -0
  354. package/dist/lint/types.d.ts +154 -0
  355. package/dist/lint/types.d.ts.map +1 -0
  356. package/dist/lint/types.js +21 -0
  357. package/dist/lint/types.js.map +1 -0
  358. package/dist/lint/workflow-types.d.ts +90 -0
  359. package/dist/lint/workflow-types.d.ts.map +1 -0
  360. package/dist/lint/workflow-types.js +7 -0
  361. package/dist/lint/workflow-types.js.map +1 -0
  362. package/dist/md/analyzer/index.d.ts +46 -0
  363. package/dist/md/analyzer/index.d.ts.map +1 -0
  364. package/dist/md/analyzer/index.js +288 -0
  365. package/dist/md/analyzer/index.js.map +1 -0
  366. package/dist/md/builder/index.d.ts +91 -0
  367. package/dist/md/builder/index.d.ts.map +1 -0
  368. package/dist/md/builder/index.js +446 -0
  369. package/dist/md/builder/index.js.map +1 -0
  370. package/dist/md/cli/analyze.d.ts +11 -0
  371. package/dist/md/cli/analyze.d.ts.map +1 -0
  372. package/dist/md/cli/analyze.js +118 -0
  373. package/dist/md/cli/analyze.js.map +1 -0
  374. package/dist/md/cli/build.d.ts +11 -0
  375. package/dist/md/cli/build.d.ts.map +1 -0
  376. package/dist/md/cli/build.js +74 -0
  377. package/dist/md/cli/build.js.map +1 -0
  378. package/dist/md/cli/extract.d.ts +25 -0
  379. package/dist/md/cli/extract.d.ts.map +1 -0
  380. package/dist/md/cli/extract.js +230 -0
  381. package/dist/md/cli/extract.js.map +1 -0
  382. package/dist/md/cli/index.d.ts +3 -0
  383. package/dist/md/cli/index.d.ts.map +1 -0
  384. package/dist/md/cli/index.js +99 -0
  385. package/dist/md/cli/index.js.map +1 -0
  386. package/dist/md/cli/lint.d.ts +11 -0
  387. package/dist/md/cli/lint.d.ts.map +1 -0
  388. package/dist/md/cli/lint.js +165 -0
  389. package/dist/md/cli/lint.js.map +1 -0
  390. package/dist/md/cli/list.d.ts +16 -0
  391. package/dist/md/cli/list.d.ts.map +1 -0
  392. package/dist/md/cli/list.js +85 -0
  393. package/dist/md/cli/list.js.map +1 -0
  394. package/dist/md/cli/program.d.ts +11 -0
  395. package/dist/md/cli/program.d.ts.map +1 -0
  396. package/dist/md/cli/program.js +104 -0
  397. package/dist/md/cli/program.js.map +1 -0
  398. package/dist/md/cli/validate.d.ts +8 -0
  399. package/dist/md/cli/validate.d.ts.map +1 -0
  400. package/dist/md/cli/validate.js +82 -0
  401. package/dist/md/cli/validate.js.map +1 -0
  402. package/dist/md/constants.d.ts +69 -0
  403. package/dist/md/constants.d.ts.map +1 -0
  404. package/dist/md/constants.js +69 -0
  405. package/dist/md/constants.js.map +1 -0
  406. package/dist/md/extractor/index.d.ts +57 -0
  407. package/dist/md/extractor/index.d.ts.map +1 -0
  408. package/dist/md/extractor/index.js +365 -0
  409. package/dist/md/extractor/index.js.map +1 -0
  410. package/dist/md/index.d.ts +26 -0
  411. package/dist/md/index.d.ts.map +1 -0
  412. package/dist/md/index.js +30 -0
  413. package/dist/md/index.js.map +1 -0
  414. package/dist/md/linter/index.d.ts +20 -0
  415. package/dist/md/linter/index.d.ts.map +1 -0
  416. package/dist/md/linter/index.js +421 -0
  417. package/dist/md/linter/index.js.map +1 -0
  418. package/dist/md/linter/token-optimizer.d.ts +66 -0
  419. package/dist/md/linter/token-optimizer.d.ts.map +1 -0
  420. package/dist/md/linter/token-optimizer.js +292 -0
  421. package/dist/md/linter/token-optimizer.js.map +1 -0
  422. package/dist/md/lister/index.d.ts +42 -0
  423. package/dist/md/lister/index.d.ts.map +1 -0
  424. package/dist/md/lister/index.js +317 -0
  425. package/dist/md/lister/index.js.map +1 -0
  426. package/dist/md/parser/heading-numbers.d.ts +43 -0
  427. package/dist/md/parser/heading-numbers.d.ts.map +1 -0
  428. package/dist/md/parser/heading-numbers.js +97 -0
  429. package/dist/md/parser/heading-numbers.js.map +1 -0
  430. package/dist/md/parser/section-meta.d.ts +50 -0
  431. package/dist/md/parser/section-meta.d.ts.map +1 -0
  432. package/dist/md/parser/section-meta.js +212 -0
  433. package/dist/md/parser/section-meta.js.map +1 -0
  434. package/dist/md/parser/template.d.ts +56 -0
  435. package/dist/md/parser/template.d.ts.map +1 -0
  436. package/dist/md/parser/template.js +122 -0
  437. package/dist/md/parser/template.js.map +1 -0
  438. package/dist/md/plugins/loader.d.ts +15 -0
  439. package/dist/md/plugins/loader.d.ts.map +1 -0
  440. package/dist/md/plugins/loader.js +80 -0
  441. package/dist/md/plugins/loader.js.map +1 -0
  442. package/dist/md/plugins/normalize-headings.d.ts +43 -0
  443. package/dist/md/plugins/normalize-headings.d.ts.map +1 -0
  444. package/dist/md/plugins/normalize-headings.js +51 -0
  445. package/dist/md/plugins/normalize-headings.js.map +1 -0
  446. package/dist/md/plugins/normalize-whitespace.d.ts +46 -0
  447. package/dist/md/plugins/normalize-whitespace.d.ts.map +1 -0
  448. package/dist/md/plugins/normalize-whitespace.js +86 -0
  449. package/dist/md/plugins/normalize-whitespace.js.map +1 -0
  450. package/dist/md/plugins/remove-badges.d.ts +36 -0
  451. package/dist/md/plugins/remove-badges.d.ts.map +1 -0
  452. package/dist/md/plugins/remove-badges.js +59 -0
  453. package/dist/md/plugins/remove-badges.js.map +1 -0
  454. package/dist/md/plugins/remove-comments.d.ts +27 -0
  455. package/dist/md/plugins/remove-comments.d.ts.map +1 -0
  456. package/dist/md/plugins/remove-comments.js +40 -0
  457. package/dist/md/plugins/remove-comments.js.map +1 -0
  458. package/dist/md/plugins/remove-duplicates.d.ts +40 -0
  459. package/dist/md/plugins/remove-duplicates.d.ts.map +1 -0
  460. package/dist/md/plugins/remove-duplicates.js +72 -0
  461. package/dist/md/plugins/remove-duplicates.js.map +1 -0
  462. package/dist/md/plugins/remove-internal-links.d.ts +38 -0
  463. package/dist/md/plugins/remove-internal-links.d.ts.map +1 -0
  464. package/dist/md/plugins/remove-internal-links.js +66 -0
  465. package/dist/md/plugins/remove-internal-links.js.map +1 -0
  466. package/dist/md/plugins/strip-heading-numbers.d.ts +35 -0
  467. package/dist/md/plugins/strip-heading-numbers.d.ts.map +1 -0
  468. package/dist/md/plugins/strip-heading-numbers.js +59 -0
  469. package/dist/md/plugins/strip-heading-numbers.js.map +1 -0
  470. package/dist/md/plugins/strip-section-meta.d.ts +37 -0
  471. package/dist/md/plugins/strip-section-meta.d.ts.map +1 -0
  472. package/dist/md/plugins/strip-section-meta.js +62 -0
  473. package/dist/md/plugins/strip-section-meta.js.map +1 -0
  474. package/dist/md/types/config.d.ts +260 -0
  475. package/dist/md/types/config.d.ts.map +1 -0
  476. package/dist/md/types/config.js +156 -0
  477. package/dist/md/types/config.js.map +1 -0
  478. package/dist/md/types/document.d.ts +37 -0
  479. package/dist/md/types/document.d.ts.map +1 -0
  480. package/dist/md/types/document.js +2 -0
  481. package/dist/md/types/document.js.map +1 -0
  482. package/dist/md/types/validation.d.ts +107 -0
  483. package/dist/md/types/validation.d.ts.map +1 -0
  484. package/dist/md/types/validation.js +2 -0
  485. package/dist/md/types/validation.js.map +1 -0
  486. package/dist/md/utils/code-blocks.d.ts +136 -0
  487. package/dist/md/utils/code-blocks.d.ts.map +1 -0
  488. package/dist/md/utils/code-blocks.js +178 -0
  489. package/dist/md/utils/code-blocks.js.map +1 -0
  490. package/dist/md/utils/config.d.ts +10 -0
  491. package/dist/md/utils/config.d.ts.map +1 -0
  492. package/dist/md/utils/config.js +99 -0
  493. package/dist/md/utils/config.js.map +1 -0
  494. package/dist/md/utils/file-collector.d.ts +78 -0
  495. package/dist/md/utils/file-collector.d.ts.map +1 -0
  496. package/dist/md/utils/file-collector.js +100 -0
  497. package/dist/md/utils/file-collector.js.map +1 -0
  498. package/dist/md/utils/markdown.d.ts +18 -0
  499. package/dist/md/utils/markdown.d.ts.map +1 -0
  500. package/dist/md/utils/markdown.js +93 -0
  501. package/dist/md/utils/markdown.js.map +1 -0
  502. package/dist/md/utils/remark.d.ts +91 -0
  503. package/dist/md/utils/remark.d.ts.map +1 -0
  504. package/dist/md/utils/remark.js +125 -0
  505. package/dist/md/utils/remark.js.map +1 -0
  506. package/dist/md/utils/tokens.d.ts +9 -0
  507. package/dist/md/utils/tokens.d.ts.map +1 -0
  508. package/dist/md/utils/tokens.js +31 -0
  509. package/dist/md/utils/tokens.js.map +1 -0
  510. package/dist/md/validator/index.d.ts +40 -0
  511. package/dist/md/validator/index.d.ts.map +1 -0
  512. package/dist/md/validator/index.js +299 -0
  513. package/dist/md/validator/index.js.map +1 -0
  514. package/dist/parsers/details-jsdoc.d.ts +42 -0
  515. package/dist/parsers/details-jsdoc.d.ts.map +1 -0
  516. package/dist/parsers/details-jsdoc.js +256 -0
  517. package/dist/parsers/details-jsdoc.js.map +1 -0
  518. package/dist/parsers/details-zod.d.ts +22 -0
  519. package/dist/parsers/details-zod.d.ts.map +1 -0
  520. package/dist/parsers/details-zod.js +146 -0
  521. package/dist/parsers/details-zod.js.map +1 -0
  522. package/dist/parsers/drizzle-schema.d.ts +92 -0
  523. package/dist/parsers/drizzle-schema.d.ts.map +1 -0
  524. package/dist/parsers/drizzle-schema.js +376 -0
  525. package/dist/parsers/drizzle-schema.js.map +1 -0
  526. package/dist/parsers/feature-map-tags.d.ts +45 -0
  527. package/dist/parsers/feature-map-tags.d.ts.map +1 -0
  528. package/dist/parsers/feature-map-tags.js +292 -0
  529. package/dist/parsers/feature-map-tags.js.map +1 -0
  530. package/dist/parsers/feature-map-type-extraction.d.ts +62 -0
  531. package/dist/parsers/feature-map-type-extraction.d.ts.map +1 -0
  532. package/dist/parsers/feature-map-type-extraction.js +347 -0
  533. package/dist/parsers/feature-map-type-extraction.js.map +1 -0
  534. package/dist/parsers/feature-map-utils.d.ts +34 -0
  535. package/dist/parsers/feature-map-utils.d.ts.map +1 -0
  536. package/dist/parsers/feature-map-utils.js +101 -0
  537. package/dist/parsers/feature-map-utils.js.map +1 -0
  538. package/dist/parsers/jsdoc-common.d.ts +209 -0
  539. package/dist/parsers/jsdoc-common.d.ts.map +1 -0
  540. package/dist/parsers/jsdoc-common.js +650 -0
  541. package/dist/parsers/jsdoc-common.js.map +1 -0
  542. package/dist/parsers/jsdoc.d.ts +76 -0
  543. package/dist/parsers/jsdoc.d.ts.map +1 -0
  544. package/dist/parsers/jsdoc.js +238 -0
  545. package/dist/parsers/jsdoc.js.map +1 -0
  546. package/dist/parsers/screenshot-annotations.d.ts +96 -0
  547. package/dist/parsers/screenshot-annotations.d.ts.map +1 -0
  548. package/dist/parsers/screenshot-annotations.js +227 -0
  549. package/dist/parsers/screenshot-annotations.js.map +1 -0
  550. package/dist/parsers/test-annotations.d.ts +46 -0
  551. package/dist/parsers/test-annotations.d.ts.map +1 -0
  552. package/dist/parsers/test-annotations.js +393 -0
  553. package/dist/parsers/test-annotations.js.map +1 -0
  554. package/dist/parsers/test-categorization.d.ts +42 -0
  555. package/dist/parsers/test-categorization.d.ts.map +1 -0
  556. package/dist/parsers/test-categorization.js +182 -0
  557. package/dist/parsers/test-categorization.js.map +1 -0
  558. package/dist/parsers/zod-schema.d.ts +105 -0
  559. package/dist/parsers/zod-schema.d.ts.map +1 -0
  560. package/dist/parsers/zod-schema.js +271 -0
  561. package/dist/parsers/zod-schema.js.map +1 -0
  562. package/dist/utils/action-inference.d.ts +23 -0
  563. package/dist/utils/action-inference.d.ts.map +1 -0
  564. package/dist/utils/action-inference.js +36 -0
  565. package/dist/utils/action-inference.js.map +1 -0
  566. package/dist/utils/app-inference.d.ts +31 -0
  567. package/dist/utils/app-inference.d.ts.map +1 -0
  568. package/dist/utils/app-inference.js +41 -0
  569. package/dist/utils/app-inference.js.map +1 -0
  570. package/dist/utils/auto-infer.d.ts +93 -0
  571. package/dist/utils/auto-infer.d.ts.map +1 -0
  572. package/dist/utils/auto-infer.js +184 -0
  573. package/dist/utils/auto-infer.js.map +1 -0
  574. package/dist/utils/config.d.ts +709 -0
  575. package/dist/utils/config.d.ts.map +1 -0
  576. package/dist/utils/config.js +504 -0
  577. package/dist/utils/config.js.map +1 -0
  578. package/dist/utils/file.d.ts +46 -0
  579. package/dist/utils/file.d.ts.map +1 -0
  580. package/dist/utils/file.js +103 -0
  581. package/dist/utils/file.js.map +1 -0
  582. package/dist/utils/formatters.d.ts +123 -0
  583. package/dist/utils/formatters.d.ts.map +1 -0
  584. package/dist/utils/formatters.js +199 -0
  585. package/dist/utils/formatters.js.map +1 -0
  586. package/dist/utils/gh-config.d.ts +99 -0
  587. package/dist/utils/gh-config.d.ts.map +1 -0
  588. package/dist/utils/gh-config.js +247 -0
  589. package/dist/utils/gh-config.js.map +1 -0
  590. package/dist/utils/github.d.ts +108 -0
  591. package/dist/utils/github.d.ts.map +1 -0
  592. package/dist/utils/github.js +320 -0
  593. package/dist/utils/github.js.map +1 -0
  594. package/dist/utils/html.d.ts +107 -0
  595. package/dist/utils/html.d.ts.map +1 -0
  596. package/dist/utils/html.js +376 -0
  597. package/dist/utils/html.js.map +1 -0
  598. package/dist/utils/i18n.d.ts +40 -0
  599. package/dist/utils/i18n.d.ts.map +1 -0
  600. package/dist/utils/i18n.js +148 -0
  601. package/dist/utils/i18n.js.map +1 -0
  602. package/dist/utils/logger.d.ts +20 -0
  603. package/dist/utils/logger.d.ts.map +1 -0
  604. package/dist/utils/logger.js +49 -0
  605. package/dist/utils/logger.js.map +1 -0
  606. package/dist/utils/project-fields.d.ts +71 -0
  607. package/dist/utils/project-fields.d.ts.map +1 -0
  608. package/dist/utils/project-fields.js +318 -0
  609. package/dist/utils/project-fields.js.map +1 -0
  610. package/dist/utils/repo-pairs.d.ts +94 -0
  611. package/dist/utils/repo-pairs.d.ts.map +1 -0
  612. package/dist/utils/repo-pairs.js +196 -0
  613. package/dist/utils/repo-pairs.js.map +1 -0
  614. package/dist/utils/route-inference.d.ts +81 -0
  615. package/dist/utils/route-inference.d.ts.map +1 -0
  616. package/dist/utils/route-inference.js +137 -0
  617. package/dist/utils/route-inference.js.map +1 -0
  618. package/dist/utils/sanitize.d.ts +27 -0
  619. package/dist/utils/sanitize.d.ts.map +1 -0
  620. package/dist/utils/sanitize.js +38 -0
  621. package/dist/utils/sanitize.js.map +1 -0
  622. package/dist/utils/setup-check.d.ts +48 -0
  623. package/dist/utils/setup-check.d.ts.map +1 -0
  624. package/dist/utils/setup-check.js +226 -0
  625. package/dist/utils/setup-check.js.map +1 -0
  626. package/dist/utils/shirokumaignore.d.ts +55 -0
  627. package/dist/utils/shirokumaignore.d.ts.map +1 -0
  628. package/dist/utils/shirokumaignore.js +94 -0
  629. package/dist/utils/shirokumaignore.js.map +1 -0
  630. package/dist/utils/skills-repo.d.ts +353 -0
  631. package/dist/utils/skills-repo.d.ts.map +1 -0
  632. package/dist/utils/skills-repo.js +793 -0
  633. package/dist/utils/skills-repo.js.map +1 -0
  634. package/dist/utils/status-workflow.d.ts +54 -0
  635. package/dist/utils/status-workflow.d.ts.map +1 -0
  636. package/dist/utils/status-workflow.js +103 -0
  637. package/dist/utils/status-workflow.js.map +1 -0
  638. package/dist/validators/frontmatter.d.ts +41 -0
  639. package/dist/validators/frontmatter.d.ts.map +1 -0
  640. package/dist/validators/frontmatter.js +117 -0
  641. package/dist/validators/frontmatter.js.map +1 -0
  642. package/dist/validators/link-checker.d.ts +48 -0
  643. package/dist/validators/link-checker.d.ts.map +1 -0
  644. package/dist/validators/link-checker.js +108 -0
  645. package/dist/validators/link-checker.js.map +1 -0
  646. package/dist/validators/markdown-structure.d.ts +50 -0
  647. package/dist/validators/markdown-structure.d.ts.map +1 -0
  648. package/dist/validators/markdown-structure.js +253 -0
  649. package/dist/validators/markdown-structure.js.map +1 -0
  650. package/i18n/cli/en.json +164 -0
  651. package/i18n/cli/ja.json +164 -0
  652. package/i18n/discussion/en.json +191 -0
  653. package/i18n/discussion/ja.json +191 -0
  654. package/package.json +113 -0
  655. package/portal/app/api-tools/api-tools-client.tsx +411 -0
  656. package/portal/app/api-tools/api-tools-document.tsx +240 -0
  657. package/portal/app/api-tools/page.tsx +56 -0
  658. package/portal/app/api-tools/swagger-view.tsx +114 -0
  659. package/portal/app/apps/[appId]/[type]/[module]/[item]/item-tabs-client.tsx +71 -0
  660. package/portal/app/apps/[appId]/[type]/[module]/[item]/page.tsx +1422 -0
  661. package/portal/app/apps/[appId]/[type]/[module]/page.tsx +373 -0
  662. package/portal/app/apps/[appId]/feature-map/feature-map-app-document.tsx +298 -0
  663. package/portal/app/apps/[appId]/feature-map/page.tsx +224 -0
  664. package/portal/app/apps/[appId]/i18n/page.tsx +139 -0
  665. package/portal/app/apps/[appId]/test-cases/page.tsx +840 -0
  666. package/portal/app/apps/[appId]/tools/[tool]/page.tsx +351 -0
  667. package/portal/app/apps/[appId]/tools/api-tools-client.tsx +429 -0
  668. package/portal/app/apps/[appId]/tools/page.tsx +119 -0
  669. package/portal/app/db-schema/[db]/[table]/page.tsx +235 -0
  670. package/portal/app/db-schema/[db]/diagram/page.tsx +81 -0
  671. package/portal/app/db-schema/[db]/page.tsx +148 -0
  672. package/portal/app/db-schema/db-schema-document.tsx +100 -0
  673. package/portal/app/db-schema/diagram/client.tsx +211 -0
  674. package/portal/app/db-schema/diagram/page.tsx +20 -0
  675. package/portal/app/db-schema/page.tsx +145 -0
  676. package/portal/app/db-schema/table-detail-document.tsx +710 -0
  677. package/portal/app/db-schema/table-detail.tsx +747 -0
  678. package/portal/app/db-schema/table-list-document.tsx +224 -0
  679. package/portal/app/db-schema/table-list.tsx +247 -0
  680. package/portal/app/details/[type]/[module]/[item]/item-tabs-client.tsx +71 -0
  681. package/portal/app/details/[type]/[module]/[item]/page.tsx +1286 -0
  682. package/portal/app/details/[type]/[module]/page.tsx +884 -0
  683. package/portal/app/feature-map/feature-map-client.tsx +681 -0
  684. package/portal/app/feature-map/feature-map-document.tsx +313 -0
  685. package/portal/app/feature-map/page.tsx +438 -0
  686. package/portal/app/globals.css +205 -0
  687. package/portal/app/i18n/[...namespace]/page.tsx +190 -0
  688. package/portal/app/i18n/i18n-client.tsx +369 -0
  689. package/portal/app/i18n/page.tsx +339 -0
  690. package/portal/app/layout.tsx +37 -0
  691. package/portal/app/overview/page.tsx +65 -0
  692. package/portal/app/packages/[packageId]/page.tsx +201 -0
  693. package/portal/app/packages/page.tsx +148 -0
  694. package/portal/app/page.tsx +568 -0
  695. package/portal/app/test-cases/[file]/[line]/page.tsx +455 -0
  696. package/portal/app/test-cases/[file]/[line]/test-detail-document.tsx +335 -0
  697. package/portal/app/test-cases/[file]/page.tsx +323 -0
  698. package/portal/app/test-cases/[file]/test-file-document.tsx +335 -0
  699. package/portal/app/test-cases/page.tsx +546 -0
  700. package/portal/app/test-cases/test-cases-document.tsx +384 -0
  701. package/portal/components/code-block.tsx +57 -0
  702. package/portal/components/document/doc-params-table.tsx +71 -0
  703. package/portal/components/document/doc-section.tsx +133 -0
  704. package/portal/components/document/doc-table.tsx +119 -0
  705. package/portal/components/document/index.ts +9 -0
  706. package/portal/components/drawflow-er-diagram.tsx +607 -0
  707. package/portal/components/interactive-er-diagram.tsx +228 -0
  708. package/portal/components/layout/app-sidebar.tsx +490 -0
  709. package/portal/components/layout/er-sidebar.tsx +116 -0
  710. package/portal/components/layout/global-header.tsx +117 -0
  711. package/portal/components/layout/layout-content.tsx +48 -0
  712. package/portal/components/markdown-content.tsx +120 -0
  713. package/portal/components/mermaid-diagram.tsx +83 -0
  714. package/portal/components/reactflow-er-diagram.tsx +475 -0
  715. package/portal/components/search-dialog.tsx +268 -0
  716. package/portal/components/shared/coverage-score-bar.tsx +144 -0
  717. package/portal/components/swagger/endpoint-accordion.tsx +117 -0
  718. package/portal/components/swagger/index.ts +7 -0
  719. package/portal/components/swagger/method-badge.tsx +55 -0
  720. package/portal/components/swagger/params-table.tsx +78 -0
  721. package/portal/components/tabs-with-hash.tsx +43 -0
  722. package/portal/components/test/index.ts +2 -0
  723. package/portal/components/test/test-bdd-card.tsx +192 -0
  724. package/portal/components/test/test-matrix.tsx +242 -0
  725. package/portal/components/ui/accordion.tsx +66 -0
  726. package/portal/components/ui/badge.tsx +46 -0
  727. package/portal/components/ui/breadcrumb.tsx +109 -0
  728. package/portal/components/ui/button.tsx +62 -0
  729. package/portal/components/ui/card.tsx +92 -0
  730. package/portal/components/ui/collapsible.tsx +33 -0
  731. package/portal/components/ui/dialog.tsx +118 -0
  732. package/portal/components/ui/progress.tsx +28 -0
  733. package/portal/components/ui/scroll-area.tsx +58 -0
  734. package/portal/components/ui/sheet.tsx +139 -0
  735. package/portal/components/ui/table.tsx +116 -0
  736. package/portal/components/ui/tabs.tsx +66 -0
  737. package/portal/components.json +21 -0
  738. package/portal/lib/constants/test-categories.ts +186 -0
  739. package/portal/lib/data-loader.ts +1181 -0
  740. package/portal/lib/db-schema-utils.ts +182 -0
  741. package/portal/lib/format.ts +43 -0
  742. package/portal/lib/hooks/use-hash-tab.ts +144 -0
  743. package/portal/lib/path-utils.ts +25 -0
  744. package/portal/lib/search-index-generator.ts +214 -0
  745. package/portal/lib/search.ts +126 -0
  746. package/portal/lib/sidebar-context.tsx +111 -0
  747. package/portal/lib/types.ts +740 -0
  748. package/portal/lib/utils.ts +6 -0
  749. package/portal/next.config.ts +18 -0
  750. package/portal/package.json +45 -0
  751. package/portal/postcss.config.mjs +8 -0
  752. package/portal/tsconfig.json +42 -0
  753. package/portal/types/drawflow.d.ts +80 -0
  754. package/templates/README.md +73 -0
  755. package/templates/coverage.html +367 -0
  756. package/templates/dark-theme.css +443 -0
  757. package/templates/discussion/adr.yml.hbs +65 -0
  758. package/templates/discussion/handovers.yml.hbs +57 -0
  759. package/templates/discussion/knowledge.yml.hbs +60 -0
  760. package/templates/discussion/reports.yml.hbs +68 -0
  761. package/templates/discussion/research.yml.hbs +61 -0
@@ -0,0 +1,840 @@
1
+ import Link from "next/link";
2
+ import { notFound } from "next/navigation";
3
+ import {
4
+ FlaskConical,
5
+ AlertTriangle,
6
+ CheckCircle2,
7
+ XCircle,
8
+ TrendingUp,
9
+ BarChart3,
10
+ Monitor,
11
+ Zap,
12
+ Component,
13
+ Database,
14
+ FileCode2,
15
+ ChevronRight,
16
+ ArrowLeft,
17
+ } from "lucide-react";
18
+ import {
19
+ loadTestCases,
20
+ loadApplications,
21
+ loadFeatureMap,
22
+ loadDetails,
23
+ loadCoverage,
24
+ type CoverageData,
25
+ } from "@/lib/data-loader";
26
+ import { encodeFilePath } from "@/lib/path-utils";
27
+ import {
28
+ Card,
29
+ CardHeader,
30
+ CardTitle,
31
+ CardDescription,
32
+ CardContent,
33
+ } from "@/components/ui/card";
34
+ import { Badge } from "@/components/ui/badge";
35
+ import { Progress } from "@/components/ui/progress";
36
+ import {
37
+ TabsWithHash,
38
+ TabsContent,
39
+ TabsList,
40
+ TabsTrigger,
41
+ } from "@/components/tabs-with-hash";
42
+ import type { TestCase, FeatureMapData, DetailsData } from "@/lib/types";
43
+
44
+ export const dynamic = "force-static";
45
+
46
+ interface PageProps {
47
+ params: Promise<{ appId: string }>;
48
+ }
49
+
50
+ /**
51
+ * Generate static params for all available apps
52
+ */
53
+ export async function generateStaticParams() {
54
+ const applications = await loadApplications();
55
+ if (!applications?.apps) return [];
56
+
57
+ return applications.apps.map((app) => ({
58
+ appId: app.id,
59
+ }));
60
+ }
61
+
62
+ /**
63
+ * Get the source path prefixes for an app
64
+ */
65
+ function getAppSourcePrefixes(appId: string, source?: string): string[] {
66
+ const defaults: Record<string, string[]> = {
67
+ admin: ["apps/admin", "tests/e2e/admin"],
68
+ public: ["apps/public", "tests/e2e/public"],
69
+ web: ["apps/web", "tests/e2e/web"],
70
+ mcp: ["apps/mcp", "tests/e2e/mcp"],
71
+ };
72
+
73
+ if (source) {
74
+ return [source, `tests/e2e/${appId}`];
75
+ }
76
+
77
+ return defaults[appId] || [`apps/${appId}`, `tests/e2e/${appId}`];
78
+ }
79
+
80
+ /**
81
+ * Filter test cases by app
82
+ */
83
+ function filterTestCasesByApp(testCases: TestCase[], appId: string, sourcePrefixes: string[]): TestCase[] {
84
+ return testCases.filter((tc) => {
85
+ for (const prefix of sourcePrefixes) {
86
+ if (tc.file.startsWith(prefix)) {
87
+ return true;
88
+ }
89
+ }
90
+ if (tc.app === appId) {
91
+ return true;
92
+ }
93
+ return false;
94
+ });
95
+ }
96
+
97
+ /**
98
+ * Strip matching prefix from file path for display
99
+ */
100
+ function stripMatchingPrefix(file: string, prefixes: string[]): string {
101
+ for (const prefix of prefixes) {
102
+ if (file.startsWith(prefix + "/")) {
103
+ return file.replace(prefix + "/", "");
104
+ }
105
+ if (file.startsWith(prefix)) {
106
+ return file.replace(prefix, "");
107
+ }
108
+ }
109
+ return file;
110
+ }
111
+
112
+ /**
113
+ * Group test cases by file
114
+ */
115
+ function groupTestCasesByFile(testCases: TestCase[]): Record<string, TestCase[]> {
116
+ const grouped: Record<string, TestCase[]> = {};
117
+ for (const tc of testCases) {
118
+ if (!grouped[tc.file]) grouped[tc.file] = [];
119
+ grouped[tc.file].push(tc);
120
+ }
121
+ return grouped;
122
+ }
123
+
124
+ /**
125
+ * Get category breakdown
126
+ */
127
+ function getCategoryBreakdown(testCases: TestCase[]): Record<string, number> {
128
+ const breakdown: Record<string, number> = {};
129
+ for (const tc of testCases) {
130
+ const cat = tc.category || "unknown";
131
+ breakdown[cat] = (breakdown[cat] || 0) + 1;
132
+ }
133
+ return breakdown;
134
+ }
135
+
136
+ // Test category labels
137
+ const testCategoryLabels: Record<string, { ja: string; color: string }> = {
138
+ "happy-path": { ja: "正常系", color: "bg-green-500" },
139
+ auth: { ja: "認証", color: "bg-blue-500" },
140
+ "error-handling": { ja: "異常系", color: "bg-red-500" },
141
+ validation: { ja: "バリデーション", color: "bg-yellow-500" },
142
+ "edge-case": { ja: "境界値", color: "bg-purple-500" },
143
+ integration: { ja: "統合", color: "bg-cyan-500" },
144
+ other: { ja: "その他", color: "bg-gray-500" },
145
+ success: { ja: "正常系", color: "bg-green-500" },
146
+ error: { ja: "異常系", color: "bg-red-500" },
147
+ edge: { ja: "境界値", color: "bg-purple-500" },
148
+ unknown: { ja: "その他", color: "bg-gray-500" },
149
+ };
150
+
151
+ // Item type config
152
+ const itemTypeConfig: Record<string, { icon: React.ElementType; label: string; labelJa: string }> = {
153
+ screens: { icon: Monitor, label: "Screens", labelJa: "画面" },
154
+ components: { icon: Component, label: "Components", labelJa: "コンポーネント" },
155
+ actions: { icon: Zap, label: "Actions", labelJa: "アクション" },
156
+ tables: { icon: Database, label: "Tables", labelJa: "テーブル" },
157
+ };
158
+
159
+ /**
160
+ * Filter feature map items by app
161
+ */
162
+ function filterFeatureMapByApp(featureMap: FeatureMapData | null, appId: string): FeatureMapData | null {
163
+ if (!featureMap) return null;
164
+
165
+ // Map appId to app names in feature map
166
+ // Note: appId "mcp" maps to items with app="API" or app="MCP" (for backward compatibility)
167
+ const appNameMap: Record<string, string[]> = {
168
+ admin: ["Admin"],
169
+ public: ["Public"],
170
+ web: ["Web"],
171
+ mcp: ["API", "MCP"], // Support both new "API" and legacy "MCP"
172
+ };
173
+
174
+ const appNames = appNameMap[appId] || [appId];
175
+ const filteredFeatures: FeatureMapData["features"] = {};
176
+
177
+ for (const [moduleName, group] of Object.entries(featureMap.features)) {
178
+ // Check if any item in the group belongs to this app
179
+ const allItems = [
180
+ ...(group.screens || []),
181
+ ...(group.components || []),
182
+ ...(group.actions || []),
183
+ ];
184
+
185
+ // Get app from first item that has it
186
+ const firstItemWithApp = allItems.find(item => item.app);
187
+ const moduleApp = firstItemWithApp?.app || "";
188
+
189
+ if (appNames.some(name => moduleApp.toLowerCase().includes(name.toLowerCase()))) {
190
+ filteredFeatures[moduleName] = group;
191
+ }
192
+ }
193
+
194
+ return {
195
+ ...featureMap,
196
+ features: filteredFeatures,
197
+ };
198
+ }
199
+
200
+ /**
201
+ * Calculate coverage by mapping coverage.json to feature-map items
202
+ * Feature-map items are considered "covered" if their source path is covered in coverage.json
203
+ */
204
+ function calculateFeatureMapCoverage(
205
+ coverage: CoverageData | null,
206
+ featureMap: FeatureMapData | null,
207
+ appId: string
208
+ ): { totalItems: number; testedItems: number; coveragePercent: number; missingCount: number } | null {
209
+ const filteredMap = filterFeatureMapByApp(featureMap, appId);
210
+ if (!coverage || !filteredMap) return null;
211
+
212
+ // Build a set of covered source paths
213
+ const coveredSources = new Set<string>();
214
+ for (const result of coverage.results) {
215
+ if (result.status === "covered" || result.status === "skipped") {
216
+ coveredSources.add(result.source);
217
+ }
218
+ }
219
+
220
+ let totalItems = 0;
221
+ let testedItems = 0;
222
+
223
+ // Check each feature-map item against covered sources
224
+ for (const group of Object.values(filteredMap.features)) {
225
+ const items = [
226
+ ...(group.screens || []),
227
+ ...(group.components || []),
228
+ ...(group.actions || []),
229
+ ];
230
+
231
+ for (const item of items) {
232
+ totalItems++;
233
+ // Check if item's path matches any covered source
234
+ if ("path" in item && item.path) {
235
+ if (coveredSources.has(item.path)) {
236
+ testedItems++;
237
+ }
238
+ }
239
+ }
240
+ }
241
+
242
+ if (totalItems === 0) return null;
243
+
244
+ const missingCount = totalItems - testedItems;
245
+ const coveragePercent = Math.round((testedItems / totalItems) * 100);
246
+
247
+ return { totalItems, testedItems, coveragePercent, missingCount };
248
+ }
249
+
250
+ /**
251
+ * Get coverage gaps for an app
252
+ */
253
+ function getCoverageGaps(
254
+ featureMap: FeatureMapData | null,
255
+ details: DetailsData | null,
256
+ appId: string
257
+ ): Array<{ type: string; module: string; name: string; path?: string }> {
258
+ const filteredMap = filterFeatureMapByApp(featureMap, appId);
259
+ if (!filteredMap || !details) return [];
260
+
261
+ const gaps: Array<{ type: string; module: string; name: string; path?: string }> = [];
262
+
263
+ for (const [moduleName, group] of Object.entries(filteredMap.features)) {
264
+ const itemTypes = [
265
+ { type: "screens", items: group.screens || [] },
266
+ { type: "components", items: group.components || [] },
267
+ { type: "actions", items: group.actions || [] },
268
+ { type: "tables", items: group.tables || [] },
269
+ ];
270
+
271
+ for (const { type, items } of itemTypes) {
272
+ for (const item of items) {
273
+ const possibleKeys = [`${type}/${moduleName}/${item.name}`];
274
+
275
+ if ("path" in item && item.path) {
276
+ const fileName = item.path.split("/").pop()?.replace(/\.(ts|tsx)$/, "");
277
+ if (fileName) {
278
+ possibleKeys.unshift(`${type}/${fileName}/${item.name}`);
279
+ }
280
+ }
281
+
282
+ let hasTest = false;
283
+ for (const key of possibleKeys) {
284
+ const detail = details.details[key];
285
+ if (detail?.testCoverage?.hasTest) {
286
+ hasTest = true;
287
+ break;
288
+ }
289
+ }
290
+
291
+ if (!hasTest) {
292
+ gaps.push({
293
+ type,
294
+ module: moduleName,
295
+ name: item.name,
296
+ path: "path" in item ? item.path : undefined,
297
+ });
298
+ }
299
+ }
300
+ }
301
+ }
302
+
303
+ return gaps;
304
+ }
305
+
306
+ /**
307
+ * Get coverage distribution for an app
308
+ */
309
+ function getCoverageDistribution(
310
+ details: DetailsData | null,
311
+ featureMap: FeatureMapData | null,
312
+ appId: string
313
+ ): { high: number; medium: number; low: number; none: number } {
314
+ const filteredMap = filterFeatureMapByApp(featureMap, appId);
315
+ if (!details || !filteredMap) return { high: 0, medium: 0, low: 0, none: 0 };
316
+
317
+ let high = 0, medium = 0, low = 0, none = 0;
318
+
319
+ // Get item names from filtered feature map
320
+ const itemNames = new Set<string>();
321
+ for (const group of Object.values(filteredMap.features)) {
322
+ for (const item of [...(group.screens || []), ...(group.components || []), ...(group.actions || [])]) {
323
+ itemNames.add(item.name);
324
+ }
325
+ }
326
+
327
+ for (const [key, item] of Object.entries(details.details)) {
328
+ // Check if this item belongs to the app
329
+ const itemName = key.split("/").pop() || "";
330
+ if (!itemNames.has(itemName)) continue;
331
+
332
+ if (!item.testCoverage?.hasTest) {
333
+ none++;
334
+ } else {
335
+ const score = item.testCoverage.coverageScore;
336
+ if (score >= 70) high++;
337
+ else if (score >= 40) medium++;
338
+ else low++;
339
+ }
340
+ }
341
+
342
+ return { high, medium, low, none };
343
+ }
344
+
345
+ /**
346
+ * Get overall stats for an app
347
+ */
348
+ function getOverallStats(
349
+ featureMap: FeatureMapData | null,
350
+ details: DetailsData | null,
351
+ appId: string
352
+ ): { totalItems: number; testedItems: number; coveragePercent: number } {
353
+ const filteredMap = filterFeatureMapByApp(featureMap, appId);
354
+ if (!filteredMap || !details) return { totalItems: 0, testedItems: 0, coveragePercent: 0 };
355
+
356
+ let totalItems = 0;
357
+ let testedItems = 0;
358
+
359
+ for (const group of Object.values(filteredMap.features)) {
360
+ const items = [
361
+ ...(group.screens || []),
362
+ ...(group.components || []),
363
+ ...(group.actions || []),
364
+ ...(group.tables || []),
365
+ ];
366
+ totalItems += items.length;
367
+ }
368
+
369
+ // Count tested items from details
370
+ const itemNames = new Set<string>();
371
+ for (const group of Object.values(filteredMap.features)) {
372
+ for (const item of [...(group.screens || []), ...(group.components || []), ...(group.actions || []), ...(group.tables || [])]) {
373
+ itemNames.add(item.name);
374
+ }
375
+ }
376
+
377
+ for (const [key, item] of Object.entries(details.details)) {
378
+ const itemName = key.split("/").pop() || "";
379
+ if (itemNames.has(itemName) && item.testCoverage?.hasTest) {
380
+ testedItems++;
381
+ }
382
+ }
383
+
384
+ return {
385
+ totalItems,
386
+ testedItems,
387
+ coveragePercent: totalItems > 0 ? Math.round((testedItems / totalItems) * 100) : 0,
388
+ };
389
+ }
390
+
391
+ /**
392
+ * Analyze test quality balance
393
+ */
394
+ function analyzeTestQuality(categoryBreakdown: Record<string, number>, totalTests: number): {
395
+ status: "good" | "warning" | "poor";
396
+ message: string;
397
+ details: string[];
398
+ } {
399
+ if (totalTests === 0) return { status: "poor", message: "テストがありません", details: [] };
400
+
401
+ const details: string[] = [];
402
+ const successRatio = (categoryBreakdown["happy-path"] || 0) / totalTests;
403
+ const errorRatio = (categoryBreakdown["error-handling"] || 0) / totalTests;
404
+ const validationRatio = (categoryBreakdown.validation || 0) / totalTests;
405
+
406
+ if (successRatio > 0.7) {
407
+ details.push("正常系テストが多すぎます(異常系・バリデーションも追加推奨)");
408
+ }
409
+ if (errorRatio < 0.1 && totalTests > 10) {
410
+ details.push("異常系テストが少ないです");
411
+ }
412
+ if (validationRatio < 0.05 && totalTests > 10) {
413
+ details.push("バリデーションテストが少ないです");
414
+ }
415
+ if ((categoryBreakdown["edge-case"] || 0) === 0 && totalTests > 20) {
416
+ details.push("境界値テストがありません");
417
+ }
418
+
419
+ if (details.length === 0) {
420
+ return { status: "good", message: "テストカテゴリのバランスが良好です", details: [] };
421
+ } else if (details.length <= 2) {
422
+ return { status: "warning", message: "改善の余地があります", details };
423
+ } else {
424
+ return { status: "poor", message: "テストバランスの改善が必要です", details };
425
+ }
426
+ }
427
+
428
+ export default async function AppTestCasesPage({ params }: PageProps) {
429
+ const { appId } = await params;
430
+
431
+ const [data, applications, featureMap, details, coverage] = await Promise.all([
432
+ loadTestCases(),
433
+ loadApplications(),
434
+ loadFeatureMap(),
435
+ loadDetails(),
436
+ loadCoverage(),
437
+ ]);
438
+
439
+ // Find the app configuration
440
+ const app = applications?.apps?.find((a) => a.id === appId);
441
+ if (!app) {
442
+ notFound();
443
+ }
444
+
445
+ if (!data) {
446
+ return (
447
+ <div className="space-y-8">
448
+ <header>
449
+ <h1 className="text-3xl font-bold tracking-tight">Test Cases - {app.name}</h1>
450
+ <p className="mt-2 text-destructive">No test cases data available.</p>
451
+ </header>
452
+ </div>
453
+ );
454
+ }
455
+
456
+ // Filter test cases by app
457
+ const sourcePrefixes = getAppSourcePrefixes(appId, app.source);
458
+ const filteredTestCases = filterTestCasesByApp(data.testCases, appId, sourcePrefixes);
459
+ const groupedByFile = groupTestCasesByFile(filteredTestCases);
460
+ const categoryBreakdown = getCategoryBreakdown(filteredTestCases);
461
+
462
+ // Count files
463
+ const fileCount = Object.keys(groupedByFile).length;
464
+
465
+ // Count by framework
466
+ const jestCount = filteredTestCases.filter((tc) => tc.framework === "jest").length;
467
+ const playwrightCount = filteredTestCases.filter((tc) => tc.framework === "playwright").length;
468
+
469
+ // Coverage analysis - map coverage.json to feature-map items
470
+ const coverageGaps = getCoverageGaps(featureMap, details, appId);
471
+ const coverageDistribution = getCoverageDistribution(details, featureMap, appId);
472
+ const appCoverage = calculateFeatureMapCoverage(coverage, featureMap, appId);
473
+ const overallStats = appCoverage || getOverallStats(featureMap, details, appId);
474
+ const qualityAnalysis = analyzeTestQuality(categoryBreakdown, filteredTestCases.length);
475
+
476
+ // Group gaps by type
477
+ const gapsByType = coverageGaps.reduce((acc, gap) => {
478
+ if (!acc[gap.type]) acc[gap.type] = [];
479
+ acc[gap.type].push(gap);
480
+ return acc;
481
+ }, {} as Record<string, typeof coverageGaps>);
482
+
483
+ // Get app color
484
+ const colorClass = app.color === "blue" ? "text-blue-500 bg-blue-500/10" :
485
+ app.color === "green" ? "text-green-500 bg-green-500/10" :
486
+ app.color === "purple" ? "text-purple-500 bg-purple-500/10" :
487
+ "text-gray-500 bg-gray-500/10";
488
+
489
+ return (
490
+ <div className="space-y-8">
491
+ {/* Breadcrumb */}
492
+ <nav className="flex items-center gap-2 text-sm text-muted-foreground">
493
+ <Link href="/" className="hover:text-foreground">
494
+ Home
495
+ </Link>
496
+ <span>/</span>
497
+ <Link href="/test-cases" className="hover:text-foreground">
498
+ Test Cases
499
+ </Link>
500
+ <span>/</span>
501
+ <span className="text-foreground">{app.name}</span>
502
+ </nav>
503
+
504
+ {/* Header */}
505
+ <header>
506
+ <div className="flex items-center justify-between">
507
+ <div className="flex items-center gap-3">
508
+ <div className={`rounded-lg p-2 ${colorClass}`}>
509
+ <FlaskConical className="h-6 w-6" />
510
+ </div>
511
+ <div>
512
+ <h1 className="text-3xl font-bold tracking-tight">Test Quality Dashboard - {app.name}</h1>
513
+ <p className="mt-1 text-muted-foreground">
514
+ {app.description || `${app.name} のテストカバレッジと品質メトリクス`}
515
+ </p>
516
+ </div>
517
+ </div>
518
+ <Link
519
+ href="/test-cases"
520
+ className="flex items-center gap-2 rounded-lg border border-border bg-card px-4 py-2 text-sm font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground"
521
+ >
522
+ <ArrowLeft className="h-4 w-4" />
523
+ 全体ビュー
524
+ </Link>
525
+ </div>
526
+ </header>
527
+
528
+ {/* Tabbed Content */}
529
+ <TabsWithHash defaultValue="overview" className="w-full">
530
+ <TabsList className="grid w-full grid-cols-3">
531
+ <TabsTrigger value="overview" className="flex items-center gap-2">
532
+ <BarChart3 className="h-4 w-4" />
533
+ 概要
534
+ </TabsTrigger>
535
+ <TabsTrigger value="files" className="flex items-center gap-2">
536
+ <FileCode2 className="h-4 w-4" />
537
+ テストファイル
538
+ <Badge variant="secondary" className="text-xs">
539
+ {fileCount}
540
+ </Badge>
541
+ </TabsTrigger>
542
+ <TabsTrigger value="gaps" className="flex items-center gap-2">
543
+ <AlertTriangle className="h-4 w-4" />
544
+ ギャップ
545
+ <Badge variant="secondary" className="text-xs bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400">
546
+ {coverageGaps.length}
547
+ </Badge>
548
+ </TabsTrigger>
549
+ </TabsList>
550
+
551
+ {/* Overview Tab */}
552
+ <TabsContent value="overview" className="mt-4 space-y-6">
553
+ {/* Stats Cards */}
554
+ <div className="grid gap-4 md:grid-cols-4">
555
+ <Card>
556
+ <CardHeader className="pb-2">
557
+ <CardDescription>総テスト数</CardDescription>
558
+ <CardTitle className="text-3xl">{filteredTestCases.length}</CardTitle>
559
+ </CardHeader>
560
+ <CardContent>
561
+ <div className="flex flex-col gap-1 text-xs text-muted-foreground">
562
+ <div className="flex gap-2">
563
+ <span>Jest: {jestCount}</span>
564
+ <span>|</span>
565
+ <span>Playwright: {playwrightCount}</span>
566
+ </div>
567
+ </div>
568
+ </CardContent>
569
+ </Card>
570
+
571
+ <Card>
572
+ <CardHeader className="pb-2">
573
+ <CardDescription>カバレッジ率</CardDescription>
574
+ <CardTitle className="text-3xl">{overallStats.coveragePercent}%</CardTitle>
575
+ </CardHeader>
576
+ <CardContent>
577
+ <Progress value={overallStats.coveragePercent} className="h-2" />
578
+ <p className="mt-1 text-xs text-muted-foreground">
579
+ {overallStats.testedItems} / {overallStats.totalItems} items
580
+ </p>
581
+ </CardContent>
582
+ </Card>
583
+
584
+ <Card>
585
+ <CardHeader className="pb-2">
586
+ <CardDescription>テスト無し</CardDescription>
587
+ <CardTitle className="text-3xl text-red-500">{coverageGaps.length}</CardTitle>
588
+ </CardHeader>
589
+ <CardContent>
590
+ <p className="text-xs text-muted-foreground">
591
+ カバレッジギャップ
592
+ </p>
593
+ </CardContent>
594
+ </Card>
595
+
596
+ <Card className={qualityAnalysis.status === "good" ? "border-green-500/50" : qualityAnalysis.status === "warning" ? "border-yellow-500/50" : "border-red-500/50"}>
597
+ <CardHeader className="pb-2">
598
+ <CardDescription>品質スコア</CardDescription>
599
+ <CardTitle className="flex items-center gap-2">
600
+ {qualityAnalysis.status === "good" ? (
601
+ <CheckCircle2 className="h-6 w-6 text-green-500" />
602
+ ) : qualityAnalysis.status === "warning" ? (
603
+ <AlertTriangle className="h-6 w-6 text-yellow-500" />
604
+ ) : (
605
+ <XCircle className="h-6 w-6 text-red-500" />
606
+ )}
607
+ <span className="text-lg">{qualityAnalysis.message}</span>
608
+ </CardTitle>
609
+ </CardHeader>
610
+ {qualityAnalysis.details.length > 0 && (
611
+ <CardContent>
612
+ <ul className="text-xs text-muted-foreground space-y-1">
613
+ {qualityAnalysis.details.map((d, i) => (
614
+ <li key={i}>• {d}</li>
615
+ ))}
616
+ </ul>
617
+ </CardContent>
618
+ )}
619
+ </Card>
620
+ </div>
621
+
622
+ {/* Two Column Layout */}
623
+ <div className="grid gap-6 lg:grid-cols-2">
624
+ {/* Test Category Distribution */}
625
+ <Card>
626
+ <CardHeader>
627
+ <div className="flex items-center gap-2">
628
+ <BarChart3 className="h-5 w-5 text-muted-foreground" />
629
+ <CardTitle>テストカテゴリ分布</CardTitle>
630
+ </div>
631
+ <CardDescription>
632
+ テストの種類別内訳
633
+ </CardDescription>
634
+ </CardHeader>
635
+ <CardContent className="space-y-4">
636
+ {Object.entries(categoryBreakdown)
637
+ .filter(([_, count]) => count > 0)
638
+ .sort((a, b) => b[1] - a[1])
639
+ .map(([category, count]) => {
640
+ const config = testCategoryLabels[category] || testCategoryLabels.unknown;
641
+ const percentage = Math.round((count / filteredTestCases.length) * 100);
642
+ return (
643
+ <div key={category} className="space-y-1">
644
+ <div className="flex items-center justify-between text-sm">
645
+ <div className="flex items-center gap-2">
646
+ <div className={`h-3 w-3 rounded-full ${config.color}`} />
647
+ <span>{config.ja}</span>
648
+ </div>
649
+ <span className="text-muted-foreground">{count} ({percentage}%)</span>
650
+ </div>
651
+ <Progress value={percentage} className="h-2" />
652
+ </div>
653
+ );
654
+ })}
655
+ </CardContent>
656
+ </Card>
657
+
658
+ {/* Coverage Score Distribution */}
659
+ <Card>
660
+ <CardHeader>
661
+ <div className="flex items-center gap-2">
662
+ <TrendingUp className="h-5 w-5 text-muted-foreground" />
663
+ <CardTitle>カバレッジスコア分布</CardTitle>
664
+ </div>
665
+ <CardDescription>
666
+ 機能別テストカバレッジの品質
667
+ </CardDescription>
668
+ </CardHeader>
669
+ <CardContent className="space-y-4">
670
+ <div className="space-y-3">
671
+ <div className="flex items-center justify-between">
672
+ <div className="flex items-center gap-2">
673
+ <div className="h-3 w-3 rounded-full bg-green-500" />
674
+ <span className="text-sm">高 (70%+)</span>
675
+ </div>
676
+ <Badge variant="secondary" className="bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400">
677
+ {coverageDistribution.high}
678
+ </Badge>
679
+ </div>
680
+ <div className="flex items-center justify-between">
681
+ <div className="flex items-center gap-2">
682
+ <div className="h-3 w-3 rounded-full bg-yellow-500" />
683
+ <span className="text-sm">中 (40-69%)</span>
684
+ </div>
685
+ <Badge variant="secondary" className="bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400">
686
+ {coverageDistribution.medium}
687
+ </Badge>
688
+ </div>
689
+ <div className="flex items-center justify-between">
690
+ <div className="flex items-center gap-2">
691
+ <div className="h-3 w-3 rounded-full bg-red-500" />
692
+ <span className="text-sm">低 (1-39%)</span>
693
+ </div>
694
+ <Badge variant="secondary" className="bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400">
695
+ {coverageDistribution.low}
696
+ </Badge>
697
+ </div>
698
+ <div className="flex items-center justify-between">
699
+ <div className="flex items-center gap-2">
700
+ <div className="h-3 w-3 rounded-full bg-gray-400" />
701
+ <span className="text-sm">なし (0%)</span>
702
+ </div>
703
+ <Badge variant="secondary">
704
+ {coverageDistribution.none}
705
+ </Badge>
706
+ </div>
707
+ </div>
708
+ </CardContent>
709
+ </Card>
710
+ </div>
711
+ </TabsContent>
712
+
713
+ {/* Test Files Tab */}
714
+ <TabsContent value="files" className="mt-4">
715
+ <Card>
716
+ <CardHeader>
717
+ <div className="flex items-center gap-2">
718
+ <FileCode2 className="h-5 w-5 text-muted-foreground" />
719
+ <CardTitle>テストファイル</CardTitle>
720
+ </div>
721
+ <CardDescription>
722
+ {fileCount} ファイル / {filteredTestCases.length} テスト
723
+ </CardDescription>
724
+ </CardHeader>
725
+ <CardContent>
726
+ <div className="space-y-4">
727
+ {Object.entries(groupedByFile)
728
+ .sort(([a], [b]) => a.localeCompare(b))
729
+ .map(([file, tests]) => (
730
+ <div
731
+ key={file}
732
+ className="rounded-lg border border-border p-4 hover:bg-muted/50 transition-colors"
733
+ >
734
+ <div className="flex items-center justify-between">
735
+ <Link
736
+ href={`/test-cases/${encodeFilePath(file)}`}
737
+ className="flex items-center gap-2 font-medium text-foreground hover:text-primary"
738
+ >
739
+ <FileCode2 className="h-4 w-4 text-muted-foreground" />
740
+ <span className="truncate">{stripMatchingPrefix(file, sourcePrefixes)}</span>
741
+ <ChevronRight className="h-4 w-4 text-muted-foreground" />
742
+ </Link>
743
+ <Badge variant="secondary">{tests.length} tests</Badge>
744
+ </div>
745
+ <div className="mt-2 flex flex-wrap gap-1">
746
+ {(() => {
747
+ const categories = new Set(tests.map((t) => t.category || "unknown"));
748
+ return Array.from(categories).map((cat) => {
749
+ const config = testCategoryLabels[cat] || testCategoryLabels.unknown;
750
+ return (
751
+ <Badge
752
+ key={cat}
753
+ variant="outline"
754
+ className="text-xs"
755
+ >
756
+ <span className={`mr-1 h-1.5 w-1.5 rounded-full ${config.color}`} />
757
+ {config.ja}
758
+ </Badge>
759
+ );
760
+ });
761
+ })()}
762
+ </div>
763
+ </div>
764
+ ))}
765
+ </div>
766
+ </CardContent>
767
+ </Card>
768
+ </TabsContent>
769
+
770
+ {/* Coverage Gaps Tab */}
771
+ <TabsContent value="gaps" className="mt-4">
772
+ {coverageGaps.length > 0 ? (
773
+ <Card className="border-red-500/30">
774
+ <CardHeader className="pb-4">
775
+ <CardDescription>
776
+ テストが存在しない機能 ({coverageGaps.length}件)
777
+ </CardDescription>
778
+ </CardHeader>
779
+ <CardContent>
780
+ <div className="space-y-6">
781
+ {Object.entries(gapsByType).map(([type, gaps]) => {
782
+ const config = itemTypeConfig[type];
783
+ const Icon = config?.icon || Zap;
784
+ return (
785
+ <div key={type} className="space-y-2">
786
+ <div className="flex items-center gap-2 text-sm font-medium">
787
+ <Icon className="h-4 w-4 text-muted-foreground" />
788
+ <span>{config?.labelJa || type}</span>
789
+ <Badge variant="outline" className="text-xs">{gaps.length}</Badge>
790
+ </div>
791
+ <div className="grid gap-2 md:grid-cols-2 lg:grid-cols-3">
792
+ {gaps.map((gap, idx) => (
793
+ <Link
794
+ key={idx}
795
+ href={`/apps/${appId}/${type}/${encodeURIComponent(gap.module)}/${encodeURIComponent(gap.name)}#tests`}
796
+ className="flex items-center gap-2 rounded-lg border p-2 text-sm hover:bg-muted/50 transition-colors"
797
+ >
798
+ <XCircle className="h-4 w-4 text-red-400 flex-shrink-0" />
799
+ <div className="min-w-0">
800
+ <p className="font-medium truncate">{gap.name}</p>
801
+ <p className="text-xs text-muted-foreground truncate">{gap.module}</p>
802
+ </div>
803
+ </Link>
804
+ ))}
805
+ </div>
806
+ </div>
807
+ );
808
+ })}
809
+ </div>
810
+ </CardContent>
811
+ </Card>
812
+ ) : (
813
+ <Card className="border-green-500/30">
814
+ <CardContent className="py-8 text-center">
815
+ <CheckCircle2 className="h-8 w-8 text-green-500 mx-auto mb-2" />
816
+ <p className="text-muted-foreground">カバレッジギャップはありません</p>
817
+ </CardContent>
818
+ </Card>
819
+ )}
820
+ </TabsContent>
821
+ </TabsWithHash>
822
+
823
+ {/* Back to all tests link */}
824
+ <div className="flex justify-center">
825
+ <Link
826
+ href="/test-cases"
827
+ className="flex items-center gap-2 text-sm text-muted-foreground hover:text-primary transition-colors"
828
+ >
829
+ <TrendingUp className="h-4 w-4" />
830
+ 全アプリのテストダッシュボードを見る
831
+ </Link>
832
+ </div>
833
+
834
+ {/* Generated timestamp */}
835
+ <footer className="text-center text-sm text-muted-foreground">
836
+ <p>Generated at {new Date(data.generatedAt).toLocaleString()}</p>
837
+ </footer>
838
+ </div>
839
+ );
840
+ }