@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,1285 @@
1
+ /**
2
+ * issues command - GitHub Issues management with Projects integration
3
+ *
4
+ * This is the main user-facing command that abstracts Issues + Projects.
5
+ *
6
+ * Subcommands:
7
+ * - list: List issues (with Projects field filtering)
8
+ * - show: Get issue details including Projects fields
9
+ * - create: Create issue and optionally add to project with fields
10
+ * - update: Update issue and/or project fields
11
+ * - comment: Add comment to issue or PR
12
+ * - comment-edit: Edit existing comment
13
+ * - close: Close an issue (with optional comment)
14
+ *
15
+ * Key design:
16
+ * - Issues provide: #number references, comments, PR links
17
+ * - Projects provide: Status/Priority/Type/Size field management
18
+ * - This command unifies both for a seamless experience
19
+ */
20
+ import { createLogger } from "../utils/logger.js";
21
+ import { runGhCommand, runGraphQL, getRepoName, getRepoInfo, validateTitle, validateBody, isIssueNumber, parseIssueNumber, } from "../utils/github.js";
22
+ import { cmdPrComments, cmdMerge, cmdPrReply, cmdResolve, } from "./issues-pr.js";
23
+ import { loadGhConfig, getDefaultLimit, getDefaultStatus } from "../utils/gh-config.js";
24
+ import { formatOutput, GH_ISSUES_LIST_COLUMNS, } from "../utils/formatters.js";
25
+ import { resolveTargetRepo, detectCurrentRepoPair, parseRepoFullName, validateCrossRepoAlias, } from "../utils/repo-pairs.js";
26
+ import { FIELD_FALLBACKS, resolveFieldName, getProjectFields, updateTextField, setItemFields, generateTimestamp, autoSetTimestamps, addItemToProject, } from "../utils/project-fields.js";
27
+ // Re-exports for backward compatibility (issues-pr.ts, session.ts)
28
+ export { FIELD_FALLBACKS, resolveFieldName, getProjectFields, updateTextField, setItemFields, generateTimestamp, autoSetTimestamps, addItemToProject, };
29
+ // =============================================================================
30
+ // GraphQL Queries
31
+ // =============================================================================
32
+ // Note: We don't use $states variable because gh CLI has issues with GraphQL enum arrays
33
+ // Instead, we filter by state client-side
34
+ const GRAPHQL_QUERY_ISSUES_WITH_PROJECTS = `
35
+ query($owner: String!, $name: String!, $first: Int!, $cursor: String) {
36
+ repository(owner: $owner, name: $name) {
37
+ issues(first: $first, after: $cursor, orderBy: {field: CREATED_AT, direction: DESC}) {
38
+ pageInfo { hasNextPage endCursor }
39
+ nodes {
40
+ number
41
+ title
42
+ url
43
+ state
44
+ createdAt
45
+ updatedAt
46
+ labels(first: 10) {
47
+ nodes { name }
48
+ }
49
+ projectItems(first: 5) {
50
+ nodes {
51
+ id
52
+ project { title }
53
+ status: fieldValueByName(name: "Status") {
54
+ ... on ProjectV2ItemFieldSingleSelectValue { name }
55
+ }
56
+ priority: fieldValueByName(name: "Priority") {
57
+ ... on ProjectV2ItemFieldSingleSelectValue { name }
58
+ }
59
+ type: fieldValueByName(name: "Type") {
60
+ ... on ProjectV2ItemFieldSingleSelectValue { name }
61
+ }
62
+ itemType: fieldValueByName(name: "Item Type") {
63
+ ... on ProjectV2ItemFieldSingleSelectValue { name }
64
+ }
65
+ size: fieldValueByName(name: "Size") {
66
+ ... on ProjectV2ItemFieldSingleSelectValue { name }
67
+ }
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+ `;
75
+ const GRAPHQL_QUERY_ISSUE_DETAIL = `
76
+ query($owner: String!, $name: String!, $number: Int!) {
77
+ repository(owner: $owner, name: $name) {
78
+ issue(number: $number) {
79
+ number
80
+ title
81
+ body
82
+ url
83
+ state
84
+ createdAt
85
+ updatedAt
86
+ labels(first: 20) {
87
+ nodes { name }
88
+ }
89
+ projectItems(first: 5) {
90
+ nodes {
91
+ id
92
+ project { id title }
93
+ status: fieldValueByName(name: "Status") {
94
+ ... on ProjectV2ItemFieldSingleSelectValue { name optionId }
95
+ }
96
+ priority: fieldValueByName(name: "Priority") {
97
+ ... on ProjectV2ItemFieldSingleSelectValue { name optionId }
98
+ }
99
+ type: fieldValueByName(name: "Type") {
100
+ ... on ProjectV2ItemFieldSingleSelectValue { name optionId }
101
+ }
102
+ itemType: fieldValueByName(name: "Item Type") {
103
+ ... on ProjectV2ItemFieldSingleSelectValue { name optionId }
104
+ }
105
+ size: fieldValueByName(name: "Size") {
106
+ ... on ProjectV2ItemFieldSingleSelectValue { name optionId }
107
+ }
108
+ }
109
+ }
110
+ }
111
+ }
112
+ }
113
+ `;
114
+ const GRAPHQL_QUERY_REPO_ID = `
115
+ query($owner: String!, $name: String!) {
116
+ repository(owner: $owner, name: $name) {
117
+ id
118
+ }
119
+ }
120
+ `;
121
+ const GRAPHQL_QUERY_LABELS = `
122
+ query($owner: String!, $name: String!) {
123
+ repository(owner: $owner, name: $name) {
124
+ labels(first: 50) {
125
+ nodes { id name }
126
+ }
127
+ }
128
+ }
129
+ `;
130
+ const GRAPHQL_MUTATION_CREATE_ISSUE = `
131
+ mutation($repositoryId: ID!, $title: String!, $body: String, $labelIds: [ID!]) {
132
+ createIssue(input: {repositoryId: $repositoryId, title: $title, body: $body, labelIds: $labelIds}) {
133
+ issue { id number url title }
134
+ }
135
+ }
136
+ `;
137
+ const GRAPHQL_MUTATION_UPDATE_ISSUE = `
138
+ mutation($id: ID!, $title: String, $body: String) {
139
+ updateIssue(input: {id: $id, title: $title, body: $body}) {
140
+ issue { id number title body }
141
+ }
142
+ }
143
+ `;
144
+ const GRAPHQL_MUTATION_ADD_COMMENT = `
145
+ mutation($subjectId: ID!, $body: String!) {
146
+ addComment(input: {subjectId: $subjectId, body: $body}) {
147
+ commentEdge {
148
+ node { id databaseId url }
149
+ }
150
+ }
151
+ }
152
+ `;
153
+ const GRAPHQL_MUTATION_CLOSE_ISSUE = `
154
+ mutation($issueId: ID!, $stateReason: IssueClosedStateReason) {
155
+ closeIssue(input: {issueId: $issueId, stateReason: $stateReason}) {
156
+ issue { id number state }
157
+ }
158
+ }
159
+ `;
160
+ const GRAPHQL_MUTATION_REOPEN_ISSUE = `
161
+ mutation($issueId: ID!) {
162
+ reopenIssue(input: {issueId: $issueId}) {
163
+ issue { id number state }
164
+ }
165
+ }
166
+ `;
167
+ const GRAPHQL_MUTATION_ADD_LABELS = `
168
+ mutation($labelableId: ID!, $labelIds: [ID!]!) {
169
+ addLabelsToLabelable(input: {labelableId: $labelableId, labelIds: $labelIds}) {
170
+ labelable { ... on Issue { id number labels(first: 20) { nodes { name } } } }
171
+ }
172
+ }
173
+ `;
174
+ const GRAPHQL_MUTATION_REMOVE_LABELS = `
175
+ mutation($labelableId: ID!, $labelIds: [ID!]!) {
176
+ removeLabelsFromLabelable(input: {labelableId: $labelableId, labelIds: $labelIds}) {
177
+ labelable { ... on Issue { id number labels(first: 20) { nodes { name } } } }
178
+ }
179
+ }
180
+ `;
181
+ const GRAPHQL_QUERY_ISSUE_ID = `
182
+ query($owner: String!, $name: String!, $number: Int!) {
183
+ repository(owner: $owner, name: $name) {
184
+ issue(number: $number) {
185
+ id
186
+ }
187
+ }
188
+ }
189
+ `;
190
+ const GRAPHQL_QUERY_PR_ID = `
191
+ query($owner: String!, $name: String!, $number: Int!) {
192
+ repository(owner: $owner, name: $name) {
193
+ pullRequest(number: $number) {
194
+ id
195
+ }
196
+ }
197
+ }
198
+ `;
199
+ const GRAPHQL_MUTATION_DELETE_ITEM = `
200
+ mutation($projectId: ID!, $itemId: ID!) {
201
+ deleteProjectV2Item(input: {projectId: $projectId, itemId: $itemId}) {
202
+ deletedItemId
203
+ }
204
+ }
205
+ `;
206
+ // =============================================================================
207
+ // Helper Functions
208
+ // =============================================================================
209
+ /**
210
+ * Get project ID by name (defaults to repository name)
211
+ */
212
+ export function getProjectId(owner, projectName) {
213
+ const targetName = projectName || getRepoName();
214
+ if (!targetName)
215
+ return null;
216
+ const result = runGhCommand(["project", "list", "--owner", owner, "--format", "json"], { silent: true });
217
+ if (!result.success || !result.data?.projects)
218
+ return null;
219
+ for (const project of result.data.projects) {
220
+ if (project.title === targetName) {
221
+ return project.id;
222
+ }
223
+ }
224
+ return result.data.projects[0]?.id ?? null;
225
+ }
226
+ /**
227
+ * Get repository ID
228
+ */
229
+ function getRepoId(owner, repo) {
230
+ const result = runGraphQL(GRAPHQL_QUERY_REPO_ID, { owner, name: repo });
231
+ if (!result.success)
232
+ return null;
233
+ return result.data?.data?.repository?.id ?? null;
234
+ }
235
+ /**
236
+ * Get issue GraphQL ID by number
237
+ */
238
+ export function getIssueId(owner, repo, number) {
239
+ const result = runGraphQL(GRAPHQL_QUERY_ISSUE_ID, { owner, name: repo, number });
240
+ if (!result.success)
241
+ return null;
242
+ return result.data?.data?.repository?.issue?.id ?? null;
243
+ }
244
+ /**
245
+ * Get pull request GraphQL ID by number
246
+ */
247
+ export function getPullRequestId(owner, repo, number) {
248
+ const result = runGraphQL(GRAPHQL_QUERY_PR_ID, { owner, name: repo, number });
249
+ if (!result.success)
250
+ return null;
251
+ return result.data?.data?.repository?.pullRequest?.id ?? null;
252
+ }
253
+ /**
254
+ * Get repository labels
255
+ */
256
+ function getLabels(owner, repo) {
257
+ const result = runGraphQL(GRAPHQL_QUERY_LABELS, { owner, name: repo });
258
+ if (!result.success)
259
+ return {};
260
+ const labels = {};
261
+ const nodes = result.data?.data?.repository?.labels?.nodes ?? [];
262
+ for (const node of nodes) {
263
+ if (node?.name && node?.id) {
264
+ labels[node.name] = node.id;
265
+ }
266
+ }
267
+ return labels;
268
+ }
269
+ // =============================================================================
270
+ // Subcommand Handlers
271
+ // =============================================================================
272
+ /**
273
+ * list subcommand
274
+ */
275
+ async function cmdList(options, logger) {
276
+ const repoInfo = resolveTargetRepo(options);
277
+ if (!repoInfo) {
278
+ logger.error("Could not determine repository");
279
+ return 1;
280
+ }
281
+ // Load config for defaults
282
+ const config = loadGhConfig();
283
+ const { owner, name: repo } = repoInfo;
284
+ const projectName = repo; // Project name = repo name convention
285
+ // Map state option for client-side filtering
286
+ // --all is shortcut for --state all
287
+ const stateFilter = options.all ? "all" : (options.state ?? "open");
288
+ const allIssues = [];
289
+ let cursor = null;
290
+ const limit = options.limit ?? getDefaultLimit(config);
291
+ while (allIssues.length < limit) {
292
+ const remaining = limit - allIssues.length;
293
+ const fetchCount = Math.min(remaining, 50);
294
+ const result = runGraphQL(GRAPHQL_QUERY_ISSUES_WITH_PROJECTS, {
295
+ owner,
296
+ name: repo,
297
+ first: fetchCount,
298
+ cursor: cursor,
299
+ });
300
+ if (!result.success || !result.data?.data?.repository?.issues)
301
+ break;
302
+ const issuesData = result.data.data.repository.issues;
303
+ const nodes = issuesData.nodes ?? [];
304
+ for (const node of nodes) {
305
+ if (!node?.number)
306
+ continue;
307
+ // Client-side state filter
308
+ const nodeState = node.state ?? "OPEN";
309
+ if (stateFilter === "open" && nodeState !== "OPEN")
310
+ continue;
311
+ if (stateFilter === "closed" && nodeState !== "CLOSED")
312
+ continue;
313
+ const projectItems = node.projectItems?.nodes ?? [];
314
+ const matchingItem = projectItems.find((p) => p?.project?.title === projectName);
315
+ const labelNodes = node.labels?.nodes ?? [];
316
+ const issueLabels = labelNodes.map((l) => l?.name ?? "").filter(Boolean);
317
+ // Client-side label filter
318
+ if (options.labels && options.labels.length > 0) {
319
+ const hasAllLabels = options.labels.every((label) => issueLabels.includes(label));
320
+ if (!hasAllLabels)
321
+ continue;
322
+ }
323
+ const issue = {
324
+ number: node.number,
325
+ title: node.title ?? "",
326
+ url: node.url ?? "",
327
+ state: nodeState,
328
+ labels: issueLabels,
329
+ createdAt: node.createdAt ?? "",
330
+ updatedAt: node.updatedAt ?? "",
331
+ projectItemId: matchingItem?.id,
332
+ status: matchingItem?.status?.name,
333
+ priority: matchingItem?.priority?.name,
334
+ type: matchingItem?.type?.name ?? matchingItem?.itemType?.name,
335
+ size: matchingItem?.size?.name,
336
+ };
337
+ allIssues.push(issue);
338
+ }
339
+ const pageInfo = issuesData.pageInfo ?? {};
340
+ if (!pageInfo.hasNextPage)
341
+ break;
342
+ cursor = pageInfo.endCursor ?? null;
343
+ }
344
+ // Apply status filter (from Projects) if specified
345
+ let filteredIssues = allIssues;
346
+ if (options.status && options.status.length > 0) {
347
+ filteredIssues = allIssues.filter((i) => options.status.includes(i.status ?? ""));
348
+ }
349
+ // Note: state filter (open/closed/all) is applied client-side during fetch
350
+ // Done/Released items are typically closed, so --state open (default) excludes them
351
+ const output = {
352
+ repository: `${owner}/${repo}`,
353
+ issues: filteredIssues.map((i) => ({
354
+ number: i.number,
355
+ title: i.title,
356
+ url: i.url,
357
+ state: i.state,
358
+ labels: i.labels,
359
+ status: i.status,
360
+ priority: i.priority,
361
+ type: i.type,
362
+ size: i.size,
363
+ project_item_id: i.projectItemId,
364
+ })),
365
+ total_count: filteredIssues.length,
366
+ };
367
+ const outputFormat = options.format ?? "json";
368
+ const formatted = formatOutput(output, outputFormat, {
369
+ arrayKey: "issues",
370
+ columns: GH_ISSUES_LIST_COLUMNS,
371
+ });
372
+ console.log(formatted);
373
+ return 0;
374
+ }
375
+ /**
376
+ * get subcommand
377
+ */
378
+ async function cmdGet(issueNumberStr, options, logger) {
379
+ const repoInfo = resolveTargetRepo(options);
380
+ if (!repoInfo) {
381
+ logger.error("Could not determine repository");
382
+ return 1;
383
+ }
384
+ const { owner, name: repo } = repoInfo;
385
+ const issueNumber = parseIssueNumber(issueNumberStr);
386
+ const projectName = repo;
387
+ const result = runGraphQL(GRAPHQL_QUERY_ISSUE_DETAIL, {
388
+ owner,
389
+ name: repo,
390
+ number: issueNumber,
391
+ });
392
+ if (!result.success || !result.data?.data?.repository?.issue) {
393
+ logger.error(`Issue #${issueNumber} not found`);
394
+ return 1;
395
+ }
396
+ const node = result.data.data.repository.issue;
397
+ const projectItems = node.projectItems?.nodes ?? [];
398
+ const matchingItem = projectItems.find((p) => p?.project?.title === projectName);
399
+ // Merge "Type" and "Item Type" fields (GitHub reserves "Type" name)
400
+ const typeField = matchingItem?.type ?? matchingItem?.itemType;
401
+ const output = {
402
+ number: node.number,
403
+ title: node.title,
404
+ body: node.body,
405
+ url: node.url,
406
+ state: node.state,
407
+ labels: (node.labels?.nodes ?? []).map((l) => l?.name ?? "").filter(Boolean),
408
+ created_at: node.createdAt,
409
+ updated_at: node.updatedAt,
410
+ // Projects fields
411
+ project_item_id: matchingItem?.id,
412
+ project_id: matchingItem?.project?.id,
413
+ status: matchingItem?.status?.name,
414
+ status_option_id: matchingItem?.status?.optionId,
415
+ priority: matchingItem?.priority?.name,
416
+ priority_option_id: matchingItem?.priority?.optionId,
417
+ type: typeField?.name,
418
+ type_option_id: typeField?.optionId,
419
+ size: matchingItem?.size?.name,
420
+ size_option_id: matchingItem?.size?.optionId,
421
+ };
422
+ console.log(JSON.stringify(output, null, 2));
423
+ return 0;
424
+ }
425
+ /**
426
+ * create subcommand
427
+ */
428
+ async function cmdCreate(options, logger) {
429
+ // Validation
430
+ if (!options.title) {
431
+ logger.error("--title is required");
432
+ return 1;
433
+ }
434
+ const titleError = validateTitle(options.title);
435
+ if (titleError) {
436
+ logger.error(titleError);
437
+ return 1;
438
+ }
439
+ const bodyError = validateBody(options.body);
440
+ if (bodyError) {
441
+ logger.error(bodyError);
442
+ return 1;
443
+ }
444
+ const repoInfo = resolveTargetRepo(options);
445
+ if (!repoInfo) {
446
+ logger.error("Could not determine repository");
447
+ return 1;
448
+ }
449
+ const { owner, name: repo } = repoInfo;
450
+ // Get repository ID
451
+ const repoId = getRepoId(owner, repo);
452
+ if (!repoId) {
453
+ logger.error("Could not get repository ID");
454
+ return 1;
455
+ }
456
+ // Resolve label names to IDs
457
+ let labelIds = null;
458
+ if (options.labels && options.labels.length > 0) {
459
+ const allLabels = getLabels(owner, repo);
460
+ labelIds = [];
461
+ for (const labelName of options.labels) {
462
+ if (allLabels[labelName]) {
463
+ labelIds.push(allLabels[labelName]);
464
+ }
465
+ else {
466
+ logger.warn(`Label '${labelName}' not found`);
467
+ }
468
+ }
469
+ }
470
+ const createResult = runGraphQL(GRAPHQL_MUTATION_CREATE_ISSUE, {
471
+ repositoryId: repoId,
472
+ title: options.title,
473
+ body: options.body ?? "",
474
+ labelIds: labelIds ?? null,
475
+ });
476
+ if (!createResult.success) {
477
+ logger.error("Failed to create issue");
478
+ return 1;
479
+ }
480
+ const issue = createResult.data?.data?.createIssue?.issue;
481
+ if (!issue?.id || !issue?.number) {
482
+ logger.error("Failed to create issue");
483
+ return 1;
484
+ }
485
+ logger.success(`Created issue #${issue.number}`);
486
+ // Always add to project and set default Status if not explicitly provided.
487
+ // --status is array (for list filtering), --field-status is string (for setting)
488
+ // Accept --status as fallback when --field-status is not provided
489
+ const createStatusValue = options.fieldStatus ?? options.status?.[0] ?? getDefaultStatus();
490
+ let projectItemId = null;
491
+ const projectId = getProjectId(owner, repo);
492
+ if (!projectId) {
493
+ logger.warn("No project found. Issue created but not added to project.");
494
+ }
495
+ else {
496
+ projectItemId = addItemToProject(projectId, issue.id, logger);
497
+ if (projectItemId) {
498
+ logger.success("Added to project");
499
+ // Set project fields
500
+ const fields = {};
501
+ if (createStatusValue)
502
+ fields["Status"] = createStatusValue;
503
+ if (options.priority)
504
+ fields["Priority"] = options.priority;
505
+ if (options.type)
506
+ fields["Type"] = options.type;
507
+ if (options.size)
508
+ fields["Size"] = options.size;
509
+ if (Object.keys(fields).length > 0) {
510
+ setItemFields(projectId, projectItemId, fields, logger);
511
+ }
512
+ }
513
+ else {
514
+ logger.warn("Failed to add to project");
515
+ }
516
+ }
517
+ // Warn about missing fields (field completeness check)
518
+ const missingFields = [];
519
+ if (!options.priority)
520
+ missingFields.push("Priority");
521
+ if (!options.type)
522
+ missingFields.push("Type");
523
+ if (!options.size)
524
+ missingFields.push("Size");
525
+ if (missingFields.length > 0) {
526
+ logger.warn(`Issue #${issue.number} created without: ${missingFields.join(", ")}. ` +
527
+ `Consider setting them with: shirokuma-docs issues update ${issue.number} ` +
528
+ missingFields.map((f) => `--${f.toLowerCase()} <value>`).join(" "));
529
+ }
530
+ // Output created issue info
531
+ const output = {
532
+ number: issue.number,
533
+ title: issue.title,
534
+ url: issue.url,
535
+ project_item_id: projectItemId,
536
+ };
537
+ console.log(JSON.stringify(output, null, 2));
538
+ return 0;
539
+ }
540
+ /**
541
+ * update subcommand
542
+ */
543
+ async function cmdUpdate(issueNumberStr, options, logger) {
544
+ const repoInfo = resolveTargetRepo(options);
545
+ if (!repoInfo) {
546
+ logger.error("Could not determine repository");
547
+ return 1;
548
+ }
549
+ const { owner, name: repo } = repoInfo;
550
+ const issueNumber = parseIssueNumber(issueNumberStr);
551
+ const getResult = runGraphQL(GRAPHQL_QUERY_ISSUE_DETAIL, {
552
+ owner,
553
+ name: repo,
554
+ number: issueNumber,
555
+ });
556
+ if (!getResult.success || !getResult.data?.data?.repository?.issue) {
557
+ logger.error(`Issue #${issueNumber} not found`);
558
+ return 1;
559
+ }
560
+ const issueNode = getResult.data.data.repository.issue;
561
+ const projectName = repo;
562
+ const projectItems = issueNode.projectItems?.nodes ?? [];
563
+ const matchingItem = projectItems.find((p) => p?.project?.title === projectName);
564
+ let updated = false;
565
+ // Update issue fields (title, body)
566
+ if (options.title !== undefined || options.body !== undefined) {
567
+ const issueId = getIssueId(owner, repo, issueNumber);
568
+ if (issueId) {
569
+ const updateResult = runGraphQL(GRAPHQL_MUTATION_UPDATE_ISSUE, {
570
+ id: issueId,
571
+ title: options.title !== undefined ? options.title : (issueNode.title ?? ""),
572
+ body: options.body !== undefined ? options.body : (issueNode.body ?? ""),
573
+ });
574
+ if (updateResult.success) {
575
+ updated = true;
576
+ logger.success("Updated issue");
577
+ }
578
+ }
579
+ }
580
+ // Update labels
581
+ if ((options.addLabel && options.addLabel.length > 0) ||
582
+ (options.removeLabel && options.removeLabel.length > 0)) {
583
+ const issueId = getIssueId(owner, repo, issueNumber);
584
+ if (issueId) {
585
+ const allLabels = getLabels(owner, repo);
586
+ // Add labels
587
+ if (options.addLabel && options.addLabel.length > 0) {
588
+ const addIds = [];
589
+ for (const name of options.addLabel) {
590
+ if (allLabels[name]) {
591
+ addIds.push(allLabels[name]);
592
+ }
593
+ else {
594
+ logger.warn(`Label '${name}' not found`);
595
+ }
596
+ }
597
+ if (addIds.length > 0) {
598
+ const addResult = runGraphQL(GRAPHQL_MUTATION_ADD_LABELS, {
599
+ labelableId: issueId,
600
+ labelIds: addIds,
601
+ });
602
+ if (addResult.success) {
603
+ updated = true;
604
+ logger.success(`Added ${addIds.length} label(s)`);
605
+ }
606
+ }
607
+ }
608
+ // Remove labels
609
+ if (options.removeLabel && options.removeLabel.length > 0) {
610
+ const removeIds = [];
611
+ for (const name of options.removeLabel) {
612
+ if (allLabels[name]) {
613
+ removeIds.push(allLabels[name]);
614
+ }
615
+ else {
616
+ logger.warn(`Label '${name}' not found`);
617
+ }
618
+ }
619
+ if (removeIds.length > 0) {
620
+ const removeResult = runGraphQL(GRAPHQL_MUTATION_REMOVE_LABELS, {
621
+ labelableId: issueId,
622
+ labelIds: removeIds,
623
+ });
624
+ if (removeResult.success) {
625
+ updated = true;
626
+ logger.success(`Removed ${removeIds.length} label(s)`);
627
+ }
628
+ }
629
+ }
630
+ }
631
+ }
632
+ // Update project fields
633
+ // --status is array (for list filtering), --field-status is string (for setting)
634
+ // Accept --status as fallback when --field-status is not provided
635
+ const statusValue = options.fieldStatus ?? options.status?.[0];
636
+ const fields = {};
637
+ if (statusValue)
638
+ fields["Status"] = statusValue;
639
+ if (options.priority)
640
+ fields["Priority"] = options.priority;
641
+ if (options.type)
642
+ fields["Type"] = options.type;
643
+ if (options.size)
644
+ fields["Size"] = options.size;
645
+ if (Object.keys(fields).length > 0) {
646
+ if (matchingItem?.id && matchingItem?.project?.id) {
647
+ const pId = matchingItem.project.id;
648
+ const iId = matchingItem.id;
649
+ const pf = getProjectFields(pId);
650
+ const count = setItemFields(pId, iId, fields, logger, pf);
651
+ if (count > 0) {
652
+ updated = true;
653
+ logger.success(`Updated ${count} project field(s)`);
654
+ }
655
+ // Auto-set timestamp when Status changes (#342) - reuse fetched fields
656
+ if (statusValue) {
657
+ autoSetTimestamps(pId, iId, statusValue, pf, logger);
658
+ }
659
+ }
660
+ else {
661
+ // Issue not in project, add it first
662
+ const projectId = getProjectId(owner, repo);
663
+ if (projectId) {
664
+ const issueId = getIssueId(owner, repo, issueNumber);
665
+ if (issueId) {
666
+ const itemId = addItemToProject(projectId, issueId, logger);
667
+ if (itemId) {
668
+ logger.success("Added to project");
669
+ const pf = getProjectFields(projectId);
670
+ const count = setItemFields(projectId, itemId, fields, logger, pf);
671
+ if (count > 0) {
672
+ updated = true;
673
+ logger.success(`Updated ${count} project field(s)`);
674
+ }
675
+ // Auto-set timestamp when Status changes (#342) - reuse fetched fields
676
+ if (statusValue) {
677
+ autoSetTimestamps(projectId, itemId, statusValue, pf, logger);
678
+ }
679
+ }
680
+ }
681
+ }
682
+ else {
683
+ logger.warn("No project found. Cannot update project fields.");
684
+ }
685
+ }
686
+ }
687
+ if (!updated) {
688
+ logger.info("No changes made");
689
+ }
690
+ // Output updated issue info
691
+ return cmdGet(issueNumberStr, options, logger);
692
+ }
693
+ /**
694
+ * comment subcommand
695
+ *
696
+ * Supports both Issues and Pull Requests via ID fallback.
697
+ * The addComment mutation accepts subjectId for both types.
698
+ */
699
+ async function cmdComment(issueNumberStr, options, logger) {
700
+ if (!options.body) {
701
+ logger.error("--body is required for comment");
702
+ return 1;
703
+ }
704
+ const repoInfo = resolveTargetRepo(options);
705
+ if (!repoInfo) {
706
+ logger.error("Could not determine repository");
707
+ return 1;
708
+ }
709
+ const { owner, name: repo } = repoInfo;
710
+ const number = parseIssueNumber(issueNumberStr);
711
+ // Try Issue first, then fallback to PR (#353)
712
+ let subjectId = getIssueId(owner, repo, number);
713
+ let targetType = "issue";
714
+ if (!subjectId) {
715
+ subjectId = getPullRequestId(owner, repo, number);
716
+ targetType = "pull_request";
717
+ }
718
+ if (!subjectId) {
719
+ logger.error(`Issue or PR #${number} not found`);
720
+ return 1;
721
+ }
722
+ const result = runGraphQL(GRAPHQL_MUTATION_ADD_COMMENT, {
723
+ subjectId,
724
+ body: options.body,
725
+ });
726
+ if (!result.success) {
727
+ logger.error("Failed to add comment");
728
+ return 1;
729
+ }
730
+ const comment = result.data?.data?.addComment?.commentEdge?.node;
731
+ logger.success(`Added comment to #${number}`);
732
+ const output = {
733
+ issue_number: number,
734
+ target_type: targetType,
735
+ comment_id: comment?.id,
736
+ comment_database_id: comment?.databaseId,
737
+ comment_url: comment?.url,
738
+ };
739
+ console.log(JSON.stringify(output, null, 2));
740
+ return 0;
741
+ }
742
+ /**
743
+ * comment-edit subcommand (#375)
744
+ *
745
+ * Edit an existing comment using REST API.
746
+ * Works for both Issue and PR comments (GitHub treats them identically).
747
+ */
748
+ async function cmdCommentEdit(commentIdStr, options, logger) {
749
+ if (!options.body) {
750
+ logger.error("--body is required for comment-edit");
751
+ return 1;
752
+ }
753
+ const repoInfo = resolveTargetRepo(options);
754
+ if (!repoInfo) {
755
+ logger.error("Could not determine repository");
756
+ return 1;
757
+ }
758
+ const { owner, name: repo } = repoInfo;
759
+ const commentId = parseInt(commentIdStr, 10);
760
+ if (isNaN(commentId) || commentId <= 0) {
761
+ logger.error(`Invalid comment ID: ${commentIdStr}`);
762
+ return 1;
763
+ }
764
+ // REST API PATCH to edit comment
765
+ const result = runGhCommand(["api", "-X", "PATCH", `repos/${owner}/${repo}/issues/comments/${commentId}`, "-f", `body=${options.body}`], { silent: true });
766
+ if (!result.success) {
767
+ logger.error(`Failed to edit comment ${commentId}`);
768
+ return 1;
769
+ }
770
+ const commentUrl = result.data?.html_url;
771
+ logger.success(`Edited comment ${commentId}`);
772
+ const output = {
773
+ comment_id: commentId,
774
+ comment_url: commentUrl,
775
+ updated: true,
776
+ };
777
+ console.log(JSON.stringify(output, null, 2));
778
+ return 0;
779
+ }
780
+ // =============================================================================
781
+ // Close / Reopen Issue
782
+ // =============================================================================
783
+ /**
784
+ * close subcommand - Close an issue with optional comment.
785
+ *
786
+ * Supports:
787
+ * - --body: Add a closing comment before closing
788
+ * - --state-reason: COMPLETED (default) or NOT_PLANNED
789
+ * - --repo: Cross-repo support
790
+ */
791
+ async function cmdClose(issueNumberStr, options, logger) {
792
+ const repoInfo = resolveTargetRepo(options);
793
+ if (!repoInfo) {
794
+ logger.error("Could not determine repository");
795
+ return 1;
796
+ }
797
+ const { owner, name: repo } = repoInfo;
798
+ const issueNumber = parseIssueNumber(issueNumberStr);
799
+ // Get issue ID
800
+ const issueId = getIssueId(owner, repo, issueNumber);
801
+ if (!issueId) {
802
+ logger.error(`Issue #${issueNumber} not found`);
803
+ return 1;
804
+ }
805
+ // Add closing comment if --body is provided
806
+ if (options.body) {
807
+ const commentResult = runGraphQL(GRAPHQL_MUTATION_ADD_COMMENT, {
808
+ subjectId: issueId,
809
+ body: options.body,
810
+ });
811
+ if (commentResult.success) {
812
+ logger.success(`Added closing comment to #${issueNumber}`);
813
+ }
814
+ else {
815
+ logger.warn("Failed to add closing comment, proceeding with close");
816
+ }
817
+ }
818
+ // Close the issue
819
+ const stateReason = options.stateReason === "NOT_PLANNED" ? "NOT_PLANNED" : "COMPLETED";
820
+ const result = runGraphQL(GRAPHQL_MUTATION_CLOSE_ISSUE, {
821
+ issueId,
822
+ stateReason,
823
+ });
824
+ if (!result.success) {
825
+ logger.error(`Failed to close issue #${issueNumber}`);
826
+ return 1;
827
+ }
828
+ logger.success(`Closed #${issueNumber} (${stateReason})`);
829
+ // Auto-update project Status based on stateReason (#373)
830
+ // Priority: --field-status > stateReason-based default
831
+ const targetStatus = options.fieldStatus
832
+ ? options.fieldStatus
833
+ : stateReason === "NOT_PLANNED"
834
+ ? "Not Planned"
835
+ : "Done";
836
+ let statusUpdated = false;
837
+ const projectId = getProjectId(owner);
838
+ if (projectId) {
839
+ const detail = cmdGetIssueDetail(owner, repo, issueNumber);
840
+ if (detail?.projectItemId) {
841
+ const fields = getProjectFields(projectId);
842
+ const fieldResult = setItemFields(projectId, detail.projectItemId, { Status: targetStatus }, logger);
843
+ if (fieldResult > 0) {
844
+ statusUpdated = true;
845
+ logger.success(`Issue #${issueNumber} → ${targetStatus}`);
846
+ // Auto-set timestamp for Done status (#342)
847
+ if (targetStatus === "Done") {
848
+ autoSetTimestamps(projectId, detail.projectItemId, "Done", fields, logger);
849
+ }
850
+ }
851
+ }
852
+ }
853
+ const output = {
854
+ number: issueNumber,
855
+ state: "CLOSED",
856
+ stateReason,
857
+ status: statusUpdated ? targetStatus : undefined,
858
+ url: `https://github.com/${owner}/${repo}/issues/${issueNumber}`,
859
+ };
860
+ console.log(JSON.stringify(output, null, 2));
861
+ return 0;
862
+ }
863
+ /**
864
+ * reopen subcommand - Reopen a closed issue.
865
+ */
866
+ async function cmdReopen(issueNumberStr, options, logger) {
867
+ const repoInfo = resolveTargetRepo(options);
868
+ if (!repoInfo) {
869
+ logger.error("Could not determine repository");
870
+ return 1;
871
+ }
872
+ const { owner, name: repo } = repoInfo;
873
+ const issueNumber = parseIssueNumber(issueNumberStr);
874
+ const issueId = getIssueId(owner, repo, issueNumber);
875
+ if (!issueId) {
876
+ logger.error(`Issue #${issueNumber} not found`);
877
+ return 1;
878
+ }
879
+ const result = runGraphQL(GRAPHQL_MUTATION_REOPEN_ISSUE, {
880
+ issueId,
881
+ });
882
+ if (!result.success) {
883
+ logger.error(`Failed to reopen issue #${issueNumber}`);
884
+ return 1;
885
+ }
886
+ logger.success(`Reopened #${issueNumber}`);
887
+ const output = {
888
+ number: issueNumber,
889
+ state: "OPEN",
890
+ url: `https://github.com/${owner}/${repo}/issues/${issueNumber}`,
891
+ };
892
+ console.log(JSON.stringify(output, null, 2));
893
+ return 0;
894
+ }
895
+ // =============================================================================
896
+ // Import from Public Repo
897
+ // =============================================================================
898
+ /**
899
+ * import subcommand - Import an issue from public repo to private repo.
900
+ *
901
+ * Workflow:
902
+ * 1. Resolve current repo pair (private ← public)
903
+ * 2. Fetch issue from public repo
904
+ * 3. Create issue in private repo with cross-reference
905
+ * 4. Add comment to public issue noting internal tracking
906
+ */
907
+ async function cmdImport(options, logger) {
908
+ if (!options.fromPublic) {
909
+ logger.error("--from-public <number> is required for import");
910
+ logger.info("Usage: shirokuma-docs issues import --from-public 5");
911
+ return 1;
912
+ }
913
+ const publicIssueNumber = parseIssueNumber(options.fromPublic);
914
+ // Resolve private (current) and public repos from pair config
915
+ const privateRepo = getRepoInfo();
916
+ if (!privateRepo) {
917
+ logger.error("Could not determine current repository");
918
+ return 1;
919
+ }
920
+ const pair = detectCurrentRepoPair();
921
+ if (!pair) {
922
+ logger.error("No repo pair found for current repository. Configure repoPairs in config.");
923
+ return 1;
924
+ }
925
+ const publicRepoParsed = parseRepoFullName(pair.public);
926
+ if (!publicRepoParsed) {
927
+ logger.error(`Invalid public repo: ${pair.public}`);
928
+ return 1;
929
+ }
930
+ logger.info(`Importing issue #${publicIssueNumber} from ${pair.public}`);
931
+ const fetchResult = runGraphQL(GRAPHQL_QUERY_ISSUE_DETAIL, {
932
+ owner: publicRepoParsed.owner,
933
+ name: publicRepoParsed.name,
934
+ number: publicIssueNumber,
935
+ });
936
+ if (!fetchResult.success || !fetchResult.data?.data?.repository?.issue) {
937
+ logger.error(`Issue #${publicIssueNumber} not found in ${pair.public}`);
938
+ return 1;
939
+ }
940
+ const publicIssue = fetchResult.data.data.repository.issue;
941
+ const publicUrl = publicIssue.url ?? `https://github.com/${pair.public}/issues/${publicIssueNumber}`;
942
+ // Create issue in private repo
943
+ const importTitle = `[Public #${publicIssueNumber}] ${publicIssue.title ?? "Imported Issue"}`;
944
+ const importBody = [
945
+ `> Imported from public repo: ${publicUrl}`,
946
+ "",
947
+ "---",
948
+ "",
949
+ publicIssue.body ?? "",
950
+ ].join("\n");
951
+ const { owner, name: repo } = privateRepo;
952
+ const repoId = getRepoId(owner, repo);
953
+ if (!repoId) {
954
+ logger.error("Could not get repository ID for private repo");
955
+ return 1;
956
+ }
957
+ const createResult = runGraphQL(GRAPHQL_MUTATION_CREATE_ISSUE, {
958
+ repositoryId: repoId,
959
+ title: importTitle,
960
+ body: importBody,
961
+ labelIds: null,
962
+ });
963
+ if (!createResult.success) {
964
+ logger.error("Failed to create issue in private repo");
965
+ return 1;
966
+ }
967
+ const privateIssue = createResult.data?.data?.createIssue?.issue;
968
+ if (!privateIssue?.number) {
969
+ logger.error("Failed to create issue in private repo");
970
+ return 1;
971
+ }
972
+ logger.success(`Created private issue #${privateIssue.number}`);
973
+ // Always add imported issue to project with default Status
974
+ const importStatusValue = options.fieldStatus ?? getDefaultStatus();
975
+ const projectId = getProjectId(owner, repo);
976
+ if (projectId && privateIssue.id) {
977
+ const itemId = addItemToProject(projectId, privateIssue.id, logger);
978
+ if (itemId) {
979
+ logger.success("Added to project");
980
+ const fields = {};
981
+ if (importStatusValue)
982
+ fields["Status"] = importStatusValue;
983
+ if (options.priority)
984
+ fields["Priority"] = options.priority;
985
+ if (options.type)
986
+ fields["Type"] = options.type;
987
+ if (options.size)
988
+ fields["Size"] = options.size;
989
+ if (Object.keys(fields).length > 0) {
990
+ setItemFields(projectId, itemId, fields, logger);
991
+ }
992
+ }
993
+ }
994
+ // Comment on public issue to note internal tracking
995
+ const publicIssueId = getIssueId(publicRepoParsed.owner, publicRepoParsed.name, publicIssueNumber);
996
+ if (publicIssueId) {
997
+ const commentBody = `This issue is being tracked internally. Thank you for the report.`;
998
+ runGraphQL(GRAPHQL_MUTATION_ADD_COMMENT, {
999
+ subjectId: publicIssueId,
1000
+ body: commentBody,
1001
+ });
1002
+ logger.debug("Added tracking comment to public issue");
1003
+ }
1004
+ // Output
1005
+ const output = {
1006
+ private_issue: {
1007
+ number: privateIssue.number,
1008
+ title: privateIssue.title,
1009
+ url: privateIssue.url,
1010
+ },
1011
+ public_issue: {
1012
+ number: publicIssueNumber,
1013
+ url: publicUrl,
1014
+ repo: pair.public,
1015
+ },
1016
+ };
1017
+ console.log(JSON.stringify(output, null, 2));
1018
+ return 0;
1019
+ }
1020
+ /**
1021
+ * fields subcommand - Show project field definitions
1022
+ * (Migrated from projects fields)
1023
+ */
1024
+ async function cmdFields(options, logger) {
1025
+ const resolved = resolveTargetRepo(options);
1026
+ const repoInfo = getRepoInfo();
1027
+ const owner = resolved?.owner ?? options.owner ?? repoInfo?.owner;
1028
+ const repoName = resolved?.name ?? repoInfo?.name;
1029
+ if (!owner) {
1030
+ logger.error("Could not determine repository owner");
1031
+ return 1;
1032
+ }
1033
+ const projectId = getProjectId(owner, repoName ?? undefined);
1034
+ if (!projectId) {
1035
+ logger.error(`No project found for owner '${owner}'`);
1036
+ return 1;
1037
+ }
1038
+ const fields = getProjectFields(projectId);
1039
+ console.log(JSON.stringify(fields, null, 2));
1040
+ return 0;
1041
+ }
1042
+ /**
1043
+ * remove subcommand - Remove issue from project
1044
+ * (Migrated from projects delete)
1045
+ */
1046
+ async function cmdRemove(target, options, logger) {
1047
+ if (!isIssueNumber(target)) {
1048
+ logger.error("Issue number required");
1049
+ return 1;
1050
+ }
1051
+ const issueNumber = parseIssueNumber(target);
1052
+ const resolved = resolveTargetRepo(options);
1053
+ const repoInfo = getRepoInfo();
1054
+ const owner = resolved?.owner ?? options.owner ?? repoInfo?.owner;
1055
+ const repo = resolved?.name ?? repoInfo?.name;
1056
+ if (!owner) {
1057
+ logger.error("Could not determine repository owner");
1058
+ return 1;
1059
+ }
1060
+ if (!repo) {
1061
+ logger.error("Could not determine repository name");
1062
+ return 1;
1063
+ }
1064
+ const projectId = getProjectId(owner, repo);
1065
+ if (!projectId) {
1066
+ logger.error(`No project found for owner '${owner}'`);
1067
+ return 1;
1068
+ }
1069
+ // Find project item for this issue
1070
+ // Fetch the issue to find its project item ID
1071
+ const issueResult = cmdGetIssueDetail(owner, repo, issueNumber);
1072
+ if (!issueResult) {
1073
+ logger.error(`Issue #${issueNumber} not found`);
1074
+ return 1;
1075
+ }
1076
+ const projectItemId = issueResult.projectItemId;
1077
+ if (!projectItemId) {
1078
+ logger.error(`Issue #${issueNumber} is not in any project`);
1079
+ return 1;
1080
+ }
1081
+ // Remove from project
1082
+ const result = runGraphQL(GRAPHQL_MUTATION_DELETE_ITEM, {
1083
+ projectId,
1084
+ itemId: projectItemId,
1085
+ });
1086
+ if (result.success) {
1087
+ const output = {
1088
+ removed: true,
1089
+ issue_number: issueNumber,
1090
+ note: "Issue removed from project. Issue still exists.",
1091
+ };
1092
+ console.log(JSON.stringify(output, null, 2));
1093
+ return 0;
1094
+ }
1095
+ else {
1096
+ logger.error(`Failed to remove Issue #${issueNumber} from project`);
1097
+ return 1;
1098
+ }
1099
+ }
1100
+ /**
1101
+ * Issue の projectItemId と projectId を GraphQL で取得する
1102
+ */
1103
+ export function cmdGetIssueDetail(owner, repo, issueNumber) {
1104
+ const result = runGraphQL(GRAPHQL_QUERY_ISSUE_DETAIL, {
1105
+ owner,
1106
+ name: repo,
1107
+ number: issueNumber,
1108
+ });
1109
+ if (!result.success)
1110
+ return null;
1111
+ const issue = result.data?.data?.repository?.issue;
1112
+ if (!issue)
1113
+ return null;
1114
+ // Match by project name convention, fallback to first item
1115
+ const projectItems = issue.projectItems?.nodes ?? [];
1116
+ const projectItem = projectItems.find((p) => p?.project?.title === repo) ?? projectItems[0];
1117
+ return {
1118
+ projectItemId: projectItem?.id,
1119
+ projectId: projectItem?.project?.id,
1120
+ };
1121
+ }
1122
+ // =============================================================================
1123
+ // Main Command Handler
1124
+ // =============================================================================
1125
+ /**
1126
+ * issues command handler
1127
+ */
1128
+ export async function issuesCommand(action, target, options) {
1129
+ const logger = createLogger(options.verbose);
1130
+ logger.debug(`Action: ${action}`);
1131
+ logger.debug(`Target: ${target ?? "(none)"}`);
1132
+ // Validate --repo alias early
1133
+ if (options.repo) {
1134
+ const aliasError = validateCrossRepoAlias(options.repo);
1135
+ if (aliasError) {
1136
+ logger.error(aliasError);
1137
+ process.exit(1);
1138
+ }
1139
+ }
1140
+ let exitCode = 0;
1141
+ switch (action) {
1142
+ case "list":
1143
+ exitCode = await cmdList(options, logger);
1144
+ break;
1145
+ case "show":
1146
+ if (!target) {
1147
+ logger.error("Issue number required");
1148
+ logger.info("Usage: shirokuma-docs issues show <number>");
1149
+ exitCode = 1;
1150
+ }
1151
+ else {
1152
+ exitCode = await cmdGet(target, options, logger);
1153
+ }
1154
+ break;
1155
+ case "create":
1156
+ exitCode = await cmdCreate(options, logger);
1157
+ break;
1158
+ case "update":
1159
+ if (!target) {
1160
+ logger.error("Issue number required");
1161
+ logger.info("Usage: shirokuma-docs issues update <number> --field-status ...");
1162
+ exitCode = 1;
1163
+ }
1164
+ else {
1165
+ exitCode = await cmdUpdate(target, options, logger);
1166
+ }
1167
+ break;
1168
+ case "comment":
1169
+ if (!target) {
1170
+ logger.error("Issue or PR number required");
1171
+ logger.info("Usage: shirokuma-docs issues comment <issue-or-pr-number> --body ...");
1172
+ exitCode = 1;
1173
+ }
1174
+ else {
1175
+ exitCode = await cmdComment(target, options, logger);
1176
+ }
1177
+ break;
1178
+ case "comment-edit":
1179
+ if (!target) {
1180
+ logger.error("Comment ID required");
1181
+ logger.info("Usage: shirokuma-docs issues comment-edit <comment-id> --body ...");
1182
+ exitCode = 1;
1183
+ }
1184
+ else {
1185
+ exitCode = await cmdCommentEdit(target, options, logger);
1186
+ }
1187
+ break;
1188
+ case "close":
1189
+ if (!target) {
1190
+ logger.error("Issue number required");
1191
+ logger.info("Usage: shirokuma-docs issues close <number> [--body ...] [--state-reason COMPLETED|NOT_PLANNED]");
1192
+ exitCode = 1;
1193
+ }
1194
+ else {
1195
+ exitCode = await cmdClose(target, options, logger);
1196
+ }
1197
+ break;
1198
+ case "cancel":
1199
+ if (!target) {
1200
+ logger.error("Issue number required");
1201
+ logger.info("Usage: shirokuma-docs issues cancel <number> [--body ...]");
1202
+ exitCode = 1;
1203
+ }
1204
+ else {
1205
+ // cancel = close with NOT_PLANNED reason (#373)
1206
+ exitCode = await cmdClose(target, { ...options, stateReason: "NOT_PLANNED" }, logger);
1207
+ }
1208
+ break;
1209
+ case "reopen":
1210
+ if (!target) {
1211
+ logger.error("Issue number required");
1212
+ logger.info("Usage: shirokuma-docs issues reopen <number>");
1213
+ exitCode = 1;
1214
+ }
1215
+ else {
1216
+ exitCode = await cmdReopen(target, options, logger);
1217
+ }
1218
+ break;
1219
+ case "import":
1220
+ exitCode = await cmdImport(options, logger);
1221
+ break;
1222
+ case "fields":
1223
+ exitCode = await cmdFields(options, logger);
1224
+ break;
1225
+ case "remove":
1226
+ if (!target) {
1227
+ logger.error("Issue number required");
1228
+ logger.info("Usage: shirokuma-docs issues remove <number>");
1229
+ exitCode = 1;
1230
+ }
1231
+ else {
1232
+ exitCode = await cmdRemove(target, options, logger);
1233
+ }
1234
+ break;
1235
+ case "pr-comments":
1236
+ if (!target) {
1237
+ logger.error("PR number required");
1238
+ logger.info("Usage: shirokuma-docs issues pr-comments <number>");
1239
+ exitCode = 1;
1240
+ }
1241
+ else {
1242
+ exitCode = await cmdPrComments(target, options, logger);
1243
+ }
1244
+ break;
1245
+ case "merge":
1246
+ if (!target && !options.head) {
1247
+ logger.error("PR number or --head <branch> required");
1248
+ logger.info("Usage: shirokuma-docs issues merge <number> [--squash|--merge|--rebase]\n" +
1249
+ " shirokuma-docs issues merge --head <branch>");
1250
+ exitCode = 1;
1251
+ }
1252
+ else {
1253
+ exitCode = await cmdMerge(target, options, logger);
1254
+ }
1255
+ break;
1256
+ case "pr-reply":
1257
+ if (!target) {
1258
+ logger.error("PR number required");
1259
+ logger.info("Usage: shirokuma-docs issues pr-reply <number> --reply-to <id> --body ...");
1260
+ exitCode = 1;
1261
+ }
1262
+ else {
1263
+ exitCode = await cmdPrReply(target, options, logger);
1264
+ }
1265
+ break;
1266
+ case "resolve":
1267
+ if (!target) {
1268
+ logger.error("PR number required");
1269
+ logger.info("Usage: shirokuma-docs issues resolve <number> --thread-id <id>");
1270
+ exitCode = 1;
1271
+ }
1272
+ else {
1273
+ exitCode = await cmdResolve(target, options, logger);
1274
+ }
1275
+ break;
1276
+ default:
1277
+ logger.error(`Unknown action: ${action}`);
1278
+ logger.info("Available actions: list, show, create, update, comment, comment-edit, close, cancel, reopen, import, fields, remove, pr-comments, merge, pr-reply, resolve");
1279
+ exitCode = 1;
1280
+ }
1281
+ if (exitCode !== 0) {
1282
+ process.exit(exitCode);
1283
+ }
1284
+ }
1285
+ //# sourceMappingURL=issues.js.map