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
@@ -351,6 +351,166 @@ export default function ${pascal}Page() {
351
351
  `;
352
352
  }
353
353
 
354
+ export function renderAiAgentFile(name: string): string {
355
+ const camel = camelCase(name);
356
+ const pascal = pascalCase(name);
357
+ return `import { agent, aiTool } from "forge/server";
358
+ import { z } from "zod";
359
+
360
+ export const ${camel}ProjectContext = aiTool({
361
+ description: "Return concise project context for the ${pascal} agent.",
362
+ inputSchema: z.object({
363
+ topic: z.string().optional(),
364
+ }),
365
+ outputSchema: z.object({
366
+ context: z.string(),
367
+ }),
368
+ risk: "read",
369
+ strict: true,
370
+ needsApproval: false,
371
+ handler: async (_ctx, input) => ({
372
+ context: \`ForgeOS project context for \${input.topic ?? "the current request"}.\`,
373
+ }),
374
+ });
375
+
376
+ export const ${camel}Agent = agent({
377
+ provider: "gateway",
378
+ model: "openai/gpt-5.4",
379
+ instructions: "You are a ForgeOS app agent. Use Forge tools before answering when runtime data is needed.",
380
+ tools: { ${camel}ProjectContext },
381
+ stopWhen: { kind: "stepCount", maxSteps: 8 },
382
+ });
383
+ `;
384
+ }
385
+
386
+ export function renderAiChatComponent(name: string): string {
387
+ const pascal = pascalCase(name);
388
+ return `"use client";
389
+
390
+ import { DefaultChatTransport } from "ai";
391
+ import { useChat } from "@ai-sdk/react";
392
+ import { FormEvent, useMemo, useState } from "react";
393
+ import { forgeUrl } from "../lib/forge";
394
+
395
+ export function ${pascal}AiChat() {
396
+ const [input, setInput] = useState("");
397
+ const transport = useMemo(
398
+ () =>
399
+ new DefaultChatTransport({
400
+ api: \`\${forgeUrl}/ai/agents/chat\`,
401
+ headers: {
402
+ "x-forge-user-id": "dev-user",
403
+ "x-forge-tenant-id": "dev-tenant",
404
+ "x-forge-role": "owner",
405
+ },
406
+ body: {
407
+ agent: "${camelCase(name)}Agent",
408
+ provider: "gateway",
409
+ model: "openai/gpt-5.4",
410
+ instructions: "Answer as a ForgeOS app agent. Use available Forge tools when useful.",
411
+ maxSteps: 8,
412
+ },
413
+ }),
414
+ [],
415
+ );
416
+ const { messages, sendMessage, status, error, addToolApprovalResponse } = useChat({
417
+ transport,
418
+ });
419
+ const busy = status === "submitted" || status === "streaming";
420
+
421
+ async function submit(event: FormEvent<HTMLFormElement>) {
422
+ event.preventDefault();
423
+ const prompt = input.trim();
424
+ if (!prompt || busy) return;
425
+ setInput("");
426
+ sendMessage({ text: prompt });
427
+ }
428
+
429
+ return (
430
+ <section>
431
+ <div>
432
+ {messages.map((message) => (
433
+ <article key={message.id}>
434
+ <strong>{message.role}</strong>
435
+ {message.parts.map((part, index) => {
436
+ if (part.type === "text") {
437
+ return <p key={index}>{part.text}</p>;
438
+ }
439
+ if (part.type.startsWith("tool-")) {
440
+ const toolPart = part as typeof part & {
441
+ input?: unknown;
442
+ output?: unknown;
443
+ approval?: { id: string; state: string };
444
+ };
445
+ return (
446
+ <div key={index}>
447
+ <code>{part.type.replace(/^tool-/, "")}</code>
448
+ {toolPart.approval?.state === "approval-requested" ? (
449
+ <span>
450
+ <button
451
+ type="button"
452
+ onClick={() =>
453
+ addToolApprovalResponse({
454
+ id: toolPart.approval!.id,
455
+ approved: true,
456
+ })
457
+ }
458
+ >
459
+ Approve
460
+ </button>
461
+ <button
462
+ type="button"
463
+ onClick={() =>
464
+ addToolApprovalResponse({
465
+ id: toolPart.approval!.id,
466
+ approved: false,
467
+ })
468
+ }
469
+ >
470
+ Deny
471
+ </button>
472
+ </span>
473
+ ) : null}
474
+ </div>
475
+ );
476
+ }
477
+ return null;
478
+ })}
479
+ </article>
480
+ ))}
481
+ </div>
482
+ <form onSubmit={submit}>
483
+ <input
484
+ value={input}
485
+ onChange={(event) => setInput(event.currentTarget.value)}
486
+ placeholder="Ask the Forge agent"
487
+ />
488
+ <button type="submit" disabled={busy}>{busy ? "Running" : "Send"}</button>
489
+ </form>
490
+ {error ? <p>{error.message}</p> : null}
491
+ </section>
492
+ );
493
+ }
494
+ `;
495
+ }
496
+
497
+ export function renderAiChatPage(name: string): string {
498
+ const pascal = pascalCase(name);
499
+ return `"use client";
500
+
501
+ import { ${pascal}AiChat } from "../../components/${pascal}AiChat";
502
+
503
+ export default function ${pascal}AiPage() {
504
+ return (
505
+ <main>
506
+ <h1>${titleCase(name)} AI</h1>
507
+ <${pascal}AiChat />
508
+ </main>
509
+ );
510
+ }
511
+ `;
512
+ }
513
+
354
514
  export function renderWebBridge(): string {
355
515
  return `export const forgeUrl =
356
516
  import.meta.env.VITE_FORGE_URL ?? "http://127.0.0.1:3765";
@@ -476,8 +636,189 @@ export function renderVitePackage(appName: string): string {
476
636
  "typecheck": "tsc --noEmit"
477
637
  },
478
638
  "dependencies": {
479
- "@vitejs/plugin-react": "^4.3.4",
480
- "vite": "^6.0.5",
639
+ "@ai-sdk/react": "^3.0.0",
640
+ "@vitejs/plugin-react": "^6.0.2",
641
+ "ai": "^6.0.0",
642
+ "vite": "^8.0.16",
643
+ "react": "^19.0.0",
644
+ "react-dom": "^19.0.0"
645
+ },
646
+ "devDependencies": {
647
+ "@types/react": "^19.0.0",
648
+ "@types/react-dom": "^19.0.0",
649
+ "typescript": "^5.7.3"
650
+ }
651
+ }
652
+ `;
653
+ }
654
+
655
+ export function renderNuxtPackage(appName: string): string {
656
+ return `{
657
+ "name": "${kebabCase(appName)}-web",
658
+ "private": true,
659
+ "type": "module",
660
+ "scripts": {
661
+ "dev": "nuxt dev --host 127.0.0.1",
662
+ "build": "nuxt build",
663
+ "typecheck": "nuxt typecheck"
664
+ },
665
+ "dependencies": {
666
+ "nuxt": "^4.0.0",
667
+ "vue": "^3.5.38"
668
+ },
669
+ "devDependencies": {
670
+ "typescript": "^5.7.3"
671
+ }
672
+ }
673
+ `;
674
+ }
675
+
676
+ export function renderNuxtConfig(): string {
677
+ return `export default defineNuxtConfig({
678
+ compatibilityDate: "2026-06-18",
679
+ runtimeConfig: {
680
+ public: {
681
+ forgeUrl: process.env.NUXT_PUBLIC_FORGE_URL ?? "http://127.0.0.1:3765",
682
+ },
683
+ },
684
+ typescript: {
685
+ strict: true,
686
+ },
687
+ });
688
+ `;
689
+ }
690
+
691
+ export function renderNuxtTsconfig(): string {
692
+ return `{
693
+ "extends": "./.nuxt/tsconfig.json"
694
+ }
695
+ `;
696
+ }
697
+
698
+ export function renderNuxtForgeComposable(): string {
699
+ return `export const forgeUrl = "http://127.0.0.1:3765";
700
+
701
+ export { api } from "../../src/forge/_generated/api";
702
+ export { createForgeClient, ForgeError } from "../../src/forge/_generated/client";
703
+ export {
704
+ ForgeVuePlugin,
705
+ provideForge,
706
+ useForgeAuth,
707
+ useForgeClient,
708
+ useForgeCommand,
709
+ useForgeLiveQuery,
710
+ useForgeQuery,
711
+ } from "../../src/forge/_generated/vue";
712
+ `;
713
+ }
714
+
715
+ export function renderNuxtForgePlugin(): string {
716
+ return `import { ForgeVuePlugin } from "../composables/forge";
717
+
718
+ export default defineNuxtPlugin((nuxtApp) => {
719
+ const config = useRuntimeConfig();
720
+
721
+ nuxtApp.vueApp.use(ForgeVuePlugin, {
722
+ url: String(config.public.forgeUrl),
723
+ devAuth: true,
724
+ });
725
+ });
726
+ `;
727
+ }
728
+
729
+ export function renderNuxtApp(): string {
730
+ return `<script setup lang="ts">
731
+ import ForgeStatus from "./components/ForgeStatus.vue";
732
+ </script>
733
+
734
+ <template>
735
+ <main class="shell">
736
+ <p class="eyebrow">ForgeOS Nuxt app</p>
737
+ <h1>Full-stack loop ready</h1>
738
+ <ForgeStatus />
739
+ </main>
740
+ </template>
741
+
742
+ <style scoped>
743
+ .shell {
744
+ width: min(760px, calc(100vw - 32px));
745
+ margin: 0 auto;
746
+ padding: 48px 0;
747
+ }
748
+
749
+ .eyebrow {
750
+ color: #58655f;
751
+ font-size: 0.82rem;
752
+ font-weight: 800;
753
+ text-transform: uppercase;
754
+ }
755
+
756
+ h1 {
757
+ margin: 0 0 12px;
758
+ color: #17211d;
759
+ font-size: 2.2rem;
760
+ }
761
+ </style>
762
+ `;
763
+ }
764
+
765
+ export function renderNuxtStatusComponent(): string {
766
+ return `<script setup lang="ts">
767
+ import { computed } from "vue";
768
+ import { useForgeAuth } from "../composables/forge";
769
+
770
+ const auth = useForgeAuth();
771
+ const tenantLabel = computed(() => auth?.tenantId ?? "dev-tenant");
772
+ const roleLabel = computed(() => auth?.role ?? "owner");
773
+ </script>
774
+
775
+ <template>
776
+ <section class="status-panel">
777
+ <span class="status-dot" aria-hidden="true" />
778
+ <p>
779
+ Connected as <strong>{{ roleLabel }}</strong> on
780
+ <strong>{{ tenantLabel }}</strong>.
781
+ </p>
782
+ </section>
783
+ </template>
784
+
785
+ <style scoped>
786
+ .status-panel {
787
+ display: flex;
788
+ align-items: center;
789
+ gap: 10px;
790
+ margin-top: 24px;
791
+ color: #26332d;
792
+ }
793
+
794
+ .status-dot {
795
+ width: 10px;
796
+ height: 10px;
797
+ border-radius: 999px;
798
+ background: #1f9d55;
799
+ }
800
+
801
+ p {
802
+ margin: 0;
803
+ }
804
+ </style>
805
+ `;
806
+ }
807
+
808
+ export function renderNextAiPackage(appName: string): string {
809
+ return `{
810
+ "name": "${kebabCase(appName)}-web",
811
+ "private": true,
812
+ "type": "module",
813
+ "scripts": {
814
+ "dev": "next dev --hostname 127.0.0.1",
815
+ "build": "next build",
816
+ "typecheck": "tsc --noEmit"
817
+ },
818
+ "dependencies": {
819
+ "@ai-sdk/react": "^3.0.0",
820
+ "ai": "^6.0.0",
821
+ "next": "^15.5.9",
481
822
  "react": "^19.0.0",
482
823
  "react-dom": "^19.0.0"
483
824
  },
@@ -14,6 +14,7 @@ export type MakePrimitive =
14
14
  | "component"
15
15
  | "page"
16
16
  | "ui"
17
+ | "ai-chat"
17
18
  | "resource"
18
19
  | "apply"
19
20
  | "rollback";
@@ -60,6 +61,7 @@ export interface MakeIntent {
60
61
  trigger?: string;
61
62
  component?: string;
62
63
  route?: string;
64
+ framework?: "vite" | "next" | "nuxt";
63
65
  withAi: boolean;
64
66
  withCreateForm: boolean;
65
67
  }
@@ -129,7 +131,7 @@ export interface MakeCommandOptions {
129
131
  event?: string;
130
132
  trigger?: string;
131
133
  component?: string;
132
- framework?: "vite" | "next";
134
+ framework?: "vite" | "next" | "nuxt";
133
135
  withAi: boolean;
134
136
  withCrud: boolean;
135
137
  withLiveQuery: boolean;
@@ -420,6 +420,7 @@ function createCommandProgram(
420
420
  module: ts.ModuleKind.ESNext,
421
421
  moduleResolution: ts.ModuleResolutionKind.Bundler,
422
422
  noEmit: true,
423
+ noLib: true,
423
424
  skipLibCheck: true,
424
425
  strict: true,
425
426
  target: ts.ScriptTarget.ES2022,
@@ -228,7 +228,7 @@ export const repairRules: RepairRule[] = [
228
228
  failureKind: "secrets",
229
229
  code: "FORGE_SECRET_DIRECT_PROCESS_ENV",
230
230
  summary: `Secret/config usage is unsafe or missing for ${secret}.`,
231
- likelyCause: "Code reads process.env directly, accesses secrets in a forbidden runtime, or the environment lacks a required secret.",
231
+ likelyCause: "Code reads secret/config values through process.env in Forge runtime code, accesses secrets in a forbidden runtime, or the environment lacks a required secret.",
232
232
  confidence: "high",
233
233
  suggestedRepairs: [
234
234
  {
@@ -466,7 +466,7 @@ export function explainDiagnostic(code: string): string {
466
466
  FORGE_GUARD_VIOLATION: "A package or capability is used in a runtime context where it is forbidden. Move side effects to actions/workflows.",
467
467
  FORGE_POLICY_UNKNOWN: "A runtime entry references a missing policy. Create or correct the policy, then simulate expected roles.",
468
468
  FORGE_POLICY_DENIED: "The caller auth context does not satisfy the policy. Fix test auth or intentionally update policy roles.",
469
- FORGE_SECRET_DIRECT_PROCESS_ENV: "Code reads process.env directly. Use ctx.secrets/ctx.config in allowed runtime contexts.",
469
+ FORGE_SECRET_DIRECT_PROCESS_ENV: "Code reads secret/config values through process.env in Forge runtime code. Use ctx.secrets/ctx.config in allowed runtime contexts.",
470
470
  FORGE_AI_FORBIDDEN_CONTEXT: "AI is being used in a deterministic context. Move AI calls to action/workflow/server runtime.",
471
471
  FORGE_WORKFLOW_STEP_FAILED: "A workflow step failed. Inspect the workflow run and trace before retrying.",
472
472
  FORGE_OUTBOX_PROCESS_FAILED: "An outbox delivery failed. Inspect the subscribed action and retry after fixing the cause.",
@@ -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"}