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

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 (753) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +308 -0
  3. package/README.md +308 -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 +172 -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 +193 -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 +743 -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 +429 -0
  105. package/dist/commands/init.js.map +1 -0
  106. package/dist/commands/issues-pr.d.ts +74 -0
  107. package/dist/commands/issues-pr.d.ts.map +1 -0
  108. package/dist/commands/issues-pr.js +417 -0
  109. package/dist/commands/issues-pr.js.map +1 -0
  110. package/dist/commands/issues.d.ts +76 -0
  111. package/dist/commands/issues.d.ts.map +1 -0
  112. package/dist/commands/issues.js +1285 -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 +969 -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/session.d.ts +153 -0
  187. package/dist/commands/session.d.ts.map +1 -0
  188. package/dist/commands/session.js +1243 -0
  189. package/dist/commands/session.js.map +1 -0
  190. package/dist/commands/test-cases-types.d.ts +154 -0
  191. package/dist/commands/test-cases-types.d.ts.map +1 -0
  192. package/dist/commands/test-cases-types.js +7 -0
  193. package/dist/commands/test-cases-types.js.map +1 -0
  194. package/dist/commands/test-cases.d.ts +28 -0
  195. package/dist/commands/test-cases.d.ts.map +1 -0
  196. package/dist/commands/test-cases.js +192 -0
  197. package/dist/commands/test-cases.js.map +1 -0
  198. package/dist/commands/typedoc.d.ts +21 -0
  199. package/dist/commands/typedoc.d.ts.map +1 -0
  200. package/dist/commands/typedoc.js +192 -0
  201. package/dist/commands/typedoc.js.map +1 -0
  202. package/dist/commands/update-skills.d.ts +56 -0
  203. package/dist/commands/update-skills.d.ts.map +1 -0
  204. package/dist/commands/update-skills.js +620 -0
  205. package/dist/commands/update-skills.js.map +1 -0
  206. package/dist/generators/details-entity-pages.d.ts +40 -0
  207. package/dist/generators/details-entity-pages.d.ts.map +1 -0
  208. package/dist/generators/details-entity-pages.js +301 -0
  209. package/dist/generators/details-entity-pages.js.map +1 -0
  210. package/dist/generators/details-html.d.ts +23 -0
  211. package/dist/generators/details-html.d.ts.map +1 -0
  212. package/dist/generators/details-html.js +324 -0
  213. package/dist/generators/details-html.js.map +1 -0
  214. package/dist/generators/details-module-page.d.ts +33 -0
  215. package/dist/generators/details-module-page.d.ts.map +1 -0
  216. package/dist/generators/details-module-page.js +408 -0
  217. package/dist/generators/details-module-page.js.map +1 -0
  218. package/dist/generators/details-styles.d.ts +39 -0
  219. package/dist/generators/details-styles.d.ts.map +1 -0
  220. package/dist/generators/details-styles.js +409 -0
  221. package/dist/generators/details-styles.js.map +1 -0
  222. package/dist/generators/feature-map-html.d.ts +66 -0
  223. package/dist/generators/feature-map-html.d.ts.map +1 -0
  224. package/dist/generators/feature-map-html.js +569 -0
  225. package/dist/generators/feature-map-html.js.map +1 -0
  226. package/dist/generators/feature-map-styles.d.ts +39 -0
  227. package/dist/generators/feature-map-styles.d.ts.map +1 -0
  228. package/dist/generators/feature-map-styles.js +449 -0
  229. package/dist/generators/feature-map-styles.js.map +1 -0
  230. package/dist/generators/test-cases-hierarchy.d.ts +21 -0
  231. package/dist/generators/test-cases-hierarchy.d.ts.map +1 -0
  232. package/dist/generators/test-cases-hierarchy.js +336 -0
  233. package/dist/generators/test-cases-hierarchy.js.map +1 -0
  234. package/dist/generators/test-cases-main.d.ts +20 -0
  235. package/dist/generators/test-cases-main.d.ts.map +1 -0
  236. package/dist/generators/test-cases-main.js +439 -0
  237. package/dist/generators/test-cases-main.js.map +1 -0
  238. package/dist/generators/test-cases-styles.d.ts +64 -0
  239. package/dist/generators/test-cases-styles.d.ts.map +1 -0
  240. package/dist/generators/test-cases-styles.js +1277 -0
  241. package/dist/generators/test-cases-styles.js.map +1 -0
  242. package/dist/index.d.ts +13 -0
  243. package/dist/index.d.ts.map +1 -0
  244. package/dist/index.js +517 -0
  245. package/dist/index.js.map +1 -0
  246. package/dist/lint/annotation-lint.d.ts +198 -0
  247. package/dist/lint/annotation-lint.d.ts.map +1 -0
  248. package/dist/lint/annotation-lint.js +510 -0
  249. package/dist/lint/annotation-lint.js.map +1 -0
  250. package/dist/lint/annotation-types.d.ts +161 -0
  251. package/dist/lint/annotation-types.d.ts.map +1 -0
  252. package/dist/lint/annotation-types.js +31 -0
  253. package/dist/lint/annotation-types.js.map +1 -0
  254. package/dist/lint/code-types.d.ts +135 -0
  255. package/dist/lint/code-types.d.ts.map +1 -0
  256. package/dist/lint/code-types.js +25 -0
  257. package/dist/lint/code-types.js.map +1 -0
  258. package/dist/lint/coverage-types.d.ts +128 -0
  259. package/dist/lint/coverage-types.d.ts.map +1 -0
  260. package/dist/lint/coverage-types.js +24 -0
  261. package/dist/lint/coverage-types.js.map +1 -0
  262. package/dist/lint/docs-types.d.ts +214 -0
  263. package/dist/lint/docs-types.d.ts.map +1 -0
  264. package/dist/lint/docs-types.js +18 -0
  265. package/dist/lint/docs-types.js.map +1 -0
  266. package/dist/lint/formatters/index.d.ts +14 -0
  267. package/dist/lint/formatters/index.d.ts.map +1 -0
  268. package/dist/lint/formatters/index.js +28 -0
  269. package/dist/lint/formatters/index.js.map +1 -0
  270. package/dist/lint/formatters/json.d.ts +11 -0
  271. package/dist/lint/formatters/json.d.ts.map +1 -0
  272. package/dist/lint/formatters/json.js +12 -0
  273. package/dist/lint/formatters/json.js.map +1 -0
  274. package/dist/lint/formatters/summary.d.ts +11 -0
  275. package/dist/lint/formatters/summary.d.ts.map +1 -0
  276. package/dist/lint/formatters/summary.js +37 -0
  277. package/dist/lint/formatters/summary.js.map +1 -0
  278. package/dist/lint/formatters/terminal.d.ts +11 -0
  279. package/dist/lint/formatters/terminal.d.ts.map +1 -0
  280. package/dist/lint/formatters/terminal.js +99 -0
  281. package/dist/lint/formatters/terminal.js.map +1 -0
  282. package/dist/lint/index.d.ts +18 -0
  283. package/dist/lint/index.d.ts.map +1 -0
  284. package/dist/lint/index.js +103 -0
  285. package/dist/lint/index.js.map +1 -0
  286. package/dist/lint/rules/annotation-required.d.ts +35 -0
  287. package/dist/lint/rules/annotation-required.d.ts.map +1 -0
  288. package/dist/lint/rules/annotation-required.js +127 -0
  289. package/dist/lint/rules/annotation-required.js.map +1 -0
  290. package/dist/lint/rules/code-rules.d.ts +12 -0
  291. package/dist/lint/rules/code-rules.d.ts.map +1 -0
  292. package/dist/lint/rules/code-rules.js +11 -0
  293. package/dist/lint/rules/code-rules.js.map +1 -0
  294. package/dist/lint/rules/describe-coverage.d.ts +8 -0
  295. package/dist/lint/rules/describe-coverage.d.ts.map +1 -0
  296. package/dist/lint/rules/describe-coverage.js +43 -0
  297. package/dist/lint/rules/describe-coverage.js.map +1 -0
  298. package/dist/lint/rules/duplicate-testdoc.d.ts +8 -0
  299. package/dist/lint/rules/duplicate-testdoc.d.ts.map +1 -0
  300. package/dist/lint/rules/duplicate-testdoc.js +38 -0
  301. package/dist/lint/rules/duplicate-testdoc.js.map +1 -0
  302. package/dist/lint/rules/index.d.ts +29 -0
  303. package/dist/lint/rules/index.d.ts.map +1 -0
  304. package/dist/lint/rules/index.js +55 -0
  305. package/dist/lint/rules/index.js.map +1 -0
  306. package/dist/lint/rules/server-action-structure.d.ts +37 -0
  307. package/dist/lint/rules/server-action-structure.d.ts.map +1 -0
  308. package/dist/lint/rules/server-action-structure.js +151 -0
  309. package/dist/lint/rules/server-action-structure.js.map +1 -0
  310. package/dist/lint/rules/skipped-test-report.d.ts +11 -0
  311. package/dist/lint/rules/skipped-test-report.d.ts.map +1 -0
  312. package/dist/lint/rules/skipped-test-report.js +31 -0
  313. package/dist/lint/rules/skipped-test-report.js.map +1 -0
  314. package/dist/lint/rules/structure-rules.d.ts +67 -0
  315. package/dist/lint/rules/structure-rules.d.ts.map +1 -0
  316. package/dist/lint/rules/structure-rules.js +615 -0
  317. package/dist/lint/rules/structure-rules.js.map +1 -0
  318. package/dist/lint/rules/testdoc-japanese.d.ts +8 -0
  319. package/dist/lint/rules/testdoc-japanese.d.ts.map +1 -0
  320. package/dist/lint/rules/testdoc-japanese.js +31 -0
  321. package/dist/lint/rules/testdoc-japanese.js.map +1 -0
  322. package/dist/lint/rules/testdoc-min-length.d.ts +8 -0
  323. package/dist/lint/rules/testdoc-min-length.d.ts.map +1 -0
  324. package/dist/lint/rules/testdoc-min-length.js +31 -0
  325. package/dist/lint/rules/testdoc-min-length.js.map +1 -0
  326. package/dist/lint/rules/testdoc-required.d.ts +8 -0
  327. package/dist/lint/rules/testdoc-required.d.ts.map +1 -0
  328. package/dist/lint/rules/testdoc-required.js +27 -0
  329. package/dist/lint/rules/testdoc-required.js.map +1 -0
  330. package/dist/lint/rules/workflow-branch-naming.d.ts +20 -0
  331. package/dist/lint/rules/workflow-branch-naming.d.ts.map +1 -0
  332. package/dist/lint/rules/workflow-branch-naming.js +85 -0
  333. package/dist/lint/rules/workflow-branch-naming.js.map +1 -0
  334. package/dist/lint/rules/workflow-commit-format.d.ts +27 -0
  335. package/dist/lint/rules/workflow-commit-format.d.ts.map +1 -0
  336. package/dist/lint/rules/workflow-commit-format.js +92 -0
  337. package/dist/lint/rules/workflow-commit-format.js.map +1 -0
  338. package/dist/lint/rules/workflow-issue-fields.d.ts +24 -0
  339. package/dist/lint/rules/workflow-issue-fields.d.ts.map +1 -0
  340. package/dist/lint/rules/workflow-issue-fields.js +89 -0
  341. package/dist/lint/rules/workflow-issue-fields.js.map +1 -0
  342. package/dist/lint/rules/workflow-main-protection.d.ts +32 -0
  343. package/dist/lint/rules/workflow-main-protection.d.ts.map +1 -0
  344. package/dist/lint/rules/workflow-main-protection.js +114 -0
  345. package/dist/lint/rules/workflow-main-protection.js.map +1 -0
  346. package/dist/lint/structure-types.d.ts +216 -0
  347. package/dist/lint/structure-types.d.ts.map +1 -0
  348. package/dist/lint/structure-types.js +96 -0
  349. package/dist/lint/structure-types.js.map +1 -0
  350. package/dist/lint/types.d.ts +154 -0
  351. package/dist/lint/types.d.ts.map +1 -0
  352. package/dist/lint/types.js +21 -0
  353. package/dist/lint/types.js.map +1 -0
  354. package/dist/lint/workflow-types.d.ts +90 -0
  355. package/dist/lint/workflow-types.d.ts.map +1 -0
  356. package/dist/lint/workflow-types.js +7 -0
  357. package/dist/lint/workflow-types.js.map +1 -0
  358. package/dist/md/analyzer/index.d.ts +46 -0
  359. package/dist/md/analyzer/index.d.ts.map +1 -0
  360. package/dist/md/analyzer/index.js +288 -0
  361. package/dist/md/analyzer/index.js.map +1 -0
  362. package/dist/md/builder/index.d.ts +91 -0
  363. package/dist/md/builder/index.d.ts.map +1 -0
  364. package/dist/md/builder/index.js +446 -0
  365. package/dist/md/builder/index.js.map +1 -0
  366. package/dist/md/cli/analyze.d.ts +11 -0
  367. package/dist/md/cli/analyze.d.ts.map +1 -0
  368. package/dist/md/cli/analyze.js +118 -0
  369. package/dist/md/cli/analyze.js.map +1 -0
  370. package/dist/md/cli/build.d.ts +11 -0
  371. package/dist/md/cli/build.d.ts.map +1 -0
  372. package/dist/md/cli/build.js +74 -0
  373. package/dist/md/cli/build.js.map +1 -0
  374. package/dist/md/cli/extract.d.ts +25 -0
  375. package/dist/md/cli/extract.d.ts.map +1 -0
  376. package/dist/md/cli/extract.js +230 -0
  377. package/dist/md/cli/extract.js.map +1 -0
  378. package/dist/md/cli/index.d.ts +3 -0
  379. package/dist/md/cli/index.d.ts.map +1 -0
  380. package/dist/md/cli/index.js +99 -0
  381. package/dist/md/cli/index.js.map +1 -0
  382. package/dist/md/cli/lint.d.ts +11 -0
  383. package/dist/md/cli/lint.d.ts.map +1 -0
  384. package/dist/md/cli/lint.js +165 -0
  385. package/dist/md/cli/lint.js.map +1 -0
  386. package/dist/md/cli/list.d.ts +16 -0
  387. package/dist/md/cli/list.d.ts.map +1 -0
  388. package/dist/md/cli/list.js +85 -0
  389. package/dist/md/cli/list.js.map +1 -0
  390. package/dist/md/cli/program.d.ts +11 -0
  391. package/dist/md/cli/program.d.ts.map +1 -0
  392. package/dist/md/cli/program.js +104 -0
  393. package/dist/md/cli/program.js.map +1 -0
  394. package/dist/md/cli/validate.d.ts +8 -0
  395. package/dist/md/cli/validate.d.ts.map +1 -0
  396. package/dist/md/cli/validate.js +82 -0
  397. package/dist/md/cli/validate.js.map +1 -0
  398. package/dist/md/constants.d.ts +69 -0
  399. package/dist/md/constants.d.ts.map +1 -0
  400. package/dist/md/constants.js +69 -0
  401. package/dist/md/constants.js.map +1 -0
  402. package/dist/md/extractor/index.d.ts +57 -0
  403. package/dist/md/extractor/index.d.ts.map +1 -0
  404. package/dist/md/extractor/index.js +359 -0
  405. package/dist/md/extractor/index.js.map +1 -0
  406. package/dist/md/index.d.ts +26 -0
  407. package/dist/md/index.d.ts.map +1 -0
  408. package/dist/md/index.js +30 -0
  409. package/dist/md/index.js.map +1 -0
  410. package/dist/md/linter/index.d.ts +20 -0
  411. package/dist/md/linter/index.d.ts.map +1 -0
  412. package/dist/md/linter/index.js +412 -0
  413. package/dist/md/linter/index.js.map +1 -0
  414. package/dist/md/linter/token-optimizer.d.ts +66 -0
  415. package/dist/md/linter/token-optimizer.d.ts.map +1 -0
  416. package/dist/md/linter/token-optimizer.js +292 -0
  417. package/dist/md/linter/token-optimizer.js.map +1 -0
  418. package/dist/md/lister/index.d.ts +42 -0
  419. package/dist/md/lister/index.d.ts.map +1 -0
  420. package/dist/md/lister/index.js +317 -0
  421. package/dist/md/lister/index.js.map +1 -0
  422. package/dist/md/parser/heading-numbers.d.ts +43 -0
  423. package/dist/md/parser/heading-numbers.d.ts.map +1 -0
  424. package/dist/md/parser/heading-numbers.js +97 -0
  425. package/dist/md/parser/heading-numbers.js.map +1 -0
  426. package/dist/md/parser/section-meta.d.ts +50 -0
  427. package/dist/md/parser/section-meta.d.ts.map +1 -0
  428. package/dist/md/parser/section-meta.js +212 -0
  429. package/dist/md/parser/section-meta.js.map +1 -0
  430. package/dist/md/parser/template.d.ts +56 -0
  431. package/dist/md/parser/template.d.ts.map +1 -0
  432. package/dist/md/parser/template.js +122 -0
  433. package/dist/md/parser/template.js.map +1 -0
  434. package/dist/md/plugins/loader.d.ts +15 -0
  435. package/dist/md/plugins/loader.d.ts.map +1 -0
  436. package/dist/md/plugins/loader.js +80 -0
  437. package/dist/md/plugins/loader.js.map +1 -0
  438. package/dist/md/plugins/normalize-headings.d.ts +43 -0
  439. package/dist/md/plugins/normalize-headings.d.ts.map +1 -0
  440. package/dist/md/plugins/normalize-headings.js +51 -0
  441. package/dist/md/plugins/normalize-headings.js.map +1 -0
  442. package/dist/md/plugins/normalize-whitespace.d.ts +46 -0
  443. package/dist/md/plugins/normalize-whitespace.d.ts.map +1 -0
  444. package/dist/md/plugins/normalize-whitespace.js +86 -0
  445. package/dist/md/plugins/normalize-whitespace.js.map +1 -0
  446. package/dist/md/plugins/remove-badges.d.ts +36 -0
  447. package/dist/md/plugins/remove-badges.d.ts.map +1 -0
  448. package/dist/md/plugins/remove-badges.js +59 -0
  449. package/dist/md/plugins/remove-badges.js.map +1 -0
  450. package/dist/md/plugins/remove-comments.d.ts +27 -0
  451. package/dist/md/plugins/remove-comments.d.ts.map +1 -0
  452. package/dist/md/plugins/remove-comments.js +40 -0
  453. package/dist/md/plugins/remove-comments.js.map +1 -0
  454. package/dist/md/plugins/remove-duplicates.d.ts +40 -0
  455. package/dist/md/plugins/remove-duplicates.d.ts.map +1 -0
  456. package/dist/md/plugins/remove-duplicates.js +72 -0
  457. package/dist/md/plugins/remove-duplicates.js.map +1 -0
  458. package/dist/md/plugins/remove-internal-links.d.ts +38 -0
  459. package/dist/md/plugins/remove-internal-links.d.ts.map +1 -0
  460. package/dist/md/plugins/remove-internal-links.js +66 -0
  461. package/dist/md/plugins/remove-internal-links.js.map +1 -0
  462. package/dist/md/plugins/strip-heading-numbers.d.ts +35 -0
  463. package/dist/md/plugins/strip-heading-numbers.d.ts.map +1 -0
  464. package/dist/md/plugins/strip-heading-numbers.js +59 -0
  465. package/dist/md/plugins/strip-heading-numbers.js.map +1 -0
  466. package/dist/md/plugins/strip-section-meta.d.ts +37 -0
  467. package/dist/md/plugins/strip-section-meta.d.ts.map +1 -0
  468. package/dist/md/plugins/strip-section-meta.js +62 -0
  469. package/dist/md/plugins/strip-section-meta.js.map +1 -0
  470. package/dist/md/types/config.d.ts +260 -0
  471. package/dist/md/types/config.d.ts.map +1 -0
  472. package/dist/md/types/config.js +156 -0
  473. package/dist/md/types/config.js.map +1 -0
  474. package/dist/md/types/document.d.ts +37 -0
  475. package/dist/md/types/document.d.ts.map +1 -0
  476. package/dist/md/types/document.js +2 -0
  477. package/dist/md/types/document.js.map +1 -0
  478. package/dist/md/types/validation.d.ts +107 -0
  479. package/dist/md/types/validation.d.ts.map +1 -0
  480. package/dist/md/types/validation.js +2 -0
  481. package/dist/md/types/validation.js.map +1 -0
  482. package/dist/md/utils/code-blocks.d.ts +136 -0
  483. package/dist/md/utils/code-blocks.d.ts.map +1 -0
  484. package/dist/md/utils/code-blocks.js +178 -0
  485. package/dist/md/utils/code-blocks.js.map +1 -0
  486. package/dist/md/utils/config.d.ts +10 -0
  487. package/dist/md/utils/config.d.ts.map +1 -0
  488. package/dist/md/utils/config.js +99 -0
  489. package/dist/md/utils/config.js.map +1 -0
  490. package/dist/md/utils/file-collector.d.ts +78 -0
  491. package/dist/md/utils/file-collector.d.ts.map +1 -0
  492. package/dist/md/utils/file-collector.js +100 -0
  493. package/dist/md/utils/file-collector.js.map +1 -0
  494. package/dist/md/utils/markdown.d.ts +18 -0
  495. package/dist/md/utils/markdown.d.ts.map +1 -0
  496. package/dist/md/utils/markdown.js +93 -0
  497. package/dist/md/utils/markdown.js.map +1 -0
  498. package/dist/md/utils/remark.d.ts +91 -0
  499. package/dist/md/utils/remark.d.ts.map +1 -0
  500. package/dist/md/utils/remark.js +125 -0
  501. package/dist/md/utils/remark.js.map +1 -0
  502. package/dist/md/utils/tokens.d.ts +9 -0
  503. package/dist/md/utils/tokens.d.ts.map +1 -0
  504. package/dist/md/utils/tokens.js +31 -0
  505. package/dist/md/utils/tokens.js.map +1 -0
  506. package/dist/md/validator/index.d.ts +40 -0
  507. package/dist/md/validator/index.d.ts.map +1 -0
  508. package/dist/md/validator/index.js +289 -0
  509. package/dist/md/validator/index.js.map +1 -0
  510. package/dist/parsers/details-jsdoc.d.ts +46 -0
  511. package/dist/parsers/details-jsdoc.d.ts.map +1 -0
  512. package/dist/parsers/details-jsdoc.js +262 -0
  513. package/dist/parsers/details-jsdoc.js.map +1 -0
  514. package/dist/parsers/details-zod.d.ts +22 -0
  515. package/dist/parsers/details-zod.d.ts.map +1 -0
  516. package/dist/parsers/details-zod.js +145 -0
  517. package/dist/parsers/details-zod.js.map +1 -0
  518. package/dist/parsers/drizzle-schema.d.ts +92 -0
  519. package/dist/parsers/drizzle-schema.d.ts.map +1 -0
  520. package/dist/parsers/drizzle-schema.js +376 -0
  521. package/dist/parsers/drizzle-schema.js.map +1 -0
  522. package/dist/parsers/feature-map-tags.d.ts +45 -0
  523. package/dist/parsers/feature-map-tags.d.ts.map +1 -0
  524. package/dist/parsers/feature-map-tags.js +292 -0
  525. package/dist/parsers/feature-map-tags.js.map +1 -0
  526. package/dist/parsers/feature-map-type-extraction.d.ts +62 -0
  527. package/dist/parsers/feature-map-type-extraction.d.ts.map +1 -0
  528. package/dist/parsers/feature-map-type-extraction.js +347 -0
  529. package/dist/parsers/feature-map-type-extraction.js.map +1 -0
  530. package/dist/parsers/feature-map-utils.d.ts +34 -0
  531. package/dist/parsers/feature-map-utils.d.ts.map +1 -0
  532. package/dist/parsers/feature-map-utils.js +101 -0
  533. package/dist/parsers/feature-map-utils.js.map +1 -0
  534. package/dist/parsers/jsdoc-common.d.ts +209 -0
  535. package/dist/parsers/jsdoc-common.d.ts.map +1 -0
  536. package/dist/parsers/jsdoc-common.js +655 -0
  537. package/dist/parsers/jsdoc-common.js.map +1 -0
  538. package/dist/parsers/jsdoc.d.ts +76 -0
  539. package/dist/parsers/jsdoc.d.ts.map +1 -0
  540. package/dist/parsers/jsdoc.js +238 -0
  541. package/dist/parsers/jsdoc.js.map +1 -0
  542. package/dist/parsers/screenshot-annotations.d.ts +96 -0
  543. package/dist/parsers/screenshot-annotations.d.ts.map +1 -0
  544. package/dist/parsers/screenshot-annotations.js +227 -0
  545. package/dist/parsers/screenshot-annotations.js.map +1 -0
  546. package/dist/parsers/test-annotations.d.ts +46 -0
  547. package/dist/parsers/test-annotations.d.ts.map +1 -0
  548. package/dist/parsers/test-annotations.js +393 -0
  549. package/dist/parsers/test-annotations.js.map +1 -0
  550. package/dist/parsers/test-categorization.d.ts +42 -0
  551. package/dist/parsers/test-categorization.d.ts.map +1 -0
  552. package/dist/parsers/test-categorization.js +182 -0
  553. package/dist/parsers/test-categorization.js.map +1 -0
  554. package/dist/parsers/zod-schema.d.ts +105 -0
  555. package/dist/parsers/zod-schema.d.ts.map +1 -0
  556. package/dist/parsers/zod-schema.js +270 -0
  557. package/dist/parsers/zod-schema.js.map +1 -0
  558. package/dist/utils/action-inference.d.ts +23 -0
  559. package/dist/utils/action-inference.d.ts.map +1 -0
  560. package/dist/utils/action-inference.js +36 -0
  561. package/dist/utils/action-inference.js.map +1 -0
  562. package/dist/utils/app-inference.d.ts +31 -0
  563. package/dist/utils/app-inference.d.ts.map +1 -0
  564. package/dist/utils/app-inference.js +41 -0
  565. package/dist/utils/app-inference.js.map +1 -0
  566. package/dist/utils/auto-infer.d.ts +93 -0
  567. package/dist/utils/auto-infer.d.ts.map +1 -0
  568. package/dist/utils/auto-infer.js +184 -0
  569. package/dist/utils/auto-infer.js.map +1 -0
  570. package/dist/utils/config.d.ts +709 -0
  571. package/dist/utils/config.d.ts.map +1 -0
  572. package/dist/utils/config.js +504 -0
  573. package/dist/utils/config.js.map +1 -0
  574. package/dist/utils/file.d.ts +46 -0
  575. package/dist/utils/file.d.ts.map +1 -0
  576. package/dist/utils/file.js +103 -0
  577. package/dist/utils/file.js.map +1 -0
  578. package/dist/utils/formatters.d.ts +111 -0
  579. package/dist/utils/formatters.d.ts.map +1 -0
  580. package/dist/utils/formatters.js +164 -0
  581. package/dist/utils/formatters.js.map +1 -0
  582. package/dist/utils/gh-config.d.ts +99 -0
  583. package/dist/utils/gh-config.d.ts.map +1 -0
  584. package/dist/utils/gh-config.js +247 -0
  585. package/dist/utils/gh-config.js.map +1 -0
  586. package/dist/utils/github.d.ts +98 -0
  587. package/dist/utils/github.d.ts.map +1 -0
  588. package/dist/utils/github.js +295 -0
  589. package/dist/utils/github.js.map +1 -0
  590. package/dist/utils/html.d.ts +107 -0
  591. package/dist/utils/html.d.ts.map +1 -0
  592. package/dist/utils/html.js +376 -0
  593. package/dist/utils/html.js.map +1 -0
  594. package/dist/utils/i18n.d.ts +40 -0
  595. package/dist/utils/i18n.d.ts.map +1 -0
  596. package/dist/utils/i18n.js +148 -0
  597. package/dist/utils/i18n.js.map +1 -0
  598. package/dist/utils/logger.d.ts +20 -0
  599. package/dist/utils/logger.d.ts.map +1 -0
  600. package/dist/utils/logger.js +49 -0
  601. package/dist/utils/logger.js.map +1 -0
  602. package/dist/utils/project-fields.d.ts +71 -0
  603. package/dist/utils/project-fields.d.ts.map +1 -0
  604. package/dist/utils/project-fields.js +318 -0
  605. package/dist/utils/project-fields.js.map +1 -0
  606. package/dist/utils/repo-pairs.d.ts +94 -0
  607. package/dist/utils/repo-pairs.d.ts.map +1 -0
  608. package/dist/utils/repo-pairs.js +196 -0
  609. package/dist/utils/repo-pairs.js.map +1 -0
  610. package/dist/utils/route-inference.d.ts +81 -0
  611. package/dist/utils/route-inference.d.ts.map +1 -0
  612. package/dist/utils/route-inference.js +137 -0
  613. package/dist/utils/route-inference.js.map +1 -0
  614. package/dist/utils/setup-check.d.ts +34 -0
  615. package/dist/utils/setup-check.d.ts.map +1 -0
  616. package/dist/utils/setup-check.js +136 -0
  617. package/dist/utils/setup-check.js.map +1 -0
  618. package/dist/utils/shirokumaignore.d.ts +55 -0
  619. package/dist/utils/shirokumaignore.d.ts.map +1 -0
  620. package/dist/utils/shirokumaignore.js +94 -0
  621. package/dist/utils/shirokumaignore.js.map +1 -0
  622. package/dist/utils/skills-repo.d.ts +353 -0
  623. package/dist/utils/skills-repo.d.ts.map +1 -0
  624. package/dist/utils/skills-repo.js +793 -0
  625. package/dist/utils/skills-repo.js.map +1 -0
  626. package/dist/utils/status-workflow.d.ts +54 -0
  627. package/dist/utils/status-workflow.d.ts.map +1 -0
  628. package/dist/utils/status-workflow.js +103 -0
  629. package/dist/utils/status-workflow.js.map +1 -0
  630. package/dist/validators/frontmatter.d.ts +41 -0
  631. package/dist/validators/frontmatter.d.ts.map +1 -0
  632. package/dist/validators/frontmatter.js +117 -0
  633. package/dist/validators/frontmatter.js.map +1 -0
  634. package/dist/validators/link-checker.d.ts +48 -0
  635. package/dist/validators/link-checker.d.ts.map +1 -0
  636. package/dist/validators/link-checker.js +108 -0
  637. package/dist/validators/link-checker.js.map +1 -0
  638. package/dist/validators/markdown-structure.d.ts +50 -0
  639. package/dist/validators/markdown-structure.d.ts.map +1 -0
  640. package/dist/validators/markdown-structure.js +253 -0
  641. package/dist/validators/markdown-structure.js.map +1 -0
  642. package/i18n/cli/en.json +155 -0
  643. package/i18n/cli/ja.json +155 -0
  644. package/i18n/discussion/en.json +191 -0
  645. package/i18n/discussion/ja.json +191 -0
  646. package/package.json +113 -0
  647. package/portal/app/api-tools/api-tools-client.tsx +411 -0
  648. package/portal/app/api-tools/api-tools-document.tsx +240 -0
  649. package/portal/app/api-tools/page.tsx +56 -0
  650. package/portal/app/api-tools/swagger-view.tsx +114 -0
  651. package/portal/app/apps/[appId]/[type]/[module]/[item]/item-tabs-client.tsx +71 -0
  652. package/portal/app/apps/[appId]/[type]/[module]/[item]/page.tsx +1422 -0
  653. package/portal/app/apps/[appId]/[type]/[module]/page.tsx +373 -0
  654. package/portal/app/apps/[appId]/feature-map/feature-map-app-document.tsx +298 -0
  655. package/portal/app/apps/[appId]/feature-map/page.tsx +224 -0
  656. package/portal/app/apps/[appId]/i18n/page.tsx +139 -0
  657. package/portal/app/apps/[appId]/test-cases/page.tsx +840 -0
  658. package/portal/app/apps/[appId]/tools/[tool]/page.tsx +351 -0
  659. package/portal/app/apps/[appId]/tools/api-tools-client.tsx +429 -0
  660. package/portal/app/apps/[appId]/tools/page.tsx +119 -0
  661. package/portal/app/db-schema/[db]/[table]/page.tsx +235 -0
  662. package/portal/app/db-schema/[db]/diagram/page.tsx +81 -0
  663. package/portal/app/db-schema/[db]/page.tsx +148 -0
  664. package/portal/app/db-schema/db-schema-document.tsx +100 -0
  665. package/portal/app/db-schema/diagram/client.tsx +211 -0
  666. package/portal/app/db-schema/diagram/page.tsx +20 -0
  667. package/portal/app/db-schema/page.tsx +145 -0
  668. package/portal/app/db-schema/table-detail-document.tsx +710 -0
  669. package/portal/app/db-schema/table-detail.tsx +747 -0
  670. package/portal/app/db-schema/table-list-document.tsx +224 -0
  671. package/portal/app/db-schema/table-list.tsx +247 -0
  672. package/portal/app/details/[type]/[module]/[item]/item-tabs-client.tsx +71 -0
  673. package/portal/app/details/[type]/[module]/[item]/page.tsx +1286 -0
  674. package/portal/app/details/[type]/[module]/page.tsx +884 -0
  675. package/portal/app/feature-map/feature-map-client.tsx +681 -0
  676. package/portal/app/feature-map/feature-map-document.tsx +313 -0
  677. package/portal/app/feature-map/page.tsx +438 -0
  678. package/portal/app/globals.css +205 -0
  679. package/portal/app/i18n/[...namespace]/page.tsx +190 -0
  680. package/portal/app/i18n/i18n-client.tsx +369 -0
  681. package/portal/app/i18n/page.tsx +339 -0
  682. package/portal/app/layout.tsx +37 -0
  683. package/portal/app/overview/page.tsx +65 -0
  684. package/portal/app/packages/[packageId]/page.tsx +201 -0
  685. package/portal/app/packages/page.tsx +148 -0
  686. package/portal/app/page.tsx +568 -0
  687. package/portal/app/test-cases/[file]/[line]/page.tsx +455 -0
  688. package/portal/app/test-cases/[file]/[line]/test-detail-document.tsx +335 -0
  689. package/portal/app/test-cases/[file]/page.tsx +323 -0
  690. package/portal/app/test-cases/[file]/test-file-document.tsx +335 -0
  691. package/portal/app/test-cases/page.tsx +546 -0
  692. package/portal/app/test-cases/test-cases-document.tsx +384 -0
  693. package/portal/components/code-block.tsx +57 -0
  694. package/portal/components/document/doc-params-table.tsx +71 -0
  695. package/portal/components/document/doc-section.tsx +133 -0
  696. package/portal/components/document/doc-table.tsx +119 -0
  697. package/portal/components/document/index.ts +9 -0
  698. package/portal/components/drawflow-er-diagram.tsx +607 -0
  699. package/portal/components/interactive-er-diagram.tsx +228 -0
  700. package/portal/components/layout/app-sidebar.tsx +490 -0
  701. package/portal/components/layout/er-sidebar.tsx +116 -0
  702. package/portal/components/layout/global-header.tsx +117 -0
  703. package/portal/components/layout/layout-content.tsx +48 -0
  704. package/portal/components/markdown-content.tsx +120 -0
  705. package/portal/components/mermaid-diagram.tsx +83 -0
  706. package/portal/components/reactflow-er-diagram.tsx +475 -0
  707. package/portal/components/search-dialog.tsx +268 -0
  708. package/portal/components/shared/coverage-score-bar.tsx +144 -0
  709. package/portal/components/swagger/endpoint-accordion.tsx +117 -0
  710. package/portal/components/swagger/index.ts +7 -0
  711. package/portal/components/swagger/method-badge.tsx +55 -0
  712. package/portal/components/swagger/params-table.tsx +78 -0
  713. package/portal/components/tabs-with-hash.tsx +43 -0
  714. package/portal/components/test/index.ts +2 -0
  715. package/portal/components/test/test-bdd-card.tsx +192 -0
  716. package/portal/components/test/test-matrix.tsx +242 -0
  717. package/portal/components/ui/accordion.tsx +66 -0
  718. package/portal/components/ui/badge.tsx +46 -0
  719. package/portal/components/ui/breadcrumb.tsx +109 -0
  720. package/portal/components/ui/button.tsx +62 -0
  721. package/portal/components/ui/card.tsx +92 -0
  722. package/portal/components/ui/collapsible.tsx +33 -0
  723. package/portal/components/ui/dialog.tsx +118 -0
  724. package/portal/components/ui/progress.tsx +28 -0
  725. package/portal/components/ui/scroll-area.tsx +58 -0
  726. package/portal/components/ui/sheet.tsx +139 -0
  727. package/portal/components/ui/table.tsx +116 -0
  728. package/portal/components/ui/tabs.tsx +66 -0
  729. package/portal/components.json +21 -0
  730. package/portal/lib/constants/test-categories.ts +186 -0
  731. package/portal/lib/data-loader.ts +1181 -0
  732. package/portal/lib/db-schema-utils.ts +182 -0
  733. package/portal/lib/format.ts +43 -0
  734. package/portal/lib/hooks/use-hash-tab.ts +144 -0
  735. package/portal/lib/path-utils.ts +25 -0
  736. package/portal/lib/search-index-generator.ts +214 -0
  737. package/portal/lib/search.ts +126 -0
  738. package/portal/lib/sidebar-context.tsx +111 -0
  739. package/portal/lib/types.ts +740 -0
  740. package/portal/lib/utils.ts +6 -0
  741. package/portal/next.config.ts +21 -0
  742. package/portal/package.json +45 -0
  743. package/portal/postcss.config.mjs +8 -0
  744. package/portal/tsconfig.json +41 -0
  745. package/portal/types/drawflow.d.ts +80 -0
  746. package/templates/README.md +73 -0
  747. package/templates/coverage.html +367 -0
  748. package/templates/dark-theme.css +443 -0
  749. package/templates/discussion/adr.yml.hbs +65 -0
  750. package/templates/discussion/handovers.yml.hbs +57 -0
  751. package/templates/discussion/knowledge.yml.hbs +60 -0
  752. package/templates/discussion/reports.yml.hbs +68 -0
  753. package/templates/discussion/research.yml.hbs +61 -0
@@ -0,0 +1,1286 @@
1
+ import { notFound } from "next/navigation";
2
+ import Link from "next/link";
3
+ import {
4
+ Monitor,
5
+ Component,
6
+ Zap,
7
+ Database,
8
+ ArrowLeft,
9
+ FileCode,
10
+ Code2,
11
+ TestTube2,
12
+ ChevronDown,
13
+ ChevronRight,
14
+ AlertTriangle,
15
+ CheckCircle2,
16
+ Info,
17
+ Shield,
18
+ Globe,
19
+ Users,
20
+ Lock,
21
+ Clock,
22
+ ExternalLink,
23
+ Route,
24
+ Layers,
25
+ Languages,
26
+ Workflow,
27
+ Tag,
28
+ AppWindow,
29
+ } from "lucide-react";
30
+ import { ItemTabsClient } from "./item-tabs-client";
31
+ import {
32
+ Card,
33
+ CardContent,
34
+ CardDescription,
35
+ CardHeader,
36
+ CardTitle,
37
+ } from "@/components/ui/card";
38
+ import { Badge } from "@/components/ui/badge";
39
+ import {
40
+ Table,
41
+ TableBody,
42
+ TableCell,
43
+ TableHead,
44
+ TableHeader,
45
+ TableRow,
46
+ } from "@/components/ui/table";
47
+ import {
48
+ Collapsible,
49
+ CollapsibleContent,
50
+ CollapsibleTrigger,
51
+ } from "@/components/ui/collapsible";
52
+ import { loadFeatureMap, loadDetails } from "@/lib/data-loader";
53
+ import { encodeFilePath } from "@/lib/path-utils";
54
+ import { CodeBlock } from "@/components/code-block";
55
+ import { CATEGORY_LABELS } from "@/lib/constants/test-categories";
56
+ import type {
57
+ FeatureMapData,
58
+ ScreenItem,
59
+ ComponentItem,
60
+ ActionItem,
61
+ TableItem,
62
+ DetailItem,
63
+ AuthLevel,
64
+ ZodParameterInfo,
65
+ ErrorCodeInfo,
66
+ } from "@/lib/types";
67
+
68
+ // Only pre-generated paths will work (required for output: export)
69
+ export const dynamicParams = false;
70
+
71
+ type LayerType = "screens" | "components" | "actions" | "tables";
72
+ type LayerTypeSingular = "screen" | "component" | "action" | "table";
73
+
74
+ interface LayerConfig {
75
+ key: LayerType;
76
+ singular: LayerTypeSingular;
77
+ label: string;
78
+ icon: typeof Monitor;
79
+ color: string;
80
+ bgColor: string;
81
+ }
82
+
83
+ const layerConfigs: Record<LayerType, LayerConfig> = {
84
+ screens: {
85
+ key: "screens",
86
+ singular: "screen",
87
+ label: "Screens",
88
+ icon: Monitor,
89
+ color: "text-accent-blue",
90
+ bgColor: "bg-accent-blue/10",
91
+ },
92
+ components: {
93
+ key: "components",
94
+ singular: "component",
95
+ label: "Components",
96
+ icon: Component,
97
+ color: "text-accent-green",
98
+ bgColor: "bg-accent-green/10",
99
+ },
100
+ actions: {
101
+ key: "actions",
102
+ singular: "action",
103
+ label: "Actions",
104
+ icon: Zap,
105
+ color: "text-accent-yellow",
106
+ bgColor: "bg-accent-yellow/10",
107
+ },
108
+ tables: {
109
+ key: "tables",
110
+ singular: "table",
111
+ label: "Tables",
112
+ icon: Database,
113
+ color: "text-accent-purple",
114
+ bgColor: "bg-accent-purple/10",
115
+ },
116
+ };
117
+
118
+ export async function generateStaticParams(): Promise<
119
+ { type: string; module: string; item: string }[]
120
+ > {
121
+ const data = await loadFeatureMap();
122
+ if (!data) return [];
123
+
124
+ const params: { type: string; module: string; item: string }[] = [];
125
+ const layers: LayerType[] = ["screens", "components", "actions", "tables"];
126
+
127
+ // Add items from feature modules
128
+ for (const [moduleName, group] of Object.entries(data.features)) {
129
+ for (const layer of layers) {
130
+ const items = group[layer] || [];
131
+ for (const item of items) {
132
+ params.push({ type: layer, module: moduleName, item: item.name });
133
+ }
134
+ }
135
+ }
136
+
137
+ // Add uncategorized items
138
+ for (const layer of layers) {
139
+ const items = data.uncategorized[layer] || [];
140
+ for (const item of items) {
141
+ params.push({ type: layer, module: "Uncategorized", item: item.name });
142
+ }
143
+ }
144
+
145
+ return params;
146
+ }
147
+
148
+ // Test category labels - using shared constant
149
+ const categoryLabels = CATEGORY_LABELS;
150
+
151
+ // Auth Level Badge Component
152
+ const authLevelConfig: Record<AuthLevel, { label: string; icon: typeof Shield; color: string }> = {
153
+ none: { label: "Public", icon: Globe, color: "text-green-600 bg-green-500/10 border-green-500/30" },
154
+ authenticated: { label: "Auth Required", icon: Lock, color: "text-blue-600 bg-blue-500/10 border-blue-500/30" },
155
+ member: { label: "Member Only", icon: Users, color: "text-purple-600 bg-purple-500/10 border-purple-500/30" },
156
+ admin: { label: "Admin Only", icon: Shield, color: "text-red-600 bg-red-500/10 border-red-500/30" },
157
+ };
158
+
159
+ function AuthLevelBadge({ level }: { level: AuthLevel }) {
160
+ const config = authLevelConfig[level];
161
+ const Icon = config.icon;
162
+ return (
163
+ <Badge variant="outline" className={`${config.color} text-xs`}>
164
+ <Icon className="mr-1 h-3 w-3" />
165
+ {config.label}
166
+ </Badge>
167
+ );
168
+ }
169
+
170
+ // Coverage Score Bar Component
171
+ function CoverageScoreBar({ score }: { score: number }) {
172
+ const getScoreColor = (score: number) => {
173
+ if (score >= 70) return "bg-green-500";
174
+ if (score >= 40) return "bg-yellow-500";
175
+ return "bg-red-500";
176
+ };
177
+
178
+ return (
179
+ <div className="space-y-1">
180
+ <div className="flex items-center justify-between text-sm">
181
+ <span className="text-muted-foreground">カバレッジスコア</span>
182
+ <span className="font-medium">{score}%</span>
183
+ </div>
184
+ <div className="h-2 w-full overflow-hidden rounded-full bg-muted">
185
+ <div
186
+ className={`h-full transition-all ${getScoreColor(score)}`}
187
+ style={{ width: `${Math.min(score, 100)}%` }}
188
+ />
189
+ </div>
190
+ </div>
191
+ );
192
+ }
193
+
194
+ // Enhanced Parameters Table (from Zod schema)
195
+ function EnhancedParametersTable({ parameters }: { parameters: ZodParameterInfo[] }) {
196
+ if (!parameters || parameters.length === 0) return null;
197
+
198
+ return (
199
+ <div>
200
+ <h4 className="mb-2 text-sm font-semibold text-muted-foreground">入力パラメータ (Zodスキーマ)</h4>
201
+ <Table>
202
+ <TableHeader>
203
+ <TableRow>
204
+ <TableHead className="w-[120px]">名前</TableHead>
205
+ <TableHead className="w-[100px]">型</TableHead>
206
+ <TableHead className="w-[60px]">必須</TableHead>
207
+ <TableHead className="w-[150px]">制約</TableHead>
208
+ <TableHead className="w-[100px]">デフォルト</TableHead>
209
+ <TableHead>説明</TableHead>
210
+ </TableRow>
211
+ </TableHeader>
212
+ <TableBody>
213
+ {parameters.map((param, idx) => {
214
+ const constraints: string[] = [];
215
+ if (param.format) constraints.push(param.format);
216
+ if (param.minLength !== undefined) constraints.push(`min: ${param.minLength}`);
217
+ if (param.maxLength !== undefined) constraints.push(`max: ${param.maxLength}`);
218
+ if (param.min !== undefined) constraints.push(`≥ ${param.min}`);
219
+ if (param.max !== undefined) constraints.push(`≤ ${param.max}`);
220
+ if (param.enumValues) constraints.push(param.enumValues.join(" | "));
221
+
222
+ return (
223
+ <TableRow key={idx}>
224
+ <TableCell className="font-mono text-sm">{param.name}</TableCell>
225
+ <TableCell className="font-mono text-xs text-muted-foreground">{param.type}</TableCell>
226
+ <TableCell>
227
+ {param.required ? (
228
+ <CheckCircle2 className="h-4 w-4 text-green-500" />
229
+ ) : (
230
+ <span className="text-muted-foreground">-</span>
231
+ )}
232
+ </TableCell>
233
+ <TableCell className="text-xs text-muted-foreground">
234
+ {constraints.length > 0 ? constraints.join(", ") : "-"}
235
+ </TableCell>
236
+ <TableCell className="font-mono text-xs">
237
+ {param.default !== undefined ? JSON.stringify(param.default) : "-"}
238
+ </TableCell>
239
+ <TableCell className="text-sm">{param.description || "-"}</TableCell>
240
+ </TableRow>
241
+ );
242
+ })}
243
+ </TableBody>
244
+ </Table>
245
+ </div>
246
+ );
247
+ }
248
+
249
+ // Error Codes Section
250
+ function ErrorCodesSection({ errorCodes }: { errorCodes: ErrorCodeInfo[] }) {
251
+ if (!errorCodes || errorCodes.length === 0) return null;
252
+
253
+ return (
254
+ <div>
255
+ <h4 className="mb-2 text-sm font-semibold text-muted-foreground">エラーコード</h4>
256
+ <Table>
257
+ <TableHeader>
258
+ <TableRow>
259
+ <TableHead className="w-[150px]">コード</TableHead>
260
+ <TableHead className="w-[80px]">ステータス</TableHead>
261
+ <TableHead>説明</TableHead>
262
+ </TableRow>
263
+ </TableHeader>
264
+ <TableBody>
265
+ {errorCodes.map((error, idx) => (
266
+ <TableRow key={idx}>
267
+ <TableCell className="font-mono text-sm text-red-600">{error.code}</TableCell>
268
+ <TableCell>
269
+ {error.status && (
270
+ <Badge variant="outline" className="text-xs">
271
+ {error.status}
272
+ </Badge>
273
+ )}
274
+ </TableCell>
275
+ <TableCell className="text-sm">{error.description}</TableCell>
276
+ </TableRow>
277
+ ))}
278
+ </TableBody>
279
+ </Table>
280
+ </div>
281
+ );
282
+ }
283
+
284
+ // Tag configuration for enhanced display
285
+ interface TagConfig {
286
+ icon: typeof Route;
287
+ color: string;
288
+ bgColor: string;
289
+ label: string;
290
+ }
291
+
292
+ const tagConfigs: Record<string, TagConfig> = {
293
+ route: {
294
+ icon: Route,
295
+ color: "text-blue-600",
296
+ bgColor: "bg-blue-500/10 border-blue-500/30",
297
+ label: "Route",
298
+ },
299
+ layer: {
300
+ icon: Layers,
301
+ color: "text-purple-600",
302
+ bgColor: "bg-purple-500/10 border-purple-500/30",
303
+ label: "Layer",
304
+ },
305
+ accessControl: {
306
+ icon: Shield,
307
+ color: "text-red-600",
308
+ bgColor: "bg-red-500/10 border-red-500/30",
309
+ label: "Access",
310
+ },
311
+ i18nNamespaces: {
312
+ icon: Languages,
313
+ color: "text-green-600",
314
+ bgColor: "bg-green-500/10 border-green-500/30",
315
+ label: "i18n",
316
+ },
317
+ dataFlow: {
318
+ icon: Workflow,
319
+ color: "text-amber-600",
320
+ bgColor: "bg-amber-500/10 border-amber-500/30",
321
+ label: "Data Flow",
322
+ },
323
+ feature: {
324
+ icon: Tag,
325
+ color: "text-cyan-600",
326
+ bgColor: "bg-cyan-500/10 border-cyan-500/30",
327
+ label: "Feature",
328
+ },
329
+ category: {
330
+ icon: Tag,
331
+ color: "text-gray-600",
332
+ bgColor: "bg-gray-500/10 border-gray-500/30",
333
+ label: "Category",
334
+ },
335
+ };
336
+
337
+ // Hidden tags (internal use, not displayed prominently)
338
+ const hiddenTags = ["screen", "component", "action", "table", "screenshot", "screenshotWaitFor"];
339
+
340
+ // Type for item lookup function
341
+ type ItemLookupFn = (type: "components" | "actions" | "screens" | "tables", name: string) => string | null;
342
+
343
+ // Build a lookup map from item name to module name using feature map
344
+ function buildItemModuleLookup(featureMap: FeatureMapData): ItemLookupFn {
345
+ // Maps: { "components": { "ProjectHeader": "ProjectManagement" }, "actions": { ... } }
346
+ const lookupMaps: Record<string, Map<string, string>> = {
347
+ screens: new Map(),
348
+ components: new Map(),
349
+ actions: new Map(),
350
+ tables: new Map(),
351
+ };
352
+
353
+ // Process all feature groups
354
+ for (const [moduleName, group] of Object.entries(featureMap.features)) {
355
+ for (const screen of group.screens || []) {
356
+ lookupMaps.screens.set(screen.name, moduleName);
357
+ }
358
+ for (const component of group.components || []) {
359
+ lookupMaps.components.set(component.name, moduleName);
360
+ }
361
+ for (const action of group.actions || []) {
362
+ lookupMaps.actions.set(action.name, moduleName);
363
+ }
364
+ for (const table of group.tables || []) {
365
+ lookupMaps.tables.set(table.name, moduleName);
366
+ }
367
+ }
368
+
369
+ // Process uncategorized
370
+ const uncategorized = featureMap.uncategorized;
371
+ for (const screen of uncategorized.screens || []) {
372
+ lookupMaps.screens.set(screen.name, "Uncategorized");
373
+ }
374
+ for (const component of uncategorized.components || []) {
375
+ lookupMaps.components.set(component.name, "Uncategorized");
376
+ }
377
+ for (const action of uncategorized.actions || []) {
378
+ lookupMaps.actions.set(action.name, "Uncategorized");
379
+ }
380
+ for (const table of uncategorized.tables || []) {
381
+ lookupMaps.tables.set(table.name, "Uncategorized");
382
+ }
383
+
384
+ return (type, name) => lookupMaps[type]?.get(name) || null;
385
+ }
386
+
387
+ // Enhanced Tags Section Component
388
+ function EnhancedTagsSection({
389
+ tags,
390
+ moduleName,
391
+ lookupModule
392
+ }: {
393
+ tags: Array<{ name: string; value: string }>;
394
+ moduleName: string;
395
+ lookupModule?: ItemLookupFn;
396
+ }) {
397
+ // Separate tags into categories
398
+ const keyTags = tags.filter(t => ["route", "layer", "accessControl", "feature", "category"].includes(t.name));
399
+ const dependencyTags = tags.filter(t => ["usedComponents", "usedActions"].includes(t.name));
400
+ const dataFlowTag = tags.find(t => t.name === "dataFlow");
401
+ const i18nTag = tags.find(t => t.name === "i18nNamespaces");
402
+ const otherTags = tags.filter(t =>
403
+ !["route", "layer", "accessControl", "feature", "category", "usedComponents", "usedActions", "dataFlow", "i18nNamespaces", ...hiddenTags].includes(t.name)
404
+ );
405
+
406
+ return (
407
+ <div className="space-y-4">
408
+ <h4 className="text-sm font-semibold text-muted-foreground">タグ情報</h4>
409
+
410
+ {/* Key Tags + i18n as Table */}
411
+ {(keyTags.length > 0 || (i18nTag && i18nTag.value)) && (
412
+ <Table>
413
+ <TableBody>
414
+ {keyTags.map((tag, idx) => {
415
+ const config = tagConfigs[tag.name];
416
+ if (!config || !tag.value) return null;
417
+ const Icon = config.icon;
418
+ return (
419
+ <TableRow key={idx} className="border-b-0">
420
+ <TableCell className="py-2 pl-0 w-[140px]">
421
+ <div className={`flex items-center gap-2 ${config.color}`}>
422
+ <Icon className="h-4 w-4" />
423
+ <span className="font-medium text-sm">{config.label}</span>
424
+ </div>
425
+ </TableCell>
426
+ <TableCell className="py-2 text-sm">
427
+ {tag.value}
428
+ </TableCell>
429
+ </TableRow>
430
+ );
431
+ })}
432
+ {/* i18n Namespaces row */}
433
+ {i18nTag && i18nTag.value && (
434
+ <TableRow className="border-b-0">
435
+ <TableCell className="py-2 pl-0 w-[140px]">
436
+ <div className="flex items-center gap-2 text-green-600">
437
+ <Languages className="h-4 w-4" />
438
+ <span className="font-medium text-sm">i18n</span>
439
+ </div>
440
+ </TableCell>
441
+ <TableCell className="py-2 text-sm">
442
+ <div className="flex flex-wrap gap-1">
443
+ {i18nTag.value.split(",").map((ns, i) => {
444
+ const namespace = ns.trim();
445
+ if (!namespace) return null;
446
+ return (
447
+ <Link key={i} href={`/i18n/${encodeURIComponent(namespace)}`}>
448
+ <Badge
449
+ variant="outline"
450
+ className="text-xs hover:bg-green-100 cursor-pointer transition-colors border-green-300"
451
+ >
452
+ {namespace}
453
+ </Badge>
454
+ </Link>
455
+ );
456
+ })}
457
+ </div>
458
+ </TableCell>
459
+ </TableRow>
460
+ )}
461
+ </TableBody>
462
+ </Table>
463
+ )}
464
+
465
+ {/* Dependencies (usedComponents, usedActions) */}
466
+ {dependencyTags.length > 0 && (
467
+ <div className="space-y-2">
468
+ {dependencyTags.map((tag, idx) => {
469
+ const items = tag.value?.split(",").map(s => s.trim()).filter(Boolean) || [];
470
+ if (items.length === 0) return null;
471
+
472
+ const isComponents = tag.name === "usedComponents";
473
+ const Icon = isComponents ? Component : Zap;
474
+ const color = isComponents ? "text-accent-green" : "text-accent-yellow";
475
+ const label = isComponents ? "使用コンポーネント" : "使用アクション";
476
+ const linkType = isComponents ? "components" : "actions";
477
+
478
+ return (
479
+ <div key={idx} className="rounded-md border p-3 bg-muted/30">
480
+ <div className="flex items-start gap-2">
481
+ <Icon className={`h-4 w-4 mt-0.5 ${color}`} />
482
+ <div>
483
+ <span className="text-sm font-medium">{label}</span>
484
+ <div className="flex flex-wrap gap-1 mt-1">
485
+ {items.map((item, i) => {
486
+ // Look up the correct module for this item
487
+ // If not found in feature-map, show plain badge (no link)
488
+ const targetModule = lookupModule?.(linkType, item);
489
+
490
+ if (targetModule) {
491
+ return (
492
+ <Link
493
+ key={i}
494
+ href={`/details/${linkType}/${encodeURIComponent(targetModule)}/${encodeURIComponent(item)}`}
495
+ >
496
+ <Badge
497
+ variant="outline"
498
+ className="text-xs hover:bg-muted cursor-pointer transition-colors"
499
+ >
500
+ {item}
501
+ </Badge>
502
+ </Link>
503
+ );
504
+ }
505
+ // Item not in feature-map - show plain badge without link
506
+ return (
507
+ <Badge
508
+ key={i}
509
+ variant="outline"
510
+ className="text-xs text-muted-foreground"
511
+ >
512
+ {item}
513
+ </Badge>
514
+ );
515
+ })}
516
+ </div>
517
+ </div>
518
+ </div>
519
+ </div>
520
+ );
521
+ })}
522
+ </div>
523
+ )}
524
+
525
+ {/* Data Flow as numbered list */}
526
+ {dataFlowTag && dataFlowTag.value && (
527
+ <div className="rounded-md border p-3 bg-amber-500/5 border-amber-500/20">
528
+ <div className="flex items-start gap-2">
529
+ <Workflow className="h-4 w-4 mt-0.5 text-amber-600" />
530
+ <div>
531
+ <span className="text-sm font-medium text-amber-700">データフロー</span>
532
+ <ol className="mt-2 space-y-1 text-sm list-decimal list-inside text-muted-foreground">
533
+ {dataFlowTag.value
534
+ .split(/\d+\.\s*/)
535
+ .filter(Boolean)
536
+ .map((step, idx) => (
537
+ <li key={idx}>{step.trim()}</li>
538
+ ))}
539
+ </ol>
540
+ </div>
541
+ </div>
542
+ </div>
543
+ )}
544
+
545
+ {/* Other Tags in collapsible */}
546
+ {otherTags.length > 0 && (
547
+ <Collapsible>
548
+ <CollapsibleTrigger className="flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground">
549
+ <ChevronRight className="h-4 w-4 transition-transform [[data-state=open]_&]:rotate-90" />
550
+ <span>その他のタグ ({otherTags.length})</span>
551
+ </CollapsibleTrigger>
552
+ <CollapsibleContent className="mt-2">
553
+ <Table>
554
+ <TableHeader>
555
+ <TableRow>
556
+ <TableHead className="w-[180px]">タグ名</TableHead>
557
+ <TableHead>値</TableHead>
558
+ </TableRow>
559
+ </TableHeader>
560
+ <TableBody>
561
+ {otherTags.map((tag, idx) => (
562
+ <TableRow key={idx}>
563
+ <TableCell className="font-mono text-sm">@{tag.name}</TableCell>
564
+ <TableCell className="text-sm">{tag.value || "-"}</TableCell>
565
+ </TableRow>
566
+ ))}
567
+ </TableBody>
568
+ </Table>
569
+ </CollapsibleContent>
570
+ </Collapsible>
571
+ )}
572
+ </div>
573
+ );
574
+ }
575
+
576
+ /**
577
+ * Parse markdown code fence and extract language and code
578
+ * @example ```tsx\nconst x = 1;\n``` -> { language: "tsx", code: "const x = 1;" }
579
+ */
580
+ function parseMarkdownCodeFence(text: string): { language: string; code: string } {
581
+ // Match ```language\ncode\n```
582
+ const fenceMatch = text.match(/^```(\w+)?\s*\n?([\s\S]*?)\n?```\s*$/);
583
+ if (fenceMatch) {
584
+ return {
585
+ language: fenceMatch[1] || "typescript",
586
+ code: fenceMatch[2].trim(),
587
+ };
588
+ }
589
+ // No code fence, return as-is
590
+ return { language: "typescript", code: text.trim() };
591
+ }
592
+
593
+ // JSDoc Section Component
594
+ function JSDocSection({
595
+ detail,
596
+ lookupModule
597
+ }: {
598
+ detail: DetailItem;
599
+ lookupModule?: ItemLookupFn;
600
+ }) {
601
+ const { jsDoc } = detail;
602
+ // Fallback to detail.description if jsDoc.description is empty
603
+ const descriptionText = jsDoc.description || detail.description;
604
+
605
+ return (
606
+ <div className="space-y-6">
607
+ {/* Description */}
608
+ {descriptionText && (
609
+ <div>
610
+ <h4 className="mb-2 text-sm font-semibold text-muted-foreground">概要</h4>
611
+ <p className="whitespace-pre-wrap text-sm">{descriptionText}</p>
612
+ </div>
613
+ )}
614
+
615
+ {/* Parameters (JSDoc) - only show if no Zod schema */}
616
+ {!detail.inputSchema && jsDoc.params && jsDoc.params.length > 0 && (
617
+ <div>
618
+ <h4 className="mb-2 text-sm font-semibold text-muted-foreground">パラメータ</h4>
619
+ <Table>
620
+ <TableHeader>
621
+ <TableRow>
622
+ <TableHead className="w-[150px]">名前</TableHead>
623
+ <TableHead className="w-[200px]">型</TableHead>
624
+ <TableHead>説明</TableHead>
625
+ </TableRow>
626
+ </TableHeader>
627
+ <TableBody>
628
+ {jsDoc.params.map((param, idx) => (
629
+ <TableRow key={idx}>
630
+ <TableCell className="font-mono text-sm">{param.name}</TableCell>
631
+ <TableCell className="font-mono text-xs text-muted-foreground">
632
+ {param.type || "-"}
633
+ </TableCell>
634
+ <TableCell className="text-sm">{param.description || "-"}</TableCell>
635
+ </TableRow>
636
+ ))}
637
+ </TableBody>
638
+ </Table>
639
+ </div>
640
+ )}
641
+
642
+ {/* Returns - only show if no outputSchema */}
643
+ {!detail.outputSchema && jsDoc.returns && (
644
+ <div>
645
+ <h4 className="mb-2 text-sm font-semibold text-muted-foreground">戻り値</h4>
646
+ <p className="text-sm">{jsDoc.returns}</p>
647
+ </div>
648
+ )}
649
+
650
+ {/* Throws */}
651
+ {jsDoc.throws && jsDoc.throws.length > 0 && (
652
+ <div>
653
+ <h4 className="mb-2 text-sm font-semibold text-muted-foreground">例外</h4>
654
+ <ul className="list-inside list-disc space-y-1 text-sm">
655
+ {jsDoc.throws.map((t, idx) => (
656
+ <li key={idx}>{t}</li>
657
+ ))}
658
+ </ul>
659
+ </div>
660
+ )}
661
+
662
+ {/* Examples - Parse markdown code fences and use CodeBlock */}
663
+ {jsDoc.examples && jsDoc.examples.length > 0 && (
664
+ <div>
665
+ <h4 className="mb-2 text-sm font-semibold text-muted-foreground">使用例</h4>
666
+ <div className="space-y-3">
667
+ {jsDoc.examples.map((example, idx) => {
668
+ const { language, code } = parseMarkdownCodeFence(example);
669
+ return (
670
+ <CodeBlock key={idx} code={code} language={language} />
671
+ );
672
+ })}
673
+ </div>
674
+ </div>
675
+ )}
676
+
677
+ {/* Enhanced Tags Section */}
678
+ {jsDoc.tags && jsDoc.tags.length > 0 && (
679
+ <EnhancedTagsSection
680
+ tags={jsDoc.tags}
681
+ moduleName={detail.moduleName}
682
+ lookupModule={lookupModule}
683
+ />
684
+ )}
685
+ </div>
686
+ );
687
+ }
688
+
689
+ // Source Code Section
690
+ function SourceCodeSection({ sourceCode }: { sourceCode: string }) {
691
+ return (
692
+ <div className="space-y-4">
693
+ <h4 className="text-sm font-semibold text-muted-foreground">ソースコード</h4>
694
+ <div className="max-h-[600px] overflow-auto">
695
+ <CodeBlock code={sourceCode} language="typescript" />
696
+ </div>
697
+ </div>
698
+ );
699
+ }
700
+
701
+ // BDD Section Component for individual test
702
+ function BddDisplay({ bdd }: { bdd: { given?: string; when?: string; then?: string; and?: string[] } }) {
703
+ const bddColors = {
704
+ given: "border-l-blue-500 bg-blue-50 dark:bg-blue-950/30",
705
+ when: "border-l-amber-500 bg-amber-50 dark:bg-amber-950/30",
706
+ then: "border-l-green-500 bg-green-50 dark:bg-green-950/30",
707
+ and: "border-l-gray-400 bg-gray-50 dark:bg-gray-950/30",
708
+ };
709
+ const labelColors = {
710
+ given: "text-blue-600 dark:text-blue-400",
711
+ when: "text-amber-600 dark:text-amber-400",
712
+ then: "text-green-600 dark:text-green-400",
713
+ and: "text-gray-600 dark:text-gray-400",
714
+ };
715
+
716
+ return (
717
+ <div className="space-y-1 mt-2">
718
+ {bdd.given && (
719
+ <div className={`border-l-4 ${bddColors.given} rounded-r px-2 py-1`}>
720
+ <span className={`text-xs font-bold uppercase ${labelColors.given}`}>Given</span>
721
+ <p className="text-xs">{bdd.given}</p>
722
+ </div>
723
+ )}
724
+ {bdd.when && (
725
+ <div className={`border-l-4 ${bddColors.when} rounded-r px-2 py-1`}>
726
+ <span className={`text-xs font-bold uppercase ${labelColors.when}`}>When</span>
727
+ <p className="text-xs">{bdd.when}</p>
728
+ </div>
729
+ )}
730
+ {bdd.then && (
731
+ <div className={`border-l-4 ${bddColors.then} rounded-r px-2 py-1`}>
732
+ <span className={`text-xs font-bold uppercase ${labelColors.then}`}>Then</span>
733
+ <p className="text-xs">{bdd.then}</p>
734
+ </div>
735
+ )}
736
+ {bdd.and?.map((andItem, idx) => (
737
+ <div key={idx} className={`border-l-4 ${bddColors.and} rounded-r px-2 py-1`}>
738
+ <span className={`text-xs font-bold uppercase ${labelColors.and}`}>And</span>
739
+ <p className="text-xs">{andItem}</p>
740
+ </div>
741
+ ))}
742
+ </div>
743
+ );
744
+ }
745
+
746
+ // Test Coverage Section
747
+ function TestCoverageSection({ detail }: { detail: DetailItem }) {
748
+ const { testCoverage } = detail;
749
+
750
+ if (!testCoverage || !testCoverage.hasTest) {
751
+ return (
752
+ <div className="space-y-4">
753
+ <div className="rounded-lg border border-yellow-500/30 bg-yellow-500/10 p-4">
754
+ <div className="flex items-center gap-2">
755
+ <AlertTriangle className="h-5 w-5 text-yellow-500" />
756
+ <span className="font-medium text-yellow-600">テストがありません</span>
757
+ </div>
758
+ {testCoverage?.recommendations && testCoverage.recommendations.length > 0 && (
759
+ <ul className="mt-2 list-inside list-disc text-sm text-muted-foreground">
760
+ {testCoverage.recommendations.map((rec, idx) => (
761
+ <li key={idx}>{rec}</li>
762
+ ))}
763
+ </ul>
764
+ )}
765
+ </div>
766
+ </div>
767
+ );
768
+ }
769
+
770
+ return (
771
+ <div className="space-y-6">
772
+ <CoverageScoreBar score={testCoverage.coverageScore || 0} />
773
+
774
+ <div className="grid gap-4 sm:grid-cols-2">
775
+ <div className="rounded-lg border p-4">
776
+ <div className="text-2xl font-bold">{testCoverage.totalTests || 0}</div>
777
+ <div className="text-sm text-muted-foreground">総テスト数</div>
778
+ </div>
779
+ <div className="rounded-lg border p-4">
780
+ <div className="text-2xl font-bold">{Object.keys(testCoverage.byCategory || {}).length}</div>
781
+ <div className="text-sm text-muted-foreground">カテゴリ数</div>
782
+ </div>
783
+ </div>
784
+
785
+ {/* Tests by Category with BDD display */}
786
+ <div className="space-y-4">
787
+ <h4 className="text-sm font-semibold text-muted-foreground">カテゴリ別テスト</h4>
788
+ {Object.entries(testCoverage.byCategory || {}).map(([category, tests]) => {
789
+ const catConfig = categoryLabels[category] || categoryLabels["other"];
790
+
791
+ return (
792
+ <Collapsible key={category} defaultOpen={tests.length <= 5}>
793
+ <CollapsibleTrigger className="flex w-full items-center justify-between rounded-lg border p-3 hover:bg-muted/50">
794
+ <div className="flex items-center gap-2">
795
+ <div className={`h-2 w-2 rounded-full ${catConfig.color}`} />
796
+ <span className="font-medium">{catConfig.label}</span>
797
+ <Badge variant="secondary" className="text-xs">
798
+ {tests.length}
799
+ </Badge>
800
+ </div>
801
+ <ChevronRight className="h-4 w-4 transition-transform [[data-state=open]_&]:rotate-90" />
802
+ </CollapsibleTrigger>
803
+ <CollapsibleContent className="mt-2 space-y-3 pl-4">
804
+ {tests.map((test, idx) => (
805
+ <Link
806
+ key={idx}
807
+ href={`/test-cases/${encodeFilePath(test.file)}/${test.line}`}
808
+ className="block rounded-lg border p-3 hover:bg-muted/30 transition-colors group"
809
+ >
810
+ <div className="flex items-start gap-2">
811
+ <TestTube2 className="mt-0.5 h-4 w-4 text-muted-foreground flex-shrink-0" />
812
+ <div className="flex-1 min-w-0">
813
+ <p className="font-medium text-sm group-hover:text-primary transition-colors">{test.name}</p>
814
+ {test.summary && (
815
+ <p className="text-xs text-muted-foreground mt-1">{test.summary}</p>
816
+ )}
817
+ {test.purpose && (
818
+ <p className="text-xs text-muted-foreground mt-1">
819
+ <span className="font-medium">目的:</span> {test.purpose}
820
+ </p>
821
+ )}
822
+ {test.expected && (
823
+ <p className="text-xs text-muted-foreground mt-1">
824
+ <span className="font-medium">期待結果:</span> {test.expected}
825
+ </p>
826
+ )}
827
+ {/* BDD Display */}
828
+ {test.bdd && (test.bdd.given || test.bdd.when || test.bdd.then) && (
829
+ <BddDisplay bdd={test.bdd} />
830
+ )}
831
+ {/* File Link */}
832
+ <div className="mt-2 flex items-center gap-2 text-xs text-muted-foreground">
833
+ <FileCode className="h-3 w-3" />
834
+ <span className="truncate">{test.file}:{test.line}</span>
835
+ </div>
836
+ </div>
837
+ </div>
838
+ </Link>
839
+ ))}
840
+ </CollapsibleContent>
841
+ </Collapsible>
842
+ );
843
+ })}
844
+ </div>
845
+
846
+ {/* Recommendations */}
847
+ {testCoverage.recommendations && testCoverage.recommendations.length > 0 && (
848
+ <div className="rounded-lg border border-yellow-500/30 bg-yellow-500/10 p-4">
849
+ <h4 className="mb-2 flex items-center gap-2 font-medium text-yellow-600">
850
+ <Info className="h-4 w-4" />
851
+ 推奨事項
852
+ </h4>
853
+ <ul className="list-inside list-disc space-y-1 text-sm text-muted-foreground">
854
+ {testCoverage.recommendations.map((rec, idx) => (
855
+ <li key={idx}>{rec}</li>
856
+ ))}
857
+ </ul>
858
+ </div>
859
+ )}
860
+ </div>
861
+ );
862
+ }
863
+
864
+ // Related Items Section
865
+ function RelatedItemsSection({
866
+ detail,
867
+ config,
868
+ lookupModule
869
+ }: {
870
+ detail: DetailItem;
871
+ config: LayerConfig;
872
+ lookupModule?: ItemLookupFn;
873
+ }) {
874
+ const { related } = detail;
875
+
876
+ const hasRelated =
877
+ (related.usedInScreens?.length || 0) +
878
+ (related.usedInComponents?.length || 0) +
879
+ (related.usedInActions?.length || 0) +
880
+ (related.dbTables?.length || 0) > 0;
881
+
882
+ if (!hasRelated) {
883
+ return (
884
+ <div className="text-center text-muted-foreground">
885
+ 関連アイテムはありません
886
+ </div>
887
+ );
888
+ }
889
+
890
+ return (
891
+ <div className="space-y-6">
892
+ {/* Used in Screens */}
893
+ {related.usedInScreens && related.usedInScreens.length > 0 && (
894
+ <div>
895
+ <h4 className="mb-2 flex items-center gap-2 text-sm font-semibold text-muted-foreground">
896
+ <Monitor className="h-4 w-4 text-accent-blue" />
897
+ 使用している画面
898
+ </h4>
899
+ <div className="flex flex-wrap gap-2">
900
+ {related.usedInScreens.map((screen, idx) => {
901
+ const targetModule = lookupModule?.("screens", screen);
902
+ if (targetModule) {
903
+ return (
904
+ <Link
905
+ key={idx}
906
+ href={`/details/screens/${encodeURIComponent(targetModule)}/${encodeURIComponent(screen)}`}
907
+ >
908
+ <Badge variant="outline" className="text-xs hover:bg-muted cursor-pointer transition-colors">
909
+ {screen}
910
+ </Badge>
911
+ </Link>
912
+ );
913
+ }
914
+ return (
915
+ <Badge key={idx} variant="outline" className="text-xs text-muted-foreground">
916
+ {screen}
917
+ </Badge>
918
+ );
919
+ })}
920
+ </div>
921
+ </div>
922
+ )}
923
+
924
+ {/* Used in Components */}
925
+ {related.usedInComponents && related.usedInComponents.length > 0 && (
926
+ <div>
927
+ <h4 className="mb-2 flex items-center gap-2 text-sm font-semibold text-muted-foreground">
928
+ <Component className="h-4 w-4 text-accent-green" />
929
+ 使用しているコンポーネント
930
+ </h4>
931
+ <div className="flex flex-wrap gap-2">
932
+ {related.usedInComponents.map((comp, idx) => {
933
+ const targetModule = lookupModule?.("components", comp);
934
+ if (targetModule) {
935
+ return (
936
+ <Link
937
+ key={idx}
938
+ href={`/details/components/${encodeURIComponent(targetModule)}/${encodeURIComponent(comp)}`}
939
+ >
940
+ <Badge variant="outline" className="text-xs hover:bg-muted cursor-pointer transition-colors">
941
+ {comp}
942
+ </Badge>
943
+ </Link>
944
+ );
945
+ }
946
+ return (
947
+ <Badge key={idx} variant="outline" className="text-xs text-muted-foreground">
948
+ {comp}
949
+ </Badge>
950
+ );
951
+ })}
952
+ </div>
953
+ </div>
954
+ )}
955
+
956
+ {/* Used in Actions */}
957
+ {related.usedInActions && related.usedInActions.length > 0 && (
958
+ <div>
959
+ <h4 className="mb-2 flex items-center gap-2 text-sm font-semibold text-muted-foreground">
960
+ <Zap className="h-4 w-4 text-accent-yellow" />
961
+ 使用しているアクション
962
+ </h4>
963
+ <div className="flex flex-wrap gap-2">
964
+ {related.usedInActions.map((action, idx) => {
965
+ const targetModule = lookupModule?.("actions", action);
966
+ if (targetModule) {
967
+ return (
968
+ <Link
969
+ key={idx}
970
+ href={`/details/actions/${encodeURIComponent(targetModule)}/${encodeURIComponent(action)}`}
971
+ >
972
+ <Badge variant="outline" className="text-xs hover:bg-muted cursor-pointer transition-colors">
973
+ {action}
974
+ </Badge>
975
+ </Link>
976
+ );
977
+ }
978
+ return (
979
+ <Badge key={idx} variant="outline" className="text-xs text-muted-foreground">
980
+ {action}
981
+ </Badge>
982
+ );
983
+ })}
984
+ </div>
985
+ </div>
986
+ )}
987
+
988
+ {/* Uses DB Tables */}
989
+ {related.dbTables && related.dbTables.length > 0 && (
990
+ <div>
991
+ <h4 className="mb-2 flex items-center gap-2 text-sm font-semibold text-muted-foreground">
992
+ <Database className="h-4 w-4 text-accent-purple" />
993
+ 使用しているテーブル
994
+ </h4>
995
+ <div className="flex flex-wrap gap-2">
996
+ {related.dbTables.map((table, idx) => {
997
+ const targetModule = lookupModule?.("tables", table);
998
+ if (targetModule) {
999
+ return (
1000
+ <Link
1001
+ key={idx}
1002
+ href={`/details/tables/${encodeURIComponent(targetModule)}/${encodeURIComponent(table)}`}
1003
+ >
1004
+ <Badge variant="outline" className="text-xs hover:bg-muted cursor-pointer transition-colors">
1005
+ {table}
1006
+ </Badge>
1007
+ </Link>
1008
+ );
1009
+ }
1010
+ return (
1011
+ <Badge key={idx} variant="outline" className="text-xs text-muted-foreground">
1012
+ {table}
1013
+ </Badge>
1014
+ );
1015
+ })}
1016
+ </div>
1017
+ </div>
1018
+ )}
1019
+ </div>
1020
+ );
1021
+ }
1022
+
1023
+ function getModuleItems(
1024
+ data: FeatureMapData,
1025
+ module: string,
1026
+ type: LayerType
1027
+ ): (ScreenItem | ComponentItem | ActionItem | TableItem)[] {
1028
+ if (module === "Uncategorized") {
1029
+ return data.uncategorized[type] || [];
1030
+ }
1031
+ return data.features[module]?.[type] || [];
1032
+ }
1033
+
1034
+ export default async function ItemDetailPage({
1035
+ params,
1036
+ }: {
1037
+ params: Promise<{ type: string; module: string; item: string }>;
1038
+ }) {
1039
+ const { type, module, item } = await params;
1040
+ const decodedModule = decodeURIComponent(module);
1041
+ const decodedItem = decodeURIComponent(item);
1042
+
1043
+ const featureMapData = await loadFeatureMap();
1044
+ const detailsData = await loadDetails();
1045
+
1046
+ if (!featureMapData) {
1047
+ notFound();
1048
+ }
1049
+
1050
+ // Build lookup function for cross-module linking
1051
+ const lookupModule = buildItemModuleLookup(featureMapData);
1052
+
1053
+ const layerType = type as LayerType;
1054
+ if (!layerConfigs[layerType]) {
1055
+ notFound();
1056
+ }
1057
+
1058
+ const config = layerConfigs[layerType];
1059
+ const Icon = config.icon;
1060
+
1061
+ // Get all items in this module
1062
+ const items = getModuleItems(featureMapData, decodedModule, layerType);
1063
+ const foundItem = items.find((i) => i.name === decodedItem);
1064
+
1065
+ if (!foundItem) {
1066
+ notFound();
1067
+ }
1068
+
1069
+ // Get detail from details.json
1070
+ const getDetailForItem = (itemName: string): DetailItem | null => {
1071
+ if (!detailsData) return null;
1072
+
1073
+ // First try exact key match (type/module/name)
1074
+ const exactKey = `${config.singular}/${decodedModule}/${itemName}`;
1075
+ if (detailsData.details[exactKey]) {
1076
+ return detailsData.details[exactKey];
1077
+ }
1078
+
1079
+ // Search by item name across all modules
1080
+ const prefix = `${config.singular}/`;
1081
+ const suffix = `/${itemName}`;
1082
+
1083
+ for (const [key, detail] of Object.entries(detailsData.details)) {
1084
+ if (key.startsWith(prefix) && key.endsWith(suffix)) {
1085
+ return detail;
1086
+ }
1087
+ }
1088
+
1089
+ return null;
1090
+ };
1091
+
1092
+ const detail = getDetailForItem(decodedItem);
1093
+
1094
+ return (
1095
+ <div className="space-y-8">
1096
+ {/* Breadcrumb */}
1097
+ <div className="flex items-center gap-2 text-sm">
1098
+ <Link
1099
+ href="/feature-map"
1100
+ className="flex items-center gap-1 text-muted-foreground hover:text-primary"
1101
+ >
1102
+ <ArrowLeft className="h-4 w-4" />
1103
+ Feature Map
1104
+ </Link>
1105
+ <span className="text-muted-foreground">/</span>
1106
+ <span className="text-muted-foreground">{config.label}</span>
1107
+ <span className="text-muted-foreground">/</span>
1108
+ <Link
1109
+ href={`/details/${type}/${module}`}
1110
+ className="text-muted-foreground hover:text-primary"
1111
+ >
1112
+ {decodedModule}
1113
+ </Link>
1114
+ <span className="text-muted-foreground">/</span>
1115
+ <span className="font-medium">{decodedItem}</span>
1116
+ </div>
1117
+
1118
+ {/* Header */}
1119
+ <header className="flex items-start gap-4">
1120
+ <div className={`rounded-lg p-3 ${config.bgColor}`}>
1121
+ <Icon className={`h-8 w-8 ${config.color}`} />
1122
+ </div>
1123
+ <div className="flex-1">
1124
+ <h1 className="text-3xl font-bold tracking-tight">{decodedItem}</h1>
1125
+ <div className="mt-3 flex flex-wrap items-center gap-2">
1126
+ {/* Auth Level Badge */}
1127
+ {detail?.authLevel && <AuthLevelBadge level={detail.authLevel} />}
1128
+
1129
+ {/* Rate Limit Badge */}
1130
+ {detail?.rateLimit && (
1131
+ <Badge variant="outline" className="text-xs text-orange-600 bg-orange-500/10 border-orange-500/30">
1132
+ <Clock className="mr-1 h-3 w-3" />
1133
+ {detail.rateLimit}
1134
+ </Badge>
1135
+ )}
1136
+
1137
+ {/* CSRF Badge */}
1138
+ {detail?.csrfProtection && (
1139
+ <Badge variant="outline" className="text-xs text-cyan-600 bg-cyan-500/10 border-cyan-500/30">
1140
+ <Shield className="mr-1 h-3 w-3" />
1141
+ CSRF Protected
1142
+ </Badge>
1143
+ )}
1144
+
1145
+ {/* Test Coverage Badges */}
1146
+ {detail?.testCoverage && (
1147
+ <>
1148
+ <Badge
1149
+ variant={detail.testCoverage.coverageScore >= 70 ? "default" : "secondary"}
1150
+ >
1151
+ {detail.testCoverage.totalTests} tests
1152
+ </Badge>
1153
+ <Badge
1154
+ variant="outline"
1155
+ className={
1156
+ detail.testCoverage.coverageScore >= 70
1157
+ ? "border-green-500 text-green-600"
1158
+ : detail.testCoverage.coverageScore >= 40
1159
+ ? "border-yellow-500 text-yellow-600"
1160
+ : "border-red-500 text-red-600"
1161
+ }
1162
+ >
1163
+ {detail.testCoverage.coverageScore}%
1164
+ </Badge>
1165
+ </>
1166
+ )}
1167
+
1168
+ {/* App Badge */}
1169
+ {foundItem.app && (
1170
+ <Badge
1171
+ variant="outline"
1172
+ className={`text-xs ${
1173
+ foundItem.app === "Admin"
1174
+ ? "bg-blue-500/10 text-blue-600 border-blue-500/30"
1175
+ : foundItem.app === "Public"
1176
+ ? "bg-green-500/10 text-green-600 border-green-500/30"
1177
+ : foundItem.app === "Web"
1178
+ ? "bg-purple-500/10 text-purple-600 border-purple-500/30"
1179
+ : "bg-gray-500/10 text-gray-600 border-gray-500/30"
1180
+ }`}
1181
+ >
1182
+ <AppWindow className="mr-1 h-3 w-3" />
1183
+ {foundItem.app}
1184
+ </Badge>
1185
+ )}
1186
+
1187
+ {/* Module Badge */}
1188
+ <Badge variant="outline" className="text-xs">
1189
+ {decodedModule}
1190
+ </Badge>
1191
+ </div>
1192
+ </div>
1193
+ </header>
1194
+
1195
+ {/* Main Content */}
1196
+ {detail ? (
1197
+ <ItemTabsClient
1198
+ overviewContent={
1199
+ <Card>
1200
+ <CardContent className="pt-6 space-y-8">
1201
+ {/* File Path */}
1202
+ <div className="flex items-center gap-2 text-sm text-muted-foreground">
1203
+ <FileCode className="h-4 w-4" />
1204
+ <code className="truncate">{detail.filePath}</code>
1205
+ </div>
1206
+
1207
+ {/* Enhanced Parameters Table (from Zod schema) */}
1208
+ {detail.inputSchema?.parameters && (
1209
+ <EnhancedParametersTable parameters={detail.inputSchema.parameters} />
1210
+ )}
1211
+
1212
+ {/* Output Schema */}
1213
+ {detail.outputSchema && (
1214
+ <div>
1215
+ <h4 className="mb-2 text-sm font-semibold text-muted-foreground">戻り値</h4>
1216
+ <div className="rounded-md bg-muted p-3">
1217
+ <code className="text-sm">{detail.outputSchema.type}</code>
1218
+ {detail.outputSchema.successType && (
1219
+ <p className="mt-1 text-xs text-muted-foreground">
1220
+ 成功時: <code>{detail.outputSchema.successType}</code>
1221
+ </p>
1222
+ )}
1223
+ {detail.outputSchema.errorType && (
1224
+ <p className="mt-1 text-xs text-muted-foreground">
1225
+ エラー時: <code>{detail.outputSchema.errorType}</code>
1226
+ </p>
1227
+ )}
1228
+ </div>
1229
+ </div>
1230
+ )}
1231
+
1232
+ {/* Error Codes */}
1233
+ {detail.errorCodes && detail.errorCodes.length > 0 && (
1234
+ <ErrorCodesSection errorCodes={detail.errorCodes} />
1235
+ )}
1236
+
1237
+ {/* JSDoc Section */}
1238
+ <JSDocSection detail={detail} lookupModule={lookupModule} />
1239
+ </CardContent>
1240
+ </Card>
1241
+ }
1242
+ codeContent={
1243
+ <Card>
1244
+ <CardContent className="pt-6">
1245
+ <SourceCodeSection sourceCode={detail.sourceCode} />
1246
+ </CardContent>
1247
+ </Card>
1248
+ }
1249
+ testsContent={
1250
+ <Card>
1251
+ <CardContent className="pt-6">
1252
+ <TestCoverageSection detail={detail} />
1253
+ </CardContent>
1254
+ </Card>
1255
+ }
1256
+ relatedContent={
1257
+ <Card>
1258
+ <CardContent className="pt-6">
1259
+ <RelatedItemsSection detail={detail} config={config} lookupModule={lookupModule} />
1260
+ </CardContent>
1261
+ </Card>
1262
+ }
1263
+ />
1264
+ ) : (
1265
+ <Card>
1266
+ <CardContent className="pt-6">
1267
+ <div className="text-center text-muted-foreground">
1268
+ 詳細情報はありません
1269
+ </div>
1270
+ </CardContent>
1271
+ </Card>
1272
+ )}
1273
+
1274
+ {/* Navigation */}
1275
+ <div className="flex justify-between pt-4 border-t">
1276
+ <Link
1277
+ href={`/details/${type}/${module}`}
1278
+ className="flex items-center gap-2 text-sm text-muted-foreground hover:text-primary"
1279
+ >
1280
+ <ArrowLeft className="h-4 w-4" />
1281
+ {decodedModule} の一覧に戻る
1282
+ </Link>
1283
+ </div>
1284
+ </div>
1285
+ );
1286
+ }