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
@@ -0,0 +1,373 @@
1
+ import { createDiagnostic } from "../diagnostics/create.ts";
2
+ import type { Diagnostic } from "../types/diagnostic.ts";
3
+ import {
4
+ FORGE_EXTERNAL_MANIFEST_PROTOCOL_VERSION,
5
+ type ForgeExternalEntryKind,
6
+ type ForgeExternalEntryRisk,
7
+ type ForgeExternalManifest,
8
+ type ForgeExternalManifestEntry,
9
+ type ForgeExternalManifestRegistryFile,
10
+ type ForgeExternalTransportKind,
11
+ type ForgeExternalTransactionMode,
12
+ } from "./types.ts";
13
+
14
+ const TRANSPORTS: ForgeExternalTransportKind[] = ["http", "grpc", "stdio"];
15
+ const ENTRY_KINDS: ForgeExternalEntryKind[] = ["command", "query"];
16
+ const RISKS: ForgeExternalEntryRisk[] = ["read", "write", "destructive", "external"];
17
+ const TRANSACTIONS: ForgeExternalTransactionMode[] = [
18
+ "read-only",
19
+ "external-managed",
20
+ "forge-managed",
21
+ "saga",
22
+ ];
23
+
24
+ function isObject(value: unknown): value is Record<string, unknown> {
25
+ return typeof value === "object" && value !== null && !Array.isArray(value);
26
+ }
27
+
28
+ function isString(value: unknown): value is string {
29
+ return typeof value === "string" && value.trim().length > 0;
30
+ }
31
+
32
+ function stringArray(value: unknown): value is string[] {
33
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
34
+ }
35
+
36
+ function commandArgsArray(value: unknown): value is string[] {
37
+ return Array.isArray(value) &&
38
+ value.length > 0 &&
39
+ typeof value[0] === "string" &&
40
+ value[0].length > 0 &&
41
+ value.every((item) => typeof item === "string");
42
+ }
43
+
44
+ function externalDiagnostic(
45
+ severity: Diagnostic["severity"],
46
+ code: string,
47
+ message: string,
48
+ file?: string,
49
+ fixHint?: string,
50
+ ): Diagnostic {
51
+ return createDiagnostic({
52
+ severity,
53
+ code,
54
+ message,
55
+ ...(file ? { file } : {}),
56
+ ...(fixHint ? { fixHint } : {}),
57
+ docs: ["docs/forge-protocol.md", "schemas/forge-manifest.schema.json"],
58
+ });
59
+ }
60
+
61
+ function validateEntry(
62
+ entry: unknown,
63
+ index: number,
64
+ serviceName: string,
65
+ diagnostics: Diagnostic[],
66
+ file?: string,
67
+ ): ForgeExternalManifestEntry | null {
68
+ if (!isObject(entry)) {
69
+ diagnostics.push(externalDiagnostic(
70
+ "error",
71
+ "FORGE_EXTERNAL_ENTRY_OBJECT",
72
+ `external manifest entry at index ${index} must be an object`,
73
+ file,
74
+ ));
75
+ return null;
76
+ }
77
+
78
+ const name = entry.name;
79
+ const kind = entry.kind;
80
+ if (!isString(name)) {
81
+ diagnostics.push(externalDiagnostic(
82
+ "error",
83
+ "FORGE_EXTERNAL_ENTRY_NAME",
84
+ `external manifest entry at index ${index} must have a non-empty name`,
85
+ file,
86
+ ));
87
+ }
88
+ if (!ENTRY_KINDS.includes(kind as ForgeExternalEntryKind)) {
89
+ diagnostics.push(externalDiagnostic(
90
+ "error",
91
+ "FORGE_EXTERNAL_ENTRY_KIND",
92
+ `external manifest entry '${String(name || index)}' must be kind command or query`,
93
+ file,
94
+ ));
95
+ }
96
+ if (entry.effects !== undefined && !stringArray(entry.effects)) {
97
+ diagnostics.push(externalDiagnostic(
98
+ "error",
99
+ "FORGE_EXTERNAL_ENTRY_EFFECTS",
100
+ `external manifest entry '${String(name || index)}' effects must be a string array`,
101
+ file,
102
+ ));
103
+ }
104
+ if (entry.risk !== undefined && !RISKS.includes(entry.risk as ForgeExternalEntryRisk)) {
105
+ diagnostics.push(externalDiagnostic(
106
+ "error",
107
+ "FORGE_EXTERNAL_ENTRY_RISK",
108
+ `external manifest entry '${String(name || index)}' has unsupported risk '${String(entry.risk)}'`,
109
+ file,
110
+ ));
111
+ }
112
+ if (
113
+ entry.transaction !== undefined &&
114
+ !TRANSACTIONS.includes(entry.transaction as ForgeExternalTransactionMode)
115
+ ) {
116
+ diagnostics.push(externalDiagnostic(
117
+ "error",
118
+ "FORGE_EXTERNAL_ENTRY_TRANSACTION",
119
+ `external manifest entry '${String(name || index)}' has unsupported transaction mode '${String(entry.transaction)}'`,
120
+ file,
121
+ ));
122
+ }
123
+ if (
124
+ entry.kind === "query" &&
125
+ entry.transaction !== undefined &&
126
+ entry.transaction !== "read-only"
127
+ ) {
128
+ diagnostics.push(externalDiagnostic(
129
+ "error",
130
+ "FORGE_EXTERNAL_QUERY_TRANSACTION",
131
+ `external query '${serviceName}.${String(name)}' must use transaction read-only when transaction is declared`,
132
+ file,
133
+ "Declare command for writes, or set transaction to read-only for external queries.",
134
+ ));
135
+ }
136
+ if (entry.kind === "query" && entry.risk !== undefined && entry.risk !== "read") {
137
+ diagnostics.push(externalDiagnostic(
138
+ "error",
139
+ "FORGE_EXTERNAL_QUERY_RISK",
140
+ `external query '${serviceName}.${String(name)}' must use risk read when risk is declared`,
141
+ file,
142
+ ));
143
+ }
144
+
145
+ if (!isString(name) || !ENTRY_KINDS.includes(kind as ForgeExternalEntryKind)) {
146
+ return null;
147
+ }
148
+
149
+ return {
150
+ name,
151
+ kind: kind as ForgeExternalEntryKind,
152
+ ...(isString(entry.description) ? { description: entry.description } : {}),
153
+ ...(isString(entry.path) ? { path: entry.path } : {}),
154
+ ...(entry.method === "GET" || entry.method === "POST" ? { method: entry.method } : {}),
155
+ ...(entry.inputSchema !== undefined ? { inputSchema: entry.inputSchema } : {}),
156
+ ...(entry.outputSchema !== undefined ? { outputSchema: entry.outputSchema } : {}),
157
+ ...(isString(entry.policy) ? { policy: entry.policy } : {}),
158
+ ...(typeof entry.tenantScoped === "boolean" ? { tenantScoped: entry.tenantScoped } : {}),
159
+ ...(TRANSACTIONS.includes(entry.transaction as ForgeExternalTransactionMode)
160
+ ? { transaction: entry.transaction as ForgeExternalTransactionMode }
161
+ : {}),
162
+ ...(RISKS.includes(entry.risk as ForgeExternalEntryRisk)
163
+ ? { risk: entry.risk as ForgeExternalEntryRisk }
164
+ : {}),
165
+ ...(typeof entry.needsApproval === "boolean" ? { needsApproval: entry.needsApproval } : {}),
166
+ ...(stringArray(entry.effects) ? { effects: entry.effects } : {}),
167
+ };
168
+ }
169
+
170
+ export function validateExternalManifest(
171
+ value: unknown,
172
+ options: { file?: string } = {},
173
+ ): { manifest: ForgeExternalManifest | null; diagnostics: Diagnostic[] } {
174
+ const diagnostics: Diagnostic[] = [];
175
+ if (!isObject(value)) {
176
+ return {
177
+ manifest: null,
178
+ diagnostics: [
179
+ externalDiagnostic(
180
+ "error",
181
+ "FORGE_EXTERNAL_MANIFEST_OBJECT",
182
+ "forge external manifest must be a JSON object",
183
+ options.file,
184
+ ),
185
+ ],
186
+ };
187
+ }
188
+
189
+ if (value.forgeProtocol !== FORGE_EXTERNAL_MANIFEST_PROTOCOL_VERSION) {
190
+ diagnostics.push(externalDiagnostic(
191
+ "error",
192
+ "FORGE_EXTERNAL_PROTOCOL_VERSION",
193
+ `forgeProtocol must be '${FORGE_EXTERNAL_MANIFEST_PROTOCOL_VERSION}'`,
194
+ options.file,
195
+ ));
196
+ }
197
+ if (!isString(value.language)) {
198
+ diagnostics.push(externalDiagnostic(
199
+ "error",
200
+ "FORGE_EXTERNAL_LANGUAGE",
201
+ "external manifest must declare a non-empty language",
202
+ options.file,
203
+ ));
204
+ }
205
+ if (!isObject(value.service)) {
206
+ diagnostics.push(externalDiagnostic(
207
+ "error",
208
+ "FORGE_EXTERNAL_SERVICE",
209
+ "external manifest must declare a service object",
210
+ options.file,
211
+ ));
212
+ }
213
+ if (!Array.isArray(value.entries)) {
214
+ diagnostics.push(externalDiagnostic(
215
+ "error",
216
+ "FORGE_EXTERNAL_ENTRIES",
217
+ "external manifest must declare an entries array",
218
+ options.file,
219
+ ));
220
+ }
221
+
222
+ const service = isObject(value.service) ? value.service : {};
223
+ if (!isString(service.name)) {
224
+ diagnostics.push(externalDiagnostic(
225
+ "error",
226
+ "FORGE_EXTERNAL_SERVICE_NAME",
227
+ "external service must have a non-empty name",
228
+ options.file,
229
+ ));
230
+ }
231
+ if (!TRANSPORTS.includes(service.transport as ForgeExternalTransportKind)) {
232
+ diagnostics.push(externalDiagnostic(
233
+ "error",
234
+ "FORGE_EXTERNAL_SERVICE_TRANSPORT",
235
+ `external service '${String(service.name || "unknown")}' must use transport http, grpc, or stdio`,
236
+ options.file,
237
+ ));
238
+ }
239
+ if (service.transport === "http" && !isString(service.baseUrl)) {
240
+ diagnostics.push(externalDiagnostic(
241
+ "error",
242
+ "FORGE_EXTERNAL_SERVICE_BASE_URL",
243
+ `external service '${String(service.name || "unknown")}' uses http transport and must declare a non-empty baseUrl`,
244
+ options.file,
245
+ "Set service.baseUrl to the external runtime base URL.",
246
+ ));
247
+ }
248
+ const hasCommand = isString(service.command);
249
+ const hasCommandArgs = commandArgsArray(service.commandArgs);
250
+ if (service.commandArgs !== undefined && !hasCommandArgs) {
251
+ diagnostics.push(externalDiagnostic(
252
+ "error",
253
+ "FORGE_EXTERNAL_SERVICE_COMMAND_ARGS",
254
+ `external service '${String(service.name || "unknown")}' commandArgs must be a non-empty string array`,
255
+ options.file,
256
+ "Set service.commandArgs to an array whose first item is the executable.",
257
+ ));
258
+ }
259
+ if (service.transport === "stdio" && !hasCommand && !hasCommandArgs) {
260
+ diagnostics.push(externalDiagnostic(
261
+ "error",
262
+ "FORGE_EXTERNAL_SERVICE_COMMAND",
263
+ `external service '${String(service.name || "unknown")}' uses stdio transport and must declare a non-empty command or commandArgs`,
264
+ options.file,
265
+ "Set service.command to a command line string or service.commandArgs to a structured executable/args array.",
266
+ ));
267
+ }
268
+
269
+ const entries = Array.isArray(value.entries)
270
+ ? value.entries
271
+ .map((entry, index) => validateEntry(entry, index, String(service.name || "unknown"), diagnostics, options.file))
272
+ .filter((entry): entry is ForgeExternalManifestEntry => entry !== null)
273
+ : [];
274
+ const seen = new Set<string>();
275
+ for (const entry of entries) {
276
+ const key = `${entry.kind}:${entry.name}`;
277
+ if (seen.has(key)) {
278
+ diagnostics.push(externalDiagnostic(
279
+ "error",
280
+ "FORGE_EXTERNAL_ENTRY_DUPLICATE",
281
+ `external service '${String(service.name)}' declares duplicate ${entry.kind} '${entry.name}'`,
282
+ options.file,
283
+ ));
284
+ }
285
+ seen.add(key);
286
+ }
287
+
288
+ if (diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
289
+ return { manifest: null, diagnostics };
290
+ }
291
+
292
+ return {
293
+ manifest: {
294
+ forgeProtocol: FORGE_EXTERNAL_MANIFEST_PROTOCOL_VERSION,
295
+ language: value.language as ForgeExternalManifest["language"],
296
+ ...(isString(value.framework) ? { framework: value.framework } : {}),
297
+ service: {
298
+ name: service.name as string,
299
+ transport: service.transport as ForgeExternalTransportKind,
300
+ ...(isString(service.baseUrl) ? { baseUrl: service.baseUrl } : {}),
301
+ ...(hasCommand ? { command: service.command as string } : {}),
302
+ ...(hasCommandArgs ? { commandArgs: service.commandArgs as string[] } : {}),
303
+ ...(isString(service.health) ? { health: service.health } : {}),
304
+ },
305
+ entries,
306
+ ...(isObject(value.schemas) ? { schemas: value.schemas } : {}),
307
+ },
308
+ diagnostics,
309
+ };
310
+ }
311
+
312
+ export function validateExternalManifestRegistry(
313
+ value: unknown,
314
+ options: { file?: string } = {},
315
+ ): { registry: ForgeExternalManifestRegistryFile | null; diagnostics: Diagnostic[] } {
316
+ if (!isObject(value)) {
317
+ return {
318
+ registry: null,
319
+ diagnostics: [
320
+ externalDiagnostic(
321
+ "error",
322
+ "FORGE_EXTERNAL_REGISTRY_OBJECT",
323
+ "external manifest registry must be a JSON object",
324
+ options.file,
325
+ ),
326
+ ],
327
+ };
328
+ }
329
+ if (value.schemaVersion !== "0.1.0") {
330
+ return {
331
+ registry: null,
332
+ diagnostics: [
333
+ externalDiagnostic(
334
+ "error",
335
+ "FORGE_EXTERNAL_REGISTRY_VERSION",
336
+ "external manifest registry schemaVersion must be '0.1.0'",
337
+ options.file,
338
+ ),
339
+ ],
340
+ };
341
+ }
342
+ if (!Array.isArray(value.manifests)) {
343
+ return {
344
+ registry: null,
345
+ diagnostics: [
346
+ externalDiagnostic(
347
+ "error",
348
+ "FORGE_EXTERNAL_REGISTRY_MANIFESTS",
349
+ "external manifest registry must include a manifests array",
350
+ options.file,
351
+ ),
352
+ ],
353
+ };
354
+ }
355
+
356
+ const diagnostics: Diagnostic[] = [];
357
+ const manifests: ForgeExternalManifest[] = [];
358
+ for (const [index, manifestValue] of value.manifests.entries()) {
359
+ const result = validateExternalManifest(manifestValue, {
360
+ file: options.file ? `${options.file}#manifests/${index}` : undefined,
361
+ });
362
+ diagnostics.push(...result.diagnostics);
363
+ if (result.manifest) {
364
+ manifests.push(result.manifest);
365
+ }
366
+ }
367
+ return {
368
+ registry: diagnostics.some((diagnostic) => diagnostic.severity === "error")
369
+ ? null
370
+ : { schemaVersion: "0.1.0", manifests },
371
+ diagnostics,
372
+ };
373
+ }
@@ -13,6 +13,7 @@ import { createDiagnostic } from "../diagnostics/create.ts";
13
13
 
14
14
  const WEB_ROOT = "web";
15
15
  const API_URL_ENV = "NEXT_PUBLIC_FORGE_URL";
16
+ const NUXT_API_URL_ENV = "NUXT_PUBLIC_FORGE_URL";
16
17
  const VITE_API_URL_ENV = "VITE_FORGE_URL";
17
18
 
18
19
  function toPosix(path: string): string {
@@ -43,7 +44,7 @@ function walkFiles(root: string): string[] {
43
44
  for (const entry of nodeFileSystem.readDir(dir)) {
44
45
  const absolute = join(dir, entry.name);
45
46
  if (entry.isDirectory) {
46
- if (entry.name === "node_modules" || entry.name === ".next" || entry.name === "dist") {
47
+ if (entry.name === "node_modules" || entry.name === ".next" || entry.name === ".nuxt" || entry.name === "dist" || entry.name === ".output") {
47
48
  continue;
48
49
  }
49
50
  walk(absolute);
@@ -71,6 +72,14 @@ function detectFramework(webRoot: string): FrontendGraph["framework"] {
71
72
  if (deps.next || nodeFileSystem.exists(join(webRoot, "next.config.ts"))) {
72
73
  return "next";
73
74
  }
75
+ if (
76
+ deps.nuxt ||
77
+ nodeFileSystem.exists(join(webRoot, "nuxt.config.ts")) ||
78
+ nodeFileSystem.exists(join(webRoot, "nuxt.config.js")) ||
79
+ nodeFileSystem.exists(join(webRoot, "nuxt.config.mjs"))
80
+ ) {
81
+ return "nuxt";
82
+ }
74
83
  if (deps.vite || nodeFileSystem.exists(join(webRoot, "vite.config.ts"))) {
75
84
  return "vite";
76
85
  }
@@ -105,6 +114,27 @@ function routePathForFile(webRoot: string, file: string): string | null {
105
114
  if (rel === "app/page.tsx" || rel === "app/page.ts" || rel === "app/page.jsx" || rel === "app/page.js") {
106
115
  return "/";
107
116
  }
117
+ if (rel === "app.vue") {
118
+ return "/";
119
+ }
120
+ if (rel === "pages/index.vue") {
121
+ return "/";
122
+ }
123
+ const vueRoute = rel.match(/^pages\/(.+)\.vue$/);
124
+ if (vueRoute) {
125
+ const route = vueRoute[1]
126
+ .split("/")
127
+ .map((segment) => {
128
+ if (segment === "index") {
129
+ return "";
130
+ }
131
+ const dynamic = segment.match(/^\[([A-Za-z0-9_]+)\]$/);
132
+ return dynamic ? `:${dynamic[1]}` : segment;
133
+ })
134
+ .filter(Boolean)
135
+ .join("/");
136
+ return `/${route}`;
137
+ }
108
138
  const match = rel.match(/^app\/(.+)\/page\.(tsx|ts|jsx|js)$/);
109
139
  if (match) {
110
140
  const route = match[1]
@@ -117,7 +147,7 @@ function routePathForFile(webRoot: string, file: string): string | null {
117
147
  }
118
148
 
119
149
  function componentNameForFile(file: string): string {
120
- return basename(file).replace(/\.(tsx|ts|jsx|js)$/, "");
150
+ return basename(file).replace(/\.(tsx|ts|jsx|js|vue)$/, "");
121
151
  }
122
152
 
123
153
  function componentNameForText(file: string, text: string): string {
@@ -134,6 +164,14 @@ function componentNameForText(file: string, text: string): string {
134
164
 
135
165
  function isComponentFile(webRoot: string, file: string, text: string): boolean {
136
166
  const rel = toPosix(relative(webRoot, file));
167
+ if (file.endsWith(".vue")) {
168
+ return (
169
+ rel === "app.vue" ||
170
+ rel.startsWith("components/") ||
171
+ rel.startsWith("src/components/") ||
172
+ rel.startsWith("pages/")
173
+ );
174
+ }
137
175
  if (!/\.(tsx|jsx)$/.test(file)) {
138
176
  return false;
139
177
  }
@@ -206,6 +244,9 @@ function devCommandFor(webRoot: string, framework: FrontendGraph["framework"]):
206
244
  }
207
245
 
208
246
  function apiEnvFor(framework: FrontendGraph["framework"]): string {
247
+ if (framework === "nuxt") {
248
+ return NUXT_API_URL_ENV;
249
+ }
209
250
  return framework === "vite" || framework === "static" ? VITE_API_URL_ENV : API_URL_ENV;
210
251
  }
211
252
 
@@ -224,7 +265,7 @@ function stringProp(text: string, prop: "userId" | "tenantId" | "role"): string
224
265
  }
225
266
 
226
267
  function defaultWebPort(framework: FrontendGraph["framework"]): number {
227
- return framework === "next" ? 3000 : 5173;
268
+ return framework === "next" || framework === "nuxt" ? 3000 : 5173;
228
269
  }
229
270
 
230
271
  function componentNamesInText(text: string, components: FrontendComponentInfo[]): string[] {
@@ -299,7 +340,7 @@ export function buildFrontendGraph(input: {
299
340
  const defaultApiUrl = `http://127.0.0.1:${input.apiPort ?? 3765}`;
300
341
  const devUrl = `http://127.0.0.1:${input.webPort ?? defaultWebPort(framework)}`;
301
342
  const files = walkFiles(webRoot);
302
- const sourceFiles = files.filter((file) => /\.(tsx|ts|jsx|js|html)$/.test(file));
343
+ const sourceFiles = files.filter((file) => /\.(tsx|ts|jsx|js|vue|html)$/.test(file));
303
344
  const routes: FrontendRouteInfo[] = [];
304
345
  const components: FrontendComponentInfo[] = [];
305
346
  const providers: FrontendProviderInfo[] = [];
@@ -314,7 +355,9 @@ export function buildFrontendGraph(input: {
314
355
  rel === "web/lib/forge.ts" ||
315
356
  rel === "web/lib/forge.tsx" ||
316
357
  rel === "web/src/lib/forge.ts" ||
317
- rel === "web/src/lib/forge.tsx";
358
+ rel === "web/src/lib/forge.tsx" ||
359
+ rel === "web/composables/forge.ts" ||
360
+ rel === "web/plugins/forge.ts";
318
361
  textByRel.set(rel, text);
319
362
  const uses = detectUses(text, input.clientManifest);
320
363
  if (isComponentFile(webRoot, file, text)) {
@@ -335,11 +378,32 @@ export function buildFrontendGraph(input: {
335
378
  ...(devAuth && stringProp(text, "role") ? { devAuthRole: stringProp(text, "role") } : {}),
336
379
  });
337
380
  }
381
+ if (
382
+ text.includes("provideForge({") ||
383
+ text.includes("vueApp.use(ForgeVuePlugin") ||
384
+ text.includes("app.use(ForgeVuePlugin")
385
+ ) {
386
+ const devAuth =
387
+ text.includes("devAuth") ||
388
+ (text.includes("userId") && text.includes("tenantId") && text.includes("role"));
389
+ providers.push({
390
+ name: framework === "nuxt" ? "ForgeNuxtPlugin" : "ForgeVueProvider",
391
+ file: rel,
392
+ ...(text.includes(NUXT_API_URL_ENV) ? { apiUrlEnv: NUXT_API_URL_ENV } : {}),
393
+ ...(text.includes(VITE_API_URL_ENV) ? { apiUrlEnv: VITE_API_URL_ENV } : {}),
394
+ devAuth,
395
+ ...(devAuth && stringProp(text, "userId") ? { devAuthUserId: stringProp(text, "userId") } : {}),
396
+ ...(devAuth && stringProp(text, "tenantId") ? { devAuthTenantId: stringProp(text, "tenantId") } : {}),
397
+ ...(devAuth && stringProp(text, "role") ? { devAuthRole: stringProp(text, "role") } : {}),
398
+ });
399
+ }
338
400
  if (
339
401
  rel === "web/lib/forge.ts" ||
340
402
  rel === "web/lib/forge.tsx" ||
341
403
  rel === "web/src/lib/forge.ts" ||
342
- rel === "web/src/lib/forge.tsx"
404
+ rel === "web/src/lib/forge.tsx" ||
405
+ rel === "web/composables/forge.ts" ||
406
+ rel === "web/plugins/forge.ts"
343
407
  ) {
344
408
  bridgeFiles.push(rel);
345
409
  }
@@ -350,7 +414,7 @@ export function buildFrontendGraph(input: {
350
414
  message: "frontend imports generated files directly; prefer the local web/lib/forge bridge",
351
415
  file: rel,
352
416
  fixHint: "Import generated client APIs through web/lib/forge.ts so agents and humans have one stable frontend bridge.",
353
- suggestedCommands: ["forge inspect frontend --json", "forge make ui --framework vite --dry-run --json"],
417
+ suggestedCommands: ["forge inspect frontend --json", `forge make ui --framework ${framework === "nuxt" ? "nuxt" : "vite"} --dry-run --json`],
354
418
  docs: ["src/forge/_generated/frontendGraph.json", "src/forge/_generated/appMap.md"],
355
419
  }));
356
420
  }
@@ -401,9 +465,13 @@ export function buildFrontendGraph(input: {
401
465
  diagnostics.push(createDiagnostic({
402
466
  severity: "warning",
403
467
  code: "FORGE_FRONTEND_PROVIDER_MISSING",
404
- message: "web app does not expose a ForgeProvider; generated hooks may not be wired",
405
- fixHint: "Mount ForgeProvider once in the web app root/provider layer and pass devAuth for local development.",
406
- suggestedCommands: ["forge inspect frontend --json", "forge make ui --framework vite --dry-run --json"],
468
+ message: framework === "nuxt"
469
+ ? "Nuxt app does not expose a Forge plugin; generated composables may not be wired"
470
+ : "web app does not expose a ForgeProvider; generated hooks may not be wired",
471
+ fixHint: framework === "nuxt"
472
+ ? "Create web/plugins/forge.ts and call provideForge with runtimeConfig.public.forgeUrl and devAuth for local development."
473
+ : "Mount ForgeProvider once in the web app root/provider layer and pass devAuth for local development.",
474
+ suggestedCommands: ["forge inspect frontend --json", `forge make ui --framework ${framework === "nuxt" ? "nuxt" : "vite"} --dry-run --json`],
407
475
  docs: ["src/forge/_generated/frontendGraph.json", "AGENTS.md"],
408
476
  }));
409
477
  }
@@ -411,9 +479,13 @@ export function buildFrontendGraph(input: {
411
479
  diagnostics.push(createDiagnostic({
412
480
  severity: "warning",
413
481
  code: "FORGE_FRONTEND_BRIDGE_MISSING",
414
- message: "web/**/lib/forge.ts bridge is missing; agents may use fragile generated import paths",
415
- fixHint: "Create web/lib/forge.ts or web/src/lib/forge.ts and re-export api, client, ForgeProvider, and generated hooks from src/forge/_generated.",
416
- suggestedCommands: ["forge make ui --framework vite --dry-run --json", "forge generate"],
482
+ message: framework === "nuxt"
483
+ ? "web/composables/forge.ts bridge is missing; agents may use fragile generated import paths"
484
+ : "web/**/lib/forge.ts bridge is missing; agents may use fragile generated import paths",
485
+ fixHint: framework === "nuxt"
486
+ ? "Create web/composables/forge.ts and re-export api plus generated Forge Vue composables from src/forge/_generated."
487
+ : "Create web/lib/forge.ts or web/src/lib/forge.ts and re-export api, client, ForgeProvider, and generated hooks from src/forge/_generated.",
488
+ suggestedCommands: [`forge make ui --framework ${framework === "nuxt" ? "nuxt" : "vite"} --dry-run --json`, "forge generate"],
417
489
  docs: ["src/forge/_generated/frontendGraph.json", "AGENTS.md"],
418
490
  }));
419
491
  }