@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,54 @@
1
+ /**
2
+ * Agent Scaffolding Types & Interfaces
3
+ *
4
+ * Type definitions for AI agent scaffolding in Claude Code and other AI tools.
5
+ */
6
+ export type AgentCategory = 'Orchestration' | 'SpecForge' | 'Research';
7
+ /**
8
+ * Agent model options
9
+ */
10
+ export type AgentModel = 'opus' | 'sonnet' | 'haiku';
11
+ /**
12
+ * Supported colors for agent display
13
+ */
14
+ export type AgentColor = 'red' | 'yellow' | 'green' | 'cyan' | 'blue' | 'magenta' | 'white' | 'gray';
15
+ /**
16
+ * Persistent memory scope for the agent. Maps to Claude Code's `memory:`
17
+ * frontmatter field, which triggers Claude Code to inject the persistent
18
+ * memory system prompt and create the matching agent-memory directory:
19
+ * - `project` → `.claude/agent-memory/<name>/`
20
+ * - `user` → `~/.claude/agent-memory/<name>/`
21
+ * - `local` → `.claude/agent-memory-local/<name>/`
22
+ */
23
+ export type AgentMemory = 'project' | 'user' | 'local';
24
+ /**
25
+ * Agent template definition
26
+ */
27
+ export interface AgentTemplate {
28
+ /** Agent name (e.g., 'sfag-orchestrator') */
29
+ name: string;
30
+ /** Short description for agent list */
31
+ description: string;
32
+ /** Full description with trigger examples for frontmatter */
33
+ triggerDescription: string;
34
+ /** AI model to use for this agent */
35
+ model: AgentModel;
36
+ /** Color for agent display */
37
+ color: AgentColor;
38
+ /** Full markdown content of the agent */
39
+ content: string;
40
+ /** Agent category for grouping */
41
+ category: AgentCategory;
42
+ /** Persistent memory scope (Claude Code only) */
43
+ memory?: AgentMemory;
44
+ }
45
+ export declare const AGENT_CATEGORIES: Record<AgentCategory, string[]>;
46
+ /**
47
+ * Get all agent category names
48
+ */
49
+ export declare function getAgentCategoryNames(): AgentCategory[];
50
+ /**
51
+ * Model display badges for CLI output
52
+ */
53
+ export declare const MODEL_BADGES: Record<AgentModel, string>;
54
+ //# sourceMappingURL=agent-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-types.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/scaffold/agent-types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,aAAa,GACrB,eAAe,GACf,WAAW,GACX,UAAU,CAAC;AAEf;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,UAAU,GAClB,KAAK,GACL,QAAQ,GACR,OAAO,GACP,MAAM,GACN,MAAM,GACN,SAAS,GACT,OAAO,GACP,MAAM,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qCAAqC;IACrC,KAAK,EAAE,UAAU,CAAC;IAClB,8BAA8B;IAC9B,KAAK,EAAE,UAAU,CAAC;IAClB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,QAAQ,EAAE,aAAa,CAAC;IACxB,iDAAiD;IACjD,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,EAAE,CAI5D,CAAC;AAEF;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,aAAa,EAAE,CAEvD;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAInD,CAAC"}
@@ -0,0 +1,22 @@
1
+ const AGENT_CATEGORIES = {
2
+ Orchestration: ["sfag-orchestrator"],
3
+ SpecForge: ["sfag-spec-creator", "sfag-ticket-implementer"],
4
+ Research: ["sfag-package-researcher"]
5
+ };
6
+ function getAgentCategoryNames() {
7
+ return Object.keys(AGENT_CATEGORIES);
8
+ }
9
+ const MODEL_BADGES = {
10
+ opus: "\u25C6",
11
+ // Diamond for opus (powerful)
12
+ sonnet: "\u25CF",
13
+ // Circle for sonnet (balanced)
14
+ haiku: "\u25CB"
15
+ // Empty circle for haiku (fast)
16
+ };
17
+ export {
18
+ AGENT_CATEGORIES,
19
+ MODEL_BADGES,
20
+ getAgentCategoryNames
21
+ };
22
+ //# sourceMappingURL=agent-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/cli/commands/scaffold/agent-types.ts"],"sourcesContent":["/**\n * Agent Scaffolding Types & Interfaces\n *\n * Type definitions for AI agent scaffolding in Claude Code and other AI tools.\n */\n\nexport type AgentCategory =\n | 'Orchestration'\n | 'SpecForge'\n | 'Research';\n\n/**\n * Agent model options\n */\nexport type AgentModel = 'opus' | 'sonnet' | 'haiku';\n\n/**\n * Supported colors for agent display\n */\nexport type AgentColor =\n | 'red'\n | 'yellow'\n | 'green'\n | 'cyan'\n | 'blue'\n | 'magenta'\n | 'white'\n | 'gray';\n\n/**\n * Persistent memory scope for the agent. Maps to Claude Code's `memory:`\n * frontmatter field, which triggers Claude Code to inject the persistent\n * memory system prompt and create the matching agent-memory directory:\n * - `project` → `.claude/agent-memory/<name>/`\n * - `user` → `~/.claude/agent-memory/<name>/`\n * - `local` → `.claude/agent-memory-local/<name>/`\n */\nexport type AgentMemory = 'project' | 'user' | 'local';\n\n/**\n * Agent template definition\n */\nexport interface AgentTemplate {\n /** Agent name (e.g., 'sfag-orchestrator') */\n name: string;\n /** Short description for agent list */\n description: string;\n /** Full description with trigger examples for frontmatter */\n triggerDescription: string;\n /** AI model to use for this agent */\n model: AgentModel;\n /** Color for agent display */\n color: AgentColor;\n /** Full markdown content of the agent */\n content: string;\n /** Agent category for grouping */\n category: AgentCategory;\n /** Persistent memory scope (Claude Code only) */\n memory?: AgentMemory;\n}\n\nexport const AGENT_CATEGORIES: Record<AgentCategory, string[]> = {\n Orchestration: ['sfag-orchestrator'],\n SpecForge: ['sfag-spec-creator', 'sfag-ticket-implementer'],\n Research: ['sfag-package-researcher'],\n};\n\n/**\n * Get all agent category names\n */\nexport function getAgentCategoryNames(): AgentCategory[] {\n return Object.keys(AGENT_CATEGORIES) as AgentCategory[];\n}\n\n/**\n * Model display badges for CLI output\n */\nexport const MODEL_BADGES: Record<AgentModel, string> = {\n opus: '◆', // Diamond for opus (powerful)\n sonnet: '●', // Circle for sonnet (balanced)\n haiku: '○', // Empty circle for haiku (fast)\n};\n"],"mappings":"AA6DO,MAAM,mBAAoD;AAAA,EAC/D,eAAe,CAAC,mBAAmB;AAAA,EACnC,WAAW,CAAC,qBAAqB,yBAAyB;AAAA,EAC1D,UAAU,CAAC,yBAAyB;AACtC;AAKO,SAAS,wBAAyC;AACvD,SAAO,OAAO,KAAK,gBAAgB;AACrC;AAKO,MAAM,eAA2C;AAAA,EACtD,MAAM;AAAA;AAAA,EACN,QAAQ;AAAA;AAAA,EACR,OAAO;AAAA;AACT;","names":[]}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Scaffold Display Functions
3
+ *
4
+ * Display functions for consistent output formatting.
5
+ */
6
+ import type { CommandTemplate, ScaffoldResult, ScaffoldTarget, FileStatus } from './types.js';
7
+ import type { AgentTemplate } from './agent-types.js';
8
+ /**
9
+ * Display list of available commands
10
+ */
11
+ export declare function displayCommandList(templates: CommandTemplate[]): void;
12
+ /**
13
+ * Display list of available agents
14
+ */
15
+ export declare function displayAgentList(templates: AgentTemplate[], categoryFilter?: string): void;
16
+ /**
17
+ * Display scaffolding header
18
+ */
19
+ export declare function displayScaffoldHeader(target: ScaffoldTarget, targetPath: string, dryRun: boolean): void;
20
+ /**
21
+ * Display agent scaffolding header
22
+ */
23
+ export declare function displayAgentScaffoldHeader(target: ScaffoldTarget, targetPath: string, dryRun: boolean): void;
24
+ /**
25
+ * Display file operation result
26
+ */
27
+ export declare function displayFileOperation(filename: string, status: FileStatus, dryRun: boolean, updating: boolean): void;
28
+ /**
29
+ * Display diff between existing and new content
30
+ */
31
+ export declare function displayDiff(diff: string): void;
32
+ /**
33
+ * Display command preview
34
+ */
35
+ export declare function displayCommandPreview(name: string, content: string): void;
36
+ /**
37
+ * Display agent preview
38
+ */
39
+ export declare function displayAgentPreview(name: string, content: string, model: string): void;
40
+ /**
41
+ * Display scaffolding summary
42
+ */
43
+ export declare function displayScaffoldSummary(result: ScaffoldResult, target: ScaffoldTarget, dryRun: boolean): void;
44
+ /**
45
+ * Display agent scaffolding summary
46
+ */
47
+ export declare function displayAgentScaffoldSummary(result: ScaffoldResult, target: ScaffoldTarget, dryRun: boolean): void;
48
+ /**
49
+ * Display error for unknown target
50
+ */
51
+ export declare function displayTargetError(target: string, validTargets: string[]): void;
52
+ /**
53
+ * Display error for unsupported agent target
54
+ */
55
+ export declare function displayAgentTargetError(target: string, validTargets: string[]): void;
56
+ //# sourceMappingURL=display.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/scaffold/display.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC9F,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,kBAAkB,CAAC;AAKrE;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,IAAI,CAgBrE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,aAAa,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAmC1F;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,GACd,IAAI,CAQN;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,GACd,IAAI,CAQN;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,OAAO,GAChB,IAAI,CAwBN;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAgB9C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAMzE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAOtF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,OAAO,GACd,IAAI,CAkCN;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,OAAO,GACd,IAAI,CAkCN;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,CAG/E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,CAGpF"}
@@ -0,0 +1,217 @@
1
+ import { colors } from "../../ui/colors.js";
2
+ import { COMMAND_CATEGORIES } from "./types.js";
3
+ import { AGENT_CATEGORIES, MODEL_BADGES } from "./agent-types.js";
4
+ import { TARGETS } from "./targets.js";
5
+ function displayCommandList(templates) {
6
+ console.log(colors.bold("\nAvailable SpecForge Commands"));
7
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n");
8
+ for (const [category, commandNames] of Object.entries(COMMAND_CATEGORIES)) {
9
+ console.log(colors.bold(category));
10
+ for (const name of commandNames) {
11
+ const template = templates.find((t) => t.name === name);
12
+ if (template) {
13
+ console.log(` ${colors.primary(name.padEnd(25))} ${colors.dim(template.description)}`);
14
+ }
15
+ }
16
+ console.log();
17
+ }
18
+ console.log(colors.dim(`Total: ${templates.length} commands
19
+ `));
20
+ }
21
+ function displayAgentList(templates, categoryFilter) {
22
+ console.log(colors.bold("\nAvailable SpecForge Agents"));
23
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n");
24
+ const filteredCategories = categoryFilter ? Object.entries(AGENT_CATEGORIES).filter(([cat]) => cat.toLowerCase() === categoryFilter.toLowerCase()) : Object.entries(AGENT_CATEGORIES);
25
+ if (filteredCategories.length === 0) {
26
+ console.log(colors.warning(`No category matching "${categoryFilter}"`));
27
+ console.log(colors.dim(`Available categories: ${Object.keys(AGENT_CATEGORIES).join(", ")}`));
28
+ return;
29
+ }
30
+ for (const [category, agentNames] of filteredCategories) {
31
+ console.log(colors.bold(category));
32
+ for (const name of agentNames) {
33
+ const template = templates.find((t) => t.name === name);
34
+ if (template) {
35
+ const badge = MODEL_BADGES[template.model];
36
+ const modelLabel = colors.dim(`[${badge} ${template.model}]`);
37
+ console.log(` ${colors.primary(name.padEnd(25))} ${modelLabel} ${colors.dim(template.description)}`);
38
+ }
39
+ }
40
+ console.log();
41
+ }
42
+ const displayedTemplates = templates.filter((t) => {
43
+ if (!categoryFilter) return true;
44
+ return t.category.toLowerCase() === categoryFilter.toLowerCase();
45
+ });
46
+ console.log(colors.dim(`Total: ${displayedTemplates.length} agents
47
+ `));
48
+ console.log(colors.dim("Model legend: \u25C6 opus (powerful) \u25CF sonnet (balanced) \u25CB haiku (fast)\n"));
49
+ }
50
+ function displayScaffoldHeader(target, targetPath, dryRun) {
51
+ const config = TARGETS[target];
52
+ console.log(colors.bold(`
53
+ Scaffolding SpecForge commands for ${config.name}`));
54
+ console.log(`Target: ${colors.primary(targetPath)}
55
+ `);
56
+ if (dryRun) {
57
+ console.log(colors.warning("DRY RUN - No files will be written\n"));
58
+ }
59
+ }
60
+ function displayAgentScaffoldHeader(target, targetPath, dryRun) {
61
+ const config = TARGETS[target];
62
+ console.log(colors.bold(`
63
+ Scaffolding SpecForge agents for ${config.name}`));
64
+ console.log(`Target: ${colors.primary(targetPath)}
65
+ `);
66
+ if (dryRun) {
67
+ console.log(colors.warning("DRY RUN - No files will be written\n"));
68
+ }
69
+ }
70
+ function displayFileOperation(filename, status, dryRun, updating) {
71
+ switch (status) {
72
+ case "new":
73
+ if (dryRun) {
74
+ console.log(colors.success(` + ${filename} (would create)`));
75
+ } else {
76
+ console.log(colors.success(` + ${filename} (created)`));
77
+ }
78
+ break;
79
+ case "identical":
80
+ console.log(colors.dim(` \u25CB ${filename} (up to date)`));
81
+ break;
82
+ case "outdated":
83
+ if (updating) {
84
+ if (dryRun) {
85
+ console.log(colors.secondary(` \u21BB ${filename} (would update)`));
86
+ } else {
87
+ console.log(colors.secondary(` \u21BB ${filename} (updated)`));
88
+ }
89
+ } else {
90
+ console.log(colors.warning(` \u26A0 ${filename} (outdated, use --update)`));
91
+ }
92
+ break;
93
+ }
94
+ }
95
+ function displayDiff(diff) {
96
+ console.log();
97
+ for (const line of diff.split("\n")) {
98
+ if (line.startsWith("---") || line.startsWith("+++")) {
99
+ console.log(colors.bold(line));
100
+ } else if (line.startsWith("-")) {
101
+ console.log(colors.error(line));
102
+ } else if (line.startsWith("+")) {
103
+ console.log(colors.success(line));
104
+ } else if (line.startsWith("@@")) {
105
+ console.log(colors.primary(line));
106
+ } else {
107
+ console.log(line);
108
+ }
109
+ }
110
+ console.log();
111
+ }
112
+ function displayCommandPreview(name, content) {
113
+ console.log(colors.bold(`
114
+ Preview: ${name}`));
115
+ console.log("\u2500".repeat(50));
116
+ console.log(content);
117
+ console.log("\u2500".repeat(50));
118
+ console.log();
119
+ }
120
+ function displayAgentPreview(name, content, model) {
121
+ console.log(colors.bold(`
122
+ Preview: ${name}`));
123
+ console.log(colors.dim(`Model: ${model}`));
124
+ console.log("\u2500".repeat(50));
125
+ console.log(content);
126
+ console.log("\u2500".repeat(50));
127
+ console.log();
128
+ }
129
+ function displayScaffoldSummary(result, target, dryRun) {
130
+ const config = TARGETS[target];
131
+ console.log();
132
+ if (!dryRun) {
133
+ if (result.created > 0) {
134
+ console.log(colors.success(`\u2713 Created ${result.created} commands`));
135
+ }
136
+ if (result.updated > 0) {
137
+ console.log(colors.secondary(`\u2713 Updated ${result.updated} commands`));
138
+ }
139
+ if (result.skipped > 0) {
140
+ console.log(colors.dim(`\u25CB Skipped ${result.skipped} up-to-date commands`));
141
+ }
142
+ if (result.outdated > 0) {
143
+ console.log(colors.warning(`\u26A0 ${result.outdated} outdated commands (run with --update to update)`));
144
+ }
145
+ console.log(colors.bold(`
146
+ ${config.name} commands ready!`));
147
+ if (config.usageHint) {
148
+ console.log(colors.dim(`
149
+ ${config.usageHint}`));
150
+ }
151
+ } else {
152
+ const parts = [];
153
+ if (result.created > 0) parts.push(`create ${result.created}`);
154
+ if (result.updated > 0) parts.push(`update ${result.updated}`);
155
+ if (result.skipped > 0) parts.push(`skip ${result.skipped}`);
156
+ if (result.outdated > 0) parts.push(`${result.outdated} outdated`);
157
+ console.log(colors.warning(`Would ${parts.join(", ")}`));
158
+ }
159
+ console.log();
160
+ }
161
+ function displayAgentScaffoldSummary(result, target, dryRun) {
162
+ const config = TARGETS[target];
163
+ console.log();
164
+ if (!dryRun) {
165
+ if (result.created > 0) {
166
+ console.log(colors.success(`\u2713 Created ${result.created} agents`));
167
+ }
168
+ if (result.updated > 0) {
169
+ console.log(colors.secondary(`\u2713 Updated ${result.updated} agents`));
170
+ }
171
+ if (result.skipped > 0) {
172
+ console.log(colors.dim(`\u25CB Skipped ${result.skipped} up-to-date agents`));
173
+ }
174
+ if (result.outdated > 0) {
175
+ console.log(colors.warning(`\u26A0 ${result.outdated} outdated agents (run with --update to update)`));
176
+ }
177
+ console.log(colors.bold(`
178
+ ${config.name} agents ready!`));
179
+ if (config.agentUsageHint) {
180
+ console.log(colors.dim(`
181
+ ${config.agentUsageHint}`));
182
+ }
183
+ } else {
184
+ const parts = [];
185
+ if (result.created > 0) parts.push(`create ${result.created}`);
186
+ if (result.updated > 0) parts.push(`update ${result.updated}`);
187
+ if (result.skipped > 0) parts.push(`skip ${result.skipped}`);
188
+ if (result.outdated > 0) parts.push(`${result.outdated} outdated`);
189
+ console.log(colors.warning(`Would ${parts.join(", ")}`));
190
+ }
191
+ console.log();
192
+ }
193
+ function displayTargetError(target, validTargets) {
194
+ console.error(colors.error(`
195
+ Error: Unknown target "${target}"`));
196
+ console.error(`Available targets: ${validTargets.join(", ")}`);
197
+ }
198
+ function displayAgentTargetError(target, validTargets) {
199
+ console.error(colors.error(`
200
+ Error: Target "${target}" does not support agents`));
201
+ console.error(`Targets with agent support: ${validTargets.join(", ")}`);
202
+ }
203
+ export {
204
+ displayAgentList,
205
+ displayAgentPreview,
206
+ displayAgentScaffoldHeader,
207
+ displayAgentScaffoldSummary,
208
+ displayAgentTargetError,
209
+ displayCommandList,
210
+ displayCommandPreview,
211
+ displayDiff,
212
+ displayFileOperation,
213
+ displayScaffoldHeader,
214
+ displayScaffoldSummary,
215
+ displayTargetError
216
+ };
217
+ //# sourceMappingURL=display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/cli/commands/scaffold/display.ts"],"sourcesContent":["/**\n * Scaffold Display Functions\n *\n * Display functions for consistent output formatting.\n */\n\nimport { colors } from '../../ui/colors.js';\nimport type { CommandTemplate, ScaffoldResult, ScaffoldTarget, FileStatus } from './types.js';\nimport type { AgentTemplate, AgentCategory } from './agent-types.js';\nimport { COMMAND_CATEGORIES } from './types.js';\nimport { AGENT_CATEGORIES, MODEL_BADGES } from './agent-types.js';\nimport { TARGETS } from './targets.js';\n\n/**\n * Display list of available commands\n */\nexport function displayCommandList(templates: CommandTemplate[]): void {\n console.log(colors.bold('\\nAvailable SpecForge Commands'));\n console.log('═══════════════════════════════\\n');\n\n for (const [category, commandNames] of Object.entries(COMMAND_CATEGORIES)) {\n console.log(colors.bold(category));\n for (const name of commandNames) {\n const template = templates.find(t => t.name === name);\n if (template) {\n console.log(` ${colors.primary(name.padEnd(25))} ${colors.dim(template.description)}`);\n }\n }\n console.log();\n }\n\n console.log(colors.dim(`Total: ${templates.length} commands\\n`));\n}\n\n/**\n * Display list of available agents\n */\nexport function displayAgentList(templates: AgentTemplate[], categoryFilter?: string): void {\n console.log(colors.bold('\\nAvailable SpecForge Agents'));\n console.log('═══════════════════════════════\\n');\n\n const filteredCategories = categoryFilter\n ? Object.entries(AGENT_CATEGORIES).filter(([cat]) =>\n cat.toLowerCase() === categoryFilter.toLowerCase())\n : Object.entries(AGENT_CATEGORIES);\n\n if (filteredCategories.length === 0) {\n console.log(colors.warning(`No category matching \"${categoryFilter}\"`));\n console.log(colors.dim(`Available categories: ${Object.keys(AGENT_CATEGORIES).join(', ')}`));\n return;\n }\n\n for (const [category, agentNames] of filteredCategories) {\n console.log(colors.bold(category));\n for (const name of agentNames) {\n const template = templates.find(t => t.name === name);\n if (template) {\n const badge = MODEL_BADGES[template.model];\n const modelLabel = colors.dim(`[${badge} ${template.model}]`);\n console.log(` ${colors.primary(name.padEnd(25))} ${modelLabel} ${colors.dim(template.description)}`);\n }\n }\n console.log();\n }\n\n const displayedTemplates = templates.filter(t => {\n if (!categoryFilter) return true;\n return t.category.toLowerCase() === categoryFilter.toLowerCase();\n });\n\n console.log(colors.dim(`Total: ${displayedTemplates.length} agents\\n`));\n console.log(colors.dim('Model legend: ◆ opus (powerful) ● sonnet (balanced) ○ haiku (fast)\\n'));\n}\n\n/**\n * Display scaffolding header\n */\nexport function displayScaffoldHeader(\n target: ScaffoldTarget,\n targetPath: string,\n dryRun: boolean\n): void {\n const config = TARGETS[target];\n console.log(colors.bold(`\\nScaffolding SpecForge commands for ${config.name}`));\n console.log(`Target: ${colors.primary(targetPath)}\\n`);\n\n if (dryRun) {\n console.log(colors.warning('DRY RUN - No files will be written\\n'));\n }\n}\n\n/**\n * Display agent scaffolding header\n */\nexport function displayAgentScaffoldHeader(\n target: ScaffoldTarget,\n targetPath: string,\n dryRun: boolean\n): void {\n const config = TARGETS[target];\n console.log(colors.bold(`\\nScaffolding SpecForge agents for ${config.name}`));\n console.log(`Target: ${colors.primary(targetPath)}\\n`);\n\n if (dryRun) {\n console.log(colors.warning('DRY RUN - No files will be written\\n'));\n }\n}\n\n/**\n * Display file operation result\n */\nexport function displayFileOperation(\n filename: string,\n status: FileStatus,\n dryRun: boolean,\n updating: boolean\n): void {\n switch (status) {\n case 'new':\n if (dryRun) {\n console.log(colors.success(` + ${filename} (would create)`));\n } else {\n console.log(colors.success(` + ${filename} (created)`));\n }\n break;\n case 'identical':\n console.log(colors.dim(` ○ ${filename} (up to date)`));\n break;\n case 'outdated':\n if (updating) {\n if (dryRun) {\n console.log(colors.secondary(` ↻ ${filename} (would update)`));\n } else {\n console.log(colors.secondary(` ↻ ${filename} (updated)`));\n }\n } else {\n console.log(colors.warning(` ⚠ ${filename} (outdated, use --update)`));\n }\n break;\n }\n}\n\n/**\n * Display diff between existing and new content\n */\nexport function displayDiff(diff: string): void {\n console.log();\n for (const line of diff.split('\\n')) {\n if (line.startsWith('---') || line.startsWith('+++')) {\n console.log(colors.bold(line));\n } else if (line.startsWith('-')) {\n console.log(colors.error(line));\n } else if (line.startsWith('+')) {\n console.log(colors.success(line));\n } else if (line.startsWith('@@')) {\n console.log(colors.primary(line));\n } else {\n console.log(line);\n }\n }\n console.log();\n}\n\n/**\n * Display command preview\n */\nexport function displayCommandPreview(name: string, content: string): void {\n console.log(colors.bold(`\\nPreview: ${name}`));\n console.log('─'.repeat(50));\n console.log(content);\n console.log('─'.repeat(50));\n console.log();\n}\n\n/**\n * Display agent preview\n */\nexport function displayAgentPreview(name: string, content: string, model: string): void {\n console.log(colors.bold(`\\nPreview: ${name}`));\n console.log(colors.dim(`Model: ${model}`));\n console.log('─'.repeat(50));\n console.log(content);\n console.log('─'.repeat(50));\n console.log();\n}\n\n/**\n * Display scaffolding summary\n */\nexport function displayScaffoldSummary(\n result: ScaffoldResult,\n target: ScaffoldTarget,\n dryRun: boolean\n): void {\n const config = TARGETS[target];\n console.log();\n\n if (!dryRun) {\n if (result.created > 0) {\n console.log(colors.success(`✓ Created ${result.created} commands`));\n }\n if (result.updated > 0) {\n console.log(colors.secondary(`✓ Updated ${result.updated} commands`));\n }\n if (result.skipped > 0) {\n console.log(colors.dim(`○ Skipped ${result.skipped} up-to-date commands`));\n }\n if (result.outdated > 0) {\n console.log(colors.warning(`⚠ ${result.outdated} outdated commands (run with --update to update)`));\n }\n\n console.log(colors.bold(`\\n${config.name} commands ready!`));\n\n // Show usage hint\n if (config.usageHint) {\n console.log(colors.dim(`\\n${config.usageHint}`));\n }\n } else {\n const parts = [];\n if (result.created > 0) parts.push(`create ${result.created}`);\n if (result.updated > 0) parts.push(`update ${result.updated}`);\n if (result.skipped > 0) parts.push(`skip ${result.skipped}`);\n if (result.outdated > 0) parts.push(`${result.outdated} outdated`);\n console.log(colors.warning(`Would ${parts.join(', ')}`));\n }\n\n console.log();\n}\n\n/**\n * Display agent scaffolding summary\n */\nexport function displayAgentScaffoldSummary(\n result: ScaffoldResult,\n target: ScaffoldTarget,\n dryRun: boolean\n): void {\n const config = TARGETS[target];\n console.log();\n\n if (!dryRun) {\n if (result.created > 0) {\n console.log(colors.success(`✓ Created ${result.created} agents`));\n }\n if (result.updated > 0) {\n console.log(colors.secondary(`✓ Updated ${result.updated} agents`));\n }\n if (result.skipped > 0) {\n console.log(colors.dim(`○ Skipped ${result.skipped} up-to-date agents`));\n }\n if (result.outdated > 0) {\n console.log(colors.warning(`⚠ ${result.outdated} outdated agents (run with --update to update)`));\n }\n\n console.log(colors.bold(`\\n${config.name} agents ready!`));\n\n // Show agent usage hint\n if (config.agentUsageHint) {\n console.log(colors.dim(`\\n${config.agentUsageHint}`));\n }\n } else {\n const parts = [];\n if (result.created > 0) parts.push(`create ${result.created}`);\n if (result.updated > 0) parts.push(`update ${result.updated}`);\n if (result.skipped > 0) parts.push(`skip ${result.skipped}`);\n if (result.outdated > 0) parts.push(`${result.outdated} outdated`);\n console.log(colors.warning(`Would ${parts.join(', ')}`));\n }\n\n console.log();\n}\n\n/**\n * Display error for unknown target\n */\nexport function displayTargetError(target: string, validTargets: string[]): void {\n console.error(colors.error(`\\nError: Unknown target \"${target}\"`));\n console.error(`Available targets: ${validTargets.join(', ')}`);\n}\n\n/**\n * Display error for unsupported agent target\n */\nexport function displayAgentTargetError(target: string, validTargets: string[]): void {\n console.error(colors.error(`\\nError: Target \"${target}\" does not support agents`));\n console.error(`Targets with agent support: ${validTargets.join(', ')}`);\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Scaffold File Writers
3
+ *
4
+ * Public surface for writing MCP configs, instruction files, and conventions
5
+ * skill files for AI CLI tools. Used by both `specforge init` (orchestration)
6
+ * and `specforge scaffold` (direct user invocation).
7
+ *
8
+ * Each writer returns a structured `WriteResult` so callers can summarize
9
+ * uniformly across dry-run / force / no-overwrite modes.
10
+ */
11
+ import type { ScaffoldTarget } from './types.js';
12
+ /**
13
+ * Outcome of attempting to write a single file.
14
+ *
15
+ * - `created` : file did not exist; written
16
+ * - `overwrote` : file existed and was overwritten (force)
17
+ * - `skipped` : file exists and force was not set; left alone
18
+ * - `would-create`: dry-run — file would be created
19
+ * - `would-overwrite`: dry-run — file exists and would be overwritten with --force
20
+ * - `would-skip` : dry-run — file exists and would be left alone (no --force)
21
+ */
22
+ export type WriteAction = 'created' | 'overwrote' | 'skipped' | 'would-create' | 'would-overwrite' | 'would-skip';
23
+ export interface WriteResult {
24
+ /** Absolute path the writer targeted */
25
+ path: string;
26
+ /** Repo-relative path (cwd-anchored) for display */
27
+ relPath: string;
28
+ /** What happened */
29
+ action: WriteAction;
30
+ /** True if the writer made (or would make) any change */
31
+ changed: boolean;
32
+ }
33
+ export interface WriteOptions {
34
+ /** Don't actually write — return would-* actions instead */
35
+ dryRun?: boolean;
36
+ /** Overwrite existing files */
37
+ force?: boolean;
38
+ }
39
+ export interface WriteMcpConfigOptions extends WriteOptions {
40
+ /** When set, bake API key into the config; else use placeholder */
41
+ apiKey?: string;
42
+ }
43
+ export interface WriteSkillOptions extends WriteOptions {
44
+ /** When set, interpolate `{{PROJECT_NAME}}` placeholders in the skill template */
45
+ projectName?: string;
46
+ }
47
+ /**
48
+ * Write the `AGENTS.md` instruction file at the repository root.
49
+ * Used by Codex CLI and OpenCode as their native instruction file, and as the
50
+ * fallback for Cursor (no dedicated instruction file). Claude, Copilot, and
51
+ * Gemini each use their own instruction file instead.
52
+ */
53
+ export declare function writeAgentsMdFile(options?: WriteOptions): WriteResult;
54
+ /**
55
+ * Write a per-target instruction file (e.g., `CLAUDE.md`, `GEMINI.md`,
56
+ * `.github/copilot-instructions.md`).
57
+ *
58
+ * Returns `null` when the target has no dedicated instruction file (cursor,
59
+ * which falls back to AGENTS.md).
60
+ */
61
+ export declare function writeTargetInstructionFile(target: ScaffoldTarget, options?: WriteOptions): WriteResult | null;
62
+ /**
63
+ * Write a per-target MCP config file (`.mcp.json` for Claude/Copilot/Cursor,
64
+ * `.gemini/settings.json`, `.codex/config.toml`, `opencode.json`).
65
+ *
66
+ * Returns `null` when the target has no MCP config path declared.
67
+ */
68
+ export declare function writeTargetMcpConfig(target: ScaffoldTarget, options?: WriteMcpConfigOptions): WriteResult | null;
69
+ /**
70
+ * Write the SpecForge conventions skill into a target's project skill path.
71
+ * Returns `null` when the target doesn't support skills or the template is missing.
72
+ */
73
+ export declare function writeSkillForTarget(target: ScaffoldTarget, options?: WriteSkillOptions): WriteResult | null;
74
+ /**
75
+ * Multi-CLI scaffolding: writes per-detected-CLI instruction files, MCP configs,
76
+ * and conventions skills. AGENTS.md is only written when at least one selected
77
+ * target needs it (codex, opencode, cursor fallback).
78
+ *
79
+ * Used by `specforge init` and by `specforge scaffold` (no flags / `--configs`
80
+ * / `--instructions`). Honors dry-run and force flags via WriteOptions.
81
+ */
82
+ export interface ScaffoldMultiCliOptions extends WriteMcpConfigOptions, WriteSkillOptions {
83
+ /** Limit the run to these targets (default: all detected) */
84
+ targets?: ScaffoldTarget[];
85
+ /** Skip MCP config writes */
86
+ skipConfigs?: boolean;
87
+ /** Skip instruction file writes (per-target + AGENTS.md) */
88
+ skipInstructions?: boolean;
89
+ /** Skip conventions skill writes */
90
+ skipSkills?: boolean;
91
+ }
92
+ export interface ScaffoldMultiCliResult {
93
+ /** Targets the run considered */
94
+ detected: ScaffoldTarget[];
95
+ /** All write attempts in order */
96
+ writes: WriteResult[];
97
+ }
98
+ export declare function scaffoldMultiCli(options?: ScaffoldMultiCliOptions): ScaffoldMultiCliResult;
99
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/scaffold/files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAQjD;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,WAAW,GACX,SAAS,GACT,cAAc,GACd,iBAAiB,GACjB,YAAY,CAAC;AAEjB,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB;IACpB,MAAM,EAAE,WAAW,CAAC;IACpB,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,qBAAsB,SAAQ,YAAY;IACzD,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA+CD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,YAAiB,GAAG,WAAW,CAGzE;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,YAAiB,GACzB,WAAW,GAAG,IAAI,CAMpB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,qBAA0B,GAClC,WAAW,GAAG,IAAI,CAOpB;AAcD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,iBAAsB,GAC9B,WAAW,GAAG,IAAI,CAcpB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,uBAAwB,SAAQ,qBAAqB,EAAE,iBAAiB;IACvF,6DAA6D;IAC7D,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;IAC3B,6BAA6B;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oCAAoC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACrC,iCAAiC;IACjC,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,kCAAkC;IAClC,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,GAAG,sBAAsB,CA6C9F"}
@@ -0,0 +1,122 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { fileURLToPath } from "url";
4
+ import { TARGETS } from "./targets.js";
5
+ import {
6
+ detectInstalledTools,
7
+ generateMcpConfig,
8
+ generateAgentsmd,
9
+ generateInstructionFileContent
10
+ } from "./utils.js";
11
+ function writeWithGuard(filePath, content, options) {
12
+ const exists = fs.existsSync(filePath);
13
+ const dryRun = options.dryRun === true;
14
+ const force = options.force === true;
15
+ const relPath = path.relative(process.cwd(), filePath) || filePath;
16
+ if (exists && !force) {
17
+ return {
18
+ path: filePath,
19
+ relPath,
20
+ action: dryRun ? "would-skip" : "skipped",
21
+ changed: false
22
+ };
23
+ }
24
+ if (dryRun) {
25
+ return {
26
+ path: filePath,
27
+ relPath,
28
+ action: exists ? "would-overwrite" : "would-create",
29
+ changed: true
30
+ };
31
+ }
32
+ const dir = path.dirname(filePath);
33
+ if (!fs.existsSync(dir)) {
34
+ fs.mkdirSync(dir, { recursive: true });
35
+ }
36
+ fs.writeFileSync(filePath, content, "utf-8");
37
+ return {
38
+ path: filePath,
39
+ relPath,
40
+ action: exists ? "overwrote" : "created",
41
+ changed: true
42
+ };
43
+ }
44
+ function writeAgentsMdFile(options = {}) {
45
+ const filePath = path.resolve(process.cwd(), "AGENTS.md");
46
+ return writeWithGuard(filePath, generateAgentsmd(), options);
47
+ }
48
+ function writeTargetInstructionFile(target, options = {}) {
49
+ const config = TARGETS[target];
50
+ if (!config.instructionFilePath) return null;
51
+ const filePath = path.resolve(process.cwd(), config.instructionFilePath);
52
+ return writeWithGuard(filePath, generateInstructionFileContent(target), options);
53
+ }
54
+ function writeTargetMcpConfig(target, options = {}) {
55
+ const config = TARGETS[target];
56
+ if (!config.mcpConfigPath) return null;
57
+ const filePath = path.resolve(process.cwd(), config.mcpConfigPath);
58
+ const content = generateMcpConfig(target, { apiKey: options.apiKey });
59
+ return writeWithGuard(filePath, content, options);
60
+ }
61
+ function getConventionsTemplatePath() {
62
+ const __filename = fileURLToPath(import.meta.url);
63
+ const __dirname = path.dirname(__filename);
64
+ const packageRoot = path.resolve(__dirname, "..", "..", "..", "..");
65
+ return path.join(packageRoot, "src", "cli", "templates", "skills", "specforge-conventions.md");
66
+ }
67
+ function writeSkillForTarget(target, options = {}) {
68
+ const config = TARGETS[target];
69
+ if (!config.supportsSkills || !config.projectSkillPath) return null;
70
+ const templatePath = getConventionsTemplatePath();
71
+ if (!fs.existsSync(templatePath)) return null;
72
+ let content = fs.readFileSync(templatePath, "utf-8");
73
+ if (options.projectName) {
74
+ content = content.replace(/\{\{PROJECT_NAME\}\}/g, options.projectName);
75
+ }
76
+ const skillFile = path.join(config.projectSkillPath(), "specforge-conventions", "SKILL.md");
77
+ return writeWithGuard(skillFile, content, options);
78
+ }
79
+ function scaffoldMultiCli(options = {}) {
80
+ let detected;
81
+ if (options.targets && options.targets.length > 0) {
82
+ detected = options.targets;
83
+ } else {
84
+ try {
85
+ detected = detectInstalledTools() ?? [];
86
+ } catch {
87
+ detected = [];
88
+ }
89
+ }
90
+ const writes = [];
91
+ const writeOpts = { dryRun: options.dryRun, force: options.force };
92
+ const needsAgentsMd = detected.some((t) => {
93
+ const cfg = TARGETS[t];
94
+ return cfg.instructionFilePath === "AGENTS.md" || cfg.instructionFilePath === null;
95
+ });
96
+ if (!options.skipInstructions && needsAgentsMd) {
97
+ writes.push(writeAgentsMdFile(writeOpts));
98
+ }
99
+ for (const target of detected) {
100
+ if (!options.skipInstructions) {
101
+ const r = writeTargetInstructionFile(target, writeOpts);
102
+ if (r) writes.push(r);
103
+ }
104
+ if (!options.skipConfigs) {
105
+ const r = writeTargetMcpConfig(target, { ...writeOpts, apiKey: options.apiKey });
106
+ if (r) writes.push(r);
107
+ }
108
+ if (!options.skipSkills) {
109
+ const r = writeSkillForTarget(target, { ...writeOpts, projectName: options.projectName });
110
+ if (r) writes.push(r);
111
+ }
112
+ }
113
+ return { detected, writes };
114
+ }
115
+ export {
116
+ scaffoldMultiCli,
117
+ writeAgentsMdFile,
118
+ writeSkillForTarget,
119
+ writeTargetInstructionFile,
120
+ writeTargetMcpConfig
121
+ };
122
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/cli/commands/scaffold/files.ts"],"sourcesContent":["/**\n * Scaffold File Writers\n *\n * Public surface for writing MCP configs, instruction files, and conventions\n * skill files for AI CLI tools. Used by both `specforge init` (orchestration)\n * and `specforge scaffold` (direct user invocation).\n *\n * Each writer returns a structured `WriteResult` so callers can summarize\n * uniformly across dry-run / force / no-overwrite modes.\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { TARGETS } from './targets.js';\nimport type { ScaffoldTarget } from './types.js';\nimport {\n detectInstalledTools,\n generateMcpConfig,\n generateAgentsmd,\n generateInstructionFileContent,\n} from './utils.js';\n\n/**\n * Outcome of attempting to write a single file.\n *\n * - `created` : file did not exist; written\n * - `overwrote` : file existed and was overwritten (force)\n * - `skipped` : file exists and force was not set; left alone\n * - `would-create`: dry-run — file would be created\n * - `would-overwrite`: dry-run — file exists and would be overwritten with --force\n * - `would-skip` : dry-run — file exists and would be left alone (no --force)\n */\nexport type WriteAction =\n | 'created'\n | 'overwrote'\n | 'skipped'\n | 'would-create'\n | 'would-overwrite'\n | 'would-skip';\n\nexport interface WriteResult {\n /** Absolute path the writer targeted */\n path: string;\n /** Repo-relative path (cwd-anchored) for display */\n relPath: string;\n /** What happened */\n action: WriteAction;\n /** True if the writer made (or would make) any change */\n changed: boolean;\n}\n\nexport interface WriteOptions {\n /** Don't actually write — return would-* actions instead */\n dryRun?: boolean;\n /** Overwrite existing files */\n force?: boolean;\n}\n\nexport interface WriteMcpConfigOptions extends WriteOptions {\n /** When set, bake API key into the config; else use placeholder */\n apiKey?: string;\n}\n\nexport interface WriteSkillOptions extends WriteOptions {\n /** When set, interpolate `{{PROJECT_NAME}}` placeholders in the skill template */\n projectName?: string;\n}\n\n/**\n * Internal: write a file (or report what would happen) with overwrite semantics.\n */\nfunction writeWithGuard(\n filePath: string,\n content: string,\n options: WriteOptions,\n): WriteResult {\n const exists = fs.existsSync(filePath);\n const dryRun = options.dryRun === true;\n const force = options.force === true;\n const relPath = path.relative(process.cwd(), filePath) || filePath;\n\n if (exists && !force) {\n return {\n path: filePath,\n relPath,\n action: dryRun ? 'would-skip' : 'skipped',\n changed: false,\n };\n }\n\n if (dryRun) {\n return {\n path: filePath,\n relPath,\n action: exists ? 'would-overwrite' : 'would-create',\n changed: true,\n };\n }\n\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(filePath, content, 'utf-8');\n\n return {\n path: filePath,\n relPath,\n action: exists ? 'overwrote' : 'created',\n changed: true,\n };\n}\n\n/**\n * Write the `AGENTS.md` instruction file at the repository root.\n * Used by Codex CLI and OpenCode as their native instruction file, and as the\n * fallback for Cursor (no dedicated instruction file). Claude, Copilot, and\n * Gemini each use their own instruction file instead.\n */\nexport function writeAgentsMdFile(options: WriteOptions = {}): WriteResult {\n const filePath = path.resolve(process.cwd(), 'AGENTS.md');\n return writeWithGuard(filePath, generateAgentsmd(), options);\n}\n\n/**\n * Write a per-target instruction file (e.g., `CLAUDE.md`, `GEMINI.md`,\n * `.github/copilot-instructions.md`).\n *\n * Returns `null` when the target has no dedicated instruction file (cursor,\n * which falls back to AGENTS.md).\n */\nexport function writeTargetInstructionFile(\n target: ScaffoldTarget,\n options: WriteOptions = {},\n): WriteResult | null {\n const config = TARGETS[target];\n if (!config.instructionFilePath) return null;\n\n const filePath = path.resolve(process.cwd(), config.instructionFilePath);\n return writeWithGuard(filePath, generateInstructionFileContent(target), options);\n}\n\n/**\n * Write a per-target MCP config file (`.mcp.json` for Claude/Copilot/Cursor,\n * `.gemini/settings.json`, `.codex/config.toml`, `opencode.json`).\n *\n * Returns `null` when the target has no MCP config path declared.\n */\nexport function writeTargetMcpConfig(\n target: ScaffoldTarget,\n options: WriteMcpConfigOptions = {},\n): WriteResult | null {\n const config = TARGETS[target];\n if (!config.mcpConfigPath) return null;\n\n const filePath = path.resolve(process.cwd(), config.mcpConfigPath);\n const content = generateMcpConfig(target, { apiKey: options.apiKey });\n return writeWithGuard(filePath, content, options);\n}\n\n/**\n * Resolve the bundled `specforge-conventions.md` skill template path.\n */\nfunction getConventionsTemplatePath(): string {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n // dist/cli/commands/scaffold/files.js or src/cli/commands/scaffold/files.ts\n // → packages/cli/{dist,src} → src/cli/templates/skills/specforge-conventions.md\n const packageRoot = path.resolve(__dirname, '..', '..', '..', '..');\n return path.join(packageRoot, 'src', 'cli', 'templates', 'skills', 'specforge-conventions.md');\n}\n\n/**\n * Write the SpecForge conventions skill into a target's project skill path.\n * Returns `null` when the target doesn't support skills or the template is missing.\n */\nexport function writeSkillForTarget(\n target: ScaffoldTarget,\n options: WriteSkillOptions = {},\n): WriteResult | null {\n const config = TARGETS[target];\n if (!config.supportsSkills || !config.projectSkillPath) return null;\n\n const templatePath = getConventionsTemplatePath();\n if (!fs.existsSync(templatePath)) return null;\n\n let content = fs.readFileSync(templatePath, 'utf-8');\n if (options.projectName) {\n content = content.replace(/\\{\\{PROJECT_NAME\\}\\}/g, options.projectName);\n }\n\n const skillFile = path.join(config.projectSkillPath(), 'specforge-conventions', 'SKILL.md');\n return writeWithGuard(skillFile, content, options);\n}\n\n/**\n * Multi-CLI scaffolding: writes per-detected-CLI instruction files, MCP configs,\n * and conventions skills. AGENTS.md is only written when at least one selected\n * target needs it (codex, opencode, cursor fallback).\n *\n * Used by `specforge init` and by `specforge scaffold` (no flags / `--configs`\n * / `--instructions`). Honors dry-run and force flags via WriteOptions.\n */\nexport interface ScaffoldMultiCliOptions extends WriteMcpConfigOptions, WriteSkillOptions {\n /** Limit the run to these targets (default: all detected) */\n targets?: ScaffoldTarget[];\n /** Skip MCP config writes */\n skipConfigs?: boolean;\n /** Skip instruction file writes (per-target + AGENTS.md) */\n skipInstructions?: boolean;\n /** Skip conventions skill writes */\n skipSkills?: boolean;\n}\n\nexport interface ScaffoldMultiCliResult {\n /** Targets the run considered */\n detected: ScaffoldTarget[];\n /** All write attempts in order */\n writes: WriteResult[];\n}\n\nexport function scaffoldMultiCli(options: ScaffoldMultiCliOptions = {}): ScaffoldMultiCliResult {\n let detected: ScaffoldTarget[];\n if (options.targets && options.targets.length > 0) {\n detected = options.targets;\n } else {\n try {\n detected = detectInstalledTools() ?? [];\n } catch {\n detected = [];\n }\n }\n\n const writes: WriteResult[] = [];\n const writeOpts: WriteOptions = { dryRun: options.dryRun, force: options.force };\n\n // AGENTS.md is only written for targets that use it natively (codex, opencode)\n // or have no dedicated instruction file and fall back to it (cursor). Claude,\n // Copilot, and Gemini each have their own instruction file and don't need it.\n const needsAgentsMd = detected.some((t) => {\n const cfg = TARGETS[t];\n return cfg.instructionFilePath === 'AGENTS.md' || cfg.instructionFilePath === null;\n });\n\n if (!options.skipInstructions && needsAgentsMd) {\n writes.push(writeAgentsMdFile(writeOpts));\n }\n\n for (const target of detected) {\n if (!options.skipInstructions) {\n const r = writeTargetInstructionFile(target, writeOpts);\n if (r) writes.push(r);\n }\n\n if (!options.skipConfigs) {\n const r = writeTargetMcpConfig(target, { ...writeOpts, apiKey: options.apiKey });\n if (r) writes.push(r);\n }\n\n if (!options.skipSkills) {\n const r = writeSkillForTarget(target, { ...writeOpts, projectName: options.projectName });\n if (r) writes.push(r);\n }\n }\n\n return { detected, writes };\n}\n"],"mappings":"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","names":[]}