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
@@ -11,6 +11,8 @@ export interface AgentProjectInfo {
11
11
  export interface AgentEntryInfo {
12
12
  name: string;
13
13
  file: string;
14
+ source?: "local" | "external";
15
+ external?: AgentExternalEntryInfo;
14
16
  policy?: string;
15
17
  allowedPackages: string[];
16
18
  forbiddenCapabilities: string[];
@@ -145,6 +147,47 @@ export interface AgentAiInfo {
145
147
  file: string;
146
148
  purpose?: string;
147
149
  }>;
150
+ tools: Array<{
151
+ name: string;
152
+ file: string;
153
+ description?: string;
154
+ risk: string;
155
+ strict: boolean;
156
+ needsApproval: boolean | "dynamic";
157
+ }>;
158
+ agents: Array<{
159
+ name: string;
160
+ file: string;
161
+ provider: string;
162
+ model: string;
163
+ instructions?: string;
164
+ tools: string[];
165
+ stopWhen: unknown;
166
+ }>;
167
+ }
168
+
169
+ export interface AgentExternalEntryInfo {
170
+ service: string;
171
+ language: string;
172
+ framework?: string;
173
+ transport: string;
174
+ transaction?: string;
175
+ risk?: "read" | "write" | "destructive" | "external";
176
+ needsApproval?: boolean;
177
+ effects: string[];
178
+ description?: string;
179
+ }
180
+
181
+ export interface AgentExternalServiceInfo {
182
+ name: string;
183
+ language: string;
184
+ framework?: string;
185
+ transport: string;
186
+ baseUrl?: string;
187
+ command?: string;
188
+ health?: string;
189
+ commands: string[];
190
+ queries: string[];
148
191
  }
149
192
 
150
193
  export interface AgentClientInfo {
@@ -306,11 +349,51 @@ export interface AgentCapabilityMap {
306
349
  diagnostics: Diagnostic[];
307
350
  }
308
351
 
352
+ export interface AgentToolRegistry {
353
+ schemaVersion: "0.1.0";
354
+ generatorVersion: string;
355
+ project: AgentProjectInfo;
356
+ explicitTools: AgentAiInfo["tools"];
357
+ autoTools: Array<{
358
+ name: string;
359
+ sourceKind: "command" | "query" | "liveQuery";
360
+ sourceName: string;
361
+ policy?: string;
362
+ file: string;
363
+ http: AgentHttpEndpointInfo;
364
+ frontend: AgentFrontendUsageInfo;
365
+ tablesRead: string[];
366
+ tablesWritten: string[];
367
+ emits: string[];
368
+ dependencies: Array<{ table: string; scope: "tenant" | "global" }>;
369
+ readOnly: boolean;
370
+ risk: "read" | "write";
371
+ needsApproval: boolean;
372
+ requiresAuth: boolean;
373
+ source?: "local" | "external";
374
+ external?: AgentExternalEntryInfo;
375
+ execution: "forge-runtime-endpoint" | "external-runtime-endpoint";
376
+ }>;
377
+ agents: AgentAiInfo["agents"];
378
+ }
379
+
309
380
  export interface AgentPlaybook {
310
381
  title: string;
311
382
  steps: string[];
312
383
  }
313
384
 
385
+ export interface AgentProtocolInfo {
386
+ id: string;
387
+ kind: "agent-protocol";
388
+ version: string;
389
+ guide: string;
390
+ commands: string[];
391
+ preferredFor: string[];
392
+ readQueries: string[];
393
+ mutationActions: string[];
394
+ compactAliases: string[];
395
+ }
396
+
314
397
  export interface AgentContract {
315
398
  schemaVersion: string;
316
399
  generatorVersion: string;
@@ -325,6 +408,7 @@ export interface AgentContract {
325
408
  packages: AgentPackageInfo[];
326
409
  dependencyApis: AgentDependencyApiInfo[];
327
410
  integrations: AgentIntegrationInfo[];
411
+ externalServices?: AgentExternalServiceInfo[];
328
412
  secrets: AgentSecretInfo[];
329
413
  telemetry: AgentTelemetryInfo;
330
414
  ai: AgentAiInfo;
@@ -334,6 +418,7 @@ export interface AgentContract {
334
418
  deploy?: AgentDeployInfo;
335
419
  rules: AgentRuntimeRule[];
336
420
  playbooks: AgentPlaybook[];
421
+ agentProtocols: AgentProtocolInfo[];
337
422
  commandsToRun: {
338
423
  beforeEditing: string[];
339
424
  afterEditing: string[];
@@ -4,9 +4,11 @@ import { canonicalJson } from "../primitives/serialize.ts";
4
4
  import type { AppGraph } from "../types/app-graph.ts";
5
5
  import type {
6
6
  AiGenerationCall,
7
+ AiAgentDefinition,
7
8
  AiModelDefinition,
8
9
  AiProviderDefinition,
9
10
  AiRegistry,
11
+ AiToolDefinition,
10
12
  ForgeAiProvider,
11
13
  } from "../types/ai-registry.ts";
12
14
  import type { ClassifiedPackage } from "../classifier/runtime-matrix.ts";
@@ -15,9 +17,17 @@ import {
15
17
  AI_REGISTRY_ANALYZER_VERSION,
16
18
  AI_REGISTRY_SCHEMA_VERSION,
17
19
  } from "./constants.ts";
18
- import { parseAiCallsFromSlice } from "./parse.ts";
20
+ import {
21
+ parseAiAgentMeta,
22
+ parseAiCallsFromSlice,
23
+ parseAiToolMeta,
24
+ } from "./parse.ts";
19
25
 
20
26
  const KNOWN_MODELS: AiModelDefinition[] = [
27
+ {
28
+ provider: "openai",
29
+ model: "gpt-5.4",
30
+ },
21
31
  {
22
32
  provider: "openai",
23
33
  model: "gpt-4o",
@@ -30,6 +40,10 @@ const KNOWN_MODELS: AiModelDefinition[] = [
30
40
  inputCostPer1kTokensUsd: 0.00015,
31
41
  outputCostPer1kTokensUsd: 0.0006,
32
42
  },
43
+ {
44
+ provider: "anthropic",
45
+ model: "claude-sonnet-4.5",
46
+ },
33
47
  {
34
48
  provider: "anthropic",
35
49
  model: "claude-3-5-sonnet-20241022",
@@ -42,6 +56,14 @@ const KNOWN_MODELS: AiModelDefinition[] = [
42
56
  inputCostPer1kTokensUsd: 0.0008,
43
57
  outputCostPer1kTokensUsd: 0.004,
44
58
  },
59
+ {
60
+ provider: "gateway",
61
+ model: "openai/gpt-5.4",
62
+ },
63
+ {
64
+ provider: "gateway",
65
+ model: "anthropic/claude-sonnet-4.5",
66
+ },
45
67
  {
46
68
  provider: "gateway",
47
69
  model: "openai/gpt-4o",
@@ -123,12 +145,39 @@ export function buildAiRegistry(
123
145
  classified: ClassifiedPackage[],
124
146
  ): AiRegistry {
125
147
  const generations: AiGenerationCall[] = [];
148
+ const tools: AiToolDefinition[] = [];
149
+ const agents: AiAgentDefinition[] = [];
126
150
 
127
151
  for (const symbol of appGraph.symbols) {
128
152
  const sourceSlice =
129
153
  typeof symbol.meta.sourceSlice === "string" ? symbol.meta.sourceSlice : "";
130
154
  if (sourceSlice.length === 0) continue;
131
155
 
156
+ if (symbol.kind === "aiTool") {
157
+ const meta = parseAiToolMeta(sourceSlice);
158
+ tools.push({
159
+ name: symbol.name,
160
+ file: symbol.file,
161
+ ...(meta.description ? { description: meta.description } : {}),
162
+ risk: meta.risk,
163
+ strict: meta.strict,
164
+ needsApproval: meta.needsApproval,
165
+ });
166
+ }
167
+
168
+ if (symbol.kind === "agent") {
169
+ const meta = parseAiAgentMeta(sourceSlice);
170
+ agents.push({
171
+ name: symbol.name,
172
+ file: symbol.file,
173
+ provider: meta.provider ?? "gateway",
174
+ model: meta.model ?? "unknown",
175
+ ...(meta.instructions ? { instructions: meta.instructions } : {}),
176
+ tools: meta.tools,
177
+ stopWhen: meta.stopWhen,
178
+ });
179
+ }
180
+
132
181
  for (const call of parseAiCallsFromSlice(sourceSlice)) {
133
182
  generations.push({
134
183
  provider: call.provider ?? "openai",
@@ -145,6 +194,16 @@ export function buildAiRegistry(
145
194
  if (fileCmp !== 0) return fileCmp;
146
195
  return a.method.localeCompare(b.method);
147
196
  });
197
+ tools.sort((a, b) => {
198
+ const nameCmp = a.name.localeCompare(b.name);
199
+ if (nameCmp !== 0) return nameCmp;
200
+ return a.file.localeCompare(b.file);
201
+ });
202
+ agents.sort((a, b) => {
203
+ const nameCmp = a.name.localeCompare(b.name);
204
+ if (nameCmp !== 0) return nameCmp;
205
+ return a.file.localeCompare(b.file);
206
+ });
148
207
 
149
208
  return {
150
209
  schemaVersion: AI_REGISTRY_SCHEMA_VERSION,
@@ -158,6 +217,8 @@ export function buildAiRegistry(
158
217
  ),
159
218
  providers: buildProviders(classified),
160
219
  generations,
220
+ tools,
221
+ agents,
161
222
  diagnostics: [],
162
223
  };
163
224
  }
@@ -1,2 +1,2 @@
1
1
  export const AI_REGISTRY_SCHEMA_VERSION = "1";
2
- export const AI_REGISTRY_ANALYZER_VERSION = "1.0.0";
2
+ export const AI_REGISTRY_ANALYZER_VERSION = "1.1.0";
@@ -1,7 +1,7 @@
1
1
  import type { ForgeAiProvider } from "../types/ai-registry.ts";
2
2
 
3
3
  const AI_METHOD_PATTERN =
4
- /(?:ctx\.ai|ai)\.(generateText|streamText|generateStructured)\s*\(/g;
4
+ /(?:(?:ctx\.ai|ai)\.(generateText|streamText|generateStructured|runAgent)|ctx\.agent\.(run))\s*\(/g;
5
5
 
6
6
  const PROVIDER_PATTERN =
7
7
  /provider\s*:\s*["'](openai|anthropic|gateway)["']/;
@@ -11,18 +11,81 @@ const MODEL_PATTERN = /model\s*:\s*["']([^"']+)["']/;
11
11
  const PURPOSE_PATTERN = /purpose\s*:\s*["']([^"']+)["']/;
12
12
 
13
13
  export interface ParsedAiCall {
14
- method: "generateText" | "streamText" | "generateStructured";
14
+ method: "generateText" | "streamText" | "generateStructured" | "runAgent";
15
15
  provider?: ForgeAiProvider;
16
16
  model?: string;
17
17
  purpose?: string;
18
18
  }
19
19
 
20
+ function quotedOrCommentRanges(source: string): Array<{ start: number; end: number }> {
21
+ const ranges: Array<{ start: number; end: number }> = [];
22
+ let i = 0;
23
+
24
+ while (i < source.length) {
25
+ const char = source[i];
26
+ const next = source[i + 1];
27
+
28
+ if (char === "/" && next === "/") {
29
+ const start = i;
30
+ i += 2;
31
+ while (i < source.length && source[i] !== "\n") {
32
+ i += 1;
33
+ }
34
+ ranges.push({ start, end: i });
35
+ continue;
36
+ }
37
+
38
+ if (char === "/" && next === "*") {
39
+ const start = i;
40
+ i += 2;
41
+ while (i < source.length && !(source[i] === "*" && source[i + 1] === "/")) {
42
+ i += 1;
43
+ }
44
+ i = Math.min(source.length, i + 2);
45
+ ranges.push({ start, end: i });
46
+ continue;
47
+ }
48
+
49
+ if (char === "\"" || char === "'" || char === "`") {
50
+ const quote = char;
51
+ const start = i;
52
+ i += 1;
53
+ while (i < source.length) {
54
+ if (source[i] === "\\") {
55
+ i += 2;
56
+ continue;
57
+ }
58
+ if (source[i] === quote) {
59
+ i += 1;
60
+ break;
61
+ }
62
+ i += 1;
63
+ }
64
+ ranges.push({ start, end: i });
65
+ continue;
66
+ }
67
+
68
+ i += 1;
69
+ }
70
+
71
+ return ranges;
72
+ }
73
+
74
+ function indexInsideRange(index: number, ranges: Array<{ start: number; end: number }>): boolean {
75
+ return ranges.some((range) => index >= range.start && index < range.end);
76
+ }
77
+
20
78
  export function parseAiCallsFromSlice(sourceSlice: string): ParsedAiCall[] {
21
79
  const calls: ParsedAiCall[] = [];
80
+ const ignoredRanges = quotedOrCommentRanges(sourceSlice);
22
81
 
23
82
  for (const match of sourceSlice.matchAll(AI_METHOD_PATTERN)) {
24
- const method = match[1] as ParsedAiCall["method"];
25
83
  const start = match.index ?? 0;
84
+ if (indexInsideRange(start, ignoredRanges)) {
85
+ continue;
86
+ }
87
+
88
+ const method = (match[1] ?? (match[2] ? "runAgent" : "")) as ParsedAiCall["method"];
26
89
  const window = sourceSlice.slice(start, start + 600);
27
90
 
28
91
  let provider: ForgeAiProvider | undefined;
@@ -49,8 +112,108 @@ export function parseAiCallsFromSlice(sourceSlice: string): ParsedAiCall[] {
49
112
  return calls;
50
113
  }
51
114
 
52
- const FORBIDDEN_AI_CONTEXT_PATTERN = /ctx\.ai\./;
115
+ const FORBIDDEN_AI_CONTEXT_PATTERN = /ctx\.(?:ai\.|agent\.run\s*\()/;
53
116
 
54
117
  export function detectCtxAiUsage(sourceSlice: string): boolean {
55
- return FORBIDDEN_AI_CONTEXT_PATTERN.test(sourceSlice);
118
+ const ignoredRanges = quotedOrCommentRanges(sourceSlice);
119
+ for (const match of sourceSlice.matchAll(new RegExp(FORBIDDEN_AI_CONTEXT_PATTERN, "g"))) {
120
+ if (!indexInsideRange(match.index ?? 0, ignoredRanges)) {
121
+ return true;
122
+ }
123
+ }
124
+ return false;
125
+ }
126
+
127
+ const DESCRIPTION_PATTERN = /description\s*:\s*["'`]([^"'`]+)["'`]/;
128
+ const RISK_PATTERN = /risk\s*:\s*["'](read|write|external|destructive)["']/;
129
+ const STRICT_PATTERN = /strict\s*:\s*(true|false)/;
130
+ const NEEDS_APPROVAL_PATTERN = /needsApproval\s*:\s*(true|false|async\s*\(|\([^)]*\)\s*=>|[A-Za-z_$][A-Za-z0-9_$]*)/;
131
+ const INSTRUCTIONS_PATTERN = /instructions\s*:\s*["'`]([^"'`]+)["'`]/;
132
+ const TOOL_ARRAY_PATTERN = /tools\s*:\s*\[([^\]]*)\]/s;
133
+ const TOOL_OBJECT_PATTERN = /tools\s*:\s*\{([^}]*)\}/s;
134
+ const STOP_TOOL_PATTERN = /stopWhen\s*:\s*\{[^}]*kind\s*:\s*["']toolCall["'][^}]*toolName\s*:\s*["']([^"']+)["'][^}]*\}/s;
135
+ const STOP_STEP_PATTERN = /stopWhen\s*:\s*\{[^}]*kind\s*:\s*["']stepCount["'][^}]*maxSteps\s*:\s*(\d+)[^}]*\}/s;
136
+ const MAX_STEPS_PATTERN = /maxSteps\s*:\s*(\d+)/;
137
+
138
+ export interface ParsedAiToolMeta {
139
+ description?: string;
140
+ risk: "read" | "write" | "external" | "destructive" | "unknown";
141
+ strict: boolean;
142
+ needsApproval: boolean | "dynamic";
143
+ }
144
+
145
+ export interface ParsedAiAgentMeta {
146
+ provider?: ForgeAiProvider;
147
+ model?: string;
148
+ instructions?: string;
149
+ tools: string[];
150
+ stopWhen:
151
+ | { kind: "stepCount"; maxSteps: number }
152
+ | { kind: "toolCall"; toolName: string }
153
+ | { kind: "default" };
154
+ }
155
+
156
+ function parseBooleanOrDynamic(value: string | undefined): boolean | "dynamic" {
157
+ if (value === "true") return true;
158
+ if (value === "false") return false;
159
+ return "dynamic";
160
+ }
161
+
162
+ function parseStringList(raw: string | undefined): string[] {
163
+ if (!raw) return [];
164
+ return [...raw.matchAll(/["'`]([^"'`]+)["'`]/g)]
165
+ .map((match) => match[1] ?? "")
166
+ .filter(Boolean)
167
+ .sort();
168
+ }
169
+
170
+ function parseObjectToolKeys(raw: string | undefined): string[] {
171
+ if (!raw) return [];
172
+ const explicit = [...raw.matchAll(/([A-Za-z_$][A-Za-z0-9_$]*)\s*:/g)]
173
+ .map((match) => match[1] ?? "")
174
+ .filter(Boolean);
175
+ const shorthand = raw
176
+ .split(",")
177
+ .map((part) => part.trim())
178
+ .filter((part) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(part));
179
+ return [...new Set([...explicit, ...shorthand])].sort();
180
+ }
181
+
182
+ export function parseAiToolMeta(sourceSlice: string): ParsedAiToolMeta {
183
+ const description = DESCRIPTION_PATTERN.exec(sourceSlice)?.[1];
184
+ const risk = RISK_PATTERN.exec(sourceSlice)?.[1] as ParsedAiToolMeta["risk"] | undefined;
185
+ const strict = STRICT_PATTERN.exec(sourceSlice)?.[1] === "true";
186
+ const needsApprovalMatch = NEEDS_APPROVAL_PATTERN.exec(sourceSlice)?.[1];
187
+
188
+ return {
189
+ ...(description ? { description } : {}),
190
+ risk: risk ?? "unknown",
191
+ strict,
192
+ needsApproval: needsApprovalMatch
193
+ ? parseBooleanOrDynamic(needsApprovalMatch)
194
+ : false,
195
+ };
196
+ }
197
+
198
+ export function parseAiAgentMeta(sourceSlice: string): ParsedAiAgentMeta {
199
+ const provider = PROVIDER_PATTERN.exec(sourceSlice)?.[1] as ForgeAiProvider | undefined;
200
+ const model = MODEL_PATTERN.exec(sourceSlice)?.[1];
201
+ const instructions = INSTRUCTIONS_PATTERN.exec(sourceSlice)?.[1];
202
+ const arrayTools = parseStringList(TOOL_ARRAY_PATTERN.exec(sourceSlice)?.[1]);
203
+ const objectTools = parseObjectToolKeys(TOOL_OBJECT_PATTERN.exec(sourceSlice)?.[1]);
204
+ const stopTool = STOP_TOOL_PATTERN.exec(sourceSlice)?.[1];
205
+ const stopStepsRaw =
206
+ STOP_STEP_PATTERN.exec(sourceSlice)?.[1] ?? MAX_STEPS_PATTERN.exec(sourceSlice)?.[1];
207
+
208
+ return {
209
+ ...(provider ? { provider } : {}),
210
+ ...(model ? { model } : {}),
211
+ ...(instructions ? { instructions } : {}),
212
+ tools: [...new Set([...arrayTools, ...objectTools])].sort(),
213
+ stopWhen: stopTool
214
+ ? { kind: "toolCall", toolName: stopTool }
215
+ : stopStepsRaw
216
+ ? { kind: "stepCount", maxSteps: Number(stopStepsRaw) }
217
+ : { kind: "default" },
218
+ };
56
219
  }
@@ -5,6 +5,16 @@ import type { QueryRegistry } from "../types/query-registry.ts";
5
5
  import type { LiveQueryRegistry } from "../types/live-query-registry.ts";
6
6
  import type { RuntimeGraph } from "../types/runtime-graph.ts";
7
7
  import type { WorkflowRegistry } from "../types/workflow-registry.ts";
8
+ import type { ForgeExternalServiceGraph } from "../external-manifest/types.ts";
9
+
10
+ export interface ApiExternalEntry {
11
+ service: string;
12
+ name: string;
13
+ kind: "command" | "query";
14
+ language: string;
15
+ framework?: string;
16
+ transport: string;
17
+ }
8
18
 
9
19
  export interface ApiSurface {
10
20
  schemaVersion: string;
@@ -15,6 +25,11 @@ export interface ApiSurface {
15
25
  liveQueries: Record<string, string>;
16
26
  actions: Record<string, string>;
17
27
  workflows: Record<string, string>;
28
+ external?: {
29
+ services: Record<string, string>;
30
+ commands: Record<string, ApiExternalEntry>;
31
+ queries: Record<string, ApiExternalEntry>;
32
+ };
18
33
  }
19
34
 
20
35
  export function buildApiSurface(
@@ -22,6 +37,7 @@ export function buildApiSurface(
22
37
  queryRegistry: QueryRegistry,
23
38
  liveQueryRegistry: LiveQueryRegistry,
24
39
  workflowRegistry: WorkflowRegistry,
40
+ externalServices?: ForgeExternalServiceGraph,
25
41
  ): ApiSurface {
26
42
  const queries: Record<string, string> = {};
27
43
  for (const query of queryRegistry.queries) {
@@ -48,6 +64,31 @@ export function buildApiSurface(
48
64
  workflows[workflow.name] = workflow.name;
49
65
  }
50
66
 
67
+ const external = {
68
+ services: {} as Record<string, string>,
69
+ commands: {} as Record<string, ApiExternalEntry>,
70
+ queries: {} as Record<string, ApiExternalEntry>,
71
+ };
72
+ for (const service of externalServices?.services ?? []) {
73
+ external.services[service.name] = service.name;
74
+ for (const entry of service.entries) {
75
+ const qualifiedName = `${service.name}.${entry.name}`;
76
+ const surfaceEntry = {
77
+ service: service.name,
78
+ name: entry.name,
79
+ kind: entry.kind,
80
+ language: service.language,
81
+ ...(service.framework ? { framework: service.framework } : {}),
82
+ transport: service.transport,
83
+ };
84
+ if (entry.kind === "command") {
85
+ external.commands[qualifiedName] = surfaceEntry;
86
+ } else {
87
+ external.queries[qualifiedName] = surfaceEntry;
88
+ }
89
+ }
90
+ }
91
+
51
92
  return {
52
93
  schemaVersion: "1.0.0",
53
94
  generatorVersion: GENERATOR_VERSION,
@@ -57,6 +98,7 @@ export function buildApiSurface(
57
98
  queryInputHash: queryRegistry.inputHash,
58
99
  liveQueryInputHash: liveQueryRegistry.inputHash,
59
100
  workflowInputHash: workflowRegistry.inputHash,
101
+ externalInputHash: externalServices?.inputHash ?? "",
60
102
  }),
61
103
  ),
62
104
  queries,
@@ -64,10 +106,12 @@ export function buildApiSurface(
64
106
  liveQueries,
65
107
  actions,
66
108
  workflows,
109
+ external,
67
110
  };
68
111
  }
69
112
 
70
113
  export function serializeApiTs(surface: ApiSurface): string {
114
+ const external = surface.external ?? { services: {}, commands: {}, queries: {} };
71
115
  return `export const api = ${JSON.stringify(
72
116
  {
73
117
  queries: surface.queries,
@@ -75,6 +119,7 @@ export function serializeApiTs(surface: ApiSurface): string {
75
119
  liveQueries: surface.liveQueries,
76
120
  actions: surface.actions,
77
121
  workflows: surface.workflows,
122
+ external,
78
123
  },
79
124
  null,
80
125
  2,
@@ -90,6 +135,7 @@ export const serverApi = {
90
135
  liveQueries: api.liveQueries,
91
136
  actions: api.actions,
92
137
  workflows: api.workflows,
138
+ external: api.external,
93
139
  } as const;
94
140
  `;
95
141
  }
@@ -102,6 +148,7 @@ export const clientApi = {
102
148
  queries: api.queries,
103
149
  commands: api.commands,
104
150
  liveQueries: api.liveQueries,
151
+ external: api.external,
105
152
  } as const;
106
153
  `;
107
154
  }
@@ -2,14 +2,15 @@ import { canonicalJson } from "../primitives/serialize.ts";
2
2
  import { hashStable } from "../primitives/hash.ts";
3
3
  import { normalizePath } from "../primitives/paths.ts";
4
4
  import { stableSortEdges, stableSortSymbols } from "../primitives/sort.ts";
5
- import type { AppGraph, SourceFile } from "../types/app-graph.ts";
5
+ import type { AppGraph, ForgeEdge, ForgeSymbol, SourceFile } from "../types/app-graph.ts";
6
6
  import { detectDuplicateSymbols } from "./dup-symbol.ts";
7
7
  import { buildModuleGraph } from "./module-graph.ts";
8
8
  import { incrementalParse } from "./parser.ts";
9
+ import { recordAppGraphProfile } from "./profile.ts";
9
10
  import { buildForgeSymbols } from "./symbols.ts";
10
11
  import { hashTsconfigForWorkspace } from "./tsconfig-hash.ts";
11
12
  import type { ParseInvalidationKey } from "./types.ts";
12
- import { buildAnalyzerVersion } from "./types.ts";
13
+ import { buildAnalyzerVersion, parseInvalidationKeyEquals } from "./types.ts";
13
14
  import {
14
15
  APP_GRAPH_SCHEMA_VERSION,
15
16
  FORGE_CLASSIFIER_VERSION,
@@ -65,10 +66,45 @@ function parseInvalidationFromPrior(prior: AppGraph): ParseInvalidationKey | und
65
66
  };
66
67
  }
67
68
 
69
+ function moduleIdByFile(moduleGraph: AppGraph["moduleGraph"]): Map<string, string> {
70
+ return new Map(moduleGraph.nodes.map((node) => [node.file, node.id]));
71
+ }
72
+
73
+ function buildAppGraphEdges(
74
+ symbols: ForgeSymbol[],
75
+ moduleGraph: AppGraph["moduleGraph"],
76
+ ): ForgeEdge[] {
77
+ const edges: ForgeEdge[] = [];
78
+ const modules = moduleIdByFile(moduleGraph);
79
+
80
+ for (const symbol of symbols) {
81
+ const moduleId = modules.get(symbol.file);
82
+ if (moduleId) {
83
+ edges.push({ from: symbol.id, to: moduleId, kind: "registers" });
84
+ }
85
+ }
86
+
87
+ for (const module of moduleGraph.nodes) {
88
+ for (const localImport of module.localImports) {
89
+ edges.push({
90
+ from: module.id,
91
+ to: localImport.toModuleId,
92
+ kind: "imports",
93
+ });
94
+ }
95
+ }
96
+
97
+ return edges;
98
+ }
99
+
68
100
  export async function buildAppGraph(
69
101
  options: AppGraphBuildOptions,
70
102
  ): Promise<AppGraph> {
103
+ const started = Date.now();
104
+ let checkpoint = started;
71
105
  const sources = normalizeSources(options.sources);
106
+ const normalizeMs = Date.now() - checkpoint;
107
+ checkpoint = Date.now();
72
108
  const tsconfigHash =
73
109
  options.tsconfigHash ??
74
110
  hashTsconfigForWorkspace(
@@ -86,36 +122,60 @@ export async function buildAppGraph(
86
122
  const priorInvalidation = options.prior
87
123
  ? parseInvalidationFromPrior(options.prior)
88
124
  : undefined;
125
+ const canReusePrior =
126
+ priorInvalidation !== undefined &&
127
+ parseInvalidationKeyEquals(priorInvalidation, invalidation);
89
128
 
90
129
  const { symbols: rawSymbols, diagnostics: parseDiagnostics } =
91
130
  incrementalParse(
92
131
  sources,
93
132
  options.prior?.symbols,
133
+ options.prior?.sourceHashes,
94
134
  priorInvalidation,
95
135
  invalidation,
96
136
  );
137
+ const parseMs = Date.now() - checkpoint;
138
+ checkpoint = Date.now();
97
139
 
98
140
  const forgeSymbols = buildForgeSymbols(rawSymbols, sources);
141
+ const symbolsMs = Date.now() - checkpoint;
142
+ checkpoint = Date.now();
99
143
  const dupDiagnostics = detectDuplicateSymbols(forgeSymbols);
144
+ const duplicatesMs = Date.now() - checkpoint;
145
+ checkpoint = Date.now();
100
146
  const moduleGraph = buildModuleGraph(
101
147
  sources,
102
148
  rawSymbols,
103
- options.workspaceRoot,
104
- options.tsconfigPath,
105
149
  options.prior,
150
+ canReusePrior,
106
151
  );
152
+ const moduleGraphMs = Date.now() - checkpoint;
153
+ checkpoint = Date.now();
154
+ const inputHash = computeInputHash(sources, invalidation);
155
+ const inputHashMs = Date.now() - checkpoint;
156
+ const sortedSymbols = stableSortSymbols(forgeSymbols);
107
157
 
108
- return {
158
+ const graph = {
109
159
  schemaVersion: APP_GRAPH_SCHEMA_VERSION,
110
160
  generatorVersion: GENERATOR_VERSION,
111
161
  analyzerVersion: buildAnalyzerVersion(invalidation),
112
- inputHash: computeInputHash(sources, invalidation),
162
+ inputHash,
113
163
  sourceHashes: Object.fromEntries(
114
164
  sources.map((source) => [source.path, source.contentHash]),
115
165
  ),
116
- symbols: stableSortSymbols(forgeSymbols),
117
- edges: stableSortEdges([]),
166
+ symbols: sortedSymbols,
167
+ edges: stableSortEdges(buildAppGraphEdges(sortedSymbols, moduleGraph)),
118
168
  moduleGraph,
119
169
  diagnostics: [...parseDiagnostics, ...dupDiagnostics],
120
170
  };
171
+ recordAppGraphProfile(graph, {
172
+ normalizeMs,
173
+ parseMs,
174
+ symbolsMs,
175
+ duplicatesMs,
176
+ moduleGraphMs,
177
+ inputHashMs,
178
+ totalMs: Date.now() - started,
179
+ });
180
+ return graph;
121
181
  }