forgeos 0.1.0-alpha.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 (540) hide show
  1. package/.npmignore +1 -0
  2. package/AGENTS.md +277 -0
  3. package/CHANGELOG.md +8 -0
  4. package/CONTRIBUTING.md +58 -0
  5. package/README.md +377 -0
  6. package/bin/forge-bun.mjs +110 -0
  7. package/bin/forge.mjs +19 -0
  8. package/package.json +96 -0
  9. package/packages/eslint-plugin-forge/index.ts +15 -0
  10. package/packages/eslint-plugin-forge/package.json +10 -0
  11. package/packages/eslint-plugin-forge/src/check-source.ts +95 -0
  12. package/packages/eslint-plugin-forge/src/load-artifacts.ts +24 -0
  13. package/packages/eslint-plugin-forge/src/rule-no-forge-guard-violation.ts +93 -0
  14. package/src/forge/_generated/actionSubscriptions.json +2 -0
  15. package/src/forge/_generated/actionSubscriptions.ts +10 -0
  16. package/src/forge/_generated/agentAdapterManifest.json +2 -0
  17. package/src/forge/_generated/agentAdapterManifest.ts +73 -0
  18. package/src/forge/_generated/agentContract.json +2 -0
  19. package/src/forge/_generated/agentContract.ts +912 -0
  20. package/src/forge/_generated/agentQuickstart.md +32 -0
  21. package/src/forge/_generated/aiContext.ts +59 -0
  22. package/src/forge/_generated/aiModels.json +2 -0
  23. package/src/forge/_generated/aiModels.ts +35 -0
  24. package/src/forge/_generated/aiProviders.json +2 -0
  25. package/src/forge/_generated/aiProviders.ts +23 -0
  26. package/src/forge/_generated/aiRegistry.json +2 -0
  27. package/src/forge/_generated/aiRegistry.ts +29 -0
  28. package/src/forge/_generated/api.json +2 -0
  29. package/src/forge/_generated/api.ts +8 -0
  30. package/src/forge/_generated/appGraph.json +2 -0
  31. package/src/forge/_generated/appGraph.ts +14511 -0
  32. package/src/forge/_generated/appMap.md +35 -0
  33. package/src/forge/_generated/artifactManifest.json +2 -0
  34. package/src/forge/_generated/artifactManifest.ts +7 -0
  35. package/src/forge/_generated/authClaims.json +2 -0
  36. package/src/forge/_generated/authClaims.ts +13 -0
  37. package/src/forge/_generated/authConfig.json +2 -0
  38. package/src/forge/_generated/authConfig.ts +17 -0
  39. package/src/forge/_generated/authContext.ts +23 -0
  40. package/src/forge/_generated/authRegistry.json +2 -0
  41. package/src/forge/_generated/authRegistry.ts +25 -0
  42. package/src/forge/_generated/buildInfo.json +2 -0
  43. package/src/forge/_generated/buildInfo.ts +9 -0
  44. package/src/forge/_generated/capabilityMap.json +2 -0
  45. package/src/forge/_generated/capabilityMap.md +15 -0
  46. package/src/forge/_generated/capabilityMap.ts +17 -0
  47. package/src/forge/_generated/client.ts +282 -0
  48. package/src/forge/_generated/clientApi.ts +9 -0
  49. package/src/forge/_generated/clientManifest.json +2 -0
  50. package/src/forge/_generated/clientManifest.ts +39 -0
  51. package/src/forge/_generated/clientTypes.ts +78 -0
  52. package/src/forge/_generated/configRegistry.json +2 -0
  53. package/src/forge/_generated/configRegistry.ts +4 -0
  54. package/src/forge/_generated/dataGraph.json +2 -0
  55. package/src/forge/_generated/dataGraph.ts +8 -0
  56. package/src/forge/_generated/db.json +2 -0
  57. package/src/forge/_generated/db.ts +2 -0
  58. package/src/forge/_generated/dbSecurityManifest.json +2 -0
  59. package/src/forge/_generated/dbSecurityManifest.ts +15 -0
  60. package/src/forge/_generated/dbSessionContext.json +2 -0
  61. package/src/forge/_generated/dbSessionContext.ts +39 -0
  62. package/src/forge/_generated/deployManifest.json +2 -0
  63. package/src/forge/_generated/deployManifest.ts +14 -0
  64. package/src/forge/_generated/devManifest.json +2 -0
  65. package/src/forge/_generated/devManifest.ts +47 -0
  66. package/src/forge/_generated/envSchema.json +2 -0
  67. package/src/forge/_generated/envSchema.ts +59 -0
  68. package/src/forge/_generated/frontendGraph.json +2 -0
  69. package/src/forge/_generated/frontendGraph.ts +27 -0
  70. package/src/forge/_generated/importGuards.json +2 -0
  71. package/src/forge/_generated/importGuards.ts +652 -0
  72. package/src/forge/_generated/index.ts +67 -0
  73. package/src/forge/_generated/liveProductionManifest.json +2 -0
  74. package/src/forge/_generated/liveProductionManifest.ts +23 -0
  75. package/src/forge/_generated/liveProtocol.json +2 -0
  76. package/src/forge/_generated/liveProtocol.ts +21 -0
  77. package/src/forge/_generated/liveQueryRegistry.json +2 -0
  78. package/src/forge/_generated/liveQueryRegistry.ts +9 -0
  79. package/src/forge/_generated/liveTransportConfig.json +2 -0
  80. package/src/forge/_generated/liveTransportConfig.ts +19 -0
  81. package/src/forge/_generated/makeRegistry.json +2 -0
  82. package/src/forge/_generated/makeRegistry.ts +163 -0
  83. package/src/forge/_generated/makeTemplates.json +2 -0
  84. package/src/forge/_generated/makeTemplates.ts +61 -0
  85. package/src/forge/_generated/mockMap.json +2 -0
  86. package/src/forge/_generated/mockMap.ts +7 -0
  87. package/src/forge/_generated/operationPlaybooks.md +145 -0
  88. package/src/forge/_generated/packageGraph.json +2 -0
  89. package/src/forge/_generated/packageGraph.ts +168569 -0
  90. package/src/forge/_generated/packageUpgradeRegistry.json +2 -0
  91. package/src/forge/_generated/packageUpgradeRegistry.ts +15 -0
  92. package/src/forge/_generated/permissionMatrix.json +2 -0
  93. package/src/forge/_generated/permissionMatrix.ts +7 -0
  94. package/src/forge/_generated/policyRegistry.json +2 -0
  95. package/src/forge/_generated/policyRegistry.ts +11 -0
  96. package/src/forge/_generated/queryRegistry.json +2 -0
  97. package/src/forge/_generated/queryRegistry.ts +9 -0
  98. package/src/forge/_generated/react.d.ts +22 -0
  99. package/src/forge/_generated/react.ts +29 -0
  100. package/src/forge/_generated/reactManifest.json +2 -0
  101. package/src/forge/_generated/reactManifest.ts +19 -0
  102. package/src/forge/_generated/releaseManifest.json +2 -0
  103. package/src/forge/_generated/releaseManifest.ts +25 -0
  104. package/src/forge/_generated/rlsPolicies.json +2 -0
  105. package/src/forge/_generated/rlsPolicies.sql +34 -0
  106. package/src/forge/_generated/rlsPolicies.ts +6 -0
  107. package/src/forge/_generated/runtimeGraph.json +2 -0
  108. package/src/forge/_generated/runtimeGraph.ts +8 -0
  109. package/src/forge/_generated/runtimeMatrix.json +2 -0
  110. package/src/forge/_generated/runtimeMatrix.ts +229125 -0
  111. package/src/forge/_generated/runtimeRegistry.ts +2 -0
  112. package/src/forge/_generated/runtimeRules.md +79 -0
  113. package/src/forge/_generated/secretRegistry.json +2 -0
  114. package/src/forge/_generated/secretRegistry.ts +50 -0
  115. package/src/forge/_generated/secretsContext.ts +11 -0
  116. package/src/forge/_generated/serverApi.ts +10 -0
  117. package/src/forge/_generated/sourceMapManifest.json +2 -0
  118. package/src/forge/_generated/sourceMapManifest.ts +7 -0
  119. package/src/forge/_generated/sqlPlan.json +2 -0
  120. package/src/forge/_generated/sqlPlan.ts +88 -0
  121. package/src/forge/_generated/subscriptionManifest.json +2 -0
  122. package/src/forge/_generated/subscriptionManifest.ts +7 -0
  123. package/src/forge/_generated/symbolicationManifest.json +2 -0
  124. package/src/forge/_generated/symbolicationManifest.ts +17 -0
  125. package/src/forge/_generated/telemetryRegistry.json +2 -0
  126. package/src/forge/_generated/telemetryRegistry.ts +9 -0
  127. package/src/forge/_generated/telemetrySinks.json +2 -0
  128. package/src/forge/_generated/telemetrySinks.ts +11 -0
  129. package/src/forge/_generated/tenantScope.json +2 -0
  130. package/src/forge/_generated/tenantScope.ts +8 -0
  131. package/src/forge/_generated/testGraph.json +2 -0
  132. package/src/forge/_generated/testGraph.ts +3054 -0
  133. package/src/forge/_generated/testPlanRegistry.json +2 -0
  134. package/src/forge/_generated/testPlanRegistry.ts +33 -0
  135. package/src/forge/_generated/uiRoutes.json +2 -0
  136. package/src/forge/_generated/uiRoutes.ts +16 -0
  137. package/src/forge/_generated/uiScenarios.json +2 -0
  138. package/src/forge/_generated/uiScenarios.ts +30 -0
  139. package/src/forge/_generated/uiTestManifest.json +2 -0
  140. package/src/forge/_generated/uiTestManifest.ts +27 -0
  141. package/src/forge/_generated/workflowRegistry.json +2 -0
  142. package/src/forge/_generated/workflowRegistry.ts +9 -0
  143. package/src/forge/_generated/workflowSubscriptions.json +2 -0
  144. package/src/forge/_generated/workflowSubscriptions.ts +10 -0
  145. package/src/forge/agent-adapters/index.ts +1002 -0
  146. package/src/forge/agent-adapters/types.ts +135 -0
  147. package/src/forge/cli/agent-contract.ts +50 -0
  148. package/src/forge/cli/ai.ts +148 -0
  149. package/src/forge/cli/auth.ts +198 -0
  150. package/src/forge/cli/build.ts +105 -0
  151. package/src/forge/cli/bun-exec.ts +4 -0
  152. package/src/forge/cli/commands.ts +1130 -0
  153. package/src/forge/cli/db.ts +316 -0
  154. package/src/forge/cli/deps.ts +277 -0
  155. package/src/forge/cli/dev.ts +529 -0
  156. package/src/forge/cli/doctor.ts +209 -0
  157. package/src/forge/cli/feature.ts +485 -0
  158. package/src/forge/cli/index.ts +25 -0
  159. package/src/forge/cli/lint-forge.ts +119 -0
  160. package/src/forge/cli/live.ts +179 -0
  161. package/src/forge/cli/main.ts +92 -0
  162. package/src/forge/cli/make.ts +133 -0
  163. package/src/forge/cli/new.ts +505 -0
  164. package/src/forge/cli/outbox.ts +297 -0
  165. package/src/forge/cli/output.ts +114 -0
  166. package/src/forge/cli/parse.ts +2211 -0
  167. package/src/forge/cli/policy.ts +204 -0
  168. package/src/forge/cli/query.ts +91 -0
  169. package/src/forge/cli/refactor.ts +221 -0
  170. package/src/forge/cli/release.ts +285 -0
  171. package/src/forge/cli/rls.ts +322 -0
  172. package/src/forge/cli/run.ts +76 -0
  173. package/src/forge/cli/secrets.ts +274 -0
  174. package/src/forge/cli/self-host.ts +468 -0
  175. package/src/forge/cli/serve.ts +93 -0
  176. package/src/forge/cli/telemetry.ts +219 -0
  177. package/src/forge/cli/verify.ts +587 -0
  178. package/src/forge/cli/version.ts +1 -0
  179. package/src/forge/cli/windows.ts +413 -0
  180. package/src/forge/cli/worker.ts +87 -0
  181. package/src/forge/cli/workflow.ts +424 -0
  182. package/src/forge/compiler/action-subscriptions/build.ts +116 -0
  183. package/src/forge/compiler/action-subscriptions/constants.ts +2 -0
  184. package/src/forge/compiler/action-subscriptions/index.ts +6 -0
  185. package/src/forge/compiler/action-subscriptions/parse.ts +6 -0
  186. package/src/forge/compiler/agent-contract/build.ts +1651 -0
  187. package/src/forge/compiler/agent-contract/types.ts +326 -0
  188. package/src/forge/compiler/ai-registry/build.ts +165 -0
  189. package/src/forge/compiler/ai-registry/constants.ts +2 -0
  190. package/src/forge/compiler/ai-registry/parse.ts +56 -0
  191. package/src/forge/compiler/api-surface/build.ts +107 -0
  192. package/src/forge/compiler/app-graph/build.ts +121 -0
  193. package/src/forge/compiler/app-graph/classify.ts +10 -0
  194. package/src/forge/compiler/app-graph/dup-symbol.ts +29 -0
  195. package/src/forge/compiler/app-graph/extract.ts +124 -0
  196. package/src/forge/compiler/app-graph/forge-apis.ts +29 -0
  197. package/src/forge/compiler/app-graph/index.ts +15 -0
  198. package/src/forge/compiler/app-graph/module-graph.ts +320 -0
  199. package/src/forge/compiler/app-graph/parser.ts +119 -0
  200. package/src/forge/compiler/app-graph/symbols.ts +48 -0
  201. package/src/forge/compiler/app-graph/tsconfig-hash.ts +62 -0
  202. package/src/forge/compiler/app-graph/types.ts +43 -0
  203. package/src/forge/compiler/app-graph/versions.ts +14 -0
  204. package/src/forge/compiler/cache/index.ts +17 -0
  205. package/src/forge/compiler/cache/key.ts +46 -0
  206. package/src/forge/compiler/cache/scheduler.ts +72 -0
  207. package/src/forge/compiler/cache/store.ts +78 -0
  208. package/src/forge/compiler/classifier/capabilities.ts +78 -0
  209. package/src/forge/compiler/classifier/classify.ts +113 -0
  210. package/src/forge/compiler/classifier/contexts.ts +188 -0
  211. package/src/forge/compiler/classifier/index.ts +18 -0
  212. package/src/forge/compiler/classifier/runtime-matrix.ts +45 -0
  213. package/src/forge/compiler/classifier/secrets.ts +41 -0
  214. package/src/forge/compiler/classifier/signals.ts +129 -0
  215. package/src/forge/compiler/client-sdk/build-manifest.ts +151 -0
  216. package/src/forge/compiler/client-sdk/render-client.ts +432 -0
  217. package/src/forge/compiler/data-graph/build.ts +131 -0
  218. package/src/forge/compiler/data-graph/constants.ts +5 -0
  219. package/src/forge/compiler/data-graph/index.ts +6 -0
  220. package/src/forge/compiler/data-graph/parse.ts +176 -0
  221. package/src/forge/compiler/data-graph/rls/build.ts +222 -0
  222. package/src/forge/compiler/data-graph/rls/types.ts +62 -0
  223. package/src/forge/compiler/data-graph/sql/ddl.ts +390 -0
  224. package/src/forge/compiler/data-graph/sql/naming.ts +10 -0
  225. package/src/forge/compiler/data-graph/sql/serialize.ts +85 -0
  226. package/src/forge/compiler/data-graph/sql/types.ts +37 -0
  227. package/src/forge/compiler/dev-manifest/build.ts +170 -0
  228. package/src/forge/compiler/dev-manifest/constants.ts +5 -0
  229. package/src/forge/compiler/diagnostics/codes.ts +611 -0
  230. package/src/forge/compiler/diagnostics/create.ts +245 -0
  231. package/src/forge/compiler/diagnostics/index.ts +55 -0
  232. package/src/forge/compiler/emitter/artifact-kind.ts +14 -0
  233. package/src/forge/compiler/emitter/barrel.ts +44 -0
  234. package/src/forge/compiler/emitter/constants.ts +7 -0
  235. package/src/forge/compiler/emitter/emit.ts +237 -0
  236. package/src/forge/compiler/emitter/index.ts +24 -0
  237. package/src/forge/compiler/emitter/lock.ts +62 -0
  238. package/src/forge/compiler/emitter/render.ts +73 -0
  239. package/src/forge/compiler/emitter/write.ts +35 -0
  240. package/src/forge/compiler/frontend-graph/build.ts +495 -0
  241. package/src/forge/compiler/fs/index.ts +23 -0
  242. package/src/forge/compiler/fs/memory.ts +233 -0
  243. package/src/forge/compiler/fs/node.ts +139 -0
  244. package/src/forge/compiler/fs/profile.ts +108 -0
  245. package/src/forge/compiler/fs/types.ts +52 -0
  246. package/src/forge/compiler/guards/artifacts.ts +96 -0
  247. package/src/forge/compiler/guards/check-ai-usage.ts +98 -0
  248. package/src/forge/compiler/guards/check-import-guards.ts +106 -0
  249. package/src/forge/compiler/guards/check-process-env.ts +98 -0
  250. package/src/forge/compiler/guards/check-query-usage.ts +76 -0
  251. package/src/forge/compiler/guards/index.ts +11 -0
  252. package/src/forge/compiler/guards/propagate-contexts.ts +57 -0
  253. package/src/forge/compiler/index.ts +17 -0
  254. package/src/forge/compiler/integration/add.ts +496 -0
  255. package/src/forge/compiler/integration/index.ts +17 -0
  256. package/src/forge/compiler/integration/plan.ts +283 -0
  257. package/src/forge/compiler/integration/render.ts +189 -0
  258. package/src/forge/compiler/integration/snapshot.ts +52 -0
  259. package/src/forge/compiler/integration/templates/ai.ts +131 -0
  260. package/src/forge/compiler/integration/templates/index.ts +8 -0
  261. package/src/forge/compiler/integration/templates/posthog.ts +145 -0
  262. package/src/forge/compiler/integration/templates/render.ts +113 -0
  263. package/src/forge/compiler/integration/templates/sentry.ts +151 -0
  264. package/src/forge/compiler/integration/templates/stripe.ts +109 -0
  265. package/src/forge/compiler/integration/templates/types.ts +14 -0
  266. package/src/forge/compiler/integration/templates/zod.ts +55 -0
  267. package/src/forge/compiler/live-production/types.ts +122 -0
  268. package/src/forge/compiler/live-query-registry/build.ts +150 -0
  269. package/src/forge/compiler/live-query-registry/constants.ts +2 -0
  270. package/src/forge/compiler/make-registry/build.ts +179 -0
  271. package/src/forge/compiler/orchestrator/discover.ts +214 -0
  272. package/src/forge/compiler/orchestrator/fast-check.ts +117 -0
  273. package/src/forge/compiler/orchestrator/generate-lock.ts +138 -0
  274. package/src/forge/compiler/orchestrator/guards.ts +5 -0
  275. package/src/forge/compiler/orchestrator/index.ts +27 -0
  276. package/src/forge/compiler/orchestrator/manifest-hashes.ts +21 -0
  277. package/src/forge/compiler/orchestrator/manifest.ts +92 -0
  278. package/src/forge/compiler/orchestrator/orphans.ts +51 -0
  279. package/src/forge/compiler/orchestrator/plan.ts +876 -0
  280. package/src/forge/compiler/orchestrator/profile.ts +36 -0
  281. package/src/forge/compiler/orchestrator/run.ts +277 -0
  282. package/src/forge/compiler/orchestrator/serialize.ts +886 -0
  283. package/src/forge/compiler/orchestrator/session.ts +96 -0
  284. package/src/forge/compiler/orchestrator/types.ts +31 -0
  285. package/src/forge/compiler/orchestrator/verify.ts +38 -0
  286. package/src/forge/compiler/orchestrator/workspace-index.ts +154 -0
  287. package/src/forge/compiler/package-graph/capabilities-stub.ts +33 -0
  288. package/src/forge/compiler/package-graph/checksum.ts +97 -0
  289. package/src/forge/compiler/package-graph/compiler.ts +392 -0
  290. package/src/forge/compiler/package-graph/constants.ts +4 -0
  291. package/src/forge/compiler/package-graph/dts-extractor.ts +142 -0
  292. package/src/forge/compiler/package-graph/exports-discovery.ts +84 -0
  293. package/src/forge/compiler/package-graph/extract-dts.ts +32 -0
  294. package/src/forge/compiler/package-graph/index.ts +33 -0
  295. package/src/forge/compiler/package-graph/jsdoc.ts +62 -0
  296. package/src/forge/compiler/package-graph/read-file.ts +21 -0
  297. package/src/forge/compiler/package-graph/resolve.ts +127 -0
  298. package/src/forge/compiler/package-manager/adapter.ts +237 -0
  299. package/src/forge/compiler/package-manager/bun-executable.ts +92 -0
  300. package/src/forge/compiler/package-manager/commands.ts +47 -0
  301. package/src/forge/compiler/package-manager/detect.ts +79 -0
  302. package/src/forge/compiler/package-manager/executor.ts +117 -0
  303. package/src/forge/compiler/package-manager/index.ts +22 -0
  304. package/src/forge/compiler/package-manager/parse-spec.ts +16 -0
  305. package/src/forge/compiler/package-manager/version.ts +27 -0
  306. package/src/forge/compiler/package-upgrades/apply.ts +195 -0
  307. package/src/forge/compiler/package-upgrades/comparator.ts +181 -0
  308. package/src/forge/compiler/package-upgrades/impact.ts +139 -0
  309. package/src/forge/compiler/package-upgrades/markdown.ts +97 -0
  310. package/src/forge/compiler/package-upgrades/planner.ts +532 -0
  311. package/src/forge/compiler/package-upgrades/risk.ts +208 -0
  312. package/src/forge/compiler/package-upgrades/types.ts +174 -0
  313. package/src/forge/compiler/policy-registry/build.ts +266 -0
  314. package/src/forge/compiler/policy-registry/constants.ts +2 -0
  315. package/src/forge/compiler/policy-registry/parse.ts +81 -0
  316. package/src/forge/compiler/primitives/compare.ts +26 -0
  317. package/src/forge/compiler/primitives/hash.ts +40 -0
  318. package/src/forge/compiler/primitives/header.ts +45 -0
  319. package/src/forge/compiler/primitives/index.ts +45 -0
  320. package/src/forge/compiler/primitives/paths.ts +24 -0
  321. package/src/forge/compiler/primitives/result.ts +164 -0
  322. package/src/forge/compiler/primitives/serialize.ts +66 -0
  323. package/src/forge/compiler/primitives/sort.ts +87 -0
  324. package/src/forge/compiler/query-registry/build.ts +114 -0
  325. package/src/forge/compiler/query-registry/constants.ts +2 -0
  326. package/src/forge/compiler/recipes/definitions.ts +289 -0
  327. package/src/forge/compiler/recipes/helpers.ts +37 -0
  328. package/src/forge/compiler/recipes/index.ts +21 -0
  329. package/src/forge/compiler/recipes/registry.ts +102 -0
  330. package/src/forge/compiler/release/build.ts +100 -0
  331. package/src/forge/compiler/release/types.ts +119 -0
  332. package/src/forge/compiler/runtime-graph/build.ts +137 -0
  333. package/src/forge/compiler/runtime-graph/constants.ts +5 -0
  334. package/src/forge/compiler/runtime-graph/index.ts +5 -0
  335. package/src/forge/compiler/sandbox/artifact-sanitize.ts +26 -0
  336. package/src/forge/compiler/sandbox/backends/child.ts +123 -0
  337. package/src/forge/compiler/sandbox/backends/docker.ts +173 -0
  338. package/src/forge/compiler/sandbox/index.ts +51 -0
  339. package/src/forge/compiler/sandbox/inspect.ts +143 -0
  340. package/src/forge/compiler/sandbox/inspector-entry.ts +115 -0
  341. package/src/forge/compiler/sandbox/limits.ts +31 -0
  342. package/src/forge/compiler/sandbox/scrub-env.ts +60 -0
  343. package/src/forge/compiler/sandbox/secret-scan.ts +54 -0
  344. package/src/forge/compiler/sandbox/serialize.ts +106 -0
  345. package/src/forge/compiler/sandbox/types.ts +7 -0
  346. package/src/forge/compiler/secret-registry/build.ts +123 -0
  347. package/src/forge/compiler/telemetry-registry/build.ts +89 -0
  348. package/src/forge/compiler/telemetry-registry/constants.ts +2 -0
  349. package/src/forge/compiler/telemetry-registry/parse.ts +13 -0
  350. package/src/forge/compiler/test-graph/build.ts +277 -0
  351. package/src/forge/compiler/types/action-subscriptions.ts +19 -0
  352. package/src/forge/compiler/types/ai-registry.ts +33 -0
  353. package/src/forge/compiler/types/app-graph.ts +80 -0
  354. package/src/forge/compiler/types/capability.ts +29 -0
  355. package/src/forge/compiler/types/classification.ts +9 -0
  356. package/src/forge/compiler/types/cli.ts +159 -0
  357. package/src/forge/compiler/types/data-graph.ts +24 -0
  358. package/src/forge/compiler/types/dev-manifest.ts +41 -0
  359. package/src/forge/compiler/types/diagnostic.ts +12 -0
  360. package/src/forge/compiler/types/emit.ts +25 -0
  361. package/src/forge/compiler/types/frontend-graph.ts +81 -0
  362. package/src/forge/compiler/types/import-guards.ts +19 -0
  363. package/src/forge/compiler/types/index.ts +98 -0
  364. package/src/forge/compiler/types/integration.ts +25 -0
  365. package/src/forge/compiler/types/json.ts +3 -0
  366. package/src/forge/compiler/types/live-query-registry.ts +32 -0
  367. package/src/forge/compiler/types/lock.ts +37 -0
  368. package/src/forge/compiler/types/package-graph.ts +84 -0
  369. package/src/forge/compiler/types/policy-registry.ts +69 -0
  370. package/src/forge/compiler/types/query-registry.ts +18 -0
  371. package/src/forge/compiler/types/runtime-graph.ts +30 -0
  372. package/src/forge/compiler/types/runtime-matrix.ts +16 -0
  373. package/src/forge/compiler/types/runtime.ts +30 -0
  374. package/src/forge/compiler/types/sandbox.ts +24 -0
  375. package/src/forge/compiler/types/secret-registry.ts +38 -0
  376. package/src/forge/compiler/types/telemetry-registry.ts +26 -0
  377. package/src/forge/compiler/types/test-graph.ts +45 -0
  378. package/src/forge/compiler/types/workflow-registry.ts +42 -0
  379. package/src/forge/compiler/workflow-registry/build.ts +180 -0
  380. package/src/forge/compiler/workflow-registry/constants.ts +2 -0
  381. package/src/forge/compiler/workflow-registry/index.ts +5 -0
  382. package/src/forge/compiler/workflow-registry/parse.ts +19 -0
  383. package/src/forge/dev/server.ts +1379 -0
  384. package/src/forge/dev/types.ts +49 -0
  385. package/src/forge/dev/watch.ts +109 -0
  386. package/src/forge/dev-console/cycle.ts +652 -0
  387. package/src/forge/dev-console/types.ts +99 -0
  388. package/src/forge/feature/compiler.ts +656 -0
  389. package/src/forge/feature/examples.ts +125 -0
  390. package/src/forge/feature/types.ts +177 -0
  391. package/src/forge/impact/index.ts +1160 -0
  392. package/src/forge/impact/types.ts +151 -0
  393. package/src/forge/intent/index.ts +490 -0
  394. package/src/forge/intent/types.ts +73 -0
  395. package/src/forge/make/fields.ts +146 -0
  396. package/src/forge/make/index.ts +1101 -0
  397. package/src/forge/make/naming.ts +42 -0
  398. package/src/forge/make/templates.ts +525 -0
  399. package/src/forge/make/types.ts +151 -0
  400. package/src/forge/platform/module.ts +20 -0
  401. package/src/forge/policy.ts +1 -0
  402. package/src/forge/react/index.ts +418 -0
  403. package/src/forge/refactor/index.ts +1936 -0
  404. package/src/forge/refactor/text-utils.ts +34 -0
  405. package/src/forge/refactor/types.ts +191 -0
  406. package/src/forge/refactor/workspace-fs.ts +171 -0
  407. package/src/forge/repair/index.ts +656 -0
  408. package/src/forge/repair/rules/index.ts +476 -0
  409. package/src/forge/repair/types.ts +175 -0
  410. package/src/forge/review/index.ts +992 -0
  411. package/src/forge/review/types.ts +196 -0
  412. package/src/forge/runtime/ai/check.ts +86 -0
  413. package/src/forge/runtime/ai/context.ts +394 -0
  414. package/src/forge/runtime/ai/cost-estimator.ts +41 -0
  415. package/src/forge/runtime/ai/mock.ts +49 -0
  416. package/src/forge/runtime/ai/providers.ts +78 -0
  417. package/src/forge/runtime/ai/state.ts +17 -0
  418. package/src/forge/runtime/ai/types.ts +67 -0
  419. package/src/forge/runtime/auth/authenticate.ts +58 -0
  420. package/src/forge/runtime/auth/claims.ts +119 -0
  421. package/src/forge/runtime/auth/config.ts +148 -0
  422. package/src/forge/runtime/auth/errors.ts +45 -0
  423. package/src/forge/runtime/auth/evaluate.ts +126 -0
  424. package/src/forge/runtime/auth/resolve.ts +74 -0
  425. package/src/forge/runtime/auth/types.ts +87 -0
  426. package/src/forge/runtime/auth/verifier.ts +138 -0
  427. package/src/forge/runtime/context/create-context.ts +204 -0
  428. package/src/forge/runtime/context/create-query-context.ts +34 -0
  429. package/src/forge/runtime/db/adapter.ts +31 -0
  430. package/src/forge/runtime/db/factory.ts +83 -0
  431. package/src/forge/runtime/db/generated-client.ts +294 -0
  432. package/src/forge/runtime/db/memory-adapter.ts +706 -0
  433. package/src/forge/runtime/db/migrate.ts +132 -0
  434. package/src/forge/runtime/db/outbox.ts +54 -0
  435. package/src/forge/runtime/db/pglite-adapter.ts +51 -0
  436. package/src/forge/runtime/db/postgres-adapter.ts +112 -0
  437. package/src/forge/runtime/db/read-only-client.ts +97 -0
  438. package/src/forge/runtime/db/session-context.ts +62 -0
  439. package/src/forge/runtime/executor.ts +446 -0
  440. package/src/forge/runtime/live/dependency-tracker.ts +57 -0
  441. package/src/forge/runtime/live/invalidation-log.ts +189 -0
  442. package/src/forge/runtime/live/live-query-runner.ts +267 -0
  443. package/src/forge/runtime/live/registry.ts +28 -0
  444. package/src/forge/runtime/live/sse.ts +75 -0
  445. package/src/forge/runtime/live/subscription-manager.ts +443 -0
  446. package/src/forge/runtime/live/types.ts +143 -0
  447. package/src/forge/runtime/outbox/claim.ts +153 -0
  448. package/src/forge/runtime/outbox/process.ts +298 -0
  449. package/src/forge/runtime/outbox/retry.ts +8 -0
  450. package/src/forge/runtime/outbox/subscriptions.ts +33 -0
  451. package/src/forge/runtime/outbox/types.ts +69 -0
  452. package/src/forge/runtime/policy/check.ts +157 -0
  453. package/src/forge/runtime/policy/load.ts +55 -0
  454. package/src/forge/runtime/query/registry.ts +19 -0
  455. package/src/forge/runtime/query/run-query.ts +347 -0
  456. package/src/forge/runtime/release/runtime.ts +322 -0
  457. package/src/forge/runtime/release/symbolicate.ts +175 -0
  458. package/src/forge/runtime/runner/command-transaction.ts +193 -0
  459. package/src/forge/runtime/runner/run-entry.ts +226 -0
  460. package/src/forge/runtime/secrets/check.ts +78 -0
  461. package/src/forge/runtime/secrets/create-context.ts +138 -0
  462. package/src/forge/runtime/secrets/env-loader.ts +94 -0
  463. package/src/forge/runtime/secrets/runtime-bundle.ts +47 -0
  464. package/src/forge/runtime/secrets/types.ts +31 -0
  465. package/src/forge/runtime/telemetry/buffer.ts +87 -0
  466. package/src/forge/runtime/telemetry/context.ts +192 -0
  467. package/src/forge/runtime/telemetry/correlation.ts +13 -0
  468. package/src/forge/runtime/telemetry/flush.ts +190 -0
  469. package/src/forge/runtime/telemetry/process.ts +20 -0
  470. package/src/forge/runtime/telemetry/scrubber.ts +115 -0
  471. package/src/forge/runtime/telemetry/sinks/local-jsonl.ts +39 -0
  472. package/src/forge/runtime/telemetry/sinks/posthog.ts +64 -0
  473. package/src/forge/runtime/telemetry/sinks/sentry.ts +60 -0
  474. package/src/forge/runtime/telemetry/spans.ts +58 -0
  475. package/src/forge/runtime/telemetry/types.ts +64 -0
  476. package/src/forge/runtime/workflows/cancel.ts +26 -0
  477. package/src/forge/runtime/workflows/create-run.ts +98 -0
  478. package/src/forge/runtime/workflows/process-run.ts +182 -0
  479. package/src/forge/runtime/workflows/process-step.ts +190 -0
  480. package/src/forge/runtime/workflows/process.ts +260 -0
  481. package/src/forge/runtime/workflows/registry.ts +51 -0
  482. package/src/forge/runtime/workflows/resolve-step.ts +46 -0
  483. package/src/forge/runtime/workflows/retry-run.ts +44 -0
  484. package/src/forge/runtime/workflows/retry.ts +8 -0
  485. package/src/forge/runtime/workflows/sanitize.ts +19 -0
  486. package/src/forge/runtime/workflows/start-from-outbox.ts +71 -0
  487. package/src/forge/runtime/workflows/types.ts +77 -0
  488. package/src/forge/server.ts +96 -0
  489. package/src/forge/ui/index.ts +770 -0
  490. package/src/forge/ui/types.ts +191 -0
  491. package/templates/b2b-support-web/.env.example +22 -0
  492. package/templates/b2b-support-web/.vscode/settings.json +14 -0
  493. package/templates/b2b-support-web/AGENTS.md +108 -0
  494. package/templates/b2b-support-web/README.md +48 -0
  495. package/templates/b2b-support-web/forge.config.ts +3 -0
  496. package/templates/b2b-support-web/package.json +34 -0
  497. package/templates/b2b-support-web/src/actions/captureTicketCreated.ts +14 -0
  498. package/templates/b2b-support-web/src/commands/closeTicket.ts +20 -0
  499. package/templates/b2b-support-web/src/commands/createTicket.ts +47 -0
  500. package/templates/b2b-support-web/src/commands/manageBilling.ts +9 -0
  501. package/templates/b2b-support-web/src/forge/schema.ts +35 -0
  502. package/templates/b2b-support-web/src/policies.ts +9 -0
  503. package/templates/b2b-support-web/src/queries/getTicket.ts +6 -0
  504. package/templates/b2b-support-web/src/queries/listTickets.ts +6 -0
  505. package/templates/b2b-support-web/src/queries/liveTickets.ts +9 -0
  506. package/templates/b2b-support-web/src/workflows/triageTicketWorkflow.ts +64 -0
  507. package/templates/b2b-support-web/tsconfig.json +14 -0
  508. package/templates/b2b-support-web/web/app/globals.css +77 -0
  509. package/templates/b2b-support-web/web/app/layout.tsx +13 -0
  510. package/templates/b2b-support-web/web/app/page.tsx +13 -0
  511. package/templates/b2b-support-web/web/app/providers.tsx +21 -0
  512. package/templates/b2b-support-web/web/app/tickets/page.tsx +21 -0
  513. package/templates/b2b-support-web/web/components/CreateTicketForm.tsx +43 -0
  514. package/templates/b2b-support-web/web/components/PolicyDeniedDemo.tsx +31 -0
  515. package/templates/b2b-support-web/web/components/TicketList.tsx +52 -0
  516. package/templates/b2b-support-web/web/components/TraceDetails.tsx +18 -0
  517. package/templates/b2b-support-web/web/components/TriageStatus.tsx +13 -0
  518. package/templates/b2b-support-web/web/lib/forge.ts +13 -0
  519. package/templates/b2b-support-web/web/next-env.d.ts +5 -0
  520. package/templates/b2b-support-web/web/next.config.ts +8 -0
  521. package/templates/b2b-support-web/web/package.json +21 -0
  522. package/templates/b2b-support-web/web/tsconfig.json +30 -0
  523. package/templates/minimal-web/.vscode/settings.json +14 -0
  524. package/templates/minimal-web/README.md +21 -0
  525. package/templates/minimal-web/forge.config.ts +3 -0
  526. package/templates/minimal-web/package.json +32 -0
  527. package/templates/minimal-web/src/actions/logNoteCreated.ts +11 -0
  528. package/templates/minimal-web/src/commands/createNote.ts +26 -0
  529. package/templates/minimal-web/src/forge/schema.ts +12 -0
  530. package/templates/minimal-web/src/policies.ts +6 -0
  531. package/templates/minimal-web/src/queries/listNotes.ts +8 -0
  532. package/templates/minimal-web/src/queries/liveNotes.ts +8 -0
  533. package/templates/minimal-web/tsconfig.json +15 -0
  534. package/templates/minimal-web/web/index.html +12 -0
  535. package/templates/minimal-web/web/package.json +21 -0
  536. package/templates/minimal-web/web/src/App.tsx +89 -0
  537. package/templates/minimal-web/web/src/lib/forge.ts +13 -0
  538. package/templates/minimal-web/web/src/main.tsx +13 -0
  539. package/templates/minimal-web/web/src/styles.css +156 -0
  540. package/templates/minimal-web/web/tsconfig.json +18 -0
@@ -0,0 +1,2211 @@
1
+ import type { AddOptions, InspectTarget, VerifyOptions } from "../compiler/types/cli.ts";
2
+ import type { SandboxBackend } from "../compiler/types/runtime.ts";
3
+ import type { DbAdapterKind } from "../runtime/db/adapter.ts";
4
+ import type { DbSubcommand } from "./db.ts";
5
+ import type { OutboxSubcommand } from "./outbox.ts";
6
+ import type { WorkflowSubcommand } from "./workflow.ts";
7
+ import type { TelemetrySubcommand } from "./telemetry.ts";
8
+ import type { PolicySubcommand } from "./policy.ts";
9
+ import type { SecretsSubcommand } from "./secrets.ts";
10
+ import type { EnvSubcommand } from "./secrets.ts";
11
+ import type { AiSubcommand } from "./ai.ts";
12
+ import type { QuerySubcommand } from "./query.ts";
13
+ import type { LiveSubcommand } from "./live.ts";
14
+ import type { ForgeAiProvider } from "../runtime/ai/types.ts";
15
+ import type { NewPackageManager, NewTemplateName } from "./new.ts";
16
+ import type { SelfHostSubcommand } from "./self-host.ts";
17
+ import type { AgentContractSubcommand } from "./agent-contract.ts";
18
+ import type { AuthSubcommand } from "./auth.ts";
19
+ import type { RlsSubcommand } from "./rls.ts";
20
+ import type { DepsSubcommand } from "./deps.ts";
21
+ import type { ReleaseAction, ReleaseArea } from "./release.ts";
22
+ import type { MakeCommandOptions, MakePrimitive } from "../make/types.ts";
23
+ import type { FeatureAction, FeatureCommandOptions } from "../feature/types.ts";
24
+ import type { RefactorAction, RefactorCommandOptions, RenameTarget } from "../refactor/types.ts";
25
+ import type { ImpactCommandOptions, TestCommandOptions, TestSubcommand } from "../impact/types.ts";
26
+ import type { TestCost } from "../compiler/types/test-graph.ts";
27
+ import type { RepairCommandOptions, RepairSubcommand } from "../repair/types.ts";
28
+ import type {
29
+ AgentAdapterTarget,
30
+ AgentCommandOptions,
31
+ AgentSubcommand,
32
+ } from "../agent-adapters/types.ts";
33
+ import type {
34
+ ReviewCommandOptions,
35
+ ReviewFailOn,
36
+ ReviewFindingCategory,
37
+ ReviewMode,
38
+ ReviewSubcommand,
39
+ } from "../review/types.ts";
40
+ import type {
41
+ UiBrowserName,
42
+ UiCommandOptions,
43
+ UiScreenshotMode,
44
+ UiSubcommand,
45
+ UiTraceMode,
46
+ UiVideoMode,
47
+ } from "../ui/types.ts";
48
+ import type { ForgeDoOptions } from "../intent/types.ts";
49
+
50
+ export type ForgeCommand =
51
+ | {
52
+ kind: "new";
53
+ name: string;
54
+ template: NewTemplateName;
55
+ packageManager: NewPackageManager;
56
+ install: boolean;
57
+ git: boolean;
58
+ forgePackageSpec?: string;
59
+ localForge: boolean;
60
+ workspaceRoot: string;
61
+ }
62
+ | { kind: "build"; json: boolean; workspaceRoot: string }
63
+ | {
64
+ kind: "serve";
65
+ host?: string;
66
+ port?: number;
67
+ databaseUrl?: string;
68
+ json: boolean;
69
+ envFile?: string;
70
+ allowDevAuth: boolean;
71
+ workspaceRoot: string;
72
+ }
73
+ | {
74
+ kind: "worker";
75
+ db: DbAdapterKind;
76
+ databaseUrl?: string;
77
+ json: boolean;
78
+ once: boolean;
79
+ pollIntervalMs: number;
80
+ limit: number;
81
+ mock: boolean;
82
+ workspaceRoot: string;
83
+ }
84
+ | {
85
+ kind: "self-host";
86
+ subcommand: SelfHostSubcommand;
87
+ json: boolean;
88
+ withWeb: boolean;
89
+ postgresVersion: string;
90
+ runtimePort: number;
91
+ webPort: number;
92
+ workspaceRoot: string;
93
+ }
94
+ | {
95
+ kind: "agent-contract";
96
+ subcommand: AgentContractSubcommand;
97
+ json: boolean;
98
+ workspaceRoot: string;
99
+ }
100
+ | { kind: "doctor"; target?: "project" | "windows"; json: boolean; workspaceRoot: string }
101
+ | { kind: "setup"; target: "windows"; json: boolean; yes: boolean; workspaceRoot: string }
102
+ | {
103
+ kind: "auth";
104
+ subcommand: AuthSubcommand;
105
+ json: boolean;
106
+ token?: string;
107
+ workspaceRoot: string;
108
+ }
109
+ | {
110
+ kind: "rls";
111
+ subcommand: RlsSubcommand;
112
+ db: DbAdapterKind;
113
+ databaseUrl?: string;
114
+ json: boolean;
115
+ workspaceRoot: string;
116
+ }
117
+ | {
118
+ kind: "deps";
119
+ subcommand: DepsSubcommand;
120
+ packageName?: string;
121
+ planPath?: string;
122
+ target?: string;
123
+ json: boolean;
124
+ yes: boolean;
125
+ allowScripts: boolean;
126
+ skipTests: boolean;
127
+ dryRun: boolean;
128
+ changed: boolean;
129
+ workspaceRoot: string;
130
+ }
131
+ | {
132
+ kind: "release";
133
+ area: ReleaseArea;
134
+ action: ReleaseAction;
135
+ releaseId?: string;
136
+ input?: string;
137
+ provider?: string;
138
+ target?: string;
139
+ env: string;
140
+ json: boolean;
141
+ allowDirty: boolean;
142
+ allowPublicSourcemaps: boolean;
143
+ workspaceRoot: string;
144
+ }
145
+ | { kind: "make"; options: MakeCommandOptions }
146
+ | { kind: "feature"; options: FeatureCommandOptions }
147
+ | { kind: "refactor"; options: RefactorCommandOptions }
148
+ | { kind: "impact"; options: ImpactCommandOptions }
149
+ | { kind: "test"; options: TestCommandOptions }
150
+ | { kind: "repair"; options: RepairCommandOptions }
151
+ | { kind: "do"; options: ForgeDoOptions }
152
+ | { kind: "agent"; options: AgentCommandOptions }
153
+ | { kind: "review"; options: ReviewCommandOptions }
154
+ | { kind: "ui"; options: UiCommandOptions }
155
+ | { kind: "generate"; check: boolean; dryRun: boolean; json: boolean; concurrency: number }
156
+ | { kind: "add"; alias: string; options: AddOptions & { workspaceRoot: string } }
157
+ | { kind: "inspect"; target: InspectTarget; json: boolean; dryRun: boolean }
158
+ | { kind: "check"; json: boolean; dryRun: boolean; strictSecrets: boolean }
159
+ | { kind: "verify"; options: VerifyOptions }
160
+ | { kind: "run"; name?: string; list: boolean; json: boolean; mock: boolean; userId?: string; tenantId?: string; role?: string; envFile?: string; workspaceRoot: string; queryMode?: boolean; args?: unknown }
161
+ | {
162
+ kind: "dev";
163
+ host?: string;
164
+ port?: number;
165
+ mock: boolean;
166
+ mockAi: boolean;
167
+ once: boolean;
168
+ watch: boolean;
169
+ json: boolean;
170
+ db: "pglite" | "postgres" | "none";
171
+ databaseUrl?: string;
172
+ worker: boolean;
173
+ withWeb: boolean;
174
+ apiOnly: boolean;
175
+ webOnly: boolean;
176
+ open: boolean;
177
+ webPort?: number;
178
+ telemetry: string[];
179
+ envFile?: string;
180
+ workspaceRoot: string;
181
+ }
182
+ | {
183
+ kind: "db";
184
+ subcommand: DbSubcommand;
185
+ db: DbAdapterKind;
186
+ databaseUrl?: string;
187
+ json: boolean;
188
+ workspaceRoot: string;
189
+ }
190
+ | {
191
+ kind: "outbox";
192
+ subcommand: OutboxSubcommand;
193
+ db: DbAdapterKind;
194
+ databaseUrl?: string;
195
+ json: boolean;
196
+ once: boolean;
197
+ watch: boolean;
198
+ limit?: number;
199
+ deliveryId?: number;
200
+ mock: boolean;
201
+ workspaceRoot: string;
202
+ }
203
+ | {
204
+ kind: "workflow";
205
+ subcommand: WorkflowSubcommand;
206
+ db: DbAdapterKind;
207
+ databaseUrl?: string;
208
+ json: boolean;
209
+ once: boolean;
210
+ watch: boolean;
211
+ limit?: number;
212
+ workflowName?: string;
213
+ runId?: number;
214
+ stepName?: string;
215
+ input?: unknown;
216
+ mock: boolean;
217
+ workspaceRoot: string;
218
+ }
219
+ | {
220
+ kind: "telemetry";
221
+ subcommand: TelemetrySubcommand;
222
+ db: DbAdapterKind;
223
+ databaseUrl?: string;
224
+ json: boolean;
225
+ traceId?: string;
226
+ sink?: string;
227
+ file?: "events" | "exceptions" | "spans";
228
+ workspaceRoot: string;
229
+ }
230
+ | {
231
+ kind: "policy";
232
+ subcommand: PolicySubcommand;
233
+ json: boolean;
234
+ policy?: string;
235
+ role?: string;
236
+ strictPolicies: boolean;
237
+ workspaceRoot: string;
238
+ }
239
+ | {
240
+ kind: "secrets";
241
+ subcommand: SecretsSubcommand;
242
+ json: boolean;
243
+ redacted: boolean;
244
+ name?: string;
245
+ value?: string;
246
+ workspaceRoot: string;
247
+ }
248
+ | {
249
+ kind: "env";
250
+ subcommand: EnvSubcommand;
251
+ json: boolean;
252
+ redacted: boolean;
253
+ workspaceRoot: string;
254
+ }
255
+ | {
256
+ kind: "query";
257
+ subcommand: QuerySubcommand;
258
+ name?: string;
259
+ args?: unknown;
260
+ json: boolean;
261
+ userId?: string;
262
+ tenantId?: string;
263
+ role?: string;
264
+ workspaceRoot: string;
265
+ }
266
+ | {
267
+ kind: "live";
268
+ subcommand: LiveSubcommand;
269
+ name?: string;
270
+ args?: unknown;
271
+ json: boolean;
272
+ userId?: string;
273
+ tenantId?: string;
274
+ role?: string;
275
+ url?: string;
276
+ workspaceRoot: string;
277
+ }
278
+ | {
279
+ kind: "ai";
280
+ subcommand: AiSubcommand;
281
+ json: boolean;
282
+ provider?: ForgeAiProvider;
283
+ model?: string;
284
+ prompt?: string;
285
+ mock: boolean;
286
+ workspaceRoot: string;
287
+ };
288
+
289
+ export interface ParsedCli {
290
+ command: ForgeCommand | null;
291
+ workspaceRoot: string;
292
+ errors: string[];
293
+ }
294
+
295
+ export const TOP_LEVEL_COMMANDS = [
296
+ "new",
297
+ "build",
298
+ "serve",
299
+ "worker",
300
+ "self-host",
301
+ "agent-contract",
302
+ "agent",
303
+ "review",
304
+ "ui",
305
+ "doctor",
306
+ "setup",
307
+ "auth",
308
+ "rls",
309
+ "deps",
310
+ "release",
311
+ "make",
312
+ "feature",
313
+ "refactor",
314
+ "impact",
315
+ "test",
316
+ "repair",
317
+ "do",
318
+ "generate",
319
+ "add",
320
+ "inspect",
321
+ "check",
322
+ "verify",
323
+ "run",
324
+ "query",
325
+ "live",
326
+ "dev",
327
+ "db",
328
+ "workflow",
329
+ "outbox",
330
+ "telemetry",
331
+ "policy",
332
+ "secrets",
333
+ "env",
334
+ "ai",
335
+ ] as const;
336
+
337
+ export const INSPECT_TARGETS: InspectTarget[] = [
338
+ "app",
339
+ "packages",
340
+ "capabilities",
341
+ "runtime-matrix",
342
+ "data",
343
+ "runtime",
344
+ "dev",
345
+ "subscriptions",
346
+ "workflows",
347
+ "telemetry",
348
+ "policies",
349
+ "secrets",
350
+ "env",
351
+ "ai",
352
+ "queries",
353
+ "api",
354
+ "client",
355
+ "frontend",
356
+ "auth",
357
+ "rls",
358
+ "db-security",
359
+ "release",
360
+ "artifacts",
361
+ "sourcemaps",
362
+ "live-production",
363
+ "live-protocol",
364
+ "live-transport",
365
+ "make",
366
+ "test-graph",
367
+ "test-plans",
368
+ "agent-contract",
369
+ "agent-adapters",
370
+ "capability-map",
371
+ "framework",
372
+ "ui",
373
+ "ui-scenarios",
374
+ "ui-routes",
375
+ "all",
376
+ "rules",
377
+ "map",
378
+ ];
379
+
380
+ const NEW_TEMPLATES: NewTemplateName[] = ["b2b-support-web", "minimal-web"];
381
+ const NEW_PACKAGE_MANAGERS: NewPackageManager[] = ["bun", "npm", "pnpm", "yarn"];
382
+ const SELF_HOST_SUBCOMMANDS: SelfHostSubcommand[] = ["compose", "env", "check", "clean"];
383
+ const AGENT_CONTRACT_SUBCOMMANDS: AgentContractSubcommand[] = [
384
+ "generate",
385
+ "check",
386
+ "print",
387
+ ];
388
+ const AUTH_SUBCOMMANDS: AuthSubcommand[] = [
389
+ "check",
390
+ "config",
391
+ "decode",
392
+ "test-token",
393
+ "jwks",
394
+ ];
395
+ const RLS_SUBCOMMANDS: RlsSubcommand[] = ["generate", "check", "apply", "test"];
396
+ const DEPS_SUBCOMMANDS: DepsSubcommand[] = [
397
+ "outdated",
398
+ "inspect",
399
+ "diff",
400
+ "upgrade-plan",
401
+ "upgrade-apply",
402
+ "upgrade-check",
403
+ "upgrade-rollback",
404
+ "risk",
405
+ ];
406
+ const LIVE_SUBCOMMANDS: LiveSubcommand[] = [
407
+ "list",
408
+ "subscribe",
409
+ "status",
410
+ "debug",
411
+ "invalidations",
412
+ "test",
413
+ "load-test",
414
+ ];
415
+ const MAKE_PRIMITIVES: MakePrimitive[] = [
416
+ "list",
417
+ "explain",
418
+ "table",
419
+ "field",
420
+ "policy",
421
+ "command",
422
+ "query",
423
+ "livequery",
424
+ "action",
425
+ "workflow",
426
+ "component",
427
+ "page",
428
+ "ui",
429
+ "resource",
430
+ "apply",
431
+ "rollback",
432
+ ];
433
+ const FEATURE_ACTIONS: FeatureAction[] = [
434
+ "validate",
435
+ "plan",
436
+ "diff",
437
+ "apply",
438
+ "list",
439
+ "inspect",
440
+ "rollback",
441
+ "examples",
442
+ ];
443
+ const REFACTOR_ACTIONS: RefactorAction[] = [
444
+ "plan",
445
+ "apply",
446
+ "diff",
447
+ "rollback",
448
+ "list",
449
+ "rename",
450
+ "move",
451
+ "extract-action",
452
+ "replace-process-env",
453
+ "replace-import",
454
+ ];
455
+ const RENAME_TARGETS: RenameTarget[] = [
456
+ "table",
457
+ "field",
458
+ "policy",
459
+ "command",
460
+ "query",
461
+ "livequery",
462
+ "action",
463
+ "workflow",
464
+ "event",
465
+ ];
466
+ const TEST_SUBCOMMANDS: TestSubcommand[] = ["plan", "run", "explain"];
467
+ const TEST_COSTS: TestCost[] = ["instant", "fast", "standard", "slow", "docker", "browser"];
468
+ const REPAIR_SUBCOMMANDS: RepairSubcommand[] = [
469
+ "diagnose",
470
+ "explain",
471
+ "plan",
472
+ "apply",
473
+ "run",
474
+ "list",
475
+ "inspect",
476
+ "rollback",
477
+ ];
478
+ const AGENT_SUBCOMMANDS: AgentSubcommand[] = [
479
+ "list-targets",
480
+ "export",
481
+ "check",
482
+ "doctor",
483
+ "print-context",
484
+ "clean",
485
+ ];
486
+ const REVIEW_SUBCOMMANDS: ReviewSubcommand[] = ["inspect", "list", "explain"];
487
+ const REVIEW_MODES: ReviewMode[] = ["quick", "standard", "strict"];
488
+ const REVIEW_FAIL_ON: ReviewFailOn[] = ["warning", "error", "blocking"];
489
+ const REVIEW_CATEGORIES: ReviewFindingCategory[] = [
490
+ "runtime",
491
+ "data",
492
+ "policy",
493
+ "secrets",
494
+ "package",
495
+ "workflow",
496
+ "livequery",
497
+ "frontend",
498
+ "test",
499
+ "deploy",
500
+ "release",
501
+ "agent",
502
+ ];
503
+ const UI_SUBCOMMANDS: UiSubcommand[] = [
504
+ "smoke",
505
+ "test",
506
+ "scenario",
507
+ "route",
508
+ "snapshot",
509
+ "report",
510
+ "doctor",
511
+ "list",
512
+ ];
513
+ const UI_BROWSERS: UiBrowserName[] = ["chromium", "firefox", "webkit"];
514
+ const UI_TRACE_MODES: UiTraceMode[] = ["on", "off", "retain-on-failure"];
515
+ const UI_SCREENSHOT_MODES: UiScreenshotMode[] = ["on", "off", "only-on-failure"];
516
+ const UI_VIDEO_MODES: UiVideoMode[] = ["on", "off", "retain-on-failure"];
517
+
518
+ function parseFlag(args: string[], flag: string): boolean {
519
+ return args.includes(flag);
520
+ }
521
+
522
+ function parseOptionValue(args: string[], flag: string): string | undefined {
523
+ const index = args.indexOf(flag);
524
+ if (index === -1 || index + 1 >= args.length) {
525
+ return undefined;
526
+ }
527
+ return args[index + 1];
528
+ }
529
+
530
+ function parseOptionValues(args: string[], flag: string): string[] {
531
+ const values: string[] = [];
532
+ for (let index = 0; index < args.length; index++) {
533
+ if (args[index] === flag && index + 1 < args.length) {
534
+ values.push(args[index + 1]);
535
+ index += 1;
536
+ }
537
+ }
538
+ return values;
539
+ }
540
+
541
+ function parseDbKind(value: string | undefined): "pglite" | "postgres" | "none" {
542
+ if (value === "postgres" || value === "none") {
543
+ return value;
544
+ }
545
+ return "pglite";
546
+ }
547
+
548
+ function parseAdapterKind(value: string | undefined): DbAdapterKind {
549
+ if (value === "postgres" || value === "memory") {
550
+ return value;
551
+ }
552
+ return "pglite";
553
+ }
554
+
555
+ function parseSandboxBackend(value: string | undefined): SandboxBackend {
556
+ if (value === "child" || value === "docker" || value === "none") {
557
+ return value;
558
+ }
559
+ return "none";
560
+ }
561
+
562
+ function parseAddOptions(
563
+ args: string[],
564
+ workspaceRoot: string,
565
+ ): AddOptions & { workspaceRoot: string } {
566
+ return {
567
+ workspaceRoot,
568
+ json: parseFlag(args, "--json"),
569
+ dryRun: parseFlag(args, "--dry-run"),
570
+ runtimeInspect: parseFlag(args, "--runtime-inspect"),
571
+ sandboxBackend: parseSandboxBackend(
572
+ parseOptionValue(args, "--sandbox-backend"),
573
+ ),
574
+ allowScripts: parseFlag(args, "--allow-scripts"),
575
+ };
576
+ }
577
+
578
+ function parseTestCost(value: string | undefined): TestCost {
579
+ return TEST_COSTS.includes(value as TestCost) ? (value as TestCost) : "standard";
580
+ }
581
+
582
+ function parseReviewMode(value: string | undefined): ReviewMode {
583
+ return REVIEW_MODES.includes(value as ReviewMode) ? (value as ReviewMode) : "standard";
584
+ }
585
+
586
+ function parseReviewFailOn(value: string | undefined): ReviewFailOn | undefined {
587
+ return REVIEW_FAIL_ON.includes(value as ReviewFailOn) ? (value as ReviewFailOn) : undefined;
588
+ }
589
+
590
+ function parseReviewCategories(value: string | undefined): ReviewFindingCategory[] {
591
+ if (!value) return [];
592
+ return value
593
+ .split(",")
594
+ .map((item) => item.trim())
595
+ .filter((item): item is ReviewFindingCategory => REVIEW_CATEGORIES.includes(item as ReviewFindingCategory));
596
+ }
597
+
598
+ function parseUiBrowser(value: string | undefined): UiBrowserName {
599
+ return UI_BROWSERS.includes(value as UiBrowserName) ? (value as UiBrowserName) : "chromium";
600
+ }
601
+
602
+ function parseUiTrace(value: string | undefined): UiTraceMode {
603
+ return UI_TRACE_MODES.includes(value as UiTraceMode) ? (value as UiTraceMode) : "retain-on-failure";
604
+ }
605
+
606
+ function parseUiScreenshot(value: string | undefined): UiScreenshotMode {
607
+ return UI_SCREENSHOT_MODES.includes(value as UiScreenshotMode) ? (value as UiScreenshotMode) : "only-on-failure";
608
+ }
609
+
610
+ function parseUiVideo(value: string | undefined): UiVideoMode {
611
+ return UI_VIDEO_MODES.includes(value as UiVideoMode) ? (value as UiVideoMode) : "retain-on-failure";
612
+ }
613
+
614
+ function parseNewTemplate(value: string | undefined): NewTemplateName {
615
+ return NEW_TEMPLATES.includes(value as NewTemplateName)
616
+ ? (value as NewTemplateName)
617
+ : "b2b-support-web";
618
+ }
619
+
620
+ function parseNewPackageManager(value: string | undefined): NewPackageManager {
621
+ return NEW_PACKAGE_MANAGERS.includes(value as NewPackageManager)
622
+ ? (value as NewPackageManager)
623
+ : "bun";
624
+ }
625
+
626
+ function parseDoObjective(rest: string[], argv: string[]): string {
627
+ const [action, name, ...tail] = rest;
628
+ if (action === "add-resource") {
629
+ return [
630
+ "add",
631
+ "resource",
632
+ name ?? "<name>",
633
+ parseFlag(argv, "--with-ui") ? "with ui" : "",
634
+ tail.join(" "),
635
+ ]
636
+ .filter(Boolean)
637
+ .join(" ")
638
+ .trim();
639
+ }
640
+ if (action === "understand") {
641
+ return tail.length > 0 ? ["understand", ...tail].join(" ").trim() : "understand project";
642
+ }
643
+ if (action === "connect-ui") {
644
+ return ["connect", "ui", name, ...tail].filter(Boolean).join(" ").trim();
645
+ }
646
+ return rest.join(" ").trim() || "inspect project";
647
+ }
648
+
649
+ export function parseCli(argv: string[]): ParsedCli {
650
+ const errors: string[] = [];
651
+ const positional = argv.filter((arg) => !arg.startsWith("-"));
652
+ const workspaceRoot = process.cwd().replace(/\\/g, "/");
653
+
654
+ if (positional.length === 0) {
655
+ errors.push(
656
+ `missing command; expected ${TOP_LEVEL_COMMANDS.join(", ")}`,
657
+ );
658
+ return { command: null, workspaceRoot, errors };
659
+ }
660
+
661
+ const [commandName, ...rest] = positional;
662
+
663
+ switch (commandName) {
664
+ case "new": {
665
+ const name = rest[0];
666
+ if (!name) {
667
+ errors.push("forge new requires a project name");
668
+ return { command: null, workspaceRoot, errors };
669
+ }
670
+ const templateRaw = parseOptionValue(argv, "--template");
671
+ if (templateRaw && !NEW_TEMPLATES.includes(templateRaw as NewTemplateName)) {
672
+ errors.push(`unsupported template '${templateRaw}'; supported: ${NEW_TEMPLATES.join(", ")}`);
673
+ }
674
+ const packageManagerRaw = parseOptionValue(argv, "--package-manager");
675
+ const forgePackageSpec = parseOptionValue(argv, "--forge-spec");
676
+ const localForge = parseFlag(argv, "--local-forge");
677
+ const install = parseFlag(argv, "--install");
678
+ const noInstall = parseFlag(argv, "--no-install");
679
+ if (
680
+ packageManagerRaw &&
681
+ !NEW_PACKAGE_MANAGERS.includes(packageManagerRaw as NewPackageManager)
682
+ ) {
683
+ errors.push(
684
+ `unsupported package manager '${packageManagerRaw}'; supported: ${NEW_PACKAGE_MANAGERS.join(", ")}`,
685
+ );
686
+ }
687
+ if (forgePackageSpec && localForge) {
688
+ errors.push("use either --forge-spec or --local-forge, not both");
689
+ }
690
+ if (install && noInstall) {
691
+ errors.push("use either --install or --no-install, not both");
692
+ }
693
+
694
+ return {
695
+ command: {
696
+ kind: "new",
697
+ name,
698
+ template: parseNewTemplate(templateRaw),
699
+ packageManager: parseNewPackageManager(packageManagerRaw),
700
+ install: install || !noInstall,
701
+ git: !parseFlag(argv, "--no-git"),
702
+ forgePackageSpec,
703
+ localForge,
704
+ workspaceRoot,
705
+ },
706
+ workspaceRoot,
707
+ errors,
708
+ };
709
+ }
710
+ case "build":
711
+ return {
712
+ command: {
713
+ kind: "build",
714
+ json: parseFlag(argv, "--json"),
715
+ workspaceRoot,
716
+ },
717
+ workspaceRoot,
718
+ errors,
719
+ };
720
+ case "serve": {
721
+ const portRaw = parseOptionValue(argv, "--port");
722
+ const port = portRaw ? Number(portRaw) : undefined;
723
+ if (portRaw !== undefined && (!Number.isFinite(port) || port! < 0)) {
724
+ errors.push("--port must be a number >= 0");
725
+ }
726
+ return {
727
+ command: {
728
+ kind: "serve",
729
+ host: parseOptionValue(argv, "--host"),
730
+ port,
731
+ databaseUrl: parseOptionValue(argv, "--database-url"),
732
+ json: parseFlag(argv, "--json"),
733
+ envFile: parseOptionValue(argv, "--env-file"),
734
+ allowDevAuth: parseFlag(argv, "--allow-dev-auth"),
735
+ workspaceRoot,
736
+ },
737
+ workspaceRoot,
738
+ errors,
739
+ };
740
+ }
741
+ case "worker": {
742
+ const limitRaw = parseOptionValue(argv, "--limit");
743
+ const limit = limitRaw ? Number(limitRaw) : 10;
744
+ if (!Number.isFinite(limit) || limit < 1) {
745
+ errors.push("--limit must be a number >= 1");
746
+ }
747
+ const pollRaw = parseOptionValue(argv, "--poll-interval");
748
+ const pollIntervalMs = pollRaw ? Number(pollRaw) : 1_000;
749
+ if (!Number.isFinite(pollIntervalMs) || pollIntervalMs < 1) {
750
+ errors.push("--poll-interval must be a number >= 1");
751
+ }
752
+ return {
753
+ command: {
754
+ kind: "worker",
755
+ db: parseAdapterKind(parseOptionValue(argv, "--db")),
756
+ databaseUrl: parseOptionValue(argv, "--database-url"),
757
+ json: parseFlag(argv, "--json"),
758
+ once: parseFlag(argv, "--once"),
759
+ pollIntervalMs,
760
+ limit: Math.floor(limit),
761
+ mock: parseFlag(argv, "--mock"),
762
+ workspaceRoot,
763
+ },
764
+ workspaceRoot,
765
+ errors,
766
+ };
767
+ }
768
+ case "self-host": {
769
+ const subcommand = rest[0] as SelfHostSubcommand | undefined;
770
+ if (!subcommand || !SELF_HOST_SUBCOMMANDS.includes(subcommand)) {
771
+ errors.push("forge self-host requires subcommand: compose, env, check, or clean");
772
+ return { command: null, workspaceRoot, errors };
773
+ }
774
+ const runtimePortRaw = parseOptionValue(argv, "--runtime-port");
775
+ const runtimePort = runtimePortRaw ? Number(runtimePortRaw) : 3765;
776
+ if (!Number.isFinite(runtimePort) || runtimePort < 1) {
777
+ errors.push("--runtime-port must be a number >= 1");
778
+ }
779
+ const webPortRaw = parseOptionValue(argv, "--web-port");
780
+ const webPort = webPortRaw ? Number(webPortRaw) : 3000;
781
+ if (!Number.isFinite(webPort) || webPort < 1) {
782
+ errors.push("--web-port must be a number >= 1");
783
+ }
784
+ return {
785
+ command: {
786
+ kind: "self-host",
787
+ subcommand,
788
+ json: parseFlag(argv, "--json"),
789
+ withWeb: !parseFlag(argv, "--no-web"),
790
+ postgresVersion: parseOptionValue(argv, "--postgres-version") ?? "16",
791
+ runtimePort: Math.floor(runtimePort),
792
+ webPort: Math.floor(webPort),
793
+ workspaceRoot,
794
+ },
795
+ workspaceRoot,
796
+ errors,
797
+ };
798
+ }
799
+ case "agent-contract": {
800
+ const subcommand = rest[0] as AgentContractSubcommand | undefined;
801
+ if (!subcommand || !AGENT_CONTRACT_SUBCOMMANDS.includes(subcommand)) {
802
+ errors.push("forge agent-contract requires subcommand: generate, check, or print");
803
+ return { command: null, workspaceRoot, errors };
804
+ }
805
+ return {
806
+ command: {
807
+ kind: "agent-contract",
808
+ subcommand,
809
+ json: parseFlag(argv, "--json"),
810
+ workspaceRoot,
811
+ },
812
+ workspaceRoot,
813
+ errors,
814
+ };
815
+ }
816
+ case "agent": {
817
+ const subcommand = rest[0] as AgentSubcommand | undefined;
818
+ if (!subcommand || !AGENT_SUBCOMMANDS.includes(subcommand)) {
819
+ errors.push("forge agent requires subcommand: list-targets, export, check, doctor, print-context, or clean");
820
+ return { command: null, workspaceRoot, errors };
821
+ }
822
+ const target =
823
+ (parseOptionValue(argv, "--target") as AgentAdapterTarget | undefined) ??
824
+ (subcommand === "export" || subcommand === "clean" ? "generic" : "generic");
825
+ return {
826
+ command: {
827
+ kind: "agent",
828
+ options: {
829
+ subcommand,
830
+ workspaceRoot,
831
+ json: parseFlag(argv, "--json"),
832
+ target,
833
+ dryRun: parseFlag(argv, "--dry-run"),
834
+ force: parseFlag(argv, "--force"),
835
+ preserveUserSections: !parseFlag(argv, "--no-preserve-user-sections"),
836
+ skills: !parseFlag(argv, "--no-skills"),
837
+ rules: !parseFlag(argv, "--no-rules"),
838
+ },
839
+ },
840
+ workspaceRoot,
841
+ errors,
842
+ };
843
+ }
844
+ case "review": {
845
+ const requested = rest[0] as ReviewSubcommand | undefined;
846
+ const subcommand =
847
+ requested && REVIEW_SUBCOMMANDS.includes(requested) ? requested : "run";
848
+ const positionalWrite = rest[0] === "write";
849
+ const noSourceFlag =
850
+ !parseFlag(argv, "--changed") &&
851
+ !parseFlag(argv, "--staged") &&
852
+ !parseOptionValue(argv, "--base") &&
853
+ !parseOptionValue(argv, "--feature") &&
854
+ !parseOptionValue(argv, "--refactor") &&
855
+ !parseOptionValue(argv, "--upgrade") &&
856
+ !parseOptionValue(argv, "--release");
857
+ return {
858
+ command: {
859
+ kind: "review",
860
+ options: {
861
+ subcommand,
862
+ workspaceRoot,
863
+ json: parseFlag(argv, "--json"),
864
+ md: parseFlag(argv, "--md"),
865
+ sarif: parseFlag(argv, "--sarif"),
866
+ write: positionalWrite || parseFlag(argv, "--write"),
867
+ changed: parseFlag(argv, "--changed") || noSourceFlag,
868
+ staged: parseFlag(argv, "--staged"),
869
+ base: parseOptionValue(argv, "--base"),
870
+ featureId: parseOptionValue(argv, "--feature"),
871
+ refactorId: parseOptionValue(argv, "--refactor"),
872
+ upgradeId: parseOptionValue(argv, "--upgrade"),
873
+ releaseId: parseOptionValue(argv, "--release"),
874
+ failOn: parseReviewFailOn(parseOptionValue(argv, "--fail-on")),
875
+ mode: parseReviewMode(parseOptionValue(argv, "--mode")),
876
+ include: parseReviewCategories(parseOptionValue(argv, "--include")),
877
+ exclude: parseReviewCategories(parseOptionValue(argv, "--exclude")),
878
+ reviewId: subcommand === "inspect" ? rest[1] : undefined,
879
+ ruleId: subcommand === "explain" ? rest[1] : undefined,
880
+ },
881
+ },
882
+ workspaceRoot,
883
+ errors,
884
+ };
885
+ }
886
+ case "ui": {
887
+ const subcommand = (rest[0] ?? "smoke") as UiSubcommand;
888
+ if (!UI_SUBCOMMANDS.includes(subcommand)) {
889
+ errors.push("forge ui requires subcommand: smoke, test, scenario, route, snapshot, report, doctor, or list");
890
+ return { command: null, workspaceRoot, errors };
891
+ }
892
+ const timeoutRaw = parseOptionValue(argv, "--timeout");
893
+ const timeoutMs = timeoutRaw ? Number(timeoutRaw) : 30_000;
894
+ if (!Number.isFinite(timeoutMs) || timeoutMs < 1) {
895
+ errors.push("--timeout must be a number >= 1");
896
+ }
897
+ const scenarioName =
898
+ parseOptionValue(argv, "--scenario") ??
899
+ (subcommand === "scenario" ? rest[1] : undefined);
900
+ const routePath =
901
+ subcommand === "route" || subcommand === "snapshot"
902
+ ? rest[1] ?? "/"
903
+ : undefined;
904
+ return {
905
+ command: {
906
+ kind: "ui",
907
+ options: {
908
+ subcommand,
909
+ workspaceRoot,
910
+ json: parseFlag(argv, "--json"),
911
+ headed: parseFlag(argv, "--headed"),
912
+ browser: parseUiBrowser(parseOptionValue(argv, "--browser")),
913
+ trace: parseUiTrace(parseOptionValue(argv, "--trace")),
914
+ screenshot: parseUiScreenshot(parseOptionValue(argv, "--screenshot")),
915
+ video: parseUiVideo(parseOptionValue(argv, "--video")),
916
+ baseUrl: parseOptionValue(argv, "--base-url") ?? "http://127.0.0.1:3000",
917
+ runtimeUrl: parseOptionValue(argv, "--runtime-url") ?? "http://127.0.0.1:3765",
918
+ reuseServers: parseFlag(argv, "--reuse-servers"),
919
+ startServers: parseFlag(argv, "--start-servers"),
920
+ scenarioName,
921
+ routePath,
922
+ snapshotName: parseOptionValue(argv, "--name"),
923
+ reportId: subcommand === "report" ? rest[1] ?? "last" : undefined,
924
+ all: parseFlag(argv, "--all"),
925
+ changed: parseFlag(argv, "--changed"),
926
+ ci: parseFlag(argv, "--ci"),
927
+ timeoutMs: Math.floor(timeoutMs),
928
+ authToken: parseOptionValue(argv, "--auth-token"),
929
+ },
930
+ },
931
+ workspaceRoot,
932
+ errors,
933
+ };
934
+ }
935
+ case "doctor":
936
+ if (rest[0] && rest[0] !== "windows") {
937
+ errors.push("forge doctor supports subcommand: windows");
938
+ return { command: null, workspaceRoot, errors };
939
+ }
940
+ return {
941
+ command: {
942
+ kind: "doctor",
943
+ target: rest[0] === "windows" ? "windows" : "project",
944
+ json: parseFlag(argv, "--json"),
945
+ workspaceRoot,
946
+ },
947
+ workspaceRoot,
948
+ errors,
949
+ };
950
+ case "setup": {
951
+ const target = rest[0];
952
+ if (target !== "windows") {
953
+ errors.push("forge setup requires subcommand: windows");
954
+ return { command: null, workspaceRoot, errors };
955
+ }
956
+ return {
957
+ command: {
958
+ kind: "setup",
959
+ target,
960
+ json: parseFlag(argv, "--json"),
961
+ yes: parseFlag(argv, "--yes"),
962
+ workspaceRoot,
963
+ },
964
+ workspaceRoot,
965
+ errors,
966
+ };
967
+ }
968
+ case "auth": {
969
+ const subcommand = rest[0] as AuthSubcommand | undefined;
970
+ if (!subcommand || !AUTH_SUBCOMMANDS.includes(subcommand)) {
971
+ errors.push("forge auth requires subcommand: check, config, decode, test-token, or jwks");
972
+ return { command: null, workspaceRoot, errors };
973
+ }
974
+ return {
975
+ command: {
976
+ kind: "auth",
977
+ subcommand,
978
+ json: parseFlag(argv, "--json"),
979
+ token: parseOptionValue(argv, "--token"),
980
+ workspaceRoot,
981
+ },
982
+ workspaceRoot,
983
+ errors,
984
+ };
985
+ }
986
+ case "rls": {
987
+ const subcommand = rest[0] as RlsSubcommand | undefined;
988
+ if (!subcommand || !RLS_SUBCOMMANDS.includes(subcommand)) {
989
+ errors.push("forge rls requires subcommand: generate, check, apply, or test");
990
+ return { command: null, workspaceRoot, errors };
991
+ }
992
+ return {
993
+ command: {
994
+ kind: "rls",
995
+ subcommand,
996
+ db: parseAdapterKind(parseOptionValue(argv, "--db")),
997
+ databaseUrl: parseOptionValue(argv, "--database-url"),
998
+ json: parseFlag(argv, "--json"),
999
+ workspaceRoot,
1000
+ },
1001
+ workspaceRoot,
1002
+ errors,
1003
+ };
1004
+ }
1005
+ case "deps": {
1006
+ const subcommand = rest[0] as DepsSubcommand | undefined;
1007
+ if (!subcommand || !DEPS_SUBCOMMANDS.includes(subcommand)) {
1008
+ errors.push("forge deps requires subcommand: outdated, inspect, diff, upgrade-plan, upgrade-apply, upgrade-check, upgrade-rollback, or risk");
1009
+ return { command: null, workspaceRoot, errors };
1010
+ }
1011
+ const packageName =
1012
+ subcommand === "outdated" || subcommand === "upgrade-check" ? undefined : rest[1];
1013
+ const planPath =
1014
+ subcommand === "upgrade-apply" || subcommand === "upgrade-rollback"
1015
+ ? rest[1]
1016
+ : undefined;
1017
+ return {
1018
+ command: {
1019
+ kind: "deps",
1020
+ subcommand,
1021
+ packageName,
1022
+ planPath,
1023
+ target: parseOptionValue(argv, "--to"),
1024
+ json: parseFlag(argv, "--json"),
1025
+ yes: parseFlag(argv, "--yes"),
1026
+ allowScripts: parseFlag(argv, "--allow-scripts"),
1027
+ skipTests: parseFlag(argv, "--skip-tests"),
1028
+ dryRun: parseFlag(argv, "--dry-run"),
1029
+ changed: parseFlag(argv, "--changed"),
1030
+ workspaceRoot,
1031
+ },
1032
+ workspaceRoot,
1033
+ errors,
1034
+ };
1035
+ }
1036
+ case "release": {
1037
+ const first = rest[0] ?? "prepare";
1038
+ const area =
1039
+ first === "artifacts" || first === "sourcemaps"
1040
+ ? (first as ReleaseArea)
1041
+ : "release";
1042
+ const action = (area === "release" ? first : rest[1]) as ReleaseAction;
1043
+ const releaseId =
1044
+ area === "release" && action === "inspect"
1045
+ ? rest[1]
1046
+ : parseOptionValue(argv, "--release");
1047
+ return {
1048
+ command: {
1049
+ kind: "release",
1050
+ area,
1051
+ action,
1052
+ releaseId,
1053
+ input: parseOptionValue(argv, "--input"),
1054
+ provider: parseOptionValue(argv, "--provider"),
1055
+ target: parseOptionValue(argv, "--target"),
1056
+ env: parseOptionValue(argv, "--env") ?? "production",
1057
+ json: parseFlag(argv, "--json"),
1058
+ allowDirty: parseFlag(argv, "--allow-dirty"),
1059
+ allowPublicSourcemaps: parseFlag(argv, "--allow-public-sourcemaps"),
1060
+ workspaceRoot,
1061
+ },
1062
+ workspaceRoot,
1063
+ errors,
1064
+ };
1065
+ }
1066
+ case "make": {
1067
+ const primitive = rest[0] as MakePrimitive | undefined;
1068
+ if (!primitive || !MAKE_PRIMITIVES.includes(primitive)) {
1069
+ errors.push(`forge make requires primitive: ${MAKE_PRIMITIVES.join(", ")}`);
1070
+ return { command: null, workspaceRoot, errors };
1071
+ }
1072
+ const name =
1073
+ primitive === "explain"
1074
+ ? undefined
1075
+ : primitive === "list"
1076
+ ? undefined
1077
+ : primitive === "ui"
1078
+ ? rest[1] ?? "ui"
1079
+ : rest[1];
1080
+ const explainPrimitive =
1081
+ primitive === "explain" ? (rest[1] as MakePrimitive | undefined) : undefined;
1082
+ if (
1083
+ primitive === "explain" &&
1084
+ (!explainPrimitive || !MAKE_PRIMITIVES.includes(explainPrimitive))
1085
+ ) {
1086
+ errors.push("forge make explain requires a known primitive");
1087
+ }
1088
+ if (
1089
+ !["list", "explain", "ui"].includes(primitive) &&
1090
+ !name
1091
+ ) {
1092
+ errors.push(`forge make ${primitive} requires a name or plan id`);
1093
+ }
1094
+
1095
+ return {
1096
+ command: {
1097
+ kind: "make",
1098
+ options: {
1099
+ primitive,
1100
+ name,
1101
+ explainPrimitive,
1102
+ workspaceRoot,
1103
+ json: parseFlag(argv, "--json"),
1104
+ dryRun: parseFlag(argv, "--dry-run"),
1105
+ plan: parseFlag(argv, "--plan"),
1106
+ apply:
1107
+ primitive === "apply" ||
1108
+ parseFlag(argv, "--apply") ||
1109
+ parseFlag(argv, "--yes"),
1110
+ yes: parseFlag(argv, "--yes"),
1111
+ force: parseFlag(argv, "--force"),
1112
+ noGenerate: parseFlag(argv, "--no-generate"),
1113
+ noVerify: parseFlag(argv, "--no-verify"),
1114
+ keepFailed: parseFlag(argv, "--keep-failed"),
1115
+ tenantScoped: parseFlag(argv, "--tenant-scoped"),
1116
+ fieldSpecs: parseOptionValues(argv, "--field"),
1117
+ fieldsRaw: parseOptionValue(argv, "--fields"),
1118
+ type: parseOptionValue(argv, "--type"),
1119
+ values: parseOptionValue(argv, "--values"),
1120
+ defaultValue: parseOptionValue(argv, "--default"),
1121
+ index: parseFlag(argv, "--index"),
1122
+ roles: parseOptionValue(argv, "--roles"),
1123
+ table: parseOptionValue(argv, "--table"),
1124
+ policy: parseOptionValue(argv, "--policy"),
1125
+ emit: parseOptionValue(argv, "--emit"),
1126
+ event: parseOptionValue(argv, "--event"),
1127
+ trigger: parseOptionValue(argv, "--trigger"),
1128
+ component: parseOptionValue(argv, "--component"),
1129
+ framework: parseOptionValue(argv, "--framework") as "vite" | "next" | undefined,
1130
+ withAi: parseFlag(argv, "--with-ai"),
1131
+ withCrud: parseFlag(argv, "--with-crud"),
1132
+ withLiveQuery: parseFlag(argv, "--with-livequery"),
1133
+ withReact: parseFlag(argv, "--with-react") || parseFlag(argv, "--with-ui"),
1134
+ withUi: parseFlag(argv, "--with-ui"),
1135
+ withTests: parseFlag(argv, "--with-tests"),
1136
+ withCreateForm: parseFlag(argv, "--with-create-form"),
1137
+ },
1138
+ },
1139
+ workspaceRoot,
1140
+ errors,
1141
+ };
1142
+ }
1143
+ case "feature": {
1144
+ const action = rest[0] as FeatureAction | undefined;
1145
+ if (!action || !FEATURE_ACTIONS.includes(action)) {
1146
+ errors.push(`forge feature requires action: ${FEATURE_ACTIONS.join(", ")}`);
1147
+ return { command: null, workspaceRoot, errors };
1148
+ }
1149
+ const blueprintPath =
1150
+ ["validate", "plan", "diff", "apply"].includes(action) ? rest[1] : undefined;
1151
+ const featureId =
1152
+ ["inspect", "rollback"].includes(action) ? rest[1] : undefined;
1153
+ const exampleName = action === "examples" ? rest[1] : undefined;
1154
+ if (["validate", "plan", "diff", "apply"].includes(action) && !blueprintPath) {
1155
+ errors.push(`forge feature ${action} requires a blueprint path`);
1156
+ }
1157
+ if (["inspect", "rollback"].includes(action) && !featureId) {
1158
+ errors.push(`forge feature ${action} requires a feature id`);
1159
+ }
1160
+ return {
1161
+ command: {
1162
+ kind: "feature",
1163
+ options: {
1164
+ action,
1165
+ blueprintPath,
1166
+ featureId,
1167
+ exampleName,
1168
+ writePath: parseOptionValue(argv, "--write"),
1169
+ workspaceRoot,
1170
+ json: parseFlag(argv, "--json"),
1171
+ dryRun: parseFlag(argv, "--dry-run"),
1172
+ yes: parseFlag(argv, "--yes"),
1173
+ noGenerate: parseFlag(argv, "--no-generate"),
1174
+ noVerify: parseFlag(argv, "--no-verify"),
1175
+ keepFailed: parseFlag(argv, "--keep-failed"),
1176
+ update: parseFlag(argv, "--update"),
1177
+ allowHighRisk: parseFlag(argv, "--allow-high-risk"),
1178
+ },
1179
+ },
1180
+ workspaceRoot,
1181
+ errors,
1182
+ };
1183
+ }
1184
+ case "refactor": {
1185
+ const action = rest[0] as RefactorAction | undefined;
1186
+ if (!action || !REFACTOR_ACTIONS.includes(action)) {
1187
+ errors.push(`forge refactor requires action: ${REFACTOR_ACTIONS.join(", ")}`);
1188
+ return { command: null, workspaceRoot, errors };
1189
+ }
1190
+ let renameTarget: RenameTarget | undefined;
1191
+ let from: string | undefined;
1192
+ let to: string | undefined;
1193
+ let planId: string | undefined;
1194
+ let componentName: string | undefined;
1195
+
1196
+ if (action === "rename") {
1197
+ renameTarget = rest[1] as RenameTarget | undefined;
1198
+ if (!renameTarget || !RENAME_TARGETS.includes(renameTarget)) {
1199
+ errors.push(`forge refactor rename requires target: ${RENAME_TARGETS.join(", ")}`);
1200
+ }
1201
+ from = rest[2];
1202
+ to = rest[3];
1203
+ if (!from || !to) {
1204
+ errors.push("forge refactor rename requires <from> <to>");
1205
+ }
1206
+ } else if (action === "move") {
1207
+ renameTarget = rest[1] as RenameTarget | undefined;
1208
+ if (renameTarget !== "field" && rest[1] !== "component") {
1209
+ errors.push("forge refactor move requires target: component");
1210
+ }
1211
+ componentName = rest[2];
1212
+ to = rest[3];
1213
+ if (!componentName || !to) {
1214
+ errors.push("forge refactor move component requires <name> <path>");
1215
+ }
1216
+ } else if (action === "extract-action") {
1217
+ from = rest[1];
1218
+ if (!from) {
1219
+ errors.push("forge refactor extract-action requires a command name");
1220
+ }
1221
+ } else if (action === "replace-process-env") {
1222
+ from = rest[1];
1223
+ if (!from) {
1224
+ errors.push("forge refactor replace-process-env requires an env var");
1225
+ }
1226
+ } else if (action === "replace-import") {
1227
+ from = rest[1];
1228
+ to = rest[2];
1229
+ if (!from || !to) {
1230
+ errors.push("forge refactor replace-import requires <from> <to>");
1231
+ }
1232
+ } else if (action === "apply" || action === "diff" || action === "rollback") {
1233
+ planId = rest[1];
1234
+ if (!planId) {
1235
+ errors.push(`forge refactor ${action} requires a plan id`);
1236
+ }
1237
+ } else if (action === "plan") {
1238
+ const nestedAction = rest[1] as RefactorAction | undefined;
1239
+ if (nestedAction === "rename") {
1240
+ renameTarget = rest[2] as RenameTarget | undefined;
1241
+ from = rest[3];
1242
+ to = rest[4];
1243
+ } else {
1244
+ errors.push("forge refactor plan currently supports: rename <target> <from> <to>");
1245
+ }
1246
+ }
1247
+
1248
+ return {
1249
+ command: {
1250
+ kind: "refactor",
1251
+ options: {
1252
+ action: action === "plan" && rest[1] === "rename" ? "rename" : action,
1253
+ renameTarget,
1254
+ from,
1255
+ to,
1256
+ planId,
1257
+ componentName,
1258
+ packageName: parseOptionValue(argv, "--package"),
1259
+ eventName: parseOptionValue(argv, "--event"),
1260
+ actionName: parseOptionValue(argv, "--action"),
1261
+ workspaceRoot,
1262
+ json: parseFlag(argv, "--json"),
1263
+ dryRun: parseFlag(argv, "--dry-run"),
1264
+ plan: action === "plan" || parseFlag(argv, "--plan"),
1265
+ yes: parseFlag(argv, "--yes"),
1266
+ force: parseFlag(argv, "--force"),
1267
+ allowHighRisk: parseFlag(argv, "--allow-high-risk"),
1268
+ noGenerate: parseFlag(argv, "--no-generate"),
1269
+ noVerify: parseFlag(argv, "--no-verify"),
1270
+ keepFailed: parseFlag(argv, "--keep-failed"),
1271
+ },
1272
+ },
1273
+ workspaceRoot,
1274
+ errors,
1275
+ };
1276
+ }
1277
+ case "impact": {
1278
+ return {
1279
+ command: {
1280
+ kind: "impact",
1281
+ options: {
1282
+ workspaceRoot,
1283
+ json: parseFlag(argv, "--json"),
1284
+ write: parseFlag(argv, "--write"),
1285
+ changed: parseFlag(argv, "--changed") || (!parseFlag(argv, "--staged") && !parseOptionValue(argv, "--since") && !parseOptionValue(argv, "--feature") && !parseOptionValue(argv, "--refactor") && !parseOptionValue(argv, "--upgrade")),
1286
+ staged: parseFlag(argv, "--staged"),
1287
+ since: parseOptionValue(argv, "--since"),
1288
+ featureId: parseOptionValue(argv, "--feature"),
1289
+ refactorId: parseOptionValue(argv, "--refactor"),
1290
+ upgradeId: parseOptionValue(argv, "--upgrade"),
1291
+ includeGenerated: parseFlag(argv, "--include-generated"),
1292
+ excludeTests: parseFlag(argv, "--exclude-tests"),
1293
+ riskThreshold: parseOptionValue(argv, "--risk-threshold") as ImpactCommandOptions["riskThreshold"],
1294
+ },
1295
+ },
1296
+ workspaceRoot,
1297
+ errors,
1298
+ };
1299
+ }
1300
+ case "test": {
1301
+ const subcommand = rest[0] as TestSubcommand | undefined;
1302
+ if (!subcommand || !TEST_SUBCOMMANDS.includes(subcommand)) {
1303
+ errors.push("forge test requires subcommand: plan, run, or explain");
1304
+ return { command: null, workspaceRoot, errors };
1305
+ }
1306
+ const timeoutRaw = parseOptionValue(argv, "--timeout-ms");
1307
+ const timeoutMs = timeoutRaw ? Number(timeoutRaw) : undefined;
1308
+ if (
1309
+ timeoutRaw !== undefined &&
1310
+ (!Number.isFinite(timeoutMs) || timeoutMs! < 1)
1311
+ ) {
1312
+ errors.push("--timeout-ms must be a number >= 1");
1313
+ }
1314
+ return {
1315
+ command: {
1316
+ kind: "test",
1317
+ options: {
1318
+ subcommand,
1319
+ workspaceRoot,
1320
+ json: parseFlag(argv, "--json"),
1321
+ write: parseFlag(argv, "--write"),
1322
+ changed: parseFlag(argv, "--changed") || (!parseFlag(argv, "--staged") && !parseOptionValue(argv, "--since") && !parseOptionValue(argv, "--feature") && !parseOptionValue(argv, "--refactor") && !parseOptionValue(argv, "--upgrade") && !parseOptionValue(argv, "--plan") && subcommand !== "explain"),
1323
+ staged: parseFlag(argv, "--staged"),
1324
+ since: parseOptionValue(argv, "--since"),
1325
+ featureId: parseOptionValue(argv, "--feature"),
1326
+ refactorId: parseOptionValue(argv, "--refactor"),
1327
+ upgradeId: parseOptionValue(argv, "--upgrade"),
1328
+ planPath: parseOptionValue(argv, "--plan"),
1329
+ testFile: subcommand === "explain" ? rest[1] : undefined,
1330
+ maxCost: parseTestCost(parseOptionValue(argv, "--max-cost")),
1331
+ includeDocker: parseFlag(argv, "--include-docker"),
1332
+ includeBrowser: parseFlag(argv, "--include-browser"),
1333
+ bail: parseFlag(argv, "--bail"),
1334
+ report: parseOptionValue(argv, "--report"),
1335
+ timeoutMs: timeoutMs ? Math.floor(timeoutMs) : undefined,
1336
+ },
1337
+ },
1338
+ workspaceRoot,
1339
+ errors,
1340
+ };
1341
+ }
1342
+ case "repair": {
1343
+ const subcommand = rest[0] as RepairSubcommand | undefined;
1344
+ if (!subcommand || !REPAIR_SUBCOMMANDS.includes(subcommand)) {
1345
+ errors.push("forge repair requires subcommand: diagnose, explain, plan, apply, run, list, inspect, or rollback");
1346
+ return { command: null, workspaceRoot, errors };
1347
+ }
1348
+ const positionalId =
1349
+ subcommand === "explain" ||
1350
+ subcommand === "apply" ||
1351
+ subcommand === "inspect" ||
1352
+ subcommand === "rollback"
1353
+ ? rest[1]
1354
+ : undefined;
1355
+ const attemptsRaw = parseOptionValue(argv, "--max-attempts");
1356
+ const maxAttempts = attemptsRaw ? Number(attemptsRaw) : 1;
1357
+ if (!Number.isFinite(maxAttempts) || maxAttempts < 1) {
1358
+ errors.push("--max-attempts must be a number >= 1");
1359
+ }
1360
+ return {
1361
+ command: {
1362
+ kind: "repair",
1363
+ options: {
1364
+ subcommand,
1365
+ workspaceRoot,
1366
+ json: parseFlag(argv, "--json"),
1367
+ fromLastTestRun: parseFlag(argv, "--from-last-test-run"),
1368
+ fromLastUiRun: parseFlag(argv, "--from-last-ui-run"),
1369
+ from: parseOptionValue(argv, "--from"),
1370
+ traceId: parseOptionValue(argv, "--trace"),
1371
+ workflowRunId: parseOptionValue(argv, "--workflow-run"),
1372
+ outboxDeliveryId: parseOptionValue(argv, "--outbox-delivery"),
1373
+ diagnosticCode:
1374
+ parseOptionValue(argv, "--diagnostic") ??
1375
+ (subcommand === "explain" ? positionalId : undefined),
1376
+ repairId:
1377
+ subcommand === "apply" || subcommand === "inspect" || subcommand === "rollback"
1378
+ ? positionalId
1379
+ : undefined,
1380
+ selectedRepair: parseOptionValue(argv, "--repair"),
1381
+ write: parseFlag(argv, "--write"),
1382
+ yes: parseFlag(argv, "--yes"),
1383
+ keepFailed: parseFlag(argv, "--keep-failed"),
1384
+ allowMediumConfidence: parseFlag(argv, "--allow-medium-confidence"),
1385
+ maxAttempts: Math.floor(maxAttempts),
1386
+ commitFriendly: parseFlag(argv, "--commit-friendly"),
1387
+ },
1388
+ },
1389
+ workspaceRoot,
1390
+ errors,
1391
+ };
1392
+ }
1393
+ case "do": {
1394
+ const objective = parseDoObjective(rest, argv);
1395
+ return {
1396
+ command: {
1397
+ kind: "do",
1398
+ options: {
1399
+ workspaceRoot,
1400
+ objective,
1401
+ json: parseFlag(argv, "--json"),
1402
+ },
1403
+ },
1404
+ workspaceRoot,
1405
+ errors,
1406
+ };
1407
+ }
1408
+ case "generate": {
1409
+ const concurrencyRaw = parseOptionValue(argv, "--concurrency");
1410
+ const concurrency = concurrencyRaw ? Number(concurrencyRaw) : 4;
1411
+ if (!Number.isFinite(concurrency) || concurrency < 1) {
1412
+ errors.push("--concurrency must be an integer >= 1");
1413
+ }
1414
+ return {
1415
+ command: {
1416
+ kind: "generate",
1417
+ check: parseFlag(argv, "--check"),
1418
+ dryRun: parseFlag(argv, "--dry-run"),
1419
+ json: parseFlag(argv, "--json"),
1420
+ concurrency: Math.max(1, Math.floor(concurrency || 4)),
1421
+ },
1422
+ workspaceRoot,
1423
+ errors,
1424
+ };
1425
+ }
1426
+ case "add": {
1427
+ const alias = rest[0];
1428
+ if (!alias) {
1429
+ errors.push("forge add requires an integration alias");
1430
+ return { command: null, workspaceRoot, errors };
1431
+ }
1432
+ return {
1433
+ command: {
1434
+ kind: "add",
1435
+ alias,
1436
+ options: parseAddOptions(argv, workspaceRoot),
1437
+ },
1438
+ workspaceRoot,
1439
+ errors,
1440
+ };
1441
+ }
1442
+ case "inspect": {
1443
+ const target = rest[0] as InspectTarget | undefined;
1444
+ if (!target || !INSPECT_TARGETS.includes(target)) {
1445
+ errors.push(
1446
+ `unsupported inspect target; supported: ${INSPECT_TARGETS.join(", ")}`,
1447
+ );
1448
+ return { command: null, workspaceRoot, errors };
1449
+ }
1450
+ return {
1451
+ command: {
1452
+ kind: "inspect",
1453
+ target,
1454
+ json: parseFlag(argv, "--json"),
1455
+ dryRun: parseFlag(argv, "--dry-run"),
1456
+ },
1457
+ workspaceRoot,
1458
+ errors,
1459
+ };
1460
+ }
1461
+ case "check":
1462
+ return {
1463
+ command: {
1464
+ kind: "check",
1465
+ json: parseFlag(argv, "--json"),
1466
+ dryRun: parseFlag(argv, "--dry-run"),
1467
+ strictSecrets: parseFlag(argv, "--strict-secrets"),
1468
+ },
1469
+ workspaceRoot,
1470
+ errors,
1471
+ };
1472
+ case "verify":
1473
+ {
1474
+ const scriptTimeoutRaw = parseOptionValue(argv, "--script-timeout-ms");
1475
+ const scriptTimeoutMs = scriptTimeoutRaw ? Number(scriptTimeoutRaw) : undefined;
1476
+ if (
1477
+ scriptTimeoutRaw !== undefined &&
1478
+ (!Number.isFinite(scriptTimeoutMs) || scriptTimeoutMs! < 1)
1479
+ ) {
1480
+ errors.push("--script-timeout-ms must be a number >= 1");
1481
+ }
1482
+ return {
1483
+ command: {
1484
+ kind: "verify",
1485
+ options: {
1486
+ workspaceRoot,
1487
+ json: parseFlag(argv, "--json"),
1488
+ skipTests: parseFlag(argv, "--skip-tests"),
1489
+ skipTypecheck: parseFlag(argv, "--skip-typecheck"),
1490
+ skipEslint: parseFlag(argv, "--skip-eslint"),
1491
+ strict: parseFlag(argv, "--strict"),
1492
+ changed: parseFlag(argv, "--changed"),
1493
+ fast: parseFlag(argv, "--fast"),
1494
+ smoke: parseFlag(argv, "--smoke"),
1495
+ standard: parseFlag(argv, "--standard"),
1496
+ scriptTimeoutMs: scriptTimeoutMs ? Math.floor(scriptTimeoutMs) : undefined,
1497
+ },
1498
+ },
1499
+ workspaceRoot,
1500
+ errors,
1501
+ };
1502
+ }
1503
+ case "run": {
1504
+ if (rest[0] === "query") {
1505
+ const queryName = rest[1];
1506
+ if (!queryName) {
1507
+ errors.push("forge run query requires a query name");
1508
+ }
1509
+ const argsRaw = parseOptionValue(argv, "--args");
1510
+ let args: unknown = {};
1511
+ if (argsRaw !== undefined) {
1512
+ try {
1513
+ args = JSON.parse(argsRaw);
1514
+ } catch {
1515
+ errors.push("--args must be valid JSON");
1516
+ }
1517
+ }
1518
+ return {
1519
+ command: {
1520
+ kind: "run",
1521
+ name: queryName,
1522
+ list: false,
1523
+ json: parseFlag(argv, "--json"),
1524
+ mock: parseFlag(argv, "--mock"),
1525
+ userId: parseOptionValue(argv, "--user-id"),
1526
+ tenantId: parseOptionValue(argv, "--tenant-id"),
1527
+ role: parseOptionValue(argv, "--role"),
1528
+ envFile: parseOptionValue(argv, "--env-file"),
1529
+ workspaceRoot,
1530
+ queryMode: true,
1531
+ args,
1532
+ },
1533
+ workspaceRoot,
1534
+ errors,
1535
+ };
1536
+ }
1537
+
1538
+ const name = rest[0];
1539
+ const list = parseFlag(argv, "--list") || !name;
1540
+ return {
1541
+ command: {
1542
+ kind: "run",
1543
+ name,
1544
+ list,
1545
+ json: parseFlag(argv, "--json"),
1546
+ mock: parseFlag(argv, "--mock"),
1547
+ userId: parseOptionValue(argv, "--user-id"),
1548
+ tenantId: parseOptionValue(argv, "--tenant-id"),
1549
+ role: parseOptionValue(argv, "--role"),
1550
+ envFile: parseOptionValue(argv, "--env-file"),
1551
+ workspaceRoot,
1552
+ },
1553
+ workspaceRoot,
1554
+ errors,
1555
+ };
1556
+ }
1557
+ case "query": {
1558
+ const subcommand = (rest[0] ?? "list") as QuerySubcommand;
1559
+ if (!["list", "run"].includes(subcommand)) {
1560
+ errors.push("forge query requires subcommand: list or run");
1561
+ return { command: null, workspaceRoot, errors };
1562
+ }
1563
+
1564
+ const queryName = subcommand === "run" ? rest[1] : undefined;
1565
+ if (subcommand === "run" && !queryName) {
1566
+ errors.push("forge query run requires a query name");
1567
+ }
1568
+
1569
+ const argsRaw = parseOptionValue(argv, "--args");
1570
+ let args: unknown = {};
1571
+ if (argsRaw !== undefined) {
1572
+ try {
1573
+ args = JSON.parse(argsRaw);
1574
+ } catch {
1575
+ errors.push("--args must be valid JSON");
1576
+ }
1577
+ }
1578
+
1579
+ return {
1580
+ command: {
1581
+ kind: "query",
1582
+ subcommand,
1583
+ name: queryName,
1584
+ args,
1585
+ json: parseFlag(argv, "--json"),
1586
+ userId: parseOptionValue(argv, "--user-id"),
1587
+ tenantId: parseOptionValue(argv, "--tenant-id"),
1588
+ role: parseOptionValue(argv, "--role"),
1589
+ workspaceRoot,
1590
+ },
1591
+ workspaceRoot,
1592
+ errors,
1593
+ };
1594
+ }
1595
+ case "live": {
1596
+ const requested = rest[0] as LiveSubcommand | undefined;
1597
+ const subcommand =
1598
+ !requested
1599
+ ? "list"
1600
+ : LIVE_SUBCOMMANDS.includes(requested)
1601
+ ? requested
1602
+ : "subscribe";
1603
+ const name =
1604
+ subcommand === "subscribe"
1605
+ ? rest[0]
1606
+ : subcommand === "debug"
1607
+ ? rest[1]
1608
+ : undefined;
1609
+ const argsRaw = parseOptionValue(argv, "--args");
1610
+ let args: unknown = {};
1611
+ if (argsRaw !== undefined) {
1612
+ try {
1613
+ args = JSON.parse(argsRaw);
1614
+ } catch {
1615
+ errors.push("--args must be valid JSON");
1616
+ }
1617
+ }
1618
+
1619
+ return {
1620
+ command: {
1621
+ kind: "live",
1622
+ subcommand,
1623
+ name,
1624
+ args,
1625
+ json: parseFlag(argv, "--json"),
1626
+ userId: parseOptionValue(argv, "--user-id"),
1627
+ tenantId: parseOptionValue(argv, "--tenant-id"),
1628
+ role: parseOptionValue(argv, "--role"),
1629
+ url: parseOptionValue(argv, "--url"),
1630
+ workspaceRoot,
1631
+ },
1632
+ workspaceRoot,
1633
+ errors,
1634
+ };
1635
+ }
1636
+ case "dev": {
1637
+ const portRaw = parseOptionValue(argv, "--port");
1638
+ const port = portRaw !== undefined ? Number(portRaw) : undefined;
1639
+ if (portRaw !== undefined && (!Number.isFinite(port) || port! < 0)) {
1640
+ errors.push("--port must be a non-negative integer");
1641
+ }
1642
+ const webPortRaw = parseOptionValue(argv, "--web-port");
1643
+ const webPort = webPortRaw !== undefined ? Number(webPortRaw) : undefined;
1644
+ if (webPortRaw !== undefined && (!Number.isFinite(webPort) || webPort! < 1)) {
1645
+ errors.push("--web-port must be a positive integer");
1646
+ }
1647
+ const aiMode = parseOptionValue(argv, "--ai");
1648
+ const mockAi =
1649
+ parseFlag(argv, "--mock-ai") || aiMode === "mock" || process.env.FORGE_MOCK_AI === "1";
1650
+ return {
1651
+ command: {
1652
+ kind: "dev",
1653
+ host: parseOptionValue(argv, "--host"),
1654
+ port,
1655
+ mock: parseFlag(argv, "--mock"),
1656
+ mockAi,
1657
+ once: parseFlag(argv, "--once"),
1658
+ watch: !parseFlag(argv, "--no-watch") || parseFlag(argv, "--watch"),
1659
+ json: parseFlag(argv, "--json"),
1660
+ db: parseDbKind(parseOptionValue(argv, "--db")),
1661
+ databaseUrl: parseOptionValue(argv, "--database-url"),
1662
+ worker: !parseFlag(argv, "--no-worker") || parseFlag(argv, "--worker"),
1663
+ withWeb: !parseFlag(argv, "--no-web") && !parseFlag(argv, "--api-only"),
1664
+ apiOnly: parseFlag(argv, "--api-only"),
1665
+ webOnly: parseFlag(argv, "--web-only"),
1666
+ open: parseFlag(argv, "--open"),
1667
+ webPort,
1668
+ telemetry: (parseOptionValue(argv, "--telemetry") ?? "local")
1669
+ .split(",")
1670
+ .map((value) => value.trim())
1671
+ .filter(Boolean),
1672
+ envFile: parseOptionValue(argv, "--env-file"),
1673
+ workspaceRoot,
1674
+ },
1675
+ workspaceRoot,
1676
+ errors,
1677
+ };
1678
+ }
1679
+ case "db": {
1680
+ const subcommand = rest[0] as DbSubcommand | undefined;
1681
+ if (!subcommand || !["diff", "migrate", "reset", "status", "rls-check"].includes(subcommand)) {
1682
+ errors.push("forge db requires subcommand: diff, migrate, reset, status, or rls-check");
1683
+ return { command: null, workspaceRoot, errors };
1684
+ }
1685
+ return {
1686
+ command: {
1687
+ kind: "db",
1688
+ subcommand,
1689
+ db: parseAdapterKind(parseOptionValue(argv, "--db")),
1690
+ databaseUrl: parseOptionValue(argv, "--database-url"),
1691
+ json: parseFlag(argv, "--json"),
1692
+ workspaceRoot,
1693
+ },
1694
+ workspaceRoot,
1695
+ errors,
1696
+ };
1697
+ }
1698
+ case "workflow": {
1699
+ const subcommand = rest[0] as WorkflowSubcommand | undefined;
1700
+ if (
1701
+ !subcommand ||
1702
+ !["list", "run", "inspect", "process", "retry", "cancel"].includes(subcommand)
1703
+ ) {
1704
+ errors.push(
1705
+ "forge workflow requires subcommand: list, run, inspect, process, retry, or cancel",
1706
+ );
1707
+ return { command: null, workspaceRoot, errors };
1708
+ }
1709
+
1710
+ const limitRaw = parseOptionValue(argv, "--limit");
1711
+ const limit = limitRaw !== undefined ? Number(limitRaw) : undefined;
1712
+ if (limitRaw !== undefined && (!Number.isFinite(limit) || limit! < 1)) {
1713
+ errors.push("--limit must be an integer >= 1");
1714
+ }
1715
+
1716
+ const inputRaw = parseOptionValue(argv, "--input");
1717
+ let input: unknown;
1718
+ if (inputRaw !== undefined) {
1719
+ try {
1720
+ input = JSON.parse(inputRaw);
1721
+ } catch {
1722
+ errors.push("--input must be valid JSON");
1723
+ }
1724
+ }
1725
+
1726
+ const stepName = parseOptionValue(argv, "--step");
1727
+ let runId: number | undefined;
1728
+ let workflowName: string | undefined;
1729
+
1730
+ if (subcommand === "run") {
1731
+ workflowName = rest[1];
1732
+ if (!workflowName) {
1733
+ errors.push("forge workflow run requires a workflow name");
1734
+ }
1735
+ } else if (["inspect", "retry", "cancel"].includes(subcommand)) {
1736
+ const runIdRaw = rest[1];
1737
+ runId = runIdRaw !== undefined ? Number(runIdRaw) : undefined;
1738
+ if (runIdRaw !== undefined && !Number.isFinite(runId)) {
1739
+ errors.push("run id must be a number");
1740
+ }
1741
+ if (!runIdRaw) {
1742
+ errors.push(`forge workflow ${subcommand} requires a run id`);
1743
+ }
1744
+ }
1745
+
1746
+ return {
1747
+ command: {
1748
+ kind: "workflow",
1749
+ subcommand,
1750
+ db: parseAdapterKind(parseOptionValue(argv, "--db")),
1751
+ databaseUrl: parseOptionValue(argv, "--database-url"),
1752
+ json: parseFlag(argv, "--json"),
1753
+ once: parseFlag(argv, "--once"),
1754
+ watch: parseFlag(argv, "--watch"),
1755
+ limit,
1756
+ workflowName,
1757
+ runId,
1758
+ stepName,
1759
+ input,
1760
+ mock: parseFlag(argv, "--mock"),
1761
+ workspaceRoot,
1762
+ },
1763
+ workspaceRoot,
1764
+ errors,
1765
+ };
1766
+ }
1767
+ case "outbox": {
1768
+ const subcommand = rest[0] as OutboxSubcommand | undefined;
1769
+ if (
1770
+ !subcommand ||
1771
+ !["list", "process", "retry", "dead", "clear"].includes(subcommand)
1772
+ ) {
1773
+ errors.push(
1774
+ "forge outbox requires subcommand: list, process, retry, dead, or clear",
1775
+ );
1776
+ return { command: null, workspaceRoot, errors };
1777
+ }
1778
+
1779
+ const limitRaw = parseOptionValue(argv, "--limit");
1780
+ const limit = limitRaw !== undefined ? Number(limitRaw) : undefined;
1781
+ if (limitRaw !== undefined && (!Number.isFinite(limit) || limit! < 1)) {
1782
+ errors.push("--limit must be an integer >= 1");
1783
+ }
1784
+
1785
+ const deliveryIdRaw = subcommand === "retry" ? rest[1] : undefined;
1786
+ const deliveryId =
1787
+ deliveryIdRaw !== undefined ? Number(deliveryIdRaw) : undefined;
1788
+ if (deliveryIdRaw !== undefined && !Number.isFinite(deliveryId)) {
1789
+ errors.push("delivery id must be a number");
1790
+ }
1791
+
1792
+ return {
1793
+ command: {
1794
+ kind: "outbox",
1795
+ subcommand,
1796
+ db: parseAdapterKind(parseOptionValue(argv, "--db")),
1797
+ databaseUrl: parseOptionValue(argv, "--database-url"),
1798
+ json: parseFlag(argv, "--json"),
1799
+ once: parseFlag(argv, "--once"),
1800
+ watch: parseFlag(argv, "--watch"),
1801
+ limit,
1802
+ deliveryId,
1803
+ mock: parseFlag(argv, "--mock"),
1804
+ workspaceRoot,
1805
+ },
1806
+ workspaceRoot,
1807
+ errors,
1808
+ };
1809
+ }
1810
+ case "telemetry": {
1811
+ const subcommand = rest[0] as TelemetrySubcommand | undefined;
1812
+ if (
1813
+ !subcommand ||
1814
+ !["list", "inspect", "symbolicate", "flush", "tail", "clear"].includes(subcommand)
1815
+ ) {
1816
+ errors.push(
1817
+ "forge telemetry requires subcommand: list, inspect, symbolicate, flush, tail, or clear",
1818
+ );
1819
+ return { command: null, workspaceRoot, errors };
1820
+ }
1821
+
1822
+ let traceId: string | undefined;
1823
+ if (subcommand === "inspect" || subcommand === "symbolicate") {
1824
+ traceId = rest[1];
1825
+ if (!traceId) {
1826
+ errors.push("forge telemetry inspect requires a trace id");
1827
+ }
1828
+ }
1829
+
1830
+ return {
1831
+ command: {
1832
+ kind: "telemetry",
1833
+ subcommand,
1834
+ db: parseAdapterKind(parseOptionValue(argv, "--db")),
1835
+ databaseUrl: parseOptionValue(argv, "--database-url"),
1836
+ json: parseFlag(argv, "--json"),
1837
+ traceId,
1838
+ sink: parseOptionValue(argv, "--sink"),
1839
+ file: parseOptionValue(argv, "--file") as "events" | "exceptions" | "spans" | undefined,
1840
+ workspaceRoot,
1841
+ },
1842
+ workspaceRoot,
1843
+ errors,
1844
+ };
1845
+ }
1846
+ case "policy": {
1847
+ const subcommand = rest[0] as PolicySubcommand | undefined;
1848
+ if (!subcommand || !["list", "matrix", "simulate", "check"].includes(subcommand)) {
1849
+ errors.push("forge policy requires subcommand: list, matrix, simulate, or check");
1850
+ return { command: null, workspaceRoot, errors };
1851
+ }
1852
+
1853
+ let policyName: string | undefined;
1854
+ if (subcommand === "simulate") {
1855
+ policyName = rest[1];
1856
+ if (!policyName) {
1857
+ errors.push("forge policy simulate requires a policy name");
1858
+ }
1859
+ }
1860
+
1861
+ return {
1862
+ command: {
1863
+ kind: "policy",
1864
+ subcommand,
1865
+ json: parseFlag(argv, "--json"),
1866
+ policy: policyName,
1867
+ role: parseOptionValue(argv, "--role"),
1868
+ strictPolicies: parseFlag(argv, "--strict-policies"),
1869
+ workspaceRoot,
1870
+ },
1871
+ workspaceRoot,
1872
+ errors,
1873
+ };
1874
+ }
1875
+ case "secrets": {
1876
+ const subcommand = rest[0] as SecretsSubcommand | undefined;
1877
+ if (
1878
+ !subcommand ||
1879
+ !["list", "check", "print", "set", "unset"].includes(subcommand)
1880
+ ) {
1881
+ errors.push(
1882
+ "forge secrets requires subcommand: list, check, print, set, or unset",
1883
+ );
1884
+ return { command: null, workspaceRoot, errors };
1885
+ }
1886
+
1887
+ return {
1888
+ command: {
1889
+ kind: "secrets",
1890
+ subcommand,
1891
+ json: parseFlag(argv, "--json"),
1892
+ redacted: parseFlag(argv, "--redacted"),
1893
+ name: subcommand === "set" || subcommand === "unset" ? rest[1] : undefined,
1894
+ value: subcommand === "set" ? rest[2] : undefined,
1895
+ workspaceRoot,
1896
+ },
1897
+ workspaceRoot,
1898
+ errors,
1899
+ };
1900
+ }
1901
+ case "env": {
1902
+ const subcommand = rest[0] as EnvSubcommand | undefined;
1903
+ if (!subcommand || !["list", "check", "print"].includes(subcommand)) {
1904
+ errors.push("forge env requires subcommand: list, check, or print");
1905
+ return { command: null, workspaceRoot, errors };
1906
+ }
1907
+
1908
+ return {
1909
+ command: {
1910
+ kind: "env",
1911
+ subcommand,
1912
+ json: parseFlag(argv, "--json"),
1913
+ redacted: parseFlag(argv, "--redacted"),
1914
+ workspaceRoot,
1915
+ },
1916
+ workspaceRoot,
1917
+ errors,
1918
+ };
1919
+ }
1920
+ case "ai": {
1921
+ const subcommand = rest[0] as AiSubcommand | undefined;
1922
+ if (!subcommand || !["providers", "check", "test", "models"].includes(subcommand)) {
1923
+ errors.push("forge ai requires subcommand: providers, check, test, or models");
1924
+ return { command: null, workspaceRoot, errors };
1925
+ }
1926
+
1927
+ const providerRaw = parseOptionValue(argv, "--provider");
1928
+ const provider = providerRaw as ForgeAiProvider | undefined;
1929
+
1930
+ return {
1931
+ command: {
1932
+ kind: "ai",
1933
+ subcommand,
1934
+ json: parseFlag(argv, "--json"),
1935
+ provider,
1936
+ model: parseOptionValue(argv, "--model"),
1937
+ prompt: parseOptionValue(argv, "--prompt"),
1938
+ mock: parseFlag(argv, "--mock"),
1939
+ workspaceRoot,
1940
+ },
1941
+ workspaceRoot,
1942
+ errors,
1943
+ };
1944
+ }
1945
+ default:
1946
+ errors.push(`unrecognized command '${commandName}'`);
1947
+ return { command: null, workspaceRoot, errors };
1948
+ }
1949
+ }
1950
+
1951
+ export function hasUnknownOption(argv: string[]): string | null {
1952
+ const known = new Set([
1953
+ "--check",
1954
+ "--json",
1955
+ "--dry-run",
1956
+ "--plan",
1957
+ "--staged",
1958
+ "--since",
1959
+ "--feature",
1960
+ "--refactor",
1961
+ "--upgrade",
1962
+ "--include-generated",
1963
+ "--exclude-tests",
1964
+ "--risk-threshold",
1965
+ "--max-cost",
1966
+ "--include-docker",
1967
+ "--include-browser",
1968
+ "--bail",
1969
+ "--report",
1970
+ "--from-last-test-run",
1971
+ "--from-last-ui-run",
1972
+ "--from",
1973
+ "--trace",
1974
+ "--workflow-run",
1975
+ "--outbox-delivery",
1976
+ "--diagnostic",
1977
+ "--repair",
1978
+ "--allow-medium-confidence",
1979
+ "--max-attempts",
1980
+ "--commit-friendly",
1981
+ "--fast",
1982
+ "--smoke",
1983
+ "--standard",
1984
+ "--script-timeout-ms",
1985
+ "--timeout-ms",
1986
+ "--apply",
1987
+ "--runtime-inspect",
1988
+ "--allow-scripts",
1989
+ "--yes",
1990
+ "--force",
1991
+ "--no-generate",
1992
+ "--no-verify",
1993
+ "--keep-failed",
1994
+ "--tenant-scoped",
1995
+ "--field",
1996
+ "--fields",
1997
+ "--type",
1998
+ "--values",
1999
+ "--default",
2000
+ "--index",
2001
+ "--roles",
2002
+ "--table",
2003
+ "--policy",
2004
+ "--emit",
2005
+ "--event",
2006
+ "--trigger",
2007
+ "--component",
2008
+ "--framework",
2009
+ "--package",
2010
+ "--action",
2011
+ "--with-ai",
2012
+ "--with-crud",
2013
+ "--with-livequery",
2014
+ "--with-react",
2015
+ "--with-ui",
2016
+ "--with-tests",
2017
+ "--with-create-form",
2018
+ "--write",
2019
+ "--md",
2020
+ "--sarif",
2021
+ "--fail-on",
2022
+ "--mode",
2023
+ "--include",
2024
+ "--exclude",
2025
+ "--base",
2026
+ "--headed",
2027
+ "--browser",
2028
+ "--trace",
2029
+ "--screenshot",
2030
+ "--video",
2031
+ "--base-url",
2032
+ "--runtime-url",
2033
+ "--reuse-servers",
2034
+ "--start-servers",
2035
+ "--scenario",
2036
+ "--all",
2037
+ "--ci",
2038
+ "--timeout",
2039
+ "--name",
2040
+ "--auth-token",
2041
+ "--update",
2042
+ "--allow-high-risk",
2043
+ "--to",
2044
+ "--changed",
2045
+ "--env",
2046
+ "--input",
2047
+ "--provider",
2048
+ "--target",
2049
+ "--release",
2050
+ "--allow-dirty",
2051
+ "--allow-public-sourcemaps",
2052
+ "--with-release",
2053
+ "--concurrency",
2054
+ "--sandbox-backend",
2055
+ "--skip-tests",
2056
+ "--skip-typecheck",
2057
+ "--skip-eslint",
2058
+ "--mock",
2059
+ "--list",
2060
+ "--port",
2061
+ "--host",
2062
+ "--watch",
2063
+ "--no-watch",
2064
+ "--db",
2065
+ "--database-url",
2066
+ "--worker",
2067
+ "--no-worker",
2068
+ "--once",
2069
+ "--limit",
2070
+ "--input",
2071
+ "--args",
2072
+ "--step",
2073
+ "--sink",
2074
+ "--file",
2075
+ "--telemetry",
2076
+ "--user-id",
2077
+ "--tenant-id",
2078
+ "--role",
2079
+ "--strict-policies",
2080
+ "--strict",
2081
+ "--strict-secrets",
2082
+ "--env-file",
2083
+ "--redacted",
2084
+ "--mock-ai",
2085
+ "--ai",
2086
+ "--provider",
2087
+ "--model",
2088
+ "--prompt",
2089
+ "--url",
2090
+ "--template",
2091
+ "--package-manager",
2092
+ "--forge-spec",
2093
+ "--local-forge",
2094
+ "--install",
2095
+ "--no-install",
2096
+ "--no-git",
2097
+ "--with-web",
2098
+ "--no-web",
2099
+ "--api-only",
2100
+ "--web-only",
2101
+ "--open",
2102
+ "--postgres-version",
2103
+ "--runtime-port",
2104
+ "--web-port",
2105
+ "--poll-interval",
2106
+ "--allow-dev-auth",
2107
+ "--token",
2108
+ "--no-preserve-user-sections",
2109
+ "--no-skills",
2110
+ "--no-rules",
2111
+ ]);
2112
+
2113
+ for (let index = 0; index < argv.length; index++) {
2114
+ const arg = argv[index];
2115
+ if (!arg.startsWith("--")) {
2116
+ continue;
2117
+ }
2118
+ if (known.has(arg)) {
2119
+ if (
2120
+ arg === "--concurrency" ||
2121
+ arg === "--field" ||
2122
+ arg === "--fields" ||
2123
+ arg === "--type" ||
2124
+ arg === "--values" ||
2125
+ arg === "--default" ||
2126
+ arg === "--roles" ||
2127
+ arg === "--table" ||
2128
+ arg === "--policy" ||
2129
+ arg === "--emit" ||
2130
+ arg === "--event" ||
2131
+ arg === "--trigger" ||
2132
+ arg === "--component" ||
2133
+ arg === "--package" ||
2134
+ arg === "--action" ||
2135
+ arg === "--since" ||
2136
+ arg === "--feature" ||
2137
+ arg === "--refactor" ||
2138
+ arg === "--upgrade" ||
2139
+ arg === "--risk-threshold" ||
2140
+ arg === "--max-cost" ||
2141
+ arg === "--report" ||
2142
+ arg === "--from" ||
2143
+ arg === "--trace" ||
2144
+ arg === "--workflow-run" ||
2145
+ arg === "--outbox-delivery" ||
2146
+ arg === "--diagnostic" ||
2147
+ arg === "--repair" ||
2148
+ arg === "--max-attempts" ||
2149
+ arg === "--write" ||
2150
+ arg === "--fail-on" ||
2151
+ arg === "--mode" ||
2152
+ arg === "--include" ||
2153
+ arg === "--exclude" ||
2154
+ arg === "--base" ||
2155
+ arg === "--browser" ||
2156
+ arg === "--trace" ||
2157
+ arg === "--screenshot" ||
2158
+ arg === "--video" ||
2159
+ arg === "--base-url" ||
2160
+ arg === "--runtime-url" ||
2161
+ arg === "--scenario" ||
2162
+ arg === "--timeout" ||
2163
+ arg === "--timeout-ms" ||
2164
+ arg === "--name" ||
2165
+ arg === "--auth-token" ||
2166
+ arg === "--sandbox-backend" ||
2167
+ arg === "--port" ||
2168
+ arg === "--host" ||
2169
+ arg === "--db" ||
2170
+ arg === "--database-url" ||
2171
+ arg === "--limit" ||
2172
+ arg === "--input" ||
2173
+ arg === "--args" ||
2174
+ arg === "--step" ||
2175
+ arg === "--sink" ||
2176
+ arg === "--file" ||
2177
+ arg === "--telemetry" ||
2178
+ arg === "--user-id" ||
2179
+ arg === "--tenant-id" ||
2180
+ arg === "--role" ||
2181
+ arg === "--strict-policies" ||
2182
+ arg === "--env-file" ||
2183
+ arg === "--ai" ||
2184
+ arg === "--provider" ||
2185
+ arg === "--model" ||
2186
+ arg === "--prompt" ||
2187
+ arg === "--url" ||
2188
+ arg === "--template" ||
2189
+ arg === "--package-manager" ||
2190
+ arg === "--forge-spec" ||
2191
+ arg === "--postgres-version" ||
2192
+ arg === "--runtime-port" ||
2193
+ arg === "--web-port" ||
2194
+ arg === "--poll-interval" ||
2195
+ arg === "--token"
2196
+ || arg === "--to" ||
2197
+ arg === "--env" ||
2198
+ arg === "--input" ||
2199
+ arg === "--provider" ||
2200
+ arg === "--target" ||
2201
+ arg === "--release"
2202
+ ) {
2203
+ index += 1;
2204
+ }
2205
+ continue;
2206
+ }
2207
+ return arg;
2208
+ }
2209
+
2210
+ return null;
2211
+ }