forgeos 0.1.0-alpha.65 → 0.1.0-alpha.67

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 (284) hide show
  1. package/.npmignore +19 -19
  2. package/AGENTS.md +1 -1
  3. package/CHANGELOG.md +24 -0
  4. package/LICENSE +21 -21
  5. package/README.md +525 -525
  6. package/adapters/java/README.md +68 -68
  7. package/adapters/java/pom.xml +47 -47
  8. package/adapters/java/src/main/java/dev/forgeos/adapter/Auth.java +20 -20
  9. package/adapters/java/src/main/java/dev/forgeos/adapter/Diagnostic.java +16 -16
  10. package/adapters/java/src/main/java/dev/forgeos/adapter/Entry.java +38 -38
  11. package/adapters/java/src/main/java/dev/forgeos/adapter/EntryKind.java +16 -16
  12. package/adapters/java/src/main/java/dev/forgeos/adapter/ErrorInfo.java +4 -4
  13. package/adapters/java/src/main/java/dev/forgeos/adapter/Forge.java +94 -94
  14. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeCall.java +12 -12
  15. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeContext.java +11 -11
  16. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHandler.java +8 -8
  17. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHttpHandler.java +179 -179
  18. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeRegistry.java +121 -121
  19. package/adapters/java/src/main/java/dev/forgeos/adapter/Json.java +14 -14
  20. package/adapters/java/src/main/java/dev/forgeos/adapter/Manifest.java +14 -14
  21. package/adapters/java/src/main/java/dev/forgeos/adapter/RequestEnvelope.java +6 -6
  22. package/adapters/java/src/main/java/dev/forgeos/adapter/ResponseEnvelope.java +25 -25
  23. package/adapters/java/src/main/java/dev/forgeos/adapter/Risk.java +18 -18
  24. package/adapters/java/src/main/java/dev/forgeos/adapter/Schemas.java +36 -36
  25. package/adapters/java/src/main/java/dev/forgeos/adapter/Service.java +65 -65
  26. package/adapters/java/src/main/java/dev/forgeos/adapter/TransactionMode.java +18 -18
  27. package/adapters/java/src/main/java/dev/forgeos/adapter/TypedForgeHandler.java +6 -6
  28. package/adapters/java-spring-boot-starter/README.md +32 -32
  29. package/adapters/java-spring-boot-starter/pom.xml +49 -49
  30. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeCommand.java +22 -22
  31. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeExternalService.java +15 -15
  32. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeQuery.java +16 -16
  33. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeServiceBeanCondition.java +18 -18
  34. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringAutoConfiguration.java +16 -16
  35. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringRuntime.java +104 -104
  36. package/adapters/java-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +1 -1
  37. package/bin/forge.mjs +38 -38
  38. package/docs/agent-fabric.md +131 -0
  39. package/examples/java-billing/pom.xml +60 -60
  40. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/CreateInvoiceInput.java +4 -4
  41. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Invoice.java +11 -11
  42. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Main.java +127 -127
  43. package/package.json +5 -4
  44. package/packages/eslint-plugin-forge/index.ts +15 -15
  45. package/packages/eslint-plugin-forge/package.json +10 -10
  46. package/packages/eslint-plugin-forge/src/check-source.ts +95 -95
  47. package/packages/eslint-plugin-forge/src/load-artifacts.ts +24 -24
  48. package/packages/eslint-plugin-forge/src/rule-no-forge-guard-violation.ts +93 -93
  49. package/schemas/agent-fabric/v0.1/control-event.schema.json +281 -281
  50. package/scripts/field-test-forgeos.mjs +1021 -1021
  51. package/src/forge/_generated/releaseManifest.json +1 -1
  52. package/src/forge/_generated/releaseManifest.ts +3 -3
  53. package/src/forge/agent-adapters/index.ts +7 -3
  54. package/src/forge/agent-adapters/types.ts +1 -0
  55. package/src/forge/agent-fabric/attached-snapshot.ts +55 -0
  56. package/src/forge/agent-fabric/attached-task-contract.ts +105 -0
  57. package/src/forge/agent-fabric/attached-task-service.ts +127 -0
  58. package/src/forge/agent-fabric/attached-task-store.ts +109 -0
  59. package/src/forge/agent-fabric/codex-adversarial-review.ts +229 -0
  60. package/src/forge/agent-fabric/codex-sdk-worker.ts +163 -0
  61. package/src/forge/agent-fabric/index.ts +19 -0
  62. package/src/forge/agent-fabric/local-adaptive-digest-worker.mjs +26 -26
  63. package/src/forge/agent-fabric/local-change-review-service.ts +374 -0
  64. package/src/forge/agent-fabric/local-task-server.ts +324 -249
  65. package/src/forge/agent-fabric/managed-environment.ts +205 -0
  66. package/src/forge/agent-fabric/managed-run-contract.ts +102 -0
  67. package/src/forge/agent-fabric/managed-run-service.ts +392 -0
  68. package/src/forge/agent-fabric/managed-run-store.ts +135 -0
  69. package/src/forge/agent-fabric/managed-workspace.ts +214 -0
  70. package/src/forge/agent-fabric/readiness.ts +26 -0
  71. package/src/forge/agent-fabric/workflow-engine.ts +218 -0
  72. package/src/forge/agent-fabric/workflow-task-actions.ts +104 -0
  73. package/src/forge/agent-fabric/workflow-templates.ts +11 -0
  74. package/src/forge/agent-memory/bridge.ts +309 -47
  75. package/src/forge/agent-memory/context-pack.ts +8 -1
  76. package/src/forge/agent-memory/hook-runner.ts +38 -19
  77. package/src/forge/agent-memory/mcp.ts +500 -286
  78. package/src/forge/agent-memory/sources/codex-hook-runner.mjs +343 -234
  79. package/src/forge/agent-memory/sources/codex.ts +49 -7
  80. package/src/forge/agent-memory/types.ts +11 -0
  81. package/src/forge/bench.ts +154 -154
  82. package/src/forge/cair/action-journal.ts +61 -61
  83. package/src/forge/cair/action-parser.ts +314 -314
  84. package/src/forge/cair/action-validator.ts +40 -40
  85. package/src/forge/cair/actions.ts +1818 -1818
  86. package/src/forge/cair/format.ts +77 -77
  87. package/src/forge/cair/index.ts +106 -106
  88. package/src/forge/cair/query.ts +478 -478
  89. package/src/forge/cair/snapshot.ts +315 -315
  90. package/src/forge/cair/types.ts +248 -248
  91. package/src/forge/cli/ai.ts +816 -816
  92. package/src/forge/cli/codex-app-server.ts +877 -877
  93. package/src/forge/cli/fabric.ts +205 -131
  94. package/src/forge/cli/index.ts +26 -26
  95. package/src/forge/cli/main.ts +259 -245
  96. package/src/forge/cli/next-actions.ts +23 -23
  97. package/src/forge/cli/parse.ts +3574 -3542
  98. package/src/forge/cli/release.ts +309 -309
  99. package/src/forge/cli/self-host.ts +510 -510
  100. package/src/forge/compiler/ai-registry/parse.ts +219 -219
  101. package/src/forge/compiler/app-graph/classify.ts +10 -10
  102. package/src/forge/compiler/app-graph/dup-symbol.ts +29 -29
  103. package/src/forge/compiler/app-graph/extract.ts +231 -231
  104. package/src/forge/compiler/app-graph/forge-apis.ts +25 -25
  105. package/src/forge/compiler/app-graph/index.ts +11 -11
  106. package/src/forge/compiler/app-graph/module-graph.ts +151 -151
  107. package/src/forge/compiler/app-graph/parser.ts +71 -71
  108. package/src/forge/compiler/app-graph/symbols.ts +48 -48
  109. package/src/forge/compiler/app-graph/types.ts +43 -43
  110. package/src/forge/compiler/app-graph/versions.ts +14 -14
  111. package/src/forge/compiler/cache/index.ts +17 -17
  112. package/src/forge/compiler/cache/key.ts +46 -46
  113. package/src/forge/compiler/cache/scheduler.ts +72 -72
  114. package/src/forge/compiler/cache/store.ts +78 -78
  115. package/src/forge/compiler/classifier/capabilities.ts +64 -64
  116. package/src/forge/compiler/classifier/classify.ts +76 -76
  117. package/src/forge/compiler/classifier/contexts.ts +188 -188
  118. package/src/forge/compiler/classifier/index.ts +18 -18
  119. package/src/forge/compiler/classifier/runtime-matrix.ts +45 -45
  120. package/src/forge/compiler/classifier/secrets.ts +31 -31
  121. package/src/forge/compiler/classifier/signals.ts +95 -95
  122. package/src/forge/compiler/client-sdk/build-manifest.ts +210 -210
  123. package/src/forge/compiler/data-graph/sql/serialize.ts +89 -89
  124. package/src/forge/compiler/data-graph/sql/types.ts +38 -38
  125. package/src/forge/compiler/diagnostics/index.ts +57 -57
  126. package/src/forge/compiler/emitter/artifact-kind.ts +14 -14
  127. package/src/forge/compiler/emitter/barrel.ts +47 -47
  128. package/src/forge/compiler/emitter/constants.ts +7 -7
  129. package/src/forge/compiler/emitter/emit.ts +223 -223
  130. package/src/forge/compiler/emitter/index.ts +24 -24
  131. package/src/forge/compiler/emitter/lock.ts +61 -61
  132. package/src/forge/compiler/external-manifest/registry.ts +205 -205
  133. package/src/forge/compiler/external-manifest/types.ts +91 -91
  134. package/src/forge/compiler/external-manifest/validate.ts +373 -373
  135. package/src/forge/compiler/frontend-graph/build.ts +623 -623
  136. package/src/forge/compiler/guards/artifacts.ts +96 -96
  137. package/src/forge/compiler/guards/check-import-guards.ts +106 -106
  138. package/src/forge/compiler/guards/index.ts +11 -11
  139. package/src/forge/compiler/guards/propagate-contexts.ts +57 -57
  140. package/src/forge/compiler/index.ts +17 -17
  141. package/src/forge/compiler/integration/index.ts +17 -17
  142. package/src/forge/compiler/integration/snapshot.ts +54 -54
  143. package/src/forge/compiler/integration/templates/convex.ts +70 -70
  144. package/src/forge/compiler/orchestrator/discover.ts +214 -214
  145. package/src/forge/compiler/orchestrator/guards.ts +5 -5
  146. package/src/forge/compiler/orchestrator/index.ts +27 -27
  147. package/src/forge/compiler/orchestrator/orphans.ts +51 -51
  148. package/src/forge/compiler/orchestrator/profile.ts +23 -23
  149. package/src/forge/compiler/orchestrator/serialize.ts +979 -979
  150. package/src/forge/compiler/orchestrator/verify.ts +35 -35
  151. package/src/forge/compiler/package-graph/capabilities-stub.ts +33 -33
  152. package/src/forge/compiler/package-graph/checksum.ts +107 -107
  153. package/src/forge/compiler/package-graph/exports-discovery.ts +91 -91
  154. package/src/forge/compiler/package-graph/extract-dts.ts +32 -32
  155. package/src/forge/compiler/package-graph/index.ts +24 -24
  156. package/src/forge/compiler/package-graph/jsdoc.ts +50 -50
  157. package/src/forge/compiler/package-graph/oracle.ts +326 -326
  158. package/src/forge/compiler/package-graph/read-file.ts +21 -21
  159. package/src/forge/compiler/package-graph/resolve.ts +131 -131
  160. package/src/forge/compiler/package-manager/adapter.ts +240 -240
  161. package/src/forge/compiler/package-manager/commands.ts +51 -51
  162. package/src/forge/compiler/package-manager/detect.ts +65 -65
  163. package/src/forge/compiler/package-manager/executor.ts +146 -146
  164. package/src/forge/compiler/package-manager/index.ts +22 -22
  165. package/src/forge/compiler/package-manager/parse-spec.ts +16 -16
  166. package/src/forge/compiler/primitives/compare.ts +26 -26
  167. package/src/forge/compiler/primitives/hash.ts +29 -29
  168. package/src/forge/compiler/primitives/header.ts +43 -43
  169. package/src/forge/compiler/primitives/index.ts +45 -45
  170. package/src/forge/compiler/primitives/paths.ts +24 -24
  171. package/src/forge/compiler/primitives/serialize.ts +66 -66
  172. package/src/forge/compiler/primitives/sort.ts +87 -87
  173. package/src/forge/compiler/recipes/helpers.ts +37 -37
  174. package/src/forge/compiler/sandbox/artifact-sanitize.ts +26 -26
  175. package/src/forge/compiler/sandbox/backends/child.ts +123 -123
  176. package/src/forge/compiler/sandbox/backends/docker.ts +173 -173
  177. package/src/forge/compiler/sandbox/index.ts +51 -51
  178. package/src/forge/compiler/sandbox/inspect.ts +143 -143
  179. package/src/forge/compiler/sandbox/inspector-entry.ts +115 -115
  180. package/src/forge/compiler/sandbox/limits.ts +31 -31
  181. package/src/forge/compiler/sandbox/scrub-env.ts +60 -60
  182. package/src/forge/compiler/sandbox/secret-scan.ts +54 -54
  183. package/src/forge/compiler/sandbox/serialize.ts +106 -106
  184. package/src/forge/compiler/sandbox/types.ts +7 -7
  185. package/src/forge/compiler/test-graph/build.ts +285 -285
  186. package/src/forge/compiler/types/app-graph.ts +87 -87
  187. package/src/forge/compiler/types/capability.ts +29 -29
  188. package/src/forge/compiler/types/classification.ts +9 -9
  189. package/src/forge/compiler/types/diagnostic.ts +2 -2
  190. package/src/forge/compiler/types/frontend-graph.ts +81 -81
  191. package/src/forge/compiler/types/import-guards.ts +19 -19
  192. package/src/forge/compiler/types/index.ts +98 -98
  193. package/src/forge/compiler/types/json.ts +3 -3
  194. package/src/forge/compiler/types/lock.ts +37 -37
  195. package/src/forge/compiler/types/runtime-matrix.ts +16 -16
  196. package/src/forge/compiler/types/runtime.ts +30 -30
  197. package/src/forge/compiler/types/sandbox.ts +24 -24
  198. package/src/forge/delta/broker-runner.mjs +5 -0
  199. package/src/forge/delta/broker.ts +429 -0
  200. package/src/forge/delta/classifier.ts +52 -52
  201. package/src/forge/delta/explain.ts +238 -238
  202. package/src/forge/delta/git-observer.ts +24 -0
  203. package/src/forge/delta/ids.ts +40 -40
  204. package/src/forge/delta/index.ts +25 -25
  205. package/src/forge/delta/process-identity.ts +31 -0
  206. package/src/forge/delta/queue-status.ts +190 -0
  207. package/src/forge/delta/redaction.ts +50 -50
  208. package/src/forge/delta/schema.ts +135 -135
  209. package/src/forge/delta/session.ts +142 -142
  210. package/src/forge/delta/status.ts +82 -145
  211. package/src/forge/delta/store.ts +77 -32
  212. package/src/forge/delta/timeline.ts +178 -178
  213. package/src/forge/dev/types.ts +63 -63
  214. package/src/forge/dev/watch.ts +119 -119
  215. package/src/forge/intent/index.ts +509 -509
  216. package/src/forge/make/types.ts +153 -153
  217. package/src/forge/refactor/index.ts +1937 -1937
  218. package/src/forge/refactor/runtime-rename.ts +598 -598
  219. package/src/forge/repair/rules/index.ts +476 -476
  220. package/src/forge/review/types.ts +211 -211
  221. package/src/forge/runtime/db/generated-client.ts +305 -305
  222. package/src/forge/runtime/db/pglite-adapter.ts +33 -11
  223. package/src/forge/runtime/runner/run-entry.ts +236 -236
  224. package/src/forge/version.ts +1 -1
  225. package/templates/agent-workroom/AGENTS.md +29 -29
  226. package/templates/agent-workroom/README.md +34 -34
  227. package/templates/agent-workroom/forge.config.ts +3 -3
  228. package/templates/agent-workroom/package.json +34 -34
  229. package/templates/agent-workroom/pnpm-workspace.yaml +2 -2
  230. package/templates/agent-workroom/src/actions/indexAgentSignal.ts +10 -10
  231. package/templates/agent-workroom/src/commands/openWorkroom.ts +61 -61
  232. package/templates/agent-workroom/src/commands/recordAgentSignal.ts +119 -119
  233. package/templates/agent-workroom/src/commands/recordCheckRun.ts +52 -52
  234. package/templates/agent-workroom/src/forge/schema.ts +54 -54
  235. package/templates/agent-workroom/src/policies.ts +6 -6
  236. package/templates/agent-workroom/src/queries/listWorkrooms.ts +11 -11
  237. package/templates/agent-workroom/src/queries/liveWorkroom.ts +63 -63
  238. package/templates/agent-workroom/tsconfig.json +16 -16
  239. package/templates/agent-workroom/web/index.html +13 -13
  240. package/templates/agent-workroom/web/package.json +21 -21
  241. package/templates/agent-workroom/web/src/App.tsx +345 -345
  242. package/templates/agent-workroom/web/src/main.tsx +13 -13
  243. package/templates/agent-workroom/web/src/styles.css +545 -545
  244. package/templates/agent-workroom/web/tsconfig.json +27 -27
  245. package/templates/b2b-support-web/package.json +37 -37
  246. package/templates/b2b-support-web/pnpm-workspace.yaml +2 -2
  247. package/templates/b2b-support-web/web/package.json +21 -21
  248. package/templates/minimal-web/package.json +34 -34
  249. package/templates/minimal-web/pnpm-workspace.yaml +2 -2
  250. package/templates/minimal-web/web/index.html +13 -13
  251. package/templates/minimal-web/web/src/styles.css +190 -190
  252. package/templates/nuxt-web/.vscode/settings.json +14 -14
  253. package/templates/nuxt-web/.yarnrc.yml +1 -1
  254. package/templates/nuxt-web/README.md +30 -30
  255. package/templates/nuxt-web/forge.config.ts +3 -3
  256. package/templates/nuxt-web/package.json +34 -34
  257. package/templates/nuxt-web/pnpm-workspace.yaml +2 -2
  258. package/templates/nuxt-web/src/actions/logNoteCreated.ts +11 -11
  259. package/templates/nuxt-web/src/commands/createNote.ts +26 -26
  260. package/templates/nuxt-web/src/forge/schema.ts +12 -12
  261. package/templates/nuxt-web/src/policies.ts +6 -6
  262. package/templates/nuxt-web/src/queries/listNotes.ts +8 -8
  263. package/templates/nuxt-web/src/queries/liveNotes.ts +8 -8
  264. package/templates/nuxt-web/tsconfig.json +17 -17
  265. package/templates/nuxt-web/web/app.vue +67 -67
  266. package/templates/nuxt-web/web/components/LiveNotes.vue +89 -89
  267. package/templates/nuxt-web/web/components/NoteComposer.vue +100 -100
  268. package/templates/nuxt-web/web/composables/forge.ts +13 -13
  269. package/templates/nuxt-web/web/composables/useNotes.ts +24 -24
  270. package/templates/nuxt-web/web/nuxt.config.ts +11 -11
  271. package/templates/nuxt-web/web/package.json +19 -19
  272. package/templates/nuxt-web/web/plugins/forge.client.ts +10 -10
  273. package/templates/nuxt-web/web/plugins/forge.server.ts +10 -10
  274. package/templates/nuxt-web/web/server/api/forge-health.get.ts +7 -7
  275. package/templates/nuxt-web/web/tsconfig.json +6 -6
  276. package/templates/vendor-access/.vscode/settings.json +14 -14
  277. package/templates/vendor-access/README.md +30 -30
  278. package/templates/vendor-access/package.json +35 -35
  279. package/templates/vendor-access/pnpm-workspace.yaml +2 -2
  280. package/templates/vendor-access/tsconfig.json +17 -17
  281. package/templates/vendor-access/web/index.html +13 -13
  282. package/templates/vendor-access/web/package.json +21 -21
  283. package/templates/vendor-access/web/src/styles.css +682 -682
  284. package/templates/vendor-access/web/tsconfig.json +18 -18
@@ -1,59 +1,59 @@
1
1
  import path from "node:path";
2
2
  import ts from "typescript";
3
- import { compareBytes } from "../primitives/compare.ts";
4
- import { hashStable } from "../primitives/hash.ts";
5
- import { normalizePath } from "../primitives/paths.ts";
6
- import { stableSortStrings } from "../primitives/sort.ts";
7
- import type {
8
- AppGraph,
9
- ImportKind,
10
- LocalImport,
11
- ModuleGraph,
12
- ModuleNode,
13
- PackageImport,
14
- SourceFile,
15
- } from "../types/app-graph.ts";
3
+ import { compareBytes } from "../primitives/compare.ts";
4
+ import { hashStable } from "../primitives/hash.ts";
5
+ import { normalizePath } from "../primitives/paths.ts";
6
+ import { stableSortStrings } from "../primitives/sort.ts";
7
+ import type {
8
+ AppGraph,
9
+ ImportKind,
10
+ LocalImport,
11
+ ModuleGraph,
12
+ ModuleNode,
13
+ PackageImport,
14
+ SourceFile,
15
+ } from "../types/app-graph.ts";
16
16
  import type { RuntimeContext } from "../types/runtime.ts";
17
17
  import { FORGE_KIND_TO_CONTEXT } from "./forge-apis.ts";
18
18
  import type { RawSymbol } from "./types.ts";
19
-
20
- export function moduleIdForFile(file: string): string {
21
- return hashStable(normalizePath(file));
22
- }
23
-
24
- export function parsePackageSpecifier(
25
- specifier: string,
26
- ): { packageName: string; subpath: string } | null {
27
- if (
28
- specifier.startsWith(".") ||
29
- specifier.startsWith("/") ||
30
- specifier.startsWith("node:")
31
- ) {
32
- return null;
33
- }
34
-
35
- const parts = specifier.split("/");
36
- if (specifier.startsWith("@") && parts.length >= 2) {
37
- return {
38
- packageName: `${parts[0]}/${parts[1]}`,
39
- subpath: parts.length > 2 ? `/${parts.slice(2).join("/")}` : "",
40
- };
41
- }
42
-
43
- return {
44
- packageName: parts[0] ?? specifier,
45
- subpath: parts.length > 1 ? `/${parts.slice(1).join("/")}` : "",
46
- };
47
- }
48
-
49
- function compareModuleNodes(a: ModuleNode, b: ModuleNode): number {
50
- return compareBytes(a.id, b.id);
51
- }
52
-
53
- function stableSortModuleNodes(nodes: ModuleNode[]): ModuleNode[] {
54
- return [...nodes].sort(compareModuleNodes);
55
- }
56
-
19
+
20
+ export function moduleIdForFile(file: string): string {
21
+ return hashStable(normalizePath(file));
22
+ }
23
+
24
+ export function parsePackageSpecifier(
25
+ specifier: string,
26
+ ): { packageName: string; subpath: string } | null {
27
+ if (
28
+ specifier.startsWith(".") ||
29
+ specifier.startsWith("/") ||
30
+ specifier.startsWith("node:")
31
+ ) {
32
+ return null;
33
+ }
34
+
35
+ const parts = specifier.split("/");
36
+ if (specifier.startsWith("@") && parts.length >= 2) {
37
+ return {
38
+ packageName: `${parts[0]}/${parts[1]}`,
39
+ subpath: parts.length > 2 ? `/${parts.slice(2).join("/")}` : "",
40
+ };
41
+ }
42
+
43
+ return {
44
+ packageName: parts[0] ?? specifier,
45
+ subpath: parts.length > 1 ? `/${parts.slice(1).join("/")}` : "",
46
+ };
47
+ }
48
+
49
+ function compareModuleNodes(a: ModuleNode, b: ModuleNode): number {
50
+ return compareBytes(a.id, b.id);
51
+ }
52
+
53
+ function stableSortModuleNodes(nodes: ModuleNode[]): ModuleNode[] {
54
+ return [...nodes].sort(compareModuleNodes);
55
+ }
56
+
57
57
  function declaredContextsForFile(
58
58
  file: string,
59
59
  contextsByFile: Map<string, RuntimeContext[]>,
@@ -78,16 +78,16 @@ function buildDeclaredContextsByFile(symbols: RawSymbol[]): Map<string, RuntimeC
78
78
  }
79
79
  return byFile;
80
80
  }
81
-
82
- function spanFromNode(node: ts.Node, sourceFile: ts.SourceFile): {
83
- start: number;
84
- end: number;
85
- } {
86
- const start = node.getStart(sourceFile);
87
- const end = node.getEnd();
88
- return { start, end };
89
- }
90
-
81
+
82
+ function spanFromNode(node: ts.Node, sourceFile: ts.SourceFile): {
83
+ start: number;
84
+ end: number;
85
+ } {
86
+ const start = node.getStart(sourceFile);
87
+ const end = node.getEnd();
88
+ return { start, end };
89
+ }
90
+
91
91
  function resolveLocalTarget(
92
92
  specifier: string,
93
93
  fromFile: string,
@@ -115,15 +115,15 @@ function resolveLocalTarget(
115
115
 
116
116
  return candidates.find((candidate) => sourcePaths.has(candidate)) ?? null;
117
117
  }
118
-
118
+
119
119
  function collectImports(
120
120
  sourceFile: ts.SourceFile,
121
121
  sourcePaths: Set<string>,
122
122
  ): { packageImports: PackageImport[]; localImports: LocalImport[] } {
123
- const packageImports: PackageImport[] = [];
124
- const localImports: LocalImport[] = [];
125
- const fromFile = normalizePath(sourceFile.fileName);
126
-
123
+ const packageImports: PackageImport[] = [];
124
+ const localImports: LocalImport[] = [];
125
+ const fromFile = normalizePath(sourceFile.fileName);
126
+
127
127
  function recordPackageImport(
128
128
  specifier: string,
129
129
  parsed: { packageName: string; subpath: string },
@@ -132,17 +132,17 @@ function collectImports(
132
132
  ): void {
133
133
  packageImports.push({
134
134
  specifier,
135
- packageName: parsed.packageName,
136
- subpath: parsed.subpath,
137
- span,
138
- importKind,
139
- });
140
- }
141
-
142
- function visit(node: ts.Node): void {
143
- if (ts.isImportDeclaration(node) && node.moduleSpecifier) {
144
- if (ts.isStringLiteral(node.moduleSpecifier)) {
145
- const specifier = node.moduleSpecifier.text;
135
+ packageName: parsed.packageName,
136
+ subpath: parsed.subpath,
137
+ span,
138
+ importKind,
139
+ });
140
+ }
141
+
142
+ function visit(node: ts.Node): void {
143
+ if (ts.isImportDeclaration(node) && node.moduleSpecifier) {
144
+ if (ts.isStringLiteral(node.moduleSpecifier)) {
145
+ const specifier = node.moduleSpecifier.text;
146
146
  const span = spanFromNode(node.moduleSpecifier, sourceFile);
147
147
  const parsed = parsePackageSpecifier(specifier);
148
148
  if (parsed) {
@@ -153,23 +153,23 @@ function collectImports(
153
153
  fromFile,
154
154
  sourcePaths,
155
155
  );
156
- if (target) {
157
- localImports.push({
158
- toModuleId: moduleIdForFile(target),
159
- span,
160
- });
161
- }
162
- }
163
- }
164
- }
165
-
166
- if (
167
- ts.isCallExpression(node) &&
168
- node.expression.kind === ts.SyntaxKind.ImportKeyword &&
169
- node.arguments[0] &&
170
- ts.isStringLiteral(node.arguments[0])
171
- ) {
172
- const specifier = node.arguments[0].text;
156
+ if (target) {
157
+ localImports.push({
158
+ toModuleId: moduleIdForFile(target),
159
+ span,
160
+ });
161
+ }
162
+ }
163
+ }
164
+ }
165
+
166
+ if (
167
+ ts.isCallExpression(node) &&
168
+ node.expression.kind === ts.SyntaxKind.ImportKeyword &&
169
+ node.arguments[0] &&
170
+ ts.isStringLiteral(node.arguments[0])
171
+ ) {
172
+ const specifier = node.arguments[0].text;
173
173
  const span = spanFromNode(node.arguments[0], sourceFile);
174
174
  const parsed = parsePackageSpecifier(specifier);
175
175
  if (parsed) {
@@ -180,23 +180,23 @@ function collectImports(
180
180
  fromFile,
181
181
  sourcePaths,
182
182
  );
183
- if (target) {
184
- localImports.push({
185
- toModuleId: moduleIdForFile(target),
186
- span,
187
- });
188
- }
189
- }
190
- }
191
-
192
- if (
193
- ts.isCallExpression(node) &&
194
- ts.isIdentifier(node.expression) &&
195
- node.expression.text === "require" &&
196
- node.arguments[0] &&
197
- ts.isStringLiteral(node.arguments[0])
198
- ) {
199
- const specifier = node.arguments[0].text;
183
+ if (target) {
184
+ localImports.push({
185
+ toModuleId: moduleIdForFile(target),
186
+ span,
187
+ });
188
+ }
189
+ }
190
+ }
191
+
192
+ if (
193
+ ts.isCallExpression(node) &&
194
+ ts.isIdentifier(node.expression) &&
195
+ node.expression.text === "require" &&
196
+ node.arguments[0] &&
197
+ ts.isStringLiteral(node.arguments[0])
198
+ ) {
199
+ const specifier = node.arguments[0].text;
200
200
  const span = spanFromNode(node.arguments[0], sourceFile);
201
201
  const parsed = parsePackageSpecifier(specifier);
202
202
  if (parsed) {
@@ -207,22 +207,22 @@ function collectImports(
207
207
  fromFile,
208
208
  sourcePaths,
209
209
  );
210
- if (target) {
211
- localImports.push({
212
- toModuleId: moduleIdForFile(target),
213
- span,
214
- });
215
- }
216
- }
217
- }
218
-
219
- ts.forEachChild(node, visit);
220
- }
221
-
222
- visit(sourceFile);
223
- return { packageImports, localImports };
224
- }
225
-
210
+ if (target) {
211
+ localImports.push({
212
+ toModuleId: moduleIdForFile(target),
213
+ span,
214
+ });
215
+ }
216
+ }
217
+ }
218
+
219
+ ts.forEachChild(node, visit);
220
+ }
221
+
222
+ visit(sourceFile);
223
+ return { packageImports, localImports };
224
+ }
225
+
226
226
  function sourcesUnchangedSincePrior(
227
227
  sources: SourceFile[],
228
228
  prior?: AppGraph,
@@ -232,21 +232,21 @@ function sourcesUnchangedSincePrior(
232
232
  return false;
233
233
  }
234
234
  const priorHashes = new Map(Object.entries(prior.sourceHashes ?? {}));
235
- if (priorHashes.size !== sources.length) {
236
- return false;
237
- }
238
- for (const source of sources) {
239
- if (priorHashes.get(source.path) !== source.contentHash) {
240
- return false;
241
- }
242
- }
243
- return true;
235
+ if (priorHashes.size !== sources.length) {
236
+ return false;
237
+ }
238
+ for (const source of sources) {
239
+ if (priorHashes.get(source.path) !== source.contentHash) {
240
+ return false;
241
+ }
242
+ }
243
+ return true;
244
244
  }
245
245
 
246
246
  function priorModuleNodesByFile(prior?: AppGraph): Map<string, ModuleNode> {
247
247
  return new Map((prior?.moduleGraph.nodes ?? []).map((node) => [node.file, node]));
248
248
  }
249
-
249
+
250
250
  export function buildModuleGraph(
251
251
  sources: SourceFile[],
252
252
  rawSymbols: RawSymbol[],
@@ -285,31 +285,31 @@ export function buildModuleGraph(
285
285
  );
286
286
 
287
287
  if (!sourceFile) {
288
- nodes.push({
289
- id: moduleIdForFile(normalizedFile),
290
- file: normalizedFile,
288
+ nodes.push({
289
+ id: moduleIdForFile(normalizedFile),
290
+ file: normalizedFile,
291
291
  directPackageImports: [],
292
292
  localImports: [],
293
293
  declaredContexts: declaredContextsForFile(normalizedFile, contextsByFile),
294
294
  effectiveContexts: [],
295
295
  });
296
- continue;
297
- }
298
-
296
+ continue;
297
+ }
298
+
299
299
  const { packageImports, localImports } = collectImports(
300
300
  sourceFile,
301
301
  sourcePaths,
302
302
  );
303
-
304
- nodes.push({
305
- id: moduleIdForFile(normalizedFile),
306
- file: normalizedFile,
303
+
304
+ nodes.push({
305
+ id: moduleIdForFile(normalizedFile),
306
+ file: normalizedFile,
307
307
  directPackageImports: packageImports,
308
308
  localImports,
309
309
  declaredContexts: declaredContextsForFile(normalizedFile, contextsByFile),
310
310
  effectiveContexts: [],
311
311
  });
312
- }
313
-
314
- return { nodes: stableSortModuleNodes(nodes) };
315
- }
312
+ }
313
+
314
+ return { nodes: stableSortModuleNodes(nodes) };
315
+ }
@@ -1,37 +1,37 @@
1
- import Parser from "tree-sitter";
2
- import TypeScript from "tree-sitter-typescript";
3
- import { createDiagnostic } from "../diagnostics/create.ts";
4
- import type { Diagnostic } from "../types/diagnostic.ts";
5
- import type { ForgeSymbol, SourceFile } from "../types/app-graph.ts";
6
- import { normalizePath } from "../primitives/paths.ts";
7
- import { extractSymbolsFromTree } from "./extract.ts";
8
- import type { ParseInvalidationKey, RawSymbol } from "./types.ts";
9
- import { parseInvalidationKeyEquals } from "./types.ts";
10
-
11
- const tsParser = new Parser();
12
- tsParser.setLanguage(TypeScript.typescript as unknown as Parser.Language);
13
-
14
- const tsxParser = new Parser();
15
- tsxParser.setLanguage(TypeScript.tsx as unknown as Parser.Language);
16
-
17
- function parserForFile(path: string): Parser {
18
- return path.endsWith(".tsx") ? tsxParser : tsParser;
19
- }
20
-
21
- function priorSymbolsToRaw(symbols: ForgeSymbol[]): RawSymbol[] {
22
- return symbols.map((symbol) => ({
23
- kind: symbol.kind,
24
- name: symbol.name,
25
- qualifiedName: symbol.qualifiedName,
26
- file: symbol.file,
27
- span: symbol.span,
28
- exportPath:
29
- typeof symbol.meta.exportPath === "string" ? symbol.meta.exportPath : "",
30
- sourceSlice:
31
- typeof symbol.meta.sourceSlice === "string" ? symbol.meta.sourceSlice : "",
32
- }));
33
- }
34
-
1
+ import Parser from "tree-sitter";
2
+ import TypeScript from "tree-sitter-typescript";
3
+ import { createDiagnostic } from "../diagnostics/create.ts";
4
+ import type { Diagnostic } from "../types/diagnostic.ts";
5
+ import type { ForgeSymbol, SourceFile } from "../types/app-graph.ts";
6
+ import { normalizePath } from "../primitives/paths.ts";
7
+ import { extractSymbolsFromTree } from "./extract.ts";
8
+ import type { ParseInvalidationKey, RawSymbol } from "./types.ts";
9
+ import { parseInvalidationKeyEquals } from "./types.ts";
10
+
11
+ const tsParser = new Parser();
12
+ tsParser.setLanguage(TypeScript.typescript as unknown as Parser.Language);
13
+
14
+ const tsxParser = new Parser();
15
+ tsxParser.setLanguage(TypeScript.tsx as unknown as Parser.Language);
16
+
17
+ function parserForFile(path: string): Parser {
18
+ return path.endsWith(".tsx") ? tsxParser : tsParser;
19
+ }
20
+
21
+ function priorSymbolsToRaw(symbols: ForgeSymbol[]): RawSymbol[] {
22
+ return symbols.map((symbol) => ({
23
+ kind: symbol.kind,
24
+ name: symbol.name,
25
+ qualifiedName: symbol.qualifiedName,
26
+ file: symbol.file,
27
+ span: symbol.span,
28
+ exportPath:
29
+ typeof symbol.meta.exportPath === "string" ? symbol.meta.exportPath : "",
30
+ sourceSlice:
31
+ typeof symbol.meta.sourceSlice === "string" ? symbol.meta.sourceSlice : "",
32
+ }));
33
+ }
34
+
35
35
  interface PriorSymbolsForFile {
36
36
  contentHash?: string;
37
37
  symbols: ForgeSymbol[];
@@ -55,12 +55,12 @@ function groupPriorSymbolsByFile(
55
55
  }
56
56
  return byFile;
57
57
  }
58
-
59
- export interface IncrementalParseResult {
60
- symbols: RawSymbol[];
61
- diagnostics: Diagnostic[];
62
- }
63
-
58
+
59
+ export interface IncrementalParseResult {
60
+ symbols: RawSymbol[];
61
+ diagnostics: Diagnostic[];
62
+ }
63
+
64
64
  export function incrementalParse(
65
65
  sources: SourceFile[],
66
66
  priorSymbols: ForgeSymbol[] | undefined,
@@ -68,17 +68,17 @@ export function incrementalParse(
68
68
  priorInvalidation: ParseInvalidationKey | undefined,
69
69
  currentInvalidation: ParseInvalidationKey,
70
70
  ): IncrementalParseResult {
71
- const diagnostics: Diagnostic[] = [];
72
- const allSymbols: RawSymbol[] = [];
73
- const globalInvalidated =
74
- priorInvalidation === undefined ||
75
- !parseInvalidationKeyEquals(priorInvalidation, currentInvalidation);
76
-
71
+ const diagnostics: Diagnostic[] = [];
72
+ const allSymbols: RawSymbol[] = [];
73
+ const globalInvalidated =
74
+ priorInvalidation === undefined ||
75
+ !parseInvalidationKeyEquals(priorInvalidation, currentInvalidation);
76
+
77
77
  const priorByFile = priorSymbols
78
78
  ? groupPriorSymbolsByFile(priorSymbols)
79
79
  : new Map<string, PriorSymbolsForFile>();
80
-
81
- for (const source of sources) {
80
+
81
+ for (const source of sources) {
82
82
  const normalizedFile = normalizePath(source.path);
83
83
  const priorForFile = priorByFile.get(normalizedFile);
84
84
  const priorHash = priorForFile?.contentHash ?? priorSourceHashes?.[normalizedFile];
@@ -94,26 +94,26 @@ export function incrementalParse(
94
94
  if (fileUnchanged) {
95
95
  continue;
96
96
  }
97
-
98
- try {
99
- const tree = parserForFile(normalizedFile).parse(source.text);
100
- const extracted = extractSymbolsFromTree(
101
- tree.rootNode,
102
- normalizedFile,
103
- source.text,
104
- );
105
- allSymbols.push(...extracted);
106
- } catch {
107
- diagnostics.push(
108
- createDiagnostic({
109
- severity: "warning",
110
- code: "FORGE_UNPARSEABLE_FILE",
111
- message: `cannot parse source file: ${normalizedFile}`,
112
- file: normalizedFile,
113
- }),
114
- );
115
- }
116
- }
117
-
118
- return { symbols: allSymbols, diagnostics };
119
- }
97
+
98
+ try {
99
+ const tree = parserForFile(normalizedFile).parse(source.text);
100
+ const extracted = extractSymbolsFromTree(
101
+ tree.rootNode,
102
+ normalizedFile,
103
+ source.text,
104
+ );
105
+ allSymbols.push(...extracted);
106
+ } catch {
107
+ diagnostics.push(
108
+ createDiagnostic({
109
+ severity: "warning",
110
+ code: "FORGE_UNPARSEABLE_FILE",
111
+ message: `cannot parse source file: ${normalizedFile}`,
112
+ file: normalizedFile,
113
+ }),
114
+ );
115
+ }
116
+ }
117
+
118
+ return { symbols: allSymbols, diagnostics };
119
+ }
@@ -1,48 +1,48 @@
1
- import { deriveStableSymbolId, hashStable } from "../primitives/hash.ts";
2
- import type { ForgeSymbol } from "../types/app-graph.ts";
3
- import type { SourceFile } from "../types/app-graph.ts";
4
- import type { RawSymbol } from "./types.ts";
5
-
6
- export function rawToForgeSymbol(
7
- raw: RawSymbol,
8
- fileContentHash: string,
9
- ): ForgeSymbol {
10
- const id = deriveStableSymbolId({
11
- kind: raw.kind,
12
- canonicalModulePath: raw.file,
13
- qualifiedName: raw.qualifiedName,
14
- exportPath: raw.exportPath,
15
- });
16
-
17
- const slice = raw.sourceSlice || "";
18
- const contentHash = slice.length > 0 ? hashStable(slice) : fileContentHash;
19
-
20
- return {
21
- id,
22
- kind: raw.kind,
23
- name: raw.name,
24
- qualifiedName: raw.qualifiedName,
25
- file: raw.file,
26
- span: raw.span,
27
- contentHash,
28
- meta: {
29
- exportPath: raw.exportPath,
30
- fileContentHash,
31
- ...(slice.length > 0 ? { sourceSlice: slice } : {}),
32
- },
33
- };
34
- }
35
-
36
- export function buildForgeSymbols(
37
- rawSymbols: RawSymbol[],
38
- sources: SourceFile[],
39
- ): ForgeSymbol[] {
40
- const hashByFile = new Map<string, string>();
41
- for (const source of sources) {
42
- hashByFile.set(source.path, source.contentHash);
43
- }
44
-
45
- return rawSymbols.map((raw) =>
46
- rawToForgeSymbol(raw, hashByFile.get(raw.file) ?? ""),
47
- );
48
- }
1
+ import { deriveStableSymbolId, hashStable } from "../primitives/hash.ts";
2
+ import type { ForgeSymbol } from "../types/app-graph.ts";
3
+ import type { SourceFile } from "../types/app-graph.ts";
4
+ import type { RawSymbol } from "./types.ts";
5
+
6
+ export function rawToForgeSymbol(
7
+ raw: RawSymbol,
8
+ fileContentHash: string,
9
+ ): ForgeSymbol {
10
+ const id = deriveStableSymbolId({
11
+ kind: raw.kind,
12
+ canonicalModulePath: raw.file,
13
+ qualifiedName: raw.qualifiedName,
14
+ exportPath: raw.exportPath,
15
+ });
16
+
17
+ const slice = raw.sourceSlice || "";
18
+ const contentHash = slice.length > 0 ? hashStable(slice) : fileContentHash;
19
+
20
+ return {
21
+ id,
22
+ kind: raw.kind,
23
+ name: raw.name,
24
+ qualifiedName: raw.qualifiedName,
25
+ file: raw.file,
26
+ span: raw.span,
27
+ contentHash,
28
+ meta: {
29
+ exportPath: raw.exportPath,
30
+ fileContentHash,
31
+ ...(slice.length > 0 ? { sourceSlice: slice } : {}),
32
+ },
33
+ };
34
+ }
35
+
36
+ export function buildForgeSymbols(
37
+ rawSymbols: RawSymbol[],
38
+ sources: SourceFile[],
39
+ ): ForgeSymbol[] {
40
+ const hashByFile = new Map<string, string>();
41
+ for (const source of sources) {
42
+ hashByFile.set(source.path, source.contentHash);
43
+ }
44
+
45
+ return rawSymbols.map((raw) =>
46
+ rawToForgeSymbol(raw, hashByFile.get(raw.file) ?? ""),
47
+ );
48
+ }