@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,120 @@
1
+ /**
2
+ * Agent Teams Configuration Types — Claude Code specific
3
+ *
4
+ * Defines interfaces for the Agent Teams integration sections
5
+ * of the .specforge/config.json configuration file. These extend the
6
+ * existing ProjectConfig without breaking backward compatibility.
7
+ *
8
+ * Agent Teams is the Claude Code-specific orchestration layer that uses
9
+ * Claude Code primitives (TeamCreate, TaskCreate, SendMessage, etc.)
10
+ * to coordinate parallel ticket implementation.
11
+ *
12
+ * @see specforge-agent-teams-spec.md (v2.0.0)
13
+ */
14
+ import type { ProjectConfig } from './types.js';
15
+ /**
16
+ * Execution strategy for Agent Teams (Claude Code specific).
17
+ *
18
+ * - `auto` – Analyzer picks based on spec structure (default)
19
+ * - `single` – Sequential, one worker at a time (<=3 tickets, no epic deps)
20
+ * - `parallel` – All epic teams run concurrently (independent epics)
21
+ * - `phased` – Epics run in dependency-ordered phases (cross-epic deps)
22
+ *
23
+ * @see specforge-agent-teams-spec.md Section 4.3
24
+ */
25
+ export type AgentTeamsStrategy = 'auto' | 'single' | 'parallel' | 'phased';
26
+ /**
27
+ * Currently active specification for Agent Teams implementation (Claude Code specific).
28
+ *
29
+ * Set automatically by `specforge spec activate`. Tells the Agent Teams Lead
30
+ * which specification to work on at startup.
31
+ *
32
+ * @see specforge-agent-teams-spec.md Section 4.2 (LOAD step)
33
+ */
34
+ export interface ActiveSpecification {
35
+ /** SpecForge specification UUID */
36
+ id: string;
37
+ /** Human-readable spec title (for display) */
38
+ title: string;
39
+ /**
40
+ * ISO 8601 timestamp of activation.
41
+ * Set automatically by `specforge spec activate`.
42
+ */
43
+ activatedAt: string;
44
+ }
45
+ /**
46
+ * Agent Teams execution settings (Claude Code specific).
47
+ *
48
+ * Controls how Agent Teams orchestrate spec implementation.
49
+ * All fields are optional — sensible defaults are applied.
50
+ *
51
+ * v2.0.0 simplified to 6 fields. Previous fields (maxTokensPerWorker,
52
+ * branchPattern, autoValidate, validationCommands, escalationPolicy,
53
+ * monorepo) are ignored on read and stripped on write.
54
+ *
55
+ * @see specforge-agent-teams-spec.md Section 9.1
56
+ */
57
+ export interface AgentTeamsConfig {
58
+ /**
59
+ * Master toggle for Agent Teams.
60
+ * @default false
61
+ */
62
+ enabled?: boolean;
63
+ /**
64
+ * Execution strategy selection.
65
+ * @default "auto"
66
+ */
67
+ strategy?: AgentTeamsStrategy;
68
+ /**
69
+ * Maximum tickets assigned to a single team (1-20).
70
+ * @default 10
71
+ */
72
+ maxTicketsPerTeam?: number;
73
+ /**
74
+ * Maximum number of epics running in parallel (1-10).
75
+ * @default 3
76
+ */
77
+ maxParallelEpics?: number;
78
+ /**
79
+ * Git branch naming prefix.
80
+ * @default "ticket/"
81
+ */
82
+ branchPrefix?: string;
83
+ /**
84
+ * Per-worker timeout in minutes (5-60).
85
+ * @default 15
86
+ */
87
+ timeoutMinutes?: number;
88
+ }
89
+ /**
90
+ * Extended .specforge/config.json configuration with Agent Teams support.
91
+ *
92
+ * Extends the existing {@link ProjectConfig} with optional sections
93
+ * for Agent Teams integration (Claude Code specific). All new fields
94
+ * are optional to maintain full backward compatibility.
95
+ */
96
+ export interface SpecforgeJsonConfig extends ProjectConfig {
97
+ /** Currently active specification for implementation (Agent Teams) */
98
+ activeSpecification?: ActiveSpecification;
99
+ /** Agent Teams execution settings (Claude Code specific) */
100
+ agentTeams?: AgentTeamsConfig;
101
+ }
102
+ /**
103
+ * Default values for AgentTeamsConfig fields (v2.0.0).
104
+ *
105
+ * @see specforge-agent-teams-spec.md Section 9.1
106
+ */
107
+ export declare const AGENT_TEAMS_DEFAULTS: {
108
+ readonly enabled: false;
109
+ readonly strategy: AgentTeamsStrategy;
110
+ readonly maxTicketsPerTeam: 10;
111
+ readonly maxParallelEpics: 3;
112
+ readonly branchPrefix: "ticket/";
113
+ readonly timeoutMinutes: 15;
114
+ };
115
+ /**
116
+ * Fields that existed pre-v2.0.0 and should be stripped on config write.
117
+ * These are silently ignored on read for backward compatibility.
118
+ */
119
+ export declare const DEPRECATED_AGENT_TEAMS_FIELDS: readonly ["maxParallelTeams", "maxTokensPerWorker", "branchPattern", "autoValidate", "validationCommands", "escalationPolicy", "maxWorkersPerTeam", "monorepo"];
120
+ //# sourceMappingURL=agent-teams.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-teams.types.d.ts","sourceRoot":"","sources":["../../../src/cli/config/agent-teams.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhD;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;AAM3E;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,mCAAmC;IACnC,EAAE,EAAE,MAAM,CAAC;IAEX,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAE9B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,sEAAsE;IACtE,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAE1C,4DAA4D;IAC5D,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAMD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;uBAEX,kBAAkB;;;;;CAK9B,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,6BAA6B,iKAShC,CAAC"}
@@ -0,0 +1,23 @@
1
+ const AGENT_TEAMS_DEFAULTS = {
2
+ enabled: false,
3
+ strategy: "auto",
4
+ maxTicketsPerTeam: 10,
5
+ maxParallelEpics: 3,
6
+ branchPrefix: "ticket/",
7
+ timeoutMinutes: 15
8
+ };
9
+ const DEPRECATED_AGENT_TEAMS_FIELDS = [
10
+ "maxParallelTeams",
11
+ "maxTokensPerWorker",
12
+ "branchPattern",
13
+ "autoValidate",
14
+ "validationCommands",
15
+ "escalationPolicy",
16
+ "maxWorkersPerTeam",
17
+ "monorepo"
18
+ ];
19
+ export {
20
+ AGENT_TEAMS_DEFAULTS,
21
+ DEPRECATED_AGENT_TEAMS_FIELDS
22
+ };
23
+ //# sourceMappingURL=agent-teams.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/config/agent-teams.types.ts"],"sourcesContent":["/**\n * Agent Teams Configuration Types — Claude Code specific\n *\n * Defines interfaces for the Agent Teams integration sections\n * of the .specforge/config.json configuration file. These extend the\n * existing ProjectConfig without breaking backward compatibility.\n *\n * Agent Teams is the Claude Code-specific orchestration layer that uses\n * Claude Code primitives (TeamCreate, TaskCreate, SendMessage, etc.)\n * to coordinate parallel ticket implementation.\n *\n * @see specforge-agent-teams-spec.md (v2.0.0)\n */\n\nimport type { ProjectConfig } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Literal union types\n// ---------------------------------------------------------------------------\n\n/**\n * Execution strategy for Agent Teams (Claude Code specific).\n *\n * - `auto` – Analyzer picks based on spec structure (default)\n * - `single` – Sequential, one worker at a time (<=3 tickets, no epic deps)\n * - `parallel` – All epic teams run concurrently (independent epics)\n * - `phased` – Epics run in dependency-ordered phases (cross-epic deps)\n *\n * @see specforge-agent-teams-spec.md Section 4.3\n */\nexport type AgentTeamsStrategy = 'auto' | 'single' | 'parallel' | 'phased';\n\n// ---------------------------------------------------------------------------\n// ActiveSpecification\n// ---------------------------------------------------------------------------\n\n/**\n * Currently active specification for Agent Teams implementation (Claude Code specific).\n *\n * Set automatically by `specforge spec activate`. Tells the Agent Teams Lead\n * which specification to work on at startup.\n *\n * @see specforge-agent-teams-spec.md Section 4.2 (LOAD step)\n */\nexport interface ActiveSpecification {\n /** SpecForge specification UUID */\n id: string;\n\n /** Human-readable spec title (for display) */\n title: string;\n\n /**\n * ISO 8601 timestamp of activation.\n * Set automatically by `specforge spec activate`.\n */\n activatedAt: string;\n}\n\n// ---------------------------------------------------------------------------\n// AgentTeamsConfig (v2.0.0)\n// ---------------------------------------------------------------------------\n\n/**\n * Agent Teams execution settings (Claude Code specific).\n *\n * Controls how Agent Teams orchestrate spec implementation.\n * All fields are optional — sensible defaults are applied.\n *\n * v2.0.0 simplified to 6 fields. Previous fields (maxTokensPerWorker,\n * branchPattern, autoValidate, validationCommands, escalationPolicy,\n * monorepo) are ignored on read and stripped on write.\n *\n * @see specforge-agent-teams-spec.md Section 9.1\n */\nexport interface AgentTeamsConfig {\n /**\n * Master toggle for Agent Teams.\n * @default false\n */\n enabled?: boolean;\n\n /**\n * Execution strategy selection.\n * @default \"auto\"\n */\n strategy?: AgentTeamsStrategy;\n\n /**\n * Maximum tickets assigned to a single team (1-20).\n * @default 10\n */\n maxTicketsPerTeam?: number;\n\n /**\n * Maximum number of epics running in parallel (1-10).\n * @default 3\n */\n maxParallelEpics?: number;\n\n /**\n * Git branch naming prefix.\n * @default \"ticket/\"\n */\n branchPrefix?: string;\n\n /**\n * Per-worker timeout in minutes (5-60).\n * @default 15\n */\n timeoutMinutes?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Extended .specforge/config.json\n// ---------------------------------------------------------------------------\n\n/**\n * Extended .specforge/config.json configuration with Agent Teams support.\n *\n * Extends the existing {@link ProjectConfig} with optional sections\n * for Agent Teams integration (Claude Code specific). All new fields\n * are optional to maintain full backward compatibility.\n */\nexport interface SpecforgeJsonConfig extends ProjectConfig {\n /** Currently active specification for implementation (Agent Teams) */\n activeSpecification?: ActiveSpecification;\n\n /** Agent Teams execution settings (Claude Code specific) */\n agentTeams?: AgentTeamsConfig;\n}\n\n// ---------------------------------------------------------------------------\n// Defaults (v2.0.0)\n// ---------------------------------------------------------------------------\n\n/**\n * Default values for AgentTeamsConfig fields (v2.0.0).\n *\n * @see specforge-agent-teams-spec.md Section 9.1\n */\nexport const AGENT_TEAMS_DEFAULTS = {\n enabled: false,\n strategy: 'auto' as AgentTeamsStrategy,\n maxTicketsPerTeam: 10,\n maxParallelEpics: 3,\n branchPrefix: 'ticket/',\n timeoutMinutes: 15,\n} as const;\n\n/**\n * Fields that existed pre-v2.0.0 and should be stripped on config write.\n * These are silently ignored on read for backward compatibility.\n */\nexport const DEPRECATED_AGENT_TEAMS_FIELDS = [\n 'maxParallelTeams',\n 'maxTokensPerWorker',\n 'branchPattern',\n 'autoValidate',\n 'validationCommands',\n 'escalationPolicy',\n 'maxWorkersPerTeam',\n 'monorepo',\n] as const;\n"],"mappings":"AA4IO,MAAM,uBAAuB;AAAA,EAClC,SAAS;AAAA,EACT,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,gBAAgB;AAClB;AAMO,MAAM,gCAAgC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * CLI Configuration Module
3
+ *
4
+ * Provides configuration loading, writing, and path resolution
5
+ * for the SpecForge CLI.
6
+ */
7
+ export * from './types.js';
8
+ export * from './agent-teams.types.js';
9
+ export * from './validation.js';
10
+ export * from './paths.js';
11
+ export * from './loader.js';
12
+ export * from './writer.js';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/config/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from "./types.js";
2
+ export * from "./agent-teams.types.js";
3
+ export * from "./validation.js";
4
+ export * from "./paths.js";
5
+ export * from "./loader.js";
6
+ export * from "./writer.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/config/index.ts"],"sourcesContent":["/**\n * CLI Configuration Module\n *\n * Provides configuration loading, writing, and path resolution\n * for the SpecForge CLI.\n */\n\nexport * from './types.js';\nexport * from './agent-teams.types.js';\nexport * from './validation.js';\nexport * from './paths.js';\nexport * from './loader.js';\nexport * from './writer.js';\n"],"mappings":"AAOA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Config Loader
3
+ *
4
+ * Loads and merges configuration from multiple sources with the following priority:
5
+ * 1. Environment variables (highest)
6
+ * 2. Project config (.specforge/config.json)
7
+ * 3. Global config (~/.specforge/config.json)
8
+ * 4. Default values (lowest)
9
+ *
10
+ * Project config is a pure read: no migration, no best-effort writes, no
11
+ * deprecation shims. The loader throws a {@link ConfigError} when the config
12
+ * is missing or when a legacy `.specforge.json` is detected.
13
+ */
14
+ import { GlobalConfig, ResolvedConfig } from './types.js';
15
+ import type { SpecforgeJsonConfig, ActiveSpecification, AgentTeamsConfig } from './agent-teams.types.js';
16
+ /**
17
+ * AgentTeamsConfig with all defaults applied (all fields required).
18
+ *
19
+ * Claude Code Agent Teams only. Not used by MCP tool handlers.
20
+ */
21
+ export type ResolvedAgentTeamsConfig = Required<AgentTeamsConfig>;
22
+ /**
23
+ * Structured error thrown by {@link loadProjectConfig}.
24
+ *
25
+ * `CONFIG_MISSING` — neither new nor legacy config exists
26
+ * `LEGACY_CONFIG_DETECTED` — only the legacy `.specforge.json` exists
27
+ */
28
+ export type ConfigErrorCode = 'CONFIG_MISSING' | 'LEGACY_CONFIG_DETECTED';
29
+ export declare class ConfigError extends Error {
30
+ readonly code: ConfigErrorCode;
31
+ constructor(code: ConfigErrorCode, message: string);
32
+ }
33
+ /**
34
+ * Load global configuration from ~/.specforge/config.json
35
+ *
36
+ * @returns GlobalConfig object (empty object if file doesn't exist or is invalid)
37
+ */
38
+ export declare function loadGlobalConfig(): GlobalConfig;
39
+ /**
40
+ * Load project configuration from .specforge/config.json.
41
+ *
42
+ * Pure read: performs no filesystem writes under any code path.
43
+ *
44
+ * @throws {ConfigError} `LEGACY_CONFIG_DETECTED` when only `.specforge.json` exists
45
+ * @throws {ConfigError} `CONFIG_MISSING` when neither new nor legacy config exists
46
+ * @throws {Error} when the config file exists but cannot be parsed as a JSON object
47
+ */
48
+ export declare function loadProjectConfig(): SpecforgeJsonConfig;
49
+ /**
50
+ * Tolerant wrapper around {@link loadProjectConfig}.
51
+ *
52
+ * Returns `null` when the project config is missing (no file at all), which
53
+ * is a valid state for commands like `login` or `init` that can run outside
54
+ * a configured project. Rethrows `LEGACY_CONFIG_DETECTED` so legacy files
55
+ * keep surfacing the breaking-change notice on every operation.
56
+ */
57
+ export declare function tryLoadProjectConfig(): SpecforgeJsonConfig | null;
58
+ /**
59
+ * Resolve final configuration from all sources
60
+ *
61
+ * Merges configuration with the following priority (highest to lowest):
62
+ * 1. Environment variables
63
+ * 2. Project config (.specforge/config.json)
64
+ * 3. Global config (~/.specforge/config.json)
65
+ * 4. Default values
66
+ *
67
+ * @returns ResolvedConfig with all values and source tracking
68
+ */
69
+ export declare function resolveConfig(): ResolvedConfig;
70
+ /**
71
+ * Check if user is authenticated (has API key configured)
72
+ *
73
+ * @returns true if API key is available from any source
74
+ */
75
+ export declare function isAuthenticated(): boolean;
76
+ /**
77
+ * Get API key if available
78
+ *
79
+ * @returns API key string or null if not configured
80
+ */
81
+ export declare function getApiKey(): string | null;
82
+ /**
83
+ * Check if running in a project context
84
+ *
85
+ * @returns true if a valid project config was found (legacy files rethrow)
86
+ */
87
+ export declare function hasProjectContext(): boolean;
88
+ /**
89
+ * Get current project ID if available
90
+ */
91
+ export declare function getProjectId(): string | null;
92
+ /**
93
+ * Get current specification ID if available
94
+ */
95
+ export declare function getSpecificationId(): string | null;
96
+ /**
97
+ * Get Agent Teams config with defaults merged (v2.0.0).
98
+ *
99
+ * Claude Code Agent Teams only. Not used by MCP tool handlers.
100
+ *
101
+ * Always returns a fully-resolved config object — never null.
102
+ * Partial configs are merged with defaults via spread operator.
103
+ *
104
+ * @param config - Parsed project config (or null for all defaults)
105
+ * @returns Resolved Agent Teams config with all defaults applied
106
+ */
107
+ export declare function getAgentTeamsConfig(config: SpecforgeJsonConfig | null): ResolvedAgentTeamsConfig;
108
+ /**
109
+ * Get the active specification from config.
110
+ *
111
+ * Claude Code Agent Teams only. Not used by MCP tool handlers.
112
+ */
113
+ export declare function getActiveSpecification(config: SpecforgeJsonConfig | null): ActiveSpecification | null;
114
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/cli/config/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EACL,YAAY,EACZ,cAAc,EAMf,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAahC;;;;GAIG;AACH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAElE;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG,wBAAwB,CAAC;AAE1E,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;gBAEnB,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM;CAKnD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,CAyB/C;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,IAAI,mBAAmB,CAqCvD;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,mBAAmB,GAAG,IAAI,CASjE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,IAAI,cAAc,CAyE9C;AASD;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAGzC;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAGzC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAG5C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAGlD;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,GAAG,wBAAwB,CAUhG;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,GAAG,mBAAmB,GAAG,IAAI,CAErG"}
@@ -0,0 +1,198 @@
1
+ import fs from "node:fs";
2
+ import {
3
+ CONFIG_DEFAULTS,
4
+ CONFIG_ENV_VARS,
5
+ CONFIG_FILES
6
+ } from "./types.js";
7
+ import {
8
+ AGENT_TEAMS_DEFAULTS
9
+ } from "./agent-teams.types.js";
10
+ import {
11
+ getGlobalConfigPath,
12
+ findProjectConfigPath
13
+ } from "./paths.js";
14
+ import {
15
+ validateSpecforgeJson,
16
+ formatValidationErrors
17
+ } from "./validation.js";
18
+ class ConfigError extends Error {
19
+ code;
20
+ constructor(code, message) {
21
+ super(message);
22
+ this.name = "ConfigError";
23
+ this.code = code;
24
+ }
25
+ }
26
+ function loadGlobalConfig() {
27
+ const configPath = getGlobalConfigPath();
28
+ if (!fs.existsSync(configPath)) {
29
+ return {};
30
+ }
31
+ try {
32
+ const content = fs.readFileSync(configPath, "utf-8");
33
+ const parsed = JSON.parse(content);
34
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
35
+ console.warn(`Warning: ${configPath} is not a valid config object`);
36
+ return {};
37
+ }
38
+ return parsed;
39
+ } catch (error) {
40
+ if (error instanceof SyntaxError) {
41
+ console.warn(`Warning: Failed to parse ${configPath} - invalid JSON`);
42
+ } else {
43
+ console.warn(`Warning: Failed to read ${configPath}`);
44
+ }
45
+ return {};
46
+ }
47
+ }
48
+ function loadProjectConfig() {
49
+ const configPath = findProjectConfigPath();
50
+ if (!configPath) {
51
+ throw new ConfigError(
52
+ "CONFIG_MISSING",
53
+ "No SpecForge config found. Run `specforge init` to initialize this project."
54
+ );
55
+ }
56
+ if (configPath.endsWith(CONFIG_FILES.LEGACY_PROJECT_CONFIG)) {
57
+ throw new ConfigError(
58
+ "LEGACY_CONFIG_DETECTED",
59
+ "Legacy .specforge.json detected. Run `specforge init` to upgrade to the new .specforge/config.json layout. This is a one-time breaking change for the first production release."
60
+ );
61
+ }
62
+ const content = fs.readFileSync(configPath, "utf-8");
63
+ let parsed;
64
+ try {
65
+ parsed = JSON.parse(content);
66
+ } catch (error) {
67
+ const detail = error instanceof Error ? error.message : String(error);
68
+ throw new Error(`Invalid JSON in ${configPath}: ${detail}`);
69
+ }
70
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
71
+ throw new Error(`${configPath} is not a valid config object`);
72
+ }
73
+ const validation = validateSpecforgeJson(parsed);
74
+ if (!validation.valid) {
75
+ const lines = formatValidationErrors(validation.errors);
76
+ console.warn(`Warning: Invalid config in ${configPath}:
77
+ ${lines.join("\n")}`);
78
+ }
79
+ return parsed;
80
+ }
81
+ function tryLoadProjectConfig() {
82
+ try {
83
+ return loadProjectConfig();
84
+ } catch (error) {
85
+ if (error instanceof ConfigError && error.code === "CONFIG_MISSING") {
86
+ return null;
87
+ }
88
+ throw error;
89
+ }
90
+ }
91
+ function resolveConfig() {
92
+ const globalConfig = loadGlobalConfig();
93
+ const projectConfig = tryLoadProjectConfig();
94
+ const sources = {
95
+ apiKey: null,
96
+ projectId: null,
97
+ specificationId: null,
98
+ mcpOutputFormat: "default"
99
+ };
100
+ const resolved = {
101
+ apiKey: null,
102
+ apiUrl: CONFIG_DEFAULTS.apiUrl,
103
+ mcpOutputFormat: CONFIG_DEFAULTS.mcpOutputFormat,
104
+ projectId: null,
105
+ specificationId: null,
106
+ autoSetContext: CONFIG_DEFAULTS.autoSetContext,
107
+ debug: CONFIG_DEFAULTS.debug,
108
+ sources
109
+ };
110
+ if (process.env[CONFIG_ENV_VARS.API_KEY]) {
111
+ resolved.apiKey = process.env[CONFIG_ENV_VARS.API_KEY];
112
+ sources.apiKey = "env";
113
+ } else if (globalConfig.apiKey) {
114
+ resolved.apiKey = globalConfig.apiKey;
115
+ sources.apiKey = "global";
116
+ }
117
+ if (process.env[CONFIG_ENV_VARS.API_URL]) {
118
+ resolved.apiUrl = process.env[CONFIG_ENV_VARS.API_URL];
119
+ }
120
+ resolved.debug = process.env[CONFIG_ENV_VARS.DEBUG] === "true";
121
+ const envFormat = process.env[CONFIG_ENV_VARS.MCP_OUTPUT_FORMAT];
122
+ if (envFormat && isValidFormat(envFormat)) {
123
+ resolved.mcpOutputFormat = envFormat;
124
+ sources.mcpOutputFormat = "env";
125
+ } else if (projectConfig?.mcpOutputFormat && isValidFormat(projectConfig.mcpOutputFormat)) {
126
+ resolved.mcpOutputFormat = projectConfig.mcpOutputFormat;
127
+ sources.mcpOutputFormat = "project";
128
+ } else if (globalConfig.mcpOutputFormat && isValidFormat(globalConfig.mcpOutputFormat)) {
129
+ resolved.mcpOutputFormat = globalConfig.mcpOutputFormat;
130
+ sources.mcpOutputFormat = "global";
131
+ }
132
+ if (projectConfig?.projectId) {
133
+ resolved.projectId = projectConfig.projectId;
134
+ sources.projectId = "project";
135
+ } else if (globalConfig.defaultProjectId) {
136
+ resolved.projectId = globalConfig.defaultProjectId;
137
+ sources.projectId = "global";
138
+ }
139
+ if (projectConfig?.specificationId) {
140
+ resolved.specificationId = projectConfig.specificationId;
141
+ sources.specificationId = "project";
142
+ }
143
+ if (projectConfig?.autoSetContext !== void 0) {
144
+ resolved.autoSetContext = projectConfig.autoSetContext;
145
+ }
146
+ return resolved;
147
+ }
148
+ function isValidFormat(format) {
149
+ return format === "json" || format === "toon";
150
+ }
151
+ function isAuthenticated() {
152
+ const config = resolveConfig();
153
+ return config.apiKey !== null;
154
+ }
155
+ function getApiKey() {
156
+ const config = resolveConfig();
157
+ return config.apiKey;
158
+ }
159
+ function hasProjectContext() {
160
+ return tryLoadProjectConfig() !== null;
161
+ }
162
+ function getProjectId() {
163
+ const config = resolveConfig();
164
+ return config.projectId;
165
+ }
166
+ function getSpecificationId() {
167
+ const config = resolveConfig();
168
+ return config.specificationId;
169
+ }
170
+ function getAgentTeamsConfig(config) {
171
+ const partial = config?.agentTeams;
172
+ return {
173
+ enabled: partial?.enabled ?? AGENT_TEAMS_DEFAULTS.enabled,
174
+ strategy: partial?.strategy ?? AGENT_TEAMS_DEFAULTS.strategy,
175
+ maxTicketsPerTeam: partial?.maxTicketsPerTeam ?? AGENT_TEAMS_DEFAULTS.maxTicketsPerTeam,
176
+ maxParallelEpics: partial?.maxParallelEpics ?? AGENT_TEAMS_DEFAULTS.maxParallelEpics,
177
+ branchPrefix: partial?.branchPrefix ?? AGENT_TEAMS_DEFAULTS.branchPrefix,
178
+ timeoutMinutes: partial?.timeoutMinutes ?? AGENT_TEAMS_DEFAULTS.timeoutMinutes
179
+ };
180
+ }
181
+ function getActiveSpecification(config) {
182
+ return config?.activeSpecification ?? null;
183
+ }
184
+ export {
185
+ ConfigError,
186
+ getActiveSpecification,
187
+ getAgentTeamsConfig,
188
+ getApiKey,
189
+ getProjectId,
190
+ getSpecificationId,
191
+ hasProjectContext,
192
+ isAuthenticated,
193
+ loadGlobalConfig,
194
+ loadProjectConfig,
195
+ resolveConfig,
196
+ tryLoadProjectConfig
197
+ };
198
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/config/loader.ts"],"sourcesContent":["/**\n * Config Loader\n *\n * Loads and merges configuration from multiple sources with the following priority:\n * 1. Environment variables (highest)\n * 2. Project config (.specforge/config.json)\n * 3. Global config (~/.specforge/config.json)\n * 4. Default values (lowest)\n *\n * Project config is a pure read: no migration, no best-effort writes, no\n * deprecation shims. The loader throws a {@link ConfigError} when the config\n * is missing or when a legacy `.specforge.json` is detected.\n */\n\nimport fs from 'node:fs';\nimport {\n GlobalConfig,\n ResolvedConfig,\n ConfigSources,\n OutputFormat,\n CONFIG_DEFAULTS,\n CONFIG_ENV_VARS,\n CONFIG_FILES,\n} from './types.js';\nimport type {\n SpecforgeJsonConfig,\n ActiveSpecification,\n AgentTeamsConfig,\n} from './agent-teams.types.js';\nimport {\n AGENT_TEAMS_DEFAULTS,\n} from './agent-teams.types.js';\nimport {\n getGlobalConfigPath,\n findProjectConfigPath,\n} from './paths.js';\nimport {\n validateSpecforgeJson,\n formatValidationErrors,\n} from './validation.js';\n\n/**\n * AgentTeamsConfig with all defaults applied (all fields required).\n *\n * Claude Code Agent Teams only. Not used by MCP tool handlers.\n */\nexport type ResolvedAgentTeamsConfig = Required<AgentTeamsConfig>;\n\n/**\n * Structured error thrown by {@link loadProjectConfig}.\n *\n * `CONFIG_MISSING` — neither new nor legacy config exists\n * `LEGACY_CONFIG_DETECTED` — only the legacy `.specforge.json` exists\n */\nexport type ConfigErrorCode = 'CONFIG_MISSING' | 'LEGACY_CONFIG_DETECTED';\n\nexport class ConfigError extends Error {\n readonly code: ConfigErrorCode;\n\n constructor(code: ConfigErrorCode, message: string) {\n super(message);\n this.name = 'ConfigError';\n this.code = code;\n }\n}\n\n/**\n * Load global configuration from ~/.specforge/config.json\n *\n * @returns GlobalConfig object (empty object if file doesn't exist or is invalid)\n */\nexport function loadGlobalConfig(): GlobalConfig {\n const configPath = getGlobalConfigPath();\n\n if (!fs.existsSync(configPath)) {\n return {};\n }\n\n try {\n const content = fs.readFileSync(configPath, 'utf-8');\n const parsed = JSON.parse(content);\n\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n console.warn(`Warning: ${configPath} is not a valid config object`);\n return {};\n }\n\n return parsed as GlobalConfig;\n } catch (error) {\n if (error instanceof SyntaxError) {\n console.warn(`Warning: Failed to parse ${configPath} - invalid JSON`);\n } else {\n console.warn(`Warning: Failed to read ${configPath}`);\n }\n return {};\n }\n}\n\n/**\n * Load project configuration from .specforge/config.json.\n *\n * Pure read: performs no filesystem writes under any code path.\n *\n * @throws {ConfigError} `LEGACY_CONFIG_DETECTED` when only `.specforge.json` exists\n * @throws {ConfigError} `CONFIG_MISSING` when neither new nor legacy config exists\n * @throws {Error} when the config file exists but cannot be parsed as a JSON object\n */\nexport function loadProjectConfig(): SpecforgeJsonConfig {\n const configPath = findProjectConfigPath();\n\n if (!configPath) {\n throw new ConfigError(\n 'CONFIG_MISSING',\n 'No SpecForge config found. Run `specforge init` to initialize this project.'\n );\n }\n\n if (configPath.endsWith(CONFIG_FILES.LEGACY_PROJECT_CONFIG)) {\n throw new ConfigError(\n 'LEGACY_CONFIG_DETECTED',\n 'Legacy .specforge.json detected. Run `specforge init` to upgrade to the new .specforge/config.json layout. This is a one-time breaking change for the first production release.'\n );\n }\n\n const content = fs.readFileSync(configPath, 'utf-8');\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n throw new Error(`Invalid JSON in ${configPath}: ${detail}`);\n }\n\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new Error(`${configPath} is not a valid config object`);\n }\n\n const validation = validateSpecforgeJson(parsed);\n if (!validation.valid) {\n const lines = formatValidationErrors(validation.errors);\n console.warn(`Warning: Invalid config in ${configPath}:\\n${lines.join('\\n')}`);\n }\n\n return parsed as SpecforgeJsonConfig;\n}\n\n/**\n * Tolerant wrapper around {@link loadProjectConfig}.\n *\n * Returns `null` when the project config is missing (no file at all), which\n * is a valid state for commands like `login` or `init` that can run outside\n * a configured project. Rethrows `LEGACY_CONFIG_DETECTED` so legacy files\n * keep surfacing the breaking-change notice on every operation.\n */\nexport function tryLoadProjectConfig(): SpecforgeJsonConfig | null {\n try {\n return loadProjectConfig();\n } catch (error) {\n if (error instanceof ConfigError && error.code === 'CONFIG_MISSING') {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Resolve final configuration from all sources\n *\n * Merges configuration with the following priority (highest to lowest):\n * 1. Environment variables\n * 2. Project config (.specforge/config.json)\n * 3. Global config (~/.specforge/config.json)\n * 4. Default values\n *\n * @returns ResolvedConfig with all values and source tracking\n */\nexport function resolveConfig(): ResolvedConfig {\n const globalConfig = loadGlobalConfig();\n const projectConfig = tryLoadProjectConfig();\n\n const sources: ConfigSources = {\n apiKey: null,\n projectId: null,\n specificationId: null,\n mcpOutputFormat: 'default',\n };\n\n const resolved: ResolvedConfig = {\n apiKey: null,\n apiUrl: CONFIG_DEFAULTS.apiUrl,\n mcpOutputFormat: CONFIG_DEFAULTS.mcpOutputFormat,\n projectId: null,\n specificationId: null,\n autoSetContext: CONFIG_DEFAULTS.autoSetContext,\n debug: CONFIG_DEFAULTS.debug,\n sources,\n };\n\n // --- API Key: ENV > Global ---\n if (process.env[CONFIG_ENV_VARS.API_KEY]) {\n resolved.apiKey = process.env[CONFIG_ENV_VARS.API_KEY]!;\n sources.apiKey = 'env';\n } else if (globalConfig.apiKey) {\n resolved.apiKey = globalConfig.apiKey;\n sources.apiKey = 'global';\n }\n\n // --- API URL: ENV > Default ---\n if (process.env[CONFIG_ENV_VARS.API_URL]) {\n resolved.apiUrl = process.env[CONFIG_ENV_VARS.API_URL]!;\n }\n\n // --- Debug: ENV only ---\n resolved.debug = process.env[CONFIG_ENV_VARS.DEBUG] === 'true';\n\n // --- MCP output format: ENV > Project > Global > Default ---\n const envFormat = process.env[CONFIG_ENV_VARS.MCP_OUTPUT_FORMAT];\n if (envFormat && isValidFormat(envFormat)) {\n resolved.mcpOutputFormat = envFormat;\n sources.mcpOutputFormat = 'env';\n } else if (projectConfig?.mcpOutputFormat && isValidFormat(projectConfig.mcpOutputFormat)) {\n resolved.mcpOutputFormat = projectConfig.mcpOutputFormat;\n sources.mcpOutputFormat = 'project';\n } else if (globalConfig.mcpOutputFormat && isValidFormat(globalConfig.mcpOutputFormat)) {\n resolved.mcpOutputFormat = globalConfig.mcpOutputFormat;\n sources.mcpOutputFormat = 'global';\n }\n\n // --- Project ID: Project > Global ---\n if (projectConfig?.projectId) {\n resolved.projectId = projectConfig.projectId;\n sources.projectId = 'project';\n } else if (globalConfig.defaultProjectId) {\n resolved.projectId = globalConfig.defaultProjectId;\n sources.projectId = 'global';\n }\n\n // --- Specification ID: Project only ---\n if (projectConfig?.specificationId) {\n resolved.specificationId = projectConfig.specificationId;\n sources.specificationId = 'project';\n }\n\n // --- Auto Set Context: Project > Default ---\n if (projectConfig?.autoSetContext !== undefined) {\n resolved.autoSetContext = projectConfig.autoSetContext;\n }\n\n return resolved;\n}\n\n/**\n * Validate that a string is a valid output format\n */\nfunction isValidFormat(format: string): format is OutputFormat {\n return format === 'json' || format === 'toon';\n}\n\n/**\n * Check if user is authenticated (has API key configured)\n *\n * @returns true if API key is available from any source\n */\nexport function isAuthenticated(): boolean {\n const config = resolveConfig();\n return config.apiKey !== null;\n}\n\n/**\n * Get API key if available\n *\n * @returns API key string or null if not configured\n */\nexport function getApiKey(): string | null {\n const config = resolveConfig();\n return config.apiKey;\n}\n\n/**\n * Check if running in a project context\n *\n * @returns true if a valid project config was found (legacy files rethrow)\n */\nexport function hasProjectContext(): boolean {\n return tryLoadProjectConfig() !== null;\n}\n\n/**\n * Get current project ID if available\n */\nexport function getProjectId(): string | null {\n const config = resolveConfig();\n return config.projectId;\n}\n\n/**\n * Get current specification ID if available\n */\nexport function getSpecificationId(): string | null {\n const config = resolveConfig();\n return config.specificationId;\n}\n\n// ---------------------------------------------------------------------------\n// Agent Teams config helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Get Agent Teams config with defaults merged (v2.0.0).\n *\n * Claude Code Agent Teams only. Not used by MCP tool handlers.\n *\n * Always returns a fully-resolved config object — never null.\n * Partial configs are merged with defaults via spread operator.\n *\n * @param config - Parsed project config (or null for all defaults)\n * @returns Resolved Agent Teams config with all defaults applied\n */\nexport function getAgentTeamsConfig(config: SpecforgeJsonConfig | null): ResolvedAgentTeamsConfig {\n const partial = config?.agentTeams;\n return {\n enabled: partial?.enabled ?? AGENT_TEAMS_DEFAULTS.enabled,\n strategy: partial?.strategy ?? AGENT_TEAMS_DEFAULTS.strategy,\n maxTicketsPerTeam: partial?.maxTicketsPerTeam ?? AGENT_TEAMS_DEFAULTS.maxTicketsPerTeam,\n maxParallelEpics: partial?.maxParallelEpics ?? AGENT_TEAMS_DEFAULTS.maxParallelEpics,\n branchPrefix: partial?.branchPrefix ?? AGENT_TEAMS_DEFAULTS.branchPrefix,\n timeoutMinutes: partial?.timeoutMinutes ?? AGENT_TEAMS_DEFAULTS.timeoutMinutes,\n };\n}\n\n/**\n * Get the active specification from config.\n *\n * Claude Code Agent Teams only. Not used by MCP tool handlers.\n */\nexport function getActiveSpecification(config: SpecforgeJsonConfig | null): ActiveSpecification | null {\n return config?.activeSpecification ?? null;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Config Paths Resolution
3
+ *
4
+ * Provides functions for resolving configuration file paths.
5
+ * Handles both global (~/.specforge/) and project-level (.specforge.json) paths.
6
+ */
7
+ import { ConfigPaths } from './types.js';
8
+ /**
9
+ * Get all configuration file paths
10
+ *
11
+ * @returns ConfigPaths object with all resolved paths
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const paths = getConfigPaths();
16
+ * console.log(paths.globalDir); // /home/user/.specforge
17
+ * console.log(paths.globalConfig); // /home/user/.specforge/config.json
18
+ * console.log(paths.projectConfig); // /current/dir/.specforge.json
19
+ * ```
20
+ */
21
+ export declare function getConfigPaths(): ConfigPaths;
22
+ /**
23
+ * Get the global configuration directory path
24
+ *
25
+ * Uses $HOME/.specforge on all platforms.
26
+ * Does not create the directory - that's handled by the writer.
27
+ *
28
+ * @returns Absolute path to global config directory
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * const dir = getGlobalConfigDir();
33
+ * // Linux/macOS: /home/user/.specforge
34
+ * // Windows: C:\Users\user\.specforge
35
+ * ```
36
+ */
37
+ export declare function getGlobalConfigDir(): string;
38
+ /**
39
+ * Get the global configuration file path
40
+ *
41
+ * @returns Absolute path to ~/.specforge/config.json
42
+ */
43
+ export declare function getGlobalConfigPath(): string;
44
+ /**
45
+ * Get the project configuration file path
46
+ *
47
+ * Resolves to .specforge.json in the current working directory.
48
+ * Note: This returns the path in CWD only - for searching up the
49
+ * directory tree, use findProjectConfigPath().
50
+ *
51
+ * @returns Absolute path to .specforge.json in current directory
52
+ */
53
+ export declare function getProjectConfigPath(): string;
54
+ /**
55
+ * Get the MCP configuration file path
56
+ *
57
+ * @returns Absolute path to .mcp.json in current directory
58
+ */
59
+ export declare function getMcpConfigPath(): string;
60
+ /**
61
+ * Get the planning-sessions registry path (M9.6 §2.6).
62
+ *
63
+ * Lives alongside config.json under the channel-aware project config dir
64
+ * (`.specforge/planning-sessions.json` on stable, `.specforge-canary/...` on
65
+ * canary — `CONFIG_FILES.PROJECT_DIR` flows from `CHANNEL.configDir`).
66
+ *
67
+ * @param targetDir - Project root (defaults to cwd)
68
+ * @returns Absolute path to the planning-sessions registry file
69
+ */
70
+ export declare function getPlanningSessionsRegistryPath(targetDir?: string): string;
71
+ /**
72
+ * Find project config by searching up the directory tree
73
+ *
74
+ * Starts from the current directory and walks up to the filesystem root,
75
+ * looking for .specforge.json at each level.
76
+ *
77
+ * @param startDir - Directory to start searching from (defaults to cwd)
78
+ * @returns Absolute path to .specforge.json if found, null otherwise
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * // Given: /home/user/projects/myapp/src/components
83
+ * // With .specforge.json at /home/user/projects/myapp/.specforge.json
84
+ *
85
+ * const configPath = findProjectConfigPath();
86
+ * // Returns: /home/user/projects/myapp/.specforge.json
87
+ * ```
88
+ */
89
+ export declare function findProjectConfigPath(startDir?: string): string | null;
90
+ /**
91
+ * Get the directory containing the project config
92
+ *
93
+ * Useful for resolving relative paths from the project root.
94
+ *
95
+ * @returns Directory path if project config found, null otherwise
96
+ */
97
+ export declare function findProjectRoot(): string | null;
98
+ /**
99
+ * Check if a path is within the global config directory
100
+ *
101
+ * Security check to prevent path traversal attacks.
102
+ *
103
+ * @param targetPath - Path to check
104
+ * @returns true if path is within ~/.specforge/
105
+ */
106
+ export declare function isWithinGlobalDir(targetPath: string): boolean;
107
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/cli/config/paths.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,WAAW,EAAgB,MAAM,YAAY,CAAC;AAEvD;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAS5C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAG1E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA+BtE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAU/C;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAO7D"}