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,390 @@
1
+ import { createDiagnostic } from "../../diagnostics/create.ts";
2
+ import {
3
+ FORGE_DB_INVALID_SQL_PLAN,
4
+ FORGE_DB_UNSUPPORTED_FIELD_TYPE,
5
+ } from "../../diagnostics/codes.ts";
6
+ import { hashStable } from "../../primitives/hash.ts";
7
+ import { canonicalJson } from "../../primitives/serialize.ts";
8
+ import type { DataField, DataGraph, DataTable } from "../../types/data-graph.ts";
9
+ import type { Diagnostic } from "../../types/diagnostic.ts";
10
+ import { quoteIdent, toSnakeCase } from "./naming.ts";
11
+ import type { ColumnDef, IndexDef, SqlChange, SqlPlan } from "./types.ts";
12
+
13
+ export const SQL_PLAN_SCHEMA_VERSION = "1.0.0";
14
+
15
+ const SYSTEM_MIGRATIONS_SQL = `CREATE TABLE IF NOT EXISTS _forge_migrations (id text PRIMARY KEY, checksum text NOT NULL, applied_at timestamptz NOT NULL DEFAULT now())`;
16
+
17
+ const SYSTEM_OUTBOX_SQL = `CREATE TABLE IF NOT EXISTS _forge_outbox (id bigserial PRIMARY KEY, event_type text NOT NULL, payload jsonb NOT NULL, auth_context jsonb, created_at timestamptz NOT NULL DEFAULT now())`;
18
+
19
+ const SYSTEM_OUTBOX_DELIVERIES_SQL = `CREATE TABLE IF NOT EXISTS _forge_outbox_deliveries (id bigserial PRIMARY KEY, outbox_id bigint NOT NULL REFERENCES _forge_outbox(id), action_name text NOT NULL, status text NOT NULL DEFAULT 'pending', attempts integer NOT NULL DEFAULT 0, max_attempts integer NOT NULL DEFAULT 5, next_attempt_at timestamptz NOT NULL DEFAULT now(), locked_at timestamptz, locked_by text, last_error text, processed_at timestamptz, created_at timestamptz NOT NULL DEFAULT now(), UNIQUE(outbox_id, action_name))`;
20
+
21
+ const SYSTEM_WORKFLOW_RUNS_SQL = `CREATE TABLE IF NOT EXISTS _forge_workflow_runs (id bigserial PRIMARY KEY, workflow_name text NOT NULL, trigger_type text NOT NULL, trigger_outbox_id bigint, idempotency_key text NOT NULL UNIQUE, input jsonb NOT NULL, auth_context jsonb, status text NOT NULL DEFAULT 'pending', current_step text, last_error text, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), started_at timestamptz, completed_at timestamptz, canceled_at timestamptz)`;
22
+
23
+ const SYSTEM_WORKFLOW_STEPS_SQL = `CREATE TABLE IF NOT EXISTS _forge_workflow_steps (id bigserial PRIMARY KEY, run_id bigint NOT NULL REFERENCES _forge_workflow_runs(id), step_name text NOT NULL, step_index integer NOT NULL, status text NOT NULL DEFAULT 'pending', input jsonb, output jsonb, attempts integer NOT NULL DEFAULT 0, max_attempts integer NOT NULL DEFAULT 5, next_attempt_at timestamptz NOT NULL DEFAULT now(), locked_at timestamptz, locked_by text, last_error text, started_at timestamptz, completed_at timestamptz, created_at timestamptz NOT NULL DEFAULT now(), UNIQUE(run_id, step_name))`;
24
+
25
+ const SYSTEM_TELEMETRY_EVENTS_SQL = `CREATE TABLE IF NOT EXISTS _forge_telemetry_events (id bigserial PRIMARY KEY, trace_id text NOT NULL, event_type text NOT NULL, payload jsonb NOT NULL, status text NOT NULL DEFAULT 'pending', sink text, attempts integer NOT NULL DEFAULT 0, max_attempts integer NOT NULL DEFAULT 5, next_attempt_at timestamptz NOT NULL DEFAULT now(), last_error text, created_at timestamptz NOT NULL DEFAULT now(), processed_at timestamptz)`;
26
+
27
+ const SYSTEM_TRACE_SPANS_SQL = `CREATE TABLE IF NOT EXISTS _forge_trace_spans (id bigserial PRIMARY KEY, trace_id text NOT NULL, parent_span_id text, span_id text NOT NULL, name text NOT NULL, kind text NOT NULL, attributes jsonb NOT NULL DEFAULT '{}', status text NOT NULL DEFAULT 'ok', started_at timestamptz NOT NULL, ended_at timestamptz, error text)`;
28
+
29
+ const SYSTEM_LIVE_REVISION_SEQUENCE_SQL = `CREATE SEQUENCE IF NOT EXISTS _forge_live_revision_seq START WITH 2`;
30
+
31
+ const SYSTEM_LIVE_INVALIDATIONS_SQL = `CREATE TABLE IF NOT EXISTS _forge_live_invalidations (id bigserial PRIMARY KEY, revision bigint NOT NULL, table_name text NOT NULL, tenant_id text, operation text NOT NULL, source_kind text NOT NULL, source_name text, trace_id text, release_id text, deploy_id text, payload jsonb NOT NULL DEFAULT '{}', created_at timestamptz NOT NULL DEFAULT now())`;
32
+
33
+ const SYSTEM_LIVE_SUBSCRIPTION_DEBUG_SQL = `CREATE TABLE IF NOT EXISTS _forge_live_subscription_debug (id text PRIMARY KEY, name text NOT NULL, tenant_id text, dependencies jsonb NOT NULL, last_revision bigint, runtime_id text, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now())`;
34
+
35
+ interface ParsedFieldType {
36
+ sqlType: string;
37
+ references?: { table: string; column: string };
38
+ checkConstraint?: string;
39
+ }
40
+
41
+ function stableSortTables(tables: DataTable[]): DataTable[] {
42
+ return [...tables].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
43
+ }
44
+
45
+ function parseFieldType(
46
+ field: DataField,
47
+ tableName: string,
48
+ diagnostics: Diagnostic[],
49
+ ): ParsedFieldType | null {
50
+ const raw = field.type.trim().toLowerCase();
51
+
52
+ if (raw === "uuid") {
53
+ return { sqlType: "uuid" };
54
+ }
55
+ if (raw === "text" || raw === "string") {
56
+ return { sqlType: "text" };
57
+ }
58
+ if (raw === "number") {
59
+ return { sqlType: "double precision" };
60
+ }
61
+ if (raw === "integer" || raw === "int") {
62
+ return { sqlType: "integer" };
63
+ }
64
+ if (raw === "boolean" || raw === "bool") {
65
+ return { sqlType: "boolean" };
66
+ }
67
+ if (raw === "timestamp") {
68
+ return { sqlType: "timestamptz" };
69
+ }
70
+ if (raw === "json") {
71
+ return { sqlType: "jsonb" };
72
+ }
73
+
74
+ if (raw.startsWith("enum:")) {
75
+ const values = raw
76
+ .slice("enum:".length)
77
+ .split(",")
78
+ .map((value) => value.trim())
79
+ .filter(Boolean);
80
+ if (values.length === 0) {
81
+ diagnostics.push(
82
+ createDiagnostic({
83
+ severity: "error",
84
+ code: FORGE_DB_UNSUPPORTED_FIELD_TYPE,
85
+ message: `unsupported enum field type '${field.type}' on ${tableName}.${field.name}`,
86
+ }),
87
+ );
88
+ return null;
89
+ }
90
+ const checkValues = values.map((value) => `'${value.replace(/'/g, "''")}'`).join(", ");
91
+ return {
92
+ sqlType: "text",
93
+ checkConstraint: `${quoteIdent(toSnakeCase(field.name))} IN (${checkValues})`,
94
+ };
95
+ }
96
+
97
+ if (raw.startsWith("enum_")) {
98
+ return { sqlType: "text" };
99
+ }
100
+
101
+ if (raw.startsWith("ref:")) {
102
+ const refTable = raw.slice("ref:".length).trim();
103
+ if (!refTable) {
104
+ diagnostics.push(
105
+ createDiagnostic({
106
+ severity: "error",
107
+ code: FORGE_DB_UNSUPPORTED_FIELD_TYPE,
108
+ message: `invalid ref field type '${field.type}' on ${tableName}.${field.name}`,
109
+ }),
110
+ );
111
+ return null;
112
+ }
113
+ return {
114
+ sqlType: "uuid",
115
+ references: { table: toSnakeCase(refTable), column: "id" },
116
+ };
117
+ }
118
+
119
+ if (raw === "ref") {
120
+ return {
121
+ sqlType: "uuid",
122
+ references: { table: toSnakeCase(field.name.replace(/Id$/i, "")), column: "id" },
123
+ };
124
+ }
125
+
126
+ diagnostics.push(
127
+ createDiagnostic({
128
+ severity: "error",
129
+ code: FORGE_DB_UNSUPPORTED_FIELD_TYPE,
130
+ message: `unsupported field type '${field.type}' on ${tableName}.${field.name}`,
131
+ }),
132
+ );
133
+ return null;
134
+ }
135
+
136
+ function defaultExprForField(field: DataField): string | undefined {
137
+ const name = field.name;
138
+ const type = field.type.trim().toLowerCase();
139
+
140
+ if (name === "id" && type === "uuid") {
141
+ return "gen_random_uuid()";
142
+ }
143
+
144
+ if (
145
+ (name === "createdAt" || name === "updatedAt") &&
146
+ (type === "timestamp" || type === "timestamptz")
147
+ ) {
148
+ return "now()";
149
+ }
150
+
151
+ return undefined;
152
+ }
153
+
154
+ function buildColumns(table: DataTable, diagnostics: Diagnostic[]): ColumnDef[] {
155
+ const columns: ColumnDef[] = [];
156
+ const fields = [...table.fields].sort((a, b) =>
157
+ a.name < b.name ? -1 : a.name > b.name ? 1 : 0,
158
+ );
159
+
160
+ const hasIdField = fields.some((field) => field.name === "id");
161
+ if (!hasIdField) {
162
+ columns.push({
163
+ name: "id",
164
+ fieldName: "id",
165
+ sqlType: "uuid",
166
+ nullable: false,
167
+ primaryKey: true,
168
+ defaultExpr: "gen_random_uuid()",
169
+ });
170
+ }
171
+
172
+ for (const field of fields) {
173
+ const parsed = parseFieldType(field, table.name, diagnostics);
174
+ if (!parsed) {
175
+ continue;
176
+ }
177
+
178
+ const snakeName = toSnakeCase(field.name);
179
+ const defaultExpr = defaultExprForField(field);
180
+ const isPrimaryKey = field.name === "id" && parsed.sqlType === "uuid";
181
+
182
+ columns.push({
183
+ name: snakeName,
184
+ fieldName: field.name,
185
+ sqlType: parsed.sqlType,
186
+ nullable: false,
187
+ primaryKey: isPrimaryKey,
188
+ defaultExpr,
189
+ references: parsed.references,
190
+ checkConstraint: parsed.checkConstraint,
191
+ });
192
+ }
193
+
194
+ if (!columns.some((column) => column.primaryKey) && columns.length > 0) {
195
+ columns[0]!.primaryKey = true;
196
+ }
197
+
198
+ return columns;
199
+ }
200
+
201
+ function renderColumn(column: ColumnDef): string {
202
+ const parts = [
203
+ quoteIdent(column.name),
204
+ column.sqlType,
205
+ column.nullable ? "" : "NOT NULL",
206
+ column.defaultExpr ? `DEFAULT ${column.defaultExpr}` : "",
207
+ column.primaryKey ? "PRIMARY KEY" : "",
208
+ column.references
209
+ ? `REFERENCES ${quoteIdent(column.references.table)} (${quoteIdent(column.references.column)})`
210
+ : "",
211
+ column.checkConstraint ? `CHECK (${column.checkConstraint})` : "",
212
+ ].filter((part) => part.length > 0);
213
+
214
+ return parts.join(" ");
215
+ }
216
+
217
+ function buildCreateTableSql(tableName: string, columns: ColumnDef[]): string {
218
+ const rendered = columns.map(renderColumn).join(", ");
219
+ return `CREATE TABLE IF NOT EXISTS ${quoteIdent(tableName)} (${rendered})`;
220
+ }
221
+
222
+ function buildForeignKeyIndexes(tableName: string, columns: ColumnDef[]): IndexDef[] {
223
+ const indexes: IndexDef[] = [];
224
+
225
+ for (const column of columns) {
226
+ if (column.references) {
227
+ indexes.push({
228
+ name: `idx_${tableName}_${column.name}`,
229
+ table: tableName,
230
+ columns: [column.name],
231
+ });
232
+ }
233
+ }
234
+
235
+ return indexes;
236
+ }
237
+
238
+ function buildTableChange(table: DataTable, diagnostics: Diagnostic[]): SqlChange | null {
239
+ const tableName = toSnakeCase(table.name);
240
+ const columns = buildColumns(table, diagnostics);
241
+
242
+ if (columns.length === 0) {
243
+ diagnostics.push(
244
+ createDiagnostic({
245
+ severity: "error",
246
+ code: FORGE_DB_INVALID_SQL_PLAN,
247
+ message: `table '${table.name}' has no valid columns`,
248
+ file: table.file,
249
+ }),
250
+ );
251
+ return null;
252
+ }
253
+
254
+ return {
255
+ kind: "create_table",
256
+ table: tableName,
257
+ columns,
258
+ sql: buildCreateTableSql(tableName, columns),
259
+ };
260
+ }
261
+
262
+ function buildIndexChange(index: IndexDef): SqlChange {
263
+ const columns = index.columns.map(quoteIdent).join(", ");
264
+ const unique = index.unique ? "UNIQUE " : "";
265
+ return {
266
+ kind: "create_index",
267
+ table: index.table,
268
+ index,
269
+ sql: `CREATE INDEX IF NOT EXISTS ${quoteIdent(index.name)} ON ${quoteIdent(index.table)} ${unique}(${columns})`,
270
+ };
271
+ }
272
+
273
+ export function buildSqlPlan(dataGraph: DataGraph): SqlPlan {
274
+ const diagnostics: Diagnostic[] = [];
275
+ const tables: SqlChange[] = [];
276
+ const indexes: SqlChange[] = [];
277
+
278
+ const systemTables: SqlChange[] = [
279
+ {
280
+ kind: "create_table",
281
+ table: "_forge_migrations",
282
+ sql: SYSTEM_MIGRATIONS_SQL,
283
+ },
284
+ {
285
+ kind: "create_table",
286
+ table: "_forge_outbox",
287
+ sql: SYSTEM_OUTBOX_SQL,
288
+ },
289
+ {
290
+ kind: "create_table",
291
+ table: "_forge_outbox_deliveries",
292
+ sql: SYSTEM_OUTBOX_DELIVERIES_SQL,
293
+ },
294
+ {
295
+ kind: "create_table",
296
+ table: "_forge_workflow_runs",
297
+ sql: SYSTEM_WORKFLOW_RUNS_SQL,
298
+ },
299
+ {
300
+ kind: "create_table",
301
+ table: "_forge_workflow_steps",
302
+ sql: SYSTEM_WORKFLOW_STEPS_SQL,
303
+ },
304
+ {
305
+ kind: "create_table",
306
+ table: "_forge_telemetry_events",
307
+ sql: SYSTEM_TELEMETRY_EVENTS_SQL,
308
+ },
309
+ {
310
+ kind: "create_table",
311
+ table: "_forge_trace_spans",
312
+ sql: SYSTEM_TRACE_SPANS_SQL,
313
+ },
314
+ {
315
+ kind: "create_sequence",
316
+ table: "_forge_live_revision_seq",
317
+ sql: SYSTEM_LIVE_REVISION_SEQUENCE_SQL,
318
+ },
319
+ {
320
+ kind: "create_table",
321
+ table: "_forge_live_invalidations",
322
+ sql: SYSTEM_LIVE_INVALIDATIONS_SQL,
323
+ },
324
+ {
325
+ kind: "create_table",
326
+ table: "_forge_live_subscription_debug",
327
+ sql: SYSTEM_LIVE_SUBSCRIPTION_DEBUG_SQL,
328
+ },
329
+ ];
330
+
331
+ for (const table of stableSortTables(dataGraph.tables)) {
332
+ const change = buildTableChange(table, diagnostics);
333
+ if (!change) {
334
+ continue;
335
+ }
336
+ tables.push(change);
337
+
338
+ if (change.columns) {
339
+ for (const index of buildForeignKeyIndexes(change.table!, change.columns)) {
340
+ indexes.push(buildIndexChange(index));
341
+ }
342
+ }
343
+ }
344
+
345
+ indexes.sort((a, b) => {
346
+ const nameA = a.index?.name ?? "";
347
+ const nameB = b.index?.name ?? "";
348
+ return nameA < nameB ? -1 : nameA > nameB ? 1 : 0;
349
+ });
350
+
351
+ indexes.push(
352
+ buildIndexChange({
353
+ name: "forge_live_invalidations_revision_idx",
354
+ table: "_forge_live_invalidations",
355
+ columns: ["revision"],
356
+ }),
357
+ buildIndexChange({
358
+ name: "forge_live_invalidations_table_tenant_revision_idx",
359
+ table: "_forge_live_invalidations",
360
+ columns: ["table_name", "tenant_id", "revision"],
361
+ }),
362
+ );
363
+
364
+ const payload = {
365
+ schemaVersion: SQL_PLAN_SCHEMA_VERSION,
366
+ systemTables: systemTables.map((change) => change.sql),
367
+ tables: tables.map((change) => change.sql),
368
+ indexes: indexes.map((change) => change.sql),
369
+ };
370
+
371
+ const checksum = hashStable(canonicalJson(payload));
372
+ const migrationId = `migration_${checksum.slice(0, 16)}`;
373
+
374
+ return {
375
+ schemaVersion: SQL_PLAN_SCHEMA_VERSION,
376
+ migrationId,
377
+ checksum,
378
+ systemTables,
379
+ tables,
380
+ indexes,
381
+ diagnostics: diagnostics.sort((a, b) => {
382
+ const fileA = a.file ?? "";
383
+ const fileB = b.file ?? "";
384
+ if (fileA !== fileB) {
385
+ return fileA < fileB ? -1 : 1;
386
+ }
387
+ return a.message < b.message ? -1 : a.message > b.message ? 1 : 0;
388
+ }),
389
+ };
390
+ }
@@ -0,0 +1,10 @@
1
+ export function toSnakeCase(name: string): string {
2
+ return name
3
+ .replace(/([a-z0-9])([A-Z])/g, "$1_$2")
4
+ .replace(/[-\s]+/g, "_")
5
+ .toLowerCase();
6
+ }
7
+
8
+ export function quoteIdent(ident: string): string {
9
+ return `"${ident.replace(/"/g, '""')}"`;
10
+ }
@@ -0,0 +1,85 @@
1
+ import { serializeCanonical } from "../../primitives/serialize.ts";
2
+ import type { SqlPlan } from "./types.ts";
3
+ import type { TenantScope } from "../../types/policy-registry.ts";
4
+
5
+ export function serializeSqlPlanJson(plan: SqlPlan): string {
6
+ const payload = {
7
+ schemaVersion: plan.schemaVersion,
8
+ migrationId: plan.migrationId,
9
+ checksum: plan.checksum,
10
+ systemTables: plan.systemTables.map((change) => ({
11
+ kind: change.kind,
12
+ table: change.table,
13
+ sql: change.sql,
14
+ })),
15
+ tables: plan.tables.map((change) => ({
16
+ kind: change.kind,
17
+ table: change.table,
18
+ columns: change.columns,
19
+ sql: change.sql,
20
+ })),
21
+ indexes: plan.indexes.map((change) => ({
22
+ kind: change.kind,
23
+ table: change.table,
24
+ index: change.index,
25
+ sql: change.sql,
26
+ })),
27
+ diagnostics: plan.diagnostics,
28
+ };
29
+ return serializeCanonical(payload);
30
+ }
31
+
32
+ export function serializeSqlPlanTs(plan: SqlPlan): string {
33
+ const parsed: unknown = JSON.parse(serializeSqlPlanJson(plan).trimEnd());
34
+ return `export const sqlPlan = ${JSON.stringify(parsed, null, 2)} as const;\n`;
35
+ }
36
+
37
+ export interface TableMapEntry {
38
+ tableName: string;
39
+ columns: { name: string; fieldName?: string; sqlType: string; primaryKey?: boolean }[];
40
+ tenantScoped?: boolean;
41
+ tenantIdColumn?: string;
42
+ }
43
+
44
+ export function buildTableMap(
45
+ plan: SqlPlan,
46
+ tenantScope?: TenantScope,
47
+ ): Record<string, TableMapEntry> {
48
+ const map: Record<string, TableMapEntry> = {};
49
+ const scopeByTable = new Map(
50
+ (tenantScope?.tables ?? []).map((entry) => [entry.table, entry.tenantIdColumn]),
51
+ );
52
+
53
+ for (const change of plan.tables) {
54
+ if (!change.table || !change.columns) {
55
+ continue;
56
+ }
57
+ const tenantIdColumn = scopeByTable.get(change.table);
58
+ map[change.table] = {
59
+ tableName: change.table,
60
+ columns: change.columns.map((column) => ({
61
+ name: column.name,
62
+ ...(column.fieldName && column.fieldName !== column.name
63
+ ? { fieldName: column.fieldName }
64
+ : {}),
65
+ sqlType: column.sqlType,
66
+ ...(column.primaryKey ? { primaryKey: true } : {}),
67
+ })),
68
+ ...(tenantIdColumn
69
+ ? { tenantScoped: true, tenantIdColumn }
70
+ : {}),
71
+ };
72
+ }
73
+
74
+ return map;
75
+ }
76
+
77
+ export function serializeDbJson(plan: SqlPlan, tenantScope?: TenantScope): string {
78
+ const tableMap = buildTableMap(plan, tenantScope);
79
+ return serializeCanonical({ tableMap });
80
+ }
81
+
82
+ export function serializeDbTs(plan: SqlPlan, tenantScope?: TenantScope): string {
83
+ const tableMap = buildTableMap(plan, tenantScope);
84
+ return `export const tableMap = ${JSON.stringify(tableMap, null, 2)} as const;\n`;
85
+ }
@@ -0,0 +1,37 @@
1
+ import type { Diagnostic } from "../../types/diagnostic.ts";
2
+
3
+ export interface ColumnDef {
4
+ name: string;
5
+ fieldName?: string;
6
+ sqlType: string;
7
+ nullable: boolean;
8
+ primaryKey?: boolean;
9
+ defaultExpr?: string;
10
+ references?: { table: string; column: string };
11
+ checkConstraint?: string;
12
+ }
13
+
14
+ export interface IndexDef {
15
+ name: string;
16
+ table: string;
17
+ columns: string[];
18
+ unique?: boolean;
19
+ }
20
+
21
+ export interface SqlChange {
22
+ kind: "create_table" | "create_index" | "create_sequence";
23
+ table?: string;
24
+ columns?: ColumnDef[];
25
+ index?: IndexDef;
26
+ sql: string;
27
+ }
28
+
29
+ export interface SqlPlan {
30
+ schemaVersion: string;
31
+ migrationId: string;
32
+ checksum: string;
33
+ systemTables: SqlChange[];
34
+ tables: SqlChange[];
35
+ indexes: SqlChange[];
36
+ diagnostics: Diagnostic[];
37
+ }
@@ -0,0 +1,170 @@
1
+ import { GENERATOR_VERSION } from "../emitter/constants.ts";
2
+ import { hashStable } from "../primitives/hash.ts";
3
+ import { canonicalJson } from "../primitives/serialize.ts";
4
+ import type { AppGraph } from "../types/app-graph.ts";
5
+ import type {
6
+ DevManifest,
7
+ DevManifestEntry,
8
+ DevManifestWorkflow,
9
+ DevRoute,
10
+ } from "../types/dev-manifest.ts";
11
+ import type { RuntimeGraph } from "../types/runtime-graph.ts";
12
+ import type { QueryRegistry } from "../types/query-registry.ts";
13
+ import {
14
+ DEV_MANIFEST_ANALYZER_VERSION,
15
+ DEV_MANIFEST_SCHEMA_VERSION,
16
+ } from "./constants.ts";
17
+
18
+ function stableSortRoutes(routes: DevRoute[]): DevRoute[] {
19
+ return [...routes].sort((a, b) => {
20
+ if (a.path !== b.path) {
21
+ return a.path < b.path ? -1 : 1;
22
+ }
23
+ if (a.method !== b.method) {
24
+ return a.method < b.method ? -1 : 1;
25
+ }
26
+ const nameA = a.entryName ?? "";
27
+ const nameB = b.entryName ?? "";
28
+ if (nameA !== nameB) {
29
+ return nameA < nameB ? -1 : 1;
30
+ }
31
+ return 0;
32
+ });
33
+ }
34
+
35
+ function stableSortEntries(entries: DevManifestEntry[]): DevManifestEntry[] {
36
+ return [...entries].sort((a, b) => {
37
+ if (a.name !== b.name) {
38
+ return a.name < b.name ? -1 : 1;
39
+ }
40
+ return a.kind < b.kind ? -1 : a.kind > b.kind ? 1 : 0;
41
+ });
42
+ }
43
+
44
+ function stableSortWorkflows(
45
+ workflows: DevManifestWorkflow[],
46
+ ): DevManifestWorkflow[] {
47
+ return [...workflows].sort((a, b) => {
48
+ if (a.name !== b.name) {
49
+ return a.name < b.name ? -1 : 1;
50
+ }
51
+ return a.file < b.file ? -1 : a.file > b.file ? 1 : 0;
52
+ });
53
+ }
54
+
55
+ function buildRoutes(
56
+ runtimeGraph: RuntimeGraph,
57
+ queryRegistry: QueryRegistry,
58
+ ): DevRoute[] {
59
+ const routes: DevRoute[] = [
60
+ { method: "GET", path: "/", purpose: "home" },
61
+ { method: "GET", path: "/health", purpose: "health" },
62
+ { method: "GET", path: "/entries", purpose: "entries" },
63
+ { method: "GET", path: "/queries", purpose: "queries" },
64
+ { method: "GET", path: "/workflows", purpose: "workflows" },
65
+ { method: "GET", path: "/workflows/runs", purpose: "workflow-runs" },
66
+ { method: "POST", path: "/workflows/process", purpose: "workflow-process" },
67
+ ];
68
+
69
+ for (const query of queryRegistry.queries) {
70
+ routes.push({
71
+ method: "POST",
72
+ path: `/queries/${query.name}`,
73
+ purpose: "query",
74
+ entryName: query.name,
75
+ entryKind: "query",
76
+ });
77
+ }
78
+
79
+ for (const entry of runtimeGraph.entries) {
80
+ routes.push({
81
+ method: "POST",
82
+ path: `/run/${entry.name}`,
83
+ purpose: "invoke",
84
+ entryName: entry.name,
85
+ entryKind: entry.kind,
86
+ });
87
+
88
+ if (entry.kind === "command") {
89
+ routes.push({
90
+ method: "POST",
91
+ path: `/commands/${entry.name}`,
92
+ purpose: "invoke",
93
+ entryName: entry.name,
94
+ entryKind: "command",
95
+ });
96
+ } else {
97
+ routes.push({
98
+ method: "POST",
99
+ path: `/actions/${entry.name}`,
100
+ purpose: "invoke",
101
+ entryName: entry.name,
102
+ entryKind: "action",
103
+ });
104
+ }
105
+ }
106
+
107
+ return stableSortRoutes(routes);
108
+ }
109
+
110
+ function buildEntries(
111
+ runtimeGraph: RuntimeGraph,
112
+ queryRegistry: QueryRegistry,
113
+ ): DevManifestEntry[] {
114
+ const queryEntries = queryRegistry.queries.map((query) => ({
115
+ name: query.name,
116
+ kind: "query" as const,
117
+ invokePath: `/queries/${query.name}`,
118
+ semanticPath: `/queries/${query.name}`,
119
+ }));
120
+
121
+ const entries = runtimeGraph.entries.map((entry) => ({
122
+ name: entry.name,
123
+ kind: entry.kind,
124
+ invokePath: `/run/${entry.name}`,
125
+ semanticPath:
126
+ entry.kind === "command"
127
+ ? `/commands/${entry.name}`
128
+ : `/actions/${entry.name}`,
129
+ }));
130
+
131
+ return stableSortEntries([...queryEntries, ...entries]);
132
+ }
133
+
134
+ function buildWorkflows(appGraph?: AppGraph): DevManifestWorkflow[] {
135
+ if (!appGraph) {
136
+ return [];
137
+ }
138
+
139
+ const workflows = appGraph.symbols
140
+ .filter((symbol) => symbol.kind === "workflow")
141
+ .map((symbol) => ({
142
+ name: symbol.name,
143
+ file: symbol.file,
144
+ }));
145
+
146
+ return stableSortWorkflows(workflows);
147
+ }
148
+
149
+ export function buildDevManifest(
150
+ runtimeGraph: RuntimeGraph,
151
+ queryRegistry: QueryRegistry,
152
+ appGraph?: AppGraph,
153
+ ): DevManifest {
154
+ return {
155
+ schemaVersion: DEV_MANIFEST_SCHEMA_VERSION,
156
+ generatorVersion: GENERATOR_VERSION,
157
+ analyzerVersion: DEV_MANIFEST_ANALYZER_VERSION,
158
+ inputHash: hashStable(
159
+ canonicalJson({
160
+ runtimeInputHash: runtimeGraph.inputHash,
161
+ queryInputHash: queryRegistry.inputHash,
162
+ analyzerVersion: DEV_MANIFEST_ANALYZER_VERSION,
163
+ }),
164
+ ),
165
+ routes: buildRoutes(runtimeGraph, queryRegistry),
166
+ entries: buildEntries(runtimeGraph, queryRegistry),
167
+ workflows: buildWorkflows(appGraph),
168
+ diagnostics: [...runtimeGraph.diagnostics, ...queryRegistry.diagnostics],
169
+ };
170
+ }
@@ -0,0 +1,5 @@
1
+ /** DevManifest model schema version. */
2
+ export const DEV_MANIFEST_SCHEMA_VERSION = "1.0.0";
3
+
4
+ /** DevManifest route / analyzer version. */
5
+ export const DEV_MANIFEST_ANALYZER_VERSION = "0.1.0";