forgeos 0.1.0-alpha.0 → 0.1.0-alpha.2

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 (283) hide show
  1. package/.npmignore +9 -1
  2. package/AGENTS.md +6 -1
  3. package/CHANGELOG.md +30 -0
  4. package/CONTRIBUTING.md +22 -1
  5. package/README.md +30 -3
  6. package/bin/forge.mjs +4 -3
  7. package/package.json +3 -1
  8. package/packages/eslint-plugin-forge/index.ts +15 -15
  9. package/packages/eslint-plugin-forge/package.json +10 -10
  10. package/packages/eslint-plugin-forge/src/check-source.ts +95 -95
  11. package/packages/eslint-plugin-forge/src/load-artifacts.ts +24 -24
  12. package/packages/eslint-plugin-forge/src/rule-no-forge-guard-violation.ts +93 -93
  13. package/src/forge/_generated/actionSubscriptions.json +2 -2
  14. package/src/forge/_generated/actionSubscriptions.ts +3 -3
  15. package/src/forge/_generated/agentAdapterManifest.json +2 -2
  16. package/src/forge/_generated/agentAdapterManifest.ts +3 -3
  17. package/src/forge/_generated/agentContract.json +2 -2
  18. package/src/forge/_generated/agentContract.ts +6786 -2
  19. package/src/forge/_generated/agentQuickstart.md +1 -1
  20. package/src/forge/_generated/aiContext.ts +1 -1
  21. package/src/forge/_generated/aiModels.json +1 -1
  22. package/src/forge/_generated/aiModels.ts +1 -1
  23. package/src/forge/_generated/aiProviders.json +1 -1
  24. package/src/forge/_generated/aiProviders.ts +1 -1
  25. package/src/forge/_generated/aiRegistry.json +2 -2
  26. package/src/forge/_generated/aiRegistry.ts +3 -3
  27. package/src/forge/_generated/api.json +2 -2
  28. package/src/forge/_generated/api.ts +1 -1
  29. package/src/forge/_generated/appGraph.json +2 -2
  30. package/src/forge/_generated/appGraph.ts +1297 -1141
  31. package/src/forge/_generated/appMap.md +1 -1
  32. package/src/forge/_generated/artifactManifest.json +2 -2
  33. package/src/forge/_generated/artifactManifest.ts +2 -2
  34. package/src/forge/_generated/authClaims.json +1 -1
  35. package/src/forge/_generated/authClaims.ts +1 -1
  36. package/src/forge/_generated/authConfig.json +1 -1
  37. package/src/forge/_generated/authConfig.ts +1 -1
  38. package/src/forge/_generated/authContext.ts +1 -1
  39. package/src/forge/_generated/authRegistry.json +1 -1
  40. package/src/forge/_generated/authRegistry.ts +1 -1
  41. package/src/forge/_generated/buildInfo.json +2 -2
  42. package/src/forge/_generated/buildInfo.ts +4 -4
  43. package/src/forge/_generated/capabilityMap.json +2 -2
  44. package/src/forge/_generated/capabilityMap.md +1 -1
  45. package/src/forge/_generated/capabilityMap.ts +2 -2
  46. package/src/forge/_generated/client.ts +1 -1
  47. package/src/forge/_generated/clientApi.ts +1 -1
  48. package/src/forge/_generated/clientManifest.json +2 -2
  49. package/src/forge/_generated/clientManifest.ts +3 -3
  50. package/src/forge/_generated/clientTypes.ts +1 -1
  51. package/src/forge/_generated/configRegistry.json +1 -1
  52. package/src/forge/_generated/configRegistry.ts +1 -1
  53. package/src/forge/_generated/dataGraph.json +2 -2
  54. package/src/forge/_generated/dataGraph.ts +3 -3
  55. package/src/forge/_generated/db.json +1 -1
  56. package/src/forge/_generated/db.ts +1 -1
  57. package/src/forge/_generated/dbSecurityManifest.json +1 -1
  58. package/src/forge/_generated/dbSecurityManifest.ts +1 -1
  59. package/src/forge/_generated/dbSessionContext.json +1 -1
  60. package/src/forge/_generated/dbSessionContext.ts +1 -1
  61. package/src/forge/_generated/deployManifest.json +2 -2
  62. package/src/forge/_generated/deployManifest.ts +7 -7
  63. package/src/forge/_generated/devManifest.json +2 -2
  64. package/src/forge/_generated/devManifest.ts +3 -3
  65. package/src/forge/_generated/envSchema.json +1 -1
  66. package/src/forge/_generated/envSchema.ts +1 -1
  67. package/src/forge/_generated/frontendGraph.json +1 -1
  68. package/src/forge/_generated/frontendGraph.ts +1 -1
  69. package/src/forge/_generated/importGuards.json +2 -2
  70. package/src/forge/_generated/importGuards.ts +35 -1
  71. package/src/forge/_generated/index.ts +1 -1
  72. package/src/forge/_generated/liveProductionManifest.json +1 -1
  73. package/src/forge/_generated/liveProductionManifest.ts +1 -1
  74. package/src/forge/_generated/liveProtocol.json +1 -1
  75. package/src/forge/_generated/liveProtocol.ts +1 -1
  76. package/src/forge/_generated/liveQueryRegistry.json +2 -2
  77. package/src/forge/_generated/liveQueryRegistry.ts +3 -3
  78. package/src/forge/_generated/liveTransportConfig.json +1 -1
  79. package/src/forge/_generated/liveTransportConfig.ts +1 -1
  80. package/src/forge/_generated/makeRegistry.json +2 -2
  81. package/src/forge/_generated/makeRegistry.ts +2 -2
  82. package/src/forge/_generated/makeTemplates.json +1 -1
  83. package/src/forge/_generated/makeTemplates.ts +1 -1
  84. package/src/forge/_generated/mockMap.json +1 -1
  85. package/src/forge/_generated/mockMap.ts +1 -1
  86. package/src/forge/_generated/operationPlaybooks.md +7 -5
  87. package/src/forge/_generated/packageGraph.json +2 -2
  88. package/src/forge/_generated/packageGraph.ts +90964 -14284
  89. package/src/forge/_generated/packageUpgradeRegistry.json +2 -2
  90. package/src/forge/_generated/packageUpgradeRegistry.ts +2 -2
  91. package/src/forge/_generated/permissionMatrix.json +2 -2
  92. package/src/forge/_generated/permissionMatrix.ts +3 -3
  93. package/src/forge/_generated/policyRegistry.json +2 -2
  94. package/src/forge/_generated/policyRegistry.ts +3 -3
  95. package/src/forge/_generated/queryRegistry.json +2 -2
  96. package/src/forge/_generated/queryRegistry.ts +3 -3
  97. package/src/forge/_generated/react.d.ts +1 -1
  98. package/src/forge/_generated/react.ts +1 -1
  99. package/src/forge/_generated/reactManifest.json +2 -2
  100. package/src/forge/_generated/reactManifest.ts +3 -3
  101. package/src/forge/_generated/releaseManifest.json +2 -2
  102. package/src/forge/_generated/releaseManifest.ts +3 -3
  103. package/src/forge/_generated/rlsPolicies.json +1 -1
  104. package/src/forge/_generated/rlsPolicies.sql +1 -1
  105. package/src/forge/_generated/rlsPolicies.ts +1 -1
  106. package/src/forge/_generated/runtimeGraph.json +2 -2
  107. package/src/forge/_generated/runtimeGraph.ts +3 -3
  108. package/src/forge/_generated/runtimeMatrix.json +2 -2
  109. package/src/forge/_generated/runtimeMatrix.ts +106177 -7917
  110. package/src/forge/_generated/runtimeRegistry.ts +1 -1
  111. package/src/forge/_generated/runtimeRules.md +1 -1
  112. package/src/forge/_generated/secretRegistry.json +1 -1
  113. package/src/forge/_generated/secretRegistry.ts +1 -1
  114. package/src/forge/_generated/secretsContext.ts +1 -1
  115. package/src/forge/_generated/serverApi.ts +1 -1
  116. package/src/forge/_generated/sourceMapManifest.json +2 -2
  117. package/src/forge/_generated/sourceMapManifest.ts +2 -2
  118. package/src/forge/_generated/sqlPlan.json +1 -1
  119. package/src/forge/_generated/sqlPlan.ts +1 -1
  120. package/src/forge/_generated/subscriptionManifest.json +2 -2
  121. package/src/forge/_generated/subscriptionManifest.ts +3 -3
  122. package/src/forge/_generated/symbolicationManifest.json +2 -2
  123. package/src/forge/_generated/symbolicationManifest.ts +2 -2
  124. package/src/forge/_generated/telemetryRegistry.json +2 -2
  125. package/src/forge/_generated/telemetryRegistry.ts +3 -3
  126. package/src/forge/_generated/telemetrySinks.json +2 -2
  127. package/src/forge/_generated/telemetrySinks.ts +2 -2
  128. package/src/forge/_generated/tenantScope.json +2 -2
  129. package/src/forge/_generated/tenantScope.ts +3 -3
  130. package/src/forge/_generated/testGraph.json +2 -2
  131. package/src/forge/_generated/testGraph.ts +129 -75
  132. package/src/forge/_generated/testPlanRegistry.json +2 -2
  133. package/src/forge/_generated/testPlanRegistry.ts +2 -2
  134. package/src/forge/_generated/uiRoutes.json +1 -1
  135. package/src/forge/_generated/uiRoutes.ts +1 -1
  136. package/src/forge/_generated/uiScenarios.json +1 -1
  137. package/src/forge/_generated/uiScenarios.ts +1 -1
  138. package/src/forge/_generated/uiTestManifest.json +2 -2
  139. package/src/forge/_generated/uiTestManifest.ts +2 -2
  140. package/src/forge/_generated/workflowRegistry.json +2 -2
  141. package/src/forge/_generated/workflowRegistry.ts +3 -3
  142. package/src/forge/_generated/workflowSubscriptions.json +2 -2
  143. package/src/forge/_generated/workflowSubscriptions.ts +3 -3
  144. package/src/forge/cli/commands.ts +861 -861
  145. package/src/forge/cli/deps.ts +178 -11
  146. package/src/forge/cli/dev.ts +32 -5
  147. package/src/forge/cli/index.ts +7 -7
  148. package/src/forge/cli/main.ts +54 -54
  149. package/src/forge/cli/new.ts +29 -1
  150. package/src/forge/cli/output.ts +97 -97
  151. package/src/forge/cli/parse.ts +679 -673
  152. package/src/forge/cli/version.ts +1 -1
  153. package/src/forge/compiler/agent-contract/build.ts +28 -0
  154. package/src/forge/compiler/agent-contract/types.ts +16 -0
  155. package/src/forge/compiler/app-graph/build.ts +112 -112
  156. package/src/forge/compiler/app-graph/classify.ts +10 -10
  157. package/src/forge/compiler/app-graph/dup-symbol.ts +29 -29
  158. package/src/forge/compiler/app-graph/extract.ts +123 -123
  159. package/src/forge/compiler/app-graph/forge-apis.ts +29 -29
  160. package/src/forge/compiler/app-graph/index.ts +11 -11
  161. package/src/forge/compiler/app-graph/module-graph.ts +316 -316
  162. package/src/forge/compiler/app-graph/parser.ts +119 -119
  163. package/src/forge/compiler/app-graph/symbols.ts +48 -48
  164. package/src/forge/compiler/app-graph/tsconfig-hash.ts +62 -62
  165. package/src/forge/compiler/app-graph/types.ts +43 -43
  166. package/src/forge/compiler/app-graph/versions.ts +14 -14
  167. package/src/forge/compiler/cache/index.ts +17 -17
  168. package/src/forge/compiler/cache/key.ts +46 -46
  169. package/src/forge/compiler/cache/scheduler.ts +72 -72
  170. package/src/forge/compiler/cache/store.ts +78 -78
  171. package/src/forge/compiler/classifier/capabilities.ts +78 -78
  172. package/src/forge/compiler/classifier/classify.ts +113 -113
  173. package/src/forge/compiler/classifier/contexts.ts +188 -188
  174. package/src/forge/compiler/classifier/index.ts +18 -18
  175. package/src/forge/compiler/classifier/runtime-matrix.ts +45 -45
  176. package/src/forge/compiler/classifier/secrets.ts +41 -41
  177. package/src/forge/compiler/classifier/signals.ts +129 -129
  178. package/src/forge/compiler/diagnostics/codes.ts +125 -120
  179. package/src/forge/compiler/diagnostics/create.ts +87 -87
  180. package/src/forge/compiler/diagnostics/index.ts +41 -41
  181. package/src/forge/compiler/emitter/artifact-kind.ts +14 -14
  182. package/src/forge/compiler/emitter/barrel.ts +38 -38
  183. package/src/forge/compiler/emitter/constants.ts +7 -7
  184. package/src/forge/compiler/emitter/emit.ts +234 -237
  185. package/src/forge/compiler/emitter/index.ts +24 -24
  186. package/src/forge/compiler/emitter/lock.ts +61 -61
  187. package/src/forge/compiler/emitter/render.ts +73 -73
  188. package/src/forge/compiler/guards/artifacts.ts +96 -96
  189. package/src/forge/compiler/guards/check-import-guards.ts +106 -106
  190. package/src/forge/compiler/guards/index.ts +11 -11
  191. package/src/forge/compiler/guards/propagate-contexts.ts +57 -57
  192. package/src/forge/compiler/index.ts +17 -17
  193. package/src/forge/compiler/integration/add.ts +493 -493
  194. package/src/forge/compiler/integration/index.ts +17 -17
  195. package/src/forge/compiler/integration/plan.ts +279 -279
  196. package/src/forge/compiler/integration/render.ts +189 -189
  197. package/src/forge/compiler/integration/snapshot.ts +52 -52
  198. package/src/forge/compiler/orchestrator/discover.ts +214 -214
  199. package/src/forge/compiler/orchestrator/guards.ts +5 -5
  200. package/src/forge/compiler/orchestrator/index.ts +27 -27
  201. package/src/forge/compiler/orchestrator/manifest.ts +69 -69
  202. package/src/forge/compiler/orchestrator/orphans.ts +51 -51
  203. package/src/forge/compiler/orchestrator/plan.ts +804 -804
  204. package/src/forge/compiler/orchestrator/run.ts +178 -178
  205. package/src/forge/compiler/orchestrator/serialize.ts +859 -859
  206. package/src/forge/compiler/orchestrator/types.ts +23 -23
  207. package/src/forge/compiler/orchestrator/verify.ts +35 -35
  208. package/src/forge/compiler/package-graph/capabilities-stub.ts +33 -33
  209. package/src/forge/compiler/package-graph/checksum.ts +107 -97
  210. package/src/forge/compiler/package-graph/compiler.ts +444 -363
  211. package/src/forge/compiler/package-graph/constants.ts +4 -4
  212. package/src/forge/compiler/package-graph/exports-discovery.ts +91 -84
  213. package/src/forge/compiler/package-graph/extract-dts.ts +32 -32
  214. package/src/forge/compiler/package-graph/index.ts +24 -24
  215. package/src/forge/compiler/package-graph/jsdoc.ts +50 -50
  216. package/src/forge/compiler/package-graph/oracle.ts +326 -0
  217. package/src/forge/compiler/package-graph/read-file.ts +21 -21
  218. package/src/forge/compiler/package-graph/resolve.ts +131 -127
  219. package/src/forge/compiler/package-manager/adapter.ts +232 -232
  220. package/src/forge/compiler/package-manager/commands.ts +47 -47
  221. package/src/forge/compiler/package-manager/detect.ts +65 -65
  222. package/src/forge/compiler/package-manager/executor.ts +29 -29
  223. package/src/forge/compiler/package-manager/index.ts +22 -22
  224. package/src/forge/compiler/package-manager/parse-spec.ts +16 -16
  225. package/src/forge/compiler/package-manager/version.ts +20 -20
  226. package/src/forge/compiler/primitives/compare.ts +26 -26
  227. package/src/forge/compiler/primitives/hash.ts +42 -33
  228. package/src/forge/compiler/primitives/header.ts +43 -43
  229. package/src/forge/compiler/primitives/index.ts +45 -45
  230. package/src/forge/compiler/primitives/paths.ts +24 -24
  231. package/src/forge/compiler/primitives/serialize.ts +66 -66
  232. package/src/forge/compiler/primitives/sort.ts +87 -87
  233. package/src/forge/compiler/recipes/definitions.ts +269 -269
  234. package/src/forge/compiler/recipes/helpers.ts +37 -37
  235. package/src/forge/compiler/recipes/index.ts +21 -21
  236. package/src/forge/compiler/recipes/registry.ts +87 -87
  237. package/src/forge/compiler/sandbox/artifact-sanitize.ts +26 -26
  238. package/src/forge/compiler/sandbox/backends/child.ts +123 -123
  239. package/src/forge/compiler/sandbox/backends/docker.ts +173 -173
  240. package/src/forge/compiler/sandbox/index.ts +51 -51
  241. package/src/forge/compiler/sandbox/inspect.ts +143 -143
  242. package/src/forge/compiler/sandbox/inspector-entry.ts +115 -115
  243. package/src/forge/compiler/sandbox/limits.ts +31 -31
  244. package/src/forge/compiler/sandbox/scrub-env.ts +60 -60
  245. package/src/forge/compiler/sandbox/secret-scan.ts +54 -54
  246. package/src/forge/compiler/sandbox/serialize.ts +106 -106
  247. package/src/forge/compiler/sandbox/types.ts +7 -7
  248. package/src/forge/compiler/types/app-graph.ts +71 -71
  249. package/src/forge/compiler/types/capability.ts +29 -29
  250. package/src/forge/compiler/types/classification.ts +9 -9
  251. package/src/forge/compiler/types/cli.ts +85 -85
  252. package/src/forge/compiler/types/diagnostic.ts +2 -2
  253. package/src/forge/compiler/types/emit.ts +25 -25
  254. package/src/forge/compiler/types/import-guards.ts +19 -19
  255. package/src/forge/compiler/types/index.ts +98 -98
  256. package/src/forge/compiler/types/integration.ts +25 -25
  257. package/src/forge/compiler/types/json.ts +3 -3
  258. package/src/forge/compiler/types/lock.ts +37 -37
  259. package/src/forge/compiler/types/package-graph.ts +122 -77
  260. package/src/forge/compiler/types/runtime-matrix.ts +16 -16
  261. package/src/forge/compiler/types/runtime.ts +30 -30
  262. package/src/forge/compiler/types/sandbox.ts +24 -24
  263. package/src/forge/dev/server.ts +16 -2
  264. package/src/forge/refactor/index.ts +10 -2
  265. package/src/forge/refactor/runtime-rename.ts +598 -0
  266. package/src/forge/runtime/executor.ts +3 -2
  267. package/src/forge/runtime/live/live-query-runner.ts +2 -1
  268. package/src/forge/runtime/outbox/process.ts +2 -1
  269. package/src/forge/runtime/query/run-query.ts +2 -1
  270. package/src/forge/runtime/runner/run-entry.ts +2 -1
  271. package/src/forge/runtime/telemetry/sinks/posthog.ts +4 -5
  272. package/src/forge/runtime/telemetry/sinks/sentry.ts +4 -5
  273. package/src/forge/runtime/workflows/resolve-step.ts +2 -1
  274. package/src/forge/version.ts +3 -0
  275. package/templates/b2b-support-web/src/actions/captureTicketCreated.ts +7 -2
  276. package/templates/b2b-support-web/src/commands/closeTicket.ts +6 -1
  277. package/templates/b2b-support-web/src/commands/createTicket.ts +8 -2
  278. package/templates/b2b-support-web/src/queries/getTicket.ts +8 -1
  279. package/templates/b2b-support-web/web/components/CreateTicketForm.tsx +1 -2
  280. package/templates/b2b-support-web/web/components/PolicyDeniedDemo.tsx +1 -2
  281. package/templates/b2b-support-web/web/components/TicketList.tsx +1 -2
  282. package/templates/b2b-support-web/web/components/TraceDetails.tsx +1 -1
  283. package/templates/b2b-support-web/web/lib/forge.ts +1 -0
@@ -0,0 +1,598 @@
1
+ import ts from "typescript";
2
+ import { createDiagnostic } from "../compiler/diagnostics/create.ts";
3
+ import type { Diagnostic } from "../compiler/types/diagnostic.ts";
4
+ import type { PlannedFile, PlannedPatch } from "../make/types.ts";
5
+ import type { RefactorIntent } from "./types.ts";
6
+ import { isGenerated, makeFile, makePatchFromContent, patchFile, readText, walkFiles } from "./workspace-fs.ts";
7
+
8
+ export type RenameRuntimeEntryIntent = Extract<RefactorIntent, { kind: "renameRuntimeEntry" }>;
9
+
10
+ function diagnostic(
11
+ severity: Diagnostic["severity"],
12
+ code: string,
13
+ message: string,
14
+ file?: string,
15
+ ): Diagnostic {
16
+ return createDiagnostic({
17
+ severity,
18
+ code,
19
+ message,
20
+ ...(file ? { file } : {}),
21
+ });
22
+ }
23
+
24
+ function runtimeCollectionProperty(entryKind: RenameRuntimeEntryIntent["entryKind"]): string {
25
+ return {
26
+ command: "commands",
27
+ query: "queries",
28
+ liveQuery: "liveQueries",
29
+ action: "actions",
30
+ workflow: "workflows",
31
+ }[entryKind];
32
+ }
33
+
34
+ function runtimeEntryDirectories(entryKind: RenameRuntimeEntryIntent["entryKind"]): string[] {
35
+ return {
36
+ command: ["src/commands"],
37
+ query: ["src/queries"],
38
+ liveQuery: ["src/queries"],
39
+ action: ["src/actions"],
40
+ workflow: ["src/workflows"],
41
+ }[entryKind];
42
+ }
43
+
44
+ function runtimeEntryCallName(entryKind: RenameRuntimeEntryIntent["entryKind"]): string {
45
+ return {
46
+ command: "command",
47
+ query: "query",
48
+ liveQuery: "liveQuery",
49
+ action: "action",
50
+ workflow: "workflow",
51
+ }[entryKind];
52
+ }
53
+
54
+ function runtimeHttpSegment(entryKind: RenameRuntimeEntryIntent["entryKind"]): string | null {
55
+ return {
56
+ command: "commands",
57
+ query: "queries",
58
+ liveQuery: "live",
59
+ action: null,
60
+ workflow: null,
61
+ }[entryKind];
62
+ }
63
+
64
+ function isTypeScriptLike(file: string): boolean {
65
+ return file.endsWith(".ts") || file.endsWith(".tsx") || file.endsWith(".js") || file.endsWith(".jsx");
66
+ }
67
+
68
+ function scriptKindForFile(file: string): ts.ScriptKind {
69
+ if (file.endsWith(".tsx")) return ts.ScriptKind.TSX;
70
+ if (file.endsWith(".jsx")) return ts.ScriptKind.JSX;
71
+ if (file.endsWith(".js")) return ts.ScriptKind.JS;
72
+ return ts.ScriptKind.TS;
73
+ }
74
+
75
+ function renameIdentifierNode(to: string): ts.Identifier {
76
+ return ts.factory.createIdentifier(to);
77
+ }
78
+
79
+ function isRuntimeEntryCall(node: ts.Expression | undefined, entryKind: RenameRuntimeEntryIntent["entryKind"]): boolean {
80
+ if (!node || !ts.isCallExpression(node)) {
81
+ return false;
82
+ }
83
+ const expected = runtimeEntryCallName(entryKind);
84
+ return (
85
+ (ts.isIdentifier(node.expression) && node.expression.text === expected) ||
86
+ (ts.isPropertyAccessExpression(node.expression) && node.expression.name.text === expected)
87
+ );
88
+ }
89
+
90
+ function isCapabilityMapRuntimeAccess(
91
+ node: ts.PropertyAccessExpression,
92
+ from: string,
93
+ entryKind: RenameRuntimeEntryIntent["entryKind"],
94
+ sourceFile: ts.SourceFile,
95
+ ): boolean {
96
+ if (node.name.text !== from) {
97
+ return false;
98
+ }
99
+ const collection = runtimeCollectionProperty(entryKind);
100
+ const parent = node.expression;
101
+ if (ts.isIdentifier(parent)) {
102
+ return parent.text === collection && hasForgeBridgeImport(sourceFile, collection);
103
+ }
104
+ if (!ts.isPropertyAccessExpression(parent)) {
105
+ return false;
106
+ }
107
+ if (parent.name.text !== collection) {
108
+ return false;
109
+ }
110
+ const root = parent.expression;
111
+ return (
112
+ ts.isIdentifier(root) &&
113
+ hasForgeBridgeImport(sourceFile, root.text) &&
114
+ (root.text === "api" ||
115
+ root.text === "client" ||
116
+ root.text === "commands" ||
117
+ root.text === "queries" ||
118
+ root.text === "liveQueries")
119
+ );
120
+ }
121
+
122
+ function importLooksLikeForgeBridge(specifier: string): boolean {
123
+ const normalized = specifier.replace(/\\/g, "/");
124
+ return (
125
+ normalized.includes("/_generated/") ||
126
+ normalized.endsWith("/_generated/api") ||
127
+ normalized.endsWith("/_generated/api.js") ||
128
+ normalized.endsWith("/_generated/api.ts") ||
129
+ normalized.endsWith("/lib/forge") ||
130
+ normalized.endsWith("/lib/forge.js") ||
131
+ normalized.endsWith("/lib/forge.ts") ||
132
+ normalized.endsWith("/lib/forge.tsx") ||
133
+ normalized === "forge/client" ||
134
+ normalized === "forge/react"
135
+ );
136
+ }
137
+
138
+ function hasForgeBridgeImport(sourceFile: ts.SourceFile, name: string): boolean {
139
+ for (const statement of sourceFile.statements) {
140
+ if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier)) {
141
+ continue;
142
+ }
143
+ if (!importLooksLikeForgeBridge(statement.moduleSpecifier.text)) {
144
+ continue;
145
+ }
146
+ const importClause = statement.importClause;
147
+ if (!importClause) {
148
+ continue;
149
+ }
150
+ if (importClause.name?.text === name) {
151
+ return true;
152
+ }
153
+ const namedBindings = importClause.namedBindings;
154
+ if (!namedBindings || !ts.isNamedImports(namedBindings)) {
155
+ continue;
156
+ }
157
+ if (namedBindings.elements.some((element) => element.name.text === name)) {
158
+ return true;
159
+ }
160
+ }
161
+ return false;
162
+ }
163
+
164
+ function hookKindForCall(node: ts.CallExpression): RenameRuntimeEntryIntent["entryKind"] | null {
165
+ if (!ts.isIdentifier(node.expression)) {
166
+ return null;
167
+ }
168
+ const map: Record<string, RenameRuntimeEntryIntent["entryKind"]> = {
169
+ useCommand: "command",
170
+ useQuery: "query",
171
+ useLiveQuery: "liveQuery",
172
+ };
173
+ return map[node.expression.text] ?? null;
174
+ }
175
+
176
+ function clientMethodForEntry(entryKind: RenameRuntimeEntryIntent["entryKind"]): string | null {
177
+ return {
178
+ command: "command",
179
+ query: "query",
180
+ liveQuery: "liveQuery",
181
+ action: null,
182
+ workflow: null,
183
+ }[entryKind];
184
+ }
185
+
186
+ function isRuntimeStringLiteralContext(
187
+ node: ts.StringLiteral | ts.NoSubstitutionTemplateLiteral,
188
+ intent: RenameRuntimeEntryIntent,
189
+ ): boolean {
190
+ const parent = node.parent;
191
+ if (ts.isCallExpression(parent)) {
192
+ const hookKind = hookKindForCall(parent);
193
+ if (hookKind === intent.entryKind && parent.arguments[0] === node) {
194
+ return true;
195
+ }
196
+ const clientMethod = clientMethodForEntry(intent.entryKind);
197
+ if (
198
+ clientMethod &&
199
+ ts.isPropertyAccessExpression(parent.expression) &&
200
+ parent.expression.name.text === clientMethod &&
201
+ parent.arguments[0] === node
202
+ ) {
203
+ return true;
204
+ }
205
+ }
206
+ const segment = runtimeHttpSegment(intent.entryKind);
207
+ if (segment && runtimeHttpPathReferences(node.text, segment, intent.from)) {
208
+ return true;
209
+ }
210
+ return false;
211
+ }
212
+
213
+ function renameImportSpecifierPath(specifier: string, from: string, to: string): string {
214
+ const slashIndex = specifier.lastIndexOf("/");
215
+ if (slashIndex === -1) {
216
+ return specifier;
217
+ }
218
+ const prefix = specifier.slice(0, slashIndex + 1);
219
+ const leaf = specifier.slice(slashIndex + 1);
220
+ for (const ext of ["", ".js", ".jsx", ".ts", ".tsx"]) {
221
+ if (leaf === `${from}${ext}`) {
222
+ return `${prefix}${to}${ext}`;
223
+ }
224
+ }
225
+ return specifier;
226
+ }
227
+
228
+ function importSpecifierReferencesRuntimeEntry(specifier: string, from: string, to = from): boolean {
229
+ return renameImportSpecifierPath(specifier, from, to) !== specifier;
230
+ }
231
+
232
+ function runtimeHttpPathReferences(value: string, segment: string, name: string): boolean {
233
+ const marker = `/${segment}/${name}`;
234
+ const index = value.indexOf(marker);
235
+ if (index === -1) {
236
+ return false;
237
+ }
238
+ const next = value[index + marker.length];
239
+ return next === undefined || next === "/" || next === "?" || next === "#" || next === "&";
240
+ }
241
+
242
+ function renameRuntimeHttpPath(value: string, segment: string, from: string, to: string): string {
243
+ const marker = `/${segment}/${from}`;
244
+ if (!runtimeHttpPathReferences(value, segment, from)) {
245
+ return value;
246
+ }
247
+ let output = "";
248
+ let cursor = 0;
249
+ while (cursor < value.length) {
250
+ const index = value.indexOf(marker, cursor);
251
+ if (index === -1) {
252
+ output += value.slice(cursor);
253
+ break;
254
+ }
255
+ const next = value[index + marker.length];
256
+ if (next === undefined || next === "/" || next === "?" || next === "#" || next === "&") {
257
+ output += value.slice(cursor, index) + `/${segment}/${to}`;
258
+ cursor = index + marker.length;
259
+ continue;
260
+ }
261
+ output += value.slice(cursor, index + marker.length);
262
+ cursor = index + marker.length;
263
+ }
264
+ return output;
265
+ }
266
+
267
+ export function findRuntimeEntryFile(
268
+ workspaceRoot: string,
269
+ entryKind: RenameRuntimeEntryIntent["entryKind"],
270
+ name: string,
271
+ ): string | null {
272
+ for (const dir of runtimeEntryDirectories(entryKind)) {
273
+ for (const ext of [".ts", ".tsx"]) {
274
+ const candidate = `${dir}/${name}${ext}`;
275
+ if (readText(workspaceRoot, candidate)) {
276
+ return candidate;
277
+ }
278
+ }
279
+ }
280
+ for (const file of walkFiles(workspaceRoot)) {
281
+ if (!runtimeEntryDirectories(entryKind).some((dir) => file.startsWith(`${dir}/`))) {
282
+ continue;
283
+ }
284
+ const content = readText(workspaceRoot, file) ?? "";
285
+ if (content.includes(`export const ${name}`)) {
286
+ return file;
287
+ }
288
+ }
289
+ return null;
290
+ }
291
+
292
+ export function sourceReferencesRuntimeEntry(source: string, file: string, intent: RenameRuntimeEntryIntent): boolean {
293
+ if (file.endsWith(`/${intent.from}.ts`) || file.endsWith(`/${intent.from}.tsx`)) {
294
+ return true;
295
+ }
296
+ if (!source.includes(intent.from)) {
297
+ return false;
298
+ }
299
+ if (isTypeScriptLike(file)) {
300
+ const sourceFile = ts.createSourceFile(file, source, ts.ScriptTarget.Latest, true, scriptKindForFile(file));
301
+ let found = false;
302
+ const visit = (node: ts.Node): void => {
303
+ if (found) {
304
+ return;
305
+ }
306
+ if (
307
+ ts.isVariableDeclaration(node) &&
308
+ ts.isIdentifier(node.name) &&
309
+ node.name.text === intent.from &&
310
+ isRuntimeEntryCall(node.initializer, intent.entryKind)
311
+ ) {
312
+ found = true;
313
+ return;
314
+ }
315
+ if (ts.isPropertyAccessExpression(node) && isCapabilityMapRuntimeAccess(node, intent.from, intent.entryKind, sourceFile)) {
316
+ found = true;
317
+ return;
318
+ }
319
+ if (
320
+ (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) &&
321
+ node.text === intent.from &&
322
+ isRuntimeStringLiteralContext(node, intent)
323
+ ) {
324
+ found = true;
325
+ return;
326
+ }
327
+ if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
328
+ if (importSpecifierReferencesRuntimeEntry(node.moduleSpecifier.text, intent.from)) {
329
+ found = true;
330
+ return;
331
+ }
332
+ }
333
+ const segment = runtimeHttpSegment(intent.entryKind);
334
+ if (
335
+ segment &&
336
+ (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) &&
337
+ runtimeHttpPathReferences(node.text, segment, intent.from)
338
+ ) {
339
+ found = true;
340
+ return;
341
+ }
342
+ ts.forEachChild(node, visit);
343
+ };
344
+ visit(sourceFile);
345
+ return found;
346
+ }
347
+ if (file.endsWith(".json")) {
348
+ try {
349
+ return jsonReferencesRuntimeEntry(JSON.parse(source) as unknown, intent.from, intent.entryKind);
350
+ } catch {
351
+ return false;
352
+ }
353
+ }
354
+ return false;
355
+ }
356
+
357
+ function jsonReferencesRuntimeEntry(value: unknown, name: string, entryKind: RenameRuntimeEntryIntent["entryKind"]): boolean {
358
+ return jsonReferencesRuntimeEntryAtKey(value, name, entryKind, undefined);
359
+ }
360
+
361
+ function runtimeJsonKeys(entryKind: RenameRuntimeEntryIntent["entryKind"]): Set<string> {
362
+ return new Set([
363
+ runtimeEntryCallName(entryKind),
364
+ runtimeCollectionProperty(entryKind),
365
+ entryKind,
366
+ ]);
367
+ }
368
+
369
+ function jsonReferencesRuntimeEntryAtKey(
370
+ value: unknown,
371
+ name: string,
372
+ entryKind: RenameRuntimeEntryIntent["entryKind"],
373
+ key: string | undefined,
374
+ ): boolean {
375
+ const allowedKeys = runtimeJsonKeys(entryKind);
376
+ if (typeof value === "string") {
377
+ return value === name && !!key && allowedKeys.has(key);
378
+ }
379
+ if (Array.isArray(value)) {
380
+ return value.some((entry) => jsonReferencesRuntimeEntryAtKey(entry, name, entryKind, key));
381
+ }
382
+ if (value && typeof value === "object") {
383
+ const record = value as Record<string, unknown>;
384
+ if (record.kind === entryKind && record.name === name) {
385
+ return true;
386
+ }
387
+ return Object.entries(record).some(([childKey, entry]) =>
388
+ jsonReferencesRuntimeEntryAtKey(entry, name, entryKind, childKey),
389
+ );
390
+ }
391
+ return false;
392
+ }
393
+
394
+ function renameRuntimeEntryInJson(source: string, intent: RenameRuntimeEntryIntent): string {
395
+ const parsed = JSON.parse(source) as unknown;
396
+ return `${JSON.stringify(renameRuntimeEntryJsonValue(parsed, intent), null, 2)}\n`;
397
+ }
398
+
399
+ function renameRuntimeEntryJsonValue(value: unknown, intent: RenameRuntimeEntryIntent): unknown {
400
+ return renameRuntimeEntryJsonValueAtKey(value, intent, undefined);
401
+ }
402
+
403
+ function renameRuntimeEntryJsonValueAtKey(
404
+ value: unknown,
405
+ intent: RenameRuntimeEntryIntent,
406
+ key: string | undefined,
407
+ ): unknown {
408
+ const allowedKeys = runtimeJsonKeys(intent.entryKind);
409
+ if (typeof value === "string") {
410
+ return value === intent.from && !!key && allowedKeys.has(key) ? intent.to : value;
411
+ }
412
+ if (Array.isArray(value)) {
413
+ return value.map((entry) => renameRuntimeEntryJsonValueAtKey(entry, intent, key));
414
+ }
415
+ if (value && typeof value === "object") {
416
+ const record = value as Record<string, unknown>;
417
+ const output: Record<string, unknown> = {};
418
+ for (const [childKey, entry] of Object.entries(record)) {
419
+ output[childKey] =
420
+ childKey === "name" && record.kind === intent.entryKind && entry === intent.from
421
+ ? intent.to
422
+ : renameRuntimeEntryJsonValueAtKey(entry, intent, childKey);
423
+ }
424
+ return output;
425
+ }
426
+ return value;
427
+ }
428
+
429
+ export function renameRuntimeEntryContent(source: string, file: string, intent: RenameRuntimeEntryIntent): string {
430
+ if (isTypeScriptLike(file)) {
431
+ return renameRuntimeEntryInSource(source, file, intent);
432
+ }
433
+ if (file.endsWith(".json")) {
434
+ return renameRuntimeEntryInJson(source, intent);
435
+ }
436
+ return source;
437
+ }
438
+
439
+ function renameRuntimeEntryInSource(source: string, file: string, intent: RenameRuntimeEntryIntent): string {
440
+ const sourceFile = ts.createSourceFile(file, source, ts.ScriptTarget.Latest, true, scriptKindForFile(file));
441
+ const transform: ts.TransformerFactory<ts.SourceFile> = (context) => {
442
+ const visit: ts.Visitor = (node) => {
443
+ if (
444
+ ts.isVariableDeclaration(node) &&
445
+ ts.isIdentifier(node.name) &&
446
+ node.name.text === intent.from &&
447
+ isRuntimeEntryCall(node.initializer, intent.entryKind)
448
+ ) {
449
+ return ts.factory.updateVariableDeclaration(
450
+ node,
451
+ renameIdentifierNode(intent.to),
452
+ node.exclamationToken,
453
+ node.type,
454
+ ts.visitNode(node.initializer, visit, ts.isExpression) ?? node.initializer,
455
+ );
456
+ }
457
+ if (ts.isPropertyAccessExpression(node) && isCapabilityMapRuntimeAccess(node, intent.from, intent.entryKind, sourceFile)) {
458
+ return ts.factory.updatePropertyAccessExpression(node, node.expression, renameIdentifierNode(intent.to));
459
+ }
460
+ if (
461
+ (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) &&
462
+ node.text === intent.from &&
463
+ isRuntimeStringLiteralContext(node, intent)
464
+ ) {
465
+ return ts.isNoSubstitutionTemplateLiteral(node)
466
+ ? ts.factory.createNoSubstitutionTemplateLiteral(intent.to)
467
+ : ts.factory.createStringLiteral(intent.to);
468
+ }
469
+ if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
470
+ const segment = runtimeHttpSegment(intent.entryKind);
471
+ if (segment) {
472
+ const nextPath = renameRuntimeHttpPath(node.text, segment, intent.from, intent.to);
473
+ if (nextPath !== node.text) {
474
+ return ts.isNoSubstitutionTemplateLiteral(node)
475
+ ? ts.factory.createNoSubstitutionTemplateLiteral(nextPath)
476
+ : ts.factory.createStringLiteral(nextPath);
477
+ }
478
+ }
479
+ }
480
+ if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
481
+ const nextSpecifier = renameImportSpecifierPath(node.moduleSpecifier.text, intent.from, intent.to);
482
+ if (nextSpecifier !== node.moduleSpecifier.text) {
483
+ return ts.factory.updateImportDeclaration(
484
+ node,
485
+ node.modifiers,
486
+ node.importClause,
487
+ ts.factory.createStringLiteral(nextSpecifier),
488
+ node.attributes,
489
+ );
490
+ }
491
+ }
492
+ return ts.visitEachChild(node, visit, context);
493
+ };
494
+ return (node) => ts.visitNode(node, visit) as ts.SourceFile;
495
+ };
496
+ const result = ts.transform(sourceFile, [transform]);
497
+ try {
498
+ const transformed = result.transformed[0];
499
+ const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
500
+ return printer.printFile(transformed);
501
+ } finally {
502
+ result.dispose();
503
+ }
504
+ }
505
+
506
+ export function buildRenameRuntimeEntryPlan(
507
+ workspaceRoot: string,
508
+ intent: RenameRuntimeEntryIntent,
509
+ ): {
510
+ patches: PlannedPatch[];
511
+ filesToCreate: PlannedFile[];
512
+ filesToDelete: Array<{ file: string; description: string }>;
513
+ diagnostics: Diagnostic[];
514
+ } {
515
+ const patches: PlannedPatch[] = [];
516
+ const filesToCreate: PlannedFile[] = [];
517
+ const filesToDelete: Array<{ file: string; description: string }> = [];
518
+ const diagnostics: Diagnostic[] = [];
519
+ const definitionFile = findRuntimeEntryFile(workspaceRoot, intent.entryKind, intent.from);
520
+ if (!definitionFile) {
521
+ return {
522
+ patches,
523
+ filesToCreate,
524
+ filesToDelete,
525
+ diagnostics: [
526
+ diagnostic(
527
+ "error",
528
+ "FORGE_REFACTOR_TARGET_NOT_FOUND",
529
+ `${intent.entryKind} '${intent.from}' was not found`,
530
+ ),
531
+ ],
532
+ };
533
+ }
534
+
535
+ let found = false;
536
+ for (const file of walkFiles(workspaceRoot)) {
537
+ if (isGenerated(file)) {
538
+ continue;
539
+ }
540
+ const content = readText(workspaceRoot, file) ?? "";
541
+ if (!sourceReferencesRuntimeEntry(content, file, intent)) {
542
+ continue;
543
+ }
544
+ if (file === definitionFile) {
545
+ const shouldRenameFile = file.endsWith(`/${intent.from}.ts`) || file.endsWith(`/${intent.from}.tsx`);
546
+ const renamedContent = renameRuntimeEntryContent(content, file, intent);
547
+ if (shouldRenameFile) {
548
+ const renamedPath = file.replace(`/${intent.from}.`, `/${intent.to}.`);
549
+ filesToCreate.push(
550
+ makeFile(
551
+ workspaceRoot,
552
+ renamedPath,
553
+ `Rename ${intent.entryKind} file ${intent.from} to ${intent.to}`,
554
+ renamedContent,
555
+ ),
556
+ );
557
+ filesToDelete.push({
558
+ file,
559
+ description: `Remove old ${intent.entryKind} file ${intent.from}`,
560
+ });
561
+ } else {
562
+ const patch = makePatchFromContent(
563
+ file,
564
+ `Rename ${intent.entryKind} ${intent.from} to ${intent.to}`,
565
+ content,
566
+ renamedContent,
567
+ );
568
+ if (patch) {
569
+ patches.push(patch);
570
+ }
571
+ }
572
+ found = true;
573
+ continue;
574
+ }
575
+ const patch = patchFile(
576
+ workspaceRoot,
577
+ file,
578
+ `Rename ${intent.entryKind} ${intent.from} to ${intent.to}`,
579
+ (source) => renameRuntimeEntryContent(source, file, intent),
580
+ );
581
+ if (patch) {
582
+ found = true;
583
+ patches.push(patch);
584
+ }
585
+ }
586
+
587
+ if (!found) {
588
+ diagnostics.push(
589
+ diagnostic(
590
+ "error",
591
+ "FORGE_REFACTOR_TARGET_NOT_FOUND",
592
+ `${intent.entryKind} '${intent.from}' was not found in editable sources`,
593
+ ),
594
+ );
595
+ }
596
+
597
+ return { patches, filesToCreate, filesToDelete, diagnostics };
598
+ }
@@ -1,5 +1,6 @@
1
1
  import { nodeFileSystem } from "../compiler/fs/index.ts";
2
2
  import { join } from "node:path";
3
+ import { pathToFileURL } from "node:url";
3
4
  import { buildAppGraph } from "../compiler/app-graph/build.ts";
4
5
  import { buildRuntimeMatrix } from "../compiler/classifier/runtime-matrix.ts";
5
6
  import { classify } from "../compiler/classifier/classify.ts";
@@ -218,7 +219,7 @@ async function applyMocks(workspaceRoot: string, lock: ForgeLock | null): Promis
218
219
  continue;
219
220
  }
220
221
 
221
- const mod = (await import(absolute)) as Record<string, unknown>;
222
+ const mod = (await import(pathToFileURL(absolute).href)) as Record<string, unknown>;
222
223
  const factoryName = `create${capitalizeSegment(packageName)}Mock`;
223
224
  const factory = mod[factoryName];
224
225
 
@@ -387,7 +388,7 @@ export async function runEntry(
387
388
  });
388
389
 
389
390
  const absolutePath = join(workspaceRoot, entry.file);
390
- const mod = (await import(absolutePath)) as Record<string, unknown>;
391
+ const mod = (await import(pathToFileURL(absolutePath).href)) as Record<string, unknown>;
391
392
  const resolved = resolveHandlerFromModule(mod, entry.name);
392
393
 
393
394
  if (!resolved) {
@@ -1,4 +1,5 @@
1
1
  import { join } from "node:path";
2
+ import { pathToFileURL } from "node:url";
2
3
  import { createDiagnostic } from "../../compiler/diagnostics/create.ts";
3
4
  import {
4
5
  FORGE_LIVEQUERY_AI_FORBIDDEN,
@@ -185,7 +186,7 @@ export async function runLiveQuery(
185
186
 
186
187
  try {
187
188
  const absolutePath = join(workspaceRoot, liveQuery.file);
188
- const mod = (await import(absolutePath)) as Record<string, unknown>;
189
+ const mod = (await import(pathToFileURL(absolutePath).href)) as Record<string, unknown>;
189
190
  const exported = mod[liveQuery.exportName];
190
191
 
191
192
  if (
@@ -1,4 +1,5 @@
1
1
  import { join } from "node:path";
2
+ import { pathToFileURL } from "node:url";
2
3
  import { createDiagnostic } from "../../compiler/diagnostics/create.ts";
3
4
  import {
4
5
  FORGE_OUTBOX_PROCESS_FAILED,
@@ -66,7 +67,7 @@ async function runDeliveryAction(
66
67
  await prepareRuntimeEnvironment(workspaceRoot, { mock, db: adapter });
67
68
 
68
69
  const absolutePath = join(workspaceRoot, entry.file);
69
- const mod = (await import(absolutePath)) as Record<string, unknown>;
70
+ const mod = (await import(pathToFileURL(absolutePath).href)) as Record<string, unknown>;
70
71
  const exported = mod[entry.name];
71
72
 
72
73
  if (
@@ -1,4 +1,5 @@
1
1
  import { join } from "node:path";
2
+ import { pathToFileURL } from "node:url";
2
3
  import { createDiagnostic } from "../../compiler/diagnostics/create.ts";
3
4
  import {
4
5
  FORGE_POLICY_DENIED,
@@ -249,7 +250,7 @@ export async function runQuery(
249
250
  await setDbSessionContext(tx, auth);
250
251
 
251
252
  const absolutePath = join(workspaceRoot, query.file);
252
- const mod = (await import(absolutePath)) as Record<string, unknown>;
253
+ const mod = (await import(pathToFileURL(absolutePath).href)) as Record<string, unknown>;
253
254
  const exported = mod[query.name];
254
255
 
255
256
  if (
@@ -1,4 +1,5 @@
1
1
  import { join } from "node:path";
2
+ import { pathToFileURL } from "node:url";
2
3
  import { createDiagnostic } from "../../compiler/diagnostics/create.ts";
3
4
  import {
4
5
  FORGE_DB_ADAPTER_UNAVAILABLE,
@@ -162,7 +163,7 @@ export async function executeResolvedEntry(
162
163
  runtime.tableMap
163
164
  ) {
164
165
  const absolutePath = join(workspaceRoot, entry.file);
165
- const mod = (await import(absolutePath)) as Record<string, unknown>;
166
+ const mod = (await import(pathToFileURL(absolutePath).href)) as Record<string, unknown>;
166
167
  const exported = mod[entry.name];
167
168
  const handler = (exported as { handler: (ctx: unknown, args: unknown) => unknown })
168
169
  .handler;
@@ -1,3 +1,5 @@
1
+ import { join } from "node:path";
2
+ import { pathToFileURL } from "node:url";
1
3
  import type { ForgeTelemetryEnvelope } from "../types.ts";
2
4
 
3
5
  export interface PosthogCaptureFn {
@@ -33,11 +35,8 @@ export async function sendToPosthog(
33
35
  }
34
36
 
35
37
  try {
36
- const adapterPath = `${workspaceRoot}/src/forge/_generated/packages/posthog.server.ts`.replace(
37
- /\\/g,
38
- "/",
39
- );
40
- const mod = (await import(adapterPath)) as {
38
+ const adapterPath = join(workspaceRoot, "src/forge/_generated/packages/posthog.server.ts");
39
+ const mod = (await import(pathToFileURL(adapterPath).href)) as {
41
40
  createPosthogServer?: () => { capture: (args: unknown) => void; shutdown: () => Promise<void> };
42
41
  };
43
42