forgeos 0.1.0-alpha.2 → 0.1.0-alpha.21

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 (406) hide show
  1. package/.npmignore +4 -0
  2. package/AGENTS.md +168 -81
  3. package/CHANGELOG.md +211 -0
  4. package/README.md +88 -14
  5. package/adapters/go/README.md +23 -0
  6. package/adapters/go/go.mod +3 -0
  7. package/adapters/go/http.go +149 -0
  8. package/adapters/go/registry.go +234 -0
  9. package/adapters/go/types.go +136 -0
  10. package/adapters/java/README.md +68 -0
  11. package/adapters/java/pom.xml +34 -0
  12. package/adapters/java/src/main/java/dev/forgeos/adapter/Auth.java +20 -0
  13. package/adapters/java/src/main/java/dev/forgeos/adapter/Diagnostic.java +16 -0
  14. package/adapters/java/src/main/java/dev/forgeos/adapter/Entry.java +38 -0
  15. package/adapters/java/src/main/java/dev/forgeos/adapter/EntryKind.java +16 -0
  16. package/adapters/java/src/main/java/dev/forgeos/adapter/ErrorInfo.java +4 -0
  17. package/adapters/java/src/main/java/dev/forgeos/adapter/Forge.java +94 -0
  18. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeCall.java +12 -0
  19. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeContext.java +11 -0
  20. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHandler.java +8 -0
  21. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHttpHandler.java +179 -0
  22. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeRegistry.java +121 -0
  23. package/adapters/java/src/main/java/dev/forgeos/adapter/Json.java +14 -0
  24. package/adapters/java/src/main/java/dev/forgeos/adapter/Manifest.java +14 -0
  25. package/adapters/java/src/main/java/dev/forgeos/adapter/RequestEnvelope.java +6 -0
  26. package/adapters/java/src/main/java/dev/forgeos/adapter/ResponseEnvelope.java +25 -0
  27. package/adapters/java/src/main/java/dev/forgeos/adapter/Risk.java +18 -0
  28. package/adapters/java/src/main/java/dev/forgeos/adapter/Schemas.java +36 -0
  29. package/adapters/java/src/main/java/dev/forgeos/adapter/Service.java +65 -0
  30. package/adapters/java/src/main/java/dev/forgeos/adapter/TransactionMode.java +18 -0
  31. package/adapters/java/src/main/java/dev/forgeos/adapter/TypedForgeHandler.java +6 -0
  32. package/adapters/java/target/classes/dev/forgeos/adapter/Auth.class +0 -0
  33. package/adapters/java/target/classes/dev/forgeos/adapter/Diagnostic.class +0 -0
  34. package/adapters/java/target/classes/dev/forgeos/adapter/Entry.class +0 -0
  35. package/adapters/java/target/classes/dev/forgeos/adapter/EntryKind.class +0 -0
  36. package/adapters/java/target/classes/dev/forgeos/adapter/ErrorInfo.class +0 -0
  37. package/adapters/java/target/classes/dev/forgeos/adapter/Forge.class +0 -0
  38. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeCall.class +0 -0
  39. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeContext.class +0 -0
  40. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeHandler.class +0 -0
  41. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeHttpHandler.class +0 -0
  42. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeRegistry$EntryOption.class +0 -0
  43. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeRegistry$RegisteredEntry.class +0 -0
  44. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeRegistry$RegistryOption.class +0 -0
  45. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeRegistry.class +0 -0
  46. package/adapters/java/target/classes/dev/forgeos/adapter/Json.class +0 -0
  47. package/adapters/java/target/classes/dev/forgeos/adapter/Manifest.class +0 -0
  48. package/adapters/java/target/classes/dev/forgeos/adapter/RequestEnvelope.class +0 -0
  49. package/adapters/java/target/classes/dev/forgeos/adapter/ResponseEnvelope.class +0 -0
  50. package/adapters/java/target/classes/dev/forgeos/adapter/Risk.class +0 -0
  51. package/adapters/java/target/classes/dev/forgeos/adapter/Schemas.class +0 -0
  52. package/adapters/java/target/classes/dev/forgeos/adapter/Service.class +0 -0
  53. package/adapters/java/target/classes/dev/forgeos/adapter/TransactionMode.class +0 -0
  54. package/adapters/java/target/classes/dev/forgeos/adapter/TypedForgeHandler.class +0 -0
  55. package/adapters/java/target/forge-java-adapter-0.1.0-alpha.11.jar +0 -0
  56. package/adapters/java/target/maven-archiver/pom.properties +3 -0
  57. package/adapters/java/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +23 -0
  58. package/adapters/java/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +20 -0
  59. package/adapters/java-spring-boot-starter/README.md +32 -0
  60. package/adapters/java-spring-boot-starter/pom.xml +36 -0
  61. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeCommand.java +22 -0
  62. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeExternalService.java +15 -0
  63. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeQuery.java +16 -0
  64. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeServiceBeanCondition.java +18 -0
  65. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringAutoConfiguration.java +16 -0
  66. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringRuntime.java +104 -0
  67. package/adapters/java-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +1 -0
  68. package/adapters/java-spring-boot-starter/target/classes/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +1 -0
  69. package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeCommand.class +0 -0
  70. package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeExternalService.class +0 -0
  71. package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeQuery.class +0 -0
  72. package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeServiceBeanCondition.class +0 -0
  73. package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeSpringAutoConfiguration.class +0 -0
  74. package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeSpringRuntime.class +0 -0
  75. package/adapters/java-spring-boot-starter/target/forge-java-spring-boot-starter-0.1.0-alpha.11.jar +0 -0
  76. package/adapters/java-spring-boot-starter/target/maven-archiver/pom.properties +3 -0
  77. package/adapters/java-spring-boot-starter/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +6 -0
  78. package/adapters/java-spring-boot-starter/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +6 -0
  79. package/bin/forge.mjs +18 -0
  80. package/docs/changelog.md +242 -0
  81. package/docs/forge-protocol.md +189 -0
  82. package/examples/go-billing/go.mod +7 -0
  83. package/examples/go-billing/main.go +120 -0
  84. package/examples/java-billing/pom.xml +52 -0
  85. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/CreateInvoiceInput.java +4 -0
  86. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Invoice.java +11 -0
  87. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Main.java +127 -0
  88. package/examples/java-billing/target/classes/dev/forgeos/examples/billing/CreateInvoiceInput.class +0 -0
  89. package/examples/java-billing/target/classes/dev/forgeos/examples/billing/Invoice.class +0 -0
  90. package/examples/java-billing/target/classes/dev/forgeos/examples/billing/Main$EmptyInput.class +0 -0
  91. package/examples/java-billing/target/classes/dev/forgeos/examples/billing/Main$Options.class +0 -0
  92. package/examples/java-billing/target/classes/dev/forgeos/examples/billing/Main.class +0 -0
  93. package/examples/java-billing/target/java-billing-0.1.0-alpha.11-all.jar +0 -0
  94. package/examples/java-billing/target/java-billing-0.1.0-alpha.11.jar +0 -0
  95. package/examples/java-billing/target/maven-archiver/pom.properties +3 -0
  96. package/examples/java-billing/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +5 -0
  97. package/examples/java-billing/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +3 -0
  98. package/package.json +29 -7
  99. package/schemas/forge-manifest.schema.json +57 -0
  100. package/src/forge/_generated/releaseManifest.json +1 -2
  101. package/src/forge/_generated/releaseManifest.ts +3 -3
  102. package/src/forge/agent-adapters/index.ts +1511 -123
  103. package/src/forge/agent-adapters/types.ts +216 -1
  104. package/src/forge/agent-memory/bridge.ts +1245 -0
  105. package/src/forge/agent-memory/context-pack.ts +151 -0
  106. package/src/forge/agent-memory/hook-runner.ts +312 -0
  107. package/src/forge/agent-memory/mcp.ts +224 -0
  108. package/src/forge/agent-memory/normalize.ts +498 -0
  109. package/src/forge/agent-memory/redaction.ts +103 -0
  110. package/src/forge/agent-memory/sources/claude-code.ts +51 -0
  111. package/src/forge/agent-memory/sources/codex-hook-runner.mjs +273 -0
  112. package/src/forge/agent-memory/sources/codex.ts +119 -0
  113. package/src/forge/agent-memory/sources/cursor.ts +35 -0
  114. package/src/forge/agent-memory/types.ts +191 -0
  115. package/src/forge/bench.ts +248 -0
  116. package/src/forge/brownfield-import/index.ts +801 -0
  117. package/src/forge/brownfield-import/types.ts +127 -0
  118. package/src/forge/cair/action-journal.ts +61 -0
  119. package/src/forge/cair/action-parser.ts +314 -0
  120. package/src/forge/cair/action-validator.ts +40 -0
  121. package/src/forge/cair/actions.ts +1818 -0
  122. package/src/forge/cair/format.ts +77 -0
  123. package/src/forge/cair/index.ts +106 -0
  124. package/src/forge/cair/query.ts +478 -0
  125. package/src/forge/cair/snapshot.ts +315 -0
  126. package/src/forge/cair/types.ts +248 -0
  127. package/src/forge/cli/ai.ts +671 -3
  128. package/src/forge/cli/auth.ts +36 -1
  129. package/src/forge/cli/build.ts +20 -4
  130. package/src/forge/cli/changed.ts +300 -0
  131. package/src/forge/cli/codex-app-server.ts +877 -0
  132. package/src/forge/cli/commands.ts +1285 -7
  133. package/src/forge/cli/db.ts +121 -2
  134. package/src/forge/cli/deps.ts +79 -12
  135. package/src/forge/cli/dev.ts +502 -38
  136. package/src/forge/cli/docs.ts +265 -0
  137. package/src/forge/cli/handoff.ts +250 -0
  138. package/src/forge/cli/index.ts +1 -0
  139. package/src/forge/cli/main.ts +49 -3
  140. package/src/forge/cli/new.ts +3 -1
  141. package/src/forge/cli/next-actions.ts +23 -0
  142. package/src/forge/cli/output.ts +290 -1
  143. package/src/forge/cli/parse.ts +770 -36
  144. package/src/forge/cli/query.ts +32 -0
  145. package/src/forge/cli/release.ts +35 -11
  146. package/src/forge/cli/rls.ts +568 -17
  147. package/src/forge/cli/run.ts +41 -0
  148. package/src/forge/cli/secrets.ts +46 -1
  149. package/src/forge/cli/security.ts +381 -0
  150. package/src/forge/cli/self-host.ts +56 -14
  151. package/src/forge/cli/studio.ts +2163 -0
  152. package/src/forge/cli/verify.ts +1422 -32
  153. package/src/forge/compiler/agent-contract/build.ts +725 -41
  154. package/src/forge/compiler/agent-contract/types.ts +85 -0
  155. package/src/forge/compiler/ai-registry/build.ts +62 -1
  156. package/src/forge/compiler/ai-registry/constants.ts +1 -1
  157. package/src/forge/compiler/ai-registry/parse.ts +168 -5
  158. package/src/forge/compiler/api-surface/build.ts +47 -0
  159. package/src/forge/compiler/app-graph/build.ts +68 -8
  160. package/src/forge/compiler/app-graph/extract.ts +107 -0
  161. package/src/forge/compiler/app-graph/forge-apis.ts +1 -0
  162. package/src/forge/compiler/app-graph/module-graph.ts +73 -78
  163. package/src/forge/compiler/app-graph/parser.ts +24 -24
  164. package/src/forge/compiler/app-graph/profile.ts +26 -0
  165. package/src/forge/compiler/app-graph/versions.ts +1 -1
  166. package/src/forge/compiler/classifier/capabilities.ts +3 -2
  167. package/src/forge/compiler/classifier/classify.ts +32 -8
  168. package/src/forge/compiler/classifier/secrets.ts +3 -2
  169. package/src/forge/compiler/classifier/signals.ts +91 -1
  170. package/src/forge/compiler/client-sdk/build-manifest.ts +59 -0
  171. package/src/forge/compiler/client-sdk/render-client.ts +188 -13
  172. package/src/forge/compiler/data-graph/parse.ts +3 -3
  173. package/src/forge/compiler/data-graph/sql/ddl.ts +60 -2
  174. package/src/forge/compiler/data-graph/sql/serialize.ts +4 -0
  175. package/src/forge/compiler/data-graph/sql/types.ts +1 -0
  176. package/src/forge/compiler/dev-manifest/build.ts +3 -0
  177. package/src/forge/compiler/diagnostics/codes.ts +35 -0
  178. package/src/forge/compiler/diagnostics/create.ts +8 -3
  179. package/src/forge/compiler/diagnostics/index.ts +2 -0
  180. package/src/forge/compiler/emitter/barrel.ts +3 -0
  181. package/src/forge/compiler/emitter/render.ts +5 -0
  182. package/src/forge/compiler/external-manifest/registry.ts +205 -0
  183. package/src/forge/compiler/external-manifest/types.ts +91 -0
  184. package/src/forge/compiler/external-manifest/validate.ts +373 -0
  185. package/src/forge/compiler/frontend-graph/build.ts +85 -13
  186. package/src/forge/compiler/integration/add.ts +498 -22
  187. package/src/forge/compiler/integration/snapshot.ts +2 -0
  188. package/src/forge/compiler/make-registry/build.ts +19 -7
  189. package/src/forge/compiler/orchestrator/plan-profile.ts +23 -0
  190. package/src/forge/compiler/orchestrator/plan.ts +78 -7
  191. package/src/forge/compiler/orchestrator/profile.ts +65 -0
  192. package/src/forge/compiler/orchestrator/run.ts +97 -31
  193. package/src/forge/compiler/orchestrator/serialize.ts +101 -8
  194. package/src/forge/compiler/package-graph/compiler.ts +13 -3
  195. package/src/forge/compiler/package-manager/adapter.ts +4 -1
  196. package/src/forge/compiler/package-manager/commands.ts +4 -0
  197. package/src/forge/compiler/package-manager/executor.ts +30 -1
  198. package/src/forge/compiler/policy-registry/build.ts +44 -1
  199. package/src/forge/compiler/test-graph/build.ts +11 -3
  200. package/src/forge/compiler/types/ai-registry.ts +25 -1
  201. package/src/forge/compiler/types/app-graph.ts +9 -2
  202. package/src/forge/compiler/types/cli.ts +76 -1
  203. package/src/forge/compiler/types/dev-manifest.ts +3 -0
  204. package/src/forge/compiler/types/frontend-graph.ts +2 -2
  205. package/src/forge/delta/classifier.ts +52 -0
  206. package/src/forge/delta/explain.ts +126 -0
  207. package/src/forge/delta/git-observer.ts +43 -0
  208. package/src/forge/delta/ids.ts +44 -0
  209. package/src/forge/delta/index.ts +13 -0
  210. package/src/forge/delta/recorder.ts +402 -0
  211. package/src/forge/delta/redaction.ts +50 -0
  212. package/src/forge/delta/schema.ts +240 -0
  213. package/src/forge/delta/session.ts +142 -0
  214. package/src/forge/delta/status.ts +489 -0
  215. package/src/forge/delta/store.ts +2975 -0
  216. package/src/forge/delta/timeline.ts +104 -0
  217. package/src/forge/dev/server.ts +768 -15
  218. package/src/forge/dev/types.ts +15 -1
  219. package/src/forge/dev/watch.ts +17 -7
  220. package/src/forge/dev-console/cycle.ts +233 -21
  221. package/src/forge/dev-console/types.ts +46 -1
  222. package/src/forge/impact/index.ts +46 -8
  223. package/src/forge/impact/types.ts +6 -0
  224. package/src/forge/intent/index.ts +35 -16
  225. package/src/forge/make/index.ts +149 -6
  226. package/src/forge/make/templates.ts +343 -2
  227. package/src/forge/make/types.ts +3 -1
  228. package/src/forge/refactor/index.ts +1 -0
  229. package/src/forge/repair/rules/index.ts +2 -2
  230. package/src/forge/review/index.ts +158 -12
  231. package/src/forge/review/types.ts +15 -0
  232. package/src/forge/runtime/ai/context.ts +210 -5
  233. package/src/forge/runtime/ai/types.ts +70 -0
  234. package/src/forge/runtime/auth/claims.ts +32 -0
  235. package/src/forge/runtime/auth/errors.ts +2 -0
  236. package/src/forge/runtime/context/create-context.ts +30 -6
  237. package/src/forge/runtime/db/generated-client.ts +13 -2
  238. package/src/forge/runtime/db/memory-adapter.ts +2 -2
  239. package/src/forge/runtime/db/pglite-adapter.ts +77 -2
  240. package/src/forge/runtime/db/postgres-adapter.ts +6 -3
  241. package/src/forge/runtime/executor.ts +112 -2
  242. package/src/forge/runtime/external/bridge.ts +649 -0
  243. package/src/forge/runtime/runner/run-entry.ts +16 -7
  244. package/src/forge/runtime/telemetry/scrubber.ts +91 -10
  245. package/src/forge/runtime/webhooks/security.ts +184 -0
  246. package/src/forge/server.ts +100 -2
  247. package/src/forge/version.ts +1 -1
  248. package/src/forge/vue/index.ts +407 -0
  249. package/src/forge/workspace/change-summary.ts +209 -0
  250. package/src/forge/workspace/forge-cli.ts +14 -0
  251. package/src/forge/workspace/git-summary.ts +279 -0
  252. package/templates/agent-workroom/AGENTS.md +29 -0
  253. package/templates/agent-workroom/README.md +34 -0
  254. package/templates/agent-workroom/forge.config.ts +3 -0
  255. package/templates/agent-workroom/package.json +33 -0
  256. package/templates/agent-workroom/src/actions/indexAgentSignal.ts +10 -0
  257. package/templates/agent-workroom/src/commands/openWorkroom.ts +61 -0
  258. package/templates/agent-workroom/src/commands/recordAgentSignal.ts +119 -0
  259. package/templates/agent-workroom/src/commands/recordCheckRun.ts +52 -0
  260. package/templates/agent-workroom/src/forge/schema.ts +54 -0
  261. package/templates/agent-workroom/src/policies.ts +6 -0
  262. package/templates/agent-workroom/src/queries/listWorkrooms.ts +11 -0
  263. package/templates/agent-workroom/src/queries/liveWorkroom.ts +63 -0
  264. package/templates/agent-workroom/tsconfig.json +16 -0
  265. package/templates/agent-workroom/web/index.html +12 -0
  266. package/templates/agent-workroom/web/package.json +21 -0
  267. package/templates/agent-workroom/web/src/App.tsx +345 -0
  268. package/templates/agent-workroom/web/src/lib/forge.ts +13 -0
  269. package/templates/agent-workroom/web/src/main.tsx +13 -0
  270. package/templates/agent-workroom/web/src/styles.css +545 -0
  271. package/templates/agent-workroom/web/tsconfig.json +27 -0
  272. package/templates/b2b-support-web/package.json +2 -0
  273. package/templates/b2b-support-web/tsconfig.json +4 -1
  274. package/templates/b2b-support-web/web/package.json +1 -1
  275. package/templates/minimal-web/package.json +2 -1
  276. package/templates/minimal-web/tsconfig.json +3 -1
  277. package/templates/minimal-web/web/package.json +2 -2
  278. package/src/forge/_generated/actionSubscriptions.json +0 -2
  279. package/src/forge/_generated/actionSubscriptions.ts +0 -10
  280. package/src/forge/_generated/agentAdapterManifest.json +0 -2
  281. package/src/forge/_generated/agentAdapterManifest.ts +0 -73
  282. package/src/forge/_generated/agentContract.json +0 -2
  283. package/src/forge/_generated/agentContract.ts +0 -7696
  284. package/src/forge/_generated/agentQuickstart.md +0 -32
  285. package/src/forge/_generated/aiContext.ts +0 -59
  286. package/src/forge/_generated/aiModels.json +0 -2
  287. package/src/forge/_generated/aiModels.ts +0 -35
  288. package/src/forge/_generated/aiProviders.json +0 -2
  289. package/src/forge/_generated/aiProviders.ts +0 -23
  290. package/src/forge/_generated/aiRegistry.json +0 -2
  291. package/src/forge/_generated/aiRegistry.ts +0 -29
  292. package/src/forge/_generated/api.json +0 -2
  293. package/src/forge/_generated/api.ts +0 -8
  294. package/src/forge/_generated/appGraph.json +0 -2
  295. package/src/forge/_generated/appGraph.ts +0 -14667
  296. package/src/forge/_generated/appMap.md +0 -35
  297. package/src/forge/_generated/artifactManifest.json +0 -2
  298. package/src/forge/_generated/artifactManifest.ts +0 -7
  299. package/src/forge/_generated/authClaims.json +0 -2
  300. package/src/forge/_generated/authClaims.ts +0 -13
  301. package/src/forge/_generated/authConfig.json +0 -2
  302. package/src/forge/_generated/authConfig.ts +0 -17
  303. package/src/forge/_generated/authContext.ts +0 -23
  304. package/src/forge/_generated/authRegistry.json +0 -2
  305. package/src/forge/_generated/authRegistry.ts +0 -25
  306. package/src/forge/_generated/buildInfo.json +0 -2
  307. package/src/forge/_generated/buildInfo.ts +0 -9
  308. package/src/forge/_generated/capabilityMap.json +0 -2
  309. package/src/forge/_generated/capabilityMap.md +0 -15
  310. package/src/forge/_generated/capabilityMap.ts +0 -17
  311. package/src/forge/_generated/client.ts +0 -282
  312. package/src/forge/_generated/clientApi.ts +0 -9
  313. package/src/forge/_generated/clientManifest.json +0 -2
  314. package/src/forge/_generated/clientManifest.ts +0 -39
  315. package/src/forge/_generated/clientTypes.ts +0 -78
  316. package/src/forge/_generated/configRegistry.json +0 -2
  317. package/src/forge/_generated/configRegistry.ts +0 -4
  318. package/src/forge/_generated/dataGraph.json +0 -2
  319. package/src/forge/_generated/dataGraph.ts +0 -8
  320. package/src/forge/_generated/db.json +0 -2
  321. package/src/forge/_generated/db.ts +0 -2
  322. package/src/forge/_generated/dbSecurityManifest.json +0 -2
  323. package/src/forge/_generated/dbSecurityManifest.ts +0 -15
  324. package/src/forge/_generated/dbSessionContext.json +0 -2
  325. package/src/forge/_generated/dbSessionContext.ts +0 -39
  326. package/src/forge/_generated/deployManifest.json +0 -2
  327. package/src/forge/_generated/deployManifest.ts +0 -14
  328. package/src/forge/_generated/devManifest.json +0 -2
  329. package/src/forge/_generated/devManifest.ts +0 -47
  330. package/src/forge/_generated/envSchema.json +0 -2
  331. package/src/forge/_generated/envSchema.ts +0 -59
  332. package/src/forge/_generated/frontendGraph.json +0 -2
  333. package/src/forge/_generated/frontendGraph.ts +0 -27
  334. package/src/forge/_generated/importGuards.json +0 -2
  335. package/src/forge/_generated/importGuards.ts +0 -686
  336. package/src/forge/_generated/index.ts +0 -67
  337. package/src/forge/_generated/liveProductionManifest.json +0 -2
  338. package/src/forge/_generated/liveProductionManifest.ts +0 -23
  339. package/src/forge/_generated/liveProtocol.json +0 -2
  340. package/src/forge/_generated/liveProtocol.ts +0 -21
  341. package/src/forge/_generated/liveQueryRegistry.json +0 -2
  342. package/src/forge/_generated/liveQueryRegistry.ts +0 -9
  343. package/src/forge/_generated/liveTransportConfig.json +0 -2
  344. package/src/forge/_generated/liveTransportConfig.ts +0 -19
  345. package/src/forge/_generated/makeRegistry.json +0 -2
  346. package/src/forge/_generated/makeRegistry.ts +0 -163
  347. package/src/forge/_generated/makeTemplates.json +0 -2
  348. package/src/forge/_generated/makeTemplates.ts +0 -61
  349. package/src/forge/_generated/mockMap.json +0 -2
  350. package/src/forge/_generated/mockMap.ts +0 -7
  351. package/src/forge/_generated/operationPlaybooks.md +0 -147
  352. package/src/forge/_generated/packageGraph.json +0 -2
  353. package/src/forge/_generated/packageGraph.ts +0 -245249
  354. package/src/forge/_generated/packageUpgradeRegistry.json +0 -2
  355. package/src/forge/_generated/packageUpgradeRegistry.ts +0 -15
  356. package/src/forge/_generated/permissionMatrix.json +0 -2
  357. package/src/forge/_generated/permissionMatrix.ts +0 -7
  358. package/src/forge/_generated/policyRegistry.json +0 -2
  359. package/src/forge/_generated/policyRegistry.ts +0 -11
  360. package/src/forge/_generated/queryRegistry.json +0 -2
  361. package/src/forge/_generated/queryRegistry.ts +0 -9
  362. package/src/forge/_generated/react.d.ts +0 -22
  363. package/src/forge/_generated/react.ts +0 -29
  364. package/src/forge/_generated/reactManifest.json +0 -2
  365. package/src/forge/_generated/reactManifest.ts +0 -19
  366. package/src/forge/_generated/rlsPolicies.json +0 -2
  367. package/src/forge/_generated/rlsPolicies.sql +0 -34
  368. package/src/forge/_generated/rlsPolicies.ts +0 -6
  369. package/src/forge/_generated/runtimeGraph.json +0 -2
  370. package/src/forge/_generated/runtimeGraph.ts +0 -8
  371. package/src/forge/_generated/runtimeMatrix.json +0 -2
  372. package/src/forge/_generated/runtimeMatrix.ts +0 -327385
  373. package/src/forge/_generated/runtimeRegistry.ts +0 -2
  374. package/src/forge/_generated/runtimeRules.md +0 -79
  375. package/src/forge/_generated/secretRegistry.json +0 -2
  376. package/src/forge/_generated/secretRegistry.ts +0 -50
  377. package/src/forge/_generated/secretsContext.ts +0 -11
  378. package/src/forge/_generated/serverApi.ts +0 -10
  379. package/src/forge/_generated/sourceMapManifest.json +0 -2
  380. package/src/forge/_generated/sourceMapManifest.ts +0 -7
  381. package/src/forge/_generated/sqlPlan.json +0 -2
  382. package/src/forge/_generated/sqlPlan.ts +0 -88
  383. package/src/forge/_generated/subscriptionManifest.json +0 -2
  384. package/src/forge/_generated/subscriptionManifest.ts +0 -7
  385. package/src/forge/_generated/symbolicationManifest.json +0 -2
  386. package/src/forge/_generated/symbolicationManifest.ts +0 -17
  387. package/src/forge/_generated/telemetryRegistry.json +0 -2
  388. package/src/forge/_generated/telemetryRegistry.ts +0 -9
  389. package/src/forge/_generated/telemetrySinks.json +0 -2
  390. package/src/forge/_generated/telemetrySinks.ts +0 -11
  391. package/src/forge/_generated/tenantScope.json +0 -2
  392. package/src/forge/_generated/tenantScope.ts +0 -8
  393. package/src/forge/_generated/testGraph.json +0 -2
  394. package/src/forge/_generated/testGraph.ts +0 -3108
  395. package/src/forge/_generated/testPlanRegistry.json +0 -2
  396. package/src/forge/_generated/testPlanRegistry.ts +0 -33
  397. package/src/forge/_generated/uiRoutes.json +0 -2
  398. package/src/forge/_generated/uiRoutes.ts +0 -16
  399. package/src/forge/_generated/uiScenarios.json +0 -2
  400. package/src/forge/_generated/uiScenarios.ts +0 -30
  401. package/src/forge/_generated/uiTestManifest.json +0 -2
  402. package/src/forge/_generated/uiTestManifest.ts +0 -27
  403. package/src/forge/_generated/workflowRegistry.json +0 -2
  404. package/src/forge/_generated/workflowRegistry.ts +0 -9
  405. package/src/forge/_generated/workflowSubscriptions.json +0 -2
  406. package/src/forge/_generated/workflowSubscriptions.ts +0 -10
@@ -1,5 +1,6 @@
1
1
  import type { Diagnostic } from "../compiler/types/diagnostic.ts";
2
2
  import type { ImpactedSystems, ImpactSource } from "../impact/types.ts";
3
+ import type { CategorizedFileSummary, ChangeType, DiffPlan } from "../workspace/change-summary.ts";
3
4
 
4
5
  export type ReviewSubcommand = "run" | "inspect" | "list" | "explain";
5
6
  export type ReviewMode = "quick" | "standard" | "strict";
@@ -26,6 +27,7 @@ export interface ReviewCommandOptions {
26
27
  json: boolean;
27
28
  md: boolean;
28
29
  sarif: boolean;
30
+ full?: boolean;
29
31
  write: boolean;
30
32
  changed: boolean;
31
33
  staged: boolean;
@@ -60,6 +62,16 @@ export interface ReviewChanged {
60
62
  deployFiles: string[];
61
63
  }
62
64
 
65
+ export interface ReviewFocus {
66
+ first: "authoredChanges";
67
+ then: "derivedArtifacts";
68
+ generatedIsDerived: boolean;
69
+ suggestedOrder: ChangeType[];
70
+ summary: string;
71
+ }
72
+
73
+ export type ReviewDiffPlan = DiffPlan;
74
+
63
75
  export interface ReviewSummary {
64
76
  title: string;
65
77
  bullets: string[];
@@ -130,6 +142,9 @@ export interface ReviewReport {
130
142
  risk: ReviewRisk;
131
143
  findings: ReviewFinding[];
132
144
  changed: ReviewChanged;
145
+ changeSummary: CategorizedFileSummary;
146
+ reviewFocus: ReviewFocus;
147
+ diffPlan: ReviewDiffPlan;
133
148
  impacted: ImpactedSystems;
134
149
  checks: ReviewCheckResult[];
135
150
  recommendedCommands: string[];
@@ -15,6 +15,8 @@ import type {
15
15
  ForgeGenerateStructuredInput,
16
16
  ForgeGenerateTextInput,
17
17
  ForgeGenerateTextResult,
18
+ ForgeRunAgentInput,
19
+ ForgeRunAgentResult,
18
20
  ForgeStreamTextInput,
19
21
  ForgeStreamTextResult,
20
22
  ForgeAiUsage,
@@ -64,6 +66,10 @@ export interface CreateAiContextOptions {
64
66
  runtimeKind: RuntimeContext;
65
67
  envelope?: AiTelemetryEnvelope;
66
68
  mockAi?: boolean;
69
+ toolContext?: {
70
+ env?: Record<string, string | undefined>;
71
+ auth?: unknown;
72
+ };
67
73
  }
68
74
 
69
75
  export function aiForbiddenInContext(runtimeKind: RuntimeContext): boolean {
@@ -94,6 +100,12 @@ export function createAiContext(options: CreateAiContextOptions): AiContext {
94
100
  `ctx.ai is forbidden in '${runtimeKind}' context`,
95
101
  );
96
102
  },
103
+ async runAgent() {
104
+ forgeError(
105
+ FORGE_AI_FORBIDDEN_CONTEXT,
106
+ `ctx.ai is forbidden in '${runtimeKind}' context`,
107
+ );
108
+ },
97
109
  };
98
110
  }
99
111
 
@@ -284,7 +296,7 @@ export function createAiContext(options: CreateAiContextOptions): AiContext {
284
296
 
285
297
  return {
286
298
  textStream: result.textStream,
287
- text: result.text.then(async (text) => {
299
+ text: Promise.resolve(result.text).then(async (text) => {
288
300
  const usage = mapUsage(await result.usage);
289
301
  await recordAiTelemetry(telemetry, "forge.ai.stream.completed", {
290
302
  ...baseProps(),
@@ -300,7 +312,7 @@ export function createAiContext(options: CreateAiContextOptions): AiContext {
300
312
  provider: input.provider,
301
313
  model: input.model,
302
314
  purpose: input.purpose,
303
- usage: result.usage.then(mapUsage),
315
+ usage: Promise.resolve(result.usage).then(mapUsage),
304
316
  latencyMs,
305
317
  };
306
318
  },
@@ -347,10 +359,10 @@ export function createAiContext(options: CreateAiContextOptions): AiContext {
347
359
  );
348
360
  const { generateText, Output } = await import("ai");
349
361
  const result = await generateText({
350
- model: languageModel,
362
+ model: languageModel as never,
351
363
  prompt: input.prompt,
352
364
  system: input.system,
353
- experimental_output: Output.object({ schema: input.schema as never }),
365
+ output: Output.object({ schema: input.schema as never }),
354
366
  });
355
367
 
356
368
  const usage = mapUsage(result.usage);
@@ -365,7 +377,7 @@ export function createAiContext(options: CreateAiContextOptions): AiContext {
365
377
  method: "generateStructured",
366
378
  });
367
379
 
368
- return result.experimental_output as T;
380
+ return result.output as T;
369
381
  } catch (error) {
370
382
  const message = error instanceof Error ? error.message : String(error);
371
383
  await recordAiTelemetry(telemetry, "forge.ai.generation.failed", {
@@ -379,6 +391,198 @@ export function createAiContext(options: CreateAiContextOptions): AiContext {
379
391
  throw error;
380
392
  }
381
393
  },
394
+
395
+ async runAgent(input: ForgeRunAgentInput): Promise<ForgeRunAgentResult> {
396
+ const provider = input.provider ?? "gateway";
397
+ const startedAt = Date.now();
398
+ await recordAiTelemetry(telemetry, "forge.ai.agent.started", {
399
+ ...baseProps(),
400
+ provider,
401
+ model: input.model,
402
+ purpose: input.purpose,
403
+ toolCount: Object.keys(input.tools ?? {}).length,
404
+ });
405
+
406
+ try {
407
+ if (useMock) {
408
+ const mock = dequeueMockAiResponse();
409
+ const usage = createMockAiUsage(mock.usage);
410
+ const latencyMs = Date.now() - startedAt;
411
+ const estimatedCostUsd = estimateCostUsd(provider, input.model, usage);
412
+ const result = {
413
+ text: mock.text,
414
+ provider,
415
+ model: input.model,
416
+ purpose: input.purpose,
417
+ usage,
418
+ latencyMs,
419
+ toolCalls: [],
420
+ toolResults: [],
421
+ steps: 1,
422
+ estimatedCostUsd,
423
+ };
424
+ await recordAiTelemetry(telemetry, "forge.ai.agent.completed", {
425
+ ...baseProps(),
426
+ provider,
427
+ model: input.model,
428
+ purpose: input.purpose,
429
+ latencyMs,
430
+ usage,
431
+ estimatedCostUsd,
432
+ status: "completed",
433
+ mode: "mock",
434
+ });
435
+ return result;
436
+ }
437
+
438
+ const languageModel = await resolveLanguageModel(provider, input.model, secrets);
439
+ const { ToolLoopAgent, hasToolCall, stepCountIs, tool } = await import("ai");
440
+ const toolRuntimeContext = {
441
+ secrets,
442
+ env: options.toolContext?.env ?? {},
443
+ telemetry,
444
+ auth: options.toolContext?.auth,
445
+ };
446
+
447
+ const tools = Object.fromEntries(
448
+ Object.entries(input.tools ?? {}).map(([name, definition]) => {
449
+ const needsApproval = definition.needsApproval;
450
+ const aiSdkToolConfig = {
451
+ description: definition.description,
452
+ inputSchema: definition.inputSchema as never,
453
+ ...(definition.outputSchema
454
+ ? { outputSchema: definition.outputSchema as never }
455
+ : {}),
456
+ ...(definition.strict !== undefined ? { strict: definition.strict } : {}),
457
+ ...(needsApproval !== undefined
458
+ ? {
459
+ needsApproval:
460
+ typeof needsApproval === "function"
461
+ ? async ({ args }: { args: unknown }) =>
462
+ Boolean(await needsApproval(args as never))
463
+ : needsApproval,
464
+ }
465
+ : {}),
466
+ execute: async (args: unknown) => {
467
+ await recordAiTelemetry(telemetry, "forge.ai.tool.started", {
468
+ ...baseProps(),
469
+ provider,
470
+ model: input.model,
471
+ purpose: input.purpose,
472
+ tool: name,
473
+ risk: definition.risk ?? "external",
474
+ });
475
+ const toolStartedAt = Date.now();
476
+ try {
477
+ const output = await definition.handler(
478
+ toolRuntimeContext,
479
+ args as never,
480
+ );
481
+ await recordAiTelemetry(telemetry, "forge.ai.tool.completed", {
482
+ ...baseProps(),
483
+ provider,
484
+ model: input.model,
485
+ purpose: input.purpose,
486
+ tool: name,
487
+ latencyMs: Date.now() - toolStartedAt,
488
+ status: "completed",
489
+ });
490
+ return output;
491
+ } catch (error) {
492
+ await recordAiTelemetry(telemetry, "forge.ai.tool.failed", {
493
+ ...baseProps(),
494
+ provider,
495
+ model: input.model,
496
+ purpose: input.purpose,
497
+ tool: name,
498
+ latencyMs: Date.now() - toolStartedAt,
499
+ status: "failed",
500
+ error: error instanceof Error ? error.message : String(error),
501
+ });
502
+ throw error;
503
+ }
504
+ },
505
+ };
506
+ return [name, tool(aiSdkToolConfig as never)];
507
+ }),
508
+ );
509
+
510
+ const stopWhen =
511
+ input.stopWhen?.kind === "toolCall"
512
+ ? hasToolCall(input.stopWhen.toolName)
513
+ : stepCountIs(input.stopWhen?.maxSteps ?? input.maxSteps ?? 20);
514
+
515
+ const agent = new ToolLoopAgent({
516
+ model: languageModel as never,
517
+ instructions: input.instructions,
518
+ tools,
519
+ stopWhen,
520
+ temperature: input.temperature,
521
+ maxOutputTokens: input.maxTokens,
522
+ });
523
+
524
+ const result = await agent.generate({ prompt: input.prompt });
525
+ const usage = mapUsage(result.usage);
526
+ const latencyMs = Date.now() - startedAt;
527
+ const estimatedCostUsd = estimateCostUsd(provider, input.model, usage);
528
+ const raw = result as unknown as {
529
+ steps?: unknown[];
530
+ toolCalls?: Array<{ toolName?: string; input?: unknown; args?: unknown }>;
531
+ toolResults?: Array<{ toolName?: string; output?: unknown; result?: unknown }>;
532
+ };
533
+
534
+ await recordAiTelemetry(telemetry, "forge.ai.agent.completed", {
535
+ ...baseProps(),
536
+ provider,
537
+ model: input.model,
538
+ purpose: input.purpose,
539
+ latencyMs,
540
+ usage,
541
+ estimatedCostUsd,
542
+ status: "completed",
543
+ steps: raw.steps?.length ?? 1,
544
+ });
545
+ await recordAiTelemetry(telemetry, "forge.ai.usage", {
546
+ ...baseProps(),
547
+ provider,
548
+ model: input.model,
549
+ purpose: input.purpose,
550
+ usage,
551
+ estimatedCostUsd,
552
+ method: "runAgent",
553
+ });
554
+
555
+ return {
556
+ text: result.text,
557
+ provider,
558
+ model: input.model,
559
+ purpose: input.purpose,
560
+ usage,
561
+ latencyMs,
562
+ toolCalls: (raw.toolCalls ?? []).map((call) => ({
563
+ toolName: call.toolName ?? "unknown",
564
+ input: call.input ?? call.args,
565
+ })),
566
+ toolResults: (raw.toolResults ?? []).map((toolResult) => ({
567
+ toolName: toolResult.toolName ?? "unknown",
568
+ output: toolResult.output ?? toolResult.result,
569
+ })),
570
+ steps: raw.steps?.length ?? 1,
571
+ estimatedCostUsd,
572
+ };
573
+ } catch (error) {
574
+ const message = error instanceof Error ? error.message : String(error);
575
+ await recordAiTelemetry(telemetry, "forge.ai.agent.failed", {
576
+ ...baseProps(),
577
+ provider,
578
+ model: input.model,
579
+ purpose: input.purpose,
580
+ status: "failed",
581
+ error: message,
582
+ });
583
+ throw error;
584
+ }
585
+ },
382
586
  };
383
587
  }
384
588
 
@@ -390,5 +594,6 @@ export function createNoopAiContext(): AiContext {
390
594
  generateText: noop,
391
595
  streamText: noop,
392
596
  generateStructured: noop,
597
+ runAgent: noop,
393
598
  };
394
599
  }
@@ -51,10 +51,80 @@ export interface ForgeGenerateStructuredInput<T> {
51
51
  schema: ForgeFlexibleSchema<T>;
52
52
  }
53
53
 
54
+ export type ForgeAiToolRisk = "read" | "write" | "external" | "destructive";
55
+
56
+ export interface ForgeAiToolRuntimeContext {
57
+ secrets: {
58
+ get(name: string): string;
59
+ optional(name: string): string | undefined;
60
+ has(name: string): boolean;
61
+ };
62
+ env: Record<string, string | undefined>;
63
+ telemetry?: {
64
+ traceId?: string;
65
+ capture(name: string, properties?: Record<string, unknown>): Promise<void>;
66
+ };
67
+ auth?: unknown;
68
+ }
69
+
70
+ export interface ForgeAiToolDefinition<TArgs = unknown, TResult = unknown> {
71
+ description: string;
72
+ inputSchema: unknown;
73
+ outputSchema?: unknown;
74
+ strict?: boolean;
75
+ needsApproval?: boolean | ((args: TArgs) => boolean | Promise<boolean>);
76
+ risk?: ForgeAiToolRisk;
77
+ handler: (
78
+ ctx: ForgeAiToolRuntimeContext,
79
+ args: TArgs,
80
+ ) => TResult | Promise<TResult>;
81
+ }
82
+
83
+ export type ForgeAgentStopWhen =
84
+ | { kind: "stepCount"; maxSteps: number }
85
+ | { kind: "toolCall"; toolName: string };
86
+
87
+ export interface ForgeRunAgentInput {
88
+ provider?: ForgeAiProvider;
89
+ model: string;
90
+ prompt: string;
91
+ instructions: string;
92
+ purpose?: string;
93
+ tools?: Record<string, ForgeAiToolDefinition>;
94
+ stopWhen?: ForgeAgentStopWhen;
95
+ maxSteps?: number;
96
+ temperature?: number;
97
+ maxTokens?: number;
98
+ }
99
+
100
+ export interface ForgeRunAgentResult {
101
+ text: string;
102
+ provider: ForgeAiProvider;
103
+ model: string;
104
+ purpose?: string;
105
+ usage: ForgeAiUsage;
106
+ latencyMs: number;
107
+ toolCalls: Array<{
108
+ toolName: string;
109
+ input: unknown;
110
+ }>;
111
+ toolResults: Array<{
112
+ toolName: string;
113
+ output: unknown;
114
+ }>;
115
+ steps: number;
116
+ estimatedCostUsd?: number;
117
+ }
118
+
54
119
  export interface AiContext {
55
120
  generateText(input: ForgeGenerateTextInput): Promise<ForgeGenerateTextResult>;
56
121
  streamText(input: ForgeStreamTextInput): Promise<ForgeStreamTextResult>;
57
122
  generateStructured<T>(input: ForgeGenerateStructuredInput<T>): Promise<T>;
123
+ runAgent(input: ForgeRunAgentInput): Promise<ForgeRunAgentResult>;
124
+ }
125
+
126
+ export interface AgentRuntimeContext {
127
+ run(input: ForgeRunAgentInput): Promise<ForgeRunAgentResult>;
58
128
  }
59
129
 
60
130
  export interface AiTelemetryEnvelope {
@@ -1,4 +1,5 @@
1
1
  import {
2
+ FORGE_AUTH_CLAIM_INVALID,
2
3
  FORGE_AUTH_CLAIM_MISSING,
3
4
  FORGE_AUTH_TENANT_MISSING,
4
5
  } from "../../compiler/diagnostics/codes.ts";
@@ -57,6 +58,31 @@ function asStringArray(value: unknown): string[] {
57
58
  return [];
58
59
  }
59
60
 
61
+ function claimExists(claims: Record<string, unknown>, path: string | undefined): boolean {
62
+ return getClaimValue(claims, path) !== undefined;
63
+ }
64
+
65
+ function validateRoleClaim(
66
+ claims: Record<string, unknown>,
67
+ path: string | undefined,
68
+ label: string,
69
+ ): void {
70
+ const value = getClaimValue(claims, path);
71
+ if (value === undefined) {
72
+ return;
73
+ }
74
+ if (typeof value === "string") {
75
+ return;
76
+ }
77
+ if (Array.isArray(value) && value.every((entry) => typeof entry === "string")) {
78
+ return;
79
+ }
80
+ throw new ForgeAuthError(
81
+ FORGE_AUTH_CLAIM_INVALID,
82
+ `auth claim '${path ?? label}' must be a string or string array`,
83
+ );
84
+ }
85
+
60
86
  function uniqueSorted(values: string[]): string[] {
61
87
  return [...new Set(values)].sort();
62
88
  }
@@ -84,6 +110,12 @@ export function mapClaimsToAuthContext(
84
110
  );
85
111
  }
86
112
 
113
+ if (claimExists(payload, mapping.role)) {
114
+ validateRoleClaim(payload, mapping.role, "role");
115
+ }
116
+ if (claimExists(payload, mapping.roles)) {
117
+ validateRoleClaim(payload, mapping.roles, "roles");
118
+ }
87
119
  const role = asString(getClaimValue(payload, mapping.role));
88
120
  const roles = uniqueSorted([
89
121
  ...(role ? [role] : []),
@@ -1,4 +1,5 @@
1
1
  import {
2
+ FORGE_AUTH_CLAIM_INVALID,
2
3
  FORGE_AUTH_CLAIM_MISSING,
3
4
  FORGE_AUTH_DEV_HEADERS_IN_PRODUCTION,
4
5
  FORGE_AUTH_DISABLED,
@@ -20,6 +21,7 @@ export type ForgeAuthDiagnosticCode =
20
21
  | typeof FORGE_AUTH_TOKEN_EXPIRED
21
22
  | typeof FORGE_AUTH_JWKS_FAILED
22
23
  | typeof FORGE_AUTH_CLAIM_MISSING
24
+ | typeof FORGE_AUTH_CLAIM_INVALID
23
25
  | typeof FORGE_AUTH_TENANT_MISSING
24
26
  | typeof FORGE_AUTH_DEV_HEADERS_IN_PRODUCTION
25
27
  | typeof FORGE_AUTH_MODE_INVALID
@@ -13,7 +13,7 @@ import { loadEnvFiles } from "../secrets/env-loader.ts";
13
13
  import { loadEnvSchema, loadSecretRegistry } from "../secrets/check.ts";
14
14
  import { createRuntimeSecretsBundle } from "../secrets/runtime-bundle.ts";
15
15
  import { createAiContext } from "../ai/context.ts";
16
- import type { AiContext } from "../ai/types.ts";
16
+ import type { AgentRuntimeContext, AiContext } from "../ai/types.ts";
17
17
  import { isMockAiEnabled } from "../ai/state.ts";
18
18
  import { currentReleaseInfo, type RuntimeReleaseInfo } from "../release/runtime.ts";
19
19
 
@@ -26,6 +26,7 @@ export interface ForgeContext {
26
26
  secrets: SecretsContext;
27
27
  config: ConfigContext;
28
28
  ai: AiContext;
29
+ agent: AgentRuntimeContext;
29
30
  release: RuntimeReleaseInfo;
30
31
  }
31
32
 
@@ -67,11 +68,16 @@ function buildSecretsConfigAndAi(
67
68
  runtimeKind: RuntimeContext,
68
69
  store: RuntimeEnvStore,
69
70
  telemetry: TelemetryContext,
70
- options?: { mockAi?: boolean },
71
+ options?: {
72
+ mockAi?: boolean;
73
+ auth?: AuthContext;
74
+ env?: Record<string, string | undefined>;
75
+ },
71
76
  ): {
72
77
  secrets: SecretsContext;
73
78
  config: ConfigContext;
74
79
  ai: AiContext;
80
+ agent: AgentRuntimeContext;
75
81
  env: Record<string, string | undefined>;
76
82
  } {
77
83
  const registry = workspaceRoot ? loadSecretRegistry(workspaceRoot) : null;
@@ -93,12 +99,20 @@ function buildSecretsConfigAndAi(
93
99
  tenantId:
94
100
  undefined,
95
101
  },
102
+ toolContext: {
103
+ env: options?.env ?? store.snapshot(),
104
+ auth: options?.auth,
105
+ },
96
106
  });
107
+ const agent: AgentRuntimeContext = {
108
+ run: (input) => ai.runAgent(input),
109
+ };
97
110
 
98
111
  return {
99
112
  secrets: bundle.secrets,
100
113
  config: bundle.config,
101
114
  ai,
115
+ agent,
102
116
  env: store.snapshot(),
103
117
  };
104
118
  }
@@ -123,12 +137,16 @@ export function createForgeContext(
123
137
  (options?.workspaceRoot
124
138
  ? getRuntimeEnvStore(options.workspaceRoot)
125
139
  : getRuntimeEnvStore());
126
- const { secrets, config, ai, env } = buildSecretsConfigAndAi(
140
+ const { secrets, config, ai, agent, env } = buildSecretsConfigAndAi(
127
141
  options?.workspaceRoot,
128
142
  runtimeKind,
129
143
  store,
130
144
  telemetry,
131
- { mockAi: options?.mockAi },
145
+ {
146
+ mockAi: options?.mockAi,
147
+ auth,
148
+ env: options?.env,
149
+ },
132
150
  );
133
151
 
134
152
  return {
@@ -139,6 +157,7 @@ export function createForgeContext(
139
157
  secrets,
140
158
  config,
141
159
  ai,
160
+ agent,
142
161
  release: currentReleaseInfo(),
143
162
  emit: async (eventType, payload) => {
144
163
  const enriched =
@@ -178,12 +197,16 @@ export function createActionContext(
178
197
  (options?.workspaceRoot
179
198
  ? getRuntimeEnvStore(options.workspaceRoot)
180
199
  : getRuntimeEnvStore());
181
- const { secrets, config, ai, env } = buildSecretsConfigAndAi(
200
+ const { secrets, config, ai, agent, env } = buildSecretsConfigAndAi(
182
201
  options?.workspaceRoot,
183
202
  runtimeKind,
184
203
  store,
185
204
  telemetry,
186
- { mockAi: options?.mockAi },
205
+ {
206
+ mockAi: options?.mockAi,
207
+ auth,
208
+ env: options?.env,
209
+ },
187
210
  );
188
211
 
189
212
  return {
@@ -194,6 +217,7 @@ export function createActionContext(
194
217
  secrets,
195
218
  config,
196
219
  ai,
220
+ agent,
197
221
  release: currentReleaseInfo(),
198
222
  emit: async () => {
199
223
  /* actions invoked by outbox worker do not emit */
@@ -37,6 +37,10 @@ export interface GeneratedDbClientOptions {
37
37
  writeTracker?: WriteTracker;
38
38
  }
39
39
 
40
+ function camelCase(value: string): string {
41
+ return value.replace(/[_-]([a-zA-Z0-9])/g, (_match, char: string) => char.toUpperCase());
42
+ }
43
+
40
44
  function quoteIdent(ident: string): string {
41
45
  return `"${ident.replace(/"/g, '""')}"`;
42
46
  }
@@ -286,8 +290,15 @@ export function createGeneratedDbClient(
286
290
  ): DbClient {
287
291
  const client: DbClient = {};
288
292
 
289
- for (const [tableName, entry] of Object.entries(tableMap).sort()) {
290
- client[tableName] = createTableClient(tx, tableName, entry, options);
293
+ for (const [accessName, entry] of Object.entries(tableMap).sort()) {
294
+ const tableClient = createTableClient(tx, entry.tableName, entry, options);
295
+ client[accessName] = tableClient;
296
+
297
+ for (const alias of new Set([camelCase(accessName), camelCase(entry.tableName)])) {
298
+ if (alias && client[alias] === undefined) {
299
+ client[alias] = tableClient;
300
+ }
301
+ }
291
302
  }
292
303
 
293
304
  return client;
@@ -656,9 +656,9 @@ export class MemoryAdapter implements DbAdapter {
656
656
  return { rows: [], rowCount: before - table.rows.length };
657
657
  }
658
658
 
659
- const id = params[0];
659
+ const rowsToDelete = new Set(this.filterRows(table.rows, sql, params));
660
660
  const before = table.rows.length;
661
- table.rows = table.rows.filter((row) => row.id !== id);
661
+ table.rows = table.rows.filter((row) => !rowsToDelete.has(row));
662
662
  return { rows: [], rowCount: before - table.rows.length };
663
663
  }
664
664
 
@@ -1,4 +1,6 @@
1
1
  import { PGlite } from "@electric-sql/pglite";
2
+ import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, unlinkSync } from "node:fs";
3
+ import { basename, dirname, join } from "node:path";
2
4
  import type { DbAdapter, DbQueryResult, DbTransaction } from "./adapter.ts";
3
5
 
4
6
  function toQueryResult(result: {
@@ -45,7 +47,80 @@ export class PgliteAdapter implements DbAdapter {
45
47
  }
46
48
 
47
49
  export async function createPgliteAdapter(dataDir: string): Promise<DbAdapter> {
50
+ mkdirSync(dataDir, { recursive: true });
51
+ repairStalePgliteStore(dataDir);
48
52
  const adapter = new PgliteAdapter(dataDir);
49
- await adapter.query("SELECT 1");
50
- return adapter;
53
+ try {
54
+ await adapter.query("SELECT 1");
55
+ return adapter;
56
+ } catch (error) {
57
+ await adapter.close().catch(() => undefined);
58
+ throw error;
59
+ }
60
+ }
61
+
62
+ function repairStalePgliteStore(dataDir: string): void {
63
+ const pidPath = join(dataDir, "postmaster.pid");
64
+ if (!existsSync(pidPath)) {
65
+ return;
66
+ }
67
+
68
+ const rawPid = readFileSync(pidPath, "utf8").split(/\r?\n/, 1)[0]?.trim();
69
+ const pid = rawPid ? Number(rawPid) : NaN;
70
+ const stale =
71
+ !Number.isInteger(pid) ||
72
+ pid <= 0 ||
73
+ !isProcessAlive(pid);
74
+
75
+ if (!stale) {
76
+ return;
77
+ }
78
+
79
+ removeStalePgliteLocks(dataDir);
80
+ }
81
+
82
+ function removeStalePgliteLocks(dataDir: string): void {
83
+ for (const file of [
84
+ "postmaster.pid",
85
+ ".s.PGSQL.5432.lock",
86
+ ".s.PGSQL.5432.lock.out",
87
+ ]) {
88
+ try {
89
+ unlinkSync(join(dataDir, file));
90
+ } catch {
91
+ // Best effort. If PGlite still cannot open, the caller reports the real open error.
92
+ }
93
+ }
94
+ }
95
+
96
+ export function archivePgliteStore(dataDir: string, reason = "repair"): string | null {
97
+ if (!existsSync(dataDir)) {
98
+ return null;
99
+ }
100
+
101
+ const parent = dirname(dataDir);
102
+ const backupsDir = join(parent, `${basename(dataDir)}.backups`);
103
+ mkdirSync(backupsDir, { recursive: true });
104
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
105
+ const backupPath = join(backupsDir, `${basename(dataDir)}.${reason}.${stamp}`);
106
+
107
+ try {
108
+ renameSync(dataDir, backupPath);
109
+ mkdirSync(dataDir, { recursive: true });
110
+ return backupPath;
111
+ } catch {
112
+ rmSync(join(dataDir, "postmaster.pid"), { force: true });
113
+ rmSync(join(dataDir, ".s.PGSQL.5432.lock"), { force: true });
114
+ rmSync(join(dataDir, ".s.PGSQL.5432.lock.out"), { force: true });
115
+ return null;
116
+ }
117
+ }
118
+
119
+ function isProcessAlive(pid: number): boolean {
120
+ try {
121
+ process.kill(pid, 0);
122
+ return true;
123
+ } catch {
124
+ return false;
125
+ }
51
126
  }