@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
package/bin/specforge ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * SpecForge MCP CLI Entry Point
5
+ *
6
+ * All logic is handled by the CLI module.
7
+ * The 'serve' command is set as default in Commander.js for backward compatibility.
8
+ *
9
+ * When called with no arguments: starts MCP server
10
+ * When called with subcommands/flags: runs CLI
11
+ */
12
+
13
+ import('../dist/cli/index.js')
14
+ .then(({ runCLI }) => runCLI())
15
+ .catch((error) => {
16
+ console.error('Fatal error:', error.message);
17
+ if (process.env.SPECFORGE_DEBUG === 'true') {
18
+ console.error(error.stack);
19
+ }
20
+ process.exit(1);
21
+ });
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Channel manifest — single import surface for build-time substitutions.
3
+ *
4
+ * `__CLI_*__` symbols are declared ambient in `channel.d.ts` and substituted
5
+ * by `tsup` (build) and `vitest` (tests) via `build/channel-defines.ts`.
6
+ *
7
+ * The rest of the CLI source must reference `CHANNEL.*` only — never the
8
+ * literal endpoint URLs, package name, or config dir name. The B1 acceptance
9
+ * grep enforces this.
10
+ */
11
+ export declare const CHANNEL: {
12
+ /** Binary / display name. e.g. `"specforge"` (stable) or `"specforge-canary"`. */
13
+ readonly name: string;
14
+ /** npm package name on the public registry. */
15
+ readonly packageName: string;
16
+ /** MCP API gateway endpoint pair + health probes. */
17
+ readonly endpoint: {
18
+ readonly primary: string;
19
+ readonly fallback: string;
20
+ readonly healthPrimary: string;
21
+ readonly healthFallback: string;
22
+ };
23
+ /** Per-channel config dir under `$HOME` (and at the project level). */
24
+ readonly configDir: string;
25
+ };
26
+ export type ChannelManifest = typeof CHANNEL;
27
+ //# sourceMappingURL=channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,eAAO,MAAM,OAAO;IAClB,kFAAkF;;IAElF,+CAA+C;;IAE/C,qDAAqD;;;;;;;IAUrD,uEAAuE;;CAE/D,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,OAAO,OAAO,CAAC"}
@@ -0,0 +1,22 @@
1
+ const CHANNEL = {
2
+ /** Binary / display name. e.g. `"specforge"` (stable) or `"specforge-canary"`. */
3
+ name: "specforge",
4
+ /** npm package name on the public registry. */
5
+ packageName: "@specforge/cli",
6
+ /** MCP API gateway endpoint pair + health probes. */
7
+ endpoint: {
8
+ primary: "https://mcp.specforge.tech/local",
9
+ fallback: "https://mcp.specforge.com.br/local",
10
+ healthPrimary: "https://mcp.specforge.tech/health",
11
+ healthFallback: "https://mcp.specforge.com.br/health"
12
+ },
13
+ // (CLI REST `cliRest` endpoints removed — the human CLI now uses the `/cli`
14
+ // route on the MCP host via `createCliClient`; the separate cli-rest gateway
15
+ // is retired.)
16
+ /** Per-channel config dir under `$HOME` (and at the project level). */
17
+ configDir: ".specforge"
18
+ };
19
+ export {
20
+ CHANNEL
21
+ };
22
+ //# sourceMappingURL=channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/channel.ts"],"sourcesContent":["/**\n * Channel manifest — single import surface for build-time substitutions.\n *\n * `__CLI_*__` symbols are declared ambient in `channel.d.ts` and substituted\n * by `tsup` (build) and `vitest` (tests) via `build/channel-defines.ts`.\n *\n * The rest of the CLI source must reference `CHANNEL.*` only — never the\n * literal endpoint URLs, package name, or config dir name. The B1 acceptance\n * grep enforces this.\n */\n\nexport const CHANNEL = {\n /** Binary / display name. e.g. `\"specforge\"` (stable) or `\"specforge-canary\"`. */\n name: __CLI_NAME__,\n /** npm package name on the public registry. */\n packageName: __CLI_PACKAGE_NAME__,\n /** MCP API gateway endpoint pair + health probes. */\n endpoint: {\n primary: __CLI_ENDPOINT_PRIMARY__,\n fallback: __CLI_ENDPOINT_FALLBACK__,\n healthPrimary: __CLI_HEALTH_PRIMARY__,\n healthFallback: __CLI_HEALTH_FALLBACK__,\n },\n // (CLI REST `cliRest` endpoints removed — the human CLI now uses the `/cli`\n // route on the MCP host via `createCliClient`; the separate cli-rest gateway\n // is retired.)\n /** Per-channel config dir under `$HOME` (and at the project level). */\n configDir: __CLI_CONFIG_DIR__,\n} as const;\n\nexport type ChannelManifest = typeof CHANNEL;\n"],"mappings":"AAWO,MAAM,UAAU;AAAA;AAAA,EAErB,MAAM;AAAA;AAAA,EAEN,aAAa;AAAA;AAAA,EAEb,UAAU;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,IACV,eAAe;AAAA,IACf,gBAAgB;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW;AACb;","names":[]}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Configure Command
3
+ *
4
+ * View and modify configuration values for global and project settings.
5
+ */
6
+ import { Command } from 'commander';
7
+ import { ConfigureOptions } from './configure.types.js';
8
+ /**
9
+ * Configure command action handler
10
+ */
11
+ export declare function configureAction(key: string | undefined, value: string | undefined, options: ConfigureOptions): Promise<void>;
12
+ /**
13
+ * Register configure command with Commander
14
+ */
15
+ export declare function registerConfigureCommand(program: Command): void;
16
+ //# sourceMappingURL=configure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/configure.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,OAAO,EACL,gBAAgB,EAMjB,MAAM,sBAAsB,CAAC;AA+K9B;;GAEG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CA0Cf;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2B/D"}
@@ -0,0 +1,186 @@
1
+ import {
2
+ resolveConfig,
3
+ loadGlobalConfig,
4
+ tryLoadProjectConfig,
5
+ saveGlobalConfig,
6
+ saveProjectConfig,
7
+ getConfigPaths
8
+ } from "../config/index.js";
9
+ import { withErrorHandler, CliError, ValidationError } from "../middleware/error-handler.js";
10
+ import {
11
+ printSuccess,
12
+ printBlank,
13
+ printHeader
14
+ } from "../ui/output.js";
15
+ import { colors } from "../ui/colors.js";
16
+ import {
17
+ VALID_KEYS,
18
+ CONFIG_KEY_META,
19
+ isValidKeyForScope,
20
+ parseConfigValue
21
+ } from "./configure.types.js";
22
+ function maskValue(value, visibleChars = 8) {
23
+ if (value.length <= visibleChars) {
24
+ return "***";
25
+ }
26
+ return "***" + value.slice(-visibleChars);
27
+ }
28
+ function formatDisplayValue(key, value) {
29
+ if (value === void 0 || value === null || value === "") {
30
+ return colors.muted("(not set)");
31
+ }
32
+ if (key === "apiKey" && typeof value === "string") {
33
+ return colors.muted(maskValue(value));
34
+ }
35
+ if (typeof value === "boolean") {
36
+ return value ? colors.success("true") : colors.muted("false");
37
+ }
38
+ return String(value);
39
+ }
40
+ function displayAllConfig() {
41
+ const config = resolveConfig();
42
+ const paths = getConfigPaths();
43
+ printBlank();
44
+ printHeader("Configuration");
45
+ printBlank();
46
+ console.log(colors.muted("# Resolved values (from all sources)"));
47
+ printBlank();
48
+ const apiKeyDisplay = config.apiKey ? colors.muted(maskValue(config.apiKey)) : colors.error("(not set)");
49
+ const apiKeySource = config.sources.apiKey ? colors.muted(` (from ${config.sources.apiKey})`) : "";
50
+ console.log(` apiKey: ${apiKeyDisplay}${apiKeySource}`);
51
+ const formatSource = config.sources.mcpOutputFormat ? colors.muted(` (from ${config.sources.mcpOutputFormat})`) : "";
52
+ console.log(` mcpOutputFormat: ${config.mcpOutputFormat}${formatSource}`);
53
+ const projectIdDisplay = formatDisplayValue("projectId", config.projectId);
54
+ const projectIdSource = config.sources.projectId ? colors.muted(` (from ${config.sources.projectId})`) : "";
55
+ console.log(` projectId: ${projectIdDisplay}${projectIdSource}`);
56
+ const specIdDisplay = formatDisplayValue("specificationId", config.specificationId);
57
+ const specIdSource = config.sources.specificationId ? colors.muted(` (from ${config.sources.specificationId})`) : "";
58
+ console.log(` specificationId: ${specIdDisplay}${specIdSource}`);
59
+ const autoSetDisplay = formatDisplayValue("autoSetContext", config.autoSetContext);
60
+ console.log(` autoSetContext: ${autoSetDisplay}`);
61
+ printBlank();
62
+ console.log(colors.muted("# File locations"));
63
+ console.log(` global: ${paths.globalConfig}`);
64
+ console.log(` project: ${paths.projectConfig}`);
65
+ printBlank();
66
+ }
67
+ function displayKey(key) {
68
+ const config = resolveConfig();
69
+ const value = config[key];
70
+ if (key === "apiKey" && typeof value === "string") {
71
+ console.log(maskValue(value));
72
+ } else if (value === void 0 || value === null || value === "") {
73
+ console.log(colors.muted("(not set)"));
74
+ } else {
75
+ console.log(String(value));
76
+ }
77
+ }
78
+ function setConfigValue(key, value, global) {
79
+ const scope = global ? "global" : "project";
80
+ if (!isValidKeyForScope(key, scope)) {
81
+ const validKeys = VALID_KEYS[scope];
82
+ throw new ValidationError(
83
+ `Invalid key "${key}" for ${scope} config`,
84
+ `Valid keys: ${validKeys.join(", ")}`
85
+ );
86
+ }
87
+ const parseResult = parseConfigValue(key, value);
88
+ if (!parseResult.valid) {
89
+ const meta = CONFIG_KEY_META[key];
90
+ throw new ValidationError(
91
+ `Invalid value "${value}" for key "${key}"`,
92
+ meta?.validValues ? `Valid values: ${meta.validValues.join(", ")}` : void 0
93
+ );
94
+ }
95
+ if (global) {
96
+ const currentConfig = loadGlobalConfig();
97
+ saveGlobalConfig({
98
+ ...currentConfig,
99
+ [key]: parseResult.parsed
100
+ });
101
+ } else {
102
+ const currentConfig = tryLoadProjectConfig() || {};
103
+ saveProjectConfig({
104
+ ...currentConfig,
105
+ [key]: parseResult.parsed
106
+ });
107
+ }
108
+ printSuccess(`Set ${key} = ${value}`);
109
+ }
110
+ function unsetConfigKey(key, global) {
111
+ const scope = global ? "global" : "project";
112
+ if (!isValidKeyForScope(key, scope)) {
113
+ const validKeys = VALID_KEYS[scope];
114
+ throw new ValidationError(
115
+ `Invalid key "${key}" for ${scope} config`,
116
+ `Valid keys: ${validKeys.join(", ")}`
117
+ );
118
+ }
119
+ if (global) {
120
+ const config = loadGlobalConfig();
121
+ delete config[key];
122
+ saveGlobalConfig(config);
123
+ } else {
124
+ const config = tryLoadProjectConfig() || {};
125
+ delete config[key];
126
+ saveProjectConfig(config);
127
+ }
128
+ printSuccess(`Removed ${key} from ${scope} config`);
129
+ }
130
+ async function configureAction(key, value, options) {
131
+ if (options.unset) {
132
+ unsetConfigKey(options.unset, !!options.global);
133
+ return;
134
+ }
135
+ if (!key) {
136
+ displayAllConfig();
137
+ return;
138
+ }
139
+ const isValidGlobal = isValidKeyForScope(key, "global");
140
+ const isValidProject = isValidKeyForScope(key, "project");
141
+ if (!isValidGlobal && !isValidProject && key !== "apiKey") {
142
+ const allKeys = [.../* @__PURE__ */ new Set([...VALID_KEYS.global, ...VALID_KEYS.project])];
143
+ throw new ValidationError(
144
+ `Unknown configuration key "${key}"`,
145
+ `Valid keys: ${allKeys.join(", ")}`
146
+ );
147
+ }
148
+ if (value === void 0) {
149
+ displayKey(key);
150
+ return;
151
+ }
152
+ if (key === "apiKey") {
153
+ throw new CliError(
154
+ "Cannot set API key via configure command",
155
+ 1,
156
+ "Use `specforge login` to set your API key"
157
+ );
158
+ }
159
+ setConfigValue(key, value, !!options.global);
160
+ }
161
+ function registerConfigureCommand(program) {
162
+ program.command("configure [key] [value]").alias("config").description("View or modify configuration").option("--global", "Read/write global config (~/.specforge/config.json)").option("--unset <key>", "Remove a configuration key").addHelpText("after", `
163
+ Examples:
164
+ $ specforge configure # Show all configuration
165
+ $ specforge configure mcpOutputFormat # Show MCP output format value
166
+ $ specforge configure mcpOutputFormat toon # Set project MCP output format to toon
167
+ $ specforge configure --global mcpOutputFormat json # Set global MCP output format to json
168
+ $ specforge configure --unset projectId # Remove projectId from project config
169
+
170
+ Valid keys:
171
+ Global: ${VALID_KEYS.global.join(", ")}
172
+ Project: ${VALID_KEYS.project.join(", ")}
173
+
174
+ Key descriptions:
175
+ mcpOutputFormat - Local MCP response encoding: json or toon (44% smaller)
176
+ projectId - Default project ID for this directory
177
+ specificationId - Default specification ID for this directory
178
+ autoSetContext - Auto-set working context on start (true/false)
179
+ defaultProjectId - Global default project ID
180
+ `).action(withErrorHandler(configureAction));
181
+ }
182
+ export {
183
+ configureAction,
184
+ registerConfigureCommand
185
+ };
186
+ //# sourceMappingURL=configure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/configure.ts"],"sourcesContent":["/**\n * Configure Command\n *\n * View and modify configuration values for global and project settings.\n */\n\nimport { Command } from 'commander';\nimport {\n resolveConfig,\n loadGlobalConfig,\n tryLoadProjectConfig,\n saveGlobalConfig,\n saveProjectConfig,\n getConfigPaths,\n} from '../config/index.js';\nimport { withErrorHandler, CliError, ValidationError } from '../middleware/error-handler.js';\nimport {\n printSuccess,\n printBlank,\n printHeader,\n} from '../ui/output.js';\nimport { colors } from '../ui/colors.js';\nimport {\n ConfigureOptions,\n VALID_KEYS,\n CONFIG_KEY_META,\n ValidConfigKey,\n isValidKeyForScope,\n parseConfigValue,\n} from './configure.types.js';\n\n/**\n * Mask a sensitive value (show only last N characters)\n */\nfunction maskValue(value: string, visibleChars = 8): string {\n if (value.length <= visibleChars) {\n return '***';\n }\n return '***' + value.slice(-visibleChars);\n}\n\n/**\n * Format a value for display\n */\nfunction formatDisplayValue(key: string, value: unknown): string {\n if (value === undefined || value === null || value === '') {\n return colors.muted('(not set)');\n }\n\n // Mask API key\n if (key === 'apiKey' && typeof value === 'string') {\n return colors.muted(maskValue(value));\n }\n\n // Boolean values\n if (typeof value === 'boolean') {\n return value ? colors.success('true') : colors.muted('false');\n }\n\n return String(value);\n}\n\n/**\n * Display all configuration values with sources\n */\nfunction displayAllConfig(): void {\n const config = resolveConfig();\n const paths = getConfigPaths();\n\n printBlank();\n printHeader('Configuration');\n printBlank();\n\n console.log(colors.muted('# Resolved values (from all sources)'));\n printBlank();\n\n // API Key (always masked)\n const apiKeyDisplay = config.apiKey\n ? colors.muted(maskValue(config.apiKey))\n : colors.error('(not set)');\n const apiKeySource = config.sources.apiKey\n ? colors.muted(` (from ${config.sources.apiKey})`)\n : '';\n console.log(` apiKey: ${apiKeyDisplay}${apiKeySource}`);\n\n // MCP output format\n const formatSource = config.sources.mcpOutputFormat\n ? colors.muted(` (from ${config.sources.mcpOutputFormat})`)\n : '';\n console.log(` mcpOutputFormat: ${config.mcpOutputFormat}${formatSource}`);\n\n // Project ID\n const projectIdDisplay = formatDisplayValue('projectId', config.projectId);\n const projectIdSource = config.sources.projectId\n ? colors.muted(` (from ${config.sources.projectId})`)\n : '';\n console.log(` projectId: ${projectIdDisplay}${projectIdSource}`);\n\n // Specification ID\n const specIdDisplay = formatDisplayValue('specificationId', config.specificationId);\n const specIdSource = config.sources.specificationId\n ? colors.muted(` (from ${config.sources.specificationId})`)\n : '';\n console.log(` specificationId: ${specIdDisplay}${specIdSource}`);\n\n // Auto Set Context\n const autoSetDisplay = formatDisplayValue('autoSetContext', config.autoSetContext);\n // Note: autoSetContext source tracking not yet implemented in ConfigSources\n console.log(` autoSetContext: ${autoSetDisplay}`);\n\n printBlank();\n console.log(colors.muted('# File locations'));\n console.log(` global: ${paths.globalConfig}`);\n console.log(` project: ${paths.projectConfig}`);\n printBlank();\n}\n\n/**\n * Display a specific configuration key value\n */\nfunction displayKey(key: string): void {\n const config = resolveConfig();\n const value = (config as unknown as Record<string, unknown>)[key];\n\n if (key === 'apiKey' && typeof value === 'string') {\n console.log(maskValue(value));\n } else if (value === undefined || value === null || value === '') {\n console.log(colors.muted('(not set)'));\n } else {\n console.log(String(value));\n }\n}\n\n/**\n * Set a configuration value\n */\nfunction setConfigValue(key: string, value: string, global: boolean): void {\n const scope = global ? 'global' : 'project';\n\n // Validate key for scope\n if (!isValidKeyForScope(key, scope)) {\n const validKeys = VALID_KEYS[scope];\n throw new ValidationError(\n `Invalid key \"${key}\" for ${scope} config`,\n `Valid keys: ${validKeys.join(', ')}`\n );\n }\n\n // Parse and validate value\n const parseResult = parseConfigValue(key, value);\n if (!parseResult.valid) {\n const meta = CONFIG_KEY_META[key as ValidConfigKey];\n throw new ValidationError(\n `Invalid value \"${value}\" for key \"${key}\"`,\n meta?.validValues ? `Valid values: ${meta.validValues.join(', ')}` : undefined\n );\n }\n\n // Save to appropriate config file\n if (global) {\n const currentConfig = loadGlobalConfig();\n saveGlobalConfig({\n ...currentConfig,\n [key]: parseResult.parsed,\n });\n } else {\n const currentConfig = tryLoadProjectConfig() || {};\n saveProjectConfig({\n ...currentConfig,\n [key]: parseResult.parsed,\n });\n }\n\n printSuccess(`Set ${key} = ${value}`);\n}\n\n/**\n * Remove a configuration key\n */\nfunction unsetConfigKey(key: string, global: boolean): void {\n const scope = global ? 'global' : 'project';\n\n // Validate key for scope\n if (!isValidKeyForScope(key, scope)) {\n const validKeys = VALID_KEYS[scope];\n throw new ValidationError(\n `Invalid key \"${key}\" for ${scope} config`,\n `Valid keys: ${validKeys.join(', ')}`\n );\n }\n\n if (global) {\n const config = loadGlobalConfig();\n delete (config as Record<string, unknown>)[key];\n saveGlobalConfig(config);\n } else {\n const config = tryLoadProjectConfig() || {};\n delete (config as Record<string, unknown>)[key];\n saveProjectConfig(config);\n }\n\n printSuccess(`Removed ${key} from ${scope} config`);\n}\n\n/**\n * Configure command action handler\n */\nexport async function configureAction(\n key: string | undefined,\n value: string | undefined,\n options: ConfigureOptions\n): Promise<void> {\n // Handle --unset\n if (options.unset) {\n unsetConfigKey(options.unset, !!options.global);\n return;\n }\n\n // No key = show all config\n if (!key) {\n displayAllConfig();\n return;\n }\n\n // Validate key exists in at least one scope\n const isValidGlobal = isValidKeyForScope(key, 'global');\n const isValidProject = isValidKeyForScope(key, 'project');\n\n if (!isValidGlobal && !isValidProject && key !== 'apiKey') {\n const allKeys = [...new Set([...VALID_KEYS.global, ...VALID_KEYS.project])];\n throw new ValidationError(\n `Unknown configuration key \"${key}\"`,\n `Valid keys: ${allKeys.join(', ')}`\n );\n }\n\n // Key only = show value\n if (value === undefined) {\n displayKey(key);\n return;\n }\n\n // Key + value = set value\n // Prevent setting apiKey via configure\n if (key === 'apiKey') {\n throw new CliError(\n 'Cannot set API key via configure command',\n 1,\n 'Use `specforge login` to set your API key'\n );\n }\n\n setConfigValue(key, value, !!options.global);\n}\n\n/**\n * Register configure command with Commander\n */\nexport function registerConfigureCommand(program: Command): void {\n program\n .command('configure [key] [value]')\n .alias('config')\n .description('View or modify configuration')\n .option('--global', 'Read/write global config (~/.specforge/config.json)')\n .option('--unset <key>', 'Remove a configuration key')\n .addHelpText('after', `\nExamples:\n $ specforge configure # Show all configuration\n $ specforge configure mcpOutputFormat # Show MCP output format value\n $ specforge configure mcpOutputFormat toon # Set project MCP output format to toon\n $ specforge configure --global mcpOutputFormat json # Set global MCP output format to json\n $ specforge configure --unset projectId # Remove projectId from project config\n\nValid keys:\n Global: ${VALID_KEYS.global.join(', ')}\n Project: ${VALID_KEYS.project.join(', ')}\n\nKey descriptions:\n mcpOutputFormat - Local MCP response encoding: json or toon (44% smaller)\n projectId - Default project ID for this directory\n specificationId - Default specification ID for this directory\n autoSetContext - Auto-set working context on start (true/false)\n defaultProjectId - Global default project ID\n`)\n .action(withErrorHandler(configureAction));\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Configure Command Types
3
+ *
4
+ * Type definitions and constants for the configure command.
5
+ */
6
+ /**
7
+ * Configure command options from Commander
8
+ */
9
+ export interface ConfigureOptions {
10
+ /** Read/write global config (~/.specforge/config.json) */
11
+ global?: boolean;
12
+ /** Remove a configuration key */
13
+ unset?: string;
14
+ }
15
+ /**
16
+ * Configuration scope
17
+ */
18
+ export type ConfigScope = 'global' | 'project';
19
+ /**
20
+ * Valid configuration keys by scope
21
+ */
22
+ export declare const VALID_KEYS: Record<ConfigScope, string[]>;
23
+ /**
24
+ * All valid configuration keys (union of both scopes)
25
+ */
26
+ export declare const ALL_VALID_KEYS: readonly ["mcpOutputFormat", "projectId", "specificationId", "autoSetContext", "defaultProjectId"];
27
+ /**
28
+ * Valid configuration key type
29
+ */
30
+ export type ValidConfigKey = (typeof ALL_VALID_KEYS)[number];
31
+ /**
32
+ * Configuration key metadata
33
+ */
34
+ export interface ConfigKeyMeta {
35
+ /** Human-readable description */
36
+ description: string;
37
+ /** Valid scopes for this key */
38
+ scopes: ConfigScope[];
39
+ /** Valid values (if restricted) */
40
+ validValues?: string[];
41
+ /** Whether the value should be masked in output */
42
+ masked?: boolean;
43
+ /** Value type after parsing */
44
+ type: 'string' | 'boolean';
45
+ }
46
+ /**
47
+ * Configuration key metadata map
48
+ */
49
+ export declare const CONFIG_KEY_META: Record<ValidConfigKey, ConfigKeyMeta>;
50
+ /**
51
+ * Key validator function type
52
+ */
53
+ export type KeyValidator = (value: string) => boolean;
54
+ /**
55
+ * Key validators for values that need validation
56
+ */
57
+ export declare const KEY_VALIDATORS: Partial<Record<ValidConfigKey, KeyValidator>>;
58
+ /**
59
+ * Value parser function type
60
+ */
61
+ export type ValueParser = (value: string) => unknown;
62
+ /**
63
+ * Value parsers for converting string input to proper types
64
+ */
65
+ export declare const VALUE_PARSERS: Partial<Record<ValidConfigKey, ValueParser>>;
66
+ /**
67
+ * Configuration display entry
68
+ */
69
+ export interface ConfigDisplayEntry {
70
+ /** Configuration key */
71
+ key: string;
72
+ /** Resolved value */
73
+ value: unknown;
74
+ /** Source of the value */
75
+ source: string;
76
+ /** Whether to mask the value */
77
+ masked?: boolean;
78
+ }
79
+ /**
80
+ * Validation result
81
+ */
82
+ export interface ValidationResult {
83
+ /** Whether the validation passed */
84
+ valid: boolean;
85
+ /** Error message if validation failed */
86
+ error?: string;
87
+ /** Hint for valid values */
88
+ hint?: string;
89
+ }
90
+ /**
91
+ * Check if a key is valid for the given scope
92
+ */
93
+ export declare function isValidKeyForScope(key: string, scope: ConfigScope): boolean;
94
+ /**
95
+ * Get validator for a key
96
+ */
97
+ export declare function getValidator(key: string): KeyValidator | undefined;
98
+ /**
99
+ * Get parser for a key
100
+ */
101
+ export declare function getParser(key: string): ValueParser | undefined;
102
+ /**
103
+ * Parse and validate a configuration value
104
+ */
105
+ export declare function parseConfigValue(key: string, value: string): {
106
+ parsed: unknown;
107
+ valid: boolean;
108
+ error?: string;
109
+ };
110
+ //# sourceMappingURL=configure.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure.types.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/configure.types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,CAGpD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,oGAMjB,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,mDAAmD;IACnD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,+BAA+B;IAC/B,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC5B;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,cAAc,EAAE,aAAa,CA4BjE,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,YAAY,CAAC,CAGxE,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;AAErD;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC,CAEtE,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,qBAAqB;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oCAAoC;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAE3E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAElE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAE9D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GACZ;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAiBrD"}
@@ -0,0 +1,82 @@
1
+ const VALID_KEYS = {
2
+ global: ["mcpOutputFormat", "defaultProjectId"],
3
+ project: ["mcpOutputFormat", "projectId", "specificationId", "autoSetContext"]
4
+ };
5
+ const ALL_VALID_KEYS = [
6
+ "mcpOutputFormat",
7
+ "projectId",
8
+ "specificationId",
9
+ "autoSetContext",
10
+ "defaultProjectId"
11
+ ];
12
+ const CONFIG_KEY_META = {
13
+ mcpOutputFormat: {
14
+ description: "Local MCP response encoding (json or toon)",
15
+ scopes: ["global", "project"],
16
+ validValues: ["json", "toon"],
17
+ type: "string"
18
+ },
19
+ projectId: {
20
+ description: "Default project ID",
21
+ scopes: ["project"],
22
+ type: "string"
23
+ },
24
+ specificationId: {
25
+ description: "Default specification ID",
26
+ scopes: ["project"],
27
+ type: "string"
28
+ },
29
+ autoSetContext: {
30
+ description: "Auto-set working context on MCP server start",
31
+ scopes: ["project"],
32
+ validValues: ["true", "false"],
33
+ type: "boolean"
34
+ },
35
+ defaultProjectId: {
36
+ description: "Global default project ID",
37
+ scopes: ["global"],
38
+ type: "string"
39
+ }
40
+ };
41
+ const KEY_VALIDATORS = {
42
+ mcpOutputFormat: (v) => ["json", "toon"].includes(v),
43
+ autoSetContext: (v) => ["true", "false"].includes(v.toLowerCase())
44
+ };
45
+ const VALUE_PARSERS = {
46
+ autoSetContext: (v) => v.toLowerCase() === "true"
47
+ };
48
+ function isValidKeyForScope(key, scope) {
49
+ return VALID_KEYS[scope].includes(key);
50
+ }
51
+ function getValidator(key) {
52
+ return KEY_VALIDATORS[key];
53
+ }
54
+ function getParser(key) {
55
+ return VALUE_PARSERS[key];
56
+ }
57
+ function parseConfigValue(key, value) {
58
+ const validator = getValidator(key);
59
+ if (validator && !validator(value)) {
60
+ const meta = CONFIG_KEY_META[key];
61
+ return {
62
+ parsed: value,
63
+ valid: false,
64
+ error: `Invalid value "${value}" for key "${key}". Valid values: ${meta?.validValues?.join(", ")}`
65
+ };
66
+ }
67
+ const parser = getParser(key);
68
+ const parsed = parser ? parser(value) : value;
69
+ return { parsed, valid: true };
70
+ }
71
+ export {
72
+ ALL_VALID_KEYS,
73
+ CONFIG_KEY_META,
74
+ KEY_VALIDATORS,
75
+ VALID_KEYS,
76
+ VALUE_PARSERS,
77
+ getParser,
78
+ getValidator,
79
+ isValidKeyForScope,
80
+ parseConfigValue
81
+ };
82
+ //# sourceMappingURL=configure.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/configure.types.ts"],"sourcesContent":["/**\n * Configure Command Types\n *\n * Type definitions and constants for the configure command.\n */\n\n/**\n * Configure command options from Commander\n */\nexport interface ConfigureOptions {\n /** Read/write global config (~/.specforge/config.json) */\n global?: boolean;\n /** Remove a configuration key */\n unset?: string;\n}\n\n/**\n * Configuration scope\n */\nexport type ConfigScope = 'global' | 'project';\n\n/**\n * Valid configuration keys by scope\n */\nexport const VALID_KEYS: Record<ConfigScope, string[]> = {\n global: ['mcpOutputFormat', 'defaultProjectId'],\n project: ['mcpOutputFormat', 'projectId', 'specificationId', 'autoSetContext'],\n};\n\n/**\n * All valid configuration keys (union of both scopes)\n */\nexport const ALL_VALID_KEYS = [\n 'mcpOutputFormat',\n 'projectId',\n 'specificationId',\n 'autoSetContext',\n 'defaultProjectId',\n] as const;\n\n/**\n * Valid configuration key type\n */\nexport type ValidConfigKey = (typeof ALL_VALID_KEYS)[number];\n\n/**\n * Configuration key metadata\n */\nexport interface ConfigKeyMeta {\n /** Human-readable description */\n description: string;\n /** Valid scopes for this key */\n scopes: ConfigScope[];\n /** Valid values (if restricted) */\n validValues?: string[];\n /** Whether the value should be masked in output */\n masked?: boolean;\n /** Value type after parsing */\n type: 'string' | 'boolean';\n}\n\n/**\n * Configuration key metadata map\n */\nexport const CONFIG_KEY_META: Record<ValidConfigKey, ConfigKeyMeta> = {\n mcpOutputFormat: {\n description: 'Local MCP response encoding (json or toon)',\n scopes: ['global', 'project'],\n validValues: ['json', 'toon'],\n type: 'string',\n },\n projectId: {\n description: 'Default project ID',\n scopes: ['project'],\n type: 'string',\n },\n specificationId: {\n description: 'Default specification ID',\n scopes: ['project'],\n type: 'string',\n },\n autoSetContext: {\n description: 'Auto-set working context on MCP server start',\n scopes: ['project'],\n validValues: ['true', 'false'],\n type: 'boolean',\n },\n defaultProjectId: {\n description: 'Global default project ID',\n scopes: ['global'],\n type: 'string',\n },\n};\n\n/**\n * Key validator function type\n */\nexport type KeyValidator = (value: string) => boolean;\n\n/**\n * Key validators for values that need validation\n */\nexport const KEY_VALIDATORS: Partial<Record<ValidConfigKey, KeyValidator>> = {\n mcpOutputFormat: (v: string) => ['json', 'toon'].includes(v),\n autoSetContext: (v: string) => ['true', 'false'].includes(v.toLowerCase()),\n};\n\n/**\n * Value parser function type\n */\nexport type ValueParser = (value: string) => unknown;\n\n/**\n * Value parsers for converting string input to proper types\n */\nexport const VALUE_PARSERS: Partial<Record<ValidConfigKey, ValueParser>> = {\n autoSetContext: (v: string) => v.toLowerCase() === 'true',\n};\n\n/**\n * Configuration display entry\n */\nexport interface ConfigDisplayEntry {\n /** Configuration key */\n key: string;\n /** Resolved value */\n value: unknown;\n /** Source of the value */\n source: string;\n /** Whether to mask the value */\n masked?: boolean;\n}\n\n/**\n * Validation result\n */\nexport interface ValidationResult {\n /** Whether the validation passed */\n valid: boolean;\n /** Error message if validation failed */\n error?: string;\n /** Hint for valid values */\n hint?: string;\n}\n\n/**\n * Check if a key is valid for the given scope\n */\nexport function isValidKeyForScope(key: string, scope: ConfigScope): boolean {\n return VALID_KEYS[scope].includes(key);\n}\n\n/**\n * Get validator for a key\n */\nexport function getValidator(key: string): KeyValidator | undefined {\n return KEY_VALIDATORS[key as ValidConfigKey];\n}\n\n/**\n * Get parser for a key\n */\nexport function getParser(key: string): ValueParser | undefined {\n return VALUE_PARSERS[key as ValidConfigKey];\n}\n\n/**\n * Parse and validate a configuration value\n */\nexport function parseConfigValue(\n key: string,\n value: string\n): { parsed: unknown; valid: boolean; error?: string } {\n // Validate if validator exists\n const validator = getValidator(key);\n if (validator && !validator(value)) {\n const meta = CONFIG_KEY_META[key as ValidConfigKey];\n return {\n parsed: value,\n valid: false,\n error: `Invalid value \"${value}\" for key \"${key}\". Valid values: ${meta?.validValues?.join(', ')}`,\n };\n }\n\n // Parse the value\n const parser = getParser(key);\n const parsed = parser ? parser(value) : value;\n\n return { parsed, valid: true };\n}\n"],"mappings":"AAwBO,MAAM,aAA4C;AAAA,EACvD,QAAQ,CAAC,mBAAmB,kBAAkB;AAAA,EAC9C,SAAS,CAAC,mBAAmB,aAAa,mBAAmB,gBAAgB;AAC/E;AAKO,MAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA0BO,MAAM,kBAAyD;AAAA,EACpE,iBAAiB;AAAA,IACf,aAAa;AAAA,IACb,QAAQ,CAAC,UAAU,SAAS;AAAA,IAC5B,aAAa,CAAC,QAAQ,MAAM;AAAA,IAC5B,MAAM;AAAA,EACR;AAAA,EACA,WAAW;AAAA,IACT,aAAa;AAAA,IACb,QAAQ,CAAC,SAAS;AAAA,IAClB,MAAM;AAAA,EACR;AAAA,EACA,iBAAiB;AAAA,IACf,aAAa;AAAA,IACb,QAAQ,CAAC,SAAS;AAAA,IAClB,MAAM;AAAA,EACR;AAAA,EACA,gBAAgB;AAAA,IACd,aAAa;AAAA,IACb,QAAQ,CAAC,SAAS;AAAA,IAClB,aAAa,CAAC,QAAQ,OAAO;AAAA,IAC7B,MAAM;AAAA,EACR;AAAA,EACA,kBAAkB;AAAA,IAChB,aAAa;AAAA,IACb,QAAQ,CAAC,QAAQ;AAAA,IACjB,MAAM;AAAA,EACR;AACF;AAUO,MAAM,iBAAgE;AAAA,EAC3E,iBAAiB,CAAC,MAAc,CAAC,QAAQ,MAAM,EAAE,SAAS,CAAC;AAAA,EAC3D,gBAAgB,CAAC,MAAc,CAAC,QAAQ,OAAO,EAAE,SAAS,EAAE,YAAY,CAAC;AAC3E;AAUO,MAAM,gBAA8D;AAAA,EACzE,gBAAgB,CAAC,MAAc,EAAE,YAAY,MAAM;AACrD;AA+BO,SAAS,mBAAmB,KAAa,OAA6B;AAC3E,SAAO,WAAW,KAAK,EAAE,SAAS,GAAG;AACvC;AAKO,SAAS,aAAa,KAAuC;AAClE,SAAO,eAAe,GAAqB;AAC7C;AAKO,SAAS,UAAU,KAAsC;AAC9D,SAAO,cAAc,GAAqB;AAC5C;AAKO,SAAS,iBACd,KACA,OACqD;AAErD,QAAM,YAAY,aAAa,GAAG;AAClC,MAAI,aAAa,CAAC,UAAU,KAAK,GAAG;AAClC,UAAM,OAAO,gBAAgB,GAAqB;AAClD,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,OAAO,kBAAkB,KAAK,cAAc,GAAG,oBAAoB,MAAM,aAAa,KAAK,IAAI,CAAC;AAAA,IAClG;AAAA,EACF;AAGA,QAAM,SAAS,UAAU,GAAG;AAC5B,QAAM,SAAS,SAAS,OAAO,KAAK,IAAI;AAExC,SAAO,EAAE,QAAQ,OAAO,KAAK;AAC/B;","names":[]}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Call Command Implementation
3
+ *
4
+ * Allows directly calling MCP tools with JSON arguments, useful for testing
5
+ * and debugging.
6
+ */
7
+ import type { CallOptions } from './types.js';
8
+ /**
9
+ * Call command implementation
10
+ *
11
+ * Directly calls an MCP tool with optional JSON arguments.
12
+ */
13
+ export declare function callCommand(tool: string, options: CallOptions): Promise<void>;
14
+ //# sourceMappingURL=call.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/debug/call.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAsD9C;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA+DnF"}
@@ -0,0 +1,96 @@
1
+ import ora from "ora";
2
+ import { resolveConfig } from "../../config/index.js";
3
+ import { colors } from "../../ui/colors.js";
4
+ import { ApiClient } from "../../../client/api-client.js";
5
+ import { handleToolCall } from "../../../tools/index.js";
6
+ function parseArgs(argsString) {
7
+ if (!argsString) {
8
+ return {};
9
+ }
10
+ try {
11
+ return JSON.parse(argsString);
12
+ } catch (error) {
13
+ throw new Error(
14
+ `Invalid JSON in --args. Example: --args='{"ticketId": "abc123"}'`
15
+ );
16
+ }
17
+ }
18
+ function formatToon(response) {
19
+ if (typeof response === "object" && response !== null) {
20
+ const lines = ["@response"];
21
+ const entries = Object.entries(response);
22
+ for (const [key, value] of entries) {
23
+ if (typeof value === "object" && value !== null) {
24
+ lines.push(` ${key}: ${JSON.stringify(value)}`);
25
+ } else {
26
+ lines.push(` ${key}: ${value}`);
27
+ }
28
+ }
29
+ return lines.join("\n");
30
+ }
31
+ return String(response);
32
+ }
33
+ function formatOutput(response, options) {
34
+ if (options.raw) {
35
+ return typeof response === "string" ? response : JSON.stringify(response);
36
+ }
37
+ if (options.format === "toon") {
38
+ return formatToon(response);
39
+ }
40
+ return JSON.stringify(response, null, 2);
41
+ }
42
+ async function callCommand(tool, options) {
43
+ if (!tool) {
44
+ console.error(colors.error("\nError: Tool name is required."));
45
+ console.error(`Usage: specforge call <tool> --args='{"key": "value"}'`);
46
+ process.exit(1);
47
+ }
48
+ const config = resolveConfig();
49
+ let args;
50
+ try {
51
+ args = parseArgs(options.args);
52
+ } catch (error) {
53
+ const message = error instanceof Error ? error.message : "Invalid JSON";
54
+ console.error(colors.error(`
55
+ Error: ${message}`));
56
+ process.exit(1);
57
+ }
58
+ const spinner = ora(`Calling ${tool}...`).start();
59
+ try {
60
+ if (!config.apiKey) {
61
+ spinner.fail("Not authenticated");
62
+ console.error(colors.error("\nError: Not authenticated."));
63
+ console.error(colors.muted("Run `specforge login` to authenticate first."));
64
+ process.exit(1);
65
+ }
66
+ const client = new ApiClient({
67
+ apiKey: config.apiKey,
68
+ apiUrl: config.apiUrl,
69
+ debug: config.debug
70
+ });
71
+ const response = await handleToolCall(client, tool, args, config.debug);
72
+ spinner.stop();
73
+ const output = formatOutput(response, options);
74
+ console.log(output);
75
+ } catch (error) {
76
+ spinner.fail(`Failed to call ${tool}`);
77
+ const message = error instanceof Error ? error.message : "Unknown error";
78
+ if (message.includes("Unknown tool") || message.includes("not found")) {
79
+ console.error(colors.error(`
80
+ Error: Unknown tool "${tool}".`));
81
+ console.error(colors.muted("Run 'specforge tools' to see available tools."));
82
+ } else if (message.includes("required")) {
83
+ console.error(colors.error(`
84
+ Error: ${message}`));
85
+ console.error(colors.muted("Check the tool requires specific arguments."));
86
+ } else {
87
+ console.error(colors.error(`
88
+ Error: ${message}`));
89
+ }
90
+ process.exit(1);
91
+ }
92
+ }
93
+ export {
94
+ callCommand
95
+ };
96
+ //# sourceMappingURL=call.js.map