forgeos 0.1.0-alpha.4 → 0.1.0-alpha.41

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 (416) hide show
  1. package/.npmignore +10 -0
  2. package/AGENTS.md +142 -90
  3. package/CHANGELOG.md +433 -0
  4. package/LICENSE +21 -0
  5. package/README.md +67 -8
  6. package/adapters/go/README.md +23 -0
  7. package/adapters/go/go.mod +3 -0
  8. package/adapters/go/http.go +149 -0
  9. package/adapters/go/registry.go +234 -0
  10. package/adapters/go/types.go +136 -0
  11. package/adapters/java/README.md +68 -0
  12. package/adapters/java/pom.xml +34 -0
  13. package/adapters/java/src/main/java/dev/forgeos/adapter/Auth.java +20 -0
  14. package/adapters/java/src/main/java/dev/forgeos/adapter/Diagnostic.java +16 -0
  15. package/adapters/java/src/main/java/dev/forgeos/adapter/Entry.java +38 -0
  16. package/adapters/java/src/main/java/dev/forgeos/adapter/EntryKind.java +16 -0
  17. package/adapters/java/src/main/java/dev/forgeos/adapter/ErrorInfo.java +4 -0
  18. package/adapters/java/src/main/java/dev/forgeos/adapter/Forge.java +94 -0
  19. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeCall.java +12 -0
  20. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeContext.java +11 -0
  21. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHandler.java +8 -0
  22. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHttpHandler.java +179 -0
  23. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeRegistry.java +121 -0
  24. package/adapters/java/src/main/java/dev/forgeos/adapter/Json.java +14 -0
  25. package/adapters/java/src/main/java/dev/forgeos/adapter/Manifest.java +14 -0
  26. package/adapters/java/src/main/java/dev/forgeos/adapter/RequestEnvelope.java +6 -0
  27. package/adapters/java/src/main/java/dev/forgeos/adapter/ResponseEnvelope.java +25 -0
  28. package/adapters/java/src/main/java/dev/forgeos/adapter/Risk.java +18 -0
  29. package/adapters/java/src/main/java/dev/forgeos/adapter/Schemas.java +36 -0
  30. package/adapters/java/src/main/java/dev/forgeos/adapter/Service.java +65 -0
  31. package/adapters/java/src/main/java/dev/forgeos/adapter/TransactionMode.java +18 -0
  32. package/adapters/java/src/main/java/dev/forgeos/adapter/TypedForgeHandler.java +6 -0
  33. package/adapters/java-spring-boot-starter/README.md +32 -0
  34. package/adapters/java-spring-boot-starter/pom.xml +36 -0
  35. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeCommand.java +22 -0
  36. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeExternalService.java +15 -0
  37. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeQuery.java +16 -0
  38. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeServiceBeanCondition.java +18 -0
  39. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringAutoConfiguration.java +16 -0
  40. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringRuntime.java +104 -0
  41. package/adapters/java-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +1 -0
  42. package/bin/forge.mjs +18 -0
  43. package/docs/cair-protocol.md +103 -0
  44. package/docs/changelog.md +548 -0
  45. package/docs/forge-protocol.md +189 -0
  46. package/examples/go-billing/go.mod +7 -0
  47. package/examples/go-billing/main.go +120 -0
  48. package/examples/java-billing/pom.xml +52 -0
  49. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/CreateInvoiceInput.java +4 -0
  50. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Invoice.java +11 -0
  51. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Main.java +127 -0
  52. package/package.json +31 -3
  53. package/schemas/forge-manifest.schema.json +57 -0
  54. package/src/forge/_generated/releaseManifest.json +1 -2
  55. package/src/forge/_generated/releaseManifest.ts +3 -3
  56. package/src/forge/agent-adapters/index.ts +1584 -125
  57. package/src/forge/agent-adapters/types.ts +224 -1
  58. package/src/forge/agent-memory/bridge.ts +1333 -0
  59. package/src/forge/agent-memory/context-pack.ts +277 -0
  60. package/src/forge/agent-memory/hook-runner.ts +312 -0
  61. package/src/forge/agent-memory/mcp.ts +224 -0
  62. package/src/forge/agent-memory/normalize.ts +498 -0
  63. package/src/forge/agent-memory/redaction.ts +103 -0
  64. package/src/forge/agent-memory/sources/claude-code.ts +51 -0
  65. package/src/forge/agent-memory/sources/codex-hook-runner.mjs +273 -0
  66. package/src/forge/agent-memory/sources/codex.ts +119 -0
  67. package/src/forge/agent-memory/sources/cursor.ts +35 -0
  68. package/src/forge/agent-memory/types.ts +204 -0
  69. package/src/forge/bench.ts +248 -0
  70. package/src/forge/brownfield-import/index.ts +801 -0
  71. package/src/forge/brownfield-import/types.ts +127 -0
  72. package/src/forge/cair/action-journal.ts +61 -0
  73. package/src/forge/cair/action-parser.ts +314 -0
  74. package/src/forge/cair/action-validator.ts +40 -0
  75. package/src/forge/cair/actions.ts +1818 -0
  76. package/src/forge/cair/format.ts +77 -0
  77. package/src/forge/cair/index.ts +106 -0
  78. package/src/forge/cair/query.ts +478 -0
  79. package/src/forge/cair/snapshot.ts +315 -0
  80. package/src/forge/cair/types.ts +248 -0
  81. package/src/forge/cli/ai.ts +339 -21
  82. package/src/forge/cli/auth.ts +348 -10
  83. package/src/forge/cli/authmd.ts +441 -0
  84. package/src/forge/cli/baseline.ts +112 -0
  85. package/src/forge/cli/build.ts +20 -4
  86. package/src/forge/cli/changed.ts +437 -0
  87. package/src/forge/cli/codex-app-server.ts +877 -0
  88. package/src/forge/cli/commands.ts +1620 -20
  89. package/src/forge/cli/db.ts +209 -2
  90. package/src/forge/cli/deploy.ts +887 -0
  91. package/src/forge/cli/deps.ts +82 -13
  92. package/src/forge/cli/dev.ts +961 -46
  93. package/src/forge/cli/docs.ts +265 -0
  94. package/src/forge/cli/doctor.ts +297 -0
  95. package/src/forge/cli/field-test.ts +329 -0
  96. package/src/forge/cli/handoff.ts +336 -0
  97. package/src/forge/cli/index.ts +1 -0
  98. package/src/forge/cli/last-run.ts +84 -0
  99. package/src/forge/cli/main.ts +107 -3
  100. package/src/forge/cli/new.ts +152 -13
  101. package/src/forge/cli/next-actions.ts +23 -0
  102. package/src/forge/cli/output.ts +389 -6
  103. package/src/forge/cli/parse.ts +1050 -34
  104. package/src/forge/cli/progress.ts +51 -0
  105. package/src/forge/cli/query.ts +32 -0
  106. package/src/forge/cli/release.ts +35 -11
  107. package/src/forge/cli/rls.ts +43 -4
  108. package/src/forge/cli/run.ts +41 -0
  109. package/src/forge/cli/security.ts +112 -0
  110. package/src/forge/cli/self-host.ts +56 -14
  111. package/src/forge/cli/studio.ts +2218 -0
  112. package/src/forge/cli/verify.ts +1455 -32
  113. package/src/forge/cli/windows.ts +23 -0
  114. package/src/forge/cli/workos.ts +1020 -0
  115. package/src/forge/compiler/agent-contract/build.ts +670 -64
  116. package/src/forge/compiler/agent-contract/types.ts +45 -2
  117. package/src/forge/compiler/ai-registry/parse.ts +71 -2
  118. package/src/forge/compiler/api-surface/build.ts +47 -0
  119. package/src/forge/compiler/app-graph/build.ts +112 -9
  120. package/src/forge/compiler/app-graph/extract.ts +107 -0
  121. package/src/forge/compiler/app-graph/module-graph.ts +73 -78
  122. package/src/forge/compiler/app-graph/parser.ts +24 -24
  123. package/src/forge/compiler/app-graph/profile.ts +26 -0
  124. package/src/forge/compiler/app-graph/versions.ts +1 -1
  125. package/src/forge/compiler/classifier/capabilities.ts +3 -2
  126. package/src/forge/compiler/classifier/classify.ts +32 -8
  127. package/src/forge/compiler/classifier/secrets.ts +3 -2
  128. package/src/forge/compiler/classifier/signals.ts +91 -1
  129. package/src/forge/compiler/client-sdk/build-manifest.ts +59 -0
  130. package/src/forge/compiler/client-sdk/render-client.ts +295 -13
  131. package/src/forge/compiler/data-graph/parse.ts +20 -4
  132. package/src/forge/compiler/data-graph/sql/ddl.ts +144 -31
  133. package/src/forge/compiler/data-graph/sql/serialize.ts +4 -0
  134. package/src/forge/compiler/data-graph/sql/types.ts +1 -0
  135. package/src/forge/compiler/diagnostics/codes.ts +30 -0
  136. package/src/forge/compiler/diagnostics/create.ts +21 -2
  137. package/src/forge/compiler/diagnostics/index.ts +2 -0
  138. package/src/forge/compiler/emitter/barrel.ts +3 -0
  139. package/src/forge/compiler/emitter/render.ts +9 -0
  140. package/src/forge/compiler/external-manifest/registry.ts +205 -0
  141. package/src/forge/compiler/external-manifest/types.ts +91 -0
  142. package/src/forge/compiler/external-manifest/validate.ts +373 -0
  143. package/src/forge/compiler/frontend-graph/build.ts +142 -14
  144. package/src/forge/compiler/integration/add.ts +618 -24
  145. package/src/forge/compiler/integration/plan.ts +43 -12
  146. package/src/forge/compiler/integration/render.ts +29 -0
  147. package/src/forge/compiler/integration/snapshot.ts +2 -0
  148. package/src/forge/compiler/integration/templates/convex.ts +70 -0
  149. package/src/forge/compiler/integration/templates/index.ts +1 -0
  150. package/src/forge/compiler/integration/templates/render.ts +38 -0
  151. package/src/forge/compiler/integration/templates/types.ts +3 -0
  152. package/src/forge/compiler/integration/templates/workos.ts +1219 -0
  153. package/src/forge/compiler/make-registry/build.ts +8 -9
  154. package/src/forge/compiler/orchestrator/fast-check.ts +4 -0
  155. package/src/forge/compiler/orchestrator/generate-lock.ts +14 -3
  156. package/src/forge/compiler/orchestrator/manifest.ts +1 -1
  157. package/src/forge/compiler/orchestrator/plan-profile.ts +23 -0
  158. package/src/forge/compiler/orchestrator/plan.ts +247 -10
  159. package/src/forge/compiler/orchestrator/profile.ts +65 -0
  160. package/src/forge/compiler/orchestrator/run.ts +97 -31
  161. package/src/forge/compiler/orchestrator/serialize.ts +33 -8
  162. package/src/forge/compiler/orchestrator/types.ts +1 -1
  163. package/src/forge/compiler/package-graph/compiler.ts +3 -1
  164. package/src/forge/compiler/package-graph/constants.ts +1 -1
  165. package/src/forge/compiler/package-manager/adapter.ts +4 -1
  166. package/src/forge/compiler/package-manager/commands.ts +4 -0
  167. package/src/forge/compiler/package-manager/executor.ts +30 -1
  168. package/src/forge/compiler/package-manager/version.ts +36 -12
  169. package/src/forge/compiler/package-upgrades/planner.ts +155 -18
  170. package/src/forge/compiler/package-upgrades/types.ts +2 -0
  171. package/src/forge/compiler/policy-registry/build.ts +47 -2
  172. package/src/forge/compiler/policy-registry/parse.ts +32 -2
  173. package/src/forge/compiler/recipes/definitions.ts +63 -0
  174. package/src/forge/compiler/recipes/index.ts +2 -0
  175. package/src/forge/compiler/recipes/registry.ts +6 -0
  176. package/src/forge/compiler/test-graph/build.ts +11 -3
  177. package/src/forge/compiler/types/app-graph.ts +8 -2
  178. package/src/forge/compiler/types/cli.ts +75 -1
  179. package/src/forge/compiler/types/dev-manifest.ts +4 -0
  180. package/src/forge/compiler/types/emit.ts +2 -0
  181. package/src/forge/compiler/types/frontend-graph.ts +2 -2
  182. package/src/forge/compiler/types/integration.ts +1 -0
  183. package/src/forge/compiler/types/package-graph.ts +6 -0
  184. package/src/forge/compiler/types/policy-registry.ts +3 -1
  185. package/src/forge/delta/classifier.ts +52 -0
  186. package/src/forge/delta/explain.ts +238 -0
  187. package/src/forge/delta/git-observer.ts +43 -0
  188. package/src/forge/delta/ids.ts +44 -0
  189. package/src/forge/delta/index.ts +25 -0
  190. package/src/forge/delta/recorder.ts +540 -0
  191. package/src/forge/delta/redaction.ts +50 -0
  192. package/src/forge/delta/schema.ts +240 -0
  193. package/src/forge/delta/session.ts +142 -0
  194. package/src/forge/delta/status.ts +1202 -0
  195. package/src/forge/delta/store.ts +3284 -0
  196. package/src/forge/delta/timeline.ts +178 -0
  197. package/src/forge/dev/server.ts +808 -17
  198. package/src/forge/dev/types.ts +15 -1
  199. package/src/forge/dev/watch.ts +17 -7
  200. package/src/forge/dev-console/cycle.ts +280 -33
  201. package/src/forge/dev-console/types.ts +47 -1
  202. package/src/forge/impact/index.ts +204 -9
  203. package/src/forge/impact/types.ts +33 -1
  204. package/src/forge/intent/index.ts +35 -16
  205. package/src/forge/make/fields.ts +26 -0
  206. package/src/forge/make/index.ts +40 -6
  207. package/src/forge/make/templates.ts +155 -2
  208. package/src/forge/make/types.ts +2 -1
  209. package/src/forge/policy.ts +1 -1
  210. package/src/forge/react/index.ts +160 -2
  211. package/src/forge/refactor/index.ts +1 -0
  212. package/src/forge/repair/rules/index.ts +2 -2
  213. package/src/forge/review/index.ts +158 -12
  214. package/src/forge/review/types.ts +15 -0
  215. package/src/forge/runtime/auth/config.ts +17 -0
  216. package/src/forge/runtime/auth/evaluate.ts +15 -2
  217. package/src/forge/runtime/auth/resolve.ts +61 -6
  218. package/src/forge/runtime/auth/types.ts +1 -0
  219. package/src/forge/runtime/db/factory.ts +1 -3
  220. package/src/forge/runtime/db/generated-client.ts +13 -2
  221. package/src/forge/runtime/db/memory-adapter.ts +139 -32
  222. package/src/forge/runtime/db/pglite-adapter.ts +263 -2
  223. package/src/forge/runtime/db/postgres-adapter.ts +6 -3
  224. package/src/forge/runtime/executor.ts +129 -16
  225. package/src/forge/runtime/external/bridge.ts +649 -0
  226. package/src/forge/runtime/runner/run-entry.ts +16 -7
  227. package/src/forge/runtime/telemetry/buffer.ts +4 -1
  228. package/src/forge/runtime/telemetry/scrubber.ts +35 -5
  229. package/src/forge/runtime/webhooks/security.ts +12 -7
  230. package/src/forge/server.ts +17 -3
  231. package/src/forge/ui/index.ts +209 -0
  232. package/src/forge/ui/types.ts +1 -0
  233. package/src/forge/version.ts +1 -1
  234. package/src/forge/vue/index.ts +422 -0
  235. package/src/forge/workspace/baseline.ts +112 -0
  236. package/src/forge/workspace/change-summary.ts +250 -0
  237. package/src/forge/workspace/forge-cli.ts +42 -0
  238. package/src/forge/workspace/git-summary.ts +391 -0
  239. package/templates/agent-workroom/AGENTS.md +29 -0
  240. package/templates/agent-workroom/README.md +34 -0
  241. package/templates/agent-workroom/forge.config.ts +3 -0
  242. package/templates/agent-workroom/package.json +33 -0
  243. package/templates/agent-workroom/src/actions/indexAgentSignal.ts +10 -0
  244. package/templates/agent-workroom/src/commands/openWorkroom.ts +61 -0
  245. package/templates/agent-workroom/src/commands/recordAgentSignal.ts +119 -0
  246. package/templates/agent-workroom/src/commands/recordCheckRun.ts +52 -0
  247. package/templates/agent-workroom/src/forge/schema.ts +54 -0
  248. package/templates/agent-workroom/src/policies.ts +6 -0
  249. package/templates/agent-workroom/src/queries/listWorkrooms.ts +11 -0
  250. package/templates/agent-workroom/src/queries/liveWorkroom.ts +63 -0
  251. package/templates/agent-workroom/tsconfig.json +16 -0
  252. package/templates/agent-workroom/web/index.html +12 -0
  253. package/templates/agent-workroom/web/package.json +21 -0
  254. package/templates/agent-workroom/web/src/App.tsx +345 -0
  255. package/templates/agent-workroom/web/src/lib/forge.ts +13 -0
  256. package/templates/agent-workroom/web/src/main.tsx +13 -0
  257. package/templates/agent-workroom/web/src/styles.css +545 -0
  258. package/templates/agent-workroom/web/tsconfig.json +27 -0
  259. package/templates/b2b-support-web/package.json +1 -0
  260. package/templates/b2b-support-web/web/package.json +1 -1
  261. package/templates/minimal-web/package.json +1 -1
  262. package/templates/minimal-web/web/package.json +2 -2
  263. package/templates/nuxt-web/.vscode/settings.json +14 -0
  264. package/templates/nuxt-web/README.md +30 -0
  265. package/templates/nuxt-web/forge.config.ts +3 -0
  266. package/templates/nuxt-web/package.json +33 -0
  267. package/templates/nuxt-web/src/actions/logNoteCreated.ts +11 -0
  268. package/templates/nuxt-web/src/commands/createNote.ts +26 -0
  269. package/templates/nuxt-web/src/forge/schema.ts +12 -0
  270. package/templates/nuxt-web/src/policies.ts +6 -0
  271. package/templates/nuxt-web/src/queries/listNotes.ts +8 -0
  272. package/templates/nuxt-web/src/queries/liveNotes.ts +8 -0
  273. package/templates/nuxt-web/tsconfig.json +17 -0
  274. package/templates/nuxt-web/web/app.vue +67 -0
  275. package/templates/nuxt-web/web/components/LiveNotes.vue +89 -0
  276. package/templates/nuxt-web/web/components/NoteComposer.vue +100 -0
  277. package/templates/nuxt-web/web/composables/forge.ts +13 -0
  278. package/templates/nuxt-web/web/composables/useNotes.ts +24 -0
  279. package/templates/nuxt-web/web/nuxt.config.ts +11 -0
  280. package/templates/nuxt-web/web/package.json +18 -0
  281. package/templates/nuxt-web/web/plugins/forge.client.ts +10 -0
  282. package/templates/nuxt-web/web/plugins/forge.server.ts +10 -0
  283. package/templates/nuxt-web/web/server/api/forge-health.get.ts +7 -0
  284. package/templates/nuxt-web/web/tsconfig.json +6 -0
  285. package/src/forge/_generated/actionSubscriptions.json +0 -2
  286. package/src/forge/_generated/actionSubscriptions.ts +0 -10
  287. package/src/forge/_generated/agentAdapterManifest.json +0 -2
  288. package/src/forge/_generated/agentAdapterManifest.ts +0 -73
  289. package/src/forge/_generated/agentContract.json +0 -2
  290. package/src/forge/_generated/agentContract.ts +0 -7829
  291. package/src/forge/_generated/agentQuickstart.md +0 -34
  292. package/src/forge/_generated/agentTools.json +0 -2
  293. package/src/forge/_generated/agentTools.md +0 -16
  294. package/src/forge/_generated/agentTools.ts +0 -12
  295. package/src/forge/_generated/aiContext.ts +0 -125
  296. package/src/forge/_generated/aiModels.json +0 -2
  297. package/src/forge/_generated/aiModels.ts +0 -51
  298. package/src/forge/_generated/aiProviders.json +0 -2
  299. package/src/forge/_generated/aiProviders.ts +0 -23
  300. package/src/forge/_generated/aiRegistry.json +0 -2
  301. package/src/forge/_generated/aiRegistry.ts +0 -31
  302. package/src/forge/_generated/api.json +0 -2
  303. package/src/forge/_generated/api.ts +0 -8
  304. package/src/forge/_generated/appGraph.json +0 -2
  305. package/src/forge/_generated/appGraph.ts +0 -14919
  306. package/src/forge/_generated/appMap.md +0 -55
  307. package/src/forge/_generated/artifactManifest.json +0 -2
  308. package/src/forge/_generated/artifactManifest.ts +0 -7
  309. package/src/forge/_generated/authClaims.json +0 -2
  310. package/src/forge/_generated/authClaims.ts +0 -13
  311. package/src/forge/_generated/authConfig.json +0 -2
  312. package/src/forge/_generated/authConfig.ts +0 -17
  313. package/src/forge/_generated/authContext.ts +0 -23
  314. package/src/forge/_generated/authRegistry.json +0 -2
  315. package/src/forge/_generated/authRegistry.ts +0 -25
  316. package/src/forge/_generated/buildInfo.json +0 -2
  317. package/src/forge/_generated/buildInfo.ts +0 -9
  318. package/src/forge/_generated/capabilityMap.json +0 -2
  319. package/src/forge/_generated/capabilityMap.md +0 -15
  320. package/src/forge/_generated/capabilityMap.ts +0 -17
  321. package/src/forge/_generated/client.ts +0 -282
  322. package/src/forge/_generated/clientApi.ts +0 -9
  323. package/src/forge/_generated/clientManifest.json +0 -2
  324. package/src/forge/_generated/clientManifest.ts +0 -39
  325. package/src/forge/_generated/clientTypes.ts +0 -78
  326. package/src/forge/_generated/configRegistry.json +0 -2
  327. package/src/forge/_generated/configRegistry.ts +0 -4
  328. package/src/forge/_generated/dataGraph.json +0 -2
  329. package/src/forge/_generated/dataGraph.ts +0 -8
  330. package/src/forge/_generated/db.json +0 -2
  331. package/src/forge/_generated/db.ts +0 -2
  332. package/src/forge/_generated/dbSecurityManifest.json +0 -2
  333. package/src/forge/_generated/dbSecurityManifest.ts +0 -15
  334. package/src/forge/_generated/dbSessionContext.json +0 -2
  335. package/src/forge/_generated/dbSessionContext.ts +0 -39
  336. package/src/forge/_generated/deployManifest.json +0 -2
  337. package/src/forge/_generated/deployManifest.ts +0 -14
  338. package/src/forge/_generated/devManifest.json +0 -2
  339. package/src/forge/_generated/devManifest.ts +0 -62
  340. package/src/forge/_generated/envSchema.json +0 -2
  341. package/src/forge/_generated/envSchema.ts +0 -59
  342. package/src/forge/_generated/frontendGraph.json +0 -2
  343. package/src/forge/_generated/frontendGraph.ts +0 -27
  344. package/src/forge/_generated/importGuards.json +0 -2
  345. package/src/forge/_generated/importGuards.ts +0 -686
  346. package/src/forge/_generated/index.ts +0 -68
  347. package/src/forge/_generated/liveProductionManifest.json +0 -2
  348. package/src/forge/_generated/liveProductionManifest.ts +0 -23
  349. package/src/forge/_generated/liveProtocol.json +0 -2
  350. package/src/forge/_generated/liveProtocol.ts +0 -21
  351. package/src/forge/_generated/liveQueryRegistry.json +0 -2
  352. package/src/forge/_generated/liveQueryRegistry.ts +0 -9
  353. package/src/forge/_generated/liveTransportConfig.json +0 -2
  354. package/src/forge/_generated/liveTransportConfig.ts +0 -19
  355. package/src/forge/_generated/makeRegistry.json +0 -2
  356. package/src/forge/_generated/makeRegistry.ts +0 -177
  357. package/src/forge/_generated/makeTemplates.json +0 -2
  358. package/src/forge/_generated/makeTemplates.ts +0 -66
  359. package/src/forge/_generated/mockMap.json +0 -2
  360. package/src/forge/_generated/mockMap.ts +0 -7
  361. package/src/forge/_generated/operationPlaybooks.md +0 -167
  362. package/src/forge/_generated/packageGraph.json +0 -2
  363. package/src/forge/_generated/packageGraph.ts +0 -249334
  364. package/src/forge/_generated/packageUpgradeRegistry.json +0 -2
  365. package/src/forge/_generated/packageUpgradeRegistry.ts +0 -15
  366. package/src/forge/_generated/permissionMatrix.json +0 -2
  367. package/src/forge/_generated/permissionMatrix.ts +0 -7
  368. package/src/forge/_generated/policyRegistry.json +0 -2
  369. package/src/forge/_generated/policyRegistry.ts +0 -11
  370. package/src/forge/_generated/queryRegistry.json +0 -2
  371. package/src/forge/_generated/queryRegistry.ts +0 -9
  372. package/src/forge/_generated/react.d.ts +0 -22
  373. package/src/forge/_generated/react.ts +0 -29
  374. package/src/forge/_generated/reactManifest.json +0 -2
  375. package/src/forge/_generated/reactManifest.ts +0 -19
  376. package/src/forge/_generated/rlsPolicies.json +0 -2
  377. package/src/forge/_generated/rlsPolicies.sql +0 -34
  378. package/src/forge/_generated/rlsPolicies.ts +0 -6
  379. package/src/forge/_generated/runtimeGraph.json +0 -2
  380. package/src/forge/_generated/runtimeGraph.ts +0 -8
  381. package/src/forge/_generated/runtimeMatrix.json +0 -2
  382. package/src/forge/_generated/runtimeMatrix.ts +0 -334130
  383. package/src/forge/_generated/runtimeRegistry.ts +0 -2
  384. package/src/forge/_generated/runtimeRules.md +0 -91
  385. package/src/forge/_generated/secretRegistry.json +0 -2
  386. package/src/forge/_generated/secretRegistry.ts +0 -50
  387. package/src/forge/_generated/secretsContext.ts +0 -11
  388. package/src/forge/_generated/serverApi.ts +0 -10
  389. package/src/forge/_generated/sourceMapManifest.json +0 -2
  390. package/src/forge/_generated/sourceMapManifest.ts +0 -7
  391. package/src/forge/_generated/sqlPlan.json +0 -2
  392. package/src/forge/_generated/sqlPlan.ts +0 -88
  393. package/src/forge/_generated/subscriptionManifest.json +0 -2
  394. package/src/forge/_generated/subscriptionManifest.ts +0 -7
  395. package/src/forge/_generated/symbolicationManifest.json +0 -2
  396. package/src/forge/_generated/symbolicationManifest.ts +0 -17
  397. package/src/forge/_generated/telemetryRegistry.json +0 -2
  398. package/src/forge/_generated/telemetryRegistry.ts +0 -9
  399. package/src/forge/_generated/telemetrySinks.json +0 -2
  400. package/src/forge/_generated/telemetrySinks.ts +0 -11
  401. package/src/forge/_generated/tenantScope.json +0 -2
  402. package/src/forge/_generated/tenantScope.ts +0 -8
  403. package/src/forge/_generated/testGraph.json +0 -2
  404. package/src/forge/_generated/testGraph.ts +0 -3430
  405. package/src/forge/_generated/testPlanRegistry.json +0 -2
  406. package/src/forge/_generated/testPlanRegistry.ts +0 -33
  407. package/src/forge/_generated/uiRoutes.json +0 -2
  408. package/src/forge/_generated/uiRoutes.ts +0 -16
  409. package/src/forge/_generated/uiScenarios.json +0 -2
  410. package/src/forge/_generated/uiScenarios.ts +0 -30
  411. package/src/forge/_generated/uiTestManifest.json +0 -2
  412. package/src/forge/_generated/uiTestManifest.ts +0 -27
  413. package/src/forge/_generated/workflowRegistry.json +0 -2
  414. package/src/forge/_generated/workflowRegistry.ts +0 -9
  415. package/src/forge/_generated/workflowSubscriptions.json +0 -2
  416. package/src/forge/_generated/workflowSubscriptions.ts +0 -10
@@ -6,6 +6,8 @@ import { serializeCanonical } from "../compiler/primitives/serialize.ts";
6
6
  import { stripDeterministicHeader } from "../compiler/primitives/header.ts";
7
7
  import { analyzeImpact, buildImpactTestPlan, detectChangedFiles } from "../impact/index.ts";
8
8
  import type { ImpactCommandOptions, ImpactSource } from "../impact/types.ts";
9
+ import { buildDiffPlanFromChangeSummary, categorizeFiles } from "../workspace/change-summary.ts";
10
+ import type { CategorizedFileSummary, ChangeType } from "../workspace/change-summary.ts";
9
11
  import type {
10
12
  ReviewChanged,
11
13
  ReviewCommandOptions,
@@ -14,6 +16,8 @@ import type {
14
16
  ReviewFinding,
15
17
  ReviewFindingCategory,
16
18
  ReviewFindingSeverity,
19
+ ReviewFocus,
20
+ ReviewDiffPlan,
17
21
  ReviewReport,
18
22
  ReviewResult,
19
23
  ReviewRisk,
@@ -41,6 +45,21 @@ const ALL_CATEGORIES: ReviewFindingCategory[] = [
41
45
  "agent",
42
46
  ];
43
47
 
48
+ const SYSTEM_ENV_NAMES = new Set([
49
+ "CI",
50
+ "HOME",
51
+ "PATH",
52
+ "PWD",
53
+ "SHELL",
54
+ "TEMP",
55
+ "TMP",
56
+ "USER",
57
+ "USERNAME",
58
+ "USERPROFILE",
59
+ ]);
60
+
61
+ const SECRET_ENV_PATTERN = /(^|_)(API_KEY|AUTH_TOKEN|CLIENT_SECRET|CREDENTIALS|JWT_SECRET|PASSWORD|PRIVATE_KEY|SECRET|SECRET_KEY|TOKEN|WEBHOOK_SECRET)$/;
62
+
44
63
  const RULE_DOCS: ReviewRuleDoc[] = [
45
64
  {
46
65
  id: "runtime-command-forbidden-import",
@@ -124,6 +143,32 @@ function changedFromFiles(files: string[]): ReviewChanged {
124
143
  };
125
144
  }
126
145
 
146
+ function buildReviewFocus(changeSummary: CategorizedFileSummary): ReviewFocus {
147
+ const authoredOrder = ([
148
+ "source",
149
+ "tests",
150
+ "docs",
151
+ "config",
152
+ "operational",
153
+ "assets",
154
+ "other",
155
+ ] satisfies ChangeType[])
156
+ .filter((type) => changeSummary.byType[type].count > 0);
157
+ const suggestedOrder: ChangeType[] = [...authoredOrder];
158
+ if (changeSummary.byType.generated.count > 0) {
159
+ suggestedOrder.push("generated");
160
+ }
161
+ return {
162
+ first: "authoredChanges",
163
+ then: "derivedArtifacts",
164
+ generatedIsDerived: true,
165
+ suggestedOrder,
166
+ summary: changeSummary.byType.generated.count > 0
167
+ ? "Review authored changes first; inspect generated artifacts after the source cause is understood."
168
+ : "Review authored changes directly; no generated artifacts changed.",
169
+ };
170
+ }
171
+
127
172
  function loadContext(options: ReviewCommandOptions): ReviewContext {
128
173
  const source = sourceFromOptions(options);
129
174
  const impactSource = impactSourceFromReview(source);
@@ -190,9 +235,22 @@ function isTestFile(file: string): boolean {
190
235
  return /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(file) || normalize(file).startsWith("tests/");
191
236
  }
192
237
 
238
+ function isDocumentationFile(file: string): boolean {
239
+ const normalized = normalize(file);
240
+ return normalized.startsWith("docs/") ||
241
+ normalized.startsWith("marketing/") ||
242
+ normalized.endsWith(".md") ||
243
+ normalized.endsWith(".mdx");
244
+ }
245
+
193
246
  function isForgeToolingFile(file: string): boolean {
194
247
  const normalized = normalize(file);
195
- return normalized.startsWith("src/forge/cli/") || normalized.startsWith("src/forge/review/");
248
+ return normalized.startsWith("src/forge/cli/") ||
249
+ normalized.startsWith("src/forge/review/") ||
250
+ normalized.startsWith("src/forge/dev/") ||
251
+ normalized.startsWith("src/forge/dev-console/") ||
252
+ normalized.startsWith("src/forge/compiler/package-manager/") ||
253
+ normalized.startsWith("src/forge/compiler/integration/");
196
254
  }
197
255
 
198
256
  function includesCategory(options: ReviewCommandOptions, category: ReviewFindingCategory): boolean {
@@ -200,20 +258,47 @@ function includesCategory(options: ReviewCommandOptions, category: ReviewFinding
200
258
  return options.include.length === 0 || options.include.includes(category);
201
259
  }
202
260
 
203
- function secretNamesFromText(text: string): string[] {
261
+ function processEnvNamesFromText(text: string): string[] {
204
262
  const names = new Set<string>();
205
- for (const regex of [/process\.env\.([A-Z0-9_]+)/g, /process\.env\[['"]([A-Z0-9_]+)['"]\]/g, /ctx\.secrets\.get\(['"]([A-Z0-9_]+)['"]\)/g]) {
263
+ for (const regex of [/process\.env\.([A-Z0-9_]+)/g, /process\.env\[['"]([A-Z0-9_]+)['"]\]/g]) {
206
264
  let match: RegExpExecArray | null;
207
265
  while ((match = regex.exec(text))) names.add(match[1]);
208
266
  }
209
267
  return [...names].sort();
210
268
  }
211
269
 
212
- function processEnvNamesFromText(text: string): string[] {
270
+ function ctxSecretNamesFromText(text: string): string[] {
271
+ const names = new Set<string>();
272
+ const regex = /ctx\.secrets\.get\(['"]([A-Z0-9_]+)['"]\)/g;
273
+ let match: RegExpExecArray | null;
274
+ while ((match = regex.exec(text))) names.add(match[1]);
275
+ return [...names].sort();
276
+ }
277
+
278
+ function isSecretEnvName(name: string): boolean {
279
+ if (SYSTEM_ENV_NAMES.has(name)) return false;
280
+ return SECRET_ENV_PATTERN.test(name);
281
+ }
282
+
283
+ function secretNamesFromText(text: string): string[] {
284
+ const names = new Set<string>();
285
+ for (const name of processEnvNamesFromText(text)) {
286
+ if (isSecretEnvName(name)) names.add(name);
287
+ }
288
+ for (const name of ctxSecretNamesFromText(text)) names.add(name);
289
+ return [...names].sort();
290
+ }
291
+
292
+ function publicSecretNamesFromText(text: string): string[] {
213
293
  const names = new Set<string>();
214
294
  for (const regex of [/process\.env\.([A-Z0-9_]+)/g, /process\.env\[['"]([A-Z0-9_]+)['"]\]/g]) {
215
295
  let match: RegExpExecArray | null;
216
- while ((match = regex.exec(text))) names.add(match[1]);
296
+ while ((match = regex.exec(text))) {
297
+ const name = match[1];
298
+ if ((name.startsWith("PUBLIC_") || name.startsWith("NEXT_PUBLIC_")) && isSecretEnvName(name)) {
299
+ names.add(name);
300
+ }
301
+ }
217
302
  }
218
303
  return [...names].sort();
219
304
  }
@@ -352,15 +437,16 @@ function secretRules(ctx: ReviewContext): ReviewFinding[] {
352
437
  const findings: ReviewFinding[] = [];
353
438
  const documented = ctx.envExample;
354
439
  for (const [file, text] of ctx.fileTexts) {
355
- if (isTestFile(file) || isForgeToolingFile(file)) continue;
440
+ if (isTestFile(file) || isDocumentationFile(file)) continue;
356
441
  const names = secretNamesFromText(text);
357
- if (processEnvNamesFromText(text).length > 0) {
442
+ const directSecretEnvNames = processEnvNamesFromText(text).filter(isSecretEnvName);
443
+ if (directSecretEnvNames.length > 0 && !isForgeToolingFile(file)) {
358
444
  findings.push(finding({
359
445
  severity: "error",
360
446
  category: "secrets",
361
447
  code: "secret-direct-process-env",
362
448
  title: "Direct process.env usage introduced",
363
- message: "ForgeOS code should access secrets through ctx.secrets or generated config context.",
449
+ message: `${directSecretEnvNames.join(", ")} should be accessed through ctx.secrets or generated config context.`,
364
450
  file,
365
451
  suggestedCommands: ["forge secrets check", "forge refactor replace-process-env <ENV_VAR>"],
366
452
  autoRepair: { available: true, command: "forge refactor replace-process-env <ENV_VAR>", confidence: "medium" },
@@ -378,7 +464,7 @@ function secretRules(ctx: ReviewContext): ReviewFinding[] {
378
464
  suggestedCommands: ["forge secrets check"],
379
465
  }));
380
466
  }
381
- if (/(_SECRET|SECRET_|TOKEN|KEY)/.test(name) && (name.startsWith("PUBLIC_") || name.startsWith("NEXT_PUBLIC_"))) {
467
+ if (publicSecretNamesFromText(text).includes(name)) {
382
468
  findings.push(finding({
383
469
  severity: "blocking",
384
470
  category: "secrets",
@@ -693,6 +779,9 @@ function buildReport(options: ReviewCommandOptions): ReviewReport {
693
779
  findings: findings.map((item) => [item.code, item.file, item.severity]),
694
780
  })).slice(0, 12)}`;
695
781
  const generatedPaths = ctx.changed.generated;
782
+ const changeSummary = categorizeFiles(ctx.changed.files);
783
+ const reviewFocus = buildReviewFocus(changeSummary);
784
+ const diffPlan: ReviewDiffPlan = buildDiffPlanFromChangeSummary(changeSummary);
696
785
  return {
697
786
  schemaVersion: "0.1.0",
698
787
  reviewVersion: REVIEW_VERSION,
@@ -709,6 +798,9 @@ function buildReport(options: ReviewCommandOptions): ReviewReport {
709
798
  risk,
710
799
  findings,
711
800
  changed: ctx.changed,
801
+ changeSummary,
802
+ reviewFocus,
803
+ diffPlan,
712
804
  impacted: ctx.impacted,
713
805
  checks: [
714
806
  { name: "impact-analysis", ok: true, message: `risk ${risk.level}` },
@@ -755,7 +847,13 @@ ${report.summary.bullets.map((bullet) => `- ${bullet}`).join("\n")}
755
847
 
756
848
  ## Changed Files
757
849
 
758
- ${report.changed.files.map((file) => `- ${file}`).join("\n") || "- none"}
850
+ ${report.changed.files.filter((file) => !file.startsWith(`${GENERATED}/`) && file !== "forge.lock").map((file) => `- ${file}`).join("\n") || "- none"}
851
+
852
+ Generated artifacts are derived and collapsed by default.
853
+
854
+ - Generated files: ${report.diffPlan.generatedFiles}
855
+ - Authored diff: \`${report.diffPlan.authoredDiffCommand}\`
856
+ - Generated diff: \`${report.diffPlan.generatedDiffCommand}\`
759
857
 
760
858
  ## Findings
761
859
 
@@ -958,8 +1056,54 @@ export function runReviewCommand(options: ReviewCommandOptions): ReviewResult {
958
1056
  }
959
1057
  }
960
1058
 
961
- export function formatReviewJson(result: ReviewResult): string {
962
- return `${JSON.stringify(result.report ?? result.reports ?? result.explanation ?? result, null, 2)}\n`;
1059
+ function compactReviewReport(result: ReviewResult): unknown {
1060
+ const report = result.report;
1061
+ if (!report) return result.reports ?? result.explanation ?? result;
1062
+ const impacted = {
1063
+ ...report.impacted,
1064
+ generatedArtifacts: report.impacted.generatedArtifacts.length,
1065
+ };
1066
+ return {
1067
+ schemaVersion: report.schemaVersion,
1068
+ reviewVersion: report.reviewVersion,
1069
+ ok: result.ok,
1070
+ id: report.id,
1071
+ source: report.source,
1072
+ summary: report.summary,
1073
+ risk: report.risk,
1074
+ findings: report.findings,
1075
+ changed: {
1076
+ files: report.changed.files.length,
1077
+ tests: report.changed.tests.length,
1078
+ sourceFiles: report.changed.sourceFiles.length,
1079
+ generated: report.changed.generated.length,
1080
+ packageFiles: report.changed.packageFiles.length,
1081
+ deployFiles: report.changed.deployFiles.length,
1082
+ },
1083
+ changeSummary: report.changeSummary,
1084
+ reviewFocus: report.reviewFocus,
1085
+ diffPlan: report.diffPlan,
1086
+ impacted,
1087
+ checks: report.checks,
1088
+ recommendedCommands: report.recommendedCommands,
1089
+ humanChecklist: report.humanChecklist,
1090
+ agentInstructions: report.agentInstructions,
1091
+ generatedArtifacts: {
1092
+ paths: report.generatedArtifacts.paths.length,
1093
+ stale: report.generatedArtifacts.stale,
1094
+ },
1095
+ writeResult: result.writeResult,
1096
+ diagnostics: result.diagnostics,
1097
+ exitCode: result.exitCode,
1098
+ fullCommand: "forge review run --changed --full --json",
1099
+ };
1100
+ }
1101
+
1102
+ export function formatReviewJson(result: ReviewResult, options: { full?: boolean } = {}): string {
1103
+ const payload = options.full
1104
+ ? result.report ?? result.reports ?? result.explanation ?? result
1105
+ : compactReviewReport(result);
1106
+ return `${JSON.stringify(payload, null, 2)}\n`;
963
1107
  }
964
1108
 
965
1109
  export function formatReviewHuman(result: ReviewResult): string {
@@ -978,6 +1122,8 @@ ${result.reports.map((report) => `- ${report.id}: ${report.dir}`).join("\n") ||
978
1122
 
979
1123
  Risk: ${report.risk.level} (${report.risk.score})
980
1124
  Findings: ${report.findings.length}
1125
+ Review focus: ${report.reviewFocus.summary}
1126
+ Review order: ${report.reviewFocus.suggestedOrder.join(" -> ") || "none"}
981
1127
 
982
1128
  Blocking issues:
983
1129
  ${report.findings.filter((finding) => finding.severity === "blocking").map((finding) => ` - ${finding.code}: ${finding.message}`).join("\n") || " - none"}
@@ -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[];
@@ -146,3 +146,20 @@ export function buildDefaultAuthRegistry(
146
146
  requiresTenant,
147
147
  };
148
148
  }
149
+
150
+ export function buildWorkOSAuthRegistry(
151
+ requiresTenant: boolean,
152
+ ): AuthRegistryArtifact {
153
+ return {
154
+ ...buildDefaultAuthRegistry(requiresTenant),
155
+ claims: {
156
+ userId: "sub",
157
+ tenantId: "organization_id",
158
+ role: "role",
159
+ roles: "roles",
160
+ permissions: "permissions",
161
+ email: "email",
162
+ name: "name",
163
+ },
164
+ };
165
+ }
@@ -22,6 +22,18 @@ function roleAllowed(
22
22
  return roles.some((role) => entry.roles.includes(role));
23
23
  }
24
24
 
25
+ function permissionAllowed(
26
+ matrix: PermissionMatrix,
27
+ policy: string,
28
+ permissions: string[],
29
+ ): boolean {
30
+ const entry = matrix.entries.find((candidate) => candidate.policy === policy);
31
+ if (!entry) {
32
+ return false;
33
+ }
34
+ return permissions.some((permission) => (entry.permissions ?? []).includes(permission));
35
+ }
36
+
25
37
  function authRoles(auth: Extract<AuthContext, { kind: "user" }>): string[] {
26
38
  return [...new Set([...(auth.role ? [auth.role] : []), ...(auth.roles ?? [])])];
27
39
  }
@@ -93,7 +105,8 @@ function evaluateAuthRequirement(
93
105
  }
94
106
 
95
107
  const roles = authRoles(auth);
96
- const allowed = roleAllowed(matrix, resolved.policy, roles);
108
+ const allowed = roleAllowed(matrix, resolved.policy, roles) ||
109
+ permissionAllowed(matrix, resolved.policy, auth.permissions ?? []);
97
110
  const role = primaryRole(roles);
98
111
  if (allowed) {
99
112
  return { allowed: true, policy: resolved.policy, role };
@@ -102,7 +115,7 @@ function evaluateAuthRequirement(
102
115
  return {
103
116
  allowed: false,
104
117
  code: FORGE_POLICY_DENIED,
105
- message: `role '${role}' denied for policy '${resolved.policy}'`,
118
+ message: `role '${role}' and permissions denied for policy '${resolved.policy}'`,
106
119
  policy: resolved.policy,
107
120
  role,
108
121
  };
@@ -3,37 +3,87 @@ import type { AuthContext } from "./types.ts";
3
3
  export interface AuthHeaderInput {
4
4
  userId?: string;
5
5
  tenantId?: string;
6
+ organizationId?: string;
7
+ organizationMembershipId?: string;
6
8
  role?: string;
9
+ roles?: string[];
10
+ permissions?: string[];
11
+ claims?: Record<string, unknown>;
7
12
  }
8
13
 
9
14
  export interface CliAuthInput {
10
15
  userId?: string;
11
16
  tenantId?: string;
12
17
  role?: string;
18
+ roles?: string[];
19
+ permissions?: string[];
13
20
  }
14
21
 
15
22
  export function resolveAuthFromHeaders(input: AuthHeaderInput): AuthContext {
16
- const { userId, tenantId, role } = input;
17
- if (userId && role) {
23
+ const { userId, role } = input;
24
+ const tenantId = input.tenantId ?? input.organizationId;
25
+ const roles = [...new Set([...(role ? [role] : []), ...(input.roles ?? [])])];
26
+ const claims = {
27
+ ...(input.claims ?? {}),
28
+ ...(input.organizationId ? { organization_id: input.organizationId } : {}),
29
+ ...(input.organizationMembershipId
30
+ ? { organization_membership_id: input.organizationMembershipId }
31
+ : {}),
32
+ };
33
+ const hasClaims = Object.keys(claims).length > 0;
34
+ if (userId && (role || roles.length > 0 || (input.permissions ?? []).length > 0 || hasClaims)) {
18
35
  return {
19
36
  kind: "user",
20
37
  userId,
21
38
  ...(tenantId ? { tenantId } : {}),
22
- role,
23
- roles: [role],
24
- permissions: [],
39
+ ...(role ? { role } : roles[0] ? { role: roles[0] } : {}),
40
+ roles,
41
+ permissions: [...new Set(input.permissions ?? [])].sort(),
25
42
  token: {
26
43
  issuer: "dev-headers",
27
44
  audience: "dev",
28
45
  subject: userId,
29
46
  authProvider: "dev-headers",
30
47
  },
31
- claims: {},
48
+ ...(hasClaims ? { claims } : {}),
32
49
  };
33
50
  }
34
51
  return { kind: "anonymous" };
35
52
  }
36
53
 
54
+ function parseHeaderList(value: string | null): string[] {
55
+ if (!value) {
56
+ return [];
57
+ }
58
+ try {
59
+ const parsed = JSON.parse(value) as unknown;
60
+ if (Array.isArray(parsed)) {
61
+ return parsed.filter((entry): entry is string => typeof entry === "string" && entry.length > 0);
62
+ }
63
+ } catch {
64
+ // Fall through to comma-separated dev header parsing.
65
+ }
66
+ return value
67
+ .split(",")
68
+ .map((entry) => entry.trim())
69
+ .filter(Boolean);
70
+ }
71
+
72
+ function parseClaims(value: string | null): Record<string, unknown> | undefined {
73
+ if (!value) {
74
+ return undefined;
75
+ }
76
+ try {
77
+ const parsed = JSON.parse(value) as unknown;
78
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
79
+ return parsed as Record<string, unknown>;
80
+ }
81
+ } catch {
82
+ // Invalid dev claims should not break the whole request; policies can still use explicit headers.
83
+ }
84
+ return undefined;
85
+ }
86
+
37
87
  export function resolveAuthFromCli(input: CliAuthInput): AuthContext {
38
88
  return resolveAuthFromHeaders(input);
39
89
  }
@@ -42,7 +92,12 @@ export function parseAuthHeaders(headers: Headers): AuthContext {
42
92
  return resolveAuthFromHeaders({
43
93
  userId: headers.get("x-forge-user-id") ?? undefined,
44
94
  tenantId: headers.get("x-forge-tenant-id") ?? undefined,
95
+ organizationId: headers.get("x-forge-organization-id") ?? undefined,
96
+ organizationMembershipId: headers.get("x-forge-organization-membership-id") ?? undefined,
45
97
  role: headers.get("x-forge-role") ?? undefined,
98
+ roles: parseHeaderList(headers.get("x-forge-roles")),
99
+ permissions: parseHeaderList(headers.get("x-forge-permissions")),
100
+ claims: parseClaims(headers.get("x-forge-claims")),
46
101
  });
47
102
  }
48
103
 
@@ -72,6 +72,7 @@ export function snapshotAuth(auth: AuthContext): AuthSnapshot {
72
72
  ...(auth.email ? { email: auth.email } : {}),
73
73
  ...(auth.name ? { name: auth.name } : {}),
74
74
  ...(auth.token ? { token: auth.token } : {}),
75
+ ...(auth.claims ? { claims: auth.claims } : {}),
75
76
  };
76
77
  }
77
78
 
@@ -4,7 +4,7 @@ import { FORGE_DB_CONNECT_FAILED } from "../../compiler/diagnostics/codes.ts";
4
4
  import type { Diagnostic } from "../../compiler/types/diagnostic.ts";
5
5
  import type { DbAdapter, DbAdapterKind } from "./adapter.ts";
6
6
  import { createMemoryAdapter } from "./memory-adapter.ts";
7
- import { createPgliteAdapter } from "./pglite-adapter.ts";
7
+ import { createPgliteAdapter, DEFAULT_PGLITE_DIR } from "./pglite-adapter.ts";
8
8
  import { createPostgresAdapter } from "./postgres-adapter.ts";
9
9
 
10
10
  export interface CreateDbAdapterOptions {
@@ -19,8 +19,6 @@ export interface CreateDbAdapterResult {
19
19
  diagnostics: Diagnostic[];
20
20
  }
21
21
 
22
- const DEFAULT_PGLITE_DIR = ".forge/pglite";
23
-
24
22
  export async function createDbAdapter(
25
23
  options: CreateDbAdapterOptions,
26
24
  ): Promise<CreateDbAdapterResult> {
@@ -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;