@specforge/cli 0.1.0

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.
Files changed (380) hide show
  1. package/README.md +781 -0
  2. package/bin/specforge +21 -0
  3. package/dist/channel.d.ts +27 -0
  4. package/dist/channel.d.ts.map +1 -0
  5. package/dist/channel.js +22 -0
  6. package/dist/channel.js.map +1 -0
  7. package/dist/cli/commands/configure.d.ts +16 -0
  8. package/dist/cli/commands/configure.d.ts.map +1 -0
  9. package/dist/cli/commands/configure.js +186 -0
  10. package/dist/cli/commands/configure.js.map +1 -0
  11. package/dist/cli/commands/configure.types.d.ts +110 -0
  12. package/dist/cli/commands/configure.types.d.ts.map +1 -0
  13. package/dist/cli/commands/configure.types.js +82 -0
  14. package/dist/cli/commands/configure.types.js.map +1 -0
  15. package/dist/cli/commands/debug/call.d.ts +14 -0
  16. package/dist/cli/commands/debug/call.d.ts.map +1 -0
  17. package/dist/cli/commands/debug/call.js +96 -0
  18. package/dist/cli/commands/debug/call.js.map +1 -0
  19. package/dist/cli/commands/debug/index.d.ts +12 -0
  20. package/dist/cli/commands/debug/index.d.ts.map +1 -0
  21. package/dist/cli/commands/debug/index.js +14 -0
  22. package/dist/cli/commands/debug/index.js.map +1 -0
  23. package/dist/cli/commands/debug/register.d.ts +11 -0
  24. package/dist/cli/commands/debug/register.d.ts.map +1 -0
  25. package/dist/cli/commands/debug/register.js +78 -0
  26. package/dist/cli/commands/debug/register.js.map +1 -0
  27. package/dist/cli/commands/debug/test.d.ts +13 -0
  28. package/dist/cli/commands/debug/test.d.ts.map +1 -0
  29. package/dist/cli/commands/debug/test.js +91 -0
  30. package/dist/cli/commands/debug/test.js.map +1 -0
  31. package/dist/cli/commands/debug/tools.d.ts +13 -0
  32. package/dist/cli/commands/debug/tools.d.ts.map +1 -0
  33. package/dist/cli/commands/debug/tools.js +86 -0
  34. package/dist/cli/commands/debug/tools.js.map +1 -0
  35. package/dist/cli/commands/debug/types.d.ts +119 -0
  36. package/dist/cli/commands/debug/types.d.ts.map +1 -0
  37. package/dist/cli/commands/debug/types.js +36 -0
  38. package/dist/cli/commands/debug/types.js.map +1 -0
  39. package/dist/cli/commands/debug/whoami.d.ts +13 -0
  40. package/dist/cli/commands/debug/whoami.d.ts.map +1 -0
  41. package/dist/cli/commands/debug/whoami.js +131 -0
  42. package/dist/cli/commands/debug/whoami.js.map +1 -0
  43. package/dist/cli/commands/doctor.d.ts +16 -0
  44. package/dist/cli/commands/doctor.d.ts.map +1 -0
  45. package/dist/cli/commands/doctor.js +413 -0
  46. package/dist/cli/commands/doctor.js.map +1 -0
  47. package/dist/cli/commands/doctor.types.d.ts +180 -0
  48. package/dist/cli/commands/doctor.types.d.ts.map +1 -0
  49. package/dist/cli/commands/doctor.types.js +140 -0
  50. package/dist/cli/commands/doctor.types.js.map +1 -0
  51. package/dist/cli/commands/feedback.d.ts +27 -0
  52. package/dist/cli/commands/feedback.d.ts.map +1 -0
  53. package/dist/cli/commands/feedback.js +262 -0
  54. package/dist/cli/commands/feedback.js.map +1 -0
  55. package/dist/cli/commands/feedback.types.d.ts +116 -0
  56. package/dist/cli/commands/feedback.types.d.ts.map +1 -0
  57. package/dist/cli/commands/feedback.types.js +65 -0
  58. package/dist/cli/commands/feedback.types.js.map +1 -0
  59. package/dist/cli/commands/index.d.ts +15 -0
  60. package/dist/cli/commands/index.d.ts.map +1 -0
  61. package/dist/cli/commands/index.js +21 -0
  62. package/dist/cli/commands/index.js.map +1 -0
  63. package/dist/cli/commands/init.d.ts +17 -0
  64. package/dist/cli/commands/init.d.ts.map +1 -0
  65. package/dist/cli/commands/init.js +773 -0
  66. package/dist/cli/commands/init.js.map +1 -0
  67. package/dist/cli/commands/init.types.d.ts +193 -0
  68. package/dist/cli/commands/init.types.d.ts.map +1 -0
  69. package/dist/cli/commands/init.types.js +29 -0
  70. package/dist/cli/commands/init.types.js.map +1 -0
  71. package/dist/cli/commands/invitations.d.ts +31 -0
  72. package/dist/cli/commands/invitations.d.ts.map +1 -0
  73. package/dist/cli/commands/invitations.js +250 -0
  74. package/dist/cli/commands/invitations.js.map +1 -0
  75. package/dist/cli/commands/login.d.ts +40 -0
  76. package/dist/cli/commands/login.d.ts.map +1 -0
  77. package/dist/cli/commands/login.js +139 -0
  78. package/dist/cli/commands/login.js.map +1 -0
  79. package/dist/cli/commands/members.d.ts +55 -0
  80. package/dist/cli/commands/members.d.ts.map +1 -0
  81. package/dist/cli/commands/members.js +296 -0
  82. package/dist/cli/commands/members.js.map +1 -0
  83. package/dist/cli/commands/scaffold/agent-types.d.ts +54 -0
  84. package/dist/cli/commands/scaffold/agent-types.d.ts.map +1 -0
  85. package/dist/cli/commands/scaffold/agent-types.js +22 -0
  86. package/dist/cli/commands/scaffold/agent-types.js.map +1 -0
  87. package/dist/cli/commands/scaffold/display.d.ts +56 -0
  88. package/dist/cli/commands/scaffold/display.d.ts.map +1 -0
  89. package/dist/cli/commands/scaffold/display.js +217 -0
  90. package/dist/cli/commands/scaffold/display.js.map +1 -0
  91. package/dist/cli/commands/scaffold/files.d.ts +99 -0
  92. package/dist/cli/commands/scaffold/files.d.ts.map +1 -0
  93. package/dist/cli/commands/scaffold/files.js +122 -0
  94. package/dist/cli/commands/scaffold/files.js.map +1 -0
  95. package/dist/cli/commands/scaffold/index.d.ts +13 -0
  96. package/dist/cli/commands/scaffold/index.d.ts.map +1 -0
  97. package/dist/cli/commands/scaffold/index.js +12 -0
  98. package/dist/cli/commands/scaffold/index.js.map +1 -0
  99. package/dist/cli/commands/scaffold/register.d.ts +11 -0
  100. package/dist/cli/commands/scaffold/register.d.ts.map +1 -0
  101. package/dist/cli/commands/scaffold/register.js +11 -0
  102. package/dist/cli/commands/scaffold/register.js.map +1 -0
  103. package/dist/cli/commands/scaffold/scaffold.d.ts +11 -0
  104. package/dist/cli/commands/scaffold/scaffold.d.ts.map +1 -0
  105. package/dist/cli/commands/scaffold/scaffold.js +728 -0
  106. package/dist/cli/commands/scaffold/scaffold.js.map +1 -0
  107. package/dist/cli/commands/scaffold/targets.d.ts +60 -0
  108. package/dist/cli/commands/scaffold/targets.d.ts.map +1 -0
  109. package/dist/cli/commands/scaffold/targets.js +251 -0
  110. package/dist/cli/commands/scaffold/targets.js.map +1 -0
  111. package/dist/cli/commands/scaffold/types.d.ts +170 -0
  112. package/dist/cli/commands/scaffold/types.d.ts.map +1 -0
  113. package/dist/cli/commands/scaffold/types.js +12 -0
  114. package/dist/cli/commands/scaffold/types.js.map +1 -0
  115. package/dist/cli/commands/scaffold/utils.d.ts +89 -0
  116. package/dist/cli/commands/scaffold/utils.d.ts.map +1 -0
  117. package/dist/cli/commands/scaffold/utils.js +401 -0
  118. package/dist/cli/commands/scaffold/utils.js.map +1 -0
  119. package/dist/cli/commands/status.d.ts +19 -0
  120. package/dist/cli/commands/status.d.ts.map +1 -0
  121. package/dist/cli/commands/status.js +124 -0
  122. package/dist/cli/commands/status.js.map +1 -0
  123. package/dist/cli/commands/status.types.d.ts +37 -0
  124. package/dist/cli/commands/status.types.d.ts.map +1 -0
  125. package/dist/cli/commands/status.types.js +7 -0
  126. package/dist/cli/commands/status.types.js.map +1 -0
  127. package/dist/cli/commands/switch.d.ts +18 -0
  128. package/dist/cli/commands/switch.d.ts.map +1 -0
  129. package/dist/cli/commands/switch.js +134 -0
  130. package/dist/cli/commands/switch.js.map +1 -0
  131. package/dist/cli/commands/switch.types.d.ts +123 -0
  132. package/dist/cli/commands/switch.types.d.ts.map +1 -0
  133. package/dist/cli/commands/switch.types.js +46 -0
  134. package/dist/cli/commands/switch.types.js.map +1 -0
  135. package/dist/cli/config/agent-teams.types.d.ts +120 -0
  136. package/dist/cli/config/agent-teams.types.d.ts.map +1 -0
  137. package/dist/cli/config/agent-teams.types.js +23 -0
  138. package/dist/cli/config/agent-teams.types.js.map +1 -0
  139. package/dist/cli/config/index.d.ts +13 -0
  140. package/dist/cli/config/index.d.ts.map +1 -0
  141. package/dist/cli/config/index.js +7 -0
  142. package/dist/cli/config/index.js.map +1 -0
  143. package/dist/cli/config/loader.d.ts +114 -0
  144. package/dist/cli/config/loader.d.ts.map +1 -0
  145. package/dist/cli/config/loader.js +198 -0
  146. package/dist/cli/config/loader.js.map +1 -0
  147. package/dist/cli/config/paths.d.ts +107 -0
  148. package/dist/cli/config/paths.d.ts.map +1 -0
  149. package/dist/cli/config/paths.js +79 -0
  150. package/dist/cli/config/paths.js.map +1 -0
  151. package/dist/cli/config/planning-sessions-registry.d.ts +52 -0
  152. package/dist/cli/config/planning-sessions-registry.d.ts.map +1 -0
  153. package/dist/cli/config/planning-sessions-registry.js +46 -0
  154. package/dist/cli/config/planning-sessions-registry.js.map +1 -0
  155. package/dist/cli/config/types.d.ts +186 -0
  156. package/dist/cli/config/types.d.ts.map +1 -0
  157. package/dist/cli/config/types.js +27 -0
  158. package/dist/cli/config/types.js.map +1 -0
  159. package/dist/cli/config/validation.d.ts +62 -0
  160. package/dist/cli/config/validation.d.ts.map +1 -0
  161. package/dist/cli/config/validation.js +133 -0
  162. package/dist/cli/config/validation.js.map +1 -0
  163. package/dist/cli/config/writer.d.ts +153 -0
  164. package/dist/cli/config/writer.d.ts.map +1 -0
  165. package/dist/cli/config/writer.js +168 -0
  166. package/dist/cli/config/writer.js.map +1 -0
  167. package/dist/cli/index.d.ts +30 -0
  168. package/dist/cli/index.d.ts.map +1 -0
  169. package/dist/cli/index.js +142 -0
  170. package/dist/cli/index.js.map +1 -0
  171. package/dist/cli/middleware/auth-guard.d.ts +107 -0
  172. package/dist/cli/middleware/auth-guard.d.ts.map +1 -0
  173. package/dist/cli/middleware/auth-guard.js +97 -0
  174. package/dist/cli/middleware/auth-guard.js.map +1 -0
  175. package/dist/cli/middleware/error-handler.d.ts +133 -0
  176. package/dist/cli/middleware/error-handler.d.ts.map +1 -0
  177. package/dist/cli/middleware/error-handler.js +139 -0
  178. package/dist/cli/middleware/error-handler.js.map +1 -0
  179. package/dist/cli/middleware/index.d.ts +6 -0
  180. package/dist/cli/middleware/index.d.ts.map +1 -0
  181. package/dist/cli/middleware/index.js +3 -0
  182. package/dist/cli/middleware/index.js.map +1 -0
  183. package/dist/cli/templates/agents/content/core/sfag-orchestrator.d.ts +9 -0
  184. package/dist/cli/templates/agents/content/core/sfag-orchestrator.d.ts.map +1 -0
  185. package/dist/cli/templates/agents/content/core/sfag-orchestrator.js +160 -0
  186. package/dist/cli/templates/agents/content/core/sfag-orchestrator.js.map +1 -0
  187. package/dist/cli/templates/agents/content/core/sfag-spec-creator.d.ts +9 -0
  188. package/dist/cli/templates/agents/content/core/sfag-spec-creator.d.ts.map +1 -0
  189. package/dist/cli/templates/agents/content/core/sfag-spec-creator.js +343 -0
  190. package/dist/cli/templates/agents/content/core/sfag-spec-creator.js.map +1 -0
  191. package/dist/cli/templates/agents/content/core/sfag-ticket-implementer.d.ts +9 -0
  192. package/dist/cli/templates/agents/content/core/sfag-ticket-implementer.d.ts.map +1 -0
  193. package/dist/cli/templates/agents/content/core/sfag-ticket-implementer.js +254 -0
  194. package/dist/cli/templates/agents/content/core/sfag-ticket-implementer.js.map +1 -0
  195. package/dist/cli/templates/agents/content/research/sfag-package-researcher.d.ts +8 -0
  196. package/dist/cli/templates/agents/content/research/sfag-package-researcher.d.ts.map +1 -0
  197. package/dist/cli/templates/agents/content/research/sfag-package-researcher.js +128 -0
  198. package/dist/cli/templates/agents/content/research/sfag-package-researcher.js.map +1 -0
  199. package/dist/cli/templates/agents/index.d.ts +23 -0
  200. package/dist/cli/templates/agents/index.d.ts.map +1 -0
  201. package/dist/cli/templates/agents/index.js +29 -0
  202. package/dist/cli/templates/agents/index.js.map +1 -0
  203. package/dist/cli/templates/commands.d.ts +17 -0
  204. package/dist/cli/templates/commands.d.ts.map +1 -0
  205. package/dist/cli/templates/commands.js +78 -0
  206. package/dist/cli/templates/commands.js.map +1 -0
  207. package/dist/cli/templates/content/sf-blockers.d.ts +7 -0
  208. package/dist/cli/templates/content/sf-blockers.d.ts.map +1 -0
  209. package/dist/cli/templates/content/sf-blockers.js +69 -0
  210. package/dist/cli/templates/content/sf-blockers.js.map +1 -0
  211. package/dist/cli/templates/content/sf-commit.d.ts +7 -0
  212. package/dist/cli/templates/content/sf-commit.d.ts.map +1 -0
  213. package/dist/cli/templates/content/sf-commit.js +79 -0
  214. package/dist/cli/templates/content/sf-commit.js.map +1 -0
  215. package/dist/cli/templates/content/sf-context.d.ts +7 -0
  216. package/dist/cli/templates/content/sf-context.d.ts.map +1 -0
  217. package/dist/cli/templates/content/sf-context.js +63 -0
  218. package/dist/cli/templates/content/sf-context.js.map +1 -0
  219. package/dist/cli/templates/content/sf-help.d.ts +7 -0
  220. package/dist/cli/templates/content/sf-help.d.ts.map +1 -0
  221. package/dist/cli/templates/content/sf-help.js +42 -0
  222. package/dist/cli/templates/content/sf-help.js.map +1 -0
  223. package/dist/cli/templates/content/sf-init.d.ts +7 -0
  224. package/dist/cli/templates/content/sf-init.d.ts.map +1 -0
  225. package/dist/cli/templates/content/sf-init.js +62 -0
  226. package/dist/cli/templates/content/sf-init.js.map +1 -0
  227. package/dist/cli/templates/content/sf-reset.d.ts +7 -0
  228. package/dist/cli/templates/content/sf-reset.d.ts.map +1 -0
  229. package/dist/cli/templates/content/sf-reset.js +67 -0
  230. package/dist/cli/templates/content/sf-reset.js.map +1 -0
  231. package/dist/cli/templates/content/sf-search.d.ts +7 -0
  232. package/dist/cli/templates/content/sf-search.d.ts.map +1 -0
  233. package/dist/cli/templates/content/sf-search.js +63 -0
  234. package/dist/cli/templates/content/sf-search.js.map +1 -0
  235. package/dist/cli/templates/content/sf-status.d.ts +7 -0
  236. package/dist/cli/templates/content/sf-status.d.ts.map +1 -0
  237. package/dist/cli/templates/content/sf-status.js +62 -0
  238. package/dist/cli/templates/content/sf-status.js.map +1 -0
  239. package/dist/cli/templates/index.d.ts +8 -0
  240. package/dist/cli/templates/index.d.ts.map +1 -0
  241. package/dist/cli/templates/index.js +17 -0
  242. package/dist/cli/templates/index.js.map +1 -0
  243. package/dist/cli/ui/banner.d.ts +38 -0
  244. package/dist/cli/ui/banner.d.ts.map +1 -0
  245. package/dist/cli/ui/banner.js +89 -0
  246. package/dist/cli/ui/banner.js.map +1 -0
  247. package/dist/cli/ui/colors.d.ts +76 -0
  248. package/dist/cli/ui/colors.d.ts.map +1 -0
  249. package/dist/cli/ui/colors.js +67 -0
  250. package/dist/cli/ui/colors.js.map +1 -0
  251. package/dist/cli/ui/index.d.ts +7 -0
  252. package/dist/cli/ui/index.d.ts.map +1 -0
  253. package/dist/cli/ui/index.js +4 -0
  254. package/dist/cli/ui/index.js.map +1 -0
  255. package/dist/cli/ui/output.d.ts +117 -0
  256. package/dist/cli/ui/output.d.ts.map +1 -0
  257. package/dist/cli/ui/output.js +83 -0
  258. package/dist/cli/ui/output.js.map +1 -0
  259. package/dist/cli/ui/spinner.d.ts +120 -0
  260. package/dist/cli/ui/spinner.d.ts.map +1 -0
  261. package/dist/cli/ui/spinner.js +158 -0
  262. package/dist/cli/ui/spinner.js.map +1 -0
  263. package/dist/cli/ui/time.d.ts +54 -0
  264. package/dist/cli/ui/time.d.ts.map +1 -0
  265. package/dist/cli/ui/time.js +119 -0
  266. package/dist/cli/ui/time.js.map +1 -0
  267. package/dist/client/api-client.d.ts +123 -0
  268. package/dist/client/api-client.d.ts.map +1 -0
  269. package/dist/client/api-client.js +105 -0
  270. package/dist/client/api-client.js.map +1 -0
  271. package/dist/client/cli-client.d.ts +26 -0
  272. package/dist/client/cli-client.d.ts.map +1 -0
  273. package/dist/client/cli-client.js +20 -0
  274. package/dist/client/cli-client.js.map +1 -0
  275. package/dist/config/index.d.ts +78 -0
  276. package/dist/config/index.d.ts.map +1 -0
  277. package/dist/config/index.js +79 -0
  278. package/dist/config/index.js.map +1 -0
  279. package/dist/index.d.ts +16 -0
  280. package/dist/index.d.ts.map +1 -0
  281. package/dist/index.js +73 -0
  282. package/dist/index.js.map +1 -0
  283. package/dist/lib/format.d.ts +126 -0
  284. package/dist/lib/format.d.ts.map +1 -0
  285. package/dist/lib/format.js +71 -0
  286. package/dist/lib/format.js.map +1 -0
  287. package/dist/lib/index.d.ts +11 -0
  288. package/dist/lib/index.d.ts.map +1 -0
  289. package/dist/lib/index.js +45 -0
  290. package/dist/lib/index.js.map +1 -0
  291. package/dist/lib/monorepo-detector.d.ts +31 -0
  292. package/dist/lib/monorepo-detector.d.ts.map +1 -0
  293. package/dist/lib/monorepo-detector.js +188 -0
  294. package/dist/lib/monorepo-detector.js.map +1 -0
  295. package/dist/lib/prompt-generator.d.ts +65 -0
  296. package/dist/lib/prompt-generator.d.ts.map +1 -0
  297. package/dist/lib/prompt-generator.js +162 -0
  298. package/dist/lib/prompt-generator.js.map +1 -0
  299. package/dist/lib/strategy-analyzer.d.ts +59 -0
  300. package/dist/lib/strategy-analyzer.d.ts.map +1 -0
  301. package/dist/lib/strategy-analyzer.js +91 -0
  302. package/dist/lib/strategy-analyzer.js.map +1 -0
  303. package/dist/lib/workflow-definitions.d.ts +41 -0
  304. package/dist/lib/workflow-definitions.d.ts.map +1 -0
  305. package/dist/lib/workflow-definitions.js +497 -0
  306. package/dist/lib/workflow-definitions.js.map +1 -0
  307. package/dist/patterns/index.d.ts +9 -0
  308. package/dist/patterns/index.d.ts.map +1 -0
  309. package/dist/patterns/index.js +21 -0
  310. package/dist/patterns/index.js.map +1 -0
  311. package/dist/patterns/inheritance.d.ts +193 -0
  312. package/dist/patterns/inheritance.d.ts.map +1 -0
  313. package/dist/patterns/inheritance.js +125 -0
  314. package/dist/patterns/inheritance.js.map +1 -0
  315. package/dist/server.d.ts +44 -0
  316. package/dist/server.d.ts.map +1 -0
  317. package/dist/server.js +91 -0
  318. package/dist/server.js.map +1 -0
  319. package/dist/tools/core/context-helper.d.ts +50 -0
  320. package/dist/tools/core/context-helper.d.ts.map +1 -0
  321. package/dist/tools/core/context-helper.js +49 -0
  322. package/dist/tools/core/context-helper.js.map +1 -0
  323. package/dist/tools/core/index.d.ts +2 -0
  324. package/dist/tools/core/index.d.ts.map +1 -0
  325. package/dist/tools/core/index.js +2 -0
  326. package/dist/tools/core/index.js.map +1 -0
  327. package/dist/tools/index.d.ts +58 -0
  328. package/dist/tools/index.d.ts.map +1 -0
  329. package/dist/tools/index.js +1499 -0
  330. package/dist/tools/index.js.map +1 -0
  331. package/dist/transport/__tests__/resolve-endpoint.test.d.ts +6 -0
  332. package/dist/transport/__tests__/resolve-endpoint.test.d.ts.map +1 -0
  333. package/dist/transport/index.d.ts +6 -0
  334. package/dist/transport/index.d.ts.map +1 -0
  335. package/dist/transport/index.js +5 -0
  336. package/dist/transport/index.js.map +1 -0
  337. package/dist/transport/interface.d.ts +25 -0
  338. package/dist/transport/interface.d.ts.map +1 -0
  339. package/dist/transport/interface.js +1 -0
  340. package/dist/transport/interface.js.map +1 -0
  341. package/dist/transport/remote.d.ts +38 -0
  342. package/dist/transport/remote.d.ts.map +1 -0
  343. package/dist/transport/remote.js +107 -0
  344. package/dist/transport/remote.js.map +1 -0
  345. package/dist/transport/resolve-endpoint.d.ts +58 -0
  346. package/dist/transport/resolve-endpoint.d.ts.map +1 -0
  347. package/dist/transport/resolve-endpoint.js +146 -0
  348. package/dist/transport/resolve-endpoint.js.map +1 -0
  349. package/dist/types/index.d.ts +212 -0
  350. package/dist/types/index.d.ts.map +1 -0
  351. package/dist/types/index.js +16 -0
  352. package/dist/types/index.js.map +1 -0
  353. package/dist/validation/index.d.ts +86 -0
  354. package/dist/validation/index.d.ts.map +1 -0
  355. package/dist/validation/index.js +392 -0
  356. package/dist/validation/index.js.map +1 -0
  357. package/dist/validation/ticket-validation.d.ts +162 -0
  358. package/dist/validation/ticket-validation.d.ts.map +1 -0
  359. package/dist/validation/ticket-validation.js +188 -0
  360. package/dist/validation/ticket-validation.js.map +1 -0
  361. package/package.json +69 -0
  362. package/src/cli/templates/agents/content/core/sfag-orchestrator.ts +165 -0
  363. package/src/cli/templates/agents/content/core/sfag-spec-creator.ts +348 -0
  364. package/src/cli/templates/agents/content/core/sfag-ticket-implementer.ts +259 -0
  365. package/src/cli/templates/agents/content/research/sfag-package-researcher.ts +132 -0
  366. package/src/cli/templates/agents/index.ts +47 -0
  367. package/src/cli/templates/commands.ts +90 -0
  368. package/src/cli/templates/content/sf-blockers.ts +71 -0
  369. package/src/cli/templates/content/sf-commit.ts +81 -0
  370. package/src/cli/templates/content/sf-context.ts +65 -0
  371. package/src/cli/templates/content/sf-help.ts +44 -0
  372. package/src/cli/templates/content/sf-init.ts +64 -0
  373. package/src/cli/templates/content/sf-reset.ts +69 -0
  374. package/src/cli/templates/content/sf-search.ts +65 -0
  375. package/src/cli/templates/content/sf-status.ts +64 -0
  376. package/src/cli/templates/index.ts +16 -0
  377. package/src/cli/templates/skills/specforge-conventions.md +114 -0
  378. package/src/cli/templates/skills/specforge-orchestrator.md +409 -0
  379. package/src/cli/templates/skills/specforge-validator.md +128 -0
  380. package/src/cli/templates/skills/specforge-worker.md +412 -0
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Doctor Command Types
3
+ *
4
+ * Type definitions for the doctor command health checks.
5
+ */
6
+ /**
7
+ * Doctor command options from Commander
8
+ */
9
+ export interface DoctorOptions {
10
+ /** Output as JSON instead of formatted text */
11
+ json?: boolean;
12
+ /** Attempt to fix issues automatically */
13
+ fix?: boolean;
14
+ }
15
+ /**
16
+ * Check status result
17
+ */
18
+ export type CheckStatus = 'pass' | 'fail' | 'warn';
19
+ /**
20
+ * Individual check result
21
+ */
22
+ export interface CheckResult {
23
+ /** Name/title of the check */
24
+ name: string;
25
+ /** Status of the check */
26
+ status: CheckStatus;
27
+ /** Detailed message about the result */
28
+ message: string;
29
+ /** Fix suggestion if check failed/warned */
30
+ fix?: string;
31
+ /** Additional metadata for JSON output */
32
+ metadata?: Record<string, unknown>;
33
+ }
34
+ /**
35
+ * Check category names
36
+ */
37
+ export type CheckCategory = 'configuration' | 'authentication' | 'connection' | 'projectAccess';
38
+ /**
39
+ * Doctor report structure
40
+ */
41
+ export interface DoctorReport {
42
+ /** Check results grouped by category */
43
+ checks: Record<CheckCategory, CheckResult[]>;
44
+ /** Summary counts */
45
+ summary: DoctorSummary;
46
+ /** Timestamp of the check */
47
+ timestamp: string;
48
+ /** Version of the CLI */
49
+ version?: string;
50
+ }
51
+ /**
52
+ * Doctor report summary
53
+ */
54
+ export interface DoctorSummary {
55
+ /** Number of passed checks */
56
+ passed: number;
57
+ /** Number of failed checks */
58
+ failed: number;
59
+ /** Number of warnings */
60
+ warnings: number;
61
+ /** Total number of checks */
62
+ total: number;
63
+ }
64
+ /**
65
+ * Check category display info
66
+ */
67
+ export interface CheckCategoryInfo {
68
+ /** Category identifier */
69
+ id: CheckCategory;
70
+ /** Display name */
71
+ name: string;
72
+ /** Description */
73
+ description: string;
74
+ }
75
+ /**
76
+ * Check category definitions with display info
77
+ */
78
+ export declare const CHECK_CATEGORIES: CheckCategoryInfo[];
79
+ /**
80
+ * Check name constants for configuration checks
81
+ */
82
+ export declare const CONFIG_CHECK_NAMES: {
83
+ readonly CHANNEL: "Channel";
84
+ readonly MCP_CONFIG_FOUND: ".mcp.json found";
85
+ readonly PROJECT_CONFIG_FOUND: "project config found";
86
+ readonly GLOBAL_CONFIG_DIR: "Global config";
87
+ readonly API_KEY_CONFIGURED: "API key configured";
88
+ readonly PLANNING_SESSION: "Active planning session";
89
+ };
90
+ /**
91
+ * Check name constants for authentication checks
92
+ */
93
+ export declare const AUTH_CHECK_NAMES: {
94
+ readonly API_KEY_FORMAT: "API key format valid";
95
+ readonly API_KEY_AUTHENTICATED: "API key authenticated";
96
+ readonly USER_INFO: "User info";
97
+ };
98
+ /**
99
+ * Check name constants for connection checks
100
+ */
101
+ export declare const CONNECTION_CHECK_NAMES: {
102
+ readonly API_ENDPOINT_REACHABLE: "API endpoint reachable";
103
+ readonly RESPONSE_TIME: "Response time";
104
+ };
105
+ /**
106
+ * Check name constants for project access checks
107
+ */
108
+ export declare const PROJECT_CHECK_NAMES: {
109
+ readonly PROJECT_ACCESSIBLE: "Default project accessible";
110
+ readonly SPECIFICATION_ACCESSIBLE: "Default specification accessible";
111
+ readonly IMPLEMENTATION_SESSION: "Implementation session";
112
+ };
113
+ /**
114
+ * Thresholds for performance checks
115
+ */
116
+ export declare const PERFORMANCE_THRESHOLDS: {
117
+ /** Response time warning threshold in ms */
118
+ readonly RESPONSE_TIME_WARNING: 500;
119
+ /** Response time error threshold in ms */
120
+ readonly RESPONSE_TIME_ERROR: 5000;
121
+ /** Connection timeout in ms */
122
+ readonly CONNECTION_TIMEOUT: 10000;
123
+ };
124
+ /**
125
+ * API key validation constants
126
+ */
127
+ export declare const API_KEY_VALIDATION: {
128
+ /** Required prefix for live API keys */
129
+ readonly PREFIX: "sf_live_";
130
+ /** Minimum length for valid API key */
131
+ readonly MIN_LENGTH: 28;
132
+ };
133
+ /**
134
+ * Fix suggestion templates
135
+ */
136
+ export declare const FIX_SUGGESTIONS: {
137
+ readonly MISSING_MCP_CONFIG: "Run 'specforge init' to create configuration";
138
+ readonly MISSING_PROJECT_CONFIG: "Run 'specforge init' to create configuration";
139
+ readonly MISSING_API_KEY: "Run 'specforge login' to authenticate";
140
+ readonly INVALID_API_KEY_FORMAT: "Get a valid API key from https://specforge.com.br/settings/api-keys";
141
+ readonly EXPIRED_API_KEY: "Run 'specforge login --force' to re-authenticate";
142
+ readonly CONNECTION_FAILED: "Check your internet connection";
143
+ readonly CONNECTION_TIMEOUT: "Check your internet connection or try again later";
144
+ readonly PROJECT_NOT_ACCESSIBLE: "Run 'specforge init' to reconfigure project";
145
+ readonly SPEC_NOT_ACCESSIBLE: "Run 'specforge init' to reconfigure specification";
146
+ readonly NO_PROJECT_CONFIGURED: "Run 'specforge init' to configure a project";
147
+ };
148
+ /**
149
+ * Create a passing check result
150
+ */
151
+ export declare function createPassResult(name: string, message: string, metadata?: Record<string, unknown>): CheckResult;
152
+ /**
153
+ * Create a failing check result
154
+ */
155
+ export declare function createFailResult(name: string, message: string, fix?: string, metadata?: Record<string, unknown>): CheckResult;
156
+ /**
157
+ * Create a warning check result
158
+ */
159
+ export declare function createWarnResult(name: string, message: string, fix?: string, metadata?: Record<string, unknown>): CheckResult;
160
+ /**
161
+ * Calculate summary from check results
162
+ */
163
+ export declare function calculateSummary(checks: Record<CheckCategory, CheckResult[]>): DoctorSummary;
164
+ /**
165
+ * Create an empty report structure
166
+ */
167
+ export declare function createEmptyReport(): DoctorReport;
168
+ /**
169
+ * Check if the report has any failures
170
+ */
171
+ export declare function hasFailures(report: DoctorReport): boolean;
172
+ /**
173
+ * Check if the report has any warnings
174
+ */
175
+ export declare function hasWarnings(report: DoctorReport): boolean;
176
+ /**
177
+ * Get status icon for display
178
+ */
179
+ export declare function getStatusIcon(status: CheckStatus): string;
180
+ //# sourceMappingURL=doctor.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.types.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,140 @@
1
+ const CHECK_CATEGORIES = [
2
+ {
3
+ id: "configuration",
4
+ name: "Configuration",
5
+ description: "Config file presence and validity"
6
+ },
7
+ {
8
+ id: "authentication",
9
+ name: "Authentication",
10
+ description: "API key format and authentication"
11
+ },
12
+ {
13
+ id: "connection",
14
+ name: "Connection",
15
+ description: "API connectivity and response time"
16
+ },
17
+ {
18
+ id: "projectAccess",
19
+ name: "Project Access",
20
+ description: "Access to configured project and specification"
21
+ }
22
+ ];
23
+ const CONFIG_CHECK_NAMES = {
24
+ CHANNEL: "Channel",
25
+ MCP_CONFIG_FOUND: ".mcp.json found",
26
+ PROJECT_CONFIG_FOUND: "project config found",
27
+ GLOBAL_CONFIG_DIR: "Global config",
28
+ API_KEY_CONFIGURED: "API key configured",
29
+ PLANNING_SESSION: "Active planning session"
30
+ };
31
+ const AUTH_CHECK_NAMES = {
32
+ API_KEY_FORMAT: "API key format valid",
33
+ API_KEY_AUTHENTICATED: "API key authenticated",
34
+ USER_INFO: "User info"
35
+ };
36
+ const CONNECTION_CHECK_NAMES = {
37
+ API_ENDPOINT_REACHABLE: "API endpoint reachable",
38
+ RESPONSE_TIME: "Response time"
39
+ };
40
+ const PROJECT_CHECK_NAMES = {
41
+ PROJECT_ACCESSIBLE: "Default project accessible",
42
+ SPECIFICATION_ACCESSIBLE: "Default specification accessible",
43
+ IMPLEMENTATION_SESSION: "Implementation session"
44
+ };
45
+ const PERFORMANCE_THRESHOLDS = {
46
+ /** Response time warning threshold in ms */
47
+ RESPONSE_TIME_WARNING: 500,
48
+ /** Response time error threshold in ms */
49
+ RESPONSE_TIME_ERROR: 5e3,
50
+ /** Connection timeout in ms */
51
+ CONNECTION_TIMEOUT: 1e4
52
+ };
53
+ const API_KEY_VALIDATION = {
54
+ /** Required prefix for live API keys */
55
+ PREFIX: "sf_live_",
56
+ /** Minimum length for valid API key */
57
+ MIN_LENGTH: 28
58
+ };
59
+ const FIX_SUGGESTIONS = {
60
+ MISSING_MCP_CONFIG: "Run 'specforge init' to create configuration",
61
+ MISSING_PROJECT_CONFIG: "Run 'specforge init' to create configuration",
62
+ MISSING_API_KEY: "Run 'specforge login' to authenticate",
63
+ INVALID_API_KEY_FORMAT: "Get a valid API key from https://specforge.com.br/settings/api-keys",
64
+ EXPIRED_API_KEY: "Run 'specforge login --force' to re-authenticate",
65
+ CONNECTION_FAILED: "Check your internet connection",
66
+ CONNECTION_TIMEOUT: "Check your internet connection or try again later",
67
+ PROJECT_NOT_ACCESSIBLE: "Run 'specforge init' to reconfigure project",
68
+ SPEC_NOT_ACCESSIBLE: "Run 'specforge init' to reconfigure specification",
69
+ NO_PROJECT_CONFIGURED: "Run 'specforge init' to configure a project"
70
+ };
71
+ function createPassResult(name, message, metadata) {
72
+ return { name, status: "pass", message, metadata };
73
+ }
74
+ function createFailResult(name, message, fix, metadata) {
75
+ return { name, status: "fail", message, fix, metadata };
76
+ }
77
+ function createWarnResult(name, message, fix, metadata) {
78
+ return { name, status: "warn", message, fix, metadata };
79
+ }
80
+ function calculateSummary(checks) {
81
+ const allChecks = Object.values(checks).flat();
82
+ return {
83
+ passed: allChecks.filter((c) => c.status === "pass").length,
84
+ failed: allChecks.filter((c) => c.status === "fail").length,
85
+ warnings: allChecks.filter((c) => c.status === "warn").length,
86
+ total: allChecks.length
87
+ };
88
+ }
89
+ function createEmptyReport() {
90
+ return {
91
+ checks: {
92
+ configuration: [],
93
+ authentication: [],
94
+ connection: [],
95
+ projectAccess: []
96
+ },
97
+ summary: {
98
+ passed: 0,
99
+ failed: 0,
100
+ warnings: 0,
101
+ total: 0
102
+ },
103
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
104
+ };
105
+ }
106
+ function hasFailures(report) {
107
+ return report.summary.failed > 0;
108
+ }
109
+ function hasWarnings(report) {
110
+ return report.summary.warnings > 0;
111
+ }
112
+ function getStatusIcon(status) {
113
+ switch (status) {
114
+ case "pass":
115
+ return "\u2713";
116
+ case "fail":
117
+ return "\u2717";
118
+ case "warn":
119
+ return "\u26A0";
120
+ }
121
+ }
122
+ export {
123
+ API_KEY_VALIDATION,
124
+ AUTH_CHECK_NAMES,
125
+ CHECK_CATEGORIES,
126
+ CONFIG_CHECK_NAMES,
127
+ CONNECTION_CHECK_NAMES,
128
+ FIX_SUGGESTIONS,
129
+ PERFORMANCE_THRESHOLDS,
130
+ PROJECT_CHECK_NAMES,
131
+ calculateSummary,
132
+ createEmptyReport,
133
+ createFailResult,
134
+ createPassResult,
135
+ createWarnResult,
136
+ getStatusIcon,
137
+ hasFailures,
138
+ hasWarnings
139
+ };
140
+ //# sourceMappingURL=doctor.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/doctor.types.ts"],"sourcesContent":["/**\n * Doctor Command Types\n *\n * Type definitions for the doctor command health checks.\n */\n\n/**\n * Doctor command options from Commander\n */\nexport interface DoctorOptions {\n /** Output as JSON instead of formatted text */\n json?: boolean;\n /** Attempt to fix issues automatically */\n fix?: boolean;\n}\n\n/**\n * Check status result\n */\nexport type CheckStatus = 'pass' | 'fail' | 'warn';\n\n/**\n * Individual check result\n */\nexport interface CheckResult {\n /** Name/title of the check */\n name: string;\n /** Status of the check */\n status: CheckStatus;\n /** Detailed message about the result */\n message: string;\n /** Fix suggestion if check failed/warned */\n fix?: string;\n /** Additional metadata for JSON output */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Check category names\n */\nexport type CheckCategory = 'configuration' | 'authentication' | 'connection' | 'projectAccess';\n\n/**\n * Doctor report structure\n */\nexport interface DoctorReport {\n /** Check results grouped by category */\n checks: Record<CheckCategory, CheckResult[]>;\n /** Summary counts */\n summary: DoctorSummary;\n /** Timestamp of the check */\n timestamp: string;\n /** Version of the CLI */\n version?: string;\n}\n\n/**\n * Doctor report summary\n */\nexport interface DoctorSummary {\n /** Number of passed checks */\n passed: number;\n /** Number of failed checks */\n failed: number;\n /** Number of warnings */\n warnings: number;\n /** Total number of checks */\n total: number;\n}\n\n/**\n * Check category display info\n */\nexport interface CheckCategoryInfo {\n /** Category identifier */\n id: CheckCategory;\n /** Display name */\n name: string;\n /** Description */\n description: string;\n}\n\n/**\n * Check category definitions with display info\n */\nexport const CHECK_CATEGORIES: CheckCategoryInfo[] = [\n {\n id: 'configuration',\n name: 'Configuration',\n description: 'Config file presence and validity',\n },\n {\n id: 'authentication',\n name: 'Authentication',\n description: 'API key format and authentication',\n },\n {\n id: 'connection',\n name: 'Connection',\n description: 'API connectivity and response time',\n },\n {\n id: 'projectAccess',\n name: 'Project Access',\n description: 'Access to configured project and specification',\n },\n];\n\n/**\n * Check name constants for configuration checks\n */\nexport const CONFIG_CHECK_NAMES = {\n CHANNEL: 'Channel',\n MCP_CONFIG_FOUND: '.mcp.json found',\n PROJECT_CONFIG_FOUND: 'project config found',\n GLOBAL_CONFIG_DIR: 'Global config',\n API_KEY_CONFIGURED: 'API key configured',\n PLANNING_SESSION: 'Active planning session',\n} as const;\n\n/**\n * Check name constants for authentication checks\n */\nexport const AUTH_CHECK_NAMES = {\n API_KEY_FORMAT: 'API key format valid',\n API_KEY_AUTHENTICATED: 'API key authenticated',\n USER_INFO: 'User info',\n} as const;\n\n/**\n * Check name constants for connection checks\n */\nexport const CONNECTION_CHECK_NAMES = {\n API_ENDPOINT_REACHABLE: 'API endpoint reachable',\n RESPONSE_TIME: 'Response time',\n} as const;\n\n/**\n * Check name constants for project access checks\n */\nexport const PROJECT_CHECK_NAMES = {\n PROJECT_ACCESSIBLE: 'Default project accessible',\n SPECIFICATION_ACCESSIBLE: 'Default specification accessible',\n IMPLEMENTATION_SESSION: 'Implementation session',\n} as const;\n\n/**\n * Thresholds for performance checks\n */\nexport const PERFORMANCE_THRESHOLDS = {\n /** Response time warning threshold in ms */\n RESPONSE_TIME_WARNING: 500,\n /** Response time error threshold in ms */\n RESPONSE_TIME_ERROR: 5000,\n /** Connection timeout in ms */\n CONNECTION_TIMEOUT: 10000,\n} as const;\n\n/**\n * API key validation constants\n */\nexport const API_KEY_VALIDATION = {\n /** Required prefix for live API keys */\n PREFIX: 'sf_live_',\n /** Minimum length for valid API key */\n MIN_LENGTH: 28,\n} as const;\n\n/**\n * Fix suggestion templates\n */\nexport const FIX_SUGGESTIONS = {\n MISSING_MCP_CONFIG: \"Run 'specforge init' to create configuration\",\n MISSING_PROJECT_CONFIG: \"Run 'specforge init' to create configuration\",\n MISSING_API_KEY: \"Run 'specforge login' to authenticate\",\n INVALID_API_KEY_FORMAT: 'Get a valid API key from https://specforge.com.br/settings/api-keys',\n EXPIRED_API_KEY: \"Run 'specforge login --force' to re-authenticate\",\n CONNECTION_FAILED: 'Check your internet connection',\n CONNECTION_TIMEOUT: 'Check your internet connection or try again later',\n PROJECT_NOT_ACCESSIBLE: \"Run 'specforge init' to reconfigure project\",\n SPEC_NOT_ACCESSIBLE: \"Run 'specforge init' to reconfigure specification\",\n NO_PROJECT_CONFIGURED: \"Run 'specforge init' to configure a project\",\n} as const;\n\n/**\n * Create a passing check result\n */\nexport function createPassResult(name: string, message: string, metadata?: Record<string, unknown>): CheckResult {\n return { name, status: 'pass', message, metadata };\n}\n\n/**\n * Create a failing check result\n */\nexport function createFailResult(name: string, message: string, fix?: string, metadata?: Record<string, unknown>): CheckResult {\n return { name, status: 'fail', message, fix, metadata };\n}\n\n/**\n * Create a warning check result\n */\nexport function createWarnResult(name: string, message: string, fix?: string, metadata?: Record<string, unknown>): CheckResult {\n return { name, status: 'warn', message, fix, metadata };\n}\n\n/**\n * Calculate summary from check results\n */\nexport function calculateSummary(checks: Record<CheckCategory, CheckResult[]>): DoctorSummary {\n const allChecks = Object.values(checks).flat();\n return {\n passed: allChecks.filter(c => c.status === 'pass').length,\n failed: allChecks.filter(c => c.status === 'fail').length,\n warnings: allChecks.filter(c => c.status === 'warn').length,\n total: allChecks.length,\n };\n}\n\n/**\n * Create an empty report structure\n */\nexport function createEmptyReport(): DoctorReport {\n return {\n checks: {\n configuration: [],\n authentication: [],\n connection: [],\n projectAccess: [],\n },\n summary: {\n passed: 0,\n failed: 0,\n warnings: 0,\n total: 0,\n },\n timestamp: new Date().toISOString(),\n };\n}\n\n/**\n * Check if the report has any failures\n */\nexport function hasFailures(report: DoctorReport): boolean {\n return report.summary.failed > 0;\n}\n\n/**\n * Check if the report has any warnings\n */\nexport function hasWarnings(report: DoctorReport): boolean {\n return report.summary.warnings > 0;\n}\n\n/**\n * Get status icon for display\n */\nexport function getStatusIcon(status: CheckStatus): string {\n switch (status) {\n case 'pass':\n return '✓';\n case 'fail':\n return '✗';\n case 'warn':\n return '⚠';\n }\n}\n"],"mappings":"AAqFO,MAAM,mBAAwC;AAAA,EACnD;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AACF;AAKO,MAAM,qBAAqB;AAAA,EAChC,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,kBAAkB;AACpB;AAKO,MAAM,mBAAmB;AAAA,EAC9B,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,WAAW;AACb;AAKO,MAAM,yBAAyB;AAAA,EACpC,wBAAwB;AAAA,EACxB,eAAe;AACjB;AAKO,MAAM,sBAAsB;AAAA,EACjC,oBAAoB;AAAA,EACpB,0BAA0B;AAAA,EAC1B,wBAAwB;AAC1B;AAKO,MAAM,yBAAyB;AAAA;AAAA,EAEpC,uBAAuB;AAAA;AAAA,EAEvB,qBAAqB;AAAA;AAAA,EAErB,oBAAoB;AACtB;AAKO,MAAM,qBAAqB;AAAA;AAAA,EAEhC,QAAQ;AAAA;AAAA,EAER,YAAY;AACd;AAKO,MAAM,kBAAkB;AAAA,EAC7B,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,uBAAuB;AACzB;AAKO,SAAS,iBAAiB,MAAc,SAAiB,UAAiD;AAC/G,SAAO,EAAE,MAAM,QAAQ,QAAQ,SAAS,SAAS;AACnD;AAKO,SAAS,iBAAiB,MAAc,SAAiB,KAAc,UAAiD;AAC7H,SAAO,EAAE,MAAM,QAAQ,QAAQ,SAAS,KAAK,SAAS;AACxD;AAKO,SAAS,iBAAiB,MAAc,SAAiB,KAAc,UAAiD;AAC7H,SAAO,EAAE,MAAM,QAAQ,QAAQ,SAAS,KAAK,SAAS;AACxD;AAKO,SAAS,iBAAiB,QAA6D;AAC5F,QAAM,YAAY,OAAO,OAAO,MAAM,EAAE,KAAK;AAC7C,SAAO;AAAA,IACL,QAAQ,UAAU,OAAO,OAAK,EAAE,WAAW,MAAM,EAAE;AAAA,IACnD,QAAQ,UAAU,OAAO,OAAK,EAAE,WAAW,MAAM,EAAE;AAAA,IACnD,UAAU,UAAU,OAAO,OAAK,EAAE,WAAW,MAAM,EAAE;AAAA,IACrD,OAAO,UAAU;AAAA,EACnB;AACF;AAKO,SAAS,oBAAkC;AAChD,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,eAAe,CAAC;AAAA,MAChB,gBAAgB,CAAC;AAAA,MACjB,YAAY,CAAC;AAAA,MACb,eAAe,CAAC;AAAA,IAClB;AAAA,IACA,SAAS;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,OAAO;AAAA,IACT;AAAA,IACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACF;AAKO,SAAS,YAAY,QAA+B;AACzD,SAAO,OAAO,QAAQ,SAAS;AACjC;AAKO,SAAS,YAAY,QAA+B;AACzD,SAAO,OAAO,QAAQ,WAAW;AACnC;AAKO,SAAS,cAAc,QAA6B;AACzD,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;","names":[]}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Feedback Command
3
+ *
4
+ * Lists and submits feedback via the MCP API.
5
+ */
6
+ import { Command } from 'commander';
7
+ import { FeedbackOptions } from './feedback.types.js';
8
+ /**
9
+ * Feedback list action handler
10
+ */
11
+ export declare function feedbackAction(options: FeedbackOptions): Promise<void>;
12
+ /**
13
+ * Feedback submit action handler
14
+ */
15
+ export declare function feedbackSubmitAction(options: {
16
+ category: string;
17
+ summary: string;
18
+ severity?: string;
19
+ tool?: string;
20
+ details?: string;
21
+ json?: boolean;
22
+ }): Promise<void>;
23
+ /**
24
+ * Register feedback command with Commander
25
+ */
26
+ export declare function registerFeedbackCommand(program: Command): void;
27
+ //# sourceMappingURL=feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/feedback.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,OAAO,EACL,eAAe,EAUhB,MAAM,qBAAqB,CAAC;AAoJ7B;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAgE5E;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuDhB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6D9D"}
@@ -0,0 +1,262 @@
1
+ import ora from "ora";
2
+ import { resolveConfig } from "../config/index.js";
3
+ import { ApiClient } from "../../client/api-client.js";
4
+ import { withErrorHandler, CliError } from "../middleware/error-handler.js";
5
+ import { printBlank, printHeader } from "../ui/output.js";
6
+ import { colors } from "../ui/colors.js";
7
+ import {
8
+ VALID_CATEGORIES,
9
+ CATEGORY_COLORS,
10
+ SEVERITY_COLORS,
11
+ isValidCategory,
12
+ truncateSummary
13
+ } from "./feedback.types.js";
14
+ function getCategoryColorFn(category) {
15
+ const colorName = CATEGORY_COLORS[category];
16
+ switch (colorName) {
17
+ case "red":
18
+ return colors.error;
19
+ case "blue":
20
+ return colors.primary;
21
+ case "yellow":
22
+ return colors.warning;
23
+ case "cyan":
24
+ return (s) => colors.primary(s);
25
+ case "magenta":
26
+ return (s) => colors.primary(s);
27
+ default:
28
+ return (s) => s;
29
+ }
30
+ }
31
+ function getSeverityColorFn(severity) {
32
+ const colorName = SEVERITY_COLORS[severity];
33
+ switch (colorName) {
34
+ case "red":
35
+ return colors.error;
36
+ case "yellow":
37
+ return colors.warning;
38
+ case "blue":
39
+ return colors.primary;
40
+ case "dim":
41
+ return colors.muted;
42
+ default:
43
+ return (s) => s;
44
+ }
45
+ }
46
+ function displayFeedbackTable(entries, total) {
47
+ printBlank();
48
+ printHeader("Feedback");
49
+ printBlank();
50
+ if (entries.length === 0) {
51
+ console.log(colors.muted("No feedback entries found."));
52
+ printBlank();
53
+ return;
54
+ }
55
+ const header = [
56
+ "ID".padEnd(24),
57
+ "CATEGORY".padEnd(16),
58
+ "SEVERITY".padEnd(10),
59
+ "TOOL".padEnd(12),
60
+ "SUMMARY"
61
+ ].join(" ");
62
+ console.log(colors.muted(header));
63
+ console.log(colors.muted("\u2500".repeat(header.length)));
64
+ for (const entry of entries) {
65
+ const categoryColor = getCategoryColorFn(entry.category);
66
+ const severityColor = getSeverityColorFn(entry.severity);
67
+ const row = [
68
+ entry.id.padEnd(24),
69
+ categoryColor(entry.category.padEnd(16)),
70
+ severityColor(entry.severity.padEnd(10)),
71
+ (entry.tool || "-").padEnd(12),
72
+ truncateSummary(entry.summary)
73
+ ].join(" ");
74
+ console.log(row);
75
+ }
76
+ printBlank();
77
+ console.log(colors.muted(`Total: ${total} ${total === 1 ? "entry" : "entries"}`));
78
+ printBlank();
79
+ }
80
+ function displayEmptyState() {
81
+ printBlank();
82
+ console.log(colors.muted("No feedback entries found."));
83
+ console.log(
84
+ colors.muted('Use "specforge feedback submit" to submit feedback.')
85
+ );
86
+ printBlank();
87
+ }
88
+ function formatFeedbackAsToon(entries, total) {
89
+ const lines = ["@feedback"];
90
+ lines.push(` total: ${total}`);
91
+ lines.push(" entries:");
92
+ for (const entry of entries) {
93
+ lines.push(` - ${entry.id}`);
94
+ lines.push(` category: ${entry.category}`);
95
+ lines.push(` severity: ${entry.severity}`);
96
+ if (entry.tool) {
97
+ lines.push(` tool: ${entry.tool}`);
98
+ }
99
+ lines.push(` summary: ${entry.summary}`);
100
+ lines.push(` createdAt: ${entry.createdAt}`);
101
+ }
102
+ return lines.join("\n");
103
+ }
104
+ function createClient() {
105
+ const config = resolveConfig();
106
+ if (!config.apiKey) {
107
+ throw new CliError(
108
+ "Not authenticated",
109
+ 1,
110
+ "Run `specforge login` to authenticate first"
111
+ );
112
+ }
113
+ return new ApiClient(
114
+ {
115
+ apiKey: config.apiKey,
116
+ apiUrl: config.apiUrl,
117
+ debug: config.debug
118
+ },
119
+ { origin: "cli" }
120
+ );
121
+ }
122
+ async function feedbackAction(options) {
123
+ const spinner = ora({
124
+ text: "Loading feedback...",
125
+ color: "cyan"
126
+ }).start();
127
+ try {
128
+ if (options.category && !isValidCategory(options.category)) {
129
+ spinner.stop();
130
+ throw new CliError(
131
+ `Invalid category: ${options.category}`,
132
+ 1,
133
+ `Valid categories: ${VALID_CATEGORIES.join(", ")}`
134
+ );
135
+ }
136
+ const limit = options.limit ? parseInt(options.limit, 10) : 10;
137
+ if (isNaN(limit) || limit < 1) {
138
+ spinner.stop();
139
+ throw new CliError("Invalid limit", 1, "Limit must be a positive number");
140
+ }
141
+ const client = createClient();
142
+ const response = await client.call("feedback", {
143
+ operation: "list",
144
+ limit,
145
+ categoryFilter: options.category || void 0
146
+ });
147
+ spinner.stop();
148
+ const entries = response.entries || [];
149
+ const total = response.total || entries.length;
150
+ if (options.json) {
151
+ console.log(JSON.stringify(response, null, 2));
152
+ return;
153
+ }
154
+ if (options.toon) {
155
+ console.log(formatFeedbackAsToon(entries, total));
156
+ return;
157
+ }
158
+ if (entries.length === 0) {
159
+ displayEmptyState();
160
+ } else {
161
+ displayFeedbackTable(entries, total);
162
+ }
163
+ } catch (error) {
164
+ spinner.stop();
165
+ if (error instanceof CliError) {
166
+ throw error;
167
+ }
168
+ const message = error instanceof Error ? error.message : "Unknown error";
169
+ throw new CliError(`Failed to load feedback: ${message}`, 1);
170
+ }
171
+ }
172
+ async function feedbackSubmitAction(options) {
173
+ if (!isValidCategory(options.category)) {
174
+ throw new CliError(
175
+ `Invalid category: ${options.category}`,
176
+ 1,
177
+ `Valid categories: ${VALID_CATEGORIES.join(", ")}`
178
+ );
179
+ }
180
+ const spinner = ora({
181
+ text: "Submitting feedback...",
182
+ color: "cyan"
183
+ }).start();
184
+ try {
185
+ const client = createClient();
186
+ const response = await client.call("feedback", {
187
+ operation: "submit",
188
+ category: options.category,
189
+ summary: options.summary,
190
+ severity: options.severity || "medium",
191
+ tool: options.tool || void 0,
192
+ details: options.details || void 0
193
+ });
194
+ spinner.stop();
195
+ if (options.json) {
196
+ console.log(JSON.stringify(response, null, 2));
197
+ return;
198
+ }
199
+ printBlank();
200
+ console.log(colors.success("\u2713") + " Feedback submitted");
201
+ console.log(colors.muted("\u2500".repeat(40)));
202
+ console.log(colors.muted(` ID: ${response.feedbackId}`));
203
+ console.log(colors.muted(` Category: ${options.category}`));
204
+ console.log(colors.muted(` Summary: ${options.summary}`));
205
+ printBlank();
206
+ } catch (error) {
207
+ spinner.stop();
208
+ if (error instanceof CliError) {
209
+ throw error;
210
+ }
211
+ const message = error instanceof Error ? error.message : "Unknown error";
212
+ throw new CliError(`Failed to submit feedback: ${message}`, 1);
213
+ }
214
+ }
215
+ function registerFeedbackCommand(program) {
216
+ const feedback = program.command("feedback").description("List and submit feedback");
217
+ feedback.option("--json", "Output as JSON").option("--toon", "Output as TOON format").option(
218
+ "--category <category>",
219
+ `Filter by category (${VALID_CATEGORIES.join(", ")})`
220
+ ).option("--limit <n>", "Limit number of results", "10").action(withErrorHandler(feedbackAction));
221
+ feedback.command("submit <summary>").description("Submit new feedback").requiredOption(
222
+ "-c, --category <category>",
223
+ `Category (${VALID_CATEGORIES.join(", ")})`
224
+ ).option(
225
+ "-s, --severity <severity>",
226
+ "Severity (critical, high, medium, low)",
227
+ "medium"
228
+ ).option("-t, --tool <tool>", "Related MCP tool").option("-d, --details <details>", "Extended description").option("--json", "Output as JSON").action(withErrorHandler(async (summary, opts) => {
229
+ await feedbackSubmitAction({
230
+ summary,
231
+ category: opts.category,
232
+ severity: opts.severity,
233
+ tool: opts.tool,
234
+ details: opts.details,
235
+ json: !!opts.json
236
+ });
237
+ }));
238
+ feedback.addHelpText(
239
+ "after",
240
+ `
241
+ Examples:
242
+ $ specforge feedback # List all feedback
243
+ $ specforge feedback --json # Output as JSON
244
+ $ specforge feedback --category bug # Filter by category
245
+ $ specforge feedback submit "Tool X fails" # Submit feedback
246
+ -c bug -s high -t action_work_session
247
+
248
+ Categories:
249
+ ${colors.error("bug")} - Something isn't working correctly
250
+ ${colors.primary("feature_request")} - New capability suggestion
251
+ ${colors.warning("usability")} - UX/DX improvement
252
+ ${colors.primary("documentation")} - Docs unclear or missing
253
+ ${colors.primary("performance")} - Speed/efficiency issue
254
+ `
255
+ );
256
+ }
257
+ export {
258
+ feedbackAction,
259
+ feedbackSubmitAction,
260
+ registerFeedbackCommand
261
+ };
262
+ //# sourceMappingURL=feedback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/feedback.ts"],"sourcesContent":["/**\n * Feedback Command\n *\n * Lists and submits feedback via the MCP API.\n */\n\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport { resolveConfig } from '../config/index.js';\nimport { ApiClient } from '../../client/api-client.js';\nimport { withErrorHandler, CliError } from '../middleware/error-handler.js';\nimport { printBlank, printHeader } from '../ui/output.js';\nimport { colors } from '../ui/colors.js';\nimport {\n FeedbackOptions,\n FeedbackListEntry,\n FeedbackListResponse,\n VALID_CATEGORIES,\n CATEGORY_COLORS,\n SEVERITY_COLORS,\n isValidCategory,\n truncateSummary,\n type FeedbackCategory,\n type FeedbackSeverity,\n} from './feedback.types.js';\n\n/**\n * Get chalk color function for category\n */\nfunction getCategoryColorFn(category: FeedbackCategory): (s: string) => string {\n const colorName = CATEGORY_COLORS[category];\n switch (colorName) {\n case 'red':\n return colors.error;\n case 'blue':\n return colors.primary;\n case 'yellow':\n return colors.warning;\n case 'cyan':\n return (s: string) => colors.primary(s);\n case 'magenta':\n return (s: string) => colors.primary(s);\n default:\n return (s: string) => s;\n }\n}\n\n/**\n * Get chalk color function for severity\n */\nfunction getSeverityColorFn(severity: FeedbackSeverity): (s: string) => string {\n const colorName = SEVERITY_COLORS[severity];\n switch (colorName) {\n case 'red':\n return colors.error;\n case 'yellow':\n return colors.warning;\n case 'blue':\n return colors.primary;\n case 'dim':\n return colors.muted;\n default:\n return (s: string) => s;\n }\n}\n\n/**\n * Display feedback entries in table format\n */\nfunction displayFeedbackTable(entries: FeedbackListEntry[], total: number): void {\n printBlank();\n printHeader('Feedback');\n printBlank();\n\n if (entries.length === 0) {\n console.log(colors.muted('No feedback entries found.'));\n printBlank();\n return;\n }\n\n // Table header\n const header = [\n 'ID'.padEnd(24),\n 'CATEGORY'.padEnd(16),\n 'SEVERITY'.padEnd(10),\n 'TOOL'.padEnd(12),\n 'SUMMARY',\n ].join(' ');\n console.log(colors.muted(header));\n console.log(colors.muted('─'.repeat(header.length)));\n\n // Table rows\n for (const entry of entries) {\n const categoryColor = getCategoryColorFn(entry.category);\n const severityColor = getSeverityColorFn(entry.severity);\n\n const row = [\n entry.id.padEnd(24),\n categoryColor(entry.category.padEnd(16)),\n severityColor(entry.severity.padEnd(10)),\n (entry.tool || '-').padEnd(12),\n truncateSummary(entry.summary),\n ].join(' ');\n\n console.log(row);\n }\n\n printBlank();\n console.log(colors.muted(`Total: ${total} ${total === 1 ? 'entry' : 'entries'}`));\n printBlank();\n}\n\n/**\n * Display empty state\n */\nfunction displayEmptyState(): void {\n printBlank();\n console.log(colors.muted('No feedback entries found.'));\n console.log(\n colors.muted('Use \"specforge feedback submit\" to submit feedback.')\n );\n printBlank();\n}\n\n/**\n * Format feedback as TOON\n */\nfunction formatFeedbackAsToon(entries: FeedbackListEntry[], total: number): string {\n const lines: string[] = ['@feedback'];\n lines.push(` total: ${total}`);\n lines.push(' entries:');\n\n for (const entry of entries) {\n lines.push(` - ${entry.id}`);\n lines.push(` category: ${entry.category}`);\n lines.push(` severity: ${entry.severity}`);\n if (entry.tool) {\n lines.push(` tool: ${entry.tool}`);\n }\n lines.push(` summary: ${entry.summary}`);\n lines.push(` createdAt: ${entry.createdAt}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Create an ApiClient from resolved config\n */\nfunction createClient(): ApiClient {\n const config = resolveConfig();\n\n if (!config.apiKey) {\n throw new CliError(\n 'Not authenticated',\n 1,\n 'Run `specforge login` to authenticate first'\n );\n }\n\n // M9.7: the human CLI surface stamps origin via the `X-SpecForge-Origin: cli`\n // header (the backend dropped the request-body `source` field in M7.4).\n return new ApiClient(\n {\n apiKey: config.apiKey,\n apiUrl: config.apiUrl,\n debug: config.debug,\n },\n { origin: 'cli' },\n );\n}\n\n/**\n * Feedback list action handler\n */\nexport async function feedbackAction(options: FeedbackOptions): Promise<void> {\n const spinner = ora({\n text: 'Loading feedback...',\n color: 'cyan',\n }).start();\n\n try {\n // Validate category filter if provided\n if (options.category && !isValidCategory(options.category)) {\n spinner.stop();\n throw new CliError(\n `Invalid category: ${options.category}`,\n 1,\n `Valid categories: ${VALID_CATEGORIES.join(', ')}`\n );\n }\n\n // Parse limit\n const limit = options.limit ? parseInt(options.limit, 10) : 10;\n if (isNaN(limit) || limit < 1) {\n spinner.stop();\n throw new CliError('Invalid limit', 1, 'Limit must be a positive number');\n }\n\n const client = createClient();\n\n const response = await client.call<FeedbackListResponse>('feedback', {\n operation: 'list',\n limit,\n categoryFilter: options.category || undefined,\n });\n\n spinner.stop();\n\n const entries: FeedbackListEntry[] = response.entries || [];\n const total = response.total || entries.length;\n\n // Output based on format\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n return;\n }\n\n if (options.toon) {\n console.log(formatFeedbackAsToon(entries, total));\n return;\n }\n\n // Default: table display\n if (entries.length === 0) {\n displayEmptyState();\n } else {\n displayFeedbackTable(entries, total);\n }\n } catch (error) {\n spinner.stop();\n\n if (error instanceof CliError) {\n throw error;\n }\n\n const message = error instanceof Error ? error.message : 'Unknown error';\n throw new CliError(`Failed to load feedback: ${message}`, 1);\n }\n}\n\n/**\n * Feedback submit action handler\n */\nexport async function feedbackSubmitAction(options: {\n category: string;\n summary: string;\n severity?: string;\n tool?: string;\n details?: string;\n json?: boolean;\n}): Promise<void> {\n // Validate category\n if (!isValidCategory(options.category)) {\n throw new CliError(\n `Invalid category: ${options.category}`,\n 1,\n `Valid categories: ${VALID_CATEGORIES.join(', ')}`\n );\n }\n\n const spinner = ora({\n text: 'Submitting feedback...',\n color: 'cyan',\n }).start();\n\n try {\n const client = createClient();\n\n const response = await client.call<{\n success: boolean;\n feedbackId: string;\n message: string;\n }>('feedback', {\n operation: 'submit',\n category: options.category,\n summary: options.summary,\n severity: options.severity || 'medium',\n tool: options.tool || undefined,\n details: options.details || undefined,\n });\n\n spinner.stop();\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n return;\n }\n\n printBlank();\n console.log(colors.success('✓') + ' Feedback submitted');\n console.log(colors.muted('─'.repeat(40)));\n console.log(colors.muted(` ID: ${response.feedbackId}`));\n console.log(colors.muted(` Category: ${options.category}`));\n console.log(colors.muted(` Summary: ${options.summary}`));\n printBlank();\n } catch (error) {\n spinner.stop();\n\n if (error instanceof CliError) {\n throw error;\n }\n\n const message = error instanceof Error ? error.message : 'Unknown error';\n throw new CliError(`Failed to submit feedback: ${message}`, 1);\n }\n}\n\n/**\n * Register feedback command with Commander\n */\nexport function registerFeedbackCommand(program: Command): void {\n const feedback = program\n .command('feedback')\n .description('List and submit feedback');\n\n // Default: list feedback\n feedback\n .option('--json', 'Output as JSON')\n .option('--toon', 'Output as TOON format')\n .option(\n '--category <category>',\n `Filter by category (${VALID_CATEGORIES.join(', ')})`\n )\n .option('--limit <n>', 'Limit number of results', '10')\n .action(withErrorHandler(feedbackAction));\n\n // Submit subcommand\n feedback\n .command('submit <summary>')\n .description('Submit new feedback')\n .requiredOption(\n '-c, --category <category>',\n `Category (${VALID_CATEGORIES.join(', ')})`\n )\n .option(\n '-s, --severity <severity>',\n 'Severity (critical, high, medium, low)',\n 'medium'\n )\n .option('-t, --tool <tool>', 'Related MCP tool')\n .option('-d, --details <details>', 'Extended description')\n .option('--json', 'Output as JSON')\n .action(withErrorHandler(async (summary: string, opts: Record<string, string | undefined>) => {\n await feedbackSubmitAction({\n summary,\n category: opts.category!,\n severity: opts.severity,\n tool: opts.tool,\n details: opts.details,\n json: !!opts.json,\n });\n }));\n\n feedback.addHelpText(\n 'after',\n `\nExamples:\n $ specforge feedback # List all feedback\n $ specforge feedback --json # Output as JSON\n $ specforge feedback --category bug # Filter by category\n $ specforge feedback submit \"Tool X fails\" # Submit feedback\n -c bug -s high -t action_work_session\n\nCategories:\n ${colors.error('bug')} - Something isn't working correctly\n ${colors.primary('feature_request')} - New capability suggestion\n ${colors.warning('usability')} - UX/DX improvement\n ${colors.primary('documentation')} - Docs unclear or missing\n ${colors.primary('performance')} - Speed/efficiency issue\n`\n );\n}\n"],"mappings":"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","names":[]}