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
@@ -5,6 +5,12 @@ import {
5
5
  import type { GenerateOptions, GenerateResult } from "../types/cli.ts";
6
6
  import type { Diagnostic } from "../types/diagnostic.ts";
7
7
  import { classify } from "../classifier/classify.ts";
8
+ import { getAppGraphProfile } from "../app-graph/profile.ts";
9
+ import {
10
+ clearSignalProfile,
11
+ getSignalProfile,
12
+ resetSignalProfile,
13
+ } from "../classifier/signals.ts";
8
14
  import type { ClassifiedPackage } from "../classifier/runtime-matrix.ts";
9
15
  import { buildRuntimeMatrix } from "../classifier/runtime-matrix.ts";
10
16
  import { emit } from "../emitter/emit.ts";
@@ -25,8 +31,10 @@ import {
25
31
  formatCompileTimings,
26
32
  isCompileProfileEnabled,
27
33
  recordCompileTimings,
34
+ shouldPrintCompileProfile,
28
35
  } from "./profile.ts";
29
36
  import { plan } from "./plan.ts";
37
+ import { getPlanProfile } from "./plan-profile.ts";
30
38
  import {
31
39
  buildAppGraphForSession,
32
40
  discoverForSession,
@@ -100,6 +108,7 @@ export async function run(options: GenerateOptions): Promise<GenerateResult> {
100
108
  async function runUnlocked(options: GenerateOptions): Promise<GenerateResult> {
101
109
  const profileEnabled = isCompileProfileEnabled();
102
110
  const runStarted = profileEnabled ? performance.now() : 0;
111
+ let fastCheckMs = 0;
103
112
  let generateCheckCache: GenerateResult["cache"] =
104
113
  options.check && !options.dryRun
105
114
  ? {
@@ -110,7 +119,9 @@ async function runUnlocked(options: GenerateOptions): Promise<GenerateResult> {
110
119
  : undefined;
111
120
 
112
121
  if (options.check && !options.dryRun) {
122
+ const fastCheckStarted = profileEnabled ? performance.now() : 0;
113
123
  const fastCheck = runFastGenerateCheck(options.workspaceRoot);
124
+ fastCheckMs = profileEnabled ? performance.now() - fastCheckStarted : 0;
114
125
  if (fastCheck.kind === "hit") {
115
126
  return fastCheck.result;
116
127
  }
@@ -121,7 +132,9 @@ async function runUnlocked(options: GenerateOptions): Promise<GenerateResult> {
121
132
  };
122
133
  }
123
134
 
135
+ const sessionStarted = profileEnabled ? performance.now() : 0;
124
136
  const session = getCompileSession(options.workspaceRoot);
137
+ const sessionMs = profileEnabled ? performance.now() - sessionStarted : 0;
125
138
 
126
139
  const discoverStarted = profileEnabled ? performance.now() : 0;
127
140
  const ctx = discoverForSession(session);
@@ -130,20 +143,40 @@ async function runUnlocked(options: GenerateOptions): Promise<GenerateResult> {
130
143
 
131
144
  const pkgCompiler = new PackageGraphCompiler();
132
145
 
133
- const graphStarted = profileEnabled ? performance.now() : 0;
134
- const [appGraph, pkgResult] = await Promise.all([
135
- buildAppGraphForSession(session),
136
- pkgCompiler.build(ctx.dependencies, {
146
+ let appGraphMs = 0;
147
+ let packageGraphMs = 0;
148
+ const graphBuildStarted = profileEnabled ? performance.now() : 0;
149
+ const appGraphPromise = (async () => {
150
+ const started = profileEnabled ? performance.now() : 0;
151
+ const graph = await buildAppGraphForSession(session);
152
+ appGraphMs = profileEnabled ? performance.now() - started : 0;
153
+ return graph;
154
+ })();
155
+ const packageGraphPromise = (async () => {
156
+ const started = profileEnabled ? performance.now() : 0;
157
+ const result = await pkgCompiler.build(ctx.dependencies, {
137
158
  runtimeInspect: false,
138
159
  resolutionMode: "nodenext",
139
160
  cacheDir: ctx.cacheDir,
140
161
  concurrency: options.concurrency,
141
162
  lockfileHash: ctx.lockfileHash,
142
- }),
143
- ]);
144
- const graphMs = profileEnabled ? performance.now() - graphStarted : 0;
163
+ });
164
+ packageGraphMs = profileEnabled ? performance.now() - started : 0;
165
+ return result;
166
+ })();
167
+ const [appGraph, pkgResult] = await Promise.all([appGraphPromise, packageGraphPromise]);
168
+ const graphBuildMs = profileEnabled ? performance.now() - graphBuildStarted : 0;
145
169
 
170
+ const classifyStarted = profileEnabled ? performance.now() : 0;
171
+ if (profileEnabled) {
172
+ resetSignalProfile();
173
+ }
146
174
  const classified = classifyPackages(pkgResult.graph);
175
+ const classifierSignals = profileEnabled ? getSignalProfile() : undefined;
176
+ if (profileEnabled) {
177
+ clearSignalProfile();
178
+ }
179
+ const classifyMs = profileEnabled ? performance.now() - classifyStarted : 0;
147
180
 
148
181
  const planStarted = profileEnabled ? performance.now() : 0;
149
182
  const emitPlan = plan({
@@ -160,8 +193,13 @@ async function runUnlocked(options: GenerateOptions): Promise<GenerateResult> {
160
193
  ? "dry-run"
161
194
  : "write";
162
195
 
196
+ const runtimeMatrixStarted = profileEnabled ? performance.now() : 0;
163
197
  const matrix = buildRuntimeMatrix(classified);
198
+ const runtimeMatrixMs = profileEnabled ? performance.now() - runtimeMatrixStarted : 0;
199
+ const importGuardsStarted = profileEnabled ? performance.now() : 0;
164
200
  const guardDiagnostics = checkImportGuards(appGraph.moduleGraph, matrix);
201
+ const importGuardsMs = profileEnabled ? performance.now() - importGuardsStarted : 0;
202
+ const qualityGateStarted = profileEnabled ? performance.now() : 0;
165
203
  // Import guards fail `forge check`; generate/drift only surface them as warnings.
166
204
  const guardDiagnosticsForGate =
167
205
  mode === "check"
@@ -176,6 +214,7 @@ async function runUnlocked(options: GenerateOptions): Promise<GenerateResult> {
176
214
  pkgResult.diagnostics,
177
215
  [...guardDiagnosticsForGate, ...(emitPlan.diagnostics ?? [])],
178
216
  );
217
+ const qualityGateMs = profileEnabled ? performance.now() - qualityGateStarted : 0;
179
218
 
180
219
  const emitStarted = profileEnabled ? performance.now() : 0;
181
220
  const emitResult = await emit(emitPlan, {
@@ -184,6 +223,7 @@ async function runUnlocked(options: GenerateOptions): Promise<GenerateResult> {
184
223
  });
185
224
  const emitMs = profileEnabled ? performance.now() - emitStarted : 0;
186
225
 
226
+ const postEmitStarted = profileEnabled ? performance.now() : 0;
187
227
  const warnings: Diagnostic[] = [
188
228
  ...qualityDiagnostics.filter((d) => d.severity === "warning"),
189
229
  ...emitResult.warnings,
@@ -214,30 +254,6 @@ async function runUnlocked(options: GenerateOptions): Promise<GenerateResult> {
214
254
  }
215
255
  }
216
256
 
217
- if (profileEnabled) {
218
- const totalMs = performance.now() - runStarted;
219
- recordCompileTimings({
220
- discoverMs,
221
- appGraphMs: graphMs,
222
- packageGraphMs: 0,
223
- planMs,
224
- emitMs,
225
- totalMs,
226
- });
227
- const fsProfile = getFileSystemProfile();
228
- process.stderr.write(`${formatCompileTimings({
229
- discoverMs,
230
- appGraphMs: graphMs,
231
- packageGraphMs: 0,
232
- planMs,
233
- emitMs,
234
- totalMs,
235
- })}\n`);
236
- if (fsProfile) {
237
- process.stderr.write(`${formatFileSystemProfile(fsProfile)}\n`);
238
- }
239
- }
240
-
241
257
  const driftFailure =
242
258
  options.check &&
243
259
  (emitResult.changed.length > 0 ||
@@ -257,6 +273,56 @@ async function runUnlocked(options: GenerateOptions): Promise<GenerateResult> {
257
273
  const unchanged = emitResult.unchanged.filter((path) =>
258
274
  plannedPaths.has(path),
259
275
  );
276
+ const postEmitMs = profileEnabled ? performance.now() - postEmitStarted : 0;
277
+
278
+ if (profileEnabled) {
279
+ const totalMs = performance.now() - runStarted;
280
+ const appGraphProfile = getAppGraphProfile(appGraph);
281
+ const planProfile = getPlanProfile(emitPlan);
282
+ const unaccountedMs = Math.max(
283
+ 0,
284
+ totalMs -
285
+ fastCheckMs -
286
+ sessionMs -
287
+ discoverMs -
288
+ graphBuildMs -
289
+ classifyMs -
290
+ planMs -
291
+ runtimeMatrixMs -
292
+ importGuardsMs -
293
+ qualityGateMs -
294
+ emitMs -
295
+ postEmitMs,
296
+ );
297
+ const timings = {
298
+ fastCheckMs,
299
+ sessionMs,
300
+ discoverMs,
301
+ graphBuildMs,
302
+ appGraphMs,
303
+ ...(appGraphProfile ? { appGraph: appGraphProfile } : {}),
304
+ packageGraphMs,
305
+ classifyMs,
306
+ ...(classifierSignals ? { classifierSignals } : {}),
307
+ planMs,
308
+ ...(planProfile ? { planDetail: planProfile } : {}),
309
+ runtimeMatrixMs,
310
+ importGuardsMs,
311
+ qualityGateMs,
312
+ emitMs,
313
+ postEmitMs,
314
+ unaccountedMs,
315
+ totalMs,
316
+ };
317
+ recordCompileTimings(timings);
318
+ const fsProfile = getFileSystemProfile();
319
+ if (shouldPrintCompileProfile()) {
320
+ process.stderr.write(`${formatCompileTimings(timings)}\n`);
321
+ if (fsProfile) {
322
+ process.stderr.write(`${formatFileSystemProfile(fsProfile)}\n`);
323
+ }
324
+ }
325
+ }
260
326
 
261
327
  return {
262
328
  changed,
@@ -86,6 +86,14 @@ function moduleGraphForAppGraphSnapshot(graph: AppGraph): AppGraph["moduleGraph"
86
86
  };
87
87
  }
88
88
 
89
+ export function serializeConstFromJson(
90
+ exportName: string,
91
+ serializedJson: string,
92
+ ): string {
93
+ const parsed: unknown = JSON.parse(serializedJson.trimEnd());
94
+ return `export const ${exportName} = ${JSON.stringify(parsed, null, 2)} as const;\n`;
95
+ }
96
+
89
97
  export function serializeAppGraphJson(graph: AppGraph): string {
90
98
  const payload = {
91
99
  schemaVersion: graph.schemaVersion,
@@ -100,26 +108,35 @@ export function serializeAppGraphJson(graph: AppGraph): string {
100
108
  }
101
109
 
102
110
  export function serializeAppGraphTs(graph: AppGraph): string {
103
- const parsed: unknown = JSON.parse(serializeAppGraphJson(graph).trimEnd());
104
- return `export const appGraph = ${JSON.stringify(parsed, null, 2)} as const;\n`;
111
+ return serializeConstFromJson("appGraph", serializeAppGraphJson(graph));
105
112
  }
106
113
 
107
114
  export function serializePackageGraphJson(graph: PackageGraph): string {
108
115
  return serializeCanonical(graph);
109
116
  }
110
117
 
111
- export function serializePackageGraphTs(graph: PackageGraph): string {
112
- const parsed: unknown = JSON.parse(serializePackageGraphJson(graph).trimEnd());
113
- return `export const packageGraph = ${JSON.stringify(parsed, null, 2)} as const;\n`;
118
+ export function serializePackageGraphTs(_graph: PackageGraph): string {
119
+ return [
120
+ "import packageGraphJson from \"./packageGraph.json\" with { type: \"json\" };",
121
+ "",
122
+ "export type PackageGraph = typeof packageGraphJson;",
123
+ "export const packageGraph = packageGraphJson;",
124
+ "",
125
+ ].join("\n");
114
126
  }
115
127
 
116
128
  export function serializeRuntimeMatrixJson(matrix: RuntimeMatrix): string {
117
129
  return serializeCanonical(matrix);
118
130
  }
119
131
 
120
- export function serializeRuntimeMatrixTs(matrix: RuntimeMatrix): string {
121
- const parsed: unknown = JSON.parse(serializeRuntimeMatrixJson(matrix).trimEnd());
122
- return `export const runtimeMatrix = ${JSON.stringify(parsed, null, 2)} as const;\n`;
132
+ export function serializeRuntimeMatrixTs(_matrix: RuntimeMatrix): string {
133
+ return [
134
+ "import runtimeMatrixJson from \"./runtimeMatrix.json\" with { type: \"json\" };",
135
+ "",
136
+ "export type RuntimeMatrix = typeof runtimeMatrixJson;",
137
+ "export const runtimeMatrix = runtimeMatrixJson;",
138
+ "",
139
+ ].join("\n");
123
140
  }
124
141
 
125
142
  export function serializeImportGuardsJson(
@@ -890,6 +907,7 @@ export function serializeSubscriptionManifestTs(
890
907
  }
891
908
 
892
909
  export function serializeApiJson(surface: ApiSurface): string {
910
+ const external = surface.external ?? { services: {}, commands: {}, queries: {} };
893
911
  return serializeCanonical({
894
912
  schemaVersion: surface.schemaVersion,
895
913
  generatorVersion: surface.generatorVersion,
@@ -899,6 +917,7 @@ export function serializeApiJson(surface: ApiSurface): string {
899
917
  liveQueries: surface.liveQueries,
900
918
  actions: surface.actions,
901
919
  workflows: surface.workflows,
920
+ external,
902
921
  });
903
922
  }
904
923
 
@@ -933,6 +952,12 @@ export function serializeReactManifestJson(
933
952
  return serializeCanonical(manifest);
934
953
  }
935
954
 
955
+ export function serializeVueManifestJson(
956
+ manifest: import("../client-sdk/build-manifest.ts").VueManifest,
957
+ ): string {
958
+ return serializeCanonical(manifest);
959
+ }
960
+
936
961
  export function serializeTestGraphJson(graph: TestGraph): string {
937
962
  return serializeCanonical(graph);
938
963
  }
@@ -3,7 +3,7 @@ import type { Dependency } from "../types/package-graph.ts";
3
3
  import type { PackageManager } from "../types/runtime.ts";
4
4
  import type { SourceFileIndex } from "./workspace-index.ts";
5
5
 
6
- export const ORCHESTRATOR_MANIFEST_VERSION = "1";
6
+ export const ORCHESTRATOR_MANIFEST_VERSION = "2";
7
7
 
8
8
  export interface DiscoverContext {
9
9
  workspaceRoot: string;
@@ -271,6 +271,7 @@ export class PackageGraphCompiler {
271
271
 
272
272
  const partialApi = {
273
273
  name: dep.name,
274
+ ...(packageJson.name && packageJson.name !== dep.name ? { packageName: packageJson.name } : {}),
274
275
  version: dep.version,
275
276
  packageManager: dep.packageManager,
276
277
  resolutionMode: opts.resolutionMode,
@@ -454,10 +455,11 @@ function portableDtsPath(dtsPath: string, dep: Pick<Dependency, "installPath" |
454
455
  }
455
456
 
456
457
  function readPackageJson(installPath: string): {
458
+ name?: string;
457
459
  exports?: unknown;
458
460
  } {
459
461
  const raw = readTextFile(join(installPath, "package.json"));
460
- return JSON.parse(raw) as { exports?: unknown };
462
+ return JSON.parse(raw) as { name?: string; exports?: unknown };
461
463
  }
462
464
 
463
465
  function resolveSandboxBackend(
@@ -1,4 +1,4 @@
1
1
  export const PACKAGE_GRAPH_SCHEMA_VERSION = "1.0.0";
2
- export const PACKAGE_ANALYZER_VERSION = "0.2.0";
2
+ export const PACKAGE_ANALYZER_VERSION = "0.2.1";
3
3
  export { GENERATOR_VERSION } from "../../version.ts";
4
4
  export const DEFAULT_PATTERN_EXPANSION_LIMIT = 50;
@@ -83,7 +83,10 @@ async function runInstall(
83
83
  executor: CommandExecutor,
84
84
  ): Promise<PmAddResult> {
85
85
  const ignoreScripts = opts.ignoreScripts ?? true;
86
- const argv = buildAddCommand(pm, spec, { ignoreScripts });
86
+ const argv = buildAddCommand(pm, spec, {
87
+ ignoreScripts,
88
+ workspace: opts.workspace,
89
+ });
87
90
  const lockBefore = hashLockfiles(opts.cwd, pm);
88
91
 
89
92
  const result = await executor.run(argv, { cwd: opts.cwd });
@@ -2,6 +2,7 @@ import type { PackageManager } from "../types/runtime.ts";
2
2
 
3
3
  export interface BuildAddCommandOptions {
4
4
  ignoreScripts: boolean;
5
+ workspace?: string;
5
6
  }
6
7
 
7
8
  /**
@@ -27,6 +28,9 @@ export function buildAddCommand(
27
28
  if (ignoreScripts) {
28
29
  args.push("--ignore-scripts");
29
30
  }
31
+ if (options.workspace) {
32
+ args.push("--workspace", options.workspace);
33
+ }
30
34
  return args;
31
35
  }
32
36
  case "pnpm": {
@@ -88,11 +88,40 @@ export class PackageManagerCommandError extends Error {
88
88
  }
89
89
  }
90
90
 
91
+ function quoteWindowsShellArg(arg: string): string {
92
+ if (/^[a-zA-Z0-9@._/:=-]+$/.test(arg)) {
93
+ return arg;
94
+ }
95
+ return `"${arg.replace(/(["^&|<>])/g, "^$1")}"`;
96
+ }
97
+
98
+ function spawnArgvForWindowsScript(originalArgv: string[], resolvedArgv: string[]): string[] {
99
+ const originalCommand = originalArgv[0] ?? resolvedArgv[0]!;
100
+ const command =
101
+ originalCommand.includes("\\") ||
102
+ originalCommand.includes("/") ||
103
+ isAbsolute(originalCommand)
104
+ ? resolvedArgv[0]!
105
+ : originalCommand;
106
+ const commandPart = command === originalCommand ? command : quoteWindowsShellArg(command);
107
+ const args = originalArgv.slice(1).map(quoteWindowsShellArg).join(" ");
108
+ return [
109
+ process.env.ComSpec ?? "cmd.exe",
110
+ "/d",
111
+ "/c",
112
+ `${commandPart}${args ? ` ${args}` : ""}`,
113
+ ];
114
+ }
115
+
91
116
  export const defaultCommandExecutor: CommandExecutor = {
92
117
  async run(argv, options) {
93
118
  const resolvedArgv = resolvePackageManagerArgv(argv);
119
+ const spawnArgv =
120
+ process.platform === "win32" && /\.(?:cmd|bat)$/i.test(resolvedArgv[0] ?? "")
121
+ ? spawnArgvForWindowsScript(argv, resolvedArgv)
122
+ : resolvedArgv;
94
123
  return new Promise<CommandRunResult>((resolve, reject) => {
95
- const child = spawn(resolvedArgv[0]!, resolvedArgv.slice(1), {
124
+ const child = spawn(spawnArgv[0]!, spawnArgv.slice(1), {
96
125
  cwd: options.cwd,
97
126
  env: options.env ?? process.env,
98
127
  windowsHide: true,
@@ -1,23 +1,21 @@
1
- import { join } from "node:path";
1
+ import { dirname, join, parse } from "node:path";
2
2
  import { nodeFileSystem } from "../fs/index.ts";
3
3
  import { parsePackageName } from "./parse-spec.ts";
4
4
 
5
- export function readInstalledVersion(
6
- specOrName: string,
7
- cwd: string,
8
- ): string | null {
9
- const name = parsePackageName(specOrName);
10
- const segments = name.startsWith("@")
11
- ? name.split("/")
12
- : [name];
13
- const pkgJsonPath = join(cwd, "node_modules", ...segments, "package.json");
5
+ function packageJsonPath(cwd: string, packageName: string): string {
6
+ const segments = packageName.startsWith("@")
7
+ ? packageName.split("/")
8
+ : [packageName];
9
+ return join(cwd, "node_modules", ...segments, "package.json");
10
+ }
14
11
 
15
- if (!nodeFileSystem.exists(pkgJsonPath)) {
12
+ function readVersionAt(path: string): string | null {
13
+ if (!nodeFileSystem.exists(path)) {
16
14
  return null;
17
15
  }
18
16
 
19
17
  try {
20
- const pkg = JSON.parse((nodeFileSystem.readText(pkgJsonPath) ?? "")) as {
18
+ const pkg = JSON.parse((nodeFileSystem.readText(path) ?? "")) as {
21
19
  version?: string;
22
20
  };
23
21
  return typeof pkg.version === "string" ? pkg.version : null;
@@ -25,3 +23,29 @@ export function readInstalledVersion(
25
23
  return null;
26
24
  }
27
25
  }
26
+
27
+ export function readInstalledVersion(
28
+ specOrName: string,
29
+ cwd: string,
30
+ ): string | null {
31
+ const name = parsePackageName(specOrName);
32
+ let current = cwd;
33
+ const root = parse(cwd).root;
34
+
35
+ while (true) {
36
+ const version = readVersionAt(packageJsonPath(current, name));
37
+ if (version) {
38
+ return version;
39
+ }
40
+
41
+ if (current === root) {
42
+ return null;
43
+ }
44
+
45
+ const parent = dirname(current);
46
+ if (parent === current) {
47
+ return null;
48
+ }
49
+ current = parent;
50
+ }
51
+ }