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
@@ -1,214 +1,214 @@
1
- import { join } from "node:path";
2
- import { nodeFileSystem } from "../fs/index.ts";
3
- import type { Dependency } from "../types/package-graph.ts";
4
- import { hashTsconfigForWorkspace } from "../app-graph/tsconfig-hash.ts";
5
- import { hashStable } from "../primitives/hash.ts";
6
- import { canonicalJson } from "../primitives/serialize.ts";
7
- import { detectPackageManager } from "../package-manager/detect.ts";
8
- import {
9
- getLockfileCandidates,
10
- getLockfileForPm,
11
- } from "../package-manager/detect.ts";
12
- import { GENERATED_DIR } from "../emitter/constants.ts";
13
- import type { DiscoverContext } from "./types.ts";
14
- import {
15
- type SourceFileIndex,
16
- walkWorkspaceSources,
17
- } from "./workspace-index.ts";
18
-
19
- const DEFAULT_SOURCE_ROOTS = ["src", "tests"];
20
-
21
- function readTextHash(absolutePath: string): string {
22
- return hashStable((nodeFileSystem.readText(absolutePath) ?? ""));
23
- }
24
-
25
- function hashFileIfExists(absolutePath: string): string {
26
- if (!nodeFileSystem.exists(absolutePath)) {
27
- return "";
28
- }
29
- return readTextHash(absolutePath);
30
- }
31
-
32
- function resolveLockfilePath(workspaceRoot: string): string | null {
33
- const pm = detectPackageManager(workspaceRoot);
34
- const candidates = getLockfileCandidates(pm);
35
- for (const file of candidates) {
36
- const absolute = join(workspaceRoot, file);
37
- if (nodeFileSystem.exists(absolute)) {
38
- return absolute;
39
- }
40
- }
41
-
42
- const fallback = join(workspaceRoot, getLockfileForPm(pm));
43
- return nodeFileSystem.exists(fallback) ? fallback : null;
44
- }
45
-
46
- interface WorkspacePackageJson {
47
- dependencies?: Record<string, string>;
48
- devDependencies?: Record<string, string>;
49
- forge?: {
50
- sourceRoots?: string[];
51
- };
52
- }
53
-
54
- function readPackageJson(workspaceRoot: string): WorkspacePackageJson {
55
- const raw = (nodeFileSystem.readText(join(workspaceRoot, "package.json")) ?? "");
56
- return JSON.parse(raw) as WorkspacePackageJson;
57
- }
58
-
59
- function resolveSourceRoots(
60
- workspaceRoot: string,
61
- override?: string[],
62
- ): string[] {
63
- if (override) {
64
- return override;
65
- }
66
-
67
- try {
68
- const configured = readPackageJson(workspaceRoot).forge?.sourceRoots;
69
- if (configured && configured.length > 0) {
70
- return configured;
71
- }
72
- } catch {
73
- // fall back to defaults
74
- }
75
-
76
- return DEFAULT_SOURCE_ROOTS;
77
- }
78
-
79
- function resolveDependency(
80
- workspaceRoot: string,
81
- name: string,
82
- specifier: string,
83
- packageManager: ReturnType<typeof detectPackageManager>,
84
- ): Dependency | null {
85
- const installPath = join(workspaceRoot, "node_modules", name);
86
- if (!nodeFileSystem.exists(installPath)) {
87
- return null;
88
- }
89
-
90
- let version = specifier.replace(/^[\^~>=<]*/, "").trim();
91
- const pkgJsonPath = join(installPath, "package.json");
92
- if (nodeFileSystem.exists(pkgJsonPath)) {
93
- try {
94
- const installed = JSON.parse((nodeFileSystem.readText(pkgJsonPath) ?? "")) as {
95
- version?: string;
96
- };
97
- if (installed.version) {
98
- version = installed.version;
99
- }
100
- } catch {
101
- // keep specifier-derived version
102
- }
103
- }
104
-
105
- return {
106
- name,
107
- version,
108
- packageManager,
109
- installPath: installPath.replace(/\\/g, "/"),
110
- };
111
- }
112
-
113
- function collectDependencies(workspaceRoot: string): Dependency[] {
114
- const packageManager = detectPackageManager(workspaceRoot);
115
- const pkg = readPackageJson(workspaceRoot);
116
- const specs = {
117
- ...pkg.dependencies,
118
- ...pkg.devDependencies,
119
- };
120
-
121
- const deps: Dependency[] = [];
122
- for (const [name, specifier] of Object.entries(specs)) {
123
- const dep = resolveDependency(
124
- workspaceRoot,
125
- name,
126
- specifier,
127
- packageManager,
128
- );
129
- if (dep) {
130
- deps.push(dep);
131
- }
132
- }
133
-
134
- deps.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
135
- return deps;
136
- }
137
-
138
- function computeSourceFingerprint(sources: import("../types/app-graph.ts").SourceFile[]): string {
139
- const payload = sources.map((source) => ({
140
- path: source.path,
141
- contentHash: source.contentHash,
142
- }));
143
- return hashStable(canonicalJson(payload));
144
- }
145
-
146
- function computeInputFingerprint(parts: {
147
- sourceFingerprint: string;
148
- packageJsonHash: string;
149
- lockfileHash: string;
150
- tsconfigHash: string;
151
- dependencyVersions: Array<{ name: string; version: string }>;
152
- }): string {
153
- return hashStable(canonicalJson(parts));
154
- }
155
-
156
- export function getSourceRoots(workspaceRoot: string, override?: string[]): string[] {
157
- return resolveSourceRoots(workspaceRoot, override);
158
- }
159
-
160
- export interface DiscoverOptions {
161
- workspaceRoot: string;
162
- sourceRoots?: string[];
163
- priorSourceIndex?: SourceFileIndex;
164
- priorSourcesByPath?: Map<string, import("../types/app-graph.ts").SourceFile>;
165
- }
166
-
167
- export function discover(options: DiscoverOptions): DiscoverContext {
168
- const workspaceRoot = options.workspaceRoot.replace(/\\/g, "/");
169
- const packageManager = detectPackageManager(workspaceRoot);
170
- const walked = walkWorkspaceSources({
171
- workspaceRoot,
172
- roots: resolveSourceRoots(workspaceRoot, options.sourceRoots),
173
- priorIndex: options.priorSourceIndex,
174
- priorSourcesByPath: options.priorSourcesByPath,
175
- });
176
-
177
- const dependencies = collectDependencies(workspaceRoot);
178
-
179
- const packageJsonHash = hashFileIfExists(join(workspaceRoot, "package.json"));
180
- const lockfilePath = resolveLockfilePath(workspaceRoot);
181
- const lockfileHash = lockfilePath ? readTextHash(lockfilePath) : "";
182
- const tsconfigPath = nodeFileSystem.exists(join(workspaceRoot, "tsconfig.json"))
183
- ? "tsconfig.json"
184
- : null;
185
- const tsconfigHash = hashTsconfigForWorkspace(workspaceRoot, tsconfigPath ?? undefined);
186
- const sourceFingerprint = computeSourceFingerprint(walked.sources);
187
-
188
- const inputFingerprint = computeInputFingerprint({
189
- sourceFingerprint,
190
- packageJsonHash,
191
- lockfileHash,
192
- tsconfigHash,
193
- dependencyVersions: dependencies.map((dep) => ({
194
- name: dep.name,
195
- version: dep.version,
196
- })),
197
- });
198
-
199
- return {
200
- workspaceRoot,
201
- cacheDir: join(workspaceRoot, ".forge", "cache"),
202
- generatedDir: GENERATED_DIR,
203
- packageManager,
204
- sources: walked.sources,
205
- dependencies,
206
- tsconfigPath,
207
- packageJsonHash,
208
- lockfileHash,
209
- tsconfigHash,
210
- sourceFingerprint,
211
- inputFingerprint,
212
- sourceFileIndex: walked.index,
213
- };
214
- }
1
+ import { join } from "node:path";
2
+ import { nodeFileSystem } from "../fs/index.ts";
3
+ import type { Dependency } from "../types/package-graph.ts";
4
+ import { hashTsconfigForWorkspace } from "../app-graph/tsconfig-hash.ts";
5
+ import { hashStable } from "../primitives/hash.ts";
6
+ import { canonicalJson } from "../primitives/serialize.ts";
7
+ import { detectPackageManager } from "../package-manager/detect.ts";
8
+ import {
9
+ getLockfileCandidates,
10
+ getLockfileForPm,
11
+ } from "../package-manager/detect.ts";
12
+ import { GENERATED_DIR } from "../emitter/constants.ts";
13
+ import type { DiscoverContext } from "./types.ts";
14
+ import {
15
+ type SourceFileIndex,
16
+ walkWorkspaceSources,
17
+ } from "./workspace-index.ts";
18
+
19
+ const DEFAULT_SOURCE_ROOTS = ["src", "tests"];
20
+
21
+ function readTextHash(absolutePath: string): string {
22
+ return hashStable((nodeFileSystem.readText(absolutePath) ?? ""));
23
+ }
24
+
25
+ function hashFileIfExists(absolutePath: string): string {
26
+ if (!nodeFileSystem.exists(absolutePath)) {
27
+ return "";
28
+ }
29
+ return readTextHash(absolutePath);
30
+ }
31
+
32
+ function resolveLockfilePath(workspaceRoot: string): string | null {
33
+ const pm = detectPackageManager(workspaceRoot);
34
+ const candidates = getLockfileCandidates(pm);
35
+ for (const file of candidates) {
36
+ const absolute = join(workspaceRoot, file);
37
+ if (nodeFileSystem.exists(absolute)) {
38
+ return absolute;
39
+ }
40
+ }
41
+
42
+ const fallback = join(workspaceRoot, getLockfileForPm(pm));
43
+ return nodeFileSystem.exists(fallback) ? fallback : null;
44
+ }
45
+
46
+ interface WorkspacePackageJson {
47
+ dependencies?: Record<string, string>;
48
+ devDependencies?: Record<string, string>;
49
+ forge?: {
50
+ sourceRoots?: string[];
51
+ };
52
+ }
53
+
54
+ function readPackageJson(workspaceRoot: string): WorkspacePackageJson {
55
+ const raw = (nodeFileSystem.readText(join(workspaceRoot, "package.json")) ?? "");
56
+ return JSON.parse(raw) as WorkspacePackageJson;
57
+ }
58
+
59
+ function resolveSourceRoots(
60
+ workspaceRoot: string,
61
+ override?: string[],
62
+ ): string[] {
63
+ if (override) {
64
+ return override;
65
+ }
66
+
67
+ try {
68
+ const configured = readPackageJson(workspaceRoot).forge?.sourceRoots;
69
+ if (configured && configured.length > 0) {
70
+ return configured;
71
+ }
72
+ } catch {
73
+ // fall back to defaults
74
+ }
75
+
76
+ return DEFAULT_SOURCE_ROOTS;
77
+ }
78
+
79
+ function resolveDependency(
80
+ workspaceRoot: string,
81
+ name: string,
82
+ specifier: string,
83
+ packageManager: ReturnType<typeof detectPackageManager>,
84
+ ): Dependency | null {
85
+ const installPath = join(workspaceRoot, "node_modules", name);
86
+ if (!nodeFileSystem.exists(installPath)) {
87
+ return null;
88
+ }
89
+
90
+ let version = specifier.replace(/^[\^~>=<]*/, "").trim();
91
+ const pkgJsonPath = join(installPath, "package.json");
92
+ if (nodeFileSystem.exists(pkgJsonPath)) {
93
+ try {
94
+ const installed = JSON.parse((nodeFileSystem.readText(pkgJsonPath) ?? "")) as {
95
+ version?: string;
96
+ };
97
+ if (installed.version) {
98
+ version = installed.version;
99
+ }
100
+ } catch {
101
+ // keep specifier-derived version
102
+ }
103
+ }
104
+
105
+ return {
106
+ name,
107
+ version,
108
+ packageManager,
109
+ installPath: installPath.replace(/\\/g, "/"),
110
+ };
111
+ }
112
+
113
+ function collectDependencies(workspaceRoot: string): Dependency[] {
114
+ const packageManager = detectPackageManager(workspaceRoot);
115
+ const pkg = readPackageJson(workspaceRoot);
116
+ const specs = {
117
+ ...pkg.dependencies,
118
+ ...pkg.devDependencies,
119
+ };
120
+
121
+ const deps: Dependency[] = [];
122
+ for (const [name, specifier] of Object.entries(specs)) {
123
+ const dep = resolveDependency(
124
+ workspaceRoot,
125
+ name,
126
+ specifier,
127
+ packageManager,
128
+ );
129
+ if (dep) {
130
+ deps.push(dep);
131
+ }
132
+ }
133
+
134
+ deps.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
135
+ return deps;
136
+ }
137
+
138
+ function computeSourceFingerprint(sources: import("../types/app-graph.ts").SourceFile[]): string {
139
+ const payload = sources.map((source) => ({
140
+ path: source.path,
141
+ contentHash: source.contentHash,
142
+ }));
143
+ return hashStable(canonicalJson(payload));
144
+ }
145
+
146
+ function computeInputFingerprint(parts: {
147
+ sourceFingerprint: string;
148
+ packageJsonHash: string;
149
+ lockfileHash: string;
150
+ tsconfigHash: string;
151
+ dependencyVersions: Array<{ name: string; version: string }>;
152
+ }): string {
153
+ return hashStable(canonicalJson(parts));
154
+ }
155
+
156
+ export function getSourceRoots(workspaceRoot: string, override?: string[]): string[] {
157
+ return resolveSourceRoots(workspaceRoot, override);
158
+ }
159
+
160
+ export interface DiscoverOptions {
161
+ workspaceRoot: string;
162
+ sourceRoots?: string[];
163
+ priorSourceIndex?: SourceFileIndex;
164
+ priorSourcesByPath?: Map<string, import("../types/app-graph.ts").SourceFile>;
165
+ }
166
+
167
+ export function discover(options: DiscoverOptions): DiscoverContext {
168
+ const workspaceRoot = options.workspaceRoot.replace(/\\/g, "/");
169
+ const packageManager = detectPackageManager(workspaceRoot);
170
+ const walked = walkWorkspaceSources({
171
+ workspaceRoot,
172
+ roots: resolveSourceRoots(workspaceRoot, options.sourceRoots),
173
+ priorIndex: options.priorSourceIndex,
174
+ priorSourcesByPath: options.priorSourcesByPath,
175
+ });
176
+
177
+ const dependencies = collectDependencies(workspaceRoot);
178
+
179
+ const packageJsonHash = hashFileIfExists(join(workspaceRoot, "package.json"));
180
+ const lockfilePath = resolveLockfilePath(workspaceRoot);
181
+ const lockfileHash = lockfilePath ? readTextHash(lockfilePath) : "";
182
+ const tsconfigPath = nodeFileSystem.exists(join(workspaceRoot, "tsconfig.json"))
183
+ ? "tsconfig.json"
184
+ : null;
185
+ const tsconfigHash = hashTsconfigForWorkspace(workspaceRoot, tsconfigPath ?? undefined);
186
+ const sourceFingerprint = computeSourceFingerprint(walked.sources);
187
+
188
+ const inputFingerprint = computeInputFingerprint({
189
+ sourceFingerprint,
190
+ packageJsonHash,
191
+ lockfileHash,
192
+ tsconfigHash,
193
+ dependencyVersions: dependencies.map((dep) => ({
194
+ name: dep.name,
195
+ version: dep.version,
196
+ })),
197
+ });
198
+
199
+ return {
200
+ workspaceRoot,
201
+ cacheDir: join(workspaceRoot, ".forge", "cache"),
202
+ generatedDir: GENERATED_DIR,
203
+ packageManager,
204
+ sources: walked.sources,
205
+ dependencies,
206
+ tsconfigPath,
207
+ packageJsonHash,
208
+ lockfileHash,
209
+ tsconfigHash,
210
+ sourceFingerprint,
211
+ inputFingerprint,
212
+ sourceFileIndex: walked.index,
213
+ };
214
+ }
@@ -1,5 +1,5 @@
1
- export { propagateContexts } from "../guards/propagate-contexts.ts";
2
- export {
3
- checkImportGuards,
4
- isContextViolating,
5
- } from "../guards/check-import-guards.ts";
1
+ export { propagateContexts } from "../guards/propagate-contexts.ts";
2
+ export {
3
+ checkImportGuards,
4
+ isContextViolating,
5
+ } from "../guards/check-import-guards.ts";
@@ -1,27 +1,27 @@
1
- export type {
2
- DiscoverContext,
3
- OrchestratorManifest,
4
- } from "./types.ts";
5
- export { ORCHESTRATOR_MANIFEST_VERSION } from "./types.ts";
6
- export { discover, type DiscoverOptions } from "./discover.ts";
7
- export { plan, type PlanInput } from "./plan.ts";
8
- export {
9
- run,
10
- createGenerationOrchestrator,
11
- type GenerationOrchestrator,
12
- } from "./run.ts";
13
- export { loadManifest, saveManifest, updateManifestAfterWrite } from "./manifest.ts";
14
- export { verifyLockIntegrity } from "./verify.ts";
15
- export { detectOrphanedGeneratedFiles } from "./orphans.ts";
16
- export {
17
- serializeAppGraphJson,
18
- serializeAppGraphTs,
19
- serializePackageGraphJson,
20
- serializePackageGraphTs,
21
- serializeRuntimeMatrixJson,
22
- serializeRuntimeMatrixTs,
23
- serializeImportGuardsJson,
24
- serializeImportGuardsTs,
25
- type ImportGuardsArtifact,
26
- } from "./serialize.ts";
27
- export { buildImportGuardsArtifact } from "../guards/artifacts.ts";
1
+ export type {
2
+ DiscoverContext,
3
+ OrchestratorManifest,
4
+ } from "./types.ts";
5
+ export { ORCHESTRATOR_MANIFEST_VERSION } from "./types.ts";
6
+ export { discover, type DiscoverOptions } from "./discover.ts";
7
+ export { plan, type PlanInput } from "./plan.ts";
8
+ export {
9
+ run,
10
+ createGenerationOrchestrator,
11
+ type GenerationOrchestrator,
12
+ } from "./run.ts";
13
+ export { loadManifest, saveManifest, updateManifestAfterWrite } from "./manifest.ts";
14
+ export { verifyLockIntegrity } from "./verify.ts";
15
+ export { detectOrphanedGeneratedFiles } from "./orphans.ts";
16
+ export {
17
+ serializeAppGraphJson,
18
+ serializeAppGraphTs,
19
+ serializePackageGraphJson,
20
+ serializePackageGraphTs,
21
+ serializeRuntimeMatrixJson,
22
+ serializeRuntimeMatrixTs,
23
+ serializeImportGuardsJson,
24
+ serializeImportGuardsTs,
25
+ type ImportGuardsArtifact,
26
+ } from "./serialize.ts";
27
+ export { buildImportGuardsArtifact } from "../guards/artifacts.ts";
@@ -1,89 +1,89 @@
1
- import { join } from "node:path";
2
- import { nodeFileSystem } from "../fs/index.ts";
3
- import type { AppGraph } from "../types/app-graph.ts";
4
- import { canonicalJson } from "../primitives/serialize.ts";
5
- import {
6
- ORCHESTRATOR_MANIFEST_VERSION,
7
- type OrchestratorManifest,
8
- } from "./types.ts";
9
-
10
- const MANIFEST_FILENAME = "manifest.json";
11
-
12
- export function manifestPath(cacheDir: string): string {
13
- return join(cacheDir, MANIFEST_FILENAME);
14
- }
15
-
16
- export function loadManifest(cacheDir: string): OrchestratorManifest {
17
- nodeFileSystem.mkdirp(cacheDir);
18
- const path = manifestPath(cacheDir);
19
-
20
- const raw = nodeFileSystem.readText(path);
21
- if (raw !== null) {
22
- try {
23
- const parsed = JSON.parse(raw) as OrchestratorManifest;
24
- return {
25
- schemaVersion: parsed.schemaVersion ?? ORCHESTRATOR_MANIFEST_VERSION,
26
- fileHashes: parsed.fileHashes ?? {},
27
- ...(parsed.priorAppGraph !== undefined
28
- ? { priorAppGraph: parsed.priorAppGraph }
29
- : {}),
30
- ...(parsed.inputFingerprint !== undefined
31
- ? { inputFingerprint: parsed.inputFingerprint }
32
- : {}),
1
+ import { join } from "node:path";
2
+ import { nodeFileSystem } from "../fs/index.ts";
3
+ import type { AppGraph } from "../types/app-graph.ts";
4
+ import { canonicalJson } from "../primitives/serialize.ts";
5
+ import {
6
+ ORCHESTRATOR_MANIFEST_VERSION,
7
+ type OrchestratorManifest,
8
+ } from "./types.ts";
9
+
10
+ const MANIFEST_FILENAME = "manifest.json";
11
+
12
+ export function manifestPath(cacheDir: string): string {
13
+ return join(cacheDir, MANIFEST_FILENAME);
14
+ }
15
+
16
+ export function loadManifest(cacheDir: string): OrchestratorManifest {
17
+ nodeFileSystem.mkdirp(cacheDir);
18
+ const path = manifestPath(cacheDir);
19
+
20
+ const raw = nodeFileSystem.readText(path);
21
+ if (raw !== null) {
22
+ try {
23
+ const parsed = JSON.parse(raw) as OrchestratorManifest;
24
+ return {
25
+ schemaVersion: parsed.schemaVersion ?? ORCHESTRATOR_MANIFEST_VERSION,
26
+ fileHashes: parsed.fileHashes ?? {},
27
+ ...(parsed.priorAppGraph !== undefined
28
+ ? { priorAppGraph: parsed.priorAppGraph }
29
+ : {}),
30
+ ...(parsed.inputFingerprint !== undefined
31
+ ? { inputFingerprint: parsed.inputFingerprint }
32
+ : {}),
33
33
  ...(parsed.sourceFileIndex !== undefined
34
34
  ? { sourceFileIndex: parsed.sourceFileIndex }
35
35
  : {}),
36
36
  ...(parsed.sourceSnapshot !== undefined
37
37
  ? { sourceSnapshot: parsed.sourceSnapshot }
38
38
  : {}),
39
- };
40
- } catch {
41
- // fall through to the default manifest below
42
- }
43
- }
44
- return {
45
- schemaVersion: ORCHESTRATOR_MANIFEST_VERSION,
46
- fileHashes: {},
47
- };
48
- }
49
-
50
- export function saveManifest(
51
- cacheDir: string,
52
- manifest: OrchestratorManifest,
53
- ): void {
54
- const path = manifestPath(cacheDir);
55
-
56
- const payload: OrchestratorManifest = {
57
- schemaVersion: ORCHESTRATOR_MANIFEST_VERSION,
58
- fileHashes: manifest.fileHashes,
59
- ...(manifest.priorAppGraph !== undefined
60
- ? { priorAppGraph: manifest.priorAppGraph }
61
- : {}),
62
- ...(manifest.inputFingerprint !== undefined
63
- ? { inputFingerprint: manifest.inputFingerprint }
64
- : {}),
39
+ };
40
+ } catch {
41
+ // fall through to the default manifest below
42
+ }
43
+ }
44
+ return {
45
+ schemaVersion: ORCHESTRATOR_MANIFEST_VERSION,
46
+ fileHashes: {},
47
+ };
48
+ }
49
+
50
+ export function saveManifest(
51
+ cacheDir: string,
52
+ manifest: OrchestratorManifest,
53
+ ): void {
54
+ const path = manifestPath(cacheDir);
55
+
56
+ const payload: OrchestratorManifest = {
57
+ schemaVersion: ORCHESTRATOR_MANIFEST_VERSION,
58
+ fileHashes: manifest.fileHashes,
59
+ ...(manifest.priorAppGraph !== undefined
60
+ ? { priorAppGraph: manifest.priorAppGraph }
61
+ : {}),
62
+ ...(manifest.inputFingerprint !== undefined
63
+ ? { inputFingerprint: manifest.inputFingerprint }
64
+ : {}),
65
65
  ...(manifest.sourceFileIndex !== undefined
66
66
  ? { sourceFileIndex: manifest.sourceFileIndex }
67
67
  : {}),
68
68
  ...(manifest.sourceSnapshot !== undefined
69
69
  ? { sourceSnapshot: manifest.sourceSnapshot }
70
70
  : {}),
71
- };
72
-
73
- nodeFileSystem.writeText(path, `${canonicalJson(payload)}\n`);
74
- }
75
-
76
- export function updateManifestAfterWrite(
77
- manifest: OrchestratorManifest,
78
- fileHashes: Record<string, string>,
71
+ };
72
+
73
+ nodeFileSystem.writeText(path, `${canonicalJson(payload)}\n`);
74
+ }
75
+
76
+ export function updateManifestAfterWrite(
77
+ manifest: OrchestratorManifest,
78
+ fileHashes: Record<string, string>,
79
79
  priorAppGraph: AppGraph,
80
80
  inputFingerprint: string,
81
81
  sourceFileIndex?: OrchestratorManifest["sourceFileIndex"],
82
82
  sourceSnapshot?: OrchestratorManifest["sourceSnapshot"],
83
83
  ): OrchestratorManifest {
84
- return {
85
- ...manifest,
86
- fileHashes: { ...manifest.fileHashes, ...fileHashes },
84
+ return {
85
+ ...manifest,
86
+ fileHashes: { ...manifest.fileHashes, ...fileHashes },
87
87
  priorAppGraph,
88
88
  inputFingerprint,
89
89
  ...(sourceFileIndex !== undefined ? { sourceFileIndex } : {}),