@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 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/scaffold/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ const COMMAND_CATEGORIES = {
2
+ "Setup": ["sf-init", "sf-context"],
3
+ "Status": ["sf-status", "sf-analyze-blockers"],
4
+ "Review": ["sf-search"],
5
+ "Utilities": ["sf-reset", "sf-commit", "sf-help"]
6
+ };
7
+ const SCAFFOLD_VERSION = "1.0.0";
8
+ export {
9
+ COMMAND_CATEGORIES,
10
+ SCAFFOLD_VERSION
11
+ };
12
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/cli/commands/scaffold/types.ts"],"sourcesContent":["/**\n * Scaffold Command Types & Interfaces\n *\n * Type definitions for the scaffold command that generates AI CLI tool commands.\n */\n\n/**\n * Options for the scaffold command\n */\nexport interface ScaffoldOptions {\n /** Target AI CLI tool (claude, copilot, codex, gemini, opencode, cursor; alias: vscode) */\n target?: string;\n /** Install to global location (default) */\n global?: boolean;\n /** Install to project .specforge/ */\n project?: boolean;\n /** List available commands */\n list?: boolean;\n /** Update existing commands to latest version */\n update?: boolean;\n /** Force overwrite existing files (configs, instructions) */\n force?: boolean;\n /** Show what would be created without writing */\n dryRun?: boolean;\n /** Preview a specific command content (interactive if no command specified) */\n preview?: string | boolean;\n /** Show diff for outdated commands */\n diff?: boolean;\n /** Scaffold MCP config files (.mcp.json, .codex/config.toml, etc.) */\n configs?: boolean;\n /** Scaffold instruction files (CLAUDE.md, GEMINI.md, AGENTS.md, etc.) */\n instructions?: boolean;\n /** Scaffold AI agents instead of commands */\n agents?: boolean;\n /** Scaffold skills instead of commands */\n skills?: boolean;\n /** Scaffold slash commands (explicit subset selector) */\n commands?: boolean;\n /** Filter agents by category */\n category?: string;\n}\n\n/**\n * Supported AI CLI targets\n *\n * Note: `vscode` is a string-level alias for `cursor` (resolved at command entry),\n * not a separate target — VS Code with Copilot reads the same `.mcp.json` Cursor reads.\n */\nexport type ScaffoldTarget = 'claude' | 'copilot' | 'codex' | 'gemini' | 'opencode' | 'cursor';\n\n/**\n * Command format for a target\n */\nexport type CommandFormat = 'markdown' | 'toml' | null;\n\n/**\n * Configuration for a target AI CLI tool\n */\nexport interface TargetConfig {\n /** Display name of the AI CLI tool */\n name: string;\n /** Detection path — directory checked to determine if CLI is installed */\n detectionPath: () => string;\n /** Function to get global command installation path */\n globalCommandPath?: () => string;\n /** Function to get project command installation path */\n projectCommandPath?: () => string;\n /** Function to get global skill installation path */\n globalSkillPath?: () => string;\n /** Function to get project skill installation path */\n projectSkillPath?: () => string;\n /** Function to get global agent installation path */\n globalAgentPath?: () => string;\n /** Function to get project agent installation path */\n projectAgentPath?: () => string;\n /** File extension for command files */\n commandExtension: string;\n /** File extension for skill files */\n skillExtension: string;\n /** File extension for agent files */\n agentExtension: string;\n /** Whether commands use YAML frontmatter */\n commandFrontmatter: boolean;\n /** Whether skills use YAML frontmatter (agentskills.io) */\n skillFrontmatter: boolean;\n /** Whether agents use YAML frontmatter */\n agentFrontmatter: boolean;\n /** Whether the target supports slash commands */\n supportsCommands: boolean;\n /** Whether the target supports skills */\n supportsSkills: boolean;\n /** Whether the target supports AI agents */\n supportsAgents: boolean;\n /** Command format (markdown, toml, or null if unsupported) */\n commandFormat: CommandFormat;\n /** Argument syntax for commands (e.g., '$ARGUMENTS', '{{args}}') */\n argSyntax: string | null;\n /** Instruction file name for this CLI (e.g., 'CLAUDE.md', 'GEMINI.md'); null = use AGENTS.md fallback */\n instructionFile?: string | null;\n /** Instruction file path (relative, e.g., '.github/copilot-instructions.md'); null = use AGENTS.md fallback */\n instructionFilePath?: string | null;\n /** MCP config file path */\n mcpConfigPath?: string;\n /** MCP config format */\n mcpConfigFormat?: 'claude-json' | 'gemini-json' | 'codex-toml' | 'opencode-json';\n /** Usage hint for after scaffolding */\n usageHint?: string;\n /** Usage hint for agents after scaffolding */\n agentUsageHint?: string;\n\n // Legacy compatibility — kept for backward compat with existing scaffold code\n /** @deprecated Use globalCommandPath */\n globalPath: () => string;\n /** @deprecated Use projectCommandPath */\n projectPath: () => string;\n /** @deprecated Use commandExtension */\n fileExtension: string;\n /** @deprecated Use commandFrontmatter */\n needsFrontmatter: boolean;\n}\n\n/**\n * Map of all target configurations\n */\nexport type TargetConfigMap = Record<ScaffoldTarget, TargetConfig>;\n\n/**\n * Command template definition\n */\nexport interface CommandTemplate {\n /** Command name (e.g., 'sf-init') */\n name: string;\n /** Short description for command list */\n description: string;\n /** Argument hint for frontmatter (e.g., '[specification-id]') */\n argumentHint?: string;\n /** Full markdown content of the command */\n content: string;\n /** Command category for grouping */\n category: CommandCategory;\n}\n\nexport type CommandCategory =\n | 'Setup'\n | 'Status'\n | 'Review'\n | 'Utilities';\n\n/**\n * Scaffolding result statistics\n */\nexport interface ScaffoldResult {\n /** Number of files created */\n created: number;\n /** Number of files updated */\n updated: number;\n /** Number of files skipped (identical) */\n skipped: number;\n /** Number of files outdated (skipped but different) */\n outdated: number;\n /** Target path where files were written */\n targetPath: string;\n}\n\n/**\n * File comparison status\n */\nexport type FileStatus = 'new' | 'identical' | 'outdated';\n\n/**\n * File comparison result\n */\nexport interface FileComparison {\n /** Status of the file */\n status: FileStatus;\n /** Existing content (if file exists) */\n existingContent?: string;\n /** New content to write */\n newContent: string;\n}\n\nexport const COMMAND_CATEGORIES: Record<CommandCategory, string[]> = {\n 'Setup': ['sf-init', 'sf-context'],\n 'Status': ['sf-status', 'sf-analyze-blockers'],\n 'Review': ['sf-search'],\n 'Utilities': ['sf-reset', 'sf-commit', 'sf-help'],\n};\n\n/**\n * Version string for generated commands\n */\nexport const SCAFFOLD_VERSION = '1.0.0';\n"],"mappings":"AAqLO,MAAM,qBAAwD;AAAA,EACnE,SAAS,CAAC,WAAW,YAAY;AAAA,EACjC,UAAU,CAAC,aAAa,qBAAqB;AAAA,EAC7C,UAAU,CAAC,WAAW;AAAA,EACtB,aAAa,CAAC,YAAY,aAAa,SAAS;AAClD;AAKO,MAAM,mBAAmB;","names":[]}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Scaffold Utility Functions
3
+ *
4
+ * Utility functions for file operations and content generation.
5
+ */
6
+ import type { CommandTemplate, ScaffoldTarget, FileComparison } from './types.js';
7
+ import type { AgentTemplate } from './agent-types.js';
8
+ /**
9
+ * Detect which AI CLI tools are installed by checking their detection paths
10
+ */
11
+ export declare function detectInstalledTools(): ScaffoldTarget[];
12
+ /**
13
+ * Generate command content for a target format
14
+ */
15
+ export declare function generateCommandContent(template: CommandTemplate, needsFrontmatter: boolean, target: string): string;
16
+ /**
17
+ * Generate agent content for a target format.
18
+ *
19
+ * File layout (all targets):
20
+ * 1. YAML frontmatter (if the target supports it)
21
+ * 2. `<!-- {short-name} SpecForge {cli-version} -->` comment
22
+ * 3. Agent body content
23
+ *
24
+ * The version comment must come AFTER the frontmatter — Claude Code (and
25
+ * stricter Markdown parsers) only recognize frontmatter when the very first
26
+ * line of the file is `---`. A leading comment makes the file look like
27
+ * plain Markdown with no frontmatter, breaking agent registration.
28
+ */
29
+ export declare function generateAgentContent(template: AgentTemplate, needsFrontmatter: boolean, target?: ScaffoldTarget): string;
30
+ /**
31
+ * Ensure directory exists
32
+ */
33
+ export declare function ensureDirectory(dirPath: string): void;
34
+ /**
35
+ * Check if file exists
36
+ */
37
+ export declare function fileExists(filePath: string): boolean;
38
+ /**
39
+ * Write content to file
40
+ */
41
+ export declare function writeFile(filePath: string, content: string): void;
42
+ /**
43
+ * Get command filename
44
+ */
45
+ export declare function getCommandFilename(commandName: string, extension: string): string;
46
+ /**
47
+ * Get agent filename for a target
48
+ */
49
+ export declare function getAgentFilename(name: string, target?: ScaffoldTarget): string;
50
+ /**
51
+ * Get skill directory name (agentskills.io uses SKILL.md inside named directory)
52
+ */
53
+ export declare function getSkillDirName(name: string): string;
54
+ /**
55
+ * Read file content
56
+ */
57
+ export declare function readFile(filePath: string): string | null;
58
+ /**
59
+ * Compare existing and new content
60
+ */
61
+ export declare function compareFiles(filePath: string, newContent: string): FileComparison;
62
+ /**
63
+ * Generate a simple unified diff between two strings
64
+ */
65
+ export declare function generateDiff(oldContent: string, newContent: string, filename: string): string;
66
+ /**
67
+ * Options for MCP config generation
68
+ */
69
+ export interface GenerateMcpConfigOptions {
70
+ /** When set, bake this API key into the env block instead of using a placeholder */
71
+ apiKey?: string;
72
+ }
73
+ /**
74
+ * Generate MCP config content for a specific target.
75
+ *
76
+ * When `options.apiKey` is provided, the key is inlined in the `env` block
77
+ * (matches the legacy `saveMcpConfig()` behavior for Claude). Otherwise a
78
+ * placeholder is emitted so the agent reads `SPECFORGE_API_KEY` from its env.
79
+ */
80
+ export declare function generateMcpConfig(target: ScaffoldTarget, options?: GenerateMcpConfigOptions): string;
81
+ /**
82
+ * Generate AGENTS.md content (universal instruction file)
83
+ */
84
+ export declare function generateAgentsmd(): string;
85
+ /**
86
+ * Generate per-target instruction file content
87
+ */
88
+ export declare function generateInstructionFileContent(target: ScaffoldTarget): string;
89
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/scaffold/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;AAC9F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AA+DtD;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,EAAE,CAWvD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,eAAe,EACzB,gBAAgB,EAAE,OAAO,EACzB,MAAM,EAAE,MAAM,GACb,MAAM,CAqCR;AAgDD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,aAAa,EACvB,gBAAgB,EAAE,OAAO,EACzB,MAAM,CAAC,EAAE,cAAc,GACtB,MAAM,CAoCR;AAkED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAIrD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAEjE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM,CAK9E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUxD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,CAgBjF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmC7F;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,wBAAwB,GAAG,MAAM,CA0DpG;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAgCzC;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CA0B7E"}
@@ -0,0 +1,401 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { fileURLToPath } from "url";
4
+ import { TARGETS } from "./targets.js";
5
+ import { SCAFFOLD_VERSION } from "./types.js";
6
+ import { CHANNEL } from "../../../channel.js";
7
+ function getCliPackageName() {
8
+ return CHANNEL.packageName;
9
+ }
10
+ let cachedCliVersion = null;
11
+ function getCliVersion() {
12
+ if (cachedCliVersion) return cachedCliVersion;
13
+ try {
14
+ const pkg = readCliPackageJson();
15
+ const version = typeof pkg.version === "string" ? pkg.version : "";
16
+ if (version) {
17
+ cachedCliVersion = version;
18
+ return version;
19
+ }
20
+ } catch {
21
+ }
22
+ cachedCliVersion = SCAFFOLD_VERSION;
23
+ return cachedCliVersion;
24
+ }
25
+ function readCliPackageJson() {
26
+ const __filename = fileURLToPath(import.meta.url);
27
+ const __dirname = path.dirname(__filename);
28
+ const packageRoot = path.resolve(__dirname, "..", "..", "..", "..");
29
+ return JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf-8"));
30
+ }
31
+ function formatAgentVersionComment(agentName) {
32
+ const shortName = agentName.startsWith("sfag-") ? agentName.slice("sfag-".length) : agentName;
33
+ return `<!-- ${shortName} SpecForge ${getCliVersion()} -->`;
34
+ }
35
+ function detectInstalledTools() {
36
+ const installed = [];
37
+ for (const [target, config] of Object.entries(TARGETS)) {
38
+ const detectionDir = config.detectionPath();
39
+ if (fs.existsSync(detectionDir)) {
40
+ installed.push(target);
41
+ }
42
+ }
43
+ return installed;
44
+ }
45
+ function generateCommandContent(template, needsFrontmatter, target) {
46
+ const config = TARGETS[target];
47
+ if (config?.commandFormat === "toml") {
48
+ return generateTomlCommandContent(template, target);
49
+ }
50
+ let content = "";
51
+ content += `<!-- SpecForge v${SCAFFOLD_VERSION} -->
52
+ `;
53
+ if (needsFrontmatter) {
54
+ content += "---\n";
55
+ if (template.argumentHint) {
56
+ content += `argument-hint: ${template.argumentHint}
57
+ `;
58
+ }
59
+ content += `description: ${template.description}
60
+ `;
61
+ content += "---\n\n";
62
+ }
63
+ let body = template.content;
64
+ if (config?.argSyntax && config.argSyntax !== "$ARGUMENTS") {
65
+ body = body.replace(/\$ARGUMENTS/g, config.argSyntax);
66
+ }
67
+ content += body;
68
+ content = content.replace(/\{TARGET\}/g, target);
69
+ return content;
70
+ }
71
+ function generateTomlCommandContent(template, target) {
72
+ let body = template.content;
73
+ body = body.replace(/\$ARGUMENTS/g, "{{args}}");
74
+ body = body.replace(/\{TARGET\}/g, target);
75
+ const escapedBody = body.replace(/"""/g, '\\"\\"\\"');
76
+ let content = `# SpecForge v${SCAFFOLD_VERSION}
77
+ `;
78
+ content += `description = "${escapeTomlString(template.description)}"
79
+ `;
80
+ content += `prompt = """
81
+ ${escapedBody}
82
+ """
83
+ `;
84
+ return content;
85
+ }
86
+ function escapeTomlString(value) {
87
+ return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
88
+ }
89
+ function escapeYaml(value) {
90
+ if (value.includes(":") || value.includes("#") || value.includes("\n") || value.includes('"') || value.includes("'") || value.startsWith(" ") || value.endsWith(" ")) {
91
+ if (value.includes("\n")) {
92
+ const lines = value.split("\n").map((line) => ` ${line}`).join("\n");
93
+ return `|
94
+ ${lines}`;
95
+ }
96
+ return `"${value.replace(/"/g, '\\"')}"`;
97
+ }
98
+ return value;
99
+ }
100
+ function generateAgentContent(template, needsFrontmatter, target) {
101
+ const config = target ? TARGETS[target] : void 0;
102
+ if (target === "copilot") {
103
+ return generateCopilotAgentContent(template);
104
+ }
105
+ if (target === "gemini") {
106
+ return generateGeminiAgentContent(template);
107
+ }
108
+ if (target === "opencode") {
109
+ return generateOpenCodeAgentContent(template);
110
+ }
111
+ let content = "";
112
+ if (needsFrontmatter || (config?.agentFrontmatter ?? needsFrontmatter)) {
113
+ content += "---\n";
114
+ content += `name: ${template.name}
115
+ `;
116
+ content += `description: ${escapeYaml(template.triggerDescription)}
117
+ `;
118
+ content += `model: ${template.model}
119
+ `;
120
+ content += `color: ${template.color}
121
+ `;
122
+ if (template.memory) {
123
+ content += `memory: ${template.memory}
124
+ `;
125
+ }
126
+ content += "---\n\n";
127
+ }
128
+ content += `${formatAgentVersionComment(template.name)}
129
+
130
+ `;
131
+ content += template.content;
132
+ return content;
133
+ }
134
+ const MODEL_MAP = {
135
+ claude: { opus: "opus", sonnet: "sonnet", haiku: "haiku" },
136
+ copilot: { opus: "", sonnet: "", haiku: "" },
137
+ // Copilot doesn't support model selection
138
+ gemini: { opus: "gemini-2.5-pro", sonnet: "gemini-2.5-flash", haiku: "gemini-2.0-flash-lite" },
139
+ codex: { opus: "", sonnet: "", haiku: "" },
140
+ // Codex uses TOML roles
141
+ opencode: {
142
+ opus: "anthropic/claude-opus-4-20250514",
143
+ sonnet: "anthropic/claude-sonnet-4-20250514",
144
+ haiku: "anthropic/claude-haiku-4-20250514"
145
+ }
146
+ };
147
+ function generateCopilotAgentContent(template) {
148
+ let content = "---\n";
149
+ content += `name: ${template.name}
150
+ `;
151
+ content += `description: ${escapeYaml(template.triggerDescription)}
152
+ `;
153
+ content += "---\n\n";
154
+ content += `${formatAgentVersionComment(template.name)}
155
+
156
+ `;
157
+ content += template.content;
158
+ return content;
159
+ }
160
+ function generateGeminiAgentContent(template) {
161
+ const model = MODEL_MAP.gemini[template.model] || "gemini-2.5-flash";
162
+ let content = "---\n";
163
+ content += `name: ${template.name}
164
+ `;
165
+ content += `description: ${escapeYaml(template.triggerDescription)}
166
+ `;
167
+ content += `model: ${model}
168
+ `;
169
+ content += `temperature: 0.2
170
+ `;
171
+ content += `max_turns: 15
172
+ `;
173
+ content += "---\n\n";
174
+ content += `${formatAgentVersionComment(template.name)}
175
+
176
+ `;
177
+ content += template.content;
178
+ return content;
179
+ }
180
+ function generateOpenCodeAgentContent(template) {
181
+ const model = MODEL_MAP.opencode[template.model] || "anthropic/claude-sonnet-4-20250514";
182
+ let content = "---\n";
183
+ content += `description: ${escapeYaml(template.triggerDescription)}
184
+ `;
185
+ content += `mode: subagent
186
+ `;
187
+ content += `model: ${model}
188
+ `;
189
+ content += `steps: 50
190
+ `;
191
+ content += "---\n\n";
192
+ content += `${formatAgentVersionComment(template.name)}
193
+
194
+ `;
195
+ content += template.content;
196
+ return content;
197
+ }
198
+ function ensureDirectory(dirPath) {
199
+ if (!fs.existsSync(dirPath)) {
200
+ fs.mkdirSync(dirPath, { recursive: true });
201
+ }
202
+ }
203
+ function fileExists(filePath) {
204
+ return fs.existsSync(filePath);
205
+ }
206
+ function writeFile(filePath, content) {
207
+ fs.writeFileSync(filePath, content, "utf-8");
208
+ }
209
+ function getCommandFilename(commandName, extension) {
210
+ return `${commandName}${extension}`;
211
+ }
212
+ function getAgentFilename(name, target) {
213
+ if (target === "copilot") {
214
+ return `${name}.agent.md`;
215
+ }
216
+ return `${name}.md`;
217
+ }
218
+ function getSkillDirName(name) {
219
+ return name;
220
+ }
221
+ function readFile(filePath) {
222
+ try {
223
+ if (!fs.existsSync(filePath)) {
224
+ return null;
225
+ }
226
+ const content = fs.readFileSync(filePath, "utf-8");
227
+ return content ?? null;
228
+ } catch {
229
+ return null;
230
+ }
231
+ }
232
+ function compareFiles(filePath, newContent) {
233
+ const existingContent = readFile(filePath);
234
+ if (existingContent === null) {
235
+ return { status: "new", newContent };
236
+ }
237
+ const normalizedExisting = existingContent.replace(/\r\n/g, "\n").trim();
238
+ const normalizedNew = newContent.replace(/\r\n/g, "\n").trim();
239
+ if (normalizedExisting === normalizedNew) {
240
+ return { status: "identical", existingContent, newContent };
241
+ }
242
+ return { status: "outdated", existingContent, newContent };
243
+ }
244
+ function generateDiff(oldContent, newContent, filename) {
245
+ const oldLines = oldContent.split("\n");
246
+ const newLines = newContent.split("\n");
247
+ const diff = [];
248
+ diff.push(`--- a/${filename}`);
249
+ diff.push(`+++ b/${filename}`);
250
+ const maxLines = Math.max(oldLines.length, newLines.length);
251
+ let hasChanges = false;
252
+ for (let i = 0; i < maxLines; i++) {
253
+ const oldLine = oldLines[i] ?? "";
254
+ const newLine = newLines[i] ?? "";
255
+ if (oldLine !== newLine) {
256
+ if (!hasChanges) {
257
+ hasChanges = true;
258
+ diff.push(`@@ -${i + 1} +${i + 1} @@`);
259
+ }
260
+ if (i < oldLines.length) {
261
+ diff.push(`- ${oldLine}`);
262
+ }
263
+ if (i < newLines.length) {
264
+ diff.push(`+ ${newLine}`);
265
+ }
266
+ }
267
+ }
268
+ if (!hasChanges) {
269
+ return "(no differences)";
270
+ }
271
+ return diff.join("\n");
272
+ }
273
+ function generateMcpConfig(target, options) {
274
+ const apiKey = options?.apiKey;
275
+ const pkg = getCliPackageName();
276
+ switch (target) {
277
+ case "claude":
278
+ case "copilot":
279
+ case "cursor":
280
+ return JSON.stringify({
281
+ mcpServers: {
282
+ specforge: {
283
+ command: "npx",
284
+ args: ["-y", pkg],
285
+ env: { SPECFORGE_API_KEY: apiKey ?? "${SPECFORGE_API_KEY}" }
286
+ }
287
+ }
288
+ }, null, 2) + "\n";
289
+ case "gemini":
290
+ return JSON.stringify({
291
+ mcpServers: {
292
+ specforge: {
293
+ command: "npx",
294
+ args: ["-y", pkg],
295
+ env: { SPECFORGE_API_KEY: apiKey ?? "$SPECFORGE_API_KEY" }
296
+ }
297
+ }
298
+ }, null, 2) + "\n";
299
+ case "codex":
300
+ return [
301
+ "[mcp_servers.specforge]",
302
+ 'command = "npx"',
303
+ `args = ["-y", "${pkg}"]`,
304
+ "",
305
+ "[mcp_servers.specforge.env]",
306
+ apiKey ? `SPECFORGE_API_KEY = "${apiKey.replace(/"/g, '\\"')}"` : 'SPECFORGE_API_KEY = "" # Set via environment',
307
+ ""
308
+ ].join("\n");
309
+ case "opencode":
310
+ return JSON.stringify({
311
+ mcp: {
312
+ specforge: {
313
+ type: "local",
314
+ command: "npx",
315
+ args: ["-y", pkg],
316
+ env: { SPECFORGE_API_KEY: apiKey ?? "{env:SPECFORGE_API_KEY}" }
317
+ }
318
+ }
319
+ }, null, 2) + "\n";
320
+ default:
321
+ return "";
322
+ }
323
+ }
324
+ function generateAgentsmd() {
325
+ return `# SpecForge Project Instructions
326
+
327
+ This project uses [SpecForge](https://specforge.com.br) for specification-driven development.
328
+
329
+ ## MCP Server
330
+
331
+ This project has a SpecForge MCP server configured. Use SpecForge MCP tools
332
+ for all specification, epic, ticket, and lifecycle operations.
333
+
334
+ ## Lifecycle
335
+
336
+ SpecForge follows a 3-phase lifecycle:
337
+
338
+ 1. **Planning** \u2014 Create specifications, epics, tickets, and dependency graphs
339
+ 2. **Implementation** \u2014 Work through tickets using the work session lifecycle
340
+ 3. **Review** \u2014 Run review gates, address findings, complete specification
341
+
342
+ ## Key MCP Tools
343
+
344
+ - \`get\` / \`list\` / \`search\` \u2014 Query specifications, epics, tickets
345
+ - \`start_work_session\` / \`action_work_session\` / \`complete_work_session\` \u2014 Ticket implementation lifecycle
346
+ - \`get_next_actionable_tickets\` \u2014 Find ready tickets (all dependencies satisfied)
347
+ - \`get_critical_path\` / \`get_dependency_tree\` \u2014 Analyze ticket dependencies
348
+
349
+ ## Conventions
350
+
351
+ - Follow the implementation guide provided by \`start_work_session\`
352
+ - Report progress atomically via \`action_work_session\` (steps, AC, files, tests)
353
+ - Never self-assess progress \u2014 it's computed server-side
354
+ - Complete tickets via \`complete_work_session\` \u2014 quality gates are enforced
355
+ `;
356
+ }
357
+ function generateInstructionFileContent(target) {
358
+ const config = TARGETS[target];
359
+ return `# SpecForge \u2014 ${config.name} Instructions
360
+
361
+ This project uses [SpecForge](https://specforge.com.br) for specification-driven development.
362
+
363
+ ## MCP Server
364
+
365
+ A SpecForge MCP server is configured for this project. Use SpecForge MCP tools
366
+ for all specification, epic, ticket, and lifecycle operations.
367
+
368
+ ## Quick Start
369
+
370
+ 1. Use \`get_specification\` to view the current specification
371
+ 2. Use \`get_next_actionable_tickets\` to find tickets ready for implementation
372
+ 3. Use \`start_work_session\` to begin working on a ticket
373
+ 4. Track progress with \`action_work_session\`
374
+ 5. Complete work with \`complete_work_session\`
375
+
376
+ ## Conventions
377
+
378
+ - Follow the implementation guide provided by \`start_work_session\`
379
+ - Report progress atomically via \`action_work_session\`
380
+ - Never self-assess progress \u2014 it's computed server-side
381
+ - Complete tickets via \`complete_work_session\` \u2014 quality gates are enforced
382
+ `;
383
+ }
384
+ export {
385
+ compareFiles,
386
+ detectInstalledTools,
387
+ ensureDirectory,
388
+ fileExists,
389
+ generateAgentContent,
390
+ generateAgentsmd,
391
+ generateCommandContent,
392
+ generateDiff,
393
+ generateInstructionFileContent,
394
+ generateMcpConfig,
395
+ getAgentFilename,
396
+ getCommandFilename,
397
+ getSkillDirName,
398
+ readFile,
399
+ writeFile
400
+ };
401
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/cli/commands/scaffold/utils.ts"],"sourcesContent":["/**\n * Scaffold Utility Functions\n *\n * Utility functions for file operations and content generation.\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport type { CommandTemplate, ScaffoldTarget, FileComparison, FileStatus } from './types.js';\nimport type { AgentTemplate } from './agent-types.js';\nimport { TARGETS } from './targets.js';\nimport { SCAFFOLD_VERSION } from './types.js';\nimport { CHANNEL } from '../../../channel.js';\n\n/**\n * The CLI's published package name for the active channel (M9.6c).\n *\n * Flows from `CHANNEL.packageName` — the build (`channel-defines.ts`)\n * substitutes the per-channel published name, so the `.mcp.json` scaffolded\n * into a user project always points at the binary that produced it (stable vs\n * canary). No package.json read, no hardcoded fallback.\n */\nfunction getCliPackageName(): string {\n return CHANNEL.packageName;\n}\n\n/**\n * Read the CLI's own version from its package.json. Used to stamp scaffolded\n * agent files with the version of the CLI that produced them, so users can\n * tell at a glance whether their agents are stale relative to a newer CLI.\n *\n * Falls back to SCAFFOLD_VERSION if package.json can't be read.\n */\nlet cachedCliVersion: string | null = null;\nfunction getCliVersion(): string {\n if (cachedCliVersion) return cachedCliVersion;\n try {\n const pkg = readCliPackageJson();\n const version = typeof pkg.version === 'string' ? pkg.version : '';\n if (version) {\n cachedCliVersion = version;\n return version;\n }\n } catch {\n // fall through to default\n }\n cachedCliVersion = SCAFFOLD_VERSION;\n return cachedCliVersion;\n}\n\nfunction readCliPackageJson(): { name?: unknown; version?: unknown } {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n // dist/cli/commands/scaffold/utils.js → dist/cli/commands/scaffold → dist/cli/commands → dist/cli → dist → packageRoot\n // src/cli/commands/scaffold/utils.ts follows the same shape.\n const packageRoot = path.resolve(__dirname, '..', '..', '..', '..');\n return JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf-8'));\n}\n\n/**\n * Build the version comment stamped on every scaffolded agent file:\n * <!-- {short-name} SpecForge {cli-version} -->\n *\n * `short-name` strips the `sfag-` prefix (e.g. `sfag-spec-creator` →\n * `spec-creator`) so the comment reads as the agent's role rather than its\n * convention-prefixed identifier.\n */\nfunction formatAgentVersionComment(agentName: string): string {\n const shortName = agentName.startsWith('sfag-') ? agentName.slice('sfag-'.length) : agentName;\n return `<!-- ${shortName} SpecForge ${getCliVersion()} -->`;\n}\n\n/**\n * Detect which AI CLI tools are installed by checking their detection paths\n */\nexport function detectInstalledTools(): ScaffoldTarget[] {\n const installed: ScaffoldTarget[] = [];\n\n for (const [target, config] of Object.entries(TARGETS)) {\n const detectionDir = config.detectionPath();\n if (fs.existsSync(detectionDir)) {\n installed.push(target as ScaffoldTarget);\n }\n }\n\n return installed;\n}\n\n/**\n * Generate command content for a target format\n */\nexport function generateCommandContent(\n template: CommandTemplate,\n needsFrontmatter: boolean,\n target: string\n): string {\n const config = TARGETS[target as ScaffoldTarget];\n\n // Gemini uses TOML format for commands\n if (config?.commandFormat === 'toml') {\n return generateTomlCommandContent(template, target);\n }\n\n let content = '';\n\n // Add version comment\n content += `<!-- SpecForge v${SCAFFOLD_VERSION} -->\\n`;\n\n // Add YAML frontmatter if needed (Claude Code)\n if (needsFrontmatter) {\n content += '---\\n';\n if (template.argumentHint) {\n content += `argument-hint: ${template.argumentHint}\\n`;\n }\n content += `description: ${template.description}\\n`;\n content += '---\\n\\n';\n }\n\n // Add main content\n let body = template.content;\n\n // Transform argument syntax for target\n if (config?.argSyntax && config.argSyntax !== '$ARGUMENTS') {\n body = body.replace(/\\$ARGUMENTS/g, config.argSyntax);\n }\n\n content += body;\n\n // Replace any target-specific placeholders\n content = content.replace(/\\{TARGET\\}/g, target);\n\n return content;\n}\n\n/**\n * Generate TOML command content for Gemini CLI\n */\nfunction generateTomlCommandContent(template: CommandTemplate, target: string): string {\n let body = template.content;\n\n // Transform argument syntax for Gemini\n body = body.replace(/\\$ARGUMENTS/g, '{{args}}');\n body = body.replace(/\\{TARGET\\}/g, target);\n\n // Escape triple quotes in content\n const escapedBody = body.replace(/\"\"\"/g, '\\\\\"\\\\\"\\\\\"');\n\n let content = `# SpecForge v${SCAFFOLD_VERSION}\\n`;\n content += `description = \"${escapeTomlString(template.description)}\"\\n`;\n content += `prompt = \"\"\"\\n${escapedBody}\\n\"\"\"\\n`;\n\n return content;\n}\n\n/**\n * Escape a string for TOML inline value\n */\nfunction escapeTomlString(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n\n/**\n * Escape YAML string values\n */\nfunction escapeYaml(value: string): string {\n // If value contains special characters, wrap in quotes\n if (value.includes(':') || value.includes('#') || value.includes('\\n') ||\n value.includes('\"') || value.includes(\"'\") || value.startsWith(' ') ||\n value.endsWith(' ')) {\n // Use literal block scalar for multiline content\n if (value.includes('\\n')) {\n const lines = value.split('\\n').map(line => ` ${line}`).join('\\n');\n return `|\\n${lines}`;\n }\n // Use double quotes for single line, escaping internal quotes\n return `\"${value.replace(/\"/g, '\\\\\"')}\"`;\n }\n return value;\n}\n\n/**\n * Generate agent content for a target format.\n *\n * File layout (all targets):\n * 1. YAML frontmatter (if the target supports it)\n * 2. `<!-- {short-name} SpecForge {cli-version} -->` comment\n * 3. Agent body content\n *\n * The version comment must come AFTER the frontmatter — Claude Code (and\n * stricter Markdown parsers) only recognize frontmatter when the very first\n * line of the file is `---`. A leading comment makes the file look like\n * plain Markdown with no frontmatter, breaking agent registration.\n */\nexport function generateAgentContent(\n template: AgentTemplate,\n needsFrontmatter: boolean,\n target?: ScaffoldTarget\n): string {\n const config = target ? TARGETS[target] : undefined;\n\n // For Copilot, use .agent.md frontmatter format (no color)\n if (target === 'copilot') {\n return generateCopilotAgentContent(template);\n }\n\n // For Gemini, include temperature and max_turns\n if (target === 'gemini') {\n return generateGeminiAgentContent(template);\n }\n\n // For OpenCode, use provider/model-id format\n if (target === 'opencode') {\n return generateOpenCodeAgentContent(template);\n }\n\n // Default: Claude Code format (or generic)\n let content = '';\n\n if (needsFrontmatter || (config?.agentFrontmatter ?? needsFrontmatter)) {\n content += '---\\n';\n content += `name: ${template.name}\\n`;\n content += `description: ${escapeYaml(template.triggerDescription)}\\n`;\n content += `model: ${template.model}\\n`;\n content += `color: ${template.color}\\n`;\n if (template.memory) {\n content += `memory: ${template.memory}\\n`;\n }\n content += '---\\n\\n';\n }\n\n content += `${formatAgentVersionComment(template.name)}\\n\\n`;\n content += template.content;\n return content;\n}\n\n/**\n * Model tier mapping for each target\n */\nconst MODEL_MAP: Record<string, Record<string, string>> = {\n claude: { opus: 'opus', sonnet: 'sonnet', haiku: 'haiku' },\n copilot: { opus: '', sonnet: '', haiku: '' }, // Copilot doesn't support model selection\n gemini: { opus: 'gemini-2.5-pro', sonnet: 'gemini-2.5-flash', haiku: 'gemini-2.0-flash-lite' },\n codex: { opus: '', sonnet: '', haiku: '' }, // Codex uses TOML roles\n opencode: {\n opus: 'anthropic/claude-opus-4-20250514',\n sonnet: 'anthropic/claude-sonnet-4-20250514',\n haiku: 'anthropic/claude-haiku-4-20250514',\n },\n};\n\n/**\n * Generate Copilot CLI agent content (.agent.md format)\n */\nfunction generateCopilotAgentContent(template: AgentTemplate): string {\n let content = '---\\n';\n content += `name: ${template.name}\\n`;\n content += `description: ${escapeYaml(template.triggerDescription)}\\n`;\n // No model field — Copilot doesn't support it in coding agent\n content += '---\\n\\n';\n content += `${formatAgentVersionComment(template.name)}\\n\\n`;\n content += template.content;\n return content;\n}\n\n/**\n * Generate Gemini CLI agent content\n */\nfunction generateGeminiAgentContent(template: AgentTemplate): string {\n const model = MODEL_MAP.gemini[template.model] || 'gemini-2.5-flash';\n\n let content = '---\\n';\n content += `name: ${template.name}\\n`;\n content += `description: ${escapeYaml(template.triggerDescription)}\\n`;\n content += `model: ${model}\\n`;\n content += `temperature: 0.2\\n`;\n content += `max_turns: 15\\n`;\n content += '---\\n\\n';\n content += `${formatAgentVersionComment(template.name)}\\n\\n`;\n content += template.content;\n return content;\n}\n\n/**\n * Generate OpenCode agent content\n */\nfunction generateOpenCodeAgentContent(template: AgentTemplate): string {\n const model = MODEL_MAP.opencode[template.model] || 'anthropic/claude-sonnet-4-20250514';\n\n let content = '---\\n';\n content += `description: ${escapeYaml(template.triggerDescription)}\\n`;\n content += `mode: subagent\\n`;\n content += `model: ${model}\\n`;\n content += `steps: 50\\n`;\n content += '---\\n\\n';\n content += `${formatAgentVersionComment(template.name)}\\n\\n`;\n content += template.content;\n return content;\n}\n\n/**\n * Ensure directory exists\n */\nexport function ensureDirectory(dirPath: string): void {\n if (!fs.existsSync(dirPath)) {\n fs.mkdirSync(dirPath, { recursive: true });\n }\n}\n\n/**\n * Check if file exists\n */\nexport function fileExists(filePath: string): boolean {\n return fs.existsSync(filePath);\n}\n\n/**\n * Write content to file\n */\nexport function writeFile(filePath: string, content: string): void {\n fs.writeFileSync(filePath, content, 'utf-8');\n}\n\n/**\n * Get command filename\n */\nexport function getCommandFilename(\n commandName: string,\n extension: string\n): string {\n return `${commandName}${extension}`;\n}\n\n/**\n * Get agent filename for a target\n */\nexport function getAgentFilename(name: string, target?: ScaffoldTarget): string {\n if (target === 'copilot') {\n return `${name}.agent.md`;\n }\n return `${name}.md`;\n}\n\n/**\n * Get skill directory name (agentskills.io uses SKILL.md inside named directory)\n */\nexport function getSkillDirName(name: string): string {\n return name;\n}\n\n/**\n * Read file content\n */\nexport function readFile(filePath: string): string | null {\n try {\n if (!fs.existsSync(filePath)) {\n return null;\n }\n const content = fs.readFileSync(filePath, 'utf-8');\n return content ?? null; // Handle undefined from mocks\n } catch {\n return null;\n }\n}\n\n/**\n * Compare existing and new content\n */\nexport function compareFiles(filePath: string, newContent: string): FileComparison {\n const existingContent = readFile(filePath);\n\n if (existingContent === null) {\n return { status: 'new', newContent };\n }\n\n // Normalize line endings for comparison\n const normalizedExisting = existingContent.replace(/\\r\\n/g, '\\n').trim();\n const normalizedNew = newContent.replace(/\\r\\n/g, '\\n').trim();\n\n if (normalizedExisting === normalizedNew) {\n return { status: 'identical', existingContent, newContent };\n }\n\n return { status: 'outdated', existingContent, newContent };\n}\n\n/**\n * Generate a simple unified diff between two strings\n */\nexport function generateDiff(oldContent: string, newContent: string, filename: string): string {\n const oldLines = oldContent.split('\\n');\n const newLines = newContent.split('\\n');\n\n const diff: string[] = [];\n diff.push(`--- a/${filename}`);\n diff.push(`+++ b/${filename}`);\n\n // Simple line-by-line diff (not a real unified diff, but good enough for preview)\n const maxLines = Math.max(oldLines.length, newLines.length);\n let hasChanges = false;\n\n for (let i = 0; i < maxLines; i++) {\n const oldLine = oldLines[i] ?? '';\n const newLine = newLines[i] ?? '';\n\n if (oldLine !== newLine) {\n if (!hasChanges) {\n hasChanges = true;\n diff.push(`@@ -${i + 1} +${i + 1} @@`);\n }\n if (i < oldLines.length) {\n diff.push(`- ${oldLine}`);\n }\n if (i < newLines.length) {\n diff.push(`+ ${newLine}`);\n }\n }\n }\n\n if (!hasChanges) {\n return '(no differences)';\n }\n\n return diff.join('\\n');\n}\n\n/**\n * Options for MCP config generation\n */\nexport interface GenerateMcpConfigOptions {\n /** When set, bake this API key into the env block instead of using a placeholder */\n apiKey?: string;\n}\n\n/**\n * Generate MCP config content for a specific target.\n *\n * When `options.apiKey` is provided, the key is inlined in the `env` block\n * (matches the legacy `saveMcpConfig()` behavior for Claude). Otherwise a\n * placeholder is emitted so the agent reads `SPECFORGE_API_KEY` from its env.\n */\nexport function generateMcpConfig(target: ScaffoldTarget, options?: GenerateMcpConfigOptions): string {\n const apiKey = options?.apiKey;\n const pkg = getCliPackageName();\n\n switch (target) {\n case 'claude':\n case 'copilot':\n case 'cursor':\n // Shared .mcp.json format — Claude Code, Copilot, Cursor, VS Code all read it\n return JSON.stringify({\n mcpServers: {\n specforge: {\n command: 'npx',\n args: ['-y', pkg],\n env: { SPECFORGE_API_KEY: apiKey ?? '${SPECFORGE_API_KEY}' },\n },\n },\n }, null, 2) + '\\n';\n\n case 'gemini':\n return JSON.stringify({\n mcpServers: {\n specforge: {\n command: 'npx',\n args: ['-y', pkg],\n env: { SPECFORGE_API_KEY: apiKey ?? '$SPECFORGE_API_KEY' },\n },\n },\n }, null, 2) + '\\n';\n\n case 'codex':\n return [\n '[mcp_servers.specforge]',\n 'command = \"npx\"',\n `args = [\"-y\", \"${pkg}\"]`,\n '',\n '[mcp_servers.specforge.env]',\n apiKey\n ? `SPECFORGE_API_KEY = \"${apiKey.replace(/\"/g, '\\\\\"')}\"`\n : 'SPECFORGE_API_KEY = \"\" # Set via environment',\n '',\n ].join('\\n');\n\n case 'opencode':\n return JSON.stringify({\n mcp: {\n specforge: {\n type: 'local',\n command: 'npx',\n args: ['-y', pkg],\n env: { SPECFORGE_API_KEY: apiKey ?? '{env:SPECFORGE_API_KEY}' },\n },\n },\n }, null, 2) + '\\n';\n\n default:\n return '';\n }\n}\n\n/**\n * Generate AGENTS.md content (universal instruction file)\n */\nexport function generateAgentsmd(): string {\n return `# SpecForge Project Instructions\n\nThis project uses [SpecForge](https://specforge.com.br) for specification-driven development.\n\n## MCP Server\n\nThis project has a SpecForge MCP server configured. Use SpecForge MCP tools\nfor all specification, epic, ticket, and lifecycle operations.\n\n## Lifecycle\n\nSpecForge follows a 3-phase lifecycle:\n\n1. **Planning** — Create specifications, epics, tickets, and dependency graphs\n2. **Implementation** — Work through tickets using the work session lifecycle\n3. **Review** — Run review gates, address findings, complete specification\n\n## Key MCP Tools\n\n- \\`get\\` / \\`list\\` / \\`search\\` — Query specifications, epics, tickets\n- \\`start_work_session\\` / \\`action_work_session\\` / \\`complete_work_session\\` — Ticket implementation lifecycle\n- \\`get_next_actionable_tickets\\` — Find ready tickets (all dependencies satisfied)\n- \\`get_critical_path\\` / \\`get_dependency_tree\\` — Analyze ticket dependencies\n\n## Conventions\n\n- Follow the implementation guide provided by \\`start_work_session\\`\n- Report progress atomically via \\`action_work_session\\` (steps, AC, files, tests)\n- Never self-assess progress — it's computed server-side\n- Complete tickets via \\`complete_work_session\\` — quality gates are enforced\n`;\n}\n\n/**\n * Generate per-target instruction file content\n */\nexport function generateInstructionFileContent(target: ScaffoldTarget): string {\n const config = TARGETS[target];\n return `# SpecForge — ${config.name} Instructions\n\nThis project uses [SpecForge](https://specforge.com.br) for specification-driven development.\n\n## MCP Server\n\nA SpecForge MCP server is configured for this project. Use SpecForge MCP tools\nfor all specification, epic, ticket, and lifecycle operations.\n\n## Quick Start\n\n1. Use \\`get_specification\\` to view the current specification\n2. Use \\`get_next_actionable_tickets\\` to find tickets ready for implementation\n3. Use \\`start_work_session\\` to begin working on a ticket\n4. Track progress with \\`action_work_session\\`\n5. Complete work with \\`complete_work_session\\`\n\n## Conventions\n\n- Follow the implementation guide provided by \\`start_work_session\\`\n- Report progress atomically via \\`action_work_session\\`\n- Never self-assess progress — it's computed server-side\n- Complete tickets via \\`complete_work_session\\` — quality gates are enforced\n`;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Status Command
3
+ *
4
+ * Shows what this terminal is pointed at (project / spec from
5
+ * `.specforge/config.json`) plus a live implementation report for the active
6
+ * spec and the next actionable tickets. Uses only canonical tools —
7
+ * `get_report` (type='implementation') + `get_next_actionable_tickets`.
8
+ */
9
+ import { Command } from 'commander';
10
+ import { StatusOptions } from './status.types.js';
11
+ /**
12
+ * Status command action handler
13
+ */
14
+ export declare function statusAction(options: StatusOptions): Promise<void>;
15
+ /**
16
+ * Register status command with Commander
17
+ */
18
+ export declare function registerStatusCommand(program: Command): void;
19
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,OAAO,EACL,aAAa,EAGd,MAAM,mBAAmB,CAAC;AA0D3B;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAoExE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkB5D"}