@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,1181 @@
1
+ import { promises as fs } from "fs";
2
+ import path from "path";
3
+
4
+ /**
5
+ * GitHub Data Types (from github-data.json)
6
+ */
7
+ export interface GithubIssue {
8
+ number: number;
9
+ title: string;
10
+ url: string;
11
+ state: string;
12
+ labels: string[];
13
+ status: string | null;
14
+ priority: string | null;
15
+ type: string | null;
16
+ size: string | null;
17
+ createdAt: string;
18
+ updatedAt: string;
19
+ }
20
+
21
+ export interface GithubDiscussion {
22
+ number: number;
23
+ title: string;
24
+ url: string;
25
+ category: string;
26
+ author: string;
27
+ createdAt: string;
28
+ updatedAt: string;
29
+ body?: string;
30
+ }
31
+
32
+ export interface GithubRepoInfo {
33
+ owner: string;
34
+ name: string;
35
+ fullName: string;
36
+ description: string | null;
37
+ url: string;
38
+ defaultBranch: string;
39
+ visibility: string;
40
+ stargazers: number;
41
+ forks: number;
42
+ issues: number;
43
+ pullRequests: number;
44
+ }
45
+
46
+ export interface GithubData {
47
+ repository: GithubRepoInfo;
48
+ issues: {
49
+ inProgress: GithubIssue[];
50
+ ready: GithubIssue[];
51
+ backlog: GithubIssue[];
52
+ icebox: GithubIssue[];
53
+ done: GithubIssue[];
54
+ total: number;
55
+ };
56
+ handovers: GithubDiscussion[];
57
+ specs: GithubDiscussion[];
58
+ fetchedAt: string;
59
+ }
60
+
61
+ import type {
62
+ TestCasesData,
63
+ FeatureMapData,
64
+ DbSchemaData,
65
+ DatabaseInfo,
66
+ LinkedDocsData,
67
+ PortalConfig,
68
+ DetailsData,
69
+ DetailItem,
70
+ ApplicationsData,
71
+ ApiToolsData,
72
+ AppConfig,
73
+ AppStats,
74
+ AppType,
75
+ ApiProtocol,
76
+ SectionType,
77
+ I18nData,
78
+ PackagesData,
79
+ PackageInfo,
80
+ } from "./types";
81
+ import type { SearchIndex } from "./search";
82
+ import { generateSearchIndex } from "./search-index-generator";
83
+
84
+ /**
85
+ * Configuration-based application definition (from shirokuma-docs.config.yaml)
86
+ */
87
+ interface ConfiguredApplication {
88
+ id: string;
89
+ type: AppType;
90
+ name: string;
91
+ description?: string;
92
+ source?: string;
93
+ icon?: string;
94
+ color?: string;
95
+ protocol?: ApiProtocol;
96
+ toolsFile?: string;
97
+ sections?: Array<{
98
+ type: SectionType;
99
+ label?: string;
100
+ icon?: string;
101
+ filter?: { paths?: string[] };
102
+ }>;
103
+ dbTables?: string[];
104
+ tests?: { match: string[] };
105
+ }
106
+
107
+ /**
108
+ * Get the project root directory (where OVERVIEW.md might be)
109
+ */
110
+ function getProjectRoot(): string {
111
+ return process.env.PROJECT_ROOT || "./";
112
+ }
113
+
114
+ /**
115
+ * Load overview markdown content
116
+ */
117
+ export async function loadOverview(): Promise<{ content: string; title: string } | null> {
118
+ const projectRoot = getProjectRoot();
119
+ const possiblePaths = [
120
+ path.join(projectRoot, "docs", "OVERVIEW.md"),
121
+ path.join(projectRoot, "OVERVIEW.md"),
122
+ path.join(projectRoot, "README.md"),
123
+ ];
124
+
125
+ for (const filePath of possiblePaths) {
126
+ try {
127
+ const content = await fs.readFile(filePath, "utf-8");
128
+ // Extract title from first h1
129
+ const titleMatch = content.match(/^#\s+(.+)$/m);
130
+ const title = titleMatch ? titleMatch[1] : "Overview";
131
+ return { content, title };
132
+ } catch {
133
+ // Try next path
134
+ }
135
+ }
136
+
137
+ // Try from data directory as fallback
138
+ try {
139
+ const dataPath = path.join(getDataDir(), "overview.md");
140
+ const content = await fs.readFile(dataPath, "utf-8");
141
+ const titleMatch = content.match(/^#\s+(.+)$/m);
142
+ const title = titleMatch ? titleMatch[1] : "Overview";
143
+ return { content, title };
144
+ } catch {
145
+ return null;
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Get the data directory path from environment or default
151
+ */
152
+ function getDataDir(): string {
153
+ if (process.env.PORTAL_DATA_DIR) {
154
+ return process.env.PORTAL_DATA_DIR;
155
+ }
156
+ // Use absolute path relative to project root
157
+ return path.join(process.cwd(), "data");
158
+ }
159
+
160
+ /**
161
+ * Read and parse a JSON file
162
+ */
163
+ async function readJsonFile<T>(filename: string): Promise<T | null> {
164
+ try {
165
+ const filePath = path.join(getDataDir(), filename);
166
+ const content = await fs.readFile(filePath, "utf-8");
167
+ return JSON.parse(content) as T;
168
+ } catch {
169
+ console.warn(`Failed to load ${filename}`);
170
+ return null;
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Check if a file exists
176
+ */
177
+ async function fileExists(filename: string): Promise<boolean> {
178
+ try {
179
+ const filePath = path.join(getDataDir(), filename);
180
+ await fs.access(filePath);
181
+ return true;
182
+ } catch {
183
+ return false;
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Load test cases data
189
+ */
190
+ export async function loadTestCases(): Promise<TestCasesData | null> {
191
+ return readJsonFile<TestCasesData>("test-cases.json");
192
+ }
193
+
194
+ /**
195
+ * Load feature map data
196
+ */
197
+ export async function loadFeatureMap(): Promise<FeatureMapData | null> {
198
+ return readJsonFile<FeatureMapData>("feature-map.json");
199
+ }
200
+
201
+ /**
202
+ * Load database schema data
203
+ *
204
+ * @param dbName - Database name (required for filtering by specific DB)
205
+ * If provided, returns only that database's tables
206
+ * If not provided, returns all tables
207
+ */
208
+ export async function loadDbSchema(dbName?: string): Promise<DbSchemaData | null> {
209
+ const data = await readJsonFile<DbSchemaData>("db-schema.json");
210
+ if (!data) return null;
211
+
212
+ // If no specific DB requested, return all data
213
+ if (!dbName) return data;
214
+
215
+ // Filter tables for the specific database
216
+ const filteredTables = data.tables.filter((t) => t.database === dbName);
217
+
218
+ // Find the database info
219
+ const dbInfo = data.databases?.find((db) => db.name === dbName);
220
+
221
+ return {
222
+ databases: dbInfo ? [dbInfo] : undefined,
223
+ tables: filteredTables,
224
+ generatedAt: data.generatedAt,
225
+ };
226
+ }
227
+
228
+ /**
229
+ * Get list of databases
230
+ * Always returns at least one database (default "database" if not specified)
231
+ */
232
+ export async function getDbList(): Promise<DatabaseInfo[]> {
233
+ const data = await readJsonFile<DbSchemaData>("db-schema.json");
234
+ if (!data) return [];
235
+
236
+ // If databases array exists, return it
237
+ if (data.databases && data.databases.length > 0) {
238
+ return data.databases;
239
+ }
240
+
241
+ // Fallback for old format without databases array
242
+ // Create a single "database" entry
243
+ return [{
244
+ name: "database",
245
+ tableCount: data.tables.length,
246
+ }];
247
+ }
248
+
249
+ /**
250
+ * Load linked docs data
251
+ */
252
+ export async function loadLinkedDocs(): Promise<LinkedDocsData | null> {
253
+ return readJsonFile<LinkedDocsData>("linked-docs.json");
254
+ }
255
+
256
+ /**
257
+ * Load details data (generated by details command)
258
+ */
259
+ export async function loadDetails(): Promise<DetailsData | null> {
260
+ return readJsonFile<DetailsData>("details.json");
261
+ }
262
+
263
+ /**
264
+ * Load MCP tools data
265
+ */
266
+ export async function loadApiTools(): Promise<ApiToolsData | null> {
267
+ return readJsonFile<ApiToolsData>("api-tools.json");
268
+ }
269
+
270
+ /**
271
+ * Load i18n documentation data
272
+ */
273
+ export async function loadI18n(): Promise<I18nData | null> {
274
+ return readJsonFile<I18nData>("i18n.json");
275
+ }
276
+
277
+ /**
278
+ * Load packages data (monorepo shared packages)
279
+ */
280
+ export async function loadPackages(): Promise<PackagesData | null> {
281
+ return readJsonFile<PackagesData>("packages.json");
282
+ }
283
+
284
+ /**
285
+ * Load GitHub data (issues, discussions, repository info)
286
+ */
287
+ export async function loadGithubData(): Promise<GithubData | null> {
288
+ return readJsonFile<GithubData>("github-data.json");
289
+ }
290
+
291
+ /**
292
+ * Get list of all packages
293
+ */
294
+ export async function getPackageList(): Promise<PackageInfo[]> {
295
+ const data = await loadPackages();
296
+ return data?.packages ?? [];
297
+ }
298
+
299
+ /**
300
+ * Get a single package by name
301
+ */
302
+ export async function getPackage(name: string): Promise<PackageInfo | null> {
303
+ const data = await loadPackages();
304
+ if (!data) return null;
305
+ return data.packages.find((pkg) => pkg.name === name) ?? null;
306
+ }
307
+
308
+ /**
309
+ * Screenshot manifest entry
310
+ */
311
+ export interface ScreenshotEntry {
312
+ /** Screen name */
313
+ name: string;
314
+ /** File name (relative path within screenshots directory) */
315
+ fileName: string;
316
+ /** Route path */
317
+ route: string;
318
+ /** Description */
319
+ description?: string;
320
+ /** Source file path */
321
+ sourcePath?: string;
322
+ /** Account (for multi-account mode) */
323
+ account?: string;
324
+ /** Viewport size */
325
+ viewport?: { width: number; height: number };
326
+ }
327
+
328
+ /**
329
+ * Screenshot manifest data (per-app format)
330
+ */
331
+ export interface ScreenshotsData {
332
+ /** Generation timestamp */
333
+ generatedAt: string;
334
+ /** Configuration */
335
+ config: {
336
+ baseUrl: string;
337
+ viewport: { width: number; height: number };
338
+ outputDir: string;
339
+ };
340
+ /** Screenshots by screen name */
341
+ screenshots: Record<string, ScreenshotEntry>;
342
+ }
343
+
344
+ /**
345
+ * Multi-app screenshot index
346
+ */
347
+ export interface MultiAppScreenshotsIndex {
348
+ /** Generation timestamp */
349
+ generatedAt: string;
350
+ /** App IDs */
351
+ apps: string[];
352
+ /** Per-app manifests */
353
+ manifests: Record<string, ScreenshotsData>;
354
+ }
355
+
356
+ /**
357
+ * Load multi-app screenshots index
358
+ * Returns the combined index.json if available, otherwise null
359
+ */
360
+ export async function loadScreenshotsIndex(): Promise<MultiAppScreenshotsIndex | null> {
361
+ try {
362
+ const indexPath = path.join(getDataDir(), "screenshots", "index.json");
363
+ const content = await fs.readFile(indexPath, "utf-8");
364
+ return JSON.parse(content) as MultiAppScreenshotsIndex;
365
+ } catch {
366
+ return null;
367
+ }
368
+ }
369
+
370
+ /**
371
+ * Load screenshots manifest data for a specific app
372
+ * @param appId - App ID (e.g., "admin", "public")
373
+ * @returns Screenshots data for the app or null if not found
374
+ */
375
+ export async function loadScreenshotsForApp(appId: string): Promise<ScreenshotsData | null> {
376
+ try {
377
+ // Try app-specific path first
378
+ const appPath = path.join(getDataDir(), "screenshots", appId, "screenshots.json");
379
+ const content = await fs.readFile(appPath, "utf-8");
380
+ return JSON.parse(content) as ScreenshotsData;
381
+ } catch {
382
+ // Fall back to multi-app index
383
+ const index = await loadScreenshotsIndex();
384
+ if (index?.manifests[appId]) {
385
+ return index.manifests[appId];
386
+ }
387
+ return null;
388
+ }
389
+ }
390
+
391
+ /**
392
+ * Load screenshots manifest data (legacy single-app format or first available app)
393
+ * Screenshots manifest is copied to data/screenshots/ during portal build
394
+ */
395
+ export async function loadScreenshots(): Promise<ScreenshotsData | null> {
396
+ try {
397
+ // Try legacy format first
398
+ const screenshotsPath = path.join(getDataDir(), "screenshots", "screenshots.json");
399
+ const content = await fs.readFile(screenshotsPath, "utf-8");
400
+ return JSON.parse(content) as ScreenshotsData;
401
+ } catch {
402
+ // Fall back to multi-app index, return first app's data
403
+ const index = await loadScreenshotsIndex();
404
+ if (index && index.apps.length > 0) {
405
+ const firstAppId = index.apps[0];
406
+ return index.manifests[firstAppId] || null;
407
+ }
408
+ return null;
409
+ }
410
+ }
411
+
412
+ /**
413
+ * Get screenshot for a specific screen
414
+ * @param screenName - Name of the screen
415
+ * @param appId - Optional app ID to search in specific app
416
+ * @returns Screenshot entry or null if not found
417
+ */
418
+ export async function getScreenshotForScreen(
419
+ screenName: string,
420
+ appId?: string
421
+ ): Promise<{ entry: ScreenshotEntry; appId: string } | null> {
422
+ // If appId specified, search only in that app
423
+ if (appId) {
424
+ const data = await loadScreenshotsForApp(appId);
425
+ if (data?.screenshots[screenName]) {
426
+ return { entry: data.screenshots[screenName], appId };
427
+ }
428
+ return null;
429
+ }
430
+
431
+ // Search across all apps
432
+ const index = await loadScreenshotsIndex();
433
+ if (index) {
434
+ for (const app of index.apps) {
435
+ const manifest = index.manifests[app];
436
+ if (manifest?.screenshots[screenName]) {
437
+ return { entry: manifest.screenshots[screenName], appId: app };
438
+ }
439
+ }
440
+ }
441
+
442
+ // Fall back to legacy format
443
+ const data = await loadScreenshots();
444
+ if (data?.screenshots[screenName]) {
445
+ return { entry: data.screenshots[screenName], appId: "default" };
446
+ }
447
+
448
+ return null;
449
+ }
450
+
451
+ /**
452
+ * Get all available app IDs with screenshots
453
+ */
454
+ export async function getScreenshotAppIds(): Promise<string[]> {
455
+ const index = await loadScreenshotsIndex();
456
+ if (index) {
457
+ return index.apps;
458
+ }
459
+ // Legacy format - return empty or single default
460
+ const legacy = await loadScreenshots();
461
+ return legacy ? ["default"] : [];
462
+ }
463
+
464
+ /**
465
+ * Coverage report data structure from lint-coverage
466
+ */
467
+ export interface CoverageData {
468
+ results: Array<{
469
+ source: string;
470
+ test?: string;
471
+ testCount: number;
472
+ status: "covered" | "skipped" | "missing";
473
+ skipReason?: string;
474
+ }>;
475
+ orphans: Array<{
476
+ test: string;
477
+ expectedSource: string;
478
+ }>;
479
+ summary: {
480
+ totalSources: number;
481
+ coveredCount: number;
482
+ skippedCount: number;
483
+ missingCount: number;
484
+ orphanCount: number;
485
+ coveragePercent: number;
486
+ };
487
+ passed: boolean;
488
+ }
489
+
490
+ /**
491
+ * Load coverage data (from lint-coverage)
492
+ */
493
+ export async function loadCoverage(): Promise<CoverageData | null> {
494
+ return readJsonFile<CoverageData>("coverage.json");
495
+ }
496
+
497
+ /**
498
+ * Load applications configuration (or generate from available data)
499
+ */
500
+ export async function loadApplications(): Promise<ApplicationsData | null> {
501
+ // Try to load pre-configured applications.json first
502
+ const configured = await readJsonFile<ApplicationsData>("applications.json");
503
+ if (configured) {
504
+ return configured;
505
+ }
506
+
507
+ // Auto-generate from available data
508
+ return autoGenerateApplications();
509
+ }
510
+
511
+ /**
512
+ * Auto-generate applications data from available JSON files
513
+ */
514
+ async function autoGenerateApplications(): Promise<ApplicationsData> {
515
+ const [available, featureMap, testCases, dbSchema, mcpTools] = await Promise.all([
516
+ getAvailableData(),
517
+ loadFeatureMap(),
518
+ loadTestCases(),
519
+ loadDbSchema(),
520
+ loadApiTools(),
521
+ ]);
522
+
523
+ // Calculate web app stats
524
+ const webStats: AppStats = { screens: 0, components: 0, actions: 0, tests: 0 };
525
+ if (featureMap) {
526
+ for (const group of Object.values(featureMap.features)) {
527
+ webStats.screens! += group.screens?.length || 0;
528
+ webStats.components! += group.components?.length || 0;
529
+ webStats.actions! += group.actions?.length || 0;
530
+ }
531
+ webStats.screens! += featureMap.uncategorized.screens?.length || 0;
532
+ webStats.components! += featureMap.uncategorized.components?.length || 0;
533
+ webStats.actions! += featureMap.uncategorized.actions?.length || 0;
534
+ }
535
+
536
+ // Count web tests (non-MCP tests)
537
+ if (testCases) {
538
+ const mcpTestCount = testCases.testCases.filter((t) =>
539
+ t.file.includes("/mcp/") || t.file.includes("apps/mcp/")
540
+ ).length;
541
+ webStats.tests = testCases.summary.totalTests - mcpTestCount;
542
+ }
543
+
544
+ // Calculate MCP/API stats
545
+ const mcpStats: AppStats = {
546
+ tools: mcpTools?.summary?.totalTools || mcpTools?.tools?.length || 0,
547
+ tests:
548
+ testCases?.testCases.filter((t) =>
549
+ t.file.includes("/mcp/") || t.file.includes("apps/mcp/")
550
+ ).length || 0,
551
+ };
552
+
553
+ const apps: AppConfig[] = [];
554
+
555
+ // Add Web app if feature map exists
556
+ if (available.hasFeatureMap) {
557
+ apps.push({
558
+ id: "web",
559
+ name: "Web アプリ",
560
+ description: "メインアプリケーション",
561
+ type: "web",
562
+ icon: "globe",
563
+ color: "blue",
564
+ source: "apps/web",
565
+ stats: webStats,
566
+ sections: [{ type: "featureMap", label: "機能マップ", icon: "layers", available: true }],
567
+ });
568
+ }
569
+
570
+ // Add API app if API tools exist (MCP, REST, etc.)
571
+ if (available.hasApiTools) {
572
+ // Determine API type from tools data (could be extended to detect REST/GraphQL)
573
+ const apiProtocol = mcpTools?.protocol || "mcp";
574
+ const apiName = mcpTools?.name || "API Server";
575
+ const apiDescription = mcpTools?.description || "API ツール一覧";
576
+
577
+ apps.push({
578
+ id: "mcp", // Keep ID for backward compatibility
579
+ name: apiName,
580
+ description: apiDescription,
581
+ type: "api",
582
+ protocol: apiProtocol,
583
+ icon: "bot",
584
+ color: "purple",
585
+ source: "apps/mcp",
586
+ stats: mcpStats,
587
+ sections: [
588
+ {
589
+ type: "tools",
590
+ label: "ツール一覧",
591
+ icon: "wrench",
592
+ available: true,
593
+ count: mcpStats.tools,
594
+ },
595
+ ],
596
+ } as AppConfig);
597
+ }
598
+
599
+ // Calculate total tests
600
+ const totalTests = testCases?.summary.totalTests || 0;
601
+
602
+ return {
603
+ shared: {
604
+ sections: [
605
+ {
606
+ type: "overview",
607
+ label: "プロジェクト概要",
608
+ icon: "file-text",
609
+ available: available.hasOverview,
610
+ },
611
+ {
612
+ type: "dbSchema",
613
+ label: "データベーススキーマ",
614
+ icon: "database",
615
+ available: available.hasDbSchema,
616
+ count: dbSchema?.tables.length,
617
+ },
618
+ {
619
+ type: "testCases",
620
+ label: "テストケース",
621
+ icon: "check-circle",
622
+ available: available.hasTestCases,
623
+ count: totalTests,
624
+ },
625
+ ],
626
+ },
627
+ apps,
628
+ };
629
+ }
630
+
631
+ /**
632
+ * Get application by ID
633
+ */
634
+ export async function getApplicationById(appId: string): Promise<AppConfig | null> {
635
+ const apps = await loadApplications();
636
+ if (!apps) return null;
637
+ return apps.apps.find((app) => app.id === appId) || null;
638
+ }
639
+
640
+ /**
641
+ * Check if an application is an API type
642
+ */
643
+ export function isApiApplication(app: AppConfig): boolean {
644
+ return app.type === "api";
645
+ }
646
+
647
+ /**
648
+ * Get API protocol for an application (if it's an API type)
649
+ */
650
+ export function getApiProtocol(app: AppConfig): ApiProtocol | null {
651
+ if (app.type === "api" && "protocol" in app) {
652
+ return (app as { protocol: ApiProtocol }).protocol;
653
+ }
654
+ return null;
655
+ }
656
+
657
+ /**
658
+ * Get a specific detail item by key
659
+ * Key format: "{type}/{moduleName}/{name}" (e.g., "action/entities/getEntities")
660
+ */
661
+ export async function getDetailItem(key: string): Promise<DetailItem | null> {
662
+ const details = await loadDetails();
663
+ if (!details) return null;
664
+ return details.details[key] || null;
665
+ }
666
+
667
+ /**
668
+ * Find detail item by type, module, and name
669
+ */
670
+ export async function findDetailItem(
671
+ type: string,
672
+ moduleName: string,
673
+ name: string
674
+ ): Promise<DetailItem | null> {
675
+ const key = `${type}/${moduleName}/${name}`;
676
+ return getDetailItem(key);
677
+ }
678
+
679
+ /**
680
+ * Load portal configuration (from YAML config, converted to JSON)
681
+ */
682
+ export async function loadPortalConfig(): Promise<PortalConfig | null> {
683
+ return readJsonFile<PortalConfig>("portal-config.json");
684
+ }
685
+
686
+ /**
687
+ * Get project name from environment
688
+ */
689
+ export function getProjectName(): string {
690
+ return process.env.PROJECT_NAME || "Documentation";
691
+ }
692
+
693
+ /**
694
+ * Check if a screenshot manifest file exists
695
+ */
696
+ async function screenshotsExist(): Promise<boolean> {
697
+ try {
698
+ const screenshotsPath = path.join(getDataDir(), "screenshots", "screenshots.json");
699
+ await fs.access(screenshotsPath);
700
+ return true;
701
+ } catch {
702
+ return false;
703
+ }
704
+ }
705
+
706
+ /**
707
+ * Check available data files
708
+ */
709
+ export async function getAvailableData(): Promise<{
710
+ hasTestCases: boolean;
711
+ hasFeatureMap: boolean;
712
+ hasDbSchema: boolean;
713
+ hasOverview: boolean;
714
+ hasApiTools: boolean;
715
+ hasI18n: boolean;
716
+ hasScreenshots: boolean;
717
+ hasPackages: boolean;
718
+ hasGithubData: boolean;
719
+ }> {
720
+ const [hasTestCases, hasFeatureMap, hasDbSchema, hasApiTools, hasI18n, hasScreenshots, hasPackages, hasGithubData, overview] = await Promise.all([
721
+ fileExists("test-cases.json"),
722
+ fileExists("feature-map.json"),
723
+ fileExists("db-schema.json"),
724
+ fileExists("api-tools.json"),
725
+ fileExists("i18n.json"),
726
+ screenshotsExist(),
727
+ fileExists("packages.json"),
728
+ fileExists("github-data.json"),
729
+ loadOverview(),
730
+ ]);
731
+
732
+ return { hasTestCases, hasFeatureMap, hasDbSchema, hasApiTools, hasI18n, hasScreenshots, hasPackages, hasGithubData, hasOverview: overview !== null };
733
+ }
734
+
735
+ /**
736
+ * Get test case categories from data
737
+ */
738
+ export function getTestCategories(data: TestCasesData): string[] {
739
+ const categories = new Set<string>();
740
+ for (const tc of data.testCases) {
741
+ // Group by framework or custom category
742
+ if (tc.framework === "playwright") {
743
+ categories.add("e2e");
744
+ } else {
745
+ // Infer category from file path
746
+ if (tc.file.includes("/actions/") || tc.file.includes("__tests__/lib/actions/")) {
747
+ categories.add("server-actions");
748
+ } else if (tc.file.includes("/components/") || tc.file.includes("__tests__/components/")) {
749
+ categories.add("components");
750
+ } else {
751
+ categories.add("other");
752
+ }
753
+ }
754
+ }
755
+ return Array.from(categories).sort();
756
+ }
757
+
758
+ /**
759
+ * Get test files for a category
760
+ */
761
+ export function getTestFilesByCategory(
762
+ data: TestCasesData,
763
+ category: string
764
+ ): { file: string; tests: number; firstTest: import("./types").TestCase }[] {
765
+ const fileMap = new Map<string, { count: number; first: import("./types").TestCase }>();
766
+
767
+ for (const tc of data.testCases) {
768
+ let tcCategory: string;
769
+ if (tc.framework === "playwright") {
770
+ tcCategory = "e2e";
771
+ } else if (tc.file.includes("/actions/") || tc.file.includes("__tests__/lib/actions/")) {
772
+ tcCategory = "server-actions";
773
+ } else if (tc.file.includes("/components/") || tc.file.includes("__tests__/components/")) {
774
+ tcCategory = "components";
775
+ } else {
776
+ tcCategory = "other";
777
+ }
778
+
779
+ if (tcCategory === category) {
780
+ const existing = fileMap.get(tc.file);
781
+ if (existing) {
782
+ existing.count++;
783
+ } else {
784
+ fileMap.set(tc.file, { count: 1, first: tc });
785
+ }
786
+ }
787
+ }
788
+
789
+ return Array.from(fileMap.entries())
790
+ .map(([file, { count, first }]) => ({ file, tests: count, firstTest: first }))
791
+ .sort((a, b) => a.file.localeCompare(b.file));
792
+ }
793
+
794
+ /**
795
+ * Get tests for a specific file
796
+ */
797
+ export function getTestsByFile(data: TestCasesData, file: string): import("./types").TestCase[] {
798
+ return data.testCases.filter((tc) => tc.file === file);
799
+ }
800
+
801
+ /**
802
+ * Extract file slug from path
803
+ */
804
+ export function fileToSlug(file: string): string {
805
+ return path.basename(file).replace(/\.(test|spec)\.(ts|tsx|js)$/, "");
806
+ }
807
+
808
+ /**
809
+ * Convert category to URL slug
810
+ */
811
+ export function categoryToSlug(category: string): string {
812
+ return category.toLowerCase().replace(/\s+/g, "-");
813
+ }
814
+
815
+ /**
816
+ * Get test coverage for a feature item from details.json
817
+ * Returns coverage info if found in details, otherwise null
818
+ */
819
+ export async function getTestCoverageForItem(
820
+ type: string,
821
+ moduleName: string,
822
+ itemName: string
823
+ ): Promise<{
824
+ hasTest: boolean;
825
+ totalTests: number;
826
+ coverageScore: number;
827
+ } | null> {
828
+ const details = await loadDetails();
829
+ if (!details) return null;
830
+
831
+ // Try different key patterns (details.json uses various formats)
832
+ const possibleKeys = [
833
+ `${type}/${moduleName}/${itemName}`,
834
+ `${type.toLowerCase()}/${moduleName}/${itemName}`,
835
+ ];
836
+
837
+ for (const key of possibleKeys) {
838
+ const item = details.details[key];
839
+ if (item?.testCoverage) {
840
+ return {
841
+ hasTest: item.testCoverage.hasTest,
842
+ totalTests: item.testCoverage.totalTests,
843
+ coverageScore: item.testCoverage.coverageScore,
844
+ };
845
+ }
846
+ }
847
+
848
+ return null;
849
+ }
850
+
851
+ /**
852
+ * Extract file module from item path
853
+ * e.g., "apps/web/lib/actions/projects.ts" -> "projects"
854
+ */
855
+ function extractFileModule(itemPath: string | undefined): string | null {
856
+ if (!itemPath) return null;
857
+ const fileName = itemPath.split("/").pop();
858
+ if (!fileName) return null;
859
+ return fileName.replace(/\.(ts|tsx)$/, "");
860
+ }
861
+
862
+ /**
863
+ * Get aggregated test coverage for a module
864
+ * Sums up coverage from all items in the module
865
+ */
866
+ export async function getModuleTestCoverage(
867
+ moduleName: string
868
+ ): Promise<{
869
+ totalTests: number;
870
+ testedItems: number;
871
+ totalItems: number;
872
+ averageCoverage: number;
873
+ }> {
874
+ const [details, featureMap] = await Promise.all([
875
+ loadDetails(),
876
+ loadFeatureMap(),
877
+ ]);
878
+
879
+ if (!details || !featureMap) {
880
+ return { totalTests: 0, testedItems: 0, totalItems: 0, averageCoverage: 0 };
881
+ }
882
+
883
+ const moduleGroup = featureMap.features[moduleName];
884
+ if (!moduleGroup) {
885
+ return { totalTests: 0, testedItems: 0, totalItems: 0, averageCoverage: 0 };
886
+ }
887
+
888
+ let totalTests = 0;
889
+ let testedItems = 0;
890
+ let totalCoverage = 0;
891
+ let totalItems = 0;
892
+
893
+ // Check all item types - include path for correct key lookup
894
+ const itemTypes: Array<{ type: string; items: Array<{ name: string; path?: string }> }> = [
895
+ { type: "screen", items: moduleGroup.screens || [] },
896
+ { type: "component", items: moduleGroup.components || [] },
897
+ { type: "action", items: moduleGroup.actions || [] },
898
+ { type: "table", items: moduleGroup.tables || [] },
899
+ ];
900
+
901
+ for (const { type, items } of itemTypes) {
902
+ for (const item of items) {
903
+ totalItems++;
904
+
905
+ // Extract file module from item path (details.json uses file module as key)
906
+ const fileModule = extractFileModule(item.path);
907
+
908
+ // Try multiple key formats
909
+ const possibleKeys = [
910
+ fileModule ? `${type}/${fileModule}/${item.name}` : null,
911
+ `${type}/${moduleName}/${item.name}`,
912
+ ].filter((k): k is string => k !== null);
913
+
914
+ let found = false;
915
+ for (const key of possibleKeys) {
916
+ const detail = details.details[key];
917
+ if (detail?.testCoverage) {
918
+ totalTests += detail.testCoverage.totalTests;
919
+ if (detail.testCoverage.hasTest) {
920
+ testedItems++;
921
+ totalCoverage += detail.testCoverage.coverageScore;
922
+ }
923
+ found = true;
924
+ break;
925
+ }
926
+ }
927
+ }
928
+ }
929
+
930
+ return {
931
+ totalTests,
932
+ testedItems,
933
+ totalItems,
934
+ averageCoverage: testedItems > 0 ? Math.round(totalCoverage / testedItems) : 0,
935
+ };
936
+ }
937
+
938
+ /**
939
+ * Group tests by feature module
940
+ * Returns tests organized by module name instead of file path
941
+ */
942
+ export async function getTestsByModule(): Promise<
943
+ Map<string, {
944
+ moduleName: string;
945
+ tests: import("./types").TestCase[];
946
+ coverage: { totalTests: number; testedItems: number; totalItems: number };
947
+ }>
948
+ > {
949
+ const [testCases, details, featureMap] = await Promise.all([
950
+ loadTestCases(),
951
+ loadDetails(),
952
+ loadFeatureMap(),
953
+ ]);
954
+
955
+ const moduleTests = new Map<string, {
956
+ moduleName: string;
957
+ tests: import("./types").TestCase[];
958
+ coverage: { totalTests: number; testedItems: number; totalItems: number };
959
+ }>();
960
+
961
+ if (!testCases || !featureMap) return moduleTests;
962
+
963
+ // Build a map of source file path -> module name
964
+ const pathToModule = new Map<string, string>();
965
+
966
+ for (const [moduleName, group] of Object.entries(featureMap.features)) {
967
+ const allItems = [
968
+ ...(group.screens || []),
969
+ ...(group.components || []),
970
+ ...(group.actions || []),
971
+ ...(group.tables || []),
972
+ ];
973
+ for (const item of allItems) {
974
+ if ("path" in item && item.path) {
975
+ pathToModule.set(item.path, moduleName);
976
+ }
977
+ }
978
+ }
979
+
980
+ // Group tests by module based on their source file
981
+ for (const tc of testCases.testCases) {
982
+ // Find module from test file's associated source
983
+ let moduleName = "Uncategorized";
984
+
985
+ // Try to infer module from test file path
986
+ const testPath = tc.file;
987
+ // E2E tests often test specific modules
988
+ for (const [srcPath, module] of pathToModule.entries()) {
989
+ const srcFileName = srcPath.split("/").pop()?.replace(/\.(ts|tsx)$/, "");
990
+ if (srcFileName && testPath.includes(srcFileName)) {
991
+ moduleName = module;
992
+ break;
993
+ }
994
+ }
995
+
996
+ // Also check based on linked-docs if available
997
+ if (details) {
998
+ for (const [key, item] of Object.entries(details.details)) {
999
+ if (item.testCoverage?.byCategory) {
1000
+ for (const tests of Object.values(item.testCoverage.byCategory)) {
1001
+ for (const t of tests) {
1002
+ if (t.file === tc.file && t.name === tc.it) {
1003
+ const keyParts = key.split("/");
1004
+ if (keyParts.length >= 2) {
1005
+ moduleName = keyParts[1];
1006
+ }
1007
+ break;
1008
+ }
1009
+ }
1010
+ }
1011
+ }
1012
+ }
1013
+ }
1014
+
1015
+ if (!moduleTests.has(moduleName)) {
1016
+ moduleTests.set(moduleName, {
1017
+ moduleName,
1018
+ tests: [],
1019
+ coverage: { totalTests: 0, testedItems: 0, totalItems: 0 },
1020
+ });
1021
+ }
1022
+ moduleTests.get(moduleName)!.tests.push(tc);
1023
+ }
1024
+
1025
+ // Update coverage stats
1026
+ for (const [moduleName, data] of moduleTests.entries()) {
1027
+ const moduleCoverage = await getModuleTestCoverage(moduleName);
1028
+ data.coverage = {
1029
+ totalTests: data.tests.length,
1030
+ testedItems: moduleCoverage.testedItems,
1031
+ totalItems: moduleCoverage.totalItems,
1032
+ };
1033
+ }
1034
+
1035
+ return moduleTests;
1036
+ }
1037
+
1038
+ /**
1039
+ * Get sidebar navigation data
1040
+ */
1041
+ export async function getSidebarNavData(): Promise<{
1042
+ modules: { name: string; screens: number; components: number; actions: number; tables: number }[];
1043
+ testCategories: { name: string; slug: string; count: number }[];
1044
+ packages: { name: string; prefix: string; moduleCount: number; exportCount: number }[];
1045
+ hasFeatureMap: boolean;
1046
+ hasDbSchema: boolean;
1047
+ hasTestCases: boolean;
1048
+ hasOverview: boolean;
1049
+ hasApiTools: boolean;
1050
+ hasI18n: boolean;
1051
+ hasPackages: boolean;
1052
+ applications: ApplicationsData | null;
1053
+ }> {
1054
+ const [featureMap, testCases, available, applications, packagesData] = await Promise.all([
1055
+ loadFeatureMap(),
1056
+ loadTestCases(),
1057
+ getAvailableData(),
1058
+ loadApplications(),
1059
+ loadPackages(),
1060
+ ]);
1061
+
1062
+ // Extract modules from feature map
1063
+ const modules: { name: string; screens: number; components: number; actions: number; tables: number }[] = [];
1064
+
1065
+ if (featureMap) {
1066
+ for (const [name, group] of Object.entries(featureMap.features)) {
1067
+ modules.push({
1068
+ name,
1069
+ screens: group.screens?.length || 0,
1070
+ components: group.components?.length || 0,
1071
+ actions: group.actions?.length || 0,
1072
+ tables: group.tables?.length || 0,
1073
+ });
1074
+ }
1075
+
1076
+ // Add uncategorized if it has items
1077
+ const uncategorized = featureMap.uncategorized;
1078
+ if (uncategorized.screens?.length || uncategorized.components?.length ||
1079
+ uncategorized.actions?.length || uncategorized.tables?.length) {
1080
+ modules.push({
1081
+ name: "Uncategorized",
1082
+ screens: uncategorized.screens?.length || 0,
1083
+ components: uncategorized.components?.length || 0,
1084
+ actions: uncategorized.actions?.length || 0,
1085
+ tables: uncategorized.tables?.length || 0,
1086
+ });
1087
+ }
1088
+ }
1089
+
1090
+ // Extract test categories
1091
+ const testCategories: { name: string; slug: string; count: number }[] = [];
1092
+
1093
+ if (testCases) {
1094
+ const categoryCounts = new Map<string, number>();
1095
+
1096
+ for (const tc of testCases.testCases) {
1097
+ let category: string;
1098
+ if (tc.framework === "playwright") {
1099
+ category = "e2e";
1100
+ } else if (tc.file.includes("/actions/") || tc.file.includes("__tests__/lib/actions/")) {
1101
+ category = "server-actions";
1102
+ } else if (tc.file.includes("/components/") || tc.file.includes("__tests__/components/")) {
1103
+ category = "components";
1104
+ } else {
1105
+ category = "other";
1106
+ }
1107
+ categoryCounts.set(category, (categoryCounts.get(category) || 0) + 1);
1108
+ }
1109
+
1110
+ const categoryLabels: Record<string, string> = {
1111
+ "e2e": "E2E テスト",
1112
+ "server-actions": "Server Actions",
1113
+ "components": "Components",
1114
+ "other": "その他",
1115
+ };
1116
+
1117
+ for (const [slug, count] of categoryCounts.entries()) {
1118
+ testCategories.push({
1119
+ name: categoryLabels[slug] || slug,
1120
+ slug,
1121
+ count,
1122
+ });
1123
+ }
1124
+
1125
+ // Sort by count descending
1126
+ testCategories.sort((a, b) => b.count - a.count);
1127
+ }
1128
+
1129
+ // Extract packages data
1130
+ const packages: { name: string; prefix: string; moduleCount: number; exportCount: number }[] = [];
1131
+ if (packagesData) {
1132
+ for (const pkg of packagesData.packages) {
1133
+ packages.push({
1134
+ name: pkg.name,
1135
+ prefix: pkg.prefix,
1136
+ moduleCount: pkg.stats.moduleCount,
1137
+ exportCount: pkg.stats.exportCount,
1138
+ });
1139
+ }
1140
+ }
1141
+
1142
+ return {
1143
+ modules,
1144
+ testCategories,
1145
+ packages,
1146
+ hasFeatureMap: available.hasFeatureMap,
1147
+ hasDbSchema: available.hasDbSchema,
1148
+ hasTestCases: available.hasTestCases,
1149
+ hasOverview: available.hasOverview,
1150
+ hasApiTools: available.hasApiTools,
1151
+ hasI18n: available.hasI18n,
1152
+ hasPackages: available.hasPackages,
1153
+ applications,
1154
+ };
1155
+ }
1156
+
1157
+ /**
1158
+ * Load or generate search index
1159
+ */
1160
+ export async function loadSearchIndex(): Promise<SearchIndex | null> {
1161
+ try {
1162
+ // Try to load pre-generated search index first
1163
+ const cached = await readJsonFile<SearchIndex>("search-index.json");
1164
+ if (cached) {
1165
+ return cached;
1166
+ }
1167
+
1168
+ // Generate search index from available data
1169
+ const [featureMap, dbSchema, testCases, details] = await Promise.all([
1170
+ loadFeatureMap(),
1171
+ loadDbSchema(),
1172
+ loadTestCases(),
1173
+ loadDetails(),
1174
+ ]);
1175
+
1176
+ return generateSearchIndex(featureMap, dbSchema, testCases, details);
1177
+ } catch (error) {
1178
+ console.warn("Failed to load search index:", error);
1179
+ return null;
1180
+ }
1181
+ }