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