forgeos 0.1.0-alpha.2 → 0.1.0-alpha.21

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 (406) hide show
  1. package/.npmignore +4 -0
  2. package/AGENTS.md +168 -81
  3. package/CHANGELOG.md +211 -0
  4. package/README.md +88 -14
  5. package/adapters/go/README.md +23 -0
  6. package/adapters/go/go.mod +3 -0
  7. package/adapters/go/http.go +149 -0
  8. package/adapters/go/registry.go +234 -0
  9. package/adapters/go/types.go +136 -0
  10. package/adapters/java/README.md +68 -0
  11. package/adapters/java/pom.xml +34 -0
  12. package/adapters/java/src/main/java/dev/forgeos/adapter/Auth.java +20 -0
  13. package/adapters/java/src/main/java/dev/forgeos/adapter/Diagnostic.java +16 -0
  14. package/adapters/java/src/main/java/dev/forgeos/adapter/Entry.java +38 -0
  15. package/adapters/java/src/main/java/dev/forgeos/adapter/EntryKind.java +16 -0
  16. package/adapters/java/src/main/java/dev/forgeos/adapter/ErrorInfo.java +4 -0
  17. package/adapters/java/src/main/java/dev/forgeos/adapter/Forge.java +94 -0
  18. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeCall.java +12 -0
  19. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeContext.java +11 -0
  20. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHandler.java +8 -0
  21. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHttpHandler.java +179 -0
  22. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeRegistry.java +121 -0
  23. package/adapters/java/src/main/java/dev/forgeos/adapter/Json.java +14 -0
  24. package/adapters/java/src/main/java/dev/forgeos/adapter/Manifest.java +14 -0
  25. package/adapters/java/src/main/java/dev/forgeos/adapter/RequestEnvelope.java +6 -0
  26. package/adapters/java/src/main/java/dev/forgeos/adapter/ResponseEnvelope.java +25 -0
  27. package/adapters/java/src/main/java/dev/forgeos/adapter/Risk.java +18 -0
  28. package/adapters/java/src/main/java/dev/forgeos/adapter/Schemas.java +36 -0
  29. package/adapters/java/src/main/java/dev/forgeos/adapter/Service.java +65 -0
  30. package/adapters/java/src/main/java/dev/forgeos/adapter/TransactionMode.java +18 -0
  31. package/adapters/java/src/main/java/dev/forgeos/adapter/TypedForgeHandler.java +6 -0
  32. package/adapters/java/target/classes/dev/forgeos/adapter/Auth.class +0 -0
  33. package/adapters/java/target/classes/dev/forgeos/adapter/Diagnostic.class +0 -0
  34. package/adapters/java/target/classes/dev/forgeos/adapter/Entry.class +0 -0
  35. package/adapters/java/target/classes/dev/forgeos/adapter/EntryKind.class +0 -0
  36. package/adapters/java/target/classes/dev/forgeos/adapter/ErrorInfo.class +0 -0
  37. package/adapters/java/target/classes/dev/forgeos/adapter/Forge.class +0 -0
  38. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeCall.class +0 -0
  39. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeContext.class +0 -0
  40. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeHandler.class +0 -0
  41. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeHttpHandler.class +0 -0
  42. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeRegistry$EntryOption.class +0 -0
  43. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeRegistry$RegisteredEntry.class +0 -0
  44. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeRegistry$RegistryOption.class +0 -0
  45. package/adapters/java/target/classes/dev/forgeos/adapter/ForgeRegistry.class +0 -0
  46. package/adapters/java/target/classes/dev/forgeos/adapter/Json.class +0 -0
  47. package/adapters/java/target/classes/dev/forgeos/adapter/Manifest.class +0 -0
  48. package/adapters/java/target/classes/dev/forgeos/adapter/RequestEnvelope.class +0 -0
  49. package/adapters/java/target/classes/dev/forgeos/adapter/ResponseEnvelope.class +0 -0
  50. package/adapters/java/target/classes/dev/forgeos/adapter/Risk.class +0 -0
  51. package/adapters/java/target/classes/dev/forgeos/adapter/Schemas.class +0 -0
  52. package/adapters/java/target/classes/dev/forgeos/adapter/Service.class +0 -0
  53. package/adapters/java/target/classes/dev/forgeos/adapter/TransactionMode.class +0 -0
  54. package/adapters/java/target/classes/dev/forgeos/adapter/TypedForgeHandler.class +0 -0
  55. package/adapters/java/target/forge-java-adapter-0.1.0-alpha.11.jar +0 -0
  56. package/adapters/java/target/maven-archiver/pom.properties +3 -0
  57. package/adapters/java/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +23 -0
  58. package/adapters/java/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +20 -0
  59. package/adapters/java-spring-boot-starter/README.md +32 -0
  60. package/adapters/java-spring-boot-starter/pom.xml +36 -0
  61. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeCommand.java +22 -0
  62. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeExternalService.java +15 -0
  63. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeQuery.java +16 -0
  64. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeServiceBeanCondition.java +18 -0
  65. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringAutoConfiguration.java +16 -0
  66. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringRuntime.java +104 -0
  67. package/adapters/java-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +1 -0
  68. package/adapters/java-spring-boot-starter/target/classes/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +1 -0
  69. package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeCommand.class +0 -0
  70. package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeExternalService.class +0 -0
  71. package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeQuery.class +0 -0
  72. package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeServiceBeanCondition.class +0 -0
  73. package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeSpringAutoConfiguration.class +0 -0
  74. package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeSpringRuntime.class +0 -0
  75. package/adapters/java-spring-boot-starter/target/forge-java-spring-boot-starter-0.1.0-alpha.11.jar +0 -0
  76. package/adapters/java-spring-boot-starter/target/maven-archiver/pom.properties +3 -0
  77. package/adapters/java-spring-boot-starter/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +6 -0
  78. package/adapters/java-spring-boot-starter/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +6 -0
  79. package/bin/forge.mjs +18 -0
  80. package/docs/changelog.md +242 -0
  81. package/docs/forge-protocol.md +189 -0
  82. package/examples/go-billing/go.mod +7 -0
  83. package/examples/go-billing/main.go +120 -0
  84. package/examples/java-billing/pom.xml +52 -0
  85. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/CreateInvoiceInput.java +4 -0
  86. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Invoice.java +11 -0
  87. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Main.java +127 -0
  88. package/examples/java-billing/target/classes/dev/forgeos/examples/billing/CreateInvoiceInput.class +0 -0
  89. package/examples/java-billing/target/classes/dev/forgeos/examples/billing/Invoice.class +0 -0
  90. package/examples/java-billing/target/classes/dev/forgeos/examples/billing/Main$EmptyInput.class +0 -0
  91. package/examples/java-billing/target/classes/dev/forgeos/examples/billing/Main$Options.class +0 -0
  92. package/examples/java-billing/target/classes/dev/forgeos/examples/billing/Main.class +0 -0
  93. package/examples/java-billing/target/java-billing-0.1.0-alpha.11-all.jar +0 -0
  94. package/examples/java-billing/target/java-billing-0.1.0-alpha.11.jar +0 -0
  95. package/examples/java-billing/target/maven-archiver/pom.properties +3 -0
  96. package/examples/java-billing/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +5 -0
  97. package/examples/java-billing/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +3 -0
  98. package/package.json +29 -7
  99. package/schemas/forge-manifest.schema.json +57 -0
  100. package/src/forge/_generated/releaseManifest.json +1 -2
  101. package/src/forge/_generated/releaseManifest.ts +3 -3
  102. package/src/forge/agent-adapters/index.ts +1511 -123
  103. package/src/forge/agent-adapters/types.ts +216 -1
  104. package/src/forge/agent-memory/bridge.ts +1245 -0
  105. package/src/forge/agent-memory/context-pack.ts +151 -0
  106. package/src/forge/agent-memory/hook-runner.ts +312 -0
  107. package/src/forge/agent-memory/mcp.ts +224 -0
  108. package/src/forge/agent-memory/normalize.ts +498 -0
  109. package/src/forge/agent-memory/redaction.ts +103 -0
  110. package/src/forge/agent-memory/sources/claude-code.ts +51 -0
  111. package/src/forge/agent-memory/sources/codex-hook-runner.mjs +273 -0
  112. package/src/forge/agent-memory/sources/codex.ts +119 -0
  113. package/src/forge/agent-memory/sources/cursor.ts +35 -0
  114. package/src/forge/agent-memory/types.ts +191 -0
  115. package/src/forge/bench.ts +248 -0
  116. package/src/forge/brownfield-import/index.ts +801 -0
  117. package/src/forge/brownfield-import/types.ts +127 -0
  118. package/src/forge/cair/action-journal.ts +61 -0
  119. package/src/forge/cair/action-parser.ts +314 -0
  120. package/src/forge/cair/action-validator.ts +40 -0
  121. package/src/forge/cair/actions.ts +1818 -0
  122. package/src/forge/cair/format.ts +77 -0
  123. package/src/forge/cair/index.ts +106 -0
  124. package/src/forge/cair/query.ts +478 -0
  125. package/src/forge/cair/snapshot.ts +315 -0
  126. package/src/forge/cair/types.ts +248 -0
  127. package/src/forge/cli/ai.ts +671 -3
  128. package/src/forge/cli/auth.ts +36 -1
  129. package/src/forge/cli/build.ts +20 -4
  130. package/src/forge/cli/changed.ts +300 -0
  131. package/src/forge/cli/codex-app-server.ts +877 -0
  132. package/src/forge/cli/commands.ts +1285 -7
  133. package/src/forge/cli/db.ts +121 -2
  134. package/src/forge/cli/deps.ts +79 -12
  135. package/src/forge/cli/dev.ts +502 -38
  136. package/src/forge/cli/docs.ts +265 -0
  137. package/src/forge/cli/handoff.ts +250 -0
  138. package/src/forge/cli/index.ts +1 -0
  139. package/src/forge/cli/main.ts +49 -3
  140. package/src/forge/cli/new.ts +3 -1
  141. package/src/forge/cli/next-actions.ts +23 -0
  142. package/src/forge/cli/output.ts +290 -1
  143. package/src/forge/cli/parse.ts +770 -36
  144. package/src/forge/cli/query.ts +32 -0
  145. package/src/forge/cli/release.ts +35 -11
  146. package/src/forge/cli/rls.ts +568 -17
  147. package/src/forge/cli/run.ts +41 -0
  148. package/src/forge/cli/secrets.ts +46 -1
  149. package/src/forge/cli/security.ts +381 -0
  150. package/src/forge/cli/self-host.ts +56 -14
  151. package/src/forge/cli/studio.ts +2163 -0
  152. package/src/forge/cli/verify.ts +1422 -32
  153. package/src/forge/compiler/agent-contract/build.ts +725 -41
  154. package/src/forge/compiler/agent-contract/types.ts +85 -0
  155. package/src/forge/compiler/ai-registry/build.ts +62 -1
  156. package/src/forge/compiler/ai-registry/constants.ts +1 -1
  157. package/src/forge/compiler/ai-registry/parse.ts +168 -5
  158. package/src/forge/compiler/api-surface/build.ts +47 -0
  159. package/src/forge/compiler/app-graph/build.ts +68 -8
  160. package/src/forge/compiler/app-graph/extract.ts +107 -0
  161. package/src/forge/compiler/app-graph/forge-apis.ts +1 -0
  162. package/src/forge/compiler/app-graph/module-graph.ts +73 -78
  163. package/src/forge/compiler/app-graph/parser.ts +24 -24
  164. package/src/forge/compiler/app-graph/profile.ts +26 -0
  165. package/src/forge/compiler/app-graph/versions.ts +1 -1
  166. package/src/forge/compiler/classifier/capabilities.ts +3 -2
  167. package/src/forge/compiler/classifier/classify.ts +32 -8
  168. package/src/forge/compiler/classifier/secrets.ts +3 -2
  169. package/src/forge/compiler/classifier/signals.ts +91 -1
  170. package/src/forge/compiler/client-sdk/build-manifest.ts +59 -0
  171. package/src/forge/compiler/client-sdk/render-client.ts +188 -13
  172. package/src/forge/compiler/data-graph/parse.ts +3 -3
  173. package/src/forge/compiler/data-graph/sql/ddl.ts +60 -2
  174. package/src/forge/compiler/data-graph/sql/serialize.ts +4 -0
  175. package/src/forge/compiler/data-graph/sql/types.ts +1 -0
  176. package/src/forge/compiler/dev-manifest/build.ts +3 -0
  177. package/src/forge/compiler/diagnostics/codes.ts +35 -0
  178. package/src/forge/compiler/diagnostics/create.ts +8 -3
  179. package/src/forge/compiler/diagnostics/index.ts +2 -0
  180. package/src/forge/compiler/emitter/barrel.ts +3 -0
  181. package/src/forge/compiler/emitter/render.ts +5 -0
  182. package/src/forge/compiler/external-manifest/registry.ts +205 -0
  183. package/src/forge/compiler/external-manifest/types.ts +91 -0
  184. package/src/forge/compiler/external-manifest/validate.ts +373 -0
  185. package/src/forge/compiler/frontend-graph/build.ts +85 -13
  186. package/src/forge/compiler/integration/add.ts +498 -22
  187. package/src/forge/compiler/integration/snapshot.ts +2 -0
  188. package/src/forge/compiler/make-registry/build.ts +19 -7
  189. package/src/forge/compiler/orchestrator/plan-profile.ts +23 -0
  190. package/src/forge/compiler/orchestrator/plan.ts +78 -7
  191. package/src/forge/compiler/orchestrator/profile.ts +65 -0
  192. package/src/forge/compiler/orchestrator/run.ts +97 -31
  193. package/src/forge/compiler/orchestrator/serialize.ts +101 -8
  194. package/src/forge/compiler/package-graph/compiler.ts +13 -3
  195. package/src/forge/compiler/package-manager/adapter.ts +4 -1
  196. package/src/forge/compiler/package-manager/commands.ts +4 -0
  197. package/src/forge/compiler/package-manager/executor.ts +30 -1
  198. package/src/forge/compiler/policy-registry/build.ts +44 -1
  199. package/src/forge/compiler/test-graph/build.ts +11 -3
  200. package/src/forge/compiler/types/ai-registry.ts +25 -1
  201. package/src/forge/compiler/types/app-graph.ts +9 -2
  202. package/src/forge/compiler/types/cli.ts +76 -1
  203. package/src/forge/compiler/types/dev-manifest.ts +3 -0
  204. package/src/forge/compiler/types/frontend-graph.ts +2 -2
  205. package/src/forge/delta/classifier.ts +52 -0
  206. package/src/forge/delta/explain.ts +126 -0
  207. package/src/forge/delta/git-observer.ts +43 -0
  208. package/src/forge/delta/ids.ts +44 -0
  209. package/src/forge/delta/index.ts +13 -0
  210. package/src/forge/delta/recorder.ts +402 -0
  211. package/src/forge/delta/redaction.ts +50 -0
  212. package/src/forge/delta/schema.ts +240 -0
  213. package/src/forge/delta/session.ts +142 -0
  214. package/src/forge/delta/status.ts +489 -0
  215. package/src/forge/delta/store.ts +2975 -0
  216. package/src/forge/delta/timeline.ts +104 -0
  217. package/src/forge/dev/server.ts +768 -15
  218. package/src/forge/dev/types.ts +15 -1
  219. package/src/forge/dev/watch.ts +17 -7
  220. package/src/forge/dev-console/cycle.ts +233 -21
  221. package/src/forge/dev-console/types.ts +46 -1
  222. package/src/forge/impact/index.ts +46 -8
  223. package/src/forge/impact/types.ts +6 -0
  224. package/src/forge/intent/index.ts +35 -16
  225. package/src/forge/make/index.ts +149 -6
  226. package/src/forge/make/templates.ts +343 -2
  227. package/src/forge/make/types.ts +3 -1
  228. package/src/forge/refactor/index.ts +1 -0
  229. package/src/forge/repair/rules/index.ts +2 -2
  230. package/src/forge/review/index.ts +158 -12
  231. package/src/forge/review/types.ts +15 -0
  232. package/src/forge/runtime/ai/context.ts +210 -5
  233. package/src/forge/runtime/ai/types.ts +70 -0
  234. package/src/forge/runtime/auth/claims.ts +32 -0
  235. package/src/forge/runtime/auth/errors.ts +2 -0
  236. package/src/forge/runtime/context/create-context.ts +30 -6
  237. package/src/forge/runtime/db/generated-client.ts +13 -2
  238. package/src/forge/runtime/db/memory-adapter.ts +2 -2
  239. package/src/forge/runtime/db/pglite-adapter.ts +77 -2
  240. package/src/forge/runtime/db/postgres-adapter.ts +6 -3
  241. package/src/forge/runtime/executor.ts +112 -2
  242. package/src/forge/runtime/external/bridge.ts +649 -0
  243. package/src/forge/runtime/runner/run-entry.ts +16 -7
  244. package/src/forge/runtime/telemetry/scrubber.ts +91 -10
  245. package/src/forge/runtime/webhooks/security.ts +184 -0
  246. package/src/forge/server.ts +100 -2
  247. package/src/forge/version.ts +1 -1
  248. package/src/forge/vue/index.ts +407 -0
  249. package/src/forge/workspace/change-summary.ts +209 -0
  250. package/src/forge/workspace/forge-cli.ts +14 -0
  251. package/src/forge/workspace/git-summary.ts +279 -0
  252. package/templates/agent-workroom/AGENTS.md +29 -0
  253. package/templates/agent-workroom/README.md +34 -0
  254. package/templates/agent-workroom/forge.config.ts +3 -0
  255. package/templates/agent-workroom/package.json +33 -0
  256. package/templates/agent-workroom/src/actions/indexAgentSignal.ts +10 -0
  257. package/templates/agent-workroom/src/commands/openWorkroom.ts +61 -0
  258. package/templates/agent-workroom/src/commands/recordAgentSignal.ts +119 -0
  259. package/templates/agent-workroom/src/commands/recordCheckRun.ts +52 -0
  260. package/templates/agent-workroom/src/forge/schema.ts +54 -0
  261. package/templates/agent-workroom/src/policies.ts +6 -0
  262. package/templates/agent-workroom/src/queries/listWorkrooms.ts +11 -0
  263. package/templates/agent-workroom/src/queries/liveWorkroom.ts +63 -0
  264. package/templates/agent-workroom/tsconfig.json +16 -0
  265. package/templates/agent-workroom/web/index.html +12 -0
  266. package/templates/agent-workroom/web/package.json +21 -0
  267. package/templates/agent-workroom/web/src/App.tsx +345 -0
  268. package/templates/agent-workroom/web/src/lib/forge.ts +13 -0
  269. package/templates/agent-workroom/web/src/main.tsx +13 -0
  270. package/templates/agent-workroom/web/src/styles.css +545 -0
  271. package/templates/agent-workroom/web/tsconfig.json +27 -0
  272. package/templates/b2b-support-web/package.json +2 -0
  273. package/templates/b2b-support-web/tsconfig.json +4 -1
  274. package/templates/b2b-support-web/web/package.json +1 -1
  275. package/templates/minimal-web/package.json +2 -1
  276. package/templates/minimal-web/tsconfig.json +3 -1
  277. package/templates/minimal-web/web/package.json +2 -2
  278. package/src/forge/_generated/actionSubscriptions.json +0 -2
  279. package/src/forge/_generated/actionSubscriptions.ts +0 -10
  280. package/src/forge/_generated/agentAdapterManifest.json +0 -2
  281. package/src/forge/_generated/agentAdapterManifest.ts +0 -73
  282. package/src/forge/_generated/agentContract.json +0 -2
  283. package/src/forge/_generated/agentContract.ts +0 -7696
  284. package/src/forge/_generated/agentQuickstart.md +0 -32
  285. package/src/forge/_generated/aiContext.ts +0 -59
  286. package/src/forge/_generated/aiModels.json +0 -2
  287. package/src/forge/_generated/aiModels.ts +0 -35
  288. package/src/forge/_generated/aiProviders.json +0 -2
  289. package/src/forge/_generated/aiProviders.ts +0 -23
  290. package/src/forge/_generated/aiRegistry.json +0 -2
  291. package/src/forge/_generated/aiRegistry.ts +0 -29
  292. package/src/forge/_generated/api.json +0 -2
  293. package/src/forge/_generated/api.ts +0 -8
  294. package/src/forge/_generated/appGraph.json +0 -2
  295. package/src/forge/_generated/appGraph.ts +0 -14667
  296. package/src/forge/_generated/appMap.md +0 -35
  297. package/src/forge/_generated/artifactManifest.json +0 -2
  298. package/src/forge/_generated/artifactManifest.ts +0 -7
  299. package/src/forge/_generated/authClaims.json +0 -2
  300. package/src/forge/_generated/authClaims.ts +0 -13
  301. package/src/forge/_generated/authConfig.json +0 -2
  302. package/src/forge/_generated/authConfig.ts +0 -17
  303. package/src/forge/_generated/authContext.ts +0 -23
  304. package/src/forge/_generated/authRegistry.json +0 -2
  305. package/src/forge/_generated/authRegistry.ts +0 -25
  306. package/src/forge/_generated/buildInfo.json +0 -2
  307. package/src/forge/_generated/buildInfo.ts +0 -9
  308. package/src/forge/_generated/capabilityMap.json +0 -2
  309. package/src/forge/_generated/capabilityMap.md +0 -15
  310. package/src/forge/_generated/capabilityMap.ts +0 -17
  311. package/src/forge/_generated/client.ts +0 -282
  312. package/src/forge/_generated/clientApi.ts +0 -9
  313. package/src/forge/_generated/clientManifest.json +0 -2
  314. package/src/forge/_generated/clientManifest.ts +0 -39
  315. package/src/forge/_generated/clientTypes.ts +0 -78
  316. package/src/forge/_generated/configRegistry.json +0 -2
  317. package/src/forge/_generated/configRegistry.ts +0 -4
  318. package/src/forge/_generated/dataGraph.json +0 -2
  319. package/src/forge/_generated/dataGraph.ts +0 -8
  320. package/src/forge/_generated/db.json +0 -2
  321. package/src/forge/_generated/db.ts +0 -2
  322. package/src/forge/_generated/dbSecurityManifest.json +0 -2
  323. package/src/forge/_generated/dbSecurityManifest.ts +0 -15
  324. package/src/forge/_generated/dbSessionContext.json +0 -2
  325. package/src/forge/_generated/dbSessionContext.ts +0 -39
  326. package/src/forge/_generated/deployManifest.json +0 -2
  327. package/src/forge/_generated/deployManifest.ts +0 -14
  328. package/src/forge/_generated/devManifest.json +0 -2
  329. package/src/forge/_generated/devManifest.ts +0 -47
  330. package/src/forge/_generated/envSchema.json +0 -2
  331. package/src/forge/_generated/envSchema.ts +0 -59
  332. package/src/forge/_generated/frontendGraph.json +0 -2
  333. package/src/forge/_generated/frontendGraph.ts +0 -27
  334. package/src/forge/_generated/importGuards.json +0 -2
  335. package/src/forge/_generated/importGuards.ts +0 -686
  336. package/src/forge/_generated/index.ts +0 -67
  337. package/src/forge/_generated/liveProductionManifest.json +0 -2
  338. package/src/forge/_generated/liveProductionManifest.ts +0 -23
  339. package/src/forge/_generated/liveProtocol.json +0 -2
  340. package/src/forge/_generated/liveProtocol.ts +0 -21
  341. package/src/forge/_generated/liveQueryRegistry.json +0 -2
  342. package/src/forge/_generated/liveQueryRegistry.ts +0 -9
  343. package/src/forge/_generated/liveTransportConfig.json +0 -2
  344. package/src/forge/_generated/liveTransportConfig.ts +0 -19
  345. package/src/forge/_generated/makeRegistry.json +0 -2
  346. package/src/forge/_generated/makeRegistry.ts +0 -163
  347. package/src/forge/_generated/makeTemplates.json +0 -2
  348. package/src/forge/_generated/makeTemplates.ts +0 -61
  349. package/src/forge/_generated/mockMap.json +0 -2
  350. package/src/forge/_generated/mockMap.ts +0 -7
  351. package/src/forge/_generated/operationPlaybooks.md +0 -147
  352. package/src/forge/_generated/packageGraph.json +0 -2
  353. package/src/forge/_generated/packageGraph.ts +0 -245249
  354. package/src/forge/_generated/packageUpgradeRegistry.json +0 -2
  355. package/src/forge/_generated/packageUpgradeRegistry.ts +0 -15
  356. package/src/forge/_generated/permissionMatrix.json +0 -2
  357. package/src/forge/_generated/permissionMatrix.ts +0 -7
  358. package/src/forge/_generated/policyRegistry.json +0 -2
  359. package/src/forge/_generated/policyRegistry.ts +0 -11
  360. package/src/forge/_generated/queryRegistry.json +0 -2
  361. package/src/forge/_generated/queryRegistry.ts +0 -9
  362. package/src/forge/_generated/react.d.ts +0 -22
  363. package/src/forge/_generated/react.ts +0 -29
  364. package/src/forge/_generated/reactManifest.json +0 -2
  365. package/src/forge/_generated/reactManifest.ts +0 -19
  366. package/src/forge/_generated/rlsPolicies.json +0 -2
  367. package/src/forge/_generated/rlsPolicies.sql +0 -34
  368. package/src/forge/_generated/rlsPolicies.ts +0 -6
  369. package/src/forge/_generated/runtimeGraph.json +0 -2
  370. package/src/forge/_generated/runtimeGraph.ts +0 -8
  371. package/src/forge/_generated/runtimeMatrix.json +0 -2
  372. package/src/forge/_generated/runtimeMatrix.ts +0 -327385
  373. package/src/forge/_generated/runtimeRegistry.ts +0 -2
  374. package/src/forge/_generated/runtimeRules.md +0 -79
  375. package/src/forge/_generated/secretRegistry.json +0 -2
  376. package/src/forge/_generated/secretRegistry.ts +0 -50
  377. package/src/forge/_generated/secretsContext.ts +0 -11
  378. package/src/forge/_generated/serverApi.ts +0 -10
  379. package/src/forge/_generated/sourceMapManifest.json +0 -2
  380. package/src/forge/_generated/sourceMapManifest.ts +0 -7
  381. package/src/forge/_generated/sqlPlan.json +0 -2
  382. package/src/forge/_generated/sqlPlan.ts +0 -88
  383. package/src/forge/_generated/subscriptionManifest.json +0 -2
  384. package/src/forge/_generated/subscriptionManifest.ts +0 -7
  385. package/src/forge/_generated/symbolicationManifest.json +0 -2
  386. package/src/forge/_generated/symbolicationManifest.ts +0 -17
  387. package/src/forge/_generated/telemetryRegistry.json +0 -2
  388. package/src/forge/_generated/telemetryRegistry.ts +0 -9
  389. package/src/forge/_generated/telemetrySinks.json +0 -2
  390. package/src/forge/_generated/telemetrySinks.ts +0 -11
  391. package/src/forge/_generated/tenantScope.json +0 -2
  392. package/src/forge/_generated/tenantScope.ts +0 -8
  393. package/src/forge/_generated/testGraph.json +0 -2
  394. package/src/forge/_generated/testGraph.ts +0 -3108
  395. package/src/forge/_generated/testPlanRegistry.json +0 -2
  396. package/src/forge/_generated/testPlanRegistry.ts +0 -33
  397. package/src/forge/_generated/uiRoutes.json +0 -2
  398. package/src/forge/_generated/uiRoutes.ts +0 -16
  399. package/src/forge/_generated/uiScenarios.json +0 -2
  400. package/src/forge/_generated/uiScenarios.ts +0 -30
  401. package/src/forge/_generated/uiTestManifest.json +0 -2
  402. package/src/forge/_generated/uiTestManifest.ts +0 -27
  403. package/src/forge/_generated/workflowRegistry.json +0 -2
  404. package/src/forge/_generated/workflowRegistry.ts +0 -9
  405. package/src/forge/_generated/workflowSubscriptions.json +0 -2
  406. package/src/forge/_generated/workflowSubscriptions.ts +0 -10
@@ -0,0 +1,77 @@
1
+ import type {
2
+ CairCommandResult,
3
+ CairObservation,
4
+ CairSnapshot,
5
+ } from "./types.ts";
6
+
7
+ function line(key: string, values: Array<string | number | boolean | null | undefined>): string {
8
+ return [key, ...values.filter((value) => value !== null && value !== undefined).map(String)].join(" ");
9
+ }
10
+
11
+ function formatObservation(observation: CairObservation): string {
12
+ return `${observation.code} ${observation.text}`.trimEnd();
13
+ }
14
+
15
+ export function formatCairSnapshotText(snapshot: CairSnapshot): string {
16
+ const sampleSymbols = snapshot.lexicon.symbols.slice(0, 8).map((symbol) =>
17
+ `${symbol.id}:${symbol.kind}:${symbol.name}@${symbol.moduleId ?? symbol.file}`,
18
+ );
19
+ const samplePackages = snapshot.lexicon.packages.slice(0, 8).map((pkg) =>
20
+ `${pkg.id}:${pkg.name}@${pkg.version}`,
21
+ );
22
+ return [
23
+ `@cair ${snapshot.schemaVersion} snapshot=${snapshot.snapshotId}`,
24
+ line("PROJECT", [`name=${snapshot.project.name}`, `version=${snapshot.project.version}`, `type=${snapshot.project.type}`]),
25
+ line("GRAPH", [
26
+ `modules=${snapshot.summary.modules}`,
27
+ `symbols=${snapshot.summary.symbols}`,
28
+ `edges=${snapshot.summary.edges}`,
29
+ `packages=${snapshot.summary.packages}`,
30
+ `apis=${snapshot.summary.apis}`,
31
+ `tests=${snapshot.summary.tests}`,
32
+ `diagnostics=${snapshot.summary.diagnostics}`,
33
+ ]),
34
+ line("TRUNCATED", [
35
+ `modules=${snapshot.truncated.modules}`,
36
+ `symbols=${snapshot.truncated.symbols}`,
37
+ `packages=${snapshot.truncated.packages}`,
38
+ `apis=${snapshot.truncated.apis}`,
39
+ `tests=${snapshot.truncated.tests}`,
40
+ ]),
41
+ ...snapshot.rules.map((rule) => line("RULE", [rule.id, rule.name])),
42
+ sampleSymbols.length > 0 ? line("SAMPLE_SYMBOLS", sampleSymbols) : "SAMPLE_SYMBOLS none",
43
+ samplePackages.length > 0 ? line("SAMPLE_PACKAGES", samplePackages) : "SAMPLE_PACKAGES none",
44
+ ...snapshot.nextActions.map((action) => line("NEXT", [action])),
45
+ "",
46
+ ].join("\n");
47
+ }
48
+
49
+ export function formatCairObservationsText(observations: CairObservation[]): string {
50
+ return `${observations.map(formatObservation).join("\n")}\n`;
51
+ }
52
+
53
+ export function formatCairHuman(result: CairCommandResult): string {
54
+ if (result.query || result.action) {
55
+ const diagnostics = result.diagnostics.map((diagnostic) =>
56
+ `${diagnostic.severity} ${diagnostic.code}: ${diagnostic.message}`,
57
+ );
58
+ return `${formatCairObservationsText(result.observations)}${diagnostics.length > 0 ? `${diagnostics.join("\n")}\n` : ""}`;
59
+ }
60
+ return formatCairSnapshotText(result.snapshot);
61
+ }
62
+
63
+ export function formatCairJson(result: CairCommandResult): string {
64
+ return `${JSON.stringify({
65
+ schemaVersion: result.snapshot.schemaVersion,
66
+ ok: result.ok,
67
+ subcommand: result.subcommand,
68
+ summary: result.snapshot.summary,
69
+ snapshot: result.subcommand === "snapshot" ? result.snapshot : undefined,
70
+ query: result.query,
71
+ action: result.action,
72
+ observations: result.observations,
73
+ diagnostics: result.diagnostics,
74
+ nextActions: result.nextActions,
75
+ exitCode: result.exitCode,
76
+ }, null, 2)}\n`;
77
+ }
@@ -0,0 +1,106 @@
1
+ import { createDiagnostic } from "../compiler/diagnostics/create.ts";
2
+ import type { Diagnostic } from "../compiler/types/diagnostic.ts";
3
+ import { runCairActionScript, statActionInput } from "./actions.ts";
4
+ import { buildCairSnapshot } from "./snapshot.ts";
5
+ import { runCairQuery } from "./query.ts";
6
+ import type { CairCommandOptions, CairCommandResult, CairSnapshotLimits } from "./types.ts";
7
+
8
+ export {
9
+ CAIR_SCHEMA_VERSION,
10
+ type CairCommandOptions,
11
+ type CairOutputFormat,
12
+ type CairSubcommand,
13
+ } from "./types.ts";
14
+ export { buildCairSnapshot } from "./snapshot.ts";
15
+ export { formatCairHuman, formatCairJson, formatCairSnapshotText } from "./format.ts";
16
+ export { runCairQuery } from "./query.ts";
17
+ export { runCairActionScript, splitCairActionScript } from "./actions.ts";
18
+
19
+ const QUERY_LIMITS: CairSnapshotLimits = {
20
+ modules: 1_000_000,
21
+ symbols: 1_000_000,
22
+ packages: 1_000_000,
23
+ apis: 1_000_000,
24
+ tests: 1_000_000,
25
+ };
26
+
27
+ export function runCairCommand(options: CairCommandOptions): CairCommandResult {
28
+ const snapshot = buildCairSnapshot(
29
+ options.workspaceRoot,
30
+ options.subcommand === "query" || options.subcommand === "action" ? QUERY_LIMITS : undefined,
31
+ );
32
+ if (options.subcommand === "query") {
33
+ const query = runCairQuery(snapshot, options.query ?? "Q HELP", options.workspaceRoot);
34
+ const diagnostics = [...snapshot.diagnostics, ...query.diagnostics];
35
+ const ok = query.ok && !diagnostics.some((diagnostic) => diagnostic.severity === "error");
36
+ return {
37
+ ok,
38
+ subcommand: options.subcommand,
39
+ snapshot,
40
+ query,
41
+ observations: query.observations,
42
+ diagnostics,
43
+ nextActions: snapshot.nextActions,
44
+ exitCode: ok ? 0 : 1,
45
+ };
46
+ }
47
+ if (options.subcommand === "action") {
48
+ let script = options.action ?? "";
49
+ const inputPath = options.inputPath;
50
+ const inputDiagnostics: Diagnostic[] = [];
51
+ if (inputPath) {
52
+ try {
53
+ script = statActionInput(options.workspaceRoot, inputPath);
54
+ } catch (error) {
55
+ inputDiagnostics.push(createDiagnostic({
56
+ severity: "error",
57
+ code: "FORGE_CAIR_ACTION_INPUT",
58
+ message: error instanceof Error ? error.message : String(error),
59
+ }));
60
+ }
61
+ }
62
+ const action = inputDiagnostics.length === 0
63
+ ? runCairActionScript({
64
+ workspaceRoot: options.workspaceRoot,
65
+ snapshot,
66
+ script,
67
+ dryRun: (options.dryRun ?? false) || (options.plan ?? false),
68
+ plan: options.plan ?? false,
69
+ allowGenerated: options.allowGenerated ?? false,
70
+ })
71
+ : {
72
+ ok: false,
73
+ dryRun: (options.dryRun ?? false) || (options.plan ?? false),
74
+ plan: options.plan ?? false,
75
+ actionCount: 0,
76
+ steps: [],
77
+ observations: [],
78
+ diagnostics: inputDiagnostics,
79
+ journalPaths: [],
80
+ planPaths: [],
81
+ };
82
+ const diagnostics = [...snapshot.diagnostics, ...action.diagnostics];
83
+ const ok = action.ok && !diagnostics.some((diagnostic) => diagnostic.severity === "error");
84
+ return {
85
+ ok,
86
+ subcommand: options.subcommand,
87
+ snapshot,
88
+ action,
89
+ observations: action.observations,
90
+ diagnostics,
91
+ nextActions: snapshot.nextActions,
92
+ exitCode: ok ? 0 : 1,
93
+ };
94
+ }
95
+
96
+ const ok = !snapshot.diagnostics.some((diagnostic) => diagnostic.severity === "error");
97
+ return {
98
+ ok,
99
+ subcommand: options.subcommand,
100
+ snapshot,
101
+ observations: [],
102
+ diagnostics: snapshot.diagnostics,
103
+ nextActions: snapshot.nextActions,
104
+ exitCode: ok ? 0 : 1,
105
+ };
106
+ }
@@ -0,0 +1,478 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { createDiagnostic } from "../compiler/diagnostics/create.ts";
4
+ import type { Diagnostic } from "../compiler/types/diagnostic.ts";
5
+ import { buildWorkspaceGitSummary } from "../workspace/git-summary.ts";
6
+ import type {
7
+ CairChangedObservation,
8
+ CairObservation,
9
+ CairQueryResult,
10
+ CairSnapshot,
11
+ CairSymbolRef,
12
+ CairTestRef,
13
+ } from "./types.ts";
14
+
15
+ function tokens(query: string): string[] {
16
+ return query.trim().split(/\s+/).filter(Boolean);
17
+ }
18
+
19
+ function keyValues(parts: string[]): Map<string, string> {
20
+ const values = new Map<string, string>();
21
+ for (const part of parts) {
22
+ const index = part.indexOf("=");
23
+ if (index <= 0) {
24
+ continue;
25
+ }
26
+ values.set(part.slice(0, index).toLowerCase(), part.slice(index + 1));
27
+ }
28
+ return values;
29
+ }
30
+
31
+ function error(query: string, message: string): CairQueryResult {
32
+ const diagnostic = createDiagnostic({
33
+ severity: "error",
34
+ code: "FORGE_CAIR_QUERY",
35
+ message,
36
+ });
37
+ return { ok: false, query, observations: [], diagnostics: [diagnostic] };
38
+ }
39
+
40
+ function observation(code: string, text: string, data?: Record<string, unknown>): CairObservation {
41
+ return data ? { code, text, data } : { code, text };
42
+ }
43
+
44
+ function statusObservations(snapshot: CairSnapshot): CairObservation[] {
45
+ return [
46
+ observation(
47
+ "O STATUS",
48
+ [
49
+ `project=${snapshot.project.name}`,
50
+ `modules=${snapshot.summary.modules}`,
51
+ `symbols=${snapshot.summary.symbols}`,
52
+ `edges=${snapshot.summary.edges}`,
53
+ `packages=${snapshot.summary.packages}`,
54
+ `apis=${snapshot.summary.apis}`,
55
+ `tests=${snapshot.summary.tests}`,
56
+ `diagnostics=${snapshot.summary.diagnostics}`,
57
+ ].join(" "),
58
+ {
59
+ project: snapshot.project,
60
+ summary: snapshot.summary,
61
+ truncated: snapshot.truncated,
62
+ },
63
+ ),
64
+ ...snapshot.rules.map((rule) =>
65
+ observation("O RULE", `${rule.id} ${rule.name}`, {
66
+ id: rule.id,
67
+ name: rule.name,
68
+ description: rule.description,
69
+ }),
70
+ ),
71
+ ];
72
+ }
73
+
74
+ function changedObservation(workspaceRoot: string): CairObservation {
75
+ const git = buildWorkspaceGitSummary(workspaceRoot);
76
+ const data: CairChangedObservation = {
77
+ available: git.available,
78
+ ...(git.branch ? { branch: git.branch } : {}),
79
+ ...(git.commit ? { commit: git.commit } : {}),
80
+ changed: git.changeSummary.changed,
81
+ staged: git.changeSummary.staged,
82
+ unstaged: git.changeSummary.unstaged,
83
+ untracked: git.changeSummary.untracked,
84
+ ...(git.error ? { error: git.error } : {}),
85
+ };
86
+ return observation(
87
+ "O CHANGED",
88
+ [
89
+ `available=${git.available}`,
90
+ git.branch ? `branch=${git.branch}` : null,
91
+ git.commit ? `commit=${git.commit}` : null,
92
+ `changed=${git.changeSummary.changed.total.count}`,
93
+ `staged=${git.changeSummary.staged.total.count}`,
94
+ `unstaged=${git.changeSummary.unstaged.total.count}`,
95
+ `untracked=${git.changeSummary.untracked.total.count}`,
96
+ `types=${git.changeSummary.changed.primaryTypes.join(",") || "none"}`,
97
+ ].filter(Boolean).join(" "),
98
+ data as unknown as Record<string, unknown>,
99
+ );
100
+ }
101
+
102
+ function findSymbol(snapshot: CairSnapshot, arg: string | undefined, kv: Map<string, string>): CairSymbolRef | null {
103
+ if (arg?.startsWith("S#")) {
104
+ return snapshot.lexicon.symbols.find((symbol) => symbol.id === arg) ?? null;
105
+ }
106
+ const name = kv.get("name") ?? arg;
107
+ if (!name) {
108
+ return null;
109
+ }
110
+ return snapshot.lexicon.symbols.find((symbol) =>
111
+ symbol.name === name || symbol.qualifiedName === name || symbol.sourceId === name,
112
+ ) ?? null;
113
+ }
114
+
115
+ function symbolObservation(symbol: CairSymbolRef): CairObservation {
116
+ return observation(
117
+ "O SYMBOL",
118
+ [
119
+ symbol.id,
120
+ `kind=${symbol.kind}`,
121
+ `name=${symbol.name}`,
122
+ `file=${symbol.file}`,
123
+ `span=${symbol.span.start}:${symbol.span.end}`,
124
+ symbol.moduleId ? `module=${symbol.moduleId}` : null,
125
+ ].filter(Boolean).join(" "),
126
+ {
127
+ symbol,
128
+ nextActions: [
129
+ `forge cair query "Q TESTS ${symbol.id}"`,
130
+ `forge cair query "Q MODULE ${symbol.moduleId ?? symbol.file}"`,
131
+ ],
132
+ },
133
+ );
134
+ }
135
+
136
+ function definitionObservation(snapshot: CairSnapshot, workspaceRoot: string, arg: string | undefined, kv: Map<string, string>): CairObservation {
137
+ const symbol = findSymbol(snapshot, arg, kv);
138
+ if (!symbol) {
139
+ return observation("O DEF", "matches=0 reason=symbol_not_found");
140
+ }
141
+ const absolute = join(workspaceRoot, symbol.file);
142
+ const source = existsSync(absolute) ? readFileSync(absolute, "utf8") : "";
143
+ const declaration = source
144
+ ? source.slice(symbol.span.start, symbol.span.end).trim()
145
+ : "";
146
+ return observation(
147
+ "O DEF",
148
+ [
149
+ `symbol=${symbol.id}`,
150
+ `file=${symbol.file}`,
151
+ `span=${symbol.span.start}:${symbol.span.end}`,
152
+ `hash=${symbol.hash}`,
153
+ ].join(" "),
154
+ {
155
+ symbol,
156
+ declaration,
157
+ nextActions: [
158
+ `forge cair query "Q REFS ${symbol.id}"`,
159
+ `forge cair query "Q IMPACT ${symbol.id}"`,
160
+ ],
161
+ },
162
+ );
163
+ }
164
+
165
+ function refsObservation(snapshot: CairSnapshot, workspaceRoot: string, arg: string | undefined, kv: Map<string, string>): CairObservation {
166
+ const symbol = findSymbol(snapshot, arg, kv);
167
+ if (!symbol) {
168
+ return observation("O REFS", "matches=0 reason=symbol_not_found", { refs: [] });
169
+ }
170
+ const regex = new RegExp(`\\b${symbol.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`, "g");
171
+ const refs: Array<{ file: string; start: number; end: number; definition: boolean }> = [];
172
+ for (const module of snapshot.lexicon.modules) {
173
+ const absolute = join(workspaceRoot, module.file);
174
+ if (!existsSync(absolute)) {
175
+ continue;
176
+ }
177
+ const text = readFileSync(absolute, "utf8");
178
+ regex.lastIndex = 0;
179
+ for (let match = regex.exec(text); match; match = regex.exec(text)) {
180
+ refs.push({
181
+ file: module.file,
182
+ start: match.index,
183
+ end: match.index + match[0].length,
184
+ definition: module.file === symbol.file && match.index >= symbol.span.start && match.index <= symbol.span.end,
185
+ });
186
+ if (match[0].length === 0) {
187
+ regex.lastIndex += 1;
188
+ }
189
+ }
190
+ }
191
+ return observation(
192
+ "O REFS",
193
+ `symbol=${symbol.id} matches=${refs.length} files=${new Set(refs.map((ref) => ref.file)).size}`,
194
+ { symbol, refs: refs.slice(0, 200), truncated: Math.max(0, refs.length - 200) },
195
+ );
196
+ }
197
+
198
+ function findModuleObservation(snapshot: CairSnapshot, arg: string | undefined): CairObservation | null {
199
+ if (!arg) {
200
+ return null;
201
+ }
202
+ const module = snapshot.lexicon.modules.find((candidate) =>
203
+ candidate.id === arg || candidate.file === arg || candidate.file.endsWith(arg),
204
+ );
205
+ if (!module) {
206
+ return null;
207
+ }
208
+ return observation(
209
+ "O MODULE",
210
+ [
211
+ module.id,
212
+ `file=${module.file}`,
213
+ `packages=${module.packageImports.join(",") || "none"}`,
214
+ `localImports=${module.localImportCount}`,
215
+ `contexts=${module.contexts.join(",") || "none"}`,
216
+ ].join(" "),
217
+ { module },
218
+ );
219
+ }
220
+
221
+ function coverageBucket(symbol: CairSymbolRef): keyof CairTestRef["covers"] | null {
222
+ switch (symbol.kind) {
223
+ case "command":
224
+ return "commands";
225
+ case "query":
226
+ return "queries";
227
+ case "liveQuery":
228
+ return "liveQueries";
229
+ case "action":
230
+ return "actions";
231
+ case "workflow":
232
+ return "workflows";
233
+ case "schema.table":
234
+ return "tables";
235
+ case "policy":
236
+ return "policies";
237
+ default:
238
+ return null;
239
+ }
240
+ }
241
+
242
+ function testsForSymbol(snapshot: CairSnapshot, symbol: CairSymbolRef): CairTestRef[] {
243
+ const bucket = coverageBucket(symbol);
244
+ if (!bucket) {
245
+ return [];
246
+ }
247
+ return snapshot.lexicon.tests.filter((test) => {
248
+ const covered = test.covers[bucket];
249
+ return covered.includes(symbol.name) || covered.includes(symbol.qualifiedName) || covered.includes(symbol.sourceId);
250
+ });
251
+ }
252
+
253
+ function testsObservation(snapshot: CairSnapshot, arg: string | undefined, kv: Map<string, string>): CairObservation {
254
+ const symbol = findSymbol(snapshot, arg, kv);
255
+ if (!symbol) {
256
+ return observation("O TESTS", "matches=0 reason=symbol_not_found", { tests: [] });
257
+ }
258
+ const tests = testsForSymbol(snapshot, symbol);
259
+ return observation(
260
+ "O TESTS",
261
+ [
262
+ `symbol=${symbol.id}`,
263
+ `matches=${tests.length}`,
264
+ tests.length > 0 ? `tests=${tests.map((test) => test.id).join(",")}` : "tests=none",
265
+ ].join(" "),
266
+ { symbol, tests },
267
+ );
268
+ }
269
+
270
+ function impactObservation(snapshot: CairSnapshot, arg: string | undefined, kv: Map<string, string>): CairObservation {
271
+ const symbol = findSymbol(snapshot, arg, kv);
272
+ if (!symbol) {
273
+ return observation("O IMPACT", "matches=0 reason=symbol_not_found", { tests: [] });
274
+ }
275
+ const tests = testsForSymbol(snapshot, symbol);
276
+ const sameFileSymbols = snapshot.lexicon.symbols.filter((candidate) => candidate.file === symbol.file);
277
+ return observation(
278
+ "O IMPACT",
279
+ [
280
+ `target=${symbol.id}`,
281
+ `tests=${tests.map((test) => test.id).join(",") || "none"}`,
282
+ `symbolsInFile=${sameFileSymbols.length}`,
283
+ `risk=${tests.length === 0 ? "unknown" : tests.length > 3 ? "medium" : "low"}`,
284
+ ].join(" "),
285
+ {
286
+ symbol,
287
+ tests,
288
+ sameFileSymbols,
289
+ nextActions: tests.map((test) => `forge test run ${test.file} --json`),
290
+ },
291
+ );
292
+ }
293
+
294
+ function depApiObservations(snapshot: CairSnapshot, parts: string[], kv: Map<string, string>): CairObservation[] {
295
+ const packageArg = kv.get("package") ?? kv.get("pkg") ?? parts.find((part) => part.startsWith("P#"));
296
+ const symbolArg = kv.get("symbol") ?? kv.get("name") ?? parts.find((part) => !part.includes("=") && !part.startsWith("P#"));
297
+ const packageName = packageArg?.startsWith("P#")
298
+ ? snapshot.lexicon.packages.find((pkg) => pkg.id === packageArg)?.name
299
+ : packageArg;
300
+
301
+ if (!packageName && !symbolArg) {
302
+ return [observation("O DEP.API", "matches=0 reason=missing_package_or_symbol")];
303
+ }
304
+
305
+ const matches = snapshot.lexicon.apis.filter((api) =>
306
+ (!packageName || api.packageName === packageName) &&
307
+ (!symbolArg || api.name === symbolArg || api.name.toLowerCase().includes(symbolArg.toLowerCase())),
308
+ );
309
+
310
+ if (matches.length === 0) {
311
+ return [
312
+ observation(
313
+ "O DEP.API",
314
+ [
315
+ "matches=0",
316
+ packageName ? `package=${packageName}` : null,
317
+ symbolArg ? `symbol=${symbolArg}` : null,
318
+ ].filter(Boolean).join(" "),
319
+ ),
320
+ ];
321
+ }
322
+
323
+ return matches.slice(0, 12).map((api) =>
324
+ observation(
325
+ "O DEP.API",
326
+ [
327
+ api.id,
328
+ `package=${api.packageName}`,
329
+ `entry=${api.entrypoint}`,
330
+ `name=${api.name}`,
331
+ `kind=${api.kind}`,
332
+ `sig=${JSON.stringify(api.signature)}`,
333
+ ].join(" "),
334
+ { api },
335
+ ),
336
+ );
337
+ }
338
+
339
+ function helpObservations(): CairObservation[] {
340
+ return [
341
+ observation("O HELP", "Q STATUS"),
342
+ observation("O HELP", "Q ST"),
343
+ observation("O HELP", "Q CHANGED"),
344
+ observation("O HELP", "Q C"),
345
+ observation("O HELP", "Q SYMBOL S#1"),
346
+ observation("O HELP", "Q S S#1"),
347
+ observation("O HELP", "Q SYMBOL name=<symbol>"),
348
+ observation("O HELP", "Q DEF S#1"),
349
+ observation("O HELP", "Q REFS S#1"),
350
+ observation("O HELP", "Q IMPACT S#1"),
351
+ observation("O HELP", "Q MODULE M#1"),
352
+ observation("O HELP", "Q M M#1"),
353
+ observation("O HELP", "Q TESTS S#1"),
354
+ observation("O HELP", "Q T S#1"),
355
+ observation("O HELP", "Q DEP.API package=<pkg> symbol=<export>"),
356
+ observation("O HELP", "A CREATE.FILE path=<repo-path> <<CODE ... CODE"),
357
+ observation("O HELP", "A CREATE.SYMBOL path=<repo-path>|file=M#1 kind=function name=<symbol> export=true"),
358
+ observation("O HELP", "A PATCH path=<repo-path> span=<start:end> hash=<sha256-prefix> <<CODE ... CODE"),
359
+ observation("O HELP", "A ADD.IMPORT file=M#1 symbol=<name> from=<specifier>"),
360
+ observation("O HELP", "A ADD.EXPORT path=<repo-path> symbol=<name> from=<specifier>"),
361
+ observation("O HELP", "A RENAME.SYMBOL target=S#1 newName=<name> expect.file=<path> expect.kind=<kind> expect.hash=<hash>"),
362
+ observation("O HELP", "A MOVE.SYMBOL target=S#1 to=<M#|path> expect.file=<path> expect.kind=<kind> expect.hash=<hash>"),
363
+ observation("O HELP", "A UPDATE.SIGNATURE target=S#1 signature=<signature> expect.file=<path> expect.kind=<kind> expect.hash=<hash>"),
364
+ observation("O HELP", "A ADD.PARAM target=S#1 name=<param> type=<type> expect.file=<path> expect.kind=<kind> expect.hash=<hash>"),
365
+ observation("O HELP", "A UPDATE.CALLSITES target=S#1 appendArg=<expr> expect.file=<path> expect.kind=<kind> expect.hash=<hash>"),
366
+ observation("O HELP", "A ORGANIZE.IMPORTS file=M#1"),
367
+ observation("O HELP", "A FORMAT file=M#1"),
368
+ observation("O HELP", "A FIND.PATTERN scope=src pattern=<ast-ish-pattern>"),
369
+ observation("O HELP", "A REWRITE.PATTERN scope=src pattern=<pattern> replacement=<replacement>"),
370
+ observation("O HELP", "A MAKE.COMMAND name=<name>"),
371
+ observation("O HELP", "A MAKE.QUERY name=<name>"),
372
+ observation("O HELP", "A MAKE.ACTION name=<name>"),
373
+ observation("O HELP", "A MAKE.TABLE name=<name> fields=<fields>"),
374
+ observation("O HELP", "A ADD.TEST target=S#1 kind=unit"),
375
+ observation("O HELP", "A WIRE.EXPORT target=S#1 file=src/index.ts"),
376
+ observation("O HELP", "A ROLLBACK journal=<path>"),
377
+ observation("O HELP", "A APPLY plan=<P#|path>"),
378
+ observation("O HELP", "A RN t=S#1 nn=<name>"),
379
+ observation("O HELP", "A OI f=M#1"),
380
+ observation("O HELP", "A FMT f=M#1"),
381
+ observation("O HELP", "A MC n=<name>"),
382
+ observation("O HELP", "A AT t=S#1"),
383
+ observation("O HELP", "A WX t=S#1"),
384
+ observation("O HELP", "V TYPECHECK"),
385
+ observation("O HELP", "V IMPACT target=S#1"),
386
+ ];
387
+ }
388
+
389
+ function normalizeQueryVerb(value: string | undefined): string | undefined {
390
+ const upper = value?.toUpperCase();
391
+ switch (upper) {
392
+ case "ST":
393
+ return "STATUS";
394
+ case "C":
395
+ return "CHANGED";
396
+ case "S":
397
+ return "SYMBOL";
398
+ case "D":
399
+ return "DEF";
400
+ case "R":
401
+ return "REFS";
402
+ case "I":
403
+ return "IMPACT";
404
+ case "M":
405
+ return "MODULE";
406
+ case "T":
407
+ return "TESTS";
408
+ case "API":
409
+ return "DEP.API";
410
+ case "H":
411
+ return "HELP";
412
+ default:
413
+ return upper;
414
+ }
415
+ }
416
+
417
+ export function runCairQuery(
418
+ snapshot: CairSnapshot,
419
+ query: string,
420
+ workspaceRoot: string,
421
+ ): CairQueryResult {
422
+ const parts = tokens(query);
423
+ if (parts.length === 0) {
424
+ return error(query, "empty CAIR query");
425
+ }
426
+ if (parts[0]?.toUpperCase() !== "Q") {
427
+ return error(query, "CAIR query must start with Q");
428
+ }
429
+ const verb = normalizeQueryVerb(parts[1]);
430
+ const rest = parts.slice(2);
431
+ const kv = keyValues(rest);
432
+ const diagnostics: Diagnostic[] = [];
433
+ let observations: CairObservation[];
434
+
435
+ switch (verb) {
436
+ case "STATUS":
437
+ observations = statusObservations(snapshot);
438
+ break;
439
+ case "CHANGED":
440
+ observations = [changedObservation(workspaceRoot)];
441
+ break;
442
+ case "SYMBOL": {
443
+ const symbol = findSymbol(snapshot, rest.find((part) => !part.includes("=")), kv);
444
+ observations = symbol
445
+ ? [symbolObservation(symbol)]
446
+ : [observation("O SYMBOL", "matches=0 reason=symbol_not_found")];
447
+ break;
448
+ }
449
+ case "DEF":
450
+ observations = [definitionObservation(snapshot, workspaceRoot, rest.find((part) => !part.includes("=")), kv)];
451
+ break;
452
+ case "REFS":
453
+ observations = [refsObservation(snapshot, workspaceRoot, rest.find((part) => !part.includes("=")), kv)];
454
+ break;
455
+ case "IMPACT":
456
+ observations = [impactObservation(snapshot, rest.find((part) => !part.includes("=")), kv)];
457
+ break;
458
+ case "MODULE": {
459
+ const module = findModuleObservation(snapshot, rest.find((part) => !part.includes("=")));
460
+ observations = module ? [module] : [observation("O MODULE", "matches=0 reason=module_not_found")];
461
+ break;
462
+ }
463
+ case "TESTS":
464
+ observations = [testsObservation(snapshot, rest.find((part) => !part.includes("=")), kv)];
465
+ break;
466
+ case "DEP.API":
467
+ observations = depApiObservations(snapshot, rest, kv);
468
+ break;
469
+ case "HELP":
470
+ case undefined:
471
+ observations = helpObservations();
472
+ break;
473
+ default:
474
+ return error(query, `unknown CAIR query verb '${verb}'`);
475
+ }
476
+
477
+ return { ok: diagnostics.length === 0, query, observations, diagnostics };
478
+ }