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,46 +1,46 @@
1
- import type { PackageCacheKey } from "../types/lock.ts";
2
- import { hashStable } from "../primitives/hash.ts";
3
- import { canonicalJson } from "../primitives/serialize.ts";
4
-
5
- export function buildPackageCacheKey(
6
- input: PackageCacheKey,
7
- ): PackageCacheKey {
8
- return {
9
- name: input.name,
10
- version: input.version,
11
- packageManager: input.packageManager,
12
- ...(input.packageIntegrity !== undefined
13
- ? { packageIntegrity: input.packageIntegrity }
14
- : {}),
15
- packageJsonHash: input.packageJsonHash,
16
- dtsFilesHash: input.dtsFilesHash,
17
- analyzerVersion: input.analyzerVersion,
18
- typescriptVersion: input.typescriptVersion,
19
- resolutionMode: input.resolutionMode,
20
- ...(input.recipeVersion !== undefined
21
- ? { recipeVersion: input.recipeVersion }
22
- : {}),
23
- };
24
- }
25
-
26
- export function serializePackageCacheKey(key: PackageCacheKey): string {
27
- return canonicalJson(key);
28
- }
29
-
30
- export function fingerprintPackageCacheKey(key: PackageCacheKey): string {
31
- return hashStable(serializePackageCacheKey(key));
32
- }
33
-
34
- export function cacheKeysEqual(
35
- a: PackageCacheKey,
36
- b: PackageCacheKey,
37
- ): boolean {
38
- return serializePackageCacheKey(a) === serializePackageCacheKey(b);
39
- }
40
-
41
- /**
42
- * Global lockfile hash is informational and intentionally excluded from cache keys.
43
- */
44
- export function lockfileHashAffectsCache(_lockfileHash: string): boolean {
45
- return false;
46
- }
1
+ import type { PackageCacheKey } from "../types/lock.ts";
2
+ import { hashStable } from "../primitives/hash.ts";
3
+ import { canonicalJson } from "../primitives/serialize.ts";
4
+
5
+ export function buildPackageCacheKey(
6
+ input: PackageCacheKey,
7
+ ): PackageCacheKey {
8
+ return {
9
+ name: input.name,
10
+ version: input.version,
11
+ packageManager: input.packageManager,
12
+ ...(input.packageIntegrity !== undefined
13
+ ? { packageIntegrity: input.packageIntegrity }
14
+ : {}),
15
+ packageJsonHash: input.packageJsonHash,
16
+ dtsFilesHash: input.dtsFilesHash,
17
+ analyzerVersion: input.analyzerVersion,
18
+ typescriptVersion: input.typescriptVersion,
19
+ resolutionMode: input.resolutionMode,
20
+ ...(input.recipeVersion !== undefined
21
+ ? { recipeVersion: input.recipeVersion }
22
+ : {}),
23
+ };
24
+ }
25
+
26
+ export function serializePackageCacheKey(key: PackageCacheKey): string {
27
+ return canonicalJson(key);
28
+ }
29
+
30
+ export function fingerprintPackageCacheKey(key: PackageCacheKey): string {
31
+ return hashStable(serializePackageCacheKey(key));
32
+ }
33
+
34
+ export function cacheKeysEqual(
35
+ a: PackageCacheKey,
36
+ b: PackageCacheKey,
37
+ ): boolean {
38
+ return serializePackageCacheKey(a) === serializePackageCacheKey(b);
39
+ }
40
+
41
+ /**
42
+ * Global lockfile hash is informational and intentionally excluded from cache keys.
43
+ */
44
+ export function lockfileHashAffectsCache(_lockfileHash: string): boolean {
45
+ return false;
46
+ }
@@ -1,72 +1,72 @@
1
- export async function runWithConcurrency<T, R>(
2
- items: T[],
3
- concurrency: number,
4
- worker: (item: T, index: number) => Promise<R> | R,
5
- ): Promise<R[]> {
6
- const limit = Math.max(1, Math.floor(concurrency));
7
- if (items.length === 0) {
8
- return [];
9
- }
10
-
11
- if (limit === 1) {
12
- const sequential: R[] = [];
13
- for (let index = 0; index < items.length; index++) {
14
- sequential.push(await worker(items[index]!, index));
15
- }
16
- return sequential;
17
- }
18
-
19
- const results = new Array<R>(items.length);
20
- let nextIndex = 0;
21
-
22
- async function runWorker(): Promise<void> {
23
- while (true) {
24
- const index = nextIndex;
25
- nextIndex += 1;
26
- if (index >= items.length) {
27
- return;
28
- }
29
- results[index] = await worker(items[index]!, index);
30
- }
31
- }
32
-
33
- const workers = Array.from({ length: Math.min(limit, items.length) }, () =>
34
- runWorker(),
35
- );
36
- await Promise.all(workers);
37
- return results;
38
- }
39
-
40
- export class ConcurrencyTracker {
41
- current = 0;
42
- maxObserved = 0;
43
-
44
- enter(): void {
45
- this.current += 1;
46
- if (this.current > this.maxObserved) {
47
- this.maxObserved = this.current;
48
- }
49
- }
50
-
51
- leave(): void {
52
- this.current -= 1;
53
- }
54
- }
55
-
56
- export async function runWithConcurrencyTracked<T, R>(
57
- items: T[],
58
- concurrency: number,
59
- worker: (item: T, index: number) => Promise<R> | R,
60
- tracker: ConcurrencyTracker,
61
- ): Promise<R[]> {
62
- const limit = Math.max(1, Math.floor(concurrency));
63
-
64
- return runWithConcurrency(items, limit, async (item, index) => {
65
- tracker.enter();
66
- try {
67
- return await worker(item, index);
68
- } finally {
69
- tracker.leave();
70
- }
71
- });
72
- }
1
+ export async function runWithConcurrency<T, R>(
2
+ items: T[],
3
+ concurrency: number,
4
+ worker: (item: T, index: number) => Promise<R> | R,
5
+ ): Promise<R[]> {
6
+ const limit = Math.max(1, Math.floor(concurrency));
7
+ if (items.length === 0) {
8
+ return [];
9
+ }
10
+
11
+ if (limit === 1) {
12
+ const sequential: R[] = [];
13
+ for (let index = 0; index < items.length; index++) {
14
+ sequential.push(await worker(items[index]!, index));
15
+ }
16
+ return sequential;
17
+ }
18
+
19
+ const results = new Array<R>(items.length);
20
+ let nextIndex = 0;
21
+
22
+ async function runWorker(): Promise<void> {
23
+ while (true) {
24
+ const index = nextIndex;
25
+ nextIndex += 1;
26
+ if (index >= items.length) {
27
+ return;
28
+ }
29
+ results[index] = await worker(items[index]!, index);
30
+ }
31
+ }
32
+
33
+ const workers = Array.from({ length: Math.min(limit, items.length) }, () =>
34
+ runWorker(),
35
+ );
36
+ await Promise.all(workers);
37
+ return results;
38
+ }
39
+
40
+ export class ConcurrencyTracker {
41
+ current = 0;
42
+ maxObserved = 0;
43
+
44
+ enter(): void {
45
+ this.current += 1;
46
+ if (this.current > this.maxObserved) {
47
+ this.maxObserved = this.current;
48
+ }
49
+ }
50
+
51
+ leave(): void {
52
+ this.current -= 1;
53
+ }
54
+ }
55
+
56
+ export async function runWithConcurrencyTracked<T, R>(
57
+ items: T[],
58
+ concurrency: number,
59
+ worker: (item: T, index: number) => Promise<R> | R,
60
+ tracker: ConcurrencyTracker,
61
+ ): Promise<R[]> {
62
+ const limit = Math.max(1, Math.floor(concurrency));
63
+
64
+ return runWithConcurrency(items, limit, async (item, index) => {
65
+ tracker.enter();
66
+ try {
67
+ return await worker(item, index);
68
+ } finally {
69
+ tracker.leave();
70
+ }
71
+ });
72
+ }
@@ -1,78 +1,78 @@
1
- import { join } from "node:path";
2
- import { nodeFileSystem } from "../fs/index.ts";
3
- import type { PackageApi } from "../types/package-graph.ts";
4
- import type { PackageCacheKey } from "../types/lock.ts";
5
- import { canonicalJson } from "../primitives/serialize.ts";
6
- import {
7
- buildPackageCacheKey,
8
- cacheKeysEqual,
9
- fingerprintPackageCacheKey,
10
- serializePackageCacheKey,
11
- } from "./key.ts";
12
-
13
- export interface CacheEntry {
14
- key: PackageCacheKey;
15
- result: PackageApi;
16
- }
17
-
18
- export class PackageCacheStore {
19
- private readonly packagesDir: string;
20
-
21
- constructor(cacheDir: string) {
22
- this.packagesDir = join(cacheDir, "packages");
23
- nodeFileSystem.mkdirp(this.packagesDir);
24
- }
25
-
26
- private entryPath(key: PackageCacheKey): string {
27
- return join(this.packagesDir, `${fingerprintPackageCacheKey(key)}.json`);
28
- }
29
-
30
- getWithValidation(
31
- key: PackageCacheKey,
32
- ): { hit: PackageApi } | { miss: true } | { corrupt: true } {
33
- const normalizedKey = buildPackageCacheKey(key);
34
- const path = this.entryPath(normalizedKey);
35
-
36
- const raw = nodeFileSystem.readText(path);
37
- if (raw === null) {
38
- return { miss: true };
39
- }
40
-
41
- let entry: CacheEntry;
42
- try {
43
- entry = JSON.parse(raw) as CacheEntry;
44
- } catch {
45
- return { corrupt: true };
46
- }
47
-
48
- if (!cacheKeysEqual(entry.key, normalizedKey)) {
49
- return { corrupt: true };
50
- }
51
-
52
- return { hit: entry.result };
53
- }
54
-
55
- async put(key: PackageCacheKey, result: PackageApi): Promise<void> {
56
- const normalizedKey = buildPackageCacheKey(key);
57
- const path = this.entryPath(normalizedKey);
58
-
59
- const entry: CacheEntry = {
60
- key: normalizedKey,
61
- result,
62
- };
63
-
64
- nodeFileSystem.writeText(path, serializeCacheEntry(entry));
65
- }
66
-
67
- serializeKey(key: PackageCacheKey): string {
68
- return serializePackageCacheKey(key);
69
- }
70
- }
71
-
72
- function serializeCacheEntry(entry: CacheEntry): string {
73
- return `${canonicalJson(entry)}\n`;
74
- }
75
-
76
- export function forgeCacheDiscardedMessage(): string {
77
- return "cache entry was discarded due to read or integrity failure; recomputing analysis";
78
- }
1
+ import { join } from "node:path";
2
+ import { nodeFileSystem } from "../fs/index.ts";
3
+ import type { PackageApi } from "../types/package-graph.ts";
4
+ import type { PackageCacheKey } from "../types/lock.ts";
5
+ import { canonicalJson } from "../primitives/serialize.ts";
6
+ import {
7
+ buildPackageCacheKey,
8
+ cacheKeysEqual,
9
+ fingerprintPackageCacheKey,
10
+ serializePackageCacheKey,
11
+ } from "./key.ts";
12
+
13
+ export interface CacheEntry {
14
+ key: PackageCacheKey;
15
+ result: PackageApi;
16
+ }
17
+
18
+ export class PackageCacheStore {
19
+ private readonly packagesDir: string;
20
+
21
+ constructor(cacheDir: string) {
22
+ this.packagesDir = join(cacheDir, "packages");
23
+ nodeFileSystem.mkdirp(this.packagesDir);
24
+ }
25
+
26
+ private entryPath(key: PackageCacheKey): string {
27
+ return join(this.packagesDir, `${fingerprintPackageCacheKey(key)}.json`);
28
+ }
29
+
30
+ getWithValidation(
31
+ key: PackageCacheKey,
32
+ ): { hit: PackageApi } | { miss: true } | { corrupt: true } {
33
+ const normalizedKey = buildPackageCacheKey(key);
34
+ const path = this.entryPath(normalizedKey);
35
+
36
+ const raw = nodeFileSystem.readText(path);
37
+ if (raw === null) {
38
+ return { miss: true };
39
+ }
40
+
41
+ let entry: CacheEntry;
42
+ try {
43
+ entry = JSON.parse(raw) as CacheEntry;
44
+ } catch {
45
+ return { corrupt: true };
46
+ }
47
+
48
+ if (!cacheKeysEqual(entry.key, normalizedKey)) {
49
+ return { corrupt: true };
50
+ }
51
+
52
+ return { hit: entry.result };
53
+ }
54
+
55
+ async put(key: PackageCacheKey, result: PackageApi): Promise<void> {
56
+ const normalizedKey = buildPackageCacheKey(key);
57
+ const path = this.entryPath(normalizedKey);
58
+
59
+ const entry: CacheEntry = {
60
+ key: normalizedKey,
61
+ result,
62
+ };
63
+
64
+ nodeFileSystem.writeText(path, serializeCacheEntry(entry));
65
+ }
66
+
67
+ serializeKey(key: PackageCacheKey): string {
68
+ return serializePackageCacheKey(key);
69
+ }
70
+ }
71
+
72
+ function serializeCacheEntry(entry: CacheEntry): string {
73
+ return `${canonicalJson(entry)}\n`;
74
+ }
75
+
76
+ export function forgeCacheDiscardedMessage(): string {
77
+ return "cache entry was discarded due to read or integrity failure; recomputing analysis";
78
+ }
@@ -1,78 +1,78 @@
1
- import type { CapabilitySet } from "../types/capability.ts";
2
- import type { IntegrationRecipe } from "../types/integration.ts";
3
- import type { PackageApi } from "../types/package-graph.ts";
4
- import { capability, emptyCapabilitySet } from "../recipes/helpers.ts";
5
- import { gatherSignals } from "./signals.ts";
6
-
7
- export function detectCapabilities(
8
- api: PackageApi,
9
- recipe?: IntegrationRecipe,
10
- ): CapabilitySet {
11
- if (recipe) {
12
- return cloneCapabilitySet(recipe.capabilities);
13
- }
14
-
15
- const signals = gatherSignals(api);
16
- const caps = emptyCapabilitySet();
17
-
18
- if (signals.usesNetwork) {
19
- caps.network = capability<{ egress?: string[] }>(
20
- "required",
21
- "static",
22
- signals.networkEvidence,
23
- );
24
- } else {
25
- caps.network = capability<{ egress?: string[] }>("unknown", "static", [
26
- "static analysis cannot prove absence of network access",
27
- ]);
28
- }
29
-
30
- if (signals.usesFilesystem) {
31
- caps.filesystem = capability<{ read?: boolean; write?: boolean }>(
32
- "required",
33
- "static",
34
- signals.filesystemEvidence,
35
- {
36
- read: true,
37
- write: signals.filesystemEvidence.some((e) => /write/i.test(e)),
38
- },
39
- );
40
- } else {
41
- caps.filesystem = capability<{ read?: boolean; write?: boolean }>(
42
- "unknown",
43
- "static",
44
- ["static analysis cannot prove absence of filesystem access"],
45
- );
46
- }
47
-
48
- if (signals.usesProcess) {
49
- caps.process = capability("required", "static", signals.processEvidence);
50
- } else {
51
- caps.process = capability("unknown", "static", [
52
- "static analysis cannot prove absence of process access",
53
- ]);
54
- }
55
-
56
- if (signals.usesNativeAddon) {
57
- caps.nativeAddon = capability("required", "static", signals.nativeAddonEvidence);
58
- } else {
59
- caps.nativeAddon = capability("not-detected", "static", ["no native addon signals"]);
60
- }
61
-
62
- caps.lifecycleScripts = capability("not-detected", "rule", [
63
- "forge add disables lifecycle scripts by default",
64
- ]);
65
-
66
- return caps;
67
- }
68
-
69
- function cloneCapabilitySet(source: CapabilitySet): CapabilitySet {
70
- return {
71
- network: { ...source.network },
72
- filesystem: { ...source.filesystem },
73
- process: { ...source.process },
74
- nativeAddon: { ...source.nativeAddon },
75
- lifecycleScripts: { ...source.lifecycleScripts },
76
- secrets: [...source.secrets],
77
- };
78
- }
1
+ import type { CapabilitySet } from "../types/capability.ts";
2
+ import type { IntegrationRecipe } from "../types/integration.ts";
3
+ import type { PackageApi } from "../types/package-graph.ts";
4
+ import { capability, emptyCapabilitySet } from "../recipes/helpers.ts";
5
+ import { gatherSignals } from "./signals.ts";
6
+
7
+ export function detectCapabilities(
8
+ api: PackageApi,
9
+ recipe?: IntegrationRecipe,
10
+ ): CapabilitySet {
11
+ if (recipe) {
12
+ return cloneCapabilitySet(recipe.capabilities);
13
+ }
14
+
15
+ const signals = gatherSignals(api);
16
+ const caps = emptyCapabilitySet();
17
+
18
+ if (signals.usesNetwork) {
19
+ caps.network = capability<{ egress?: string[] }>(
20
+ "required",
21
+ "static",
22
+ signals.networkEvidence,
23
+ );
24
+ } else {
25
+ caps.network = capability<{ egress?: string[] }>("unknown", "static", [
26
+ "static analysis cannot prove absence of network access",
27
+ ]);
28
+ }
29
+
30
+ if (signals.usesFilesystem) {
31
+ caps.filesystem = capability<{ read?: boolean; write?: boolean }>(
32
+ "required",
33
+ "static",
34
+ signals.filesystemEvidence,
35
+ {
36
+ read: true,
37
+ write: signals.filesystemEvidence.some((e) => /write/i.test(e)),
38
+ },
39
+ );
40
+ } else {
41
+ caps.filesystem = capability<{ read?: boolean; write?: boolean }>(
42
+ "unknown",
43
+ "static",
44
+ ["static analysis cannot prove absence of filesystem access"],
45
+ );
46
+ }
47
+
48
+ if (signals.usesProcess) {
49
+ caps.process = capability("required", "static", signals.processEvidence);
50
+ } else {
51
+ caps.process = capability("unknown", "static", [
52
+ "static analysis cannot prove absence of process access",
53
+ ]);
54
+ }
55
+
56
+ if (signals.usesNativeAddon) {
57
+ caps.nativeAddon = capability("required", "static", signals.nativeAddonEvidence);
58
+ } else {
59
+ caps.nativeAddon = capability("not-detected", "static", ["no native addon signals"]);
60
+ }
61
+
62
+ caps.lifecycleScripts = capability("not-detected", "rule", [
63
+ "forge add disables lifecycle scripts by default",
64
+ ]);
65
+
66
+ return caps;
67
+ }
68
+
69
+ function cloneCapabilitySet(source: CapabilitySet): CapabilitySet {
70
+ return {
71
+ network: { ...source.network },
72
+ filesystem: { ...source.filesystem },
73
+ process: { ...source.process },
74
+ nativeAddon: { ...source.nativeAddon },
75
+ lifecycleScripts: { ...source.lifecycleScripts },
76
+ secrets: [...source.secrets],
77
+ };
78
+ }