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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (416) hide show
  1. package/.npmignore +10 -0
  2. package/AGENTS.md +142 -90
  3. package/CHANGELOG.md +433 -0
  4. package/LICENSE +21 -0
  5. package/README.md +67 -8
  6. package/adapters/go/README.md +23 -0
  7. package/adapters/go/go.mod +3 -0
  8. package/adapters/go/http.go +149 -0
  9. package/adapters/go/registry.go +234 -0
  10. package/adapters/go/types.go +136 -0
  11. package/adapters/java/README.md +68 -0
  12. package/adapters/java/pom.xml +34 -0
  13. package/adapters/java/src/main/java/dev/forgeos/adapter/Auth.java +20 -0
  14. package/adapters/java/src/main/java/dev/forgeos/adapter/Diagnostic.java +16 -0
  15. package/adapters/java/src/main/java/dev/forgeos/adapter/Entry.java +38 -0
  16. package/adapters/java/src/main/java/dev/forgeos/adapter/EntryKind.java +16 -0
  17. package/adapters/java/src/main/java/dev/forgeos/adapter/ErrorInfo.java +4 -0
  18. package/adapters/java/src/main/java/dev/forgeos/adapter/Forge.java +94 -0
  19. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeCall.java +12 -0
  20. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeContext.java +11 -0
  21. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHandler.java +8 -0
  22. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHttpHandler.java +179 -0
  23. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeRegistry.java +121 -0
  24. package/adapters/java/src/main/java/dev/forgeos/adapter/Json.java +14 -0
  25. package/adapters/java/src/main/java/dev/forgeos/adapter/Manifest.java +14 -0
  26. package/adapters/java/src/main/java/dev/forgeos/adapter/RequestEnvelope.java +6 -0
  27. package/adapters/java/src/main/java/dev/forgeos/adapter/ResponseEnvelope.java +25 -0
  28. package/adapters/java/src/main/java/dev/forgeos/adapter/Risk.java +18 -0
  29. package/adapters/java/src/main/java/dev/forgeos/adapter/Schemas.java +36 -0
  30. package/adapters/java/src/main/java/dev/forgeos/adapter/Service.java +65 -0
  31. package/adapters/java/src/main/java/dev/forgeos/adapter/TransactionMode.java +18 -0
  32. package/adapters/java/src/main/java/dev/forgeos/adapter/TypedForgeHandler.java +6 -0
  33. package/adapters/java-spring-boot-starter/README.md +32 -0
  34. package/adapters/java-spring-boot-starter/pom.xml +36 -0
  35. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeCommand.java +22 -0
  36. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeExternalService.java +15 -0
  37. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeQuery.java +16 -0
  38. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeServiceBeanCondition.java +18 -0
  39. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringAutoConfiguration.java +16 -0
  40. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringRuntime.java +104 -0
  41. package/adapters/java-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +1 -0
  42. package/bin/forge.mjs +18 -0
  43. package/docs/cair-protocol.md +103 -0
  44. package/docs/changelog.md +548 -0
  45. package/docs/forge-protocol.md +189 -0
  46. package/examples/go-billing/go.mod +7 -0
  47. package/examples/go-billing/main.go +120 -0
  48. package/examples/java-billing/pom.xml +52 -0
  49. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/CreateInvoiceInput.java +4 -0
  50. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Invoice.java +11 -0
  51. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Main.java +127 -0
  52. package/package.json +31 -3
  53. package/schemas/forge-manifest.schema.json +57 -0
  54. package/src/forge/_generated/releaseManifest.json +1 -2
  55. package/src/forge/_generated/releaseManifest.ts +3 -3
  56. package/src/forge/agent-adapters/index.ts +1584 -125
  57. package/src/forge/agent-adapters/types.ts +224 -1
  58. package/src/forge/agent-memory/bridge.ts +1333 -0
  59. package/src/forge/agent-memory/context-pack.ts +277 -0
  60. package/src/forge/agent-memory/hook-runner.ts +312 -0
  61. package/src/forge/agent-memory/mcp.ts +224 -0
  62. package/src/forge/agent-memory/normalize.ts +498 -0
  63. package/src/forge/agent-memory/redaction.ts +103 -0
  64. package/src/forge/agent-memory/sources/claude-code.ts +51 -0
  65. package/src/forge/agent-memory/sources/codex-hook-runner.mjs +273 -0
  66. package/src/forge/agent-memory/sources/codex.ts +119 -0
  67. package/src/forge/agent-memory/sources/cursor.ts +35 -0
  68. package/src/forge/agent-memory/types.ts +204 -0
  69. package/src/forge/bench.ts +248 -0
  70. package/src/forge/brownfield-import/index.ts +801 -0
  71. package/src/forge/brownfield-import/types.ts +127 -0
  72. package/src/forge/cair/action-journal.ts +61 -0
  73. package/src/forge/cair/action-parser.ts +314 -0
  74. package/src/forge/cair/action-validator.ts +40 -0
  75. package/src/forge/cair/actions.ts +1818 -0
  76. package/src/forge/cair/format.ts +77 -0
  77. package/src/forge/cair/index.ts +106 -0
  78. package/src/forge/cair/query.ts +478 -0
  79. package/src/forge/cair/snapshot.ts +315 -0
  80. package/src/forge/cair/types.ts +248 -0
  81. package/src/forge/cli/ai.ts +339 -21
  82. package/src/forge/cli/auth.ts +348 -10
  83. package/src/forge/cli/authmd.ts +441 -0
  84. package/src/forge/cli/baseline.ts +112 -0
  85. package/src/forge/cli/build.ts +20 -4
  86. package/src/forge/cli/changed.ts +437 -0
  87. package/src/forge/cli/codex-app-server.ts +877 -0
  88. package/src/forge/cli/commands.ts +1620 -20
  89. package/src/forge/cli/db.ts +209 -2
  90. package/src/forge/cli/deploy.ts +887 -0
  91. package/src/forge/cli/deps.ts +82 -13
  92. package/src/forge/cli/dev.ts +961 -46
  93. package/src/forge/cli/docs.ts +265 -0
  94. package/src/forge/cli/doctor.ts +297 -0
  95. package/src/forge/cli/field-test.ts +329 -0
  96. package/src/forge/cli/handoff.ts +336 -0
  97. package/src/forge/cli/index.ts +1 -0
  98. package/src/forge/cli/last-run.ts +84 -0
  99. package/src/forge/cli/main.ts +107 -3
  100. package/src/forge/cli/new.ts +152 -13
  101. package/src/forge/cli/next-actions.ts +23 -0
  102. package/src/forge/cli/output.ts +389 -6
  103. package/src/forge/cli/parse.ts +1050 -34
  104. package/src/forge/cli/progress.ts +51 -0
  105. package/src/forge/cli/query.ts +32 -0
  106. package/src/forge/cli/release.ts +35 -11
  107. package/src/forge/cli/rls.ts +43 -4
  108. package/src/forge/cli/run.ts +41 -0
  109. package/src/forge/cli/security.ts +112 -0
  110. package/src/forge/cli/self-host.ts +56 -14
  111. package/src/forge/cli/studio.ts +2218 -0
  112. package/src/forge/cli/verify.ts +1455 -32
  113. package/src/forge/cli/windows.ts +23 -0
  114. package/src/forge/cli/workos.ts +1020 -0
  115. package/src/forge/compiler/agent-contract/build.ts +670 -64
  116. package/src/forge/compiler/agent-contract/types.ts +45 -2
  117. package/src/forge/compiler/ai-registry/parse.ts +71 -2
  118. package/src/forge/compiler/api-surface/build.ts +47 -0
  119. package/src/forge/compiler/app-graph/build.ts +112 -9
  120. package/src/forge/compiler/app-graph/extract.ts +107 -0
  121. package/src/forge/compiler/app-graph/module-graph.ts +73 -78
  122. package/src/forge/compiler/app-graph/parser.ts +24 -24
  123. package/src/forge/compiler/app-graph/profile.ts +26 -0
  124. package/src/forge/compiler/app-graph/versions.ts +1 -1
  125. package/src/forge/compiler/classifier/capabilities.ts +3 -2
  126. package/src/forge/compiler/classifier/classify.ts +32 -8
  127. package/src/forge/compiler/classifier/secrets.ts +3 -2
  128. package/src/forge/compiler/classifier/signals.ts +91 -1
  129. package/src/forge/compiler/client-sdk/build-manifest.ts +59 -0
  130. package/src/forge/compiler/client-sdk/render-client.ts +295 -13
  131. package/src/forge/compiler/data-graph/parse.ts +20 -4
  132. package/src/forge/compiler/data-graph/sql/ddl.ts +144 -31
  133. package/src/forge/compiler/data-graph/sql/serialize.ts +4 -0
  134. package/src/forge/compiler/data-graph/sql/types.ts +1 -0
  135. package/src/forge/compiler/diagnostics/codes.ts +30 -0
  136. package/src/forge/compiler/diagnostics/create.ts +21 -2
  137. package/src/forge/compiler/diagnostics/index.ts +2 -0
  138. package/src/forge/compiler/emitter/barrel.ts +3 -0
  139. package/src/forge/compiler/emitter/render.ts +9 -0
  140. package/src/forge/compiler/external-manifest/registry.ts +205 -0
  141. package/src/forge/compiler/external-manifest/types.ts +91 -0
  142. package/src/forge/compiler/external-manifest/validate.ts +373 -0
  143. package/src/forge/compiler/frontend-graph/build.ts +142 -14
  144. package/src/forge/compiler/integration/add.ts +618 -24
  145. package/src/forge/compiler/integration/plan.ts +43 -12
  146. package/src/forge/compiler/integration/render.ts +29 -0
  147. package/src/forge/compiler/integration/snapshot.ts +2 -0
  148. package/src/forge/compiler/integration/templates/convex.ts +70 -0
  149. package/src/forge/compiler/integration/templates/index.ts +1 -0
  150. package/src/forge/compiler/integration/templates/render.ts +38 -0
  151. package/src/forge/compiler/integration/templates/types.ts +3 -0
  152. package/src/forge/compiler/integration/templates/workos.ts +1219 -0
  153. package/src/forge/compiler/make-registry/build.ts +8 -9
  154. package/src/forge/compiler/orchestrator/fast-check.ts +4 -0
  155. package/src/forge/compiler/orchestrator/generate-lock.ts +14 -3
  156. package/src/forge/compiler/orchestrator/manifest.ts +1 -1
  157. package/src/forge/compiler/orchestrator/plan-profile.ts +23 -0
  158. package/src/forge/compiler/orchestrator/plan.ts +247 -10
  159. package/src/forge/compiler/orchestrator/profile.ts +65 -0
  160. package/src/forge/compiler/orchestrator/run.ts +97 -31
  161. package/src/forge/compiler/orchestrator/serialize.ts +33 -8
  162. package/src/forge/compiler/orchestrator/types.ts +1 -1
  163. package/src/forge/compiler/package-graph/compiler.ts +3 -1
  164. package/src/forge/compiler/package-graph/constants.ts +1 -1
  165. package/src/forge/compiler/package-manager/adapter.ts +4 -1
  166. package/src/forge/compiler/package-manager/commands.ts +4 -0
  167. package/src/forge/compiler/package-manager/executor.ts +30 -1
  168. package/src/forge/compiler/package-manager/version.ts +36 -12
  169. package/src/forge/compiler/package-upgrades/planner.ts +155 -18
  170. package/src/forge/compiler/package-upgrades/types.ts +2 -0
  171. package/src/forge/compiler/policy-registry/build.ts +47 -2
  172. package/src/forge/compiler/policy-registry/parse.ts +32 -2
  173. package/src/forge/compiler/recipes/definitions.ts +63 -0
  174. package/src/forge/compiler/recipes/index.ts +2 -0
  175. package/src/forge/compiler/recipes/registry.ts +6 -0
  176. package/src/forge/compiler/test-graph/build.ts +11 -3
  177. package/src/forge/compiler/types/app-graph.ts +8 -2
  178. package/src/forge/compiler/types/cli.ts +75 -1
  179. package/src/forge/compiler/types/dev-manifest.ts +4 -0
  180. package/src/forge/compiler/types/emit.ts +2 -0
  181. package/src/forge/compiler/types/frontend-graph.ts +2 -2
  182. package/src/forge/compiler/types/integration.ts +1 -0
  183. package/src/forge/compiler/types/package-graph.ts +6 -0
  184. package/src/forge/compiler/types/policy-registry.ts +3 -1
  185. package/src/forge/delta/classifier.ts +52 -0
  186. package/src/forge/delta/explain.ts +238 -0
  187. package/src/forge/delta/git-observer.ts +43 -0
  188. package/src/forge/delta/ids.ts +44 -0
  189. package/src/forge/delta/index.ts +25 -0
  190. package/src/forge/delta/recorder.ts +540 -0
  191. package/src/forge/delta/redaction.ts +50 -0
  192. package/src/forge/delta/schema.ts +240 -0
  193. package/src/forge/delta/session.ts +142 -0
  194. package/src/forge/delta/status.ts +1202 -0
  195. package/src/forge/delta/store.ts +3284 -0
  196. package/src/forge/delta/timeline.ts +178 -0
  197. package/src/forge/dev/server.ts +808 -17
  198. package/src/forge/dev/types.ts +15 -1
  199. package/src/forge/dev/watch.ts +17 -7
  200. package/src/forge/dev-console/cycle.ts +280 -33
  201. package/src/forge/dev-console/types.ts +47 -1
  202. package/src/forge/impact/index.ts +204 -9
  203. package/src/forge/impact/types.ts +33 -1
  204. package/src/forge/intent/index.ts +35 -16
  205. package/src/forge/make/fields.ts +26 -0
  206. package/src/forge/make/index.ts +40 -6
  207. package/src/forge/make/templates.ts +155 -2
  208. package/src/forge/make/types.ts +2 -1
  209. package/src/forge/policy.ts +1 -1
  210. package/src/forge/react/index.ts +160 -2
  211. package/src/forge/refactor/index.ts +1 -0
  212. package/src/forge/repair/rules/index.ts +2 -2
  213. package/src/forge/review/index.ts +158 -12
  214. package/src/forge/review/types.ts +15 -0
  215. package/src/forge/runtime/auth/config.ts +17 -0
  216. package/src/forge/runtime/auth/evaluate.ts +15 -2
  217. package/src/forge/runtime/auth/resolve.ts +61 -6
  218. package/src/forge/runtime/auth/types.ts +1 -0
  219. package/src/forge/runtime/db/factory.ts +1 -3
  220. package/src/forge/runtime/db/generated-client.ts +13 -2
  221. package/src/forge/runtime/db/memory-adapter.ts +139 -32
  222. package/src/forge/runtime/db/pglite-adapter.ts +263 -2
  223. package/src/forge/runtime/db/postgres-adapter.ts +6 -3
  224. package/src/forge/runtime/executor.ts +129 -16
  225. package/src/forge/runtime/external/bridge.ts +649 -0
  226. package/src/forge/runtime/runner/run-entry.ts +16 -7
  227. package/src/forge/runtime/telemetry/buffer.ts +4 -1
  228. package/src/forge/runtime/telemetry/scrubber.ts +35 -5
  229. package/src/forge/runtime/webhooks/security.ts +12 -7
  230. package/src/forge/server.ts +17 -3
  231. package/src/forge/ui/index.ts +209 -0
  232. package/src/forge/ui/types.ts +1 -0
  233. package/src/forge/version.ts +1 -1
  234. package/src/forge/vue/index.ts +422 -0
  235. package/src/forge/workspace/baseline.ts +112 -0
  236. package/src/forge/workspace/change-summary.ts +250 -0
  237. package/src/forge/workspace/forge-cli.ts +42 -0
  238. package/src/forge/workspace/git-summary.ts +391 -0
  239. package/templates/agent-workroom/AGENTS.md +29 -0
  240. package/templates/agent-workroom/README.md +34 -0
  241. package/templates/agent-workroom/forge.config.ts +3 -0
  242. package/templates/agent-workroom/package.json +33 -0
  243. package/templates/agent-workroom/src/actions/indexAgentSignal.ts +10 -0
  244. package/templates/agent-workroom/src/commands/openWorkroom.ts +61 -0
  245. package/templates/agent-workroom/src/commands/recordAgentSignal.ts +119 -0
  246. package/templates/agent-workroom/src/commands/recordCheckRun.ts +52 -0
  247. package/templates/agent-workroom/src/forge/schema.ts +54 -0
  248. package/templates/agent-workroom/src/policies.ts +6 -0
  249. package/templates/agent-workroom/src/queries/listWorkrooms.ts +11 -0
  250. package/templates/agent-workroom/src/queries/liveWorkroom.ts +63 -0
  251. package/templates/agent-workroom/tsconfig.json +16 -0
  252. package/templates/agent-workroom/web/index.html +12 -0
  253. package/templates/agent-workroom/web/package.json +21 -0
  254. package/templates/agent-workroom/web/src/App.tsx +345 -0
  255. package/templates/agent-workroom/web/src/lib/forge.ts +13 -0
  256. package/templates/agent-workroom/web/src/main.tsx +13 -0
  257. package/templates/agent-workroom/web/src/styles.css +545 -0
  258. package/templates/agent-workroom/web/tsconfig.json +27 -0
  259. package/templates/b2b-support-web/package.json +1 -0
  260. package/templates/b2b-support-web/web/package.json +1 -1
  261. package/templates/minimal-web/package.json +1 -1
  262. package/templates/minimal-web/web/package.json +2 -2
  263. package/templates/nuxt-web/.vscode/settings.json +14 -0
  264. package/templates/nuxt-web/README.md +30 -0
  265. package/templates/nuxt-web/forge.config.ts +3 -0
  266. package/templates/nuxt-web/package.json +33 -0
  267. package/templates/nuxt-web/src/actions/logNoteCreated.ts +11 -0
  268. package/templates/nuxt-web/src/commands/createNote.ts +26 -0
  269. package/templates/nuxt-web/src/forge/schema.ts +12 -0
  270. package/templates/nuxt-web/src/policies.ts +6 -0
  271. package/templates/nuxt-web/src/queries/listNotes.ts +8 -0
  272. package/templates/nuxt-web/src/queries/liveNotes.ts +8 -0
  273. package/templates/nuxt-web/tsconfig.json +17 -0
  274. package/templates/nuxt-web/web/app.vue +67 -0
  275. package/templates/nuxt-web/web/components/LiveNotes.vue +89 -0
  276. package/templates/nuxt-web/web/components/NoteComposer.vue +100 -0
  277. package/templates/nuxt-web/web/composables/forge.ts +13 -0
  278. package/templates/nuxt-web/web/composables/useNotes.ts +24 -0
  279. package/templates/nuxt-web/web/nuxt.config.ts +11 -0
  280. package/templates/nuxt-web/web/package.json +18 -0
  281. package/templates/nuxt-web/web/plugins/forge.client.ts +10 -0
  282. package/templates/nuxt-web/web/plugins/forge.server.ts +10 -0
  283. package/templates/nuxt-web/web/server/api/forge-health.get.ts +7 -0
  284. package/templates/nuxt-web/web/tsconfig.json +6 -0
  285. package/src/forge/_generated/actionSubscriptions.json +0 -2
  286. package/src/forge/_generated/actionSubscriptions.ts +0 -10
  287. package/src/forge/_generated/agentAdapterManifest.json +0 -2
  288. package/src/forge/_generated/agentAdapterManifest.ts +0 -73
  289. package/src/forge/_generated/agentContract.json +0 -2
  290. package/src/forge/_generated/agentContract.ts +0 -7829
  291. package/src/forge/_generated/agentQuickstart.md +0 -34
  292. package/src/forge/_generated/agentTools.json +0 -2
  293. package/src/forge/_generated/agentTools.md +0 -16
  294. package/src/forge/_generated/agentTools.ts +0 -12
  295. package/src/forge/_generated/aiContext.ts +0 -125
  296. package/src/forge/_generated/aiModels.json +0 -2
  297. package/src/forge/_generated/aiModels.ts +0 -51
  298. package/src/forge/_generated/aiProviders.json +0 -2
  299. package/src/forge/_generated/aiProviders.ts +0 -23
  300. package/src/forge/_generated/aiRegistry.json +0 -2
  301. package/src/forge/_generated/aiRegistry.ts +0 -31
  302. package/src/forge/_generated/api.json +0 -2
  303. package/src/forge/_generated/api.ts +0 -8
  304. package/src/forge/_generated/appGraph.json +0 -2
  305. package/src/forge/_generated/appGraph.ts +0 -14919
  306. package/src/forge/_generated/appMap.md +0 -55
  307. package/src/forge/_generated/artifactManifest.json +0 -2
  308. package/src/forge/_generated/artifactManifest.ts +0 -7
  309. package/src/forge/_generated/authClaims.json +0 -2
  310. package/src/forge/_generated/authClaims.ts +0 -13
  311. package/src/forge/_generated/authConfig.json +0 -2
  312. package/src/forge/_generated/authConfig.ts +0 -17
  313. package/src/forge/_generated/authContext.ts +0 -23
  314. package/src/forge/_generated/authRegistry.json +0 -2
  315. package/src/forge/_generated/authRegistry.ts +0 -25
  316. package/src/forge/_generated/buildInfo.json +0 -2
  317. package/src/forge/_generated/buildInfo.ts +0 -9
  318. package/src/forge/_generated/capabilityMap.json +0 -2
  319. package/src/forge/_generated/capabilityMap.md +0 -15
  320. package/src/forge/_generated/capabilityMap.ts +0 -17
  321. package/src/forge/_generated/client.ts +0 -282
  322. package/src/forge/_generated/clientApi.ts +0 -9
  323. package/src/forge/_generated/clientManifest.json +0 -2
  324. package/src/forge/_generated/clientManifest.ts +0 -39
  325. package/src/forge/_generated/clientTypes.ts +0 -78
  326. package/src/forge/_generated/configRegistry.json +0 -2
  327. package/src/forge/_generated/configRegistry.ts +0 -4
  328. package/src/forge/_generated/dataGraph.json +0 -2
  329. package/src/forge/_generated/dataGraph.ts +0 -8
  330. package/src/forge/_generated/db.json +0 -2
  331. package/src/forge/_generated/db.ts +0 -2
  332. package/src/forge/_generated/dbSecurityManifest.json +0 -2
  333. package/src/forge/_generated/dbSecurityManifest.ts +0 -15
  334. package/src/forge/_generated/dbSessionContext.json +0 -2
  335. package/src/forge/_generated/dbSessionContext.ts +0 -39
  336. package/src/forge/_generated/deployManifest.json +0 -2
  337. package/src/forge/_generated/deployManifest.ts +0 -14
  338. package/src/forge/_generated/devManifest.json +0 -2
  339. package/src/forge/_generated/devManifest.ts +0 -62
  340. package/src/forge/_generated/envSchema.json +0 -2
  341. package/src/forge/_generated/envSchema.ts +0 -59
  342. package/src/forge/_generated/frontendGraph.json +0 -2
  343. package/src/forge/_generated/frontendGraph.ts +0 -27
  344. package/src/forge/_generated/importGuards.json +0 -2
  345. package/src/forge/_generated/importGuards.ts +0 -686
  346. package/src/forge/_generated/index.ts +0 -68
  347. package/src/forge/_generated/liveProductionManifest.json +0 -2
  348. package/src/forge/_generated/liveProductionManifest.ts +0 -23
  349. package/src/forge/_generated/liveProtocol.json +0 -2
  350. package/src/forge/_generated/liveProtocol.ts +0 -21
  351. package/src/forge/_generated/liveQueryRegistry.json +0 -2
  352. package/src/forge/_generated/liveQueryRegistry.ts +0 -9
  353. package/src/forge/_generated/liveTransportConfig.json +0 -2
  354. package/src/forge/_generated/liveTransportConfig.ts +0 -19
  355. package/src/forge/_generated/makeRegistry.json +0 -2
  356. package/src/forge/_generated/makeRegistry.ts +0 -177
  357. package/src/forge/_generated/makeTemplates.json +0 -2
  358. package/src/forge/_generated/makeTemplates.ts +0 -66
  359. package/src/forge/_generated/mockMap.json +0 -2
  360. package/src/forge/_generated/mockMap.ts +0 -7
  361. package/src/forge/_generated/operationPlaybooks.md +0 -167
  362. package/src/forge/_generated/packageGraph.json +0 -2
  363. package/src/forge/_generated/packageGraph.ts +0 -249334
  364. package/src/forge/_generated/packageUpgradeRegistry.json +0 -2
  365. package/src/forge/_generated/packageUpgradeRegistry.ts +0 -15
  366. package/src/forge/_generated/permissionMatrix.json +0 -2
  367. package/src/forge/_generated/permissionMatrix.ts +0 -7
  368. package/src/forge/_generated/policyRegistry.json +0 -2
  369. package/src/forge/_generated/policyRegistry.ts +0 -11
  370. package/src/forge/_generated/queryRegistry.json +0 -2
  371. package/src/forge/_generated/queryRegistry.ts +0 -9
  372. package/src/forge/_generated/react.d.ts +0 -22
  373. package/src/forge/_generated/react.ts +0 -29
  374. package/src/forge/_generated/reactManifest.json +0 -2
  375. package/src/forge/_generated/reactManifest.ts +0 -19
  376. package/src/forge/_generated/rlsPolicies.json +0 -2
  377. package/src/forge/_generated/rlsPolicies.sql +0 -34
  378. package/src/forge/_generated/rlsPolicies.ts +0 -6
  379. package/src/forge/_generated/runtimeGraph.json +0 -2
  380. package/src/forge/_generated/runtimeGraph.ts +0 -8
  381. package/src/forge/_generated/runtimeMatrix.json +0 -2
  382. package/src/forge/_generated/runtimeMatrix.ts +0 -334130
  383. package/src/forge/_generated/runtimeRegistry.ts +0 -2
  384. package/src/forge/_generated/runtimeRules.md +0 -91
  385. package/src/forge/_generated/secretRegistry.json +0 -2
  386. package/src/forge/_generated/secretRegistry.ts +0 -50
  387. package/src/forge/_generated/secretsContext.ts +0 -11
  388. package/src/forge/_generated/serverApi.ts +0 -10
  389. package/src/forge/_generated/sourceMapManifest.json +0 -2
  390. package/src/forge/_generated/sourceMapManifest.ts +0 -7
  391. package/src/forge/_generated/sqlPlan.json +0 -2
  392. package/src/forge/_generated/sqlPlan.ts +0 -88
  393. package/src/forge/_generated/subscriptionManifest.json +0 -2
  394. package/src/forge/_generated/subscriptionManifest.ts +0 -7
  395. package/src/forge/_generated/symbolicationManifest.json +0 -2
  396. package/src/forge/_generated/symbolicationManifest.ts +0 -17
  397. package/src/forge/_generated/telemetryRegistry.json +0 -2
  398. package/src/forge/_generated/telemetryRegistry.ts +0 -9
  399. package/src/forge/_generated/telemetrySinks.json +0 -2
  400. package/src/forge/_generated/telemetrySinks.ts +0 -11
  401. package/src/forge/_generated/tenantScope.json +0 -2
  402. package/src/forge/_generated/tenantScope.ts +0 -8
  403. package/src/forge/_generated/testGraph.json +0 -2
  404. package/src/forge/_generated/testGraph.ts +0 -3430
  405. package/src/forge/_generated/testPlanRegistry.json +0 -2
  406. package/src/forge/_generated/testPlanRegistry.ts +0 -33
  407. package/src/forge/_generated/uiRoutes.json +0 -2
  408. package/src/forge/_generated/uiRoutes.ts +0 -16
  409. package/src/forge/_generated/uiScenarios.json +0 -2
  410. package/src/forge/_generated/uiScenarios.ts +0 -30
  411. package/src/forge/_generated/uiTestManifest.json +0 -2
  412. package/src/forge/_generated/uiTestManifest.ts +0 -27
  413. package/src/forge/_generated/workflowRegistry.json +0 -2
  414. package/src/forge/_generated/workflowRegistry.ts +0 -9
  415. package/src/forge/_generated/workflowSubscriptions.json +0 -2
  416. package/src/forge/_generated/workflowSubscriptions.ts +0 -10
@@ -15,7 +15,6 @@ import type {
15
15
  } from "../types/app-graph.ts";
16
16
  import type { RuntimeContext } from "../types/runtime.ts";
17
17
  import { FORGE_KIND_TO_CONTEXT } from "./forge-apis.ts";
18
- import { loadTsconfig } from "./tsconfig-hash.ts";
19
18
  import type { RawSymbol } from "./types.ts";
20
19
 
21
20
  export function moduleIdForFile(file: string): string {
@@ -57,19 +56,27 @@ function stableSortModuleNodes(nodes: ModuleNode[]): ModuleNode[] {
57
56
 
58
57
  function declaredContextsForFile(
59
58
  file: string,
60
- symbols: RawSymbol[],
59
+ contextsByFile: Map<string, RuntimeContext[]>,
61
60
  ): RuntimeContext[] {
62
- const contexts = new Set<RuntimeContext>();
61
+ return contextsByFile.get(file) ?? [];
62
+ }
63
+
64
+ function buildDeclaredContextsByFile(symbols: RawSymbol[]): Map<string, RuntimeContext[]> {
65
+ const mutable = new Map<string, Set<RuntimeContext>>();
63
66
  for (const symbol of symbols) {
64
- if (symbol.file !== file) {
65
- continue;
66
- }
67
67
  const context = FORGE_KIND_TO_CONTEXT[symbol.kind];
68
68
  if (context) {
69
- contexts.add(context);
69
+ const fileContexts = mutable.get(symbol.file) ?? new Set<RuntimeContext>();
70
+ fileContexts.add(context);
71
+ mutable.set(symbol.file, fileContexts);
70
72
  }
71
73
  }
72
- return stableSortStrings([...contexts]) as RuntimeContext[];
74
+
75
+ const byFile = new Map<string, RuntimeContext[]>();
76
+ for (const [file, fileContexts] of mutable) {
77
+ byFile.set(file, stableSortStrings([...fileContexts]) as RuntimeContext[]);
78
+ }
79
+ return byFile;
73
80
  }
74
81
 
75
82
  function spanFromNode(node: ts.Node, sourceFile: ts.SourceFile): {
@@ -81,50 +88,37 @@ function spanFromNode(node: ts.Node, sourceFile: ts.SourceFile): {
81
88
  return { start, end };
82
89
  }
83
90
 
84
- function toWorkspaceRelativePath(
85
- absoluteOrRelativePath: string,
86
- workspaceRoot: string,
87
- ): string {
88
- const normalized = normalizePath(absoluteOrRelativePath);
89
- const root = normalizePath(path.resolve(workspaceRoot).replace(/\\/g, "/"));
90
- const rootWithSlash = root.endsWith("/") ? root : `${root}/`;
91
-
92
- if (normalized.startsWith(rootWithSlash)) {
93
- return normalized.slice(rootWithSlash.length);
94
- }
95
-
96
- if (normalized === root) {
97
- return "";
98
- }
99
-
100
- return normalized;
101
- }
102
-
103
91
  function resolveLocalTarget(
104
92
  specifier: string,
105
93
  fromFile: string,
106
- program: ts.Program,
107
- workspaceRoot: string,
94
+ sourcePaths: Set<string>,
108
95
  ): string | null {
109
- const resolved = ts.resolveModuleName(
110
- specifier,
111
- fromFile,
112
- program.getCompilerOptions(),
113
- ts.sys,
114
- );
115
-
116
- const fileName = resolved.resolvedModule?.resolvedFileName;
117
- if (!fileName) {
96
+ if (!specifier.startsWith(".")) {
118
97
  return null;
119
98
  }
120
99
 
121
- return toWorkspaceRelativePath(fileName, workspaceRoot);
100
+ const base = normalizePath(path.join(path.dirname(fromFile), specifier));
101
+ const candidates = [
102
+ base,
103
+ `${base}.ts`,
104
+ `${base}.tsx`,
105
+ `${base}/index.ts`,
106
+ `${base}/index.tsx`,
107
+ ];
108
+ if (/\.[cm]?jsx?$/.test(base)) {
109
+ const withoutJsExtension = base.replace(/\.[cm]?jsx?$/, "");
110
+ candidates.push(
111
+ `${withoutJsExtension}.ts`,
112
+ `${withoutJsExtension}.tsx`,
113
+ );
114
+ }
115
+
116
+ return candidates.find((candidate) => sourcePaths.has(candidate)) ?? null;
122
117
  }
123
118
 
124
119
  function collectImports(
125
120
  sourceFile: ts.SourceFile,
126
- program: ts.Program,
127
- workspaceRoot: string,
121
+ sourcePaths: Set<string>,
128
122
  ): { packageImports: PackageImport[]; localImports: LocalImport[] } {
129
123
  const packageImports: PackageImport[] = [];
130
124
  const localImports: LocalImport[] = [];
@@ -132,13 +126,10 @@ function collectImports(
132
126
 
133
127
  function recordPackageImport(
134
128
  specifier: string,
129
+ parsed: { packageName: string; subpath: string },
135
130
  span: { start: number; end: number },
136
131
  importKind: ImportKind,
137
132
  ): void {
138
- const parsed = parsePackageSpecifier(specifier);
139
- if (!parsed) {
140
- return;
141
- }
142
133
  packageImports.push({
143
134
  specifier,
144
135
  packageName: parsed.packageName,
@@ -155,13 +146,12 @@ function collectImports(
155
146
  const span = spanFromNode(node.moduleSpecifier, sourceFile);
156
147
  const parsed = parsePackageSpecifier(specifier);
157
148
  if (parsed) {
158
- recordPackageImport(specifier, span, "static");
149
+ recordPackageImport(specifier, parsed, span, "static");
159
150
  } else {
160
151
  const target = resolveLocalTarget(
161
152
  specifier,
162
153
  fromFile,
163
- program,
164
- workspaceRoot,
154
+ sourcePaths,
165
155
  );
166
156
  if (target) {
167
157
  localImports.push({
@@ -183,13 +173,12 @@ function collectImports(
183
173
  const span = spanFromNode(node.arguments[0], sourceFile);
184
174
  const parsed = parsePackageSpecifier(specifier);
185
175
  if (parsed) {
186
- recordPackageImport(specifier, span, "dynamic");
176
+ recordPackageImport(specifier, parsed, span, "dynamic");
187
177
  } else {
188
178
  const target = resolveLocalTarget(
189
179
  specifier,
190
180
  fromFile,
191
- program,
192
- workspaceRoot,
181
+ sourcePaths,
193
182
  );
194
183
  if (target) {
195
184
  localImports.push({
@@ -211,13 +200,12 @@ function collectImports(
211
200
  const span = spanFromNode(node.arguments[0], sourceFile);
212
201
  const parsed = parsePackageSpecifier(specifier);
213
202
  if (parsed) {
214
- recordPackageImport(specifier, span, "require");
203
+ recordPackageImport(specifier, parsed, span, "require");
215
204
  } else {
216
205
  const target = resolveLocalTarget(
217
206
  specifier,
218
207
  fromFile,
219
- program,
220
- workspaceRoot,
208
+ sourcePaths,
221
209
  );
222
210
  if (target) {
223
211
  localImports.push({
@@ -238,8 +226,9 @@ function collectImports(
238
226
  function sourcesUnchangedSincePrior(
239
227
  sources: SourceFile[],
240
228
  prior?: AppGraph,
229
+ canReusePrior = true,
241
230
  ): boolean {
242
- if (!prior) {
231
+ if (!prior || !canReusePrior) {
243
232
  return false;
244
233
  }
245
234
  const priorHashes = new Map(Object.entries(prior.sourceHashes ?? {}));
@@ -254,39 +243,46 @@ function sourcesUnchangedSincePrior(
254
243
  return true;
255
244
  }
256
245
 
246
+ function priorModuleNodesByFile(prior?: AppGraph): Map<string, ModuleNode> {
247
+ return new Map((prior?.moduleGraph.nodes ?? []).map((node) => [node.file, node]));
248
+ }
249
+
257
250
  export function buildModuleGraph(
258
251
  sources: SourceFile[],
259
252
  rawSymbols: RawSymbol[],
260
- workspaceRoot: string,
261
- tsconfigPath?: string,
262
253
  prior?: AppGraph,
254
+ canReusePrior = true,
263
255
  ): ModuleGraph {
264
- if (sourcesUnchangedSincePrior(sources, prior)) {
256
+ if (sourcesUnchangedSincePrior(sources, prior, canReusePrior)) {
265
257
  return prior!.moduleGraph;
266
258
  }
267
259
 
268
- const parsedConfig = loadTsconfig(workspaceRoot, tsconfigPath);
269
- const fileNames = sources.map((source) =>
270
- path.resolve(workspaceRoot, source.path).replace(/\\/g, "/"),
271
- );
272
-
273
- const program = ts.createProgram(fileNames, {
274
- ...parsedConfig.options,
275
- noEmit: true,
276
- skipLibCheck: true,
277
- });
260
+ const priorHashes = new Map(Object.entries(prior?.sourceHashes ?? {}));
261
+ const priorNodes = priorModuleNodesByFile(prior);
262
+ const contextsByFile = buildDeclaredContextsByFile(rawSymbols);
263
+ const sourcePaths = new Set(sources.map((source) => normalizePath(source.path)));
278
264
 
279
265
  const nodes: ModuleNode[] = [];
280
266
 
281
267
  for (const source of sources) {
282
268
  const normalizedFile = normalizePath(source.path);
283
- const absolutePath = fileNames.find(
284
- (name) => normalizePath(name).endsWith(normalizedFile),
285
- );
269
+ const priorNode = priorNodes.get(normalizedFile);
270
+ if (
271
+ canReusePrior &&
272
+ priorNode &&
273
+ priorHashes.get(normalizedFile) === source.contentHash
274
+ ) {
275
+ nodes.push(priorNode);
276
+ continue;
277
+ }
286
278
 
287
- const sourceFile = absolutePath
288
- ? program.getSourceFile(absolutePath)
289
- : undefined;
279
+ const sourceFile = ts.createSourceFile(
280
+ normalizedFile,
281
+ source.text,
282
+ ts.ScriptTarget.Latest,
283
+ true,
284
+ normalizedFile.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS,
285
+ );
290
286
 
291
287
  if (!sourceFile) {
292
288
  nodes.push({
@@ -294,7 +290,7 @@ export function buildModuleGraph(
294
290
  file: normalizedFile,
295
291
  directPackageImports: [],
296
292
  localImports: [],
297
- declaredContexts: declaredContextsForFile(normalizedFile, rawSymbols),
293
+ declaredContexts: declaredContextsForFile(normalizedFile, contextsByFile),
298
294
  effectiveContexts: [],
299
295
  });
300
296
  continue;
@@ -302,8 +298,7 @@ export function buildModuleGraph(
302
298
 
303
299
  const { packageImports, localImports } = collectImports(
304
300
  sourceFile,
305
- program,
306
- workspaceRoot,
301
+ sourcePaths,
307
302
  );
308
303
 
309
304
  nodes.push({
@@ -311,7 +306,7 @@ export function buildModuleGraph(
311
306
  file: normalizedFile,
312
307
  directPackageImports: packageImports,
313
308
  localImports,
314
- declaredContexts: declaredContextsForFile(normalizedFile, rawSymbols),
309
+ declaredContexts: declaredContextsForFile(normalizedFile, contextsByFile),
315
310
  effectiveContexts: [],
316
311
  });
317
312
  }
@@ -32,31 +32,30 @@ function priorSymbolsToRaw(symbols: ForgeSymbol[]): RawSymbol[] {
32
32
  }));
33
33
  }
34
34
 
35
+ interface PriorSymbolsForFile {
36
+ contentHash?: string;
37
+ symbols: ForgeSymbol[];
38
+ }
39
+
35
40
  function groupPriorSymbolsByFile(
36
41
  priorSymbols: ForgeSymbol[],
37
- ): Map<string, ForgeSymbol[]> {
38
- const byFile = new Map<string, ForgeSymbol[]>();
42
+ ): Map<string, PriorSymbolsForFile> {
43
+ const byFile = new Map<string, PriorSymbolsForFile>();
39
44
  for (const symbol of priorSymbols) {
40
- const list = byFile.get(symbol.file) ?? [];
41
- list.push(symbol);
42
- byFile.set(symbol.file, list);
45
+ const existing = byFile.get(symbol.file);
46
+ if (existing) {
47
+ existing.symbols.push(symbol);
48
+ continue;
49
+ }
50
+ const fromMeta = symbol.meta.fileContentHash;
51
+ byFile.set(symbol.file, {
52
+ contentHash: typeof fromMeta === "string" ? fromMeta : undefined,
53
+ symbols: [symbol],
54
+ });
43
55
  }
44
56
  return byFile;
45
57
  }
46
58
 
47
- function priorFileContentHash(
48
- priorSymbols: ForgeSymbol[],
49
- file: string,
50
- ): string | undefined {
51
- const match = priorSymbols.find((symbol) => symbol.file === file);
52
- if (!match) {
53
- return undefined;
54
- }
55
- // All symbols from the same file share the same slice hash basis; use meta when present.
56
- const fromMeta = match.meta.fileContentHash;
57
- return typeof fromMeta === "string" ? fromMeta : undefined;
58
- }
59
-
60
59
  export interface IncrementalParseResult {
61
60
  symbols: RawSymbol[];
62
61
  diagnostics: Diagnostic[];
@@ -65,6 +64,7 @@ export interface IncrementalParseResult {
65
64
  export function incrementalParse(
66
65
  sources: SourceFile[],
67
66
  priorSymbols: ForgeSymbol[] | undefined,
67
+ priorSourceHashes: Record<string, string> | undefined,
68
68
  priorInvalidation: ParseInvalidationKey | undefined,
69
69
  currentInvalidation: ParseInvalidationKey,
70
70
  ): IncrementalParseResult {
@@ -76,22 +76,22 @@ export function incrementalParse(
76
76
 
77
77
  const priorByFile = priorSymbols
78
78
  ? groupPriorSymbolsByFile(priorSymbols)
79
- : new Map<string, ForgeSymbol[]>();
79
+ : new Map<string, PriorSymbolsForFile>();
80
80
 
81
81
  for (const source of sources) {
82
82
  const normalizedFile = normalizePath(source.path);
83
83
  const priorForFile = priorByFile.get(normalizedFile);
84
- const priorHash = priorSymbols
85
- ? priorFileContentHash(priorSymbols, normalizedFile)
86
- : undefined;
84
+ const priorHash = priorForFile?.contentHash ?? priorSourceHashes?.[normalizedFile];
87
85
 
88
86
  const fileUnchanged =
89
87
  !globalInvalidated &&
90
- priorForFile !== undefined &&
91
88
  priorHash === source.contentHash;
92
89
 
90
+ if (fileUnchanged && priorForFile) {
91
+ allSymbols.push(...priorSymbolsToRaw(priorForFile.symbols));
92
+ continue;
93
+ }
93
94
  if (fileUnchanged) {
94
- allSymbols.push(...priorSymbolsToRaw(priorForFile));
95
95
  continue;
96
96
  }
97
97
 
@@ -0,0 +1,26 @@
1
+ import type { AppGraph } from "../types/app-graph.ts";
2
+
3
+ export interface AppGraphPhaseTimings {
4
+ normalizeMs: number;
5
+ parseMs: number;
6
+ symbolsMs: number;
7
+ duplicatesMs: number;
8
+ moduleGraphMs: number;
9
+ inputHashMs: number;
10
+ totalMs: number;
11
+ }
12
+
13
+ const appGraphProfiles = new WeakMap<AppGraph, AppGraphPhaseTimings>();
14
+
15
+ export function recordAppGraphProfile(
16
+ graph: AppGraph,
17
+ timings: AppGraphPhaseTimings,
18
+ ): void {
19
+ appGraphProfiles.set(graph, timings);
20
+ }
21
+
22
+ export function getAppGraphProfile(
23
+ graph: AppGraph,
24
+ ): AppGraphPhaseTimings | undefined {
25
+ return appGraphProfiles.get(graph);
26
+ }
@@ -8,7 +8,7 @@ export const APP_GRAPH_ANALYZER_VERSION = "0.1.0";
8
8
  export const TREE_SITTER_GRAMMAR_VERSION = "0.23.2";
9
9
 
10
10
  /** Forge builder API → ForgeKind classifier version. */
11
- export const FORGE_CLASSIFIER_VERSION = "0.1.1";
11
+ export const FORGE_CLASSIFIER_VERSION = "0.1.3";
12
12
 
13
13
  /** Generation orchestrator version (recorded on emitted AppGraph). */
14
14
  export { GENERATOR_VERSION } from "../../version.ts";
@@ -2,17 +2,18 @@ import type { CapabilitySet } from "../types/capability.ts";
2
2
  import type { IntegrationRecipe } from "../types/integration.ts";
3
3
  import type { PackageApi } from "../types/package-graph.ts";
4
4
  import { capability, emptyCapabilitySet } from "../recipes/helpers.ts";
5
- import { gatherSignals } from "./signals.ts";
5
+ import { gatherSignals, type PackageSignals } from "./signals.ts";
6
6
 
7
7
  export function detectCapabilities(
8
8
  api: PackageApi,
9
9
  recipe?: IntegrationRecipe,
10
+ precomputedSignals?: PackageSignals,
10
11
  ): CapabilitySet {
11
12
  if (recipe) {
12
13
  return cloneCapabilitySet(recipe.capabilities);
13
14
  }
14
15
 
15
- const signals = gatherSignals(api);
16
+ const signals = precomputedSignals ?? gatherSignals(api);
16
17
  const caps = emptyCapabilitySet();
17
18
 
18
19
  if (signals.usesNetwork) {
@@ -8,7 +8,7 @@ import { resolveByPackageName } from "../recipes/registry.ts";
8
8
  import { detectCapabilities } from "./capabilities.ts";
9
9
  import { partitionContexts } from "./contexts.ts";
10
10
  import { detectSecrets } from "./secrets.ts";
11
- import { gatherSignals } from "./signals.ts";
11
+ import { gatherSignals, type PackageSignals } from "./signals.ts";
12
12
 
13
13
  export interface RuntimeClassifier {
14
14
  classify(api: PackageApi, recipe?: IntegrationRecipe): RuntimeClassification;
@@ -30,8 +30,8 @@ function classifyExport(
30
30
  recipe: IntegrationRecipe | undefined,
31
31
  caps: CapabilitySet,
32
32
  alias: string,
33
+ signals: PackageSignals,
33
34
  ): ExportClassification {
34
- const signals = gatherSignals(api);
35
35
  const { compatible, incompatible } = partitionContexts(
36
36
  recipe,
37
37
  caps,
@@ -55,12 +55,12 @@ export function classify(
55
55
  recipe?: IntegrationRecipe,
56
56
  ): RuntimeClassification {
57
57
  const resolvedRecipe = resolveRecipeForApi(api, recipe);
58
- const caps = detectCapabilities(api, resolvedRecipe);
58
+ const signals = gatherSignals(api);
59
+ const caps = detectCapabilities(api, resolvedRecipe, signals);
59
60
  const capsWithSecrets: CapabilitySet = {
60
61
  ...caps,
61
- secrets: detectSecrets(api, resolvedRecipe),
62
+ secrets: detectSecrets(api, resolvedRecipe, signals),
62
63
  };
63
- const signals = gatherSignals(api);
64
64
  const alias = resolvedRecipe?.alias ?? api.name;
65
65
 
66
66
  const { compatible, incompatible, rationale } = partitionContexts(
@@ -74,19 +74,43 @@ export function classify(
74
74
  for (const ep of api.entrypoints) {
75
75
  for (const exp of ep.exports) {
76
76
  perEntrypoint.push(
77
- classifyExport(api, ep.subpath, exp.name, resolvedRecipe, capsWithSecrets, alias),
77
+ classifyExport(
78
+ api,
79
+ ep.subpath,
80
+ exp.name,
81
+ resolvedRecipe,
82
+ capsWithSecrets,
83
+ alias,
84
+ signals,
85
+ ),
78
86
  );
79
87
  }
80
88
  if (ep.exports.length === 0) {
81
89
  perEntrypoint.push(
82
- classifyExport(api, ep.subpath, "*", resolvedRecipe, capsWithSecrets, alias),
90
+ classifyExport(
91
+ api,
92
+ ep.subpath,
93
+ "*",
94
+ resolvedRecipe,
95
+ capsWithSecrets,
96
+ alias,
97
+ signals,
98
+ ),
83
99
  );
84
100
  }
85
101
  }
86
102
 
87
103
  if (api.entrypoints.length === 0) {
88
104
  perEntrypoint.push(
89
- classifyExport(api, ".", "*", resolvedRecipe, capsWithSecrets, alias),
105
+ classifyExport(
106
+ api,
107
+ ".",
108
+ "*",
109
+ resolvedRecipe,
110
+ capsWithSecrets,
111
+ alias,
112
+ signals,
113
+ ),
90
114
  );
91
115
  }
92
116
 
@@ -2,11 +2,12 @@ import type { SecretRequirement } from "../types/capability.ts";
2
2
  import type { IntegrationRecipe } from "../types/integration.ts";
3
3
  import type { PackageApi } from "../types/package-graph.ts";
4
4
  import { secret } from "../recipes/helpers.ts";
5
- import { gatherSignals } from "./signals.ts";
5
+ import { gatherSignals, type PackageSignals } from "./signals.ts";
6
6
 
7
7
  export function detectSecrets(
8
8
  api: PackageApi,
9
9
  recipe?: IntegrationRecipe,
10
+ precomputedSignals?: PackageSignals,
10
11
  ): SecretRequirement[] {
11
12
  const found = new Map<string, SecretRequirement>();
12
13
 
@@ -16,7 +17,7 @@ export function detectSecrets(
16
17
  }
17
18
  }
18
19
 
19
- const signals = gatherSignals(api);
20
+ const signals = precomputedSignals ?? gatherSignals(api);
20
21
  for (const evidence of signals.envSecretEvidence) {
21
22
  const envVar = evidence.replace(/^env:/, "");
22
23
  if (!found.has(envVar)) {
@@ -15,6 +15,64 @@ export interface PackageSignals {
15
15
  nativeAddonEvidence: string[];
16
16
  }
17
17
 
18
+ export interface SignalProfile {
19
+ calls: number;
20
+ totalMs: number;
21
+ entrypoints: number;
22
+ exports: number;
23
+ textFragments: number;
24
+ corpusBytes: number;
25
+ packageCount: number;
26
+ topPackages: SignalPackageProfile[];
27
+ }
28
+
29
+ export interface SignalPackageProfile {
30
+ packageName: string;
31
+ calls: number;
32
+ totalMs: number;
33
+ entrypoints: number;
34
+ exports: number;
35
+ textFragments: number;
36
+ corpusBytes: number;
37
+ }
38
+
39
+ let activeProfile: SignalProfile | undefined;
40
+ let activePackageProfiles: Map<string, SignalPackageProfile> | undefined;
41
+
42
+ export function resetSignalProfile(): void {
43
+ activeProfile = {
44
+ calls: 0,
45
+ totalMs: 0,
46
+ entrypoints: 0,
47
+ exports: 0,
48
+ textFragments: 0,
49
+ corpusBytes: 0,
50
+ packageCount: 0,
51
+ topPackages: [],
52
+ };
53
+ activePackageProfiles = new Map();
54
+ }
55
+
56
+ export function getSignalProfile(): SignalProfile | undefined {
57
+ if (!activeProfile) {
58
+ return undefined;
59
+ }
60
+ const topPackages = [...(activePackageProfiles?.values() ?? [])]
61
+ .sort((a, b) => b.totalMs - a.totalMs)
62
+ .slice(0, 10)
63
+ .map((entry) => ({ ...entry }));
64
+ return {
65
+ ...activeProfile,
66
+ packageCount: activePackageProfiles?.size ?? 0,
67
+ topPackages,
68
+ };
69
+ }
70
+
71
+ export function clearSignalProfile(): void {
72
+ activeProfile = undefined;
73
+ activePackageProfiles = undefined;
74
+ }
75
+
18
76
  const NODE_BUILTIN_PATTERNS = [
19
77
  /\bnode:/,
20
78
  /\brequire\s*\(\s*["'](?:fs|child_process|net|http|https|dns|tls|os|crypto)["']/,
@@ -89,9 +147,12 @@ function collectEnvVars(text: string): string[] {
89
147
  }
90
148
 
91
149
  export function gatherSignals(api: PackageApi): PackageSignals {
150
+ const started = activeProfile ? performance.now() : 0;
92
151
  const texts: string[] = [];
152
+ let exportCount = 0;
93
153
  for (const ep of api.entrypoints) {
94
154
  for (const exp of ep.exports) {
155
+ exportCount += 1;
95
156
  texts.push(exp.signature);
96
157
  if (exp.overloads) texts.push(...exp.overloads);
97
158
  if (exp.declarations) texts.push(...exp.declarations);
@@ -112,7 +173,7 @@ export function gatherSignals(api: PackageApi): PackageSignals {
112
173
  const nativeAddonEvidence = collectMatches(corpus, NATIVE_ADDON_PATTERNS);
113
174
  const envVars = collectEnvVars(corpus);
114
175
 
115
- return {
176
+ const result = {
116
177
  usesNodeBuiltins: nodeBuiltins.length > 0,
117
178
  nodeBuiltins,
118
179
  usesNetwork: networkEvidence.length > 0,
@@ -126,4 +187,33 @@ export function gatherSignals(api: PackageApi): PackageSignals {
126
187
  usesNativeAddon: nativeAddonEvidence.length > 0,
127
188
  nativeAddonEvidence,
128
189
  };
190
+
191
+ if (activeProfile) {
192
+ const durationMs = performance.now() - started;
193
+ activeProfile.calls += 1;
194
+ activeProfile.totalMs += durationMs;
195
+ activeProfile.entrypoints += api.entrypoints.length;
196
+ activeProfile.exports += exportCount;
197
+ activeProfile.textFragments += texts.length;
198
+ activeProfile.corpusBytes += corpus.length;
199
+
200
+ const packageProfile = activePackageProfiles?.get(api.name) ?? {
201
+ packageName: api.name,
202
+ calls: 0,
203
+ totalMs: 0,
204
+ entrypoints: 0,
205
+ exports: 0,
206
+ textFragments: 0,
207
+ corpusBytes: 0,
208
+ };
209
+ packageProfile.calls += 1;
210
+ packageProfile.totalMs += durationMs;
211
+ packageProfile.entrypoints += api.entrypoints.length;
212
+ packageProfile.exports += exportCount;
213
+ packageProfile.textFragments += texts.length;
214
+ packageProfile.corpusBytes += corpus.length;
215
+ activePackageProfiles?.set(api.name, packageProfile);
216
+ }
217
+
218
+ return result;
129
219
  }