forgeos 0.1.0-alpha.7 → 0.1.0-alpha.71

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 (598) hide show
  1. package/.agents/skills/forge-agent-fabric/SKILL.md +178 -0
  2. package/.agents/skills/forge-agent-fabric/references/managed-workflows.md +95 -0
  3. package/.agents/skills/forge-agent-fabric/references/repository-analysis.md +102 -0
  4. package/.agents/skills/forge-agent-fabric/scripts/fabric.mjs +46 -0
  5. package/.agents/skills/forge-agent-fabric/scripts/repository.mjs +44 -0
  6. package/.npmignore +10 -0
  7. package/AGENTS.md +142 -90
  8. package/CHANGELOG.md +870 -9
  9. package/LICENSE +21 -0
  10. package/README.md +121 -6
  11. package/adapters/go/README.md +23 -0
  12. package/adapters/go/go.mod +3 -0
  13. package/adapters/go/http.go +149 -0
  14. package/adapters/go/registry.go +234 -0
  15. package/adapters/go/types.go +136 -0
  16. package/adapters/java/README.md +68 -0
  17. package/adapters/java/pom.xml +47 -0
  18. package/adapters/java/src/main/java/dev/forgeos/adapter/Auth.java +20 -0
  19. package/adapters/java/src/main/java/dev/forgeos/adapter/Diagnostic.java +16 -0
  20. package/adapters/java/src/main/java/dev/forgeos/adapter/Entry.java +38 -0
  21. package/adapters/java/src/main/java/dev/forgeos/adapter/EntryKind.java +16 -0
  22. package/adapters/java/src/main/java/dev/forgeos/adapter/ErrorInfo.java +4 -0
  23. package/adapters/java/src/main/java/dev/forgeos/adapter/Forge.java +94 -0
  24. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeCall.java +12 -0
  25. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeContext.java +11 -0
  26. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHandler.java +8 -0
  27. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHttpHandler.java +179 -0
  28. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeRegistry.java +121 -0
  29. package/adapters/java/src/main/java/dev/forgeos/adapter/Json.java +14 -0
  30. package/adapters/java/src/main/java/dev/forgeos/adapter/Manifest.java +14 -0
  31. package/adapters/java/src/main/java/dev/forgeos/adapter/RequestEnvelope.java +6 -0
  32. package/adapters/java/src/main/java/dev/forgeos/adapter/ResponseEnvelope.java +25 -0
  33. package/adapters/java/src/main/java/dev/forgeos/adapter/Risk.java +18 -0
  34. package/adapters/java/src/main/java/dev/forgeos/adapter/Schemas.java +36 -0
  35. package/adapters/java/src/main/java/dev/forgeos/adapter/Service.java +65 -0
  36. package/adapters/java/src/main/java/dev/forgeos/adapter/TransactionMode.java +18 -0
  37. package/adapters/java/src/main/java/dev/forgeos/adapter/TypedForgeHandler.java +6 -0
  38. package/adapters/java-spring-boot-starter/README.md +32 -0
  39. package/adapters/java-spring-boot-starter/pom.xml +49 -0
  40. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeCommand.java +22 -0
  41. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeExternalService.java +15 -0
  42. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeQuery.java +16 -0
  43. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeServiceBeanCondition.java +18 -0
  44. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringAutoConfiguration.java +16 -0
  45. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringRuntime.java +104 -0
  46. package/adapters/java-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +1 -0
  47. package/bin/forge.mjs +18 -0
  48. package/docs/agent-fabric-programs.md +151 -0
  49. package/docs/agent-fabric.md +582 -0
  50. package/docs/architecture/agent-fabric/PORTABLE_PROJECTS_PLAN.md +136 -0
  51. package/docs/architecture/agent-fabric/README.md +180 -0
  52. package/docs/architecture/agent-fabric/REPOSITORY_MANIFEST_PLAN.md +284 -0
  53. package/docs/architecture/agent-fabric/WORKFLOW_PROGRAM_V2_ADR.md +81 -0
  54. package/docs/architecture/agent-fabric/WORKFLOW_PROGRAM_V2_CORRECTIONS.md +39 -0
  55. package/docs/architecture/agent-fabric/WORKFLOW_PROGRAM_V2_CORRECTIONS_EVIDENCE.md +53 -0
  56. package/docs/architecture/agent-fabric/WORKFLOW_PROGRAM_V2_EVIDENCE.md +49 -0
  57. package/docs/architecture/agent-fabric/WORKFLOW_PROGRAM_V2_PLAN.md +590 -0
  58. package/docs/cair-protocol.md +103 -0
  59. package/docs/changelog.md +1070 -0
  60. package/docs/forge-protocol.md +189 -0
  61. package/docs/repository-agent-benchmark.md +179 -0
  62. package/docs/repository-analysis.md +139 -0
  63. package/docs/repository-context-quality.md +179 -0
  64. package/docs/repository-runtime-observation.md +82 -0
  65. package/examples/agent-fabric-v2/README.md +70 -0
  66. package/examples/agent-fabric-v2/item-child.workflow.ts +11 -0
  67. package/examples/agent-fabric-v2/make-request.mjs +4 -0
  68. package/examples/agent-fabric-v2/map-child.workflow.ts +10 -0
  69. package/examples/agent-fabric-v2/migrate.workflow.ts +35 -0
  70. package/examples/agent-fabric-v2/registry.example.json +256 -0
  71. package/examples/agent-fabric-v2/run-ui-fixture.ts +48 -0
  72. package/examples/agent-fabric-v2/ui-audit.workflow.ts +28 -0
  73. package/examples/agent-fabric-v2/ui-fixture-worker.cjs +36 -0
  74. package/examples/agent-fabric-v2/visual-population.json +13 -0
  75. package/examples/agent-fabric-v2/workers/check.mjs +2 -0
  76. package/examples/agent-fabric-v2/workers/common.mjs +7 -0
  77. package/examples/agent-fabric-v2/workers/discover.mjs +2 -0
  78. package/examples/agent-fabric-v2/workers/migrate.mjs +4 -0
  79. package/examples/agent-fabric-v2/workers/review.mjs +3 -0
  80. package/examples/go-billing/go.mod +7 -0
  81. package/examples/go-billing/main.go +120 -0
  82. package/examples/java-billing/pom.xml +60 -0
  83. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/CreateInvoiceInput.java +4 -0
  84. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Invoice.java +11 -0
  85. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Main.java +127 -0
  86. package/package.json +60 -5
  87. package/schemas/agent-fabric/v0.1/control-event.schema.json +281 -0
  88. package/schemas/forge-manifest.schema.json +389 -0
  89. package/scripts/field-test-forgeos.mjs +1021 -0
  90. package/scripts/install-agent-fabric-skill.mjs +105 -0
  91. package/src/forge/_generated/releaseManifest.json +1 -2
  92. package/src/forge/_generated/releaseManifest.ts +3 -3
  93. package/src/forge/agent-adapters/index.ts +1592 -125
  94. package/src/forge/agent-adapters/types.ts +225 -1
  95. package/src/forge/agent-fabric/adapter.ts +131 -0
  96. package/src/forge/agent-fabric/attached-snapshot.ts +55 -0
  97. package/src/forge/agent-fabric/attached-task-contract.ts +105 -0
  98. package/src/forge/agent-fabric/attached-task-service.ts +127 -0
  99. package/src/forge/agent-fabric/attached-task-store.ts +109 -0
  100. package/src/forge/agent-fabric/authority.ts +298 -0
  101. package/src/forge/agent-fabric/canonical.ts +135 -0
  102. package/src/forge/agent-fabric/codex-adversarial-review.ts +229 -0
  103. package/src/forge/agent-fabric/codex-sdk-worker.ts +203 -0
  104. package/src/forge/agent-fabric/conductor.ts +754 -0
  105. package/src/forge/agent-fabric/dictionary.ts +12 -0
  106. package/src/forge/agent-fabric/errors.ts +32 -0
  107. package/src/forge/agent-fabric/hardened-conductor.ts +485 -0
  108. package/src/forge/agent-fabric/hardened-reducer.ts +211 -0
  109. package/src/forge/agent-fabric/index.ts +48 -0
  110. package/src/forge/agent-fabric/journal.ts +116 -0
  111. package/src/forge/agent-fabric/local-adaptive-digest-worker.mjs +26 -0
  112. package/src/forge/agent-fabric/local-adaptive-harness.ts +343 -0
  113. package/src/forge/agent-fabric/local-adaptive-service.ts +398 -0
  114. package/src/forge/agent-fabric/local-adaptive-worker.ts +146 -0
  115. package/src/forge/agent-fabric/local-approval-window.ts +211 -0
  116. package/src/forge/agent-fabric/local-change-review-service.ts +374 -0
  117. package/src/forge/agent-fabric/local-coding-worker.ts +285 -0
  118. package/src/forge/agent-fabric/local-control-store.ts +239 -0
  119. package/src/forge/agent-fabric/local-effect-broker.ts +348 -0
  120. package/src/forge/agent-fabric/local-evolution-approval.ts +81 -0
  121. package/src/forge/agent-fabric/local-evolution-profile.ts +87 -0
  122. package/src/forge/agent-fabric/local-evolution-registry.ts +427 -0
  123. package/src/forge/agent-fabric/local-evolution-service.ts +200 -0
  124. package/src/forge/agent-fabric/local-intelligence.ts +281 -0
  125. package/src/forge/agent-fabric/local-paths.ts +18 -0
  126. package/src/forge/agent-fabric/local-task-contract.ts +203 -0
  127. package/src/forge/agent-fabric/local-task-inbox.ts +543 -0
  128. package/src/forge/agent-fabric/local-task-server.ts +374 -0
  129. package/src/forge/agent-fabric/local-task-service.ts +982 -0
  130. package/src/forge/agent-fabric/local-verification.ts +551 -0
  131. package/src/forge/agent-fabric/managed-environment.ts +205 -0
  132. package/src/forge/agent-fabric/managed-run-contract.ts +103 -0
  133. package/src/forge/agent-fabric/managed-run-service.ts +401 -0
  134. package/src/forge/agent-fabric/managed-run-store.ts +165 -0
  135. package/src/forge/agent-fabric/managed-workspace.ts +253 -0
  136. package/src/forge/agent-fabric/p0a.ts +104 -0
  137. package/src/forge/agent-fabric/p0b-model-adapter.ts +434 -0
  138. package/src/forge/agent-fabric/planning.ts +155 -0
  139. package/src/forge/agent-fabric/program-api.ts +37 -0
  140. package/src/forge/agent-fabric/program-contract.ts +283 -0
  141. package/src/forge/agent-fabric/program-dsl.ts +126 -0
  142. package/src/forge/agent-fabric/program-evidence.ts +22 -0
  143. package/src/forge/agent-fabric/program-image.ts +15 -0
  144. package/src/forge/agent-fabric/program-lock.ts +50 -0
  145. package/src/forge/agent-fabric/program-owner.ts +16 -0
  146. package/src/forge/agent-fabric/program-scheduler.ts +38 -0
  147. package/src/forge/agent-fabric/program-service.ts +793 -0
  148. package/src/forge/agent-fabric/program-store.ts +142 -0
  149. package/src/forge/agent-fabric/program-structure.ts +65 -0
  150. package/src/forge/agent-fabric/program-types.ts +110 -0
  151. package/src/forge/agent-fabric/program-view.ts +12 -0
  152. package/src/forge/agent-fabric/program-worker.ts +108 -0
  153. package/src/forge/agent-fabric/project-profile.ts +50 -0
  154. package/src/forge/agent-fabric/project-registry.ts +120 -0
  155. package/src/forge/agent-fabric/project-runtime.ts +85 -0
  156. package/src/forge/agent-fabric/readiness.ts +26 -0
  157. package/src/forge/agent-fabric/reducer.ts +863 -0
  158. package/src/forge/agent-fabric/repository-context.ts +83 -0
  159. package/src/forge/agent-fabric/resource-ledger.ts +266 -0
  160. package/src/forge/agent-fabric/serialized-local-adapter.ts +60 -0
  161. package/src/forge/agent-fabric/types.ts +424 -0
  162. package/src/forge/agent-fabric/validation.ts +500 -0
  163. package/src/forge/agent-fabric/workflow-engine.ts +218 -0
  164. package/src/forge/agent-fabric/workflow-task-actions.ts +104 -0
  165. package/src/forge/agent-fabric/workflow-templates.ts +11 -0
  166. package/src/forge/agent-memory/bridge.ts +1728 -0
  167. package/src/forge/agent-memory/context-pack.ts +284 -0
  168. package/src/forge/agent-memory/hook-runner.ts +331 -0
  169. package/src/forge/agent-memory/mcp.ts +597 -0
  170. package/src/forge/agent-memory/normalize.ts +498 -0
  171. package/src/forge/agent-memory/redaction.ts +103 -0
  172. package/src/forge/agent-memory/sources/claude-code.ts +51 -0
  173. package/src/forge/agent-memory/sources/codex-hook-runner.mjs +343 -0
  174. package/src/forge/agent-memory/sources/codex.ts +161 -0
  175. package/src/forge/agent-memory/sources/cursor.ts +35 -0
  176. package/src/forge/agent-memory/types.ts +215 -0
  177. package/src/forge/bench.ts +248 -0
  178. package/src/forge/brownfield-import/index.ts +896 -0
  179. package/src/forge/brownfield-import/types.ts +127 -0
  180. package/src/forge/cair/action-journal.ts +61 -0
  181. package/src/forge/cair/action-parser.ts +314 -0
  182. package/src/forge/cair/action-validator.ts +40 -0
  183. package/src/forge/cair/actions.ts +1818 -0
  184. package/src/forge/cair/format.ts +77 -0
  185. package/src/forge/cair/index.ts +118 -0
  186. package/src/forge/cair/query.ts +478 -0
  187. package/src/forge/cair/snapshot.ts +315 -0
  188. package/src/forge/cair/types.ts +255 -0
  189. package/src/forge/cli/adaptive.ts +51 -0
  190. package/src/forge/cli/ai.ts +16 -1
  191. package/src/forge/cli/auth.ts +459 -15
  192. package/src/forge/cli/authmd.ts +441 -0
  193. package/src/forge/cli/baseline.ts +112 -0
  194. package/src/forge/cli/build.ts +20 -4
  195. package/src/forge/cli/changed.ts +418 -0
  196. package/src/forge/cli/codex-app-server.ts +877 -0
  197. package/src/forge/cli/commands.ts +1859 -20
  198. package/src/forge/cli/db.ts +209 -2
  199. package/src/forge/cli/deploy.ts +1339 -0
  200. package/src/forge/cli/deps.ts +150 -23
  201. package/src/forge/cli/dev.ts +1137 -53
  202. package/src/forge/cli/docs.ts +265 -0
  203. package/src/forge/cli/doctor.ts +297 -0
  204. package/src/forge/cli/env-placeholders.ts +62 -0
  205. package/src/forge/cli/evolution.ts +40 -0
  206. package/src/forge/cli/fabric.ts +253 -0
  207. package/src/forge/cli/field-test.ts +568 -0
  208. package/src/forge/cli/golden-path.ts +487 -0
  209. package/src/forge/cli/handoff.ts +336 -0
  210. package/src/forge/cli/index.ts +1 -0
  211. package/src/forge/cli/last-run.ts +84 -0
  212. package/src/forge/cli/main.ts +196 -3
  213. package/src/forge/cli/new.ts +169 -17
  214. package/src/forge/cli/next-actions.ts +23 -0
  215. package/src/forge/cli/output.ts +398 -6
  216. package/src/forge/cli/parse.ts +1377 -38
  217. package/src/forge/cli/progress.ts +51 -0
  218. package/src/forge/cli/query.ts +32 -0
  219. package/src/forge/cli/release.ts +35 -11
  220. package/src/forge/cli/repository.ts +151 -0
  221. package/src/forge/cli/run.ts +42 -0
  222. package/src/forge/cli/secrets.ts +137 -1
  223. package/src/forge/cli/seed.ts +581 -0
  224. package/src/forge/cli/self-host.ts +56 -14
  225. package/src/forge/cli/studio.ts +2282 -0
  226. package/src/forge/cli/verify.ts +1458 -32
  227. package/src/forge/cli/windows.ts +23 -0
  228. package/src/forge/cli/workos.ts +3509 -0
  229. package/src/forge/compiler/agent-contract/build.ts +728 -64
  230. package/src/forge/compiler/agent-contract/types.ts +45 -2
  231. package/src/forge/compiler/ai-registry/parse.ts +71 -2
  232. package/src/forge/compiler/api-surface/build.ts +47 -0
  233. package/src/forge/compiler/app-graph/build.ts +112 -9
  234. package/src/forge/compiler/app-graph/extract.ts +107 -0
  235. package/src/forge/compiler/app-graph/module-graph.ts +73 -78
  236. package/src/forge/compiler/app-graph/parser.ts +24 -24
  237. package/src/forge/compiler/app-graph/profile.ts +26 -0
  238. package/src/forge/compiler/app-graph/tsconfig-hash.ts +41 -4
  239. package/src/forge/compiler/app-graph/versions.ts +1 -1
  240. package/src/forge/compiler/classifier/capabilities.ts +3 -2
  241. package/src/forge/compiler/classifier/classify.ts +32 -8
  242. package/src/forge/compiler/classifier/secrets.ts +3 -2
  243. package/src/forge/compiler/classifier/signals.ts +91 -1
  244. package/src/forge/compiler/client-sdk/build-manifest.ts +59 -0
  245. package/src/forge/compiler/client-sdk/render-client.ts +295 -13
  246. package/src/forge/compiler/data-graph/build.ts +29 -1
  247. package/src/forge/compiler/data-graph/parse.ts +20 -4
  248. package/src/forge/compiler/data-graph/sql/ddl.ts +144 -31
  249. package/src/forge/compiler/data-graph/sql/serialize.ts +4 -0
  250. package/src/forge/compiler/data-graph/sql/types.ts +1 -0
  251. package/src/forge/compiler/diagnostics/codes.ts +38 -0
  252. package/src/forge/compiler/diagnostics/create.ts +28 -2
  253. package/src/forge/compiler/diagnostics/index.ts +2 -0
  254. package/src/forge/compiler/emitter/barrel.ts +3 -0
  255. package/src/forge/compiler/emitter/render.ts +9 -0
  256. package/src/forge/compiler/external-manifest/registry.ts +217 -0
  257. package/src/forge/compiler/external-manifest/types.ts +91 -0
  258. package/src/forge/compiler/external-manifest/validate.ts +373 -0
  259. package/src/forge/compiler/frontend-graph/build.ts +142 -14
  260. package/src/forge/compiler/integration/add.ts +991 -33
  261. package/src/forge/compiler/integration/plan.ts +43 -12
  262. package/src/forge/compiler/integration/render.ts +29 -0
  263. package/src/forge/compiler/integration/snapshot.ts +2 -0
  264. package/src/forge/compiler/integration/templates/convex.ts +70 -0
  265. package/src/forge/compiler/integration/templates/index.ts +1 -0
  266. package/src/forge/compiler/integration/templates/render.ts +38 -0
  267. package/src/forge/compiler/integration/templates/types.ts +3 -0
  268. package/src/forge/compiler/integration/templates/workos.ts +1439 -0
  269. package/src/forge/compiler/make-registry/build.ts +8 -9
  270. package/src/forge/compiler/orchestrator/fast-check.ts +4 -0
  271. package/src/forge/compiler/orchestrator/generate-lock.ts +14 -3
  272. package/src/forge/compiler/orchestrator/manifest.ts +1 -1
  273. package/src/forge/compiler/orchestrator/plan-profile.ts +23 -0
  274. package/src/forge/compiler/orchestrator/plan.ts +249 -10
  275. package/src/forge/compiler/orchestrator/profile.ts +65 -0
  276. package/src/forge/compiler/orchestrator/run.ts +101 -33
  277. package/src/forge/compiler/orchestrator/serialize.ts +33 -8
  278. package/src/forge/compiler/orchestrator/types.ts +1 -1
  279. package/src/forge/compiler/package-graph/compiler.ts +3 -1
  280. package/src/forge/compiler/package-graph/constants.ts +1 -1
  281. package/src/forge/compiler/package-graph/dts-extractor.ts +14 -1
  282. package/src/forge/compiler/package-manager/adapter.ts +4 -1
  283. package/src/forge/compiler/package-manager/commands.ts +4 -0
  284. package/src/forge/compiler/package-manager/executor.ts +30 -1
  285. package/src/forge/compiler/package-manager/version.ts +36 -12
  286. package/src/forge/compiler/package-upgrades/planner.ts +155 -18
  287. package/src/forge/compiler/package-upgrades/types.ts +2 -0
  288. package/src/forge/compiler/policy-registry/build.ts +47 -2
  289. package/src/forge/compiler/policy-registry/parse.ts +32 -2
  290. package/src/forge/compiler/recipes/definitions.ts +63 -0
  291. package/src/forge/compiler/recipes/index.ts +2 -0
  292. package/src/forge/compiler/recipes/profiles.ts +81 -0
  293. package/src/forge/compiler/recipes/registry.ts +6 -0
  294. package/src/forge/compiler/test-graph/build.ts +11 -3
  295. package/src/forge/compiler/types/app-graph.ts +8 -2
  296. package/src/forge/compiler/types/cli.ts +76 -1
  297. package/src/forge/compiler/types/dev-manifest.ts +4 -0
  298. package/src/forge/compiler/types/emit.ts +2 -0
  299. package/src/forge/compiler/types/frontend-graph.ts +2 -2
  300. package/src/forge/compiler/types/integration.ts +1 -0
  301. package/src/forge/compiler/types/package-graph.ts +6 -0
  302. package/src/forge/compiler/types/policy-registry.ts +3 -1
  303. package/src/forge/delta/broker-runner.mjs +5 -0
  304. package/src/forge/delta/broker.ts +429 -0
  305. package/src/forge/delta/classifier.ts +52 -0
  306. package/src/forge/delta/explain.ts +238 -0
  307. package/src/forge/delta/git-observer.ts +67 -0
  308. package/src/forge/delta/ids.ts +44 -0
  309. package/src/forge/delta/index.ts +25 -0
  310. package/src/forge/delta/process-identity.ts +37 -0
  311. package/src/forge/delta/queue-status.ts +190 -0
  312. package/src/forge/delta/recorder.ts +540 -0
  313. package/src/forge/delta/redaction.ts +50 -0
  314. package/src/forge/delta/schema.ts +240 -0
  315. package/src/forge/delta/session.ts +142 -0
  316. package/src/forge/delta/status.ts +1139 -0
  317. package/src/forge/delta/store.ts +3329 -0
  318. package/src/forge/delta/timeline.ts +178 -0
  319. package/src/forge/dev/server.ts +1061 -22
  320. package/src/forge/dev/types.ts +15 -1
  321. package/src/forge/dev/watch.ts +17 -7
  322. package/src/forge/dev-console/cycle.ts +285 -33
  323. package/src/forge/dev-console/types.ts +47 -1
  324. package/src/forge/impact/index.ts +222 -30
  325. package/src/forge/impact/types.ts +33 -1
  326. package/src/forge/intent/index.ts +35 -16
  327. package/src/forge/make/fields.ts +26 -0
  328. package/src/forge/make/index.ts +42 -6
  329. package/src/forge/make/templates.ts +211 -4
  330. package/src/forge/make/types.ts +2 -1
  331. package/src/forge/policy.ts +1 -1
  332. package/src/forge/react/index.ts +160 -2
  333. package/src/forge/refactor/index.ts +1 -0
  334. package/src/forge/repair/rules/index.ts +2 -2
  335. package/src/forge/repository-analysis/adapters/common.ts +72 -0
  336. package/src/forge/repository-analysis/adapters/docker.ts +185 -0
  337. package/src/forge/repository-analysis/adapters/java.ts +133 -0
  338. package/src/forge/repository-analysis/adapters/typescript.ts +350 -0
  339. package/src/forge/repository-analysis/adapters/vue.ts +71 -0
  340. package/src/forge/repository-analysis/analyze.ts +434 -0
  341. package/src/forge/repository-analysis/benchmark.ts +336 -0
  342. package/src/forge/repository-analysis/cache-gc.ts +154 -0
  343. package/src/forge/repository-analysis/check-selection.ts +123 -0
  344. package/src/forge/repository-analysis/context-node.ts +17 -0
  345. package/src/forge/repository-analysis/context.ts +456 -0
  346. package/src/forge/repository-analysis/http-resolution.ts +135 -0
  347. package/src/forge/repository-analysis/identity.ts +45 -0
  348. package/src/forge/repository-analysis/index.ts +18 -0
  349. package/src/forge/repository-analysis/nuxt-resolution.ts +188 -0
  350. package/src/forge/repository-analysis/quality.ts +60 -0
  351. package/src/forge/repository-analysis/retrieval.ts +309 -0
  352. package/src/forge/repository-analysis/runtime-artifacts.ts +195 -0
  353. package/src/forge/repository-analysis/runtime-observation.ts +325 -0
  354. package/src/forge/repository-analysis/scanner.ts +174 -0
  355. package/src/forge/repository-analysis/storage.ts +193 -0
  356. package/src/forge/repository-analysis/test-associations.ts +59 -0
  357. package/src/forge/repository-analysis/types.ts +99 -0
  358. package/src/forge/repository-manifest/index.ts +178 -0
  359. package/src/forge/repository-manifest/types.ts +63 -0
  360. package/src/forge/review/index.ts +162 -12
  361. package/src/forge/review/types.ts +15 -0
  362. package/src/forge/runtime/ai/providers.ts +19 -4
  363. package/src/forge/runtime/auth/config.ts +17 -0
  364. package/src/forge/runtime/auth/evaluate.ts +15 -2
  365. package/src/forge/runtime/auth/resolve.ts +61 -6
  366. package/src/forge/runtime/auth/types.ts +1 -0
  367. package/src/forge/runtime/db/factory.ts +1 -3
  368. package/src/forge/runtime/db/generated-client.ts +13 -2
  369. package/src/forge/runtime/db/memory-adapter.ts +139 -32
  370. package/src/forge/runtime/db/pglite-adapter.ts +285 -2
  371. package/src/forge/runtime/executor.ts +129 -16
  372. package/src/forge/runtime/external/bridge.ts +663 -0
  373. package/src/forge/runtime/runner/run-entry.ts +16 -7
  374. package/src/forge/runtime/telemetry/buffer.ts +4 -1
  375. package/src/forge/runtime/telemetry/scrubber.ts +35 -5
  376. package/src/forge/runtime/webhooks/security.ts +12 -7
  377. package/src/forge/server.ts +71 -7
  378. package/src/forge/ui/index.ts +831 -19
  379. package/src/forge/ui/types.ts +3 -1
  380. package/src/forge/version.ts +1 -1
  381. package/src/forge/vue/index.ts +422 -0
  382. package/src/forge/workspace/baseline.ts +112 -0
  383. package/src/forge/workspace/change-summary.ts +292 -0
  384. package/src/forge/workspace/forge-cli.ts +42 -0
  385. package/src/forge/workspace/git-summary.ts +393 -0
  386. package/templates/agent-workroom/AGENTS.md +29 -0
  387. package/templates/agent-workroom/README.md +34 -0
  388. package/templates/agent-workroom/forge.config.ts +3 -0
  389. package/templates/agent-workroom/package.json +34 -0
  390. package/templates/agent-workroom/pnpm-workspace.yaml +2 -0
  391. package/templates/agent-workroom/src/actions/indexAgentSignal.ts +10 -0
  392. package/templates/agent-workroom/src/commands/openWorkroom.ts +61 -0
  393. package/templates/agent-workroom/src/commands/recordAgentSignal.ts +119 -0
  394. package/templates/agent-workroom/src/commands/recordCheckRun.ts +52 -0
  395. package/templates/agent-workroom/src/forge/schema.ts +54 -0
  396. package/templates/agent-workroom/src/policies.ts +6 -0
  397. package/templates/agent-workroom/src/queries/listWorkrooms.ts +11 -0
  398. package/templates/agent-workroom/src/queries/liveWorkroom.ts +63 -0
  399. package/templates/agent-workroom/tsconfig.json +16 -0
  400. package/templates/agent-workroom/web/index.html +13 -0
  401. package/templates/agent-workroom/web/package.json +21 -0
  402. package/templates/agent-workroom/web/src/App.tsx +345 -0
  403. package/templates/agent-workroom/web/src/lib/forge.ts +20 -0
  404. package/templates/agent-workroom/web/src/main.tsx +13 -0
  405. package/templates/agent-workroom/web/src/styles.css +545 -0
  406. package/templates/agent-workroom/web/tsconfig.json +27 -0
  407. package/templates/agent-workroom/web/vite.config.ts +36 -0
  408. package/templates/b2b-support-web/package.json +2 -0
  409. package/templates/b2b-support-web/pnpm-workspace.yaml +2 -0
  410. package/templates/b2b-support-web/web/app/page.tsx +2 -2
  411. package/templates/b2b-support-web/web/lib/forge.ts +9 -2
  412. package/templates/b2b-support-web/web/next.config.ts +24 -0
  413. package/templates/b2b-support-web/web/package.json +1 -1
  414. package/templates/minimal-web/package.json +2 -1
  415. package/templates/minimal-web/pnpm-workspace.yaml +2 -0
  416. package/templates/minimal-web/web/index.html +1 -0
  417. package/templates/minimal-web/web/src/App.tsx +12 -6
  418. package/templates/minimal-web/web/src/lib/forge.ts +9 -2
  419. package/templates/minimal-web/web/src/styles.css +34 -0
  420. package/templates/minimal-web/web/vite.config.ts +36 -0
  421. package/templates/nuxt-web/.vscode/settings.json +14 -0
  422. package/templates/nuxt-web/.yarnrc.yml +1 -0
  423. package/templates/nuxt-web/README.md +30 -0
  424. package/templates/nuxt-web/forge.config.ts +3 -0
  425. package/templates/nuxt-web/package.json +37 -0
  426. package/templates/nuxt-web/pnpm-workspace.yaml +2 -0
  427. package/templates/nuxt-web/src/actions/logNoteCreated.ts +11 -0
  428. package/templates/nuxt-web/src/commands/createNote.ts +26 -0
  429. package/templates/nuxt-web/src/forge/schema.ts +12 -0
  430. package/templates/nuxt-web/src/policies.ts +6 -0
  431. package/templates/nuxt-web/src/queries/listNotes.ts +8 -0
  432. package/templates/nuxt-web/src/queries/liveNotes.ts +8 -0
  433. package/templates/nuxt-web/tsconfig.json +17 -0
  434. package/templates/nuxt-web/web/app.vue +67 -0
  435. package/templates/nuxt-web/web/components/LiveNotes.vue +89 -0
  436. package/templates/nuxt-web/web/components/NoteComposer.vue +100 -0
  437. package/templates/nuxt-web/web/composables/forge.ts +13 -0
  438. package/templates/nuxt-web/web/composables/useNotes.ts +24 -0
  439. package/templates/nuxt-web/web/nuxt.config.ts +11 -0
  440. package/templates/nuxt-web/web/package.json +22 -0
  441. package/templates/nuxt-web/web/plugins/forge.client.ts +10 -0
  442. package/templates/nuxt-web/web/plugins/forge.server.ts +10 -0
  443. package/templates/nuxt-web/web/server/api/forge-health.get.ts +7 -0
  444. package/templates/nuxt-web/web/tsconfig.json +6 -0
  445. package/templates/vendor-access/.vscode/settings.json +14 -0
  446. package/templates/vendor-access/README.md +30 -0
  447. package/templates/vendor-access/forge.config.ts +3 -0
  448. package/templates/vendor-access/package.json +35 -0
  449. package/templates/vendor-access/pnpm-workspace.yaml +2 -0
  450. package/templates/vendor-access/src/commands/addEvidence.ts +42 -0
  451. package/templates/vendor-access/src/commands/approveAccessRequest.ts +43 -0
  452. package/templates/vendor-access/src/commands/createAccessRequest.ts +49 -0
  453. package/templates/vendor-access/src/commands/seedVendorAccessDemo.ts +200 -0
  454. package/templates/vendor-access/src/forge/schema.ts +74 -0
  455. package/templates/vendor-access/src/policies.ts +11 -0
  456. package/templates/vendor-access/src/queries/listVendorAccessDashboard.ts +24 -0
  457. package/templates/vendor-access/src/queries/liveVendorAccessDashboard.ts +24 -0
  458. package/templates/vendor-access/tsconfig.json +17 -0
  459. package/templates/vendor-access/web/index.html +13 -0
  460. package/templates/vendor-access/web/package.json +21 -0
  461. package/templates/vendor-access/web/src/App.tsx +573 -0
  462. package/templates/vendor-access/web/src/lib/forge.ts +20 -0
  463. package/templates/vendor-access/web/src/main.tsx +205 -0
  464. package/templates/vendor-access/web/src/styles.css +682 -0
  465. package/templates/vendor-access/web/tsconfig.json +18 -0
  466. package/templates/vendor-access/web/vite.config.ts +36 -0
  467. package/src/forge/_generated/actionSubscriptions.json +0 -2
  468. package/src/forge/_generated/actionSubscriptions.ts +0 -10
  469. package/src/forge/_generated/agentAdapterManifest.json +0 -2
  470. package/src/forge/_generated/agentAdapterManifest.ts +0 -73
  471. package/src/forge/_generated/agentContract.json +0 -2
  472. package/src/forge/_generated/agentContract.ts +0 -7829
  473. package/src/forge/_generated/agentQuickstart.md +0 -34
  474. package/src/forge/_generated/agentTools.json +0 -2
  475. package/src/forge/_generated/agentTools.md +0 -16
  476. package/src/forge/_generated/agentTools.ts +0 -12
  477. package/src/forge/_generated/aiContext.ts +0 -125
  478. package/src/forge/_generated/aiModels.json +0 -2
  479. package/src/forge/_generated/aiModels.ts +0 -51
  480. package/src/forge/_generated/aiProviders.json +0 -2
  481. package/src/forge/_generated/aiProviders.ts +0 -23
  482. package/src/forge/_generated/aiRegistry.json +0 -2
  483. package/src/forge/_generated/aiRegistry.ts +0 -31
  484. package/src/forge/_generated/api.json +0 -2
  485. package/src/forge/_generated/api.ts +0 -8
  486. package/src/forge/_generated/appGraph.json +0 -2
  487. package/src/forge/_generated/appGraph.ts +0 -14937
  488. package/src/forge/_generated/appMap.md +0 -55
  489. package/src/forge/_generated/artifactManifest.json +0 -2
  490. package/src/forge/_generated/artifactManifest.ts +0 -7
  491. package/src/forge/_generated/authClaims.json +0 -2
  492. package/src/forge/_generated/authClaims.ts +0 -13
  493. package/src/forge/_generated/authConfig.json +0 -2
  494. package/src/forge/_generated/authConfig.ts +0 -17
  495. package/src/forge/_generated/authContext.ts +0 -23
  496. package/src/forge/_generated/authRegistry.json +0 -2
  497. package/src/forge/_generated/authRegistry.ts +0 -25
  498. package/src/forge/_generated/buildInfo.json +0 -2
  499. package/src/forge/_generated/buildInfo.ts +0 -9
  500. package/src/forge/_generated/capabilityMap.json +0 -2
  501. package/src/forge/_generated/capabilityMap.md +0 -15
  502. package/src/forge/_generated/capabilityMap.ts +0 -17
  503. package/src/forge/_generated/client.ts +0 -282
  504. package/src/forge/_generated/clientApi.ts +0 -9
  505. package/src/forge/_generated/clientManifest.json +0 -2
  506. package/src/forge/_generated/clientManifest.ts +0 -39
  507. package/src/forge/_generated/clientTypes.ts +0 -78
  508. package/src/forge/_generated/configRegistry.json +0 -2
  509. package/src/forge/_generated/configRegistry.ts +0 -4
  510. package/src/forge/_generated/dataGraph.json +0 -2
  511. package/src/forge/_generated/dataGraph.ts +0 -8
  512. package/src/forge/_generated/db.json +0 -2
  513. package/src/forge/_generated/db.ts +0 -2
  514. package/src/forge/_generated/dbSecurityManifest.json +0 -2
  515. package/src/forge/_generated/dbSecurityManifest.ts +0 -15
  516. package/src/forge/_generated/dbSessionContext.json +0 -2
  517. package/src/forge/_generated/dbSessionContext.ts +0 -39
  518. package/src/forge/_generated/deployManifest.json +0 -2
  519. package/src/forge/_generated/deployManifest.ts +0 -14
  520. package/src/forge/_generated/devManifest.json +0 -2
  521. package/src/forge/_generated/devManifest.ts +0 -62
  522. package/src/forge/_generated/envSchema.json +0 -2
  523. package/src/forge/_generated/envSchema.ts +0 -59
  524. package/src/forge/_generated/frontendGraph.json +0 -2
  525. package/src/forge/_generated/frontendGraph.ts +0 -27
  526. package/src/forge/_generated/importGuards.json +0 -2
  527. package/src/forge/_generated/importGuards.ts +0 -686
  528. package/src/forge/_generated/index.ts +0 -68
  529. package/src/forge/_generated/liveProductionManifest.json +0 -2
  530. package/src/forge/_generated/liveProductionManifest.ts +0 -23
  531. package/src/forge/_generated/liveProtocol.json +0 -2
  532. package/src/forge/_generated/liveProtocol.ts +0 -21
  533. package/src/forge/_generated/liveQueryRegistry.json +0 -2
  534. package/src/forge/_generated/liveQueryRegistry.ts +0 -9
  535. package/src/forge/_generated/liveTransportConfig.json +0 -2
  536. package/src/forge/_generated/liveTransportConfig.ts +0 -19
  537. package/src/forge/_generated/makeRegistry.json +0 -2
  538. package/src/forge/_generated/makeRegistry.ts +0 -177
  539. package/src/forge/_generated/makeTemplates.json +0 -2
  540. package/src/forge/_generated/makeTemplates.ts +0 -66
  541. package/src/forge/_generated/mockMap.json +0 -2
  542. package/src/forge/_generated/mockMap.ts +0 -7
  543. package/src/forge/_generated/operationPlaybooks.md +0 -167
  544. package/src/forge/_generated/packageGraph.json +0 -2
  545. package/src/forge/_generated/packageGraph.ts +0 -249334
  546. package/src/forge/_generated/packageUpgradeRegistry.json +0 -2
  547. package/src/forge/_generated/packageUpgradeRegistry.ts +0 -15
  548. package/src/forge/_generated/permissionMatrix.json +0 -2
  549. package/src/forge/_generated/permissionMatrix.ts +0 -7
  550. package/src/forge/_generated/policyRegistry.json +0 -2
  551. package/src/forge/_generated/policyRegistry.ts +0 -11
  552. package/src/forge/_generated/queryRegistry.json +0 -2
  553. package/src/forge/_generated/queryRegistry.ts +0 -9
  554. package/src/forge/_generated/react.d.ts +0 -22
  555. package/src/forge/_generated/react.ts +0 -29
  556. package/src/forge/_generated/reactManifest.json +0 -2
  557. package/src/forge/_generated/reactManifest.ts +0 -19
  558. package/src/forge/_generated/rlsPolicies.json +0 -2
  559. package/src/forge/_generated/rlsPolicies.sql +0 -34
  560. package/src/forge/_generated/rlsPolicies.ts +0 -6
  561. package/src/forge/_generated/runtimeGraph.json +0 -2
  562. package/src/forge/_generated/runtimeGraph.ts +0 -8
  563. package/src/forge/_generated/runtimeMatrix.json +0 -2
  564. package/src/forge/_generated/runtimeMatrix.ts +0 -334130
  565. package/src/forge/_generated/runtimeRegistry.ts +0 -2
  566. package/src/forge/_generated/runtimeRules.md +0 -91
  567. package/src/forge/_generated/secretRegistry.json +0 -2
  568. package/src/forge/_generated/secretRegistry.ts +0 -50
  569. package/src/forge/_generated/secretsContext.ts +0 -11
  570. package/src/forge/_generated/serverApi.ts +0 -10
  571. package/src/forge/_generated/sourceMapManifest.json +0 -2
  572. package/src/forge/_generated/sourceMapManifest.ts +0 -7
  573. package/src/forge/_generated/sqlPlan.json +0 -2
  574. package/src/forge/_generated/sqlPlan.ts +0 -88
  575. package/src/forge/_generated/subscriptionManifest.json +0 -2
  576. package/src/forge/_generated/subscriptionManifest.ts +0 -7
  577. package/src/forge/_generated/symbolicationManifest.json +0 -2
  578. package/src/forge/_generated/symbolicationManifest.ts +0 -17
  579. package/src/forge/_generated/telemetryRegistry.json +0 -2
  580. package/src/forge/_generated/telemetryRegistry.ts +0 -9
  581. package/src/forge/_generated/telemetrySinks.json +0 -2
  582. package/src/forge/_generated/telemetrySinks.ts +0 -11
  583. package/src/forge/_generated/tenantScope.json +0 -2
  584. package/src/forge/_generated/tenantScope.ts +0 -8
  585. package/src/forge/_generated/testGraph.json +0 -2
  586. package/src/forge/_generated/testGraph.ts +0 -3452
  587. package/src/forge/_generated/testPlanRegistry.json +0 -2
  588. package/src/forge/_generated/testPlanRegistry.ts +0 -33
  589. package/src/forge/_generated/uiRoutes.json +0 -2
  590. package/src/forge/_generated/uiRoutes.ts +0 -16
  591. package/src/forge/_generated/uiScenarios.json +0 -2
  592. package/src/forge/_generated/uiScenarios.ts +0 -30
  593. package/src/forge/_generated/uiTestManifest.json +0 -2
  594. package/src/forge/_generated/uiTestManifest.ts +0 -27
  595. package/src/forge/_generated/workflowRegistry.json +0 -2
  596. package/src/forge/_generated/workflowRegistry.ts +0 -9
  597. package/src/forge/_generated/workflowSubscriptions.json +0 -2
  598. package/src/forge/_generated/workflowSubscriptions.ts +0 -10
@@ -0,0 +1,568 @@
1
+ import { spawn } from "node:child_process";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { dirname, isAbsolute, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { runNewCommand, type NewPackageManager, type NewTemplateName } from "./new.ts";
6
+ import { normalizeForgeCliCommandsInValue } from "../workspace/forge-cli.ts";
7
+
8
+ export type FieldTestSubcommand = "create" | "run" | "report";
9
+
10
+ export interface FieldTestCommandOptions {
11
+ subcommand: FieldTestSubcommand;
12
+ workspaceRoot: string;
13
+ json: boolean;
14
+ name?: string;
15
+ template: NewTemplateName;
16
+ templates?: NewTemplateName[];
17
+ packageManager: NewPackageManager;
18
+ packageManagers?: NewPackageManager[];
19
+ forgeSpec?: string;
20
+ auth?: "none" | "workos";
21
+ dryRun: boolean;
22
+ keep: boolean;
23
+ runtimeProbes: boolean;
24
+ authProbes: boolean;
25
+ uiProbes: boolean;
26
+ realistic: boolean;
27
+ timeoutMs: number;
28
+ writeReport?: string;
29
+ }
30
+
31
+ export interface FieldTestCommandResult {
32
+ schemaVersion: "0.1.0";
33
+ ok: boolean;
34
+ kind: "field-test";
35
+ action: FieldTestSubcommand;
36
+ data?: unknown;
37
+ summary?: unknown;
38
+ command?: string[];
39
+ reportPath?: string;
40
+ stdout?: string;
41
+ stderr?: string;
42
+ nextActions: string[];
43
+ exitCode: 0 | 1;
44
+ }
45
+
46
+ function scriptCandidates(workspaceRoot: string): string[] {
47
+ const localScript = join(workspaceRoot, "scripts", "field-test-forgeos.mjs");
48
+ const packageScript = join(dirname(fileURLToPath(import.meta.url)), "../../../scripts/field-test-forgeos.mjs");
49
+ return Array.from(new Set([localScript, packageScript]));
50
+ }
51
+
52
+ function scriptPath(workspaceRoot: string): string | null {
53
+ return scriptCandidates(workspaceRoot).find((candidate) => existsSync(candidate)) ?? null;
54
+ }
55
+
56
+ function compact(text: string, limit = 12000): string {
57
+ if (text.length <= limit) return text;
58
+ const half = Math.floor(limit / 2);
59
+ return `${text.slice(0, half)}\n...[truncated ${text.length - limit} chars]...\n${text.slice(-half)}`;
60
+ }
61
+
62
+ function defaultReportPath(): string {
63
+ return ".forge/field-test-report.json";
64
+ }
65
+
66
+ function resolveReportPath(workspaceRoot: string, reportPath: string): string {
67
+ return isAbsolute(reportPath) ? reportPath : join(workspaceRoot, reportPath);
68
+ }
69
+
70
+ function parseJsonOutput(text: string): unknown | null {
71
+ const trimmed = text.trim();
72
+ if (!trimmed) return null;
73
+ try {
74
+ return JSON.parse(trimmed) as unknown;
75
+ } catch {
76
+ const start = trimmed.indexOf("{");
77
+ const end = trimmed.lastIndexOf("}");
78
+ if (start === -1 || end <= start) return null;
79
+ try {
80
+ return JSON.parse(trimmed.slice(start, end + 1)) as unknown;
81
+ } catch {
82
+ return null;
83
+ }
84
+ }
85
+ }
86
+
87
+ function summarizeReport(data: unknown) {
88
+ const root = data && typeof data === "object" ? data as Record<string, unknown> : {};
89
+ const results = Array.isArray(root.results) ? root.results as Array<Record<string, unknown>> : [];
90
+ const plannedCases = Array.isArray(root.cases) ? root.cases as Array<Record<string, unknown>> : [];
91
+ const failed = results.filter((result) => result.ok === false && result.skipped !== true);
92
+ const skipped = results.filter((result) => result.skipped === true);
93
+ const topLevelSteps = results.flatMap((result) =>
94
+ Array.isArray(result.steps) ? result.steps as unknown[] : [],
95
+ );
96
+ const runtimeProbeSteps = results.flatMap((result) => {
97
+ const runtime = result.runtime && typeof result.runtime === "object"
98
+ ? result.runtime as Record<string, unknown>
99
+ : {};
100
+ return Array.isArray(runtime.steps) ? runtime.steps as unknown[] : [];
101
+ });
102
+ const hasVendorAccessCase = results.some((result) => result.template === "vendor-access");
103
+ const commandOf = (step: unknown): string =>
104
+ step && typeof step === "object" && typeof (step as { command?: unknown }).command === "string"
105
+ ? (step as { command: string }).command
106
+ : "";
107
+ const stdoutOf = (step: unknown): string =>
108
+ step && typeof step === "object" && typeof (step as { stdout?: unknown }).stdout === "string"
109
+ ? (step as { stdout: string }).stdout
110
+ : "";
111
+ const okStep = (step: unknown): boolean =>
112
+ Boolean(step && typeof step === "object" && (step as { ok?: unknown }).ok === true);
113
+ const jsonOfStep = (step: unknown): Record<string, unknown> | null => {
114
+ const stdout = stdoutOf(step).trim();
115
+ if (!stdout) return null;
116
+ const parsed = parseJsonOutput(stdout);
117
+ return parsed && typeof parsed === "object" ? parsed as Record<string, unknown> : null;
118
+ };
119
+ const hasOkRuntimeCommand = (pattern: RegExp): boolean =>
120
+ runtimeProbeSteps.some((step) => okStep(step) && pattern.test(commandOf(step)));
121
+ const hasOkTopLevelCommand = (pattern: RegExp): boolean =>
122
+ topLevelSteps.some((step) => okStep(step) && pattern.test(commandOf(step)));
123
+ const seedProbeSteps = runtimeProbeSteps.filter((step) => commandOf(step).includes("seed-"));
124
+ const seedReadinessSteps = runtimeProbeSteps.filter((step) => commandOf(step).includes("seed-status"));
125
+ const seedReadinessResults = seedReadinessSteps
126
+ .filter((step) => okStep(step))
127
+ .map((step) => {
128
+ const payload = jsonOfStep(step);
129
+ const readiness = payload?.readiness && typeof payload.readiness === "object"
130
+ ? payload.readiness as Record<string, unknown>
131
+ : {};
132
+ const recovery = Array.isArray(readiness.emptyWorkspaceRecovery)
133
+ ? readiness.emptyWorkspaceRecovery.filter((item) => typeof item === "string")
134
+ : [];
135
+ return {
136
+ ready: readiness.ready === true,
137
+ autoSeedOnDev: readiness.autoSeedOnDev === true,
138
+ autoSeedAllTenantsOnDev: readiness.autoSeedAllTenantsOnDev === true,
139
+ autoSeedMode: typeof readiness.autoSeedMode === "string" ? readiness.autoSeedMode : undefined,
140
+ selectedCommand: typeof readiness.selectedCommand === "string" ? readiness.selectedCommand : undefined,
141
+ recoveryCommands: recovery.length,
142
+ };
143
+ });
144
+ const seedReadinessEvidence = !hasVendorAccessCase || seedReadinessResults.some((result) =>
145
+ result.ready &&
146
+ result.selectedCommand === "seedVendorAccessDemo" &&
147
+ result.recoveryCommands >= 2,
148
+ );
149
+ const seedAllTenantsAutoSeedEvidence = !hasVendorAccessCase || seedReadinessResults.some((result) =>
150
+ result.ready &&
151
+ result.selectedCommand === "seedVendorAccessDemo" &&
152
+ (result.autoSeedMode === "all-tenants" || result.autoSeedAllTenantsOnDev),
153
+ );
154
+ const vendorAccessProbeSteps = runtimeProbeSteps.filter((step) => commandOf(step).includes("vendor-access-"));
155
+ const uiProbeSteps = runtimeProbeSteps.filter((step) => /^GET\s+https?:\/\/[^/]+\/$/i.test(commandOf(step)));
156
+ const authMetadataProbeSteps = runtimeProbeSteps.filter((step) =>
157
+ /^(HEAD|GET)\s+https?:\/\/[^/]+\/(auth\.md|\.well-known\/oauth-protected-resource)\b/i.test(commandOf(step)),
158
+ );
159
+ const authSetupProbeSteps = topLevelSteps.filter((step) =>
160
+ /forge\s+(?:--\s+)?(add\s+auth\s+workos|authmd\s+generate|authmd\s+check|workos\s+doctor|workos\s+seed|workos\s+prove|auth\s+prove)/.test(commandOf(step)),
161
+ );
162
+ const uiErgonomicsResults = results
163
+ .map((result) => result.uiErgonomics)
164
+ .filter((value): value is Record<string, unknown> => Boolean(value && typeof value === "object"));
165
+ const uiErgonomicsWarnings = uiErgonomicsResults.reduce((total, result) =>
166
+ total + (typeof result.warnings === "number" ? result.warnings : 0), 0);
167
+ const uiErgonomicsErrors = uiErgonomicsResults.reduce((total, result) =>
168
+ total + (typeof result.errors === "number" ? result.errors : 0), 0);
169
+ const uiErgonomicsWarningCodes = Array.from(new Set(uiErgonomicsResults.flatMap((result) =>
170
+ Array.isArray(result.diagnosticCodes)
171
+ ? result.diagnosticCodes.filter((code): code is string => typeof code === "string")
172
+ : [],
173
+ ))).sort();
174
+ const uiScenarioNames = Array.from(new Set(uiErgonomicsResults.flatMap((result) =>
175
+ Array.isArray(result.scenarioNames)
176
+ ? result.scenarioNames.filter((name): name is string => typeof name === "string")
177
+ : [],
178
+ ))).sort();
179
+ const vendorAccessRequiredUiScenarios = [
180
+ "vendor-access-autoseed-data-visible",
181
+ "vendor-access-local-login",
182
+ "vendor-access-requester-denied-visible",
183
+ "vendor-access-seed-control-visible",
184
+ ];
185
+ const ok = root.ok === true;
186
+ const runtimeProbes = root.runtimeProbes === true;
187
+ const authProbes = root.authProbes === true;
188
+ const uiProbes = root.uiProbes === true;
189
+ const uiErgonomics = !uiProbes || (results.length > 0 && uiErgonomicsResults.length === results.filter((result) => result.skipped !== true).length);
190
+ const runtimeHealthEvidence = !runtimeProbes || hasOkRuntimeCommand(/\bGET\s+.*\/health\b/i);
191
+ const runtimeEntriesEvidence = !runtimeProbes || hasOkRuntimeCommand(/\bGET\s+.*\/entries\b/i);
192
+ const authSetupEvidence = !authProbes || [
193
+ /forge\s+(?:--\s+)?add\s+auth\s+workos\b/,
194
+ /forge\s+(?:--\s+)?authmd\s+generate\b/,
195
+ /forge\s+(?:--\s+)?authmd\s+check\b/,
196
+ /forge\s+(?:--\s+)?workos\s+doctor\b/,
197
+ /forge\s+(?:--\s+)?workos\s+seed\b/,
198
+ /forge\s+(?:--\s+)?workos\s+prove\b/,
199
+ /forge\s+(?:--\s+)?auth\s+prove\b/,
200
+ ].every((pattern) => hasOkTopLevelCommand(pattern));
201
+ const authMetadataEvidence = !authProbes || [
202
+ /^HEAD\s+.*\/auth\.md\b/i,
203
+ /^GET\s+.*\/auth\.md\b/i,
204
+ /^HEAD\s+.*\/\.well-known\/oauth-protected-resource\b/i,
205
+ /^GET\s+.*\/\.well-known\/oauth-protected-resource\b/i,
206
+ ].every((pattern) => hasOkRuntimeCommand(pattern));
207
+ const uiProbeEvidence = !uiProbes || uiProbeSteps.some((step) => okStep(step));
208
+ const vendorAccessSeedEvidence = !hasVendorAccessCase ||
209
+ hasOkRuntimeCommand(/vendor-access-seed-all-tenants:/) ||
210
+ [
211
+ /vendor-access-seed-acme:/,
212
+ /vendor-access-seed-globex:/,
213
+ ].every((pattern) => hasOkRuntimeCommand(pattern));
214
+ const vendorAccessEvidence = !hasVendorAccessCase || (
215
+ vendorAccessSeedEvidence &&
216
+ [
217
+ /vendor-access-query-acme:/,
218
+ /vendor-access-query-globex:/,
219
+ /vendor-access-owner-approve:/,
220
+ /vendor-access-requester-approve-denied:/,
221
+ /vendor-access-cross-tenant-approve-denied:/,
222
+ ].every((pattern) => hasOkRuntimeCommand(pattern))
223
+ );
224
+ const vendorAccessUiScenarioEvidence = !hasVendorAccessCase || !uiProbes ||
225
+ vendorAccessRequiredUiScenarios.every((scenario) => uiScenarioNames.includes(scenario));
226
+ const productionEvidenceMissing = [
227
+ ...(!ok ? ["passing field-test report"] : []),
228
+ ...(!runtimeProbes ? ["runtime probes"] : []),
229
+ ...(!authProbes ? ["auth probes"] : []),
230
+ ...(!uiProbes ? ["ui probes"] : []),
231
+ ...(!runtimeHealthEvidence ? ["runtime health probe"] : []),
232
+ ...(!runtimeEntriesEvidence ? ["runtime entries probe"] : []),
233
+ ...(!authSetupEvidence ? ["auth setup probes"] : []),
234
+ ...(!authMetadataEvidence ? ["auth metadata endpoint probes"] : []),
235
+ ...(!uiProbeEvidence ? ["web UI probe"] : []),
236
+ ...(!seedReadinessEvidence ? ["seed readiness evidence"] : []),
237
+ ...(!seedAllTenantsAutoSeedEvidence ? ["seed readiness all-tenants auto-seed evidence"] : []),
238
+ ...(!vendorAccessEvidence ? ["vendor-access multi-tenant domain probes"] : []),
239
+ ...(!vendorAccessUiScenarioEvidence ? ["vendor-access UI scenarios"] : []),
240
+ ...(!uiErgonomics ? ["UI ergonomics audit"] : []),
241
+ ...(uiErgonomicsWarnings > 0 ? ["zero UI ergonomics warnings"] : []),
242
+ ...(uiErgonomicsErrors > 0 ? ["zero UI ergonomics errors"] : []),
243
+ ...(failed.length > 0 ? ["zero failed cases"] : []),
244
+ ];
245
+ return {
246
+ ok,
247
+ cases: results.length || plannedCases.length,
248
+ executedCases: results.length,
249
+ plannedCases: plannedCases.length,
250
+ passed: results.filter((result) => result.ok === true && result.skipped !== true).length,
251
+ failed: failed.length,
252
+ skipped: skipped.length,
253
+ runtimeProbes,
254
+ authProbes,
255
+ uiProbes,
256
+ uiErgonomics,
257
+ uiErgonomicsWarnings,
258
+ uiErgonomicsErrors,
259
+ uiErgonomicsWarningCodes,
260
+ uiScenarios: {
261
+ names: uiScenarioNames,
262
+ vendorAccessReady: vendorAccessUiScenarioEvidence,
263
+ requiredVendorAccess: hasVendorAccessCase ? vendorAccessRequiredUiScenarios : [],
264
+ },
265
+ runtimeProbeSteps: runtimeProbeSteps.length,
266
+ seedProbeSteps: seedProbeSteps.length,
267
+ seedReadiness: {
268
+ ready: seedReadinessEvidence,
269
+ steps: seedReadinessSteps.length,
270
+ autoSeedOnDev: seedReadinessResults.some((result) => result.autoSeedOnDev),
271
+ autoSeedAllTenantsOnDev: seedReadinessResults.some((result) => result.autoSeedAllTenantsOnDev),
272
+ allTenantsAutoSeedReady: seedAllTenantsAutoSeedEvidence,
273
+ autoSeedModes: Array.from(new Set(seedReadinessResults
274
+ .map((result) => result.autoSeedMode)
275
+ .filter((value): value is string => Boolean(value)))),
276
+ selectedCommands: Array.from(new Set(seedReadinessResults
277
+ .map((result) => result.selectedCommand)
278
+ .filter((value): value is string => Boolean(value)))),
279
+ },
280
+ authSetupProbeSteps: authSetupProbeSteps.length,
281
+ authMetadataProbeSteps: authMetadataProbeSteps.length,
282
+ uiProbeSteps: uiProbeSteps.length,
283
+ vendorAccessProbeSteps: vendorAccessProbeSteps.length,
284
+ productionEvidence: {
285
+ readyForDeployCheck: productionEvidenceMissing.length === 0,
286
+ missing: productionEvidenceMissing,
287
+ deployCheckCommand: "forge deploy check --production --json",
288
+ note: "This proves field-test evidence only; deploy check still validates production auth, database, metadata, lockfile, and tenant posture.",
289
+ },
290
+ failedCases: failed.map((result) => ({
291
+ template: result.template,
292
+ packageManager: result.packageManager,
293
+ reason: result.reason,
294
+ })),
295
+ };
296
+ }
297
+
298
+ function runCommandForOptions(templates: NewTemplateName[], packageManagers: NewPackageManager[]): string {
299
+ return [
300
+ "forge field-test run --realistic",
301
+ `--templates ${templates.join(",")}`,
302
+ `--package-managers ${packageManagers.join(",")}`,
303
+ "--json",
304
+ ].join(" ");
305
+ }
306
+
307
+ async function createFieldTestApp(options: FieldTestCommandOptions): Promise<FieldTestCommandResult> {
308
+ if (!options.name) {
309
+ return {
310
+ schemaVersion: "0.1.0",
311
+ ok: false,
312
+ kind: "field-test",
313
+ action: "create",
314
+ data: { error: "forge field-test create requires an app name" },
315
+ nextActions: ["forge field-test create vendor-access --auth workos --json"],
316
+ exitCode: 1,
317
+ };
318
+ }
319
+ if (options.dryRun) {
320
+ const forgeSpecFlag = options.forgeSpec ? ` --forge-spec ${options.forgeSpec}` : "";
321
+ return normalizeForgeCliCommandsInValue(options.workspaceRoot, {
322
+ schemaVersion: "0.1.0",
323
+ ok: true,
324
+ kind: "field-test",
325
+ action: "create",
326
+ data: {
327
+ dryRun: true,
328
+ name: options.name,
329
+ template: options.template,
330
+ packageManager: options.packageManager,
331
+ auth: options.auth,
332
+ forgeSpec: options.forgeSpec,
333
+ install: true,
334
+ git: true,
335
+ command: `forge new ${options.name} --template ${options.template} --package-manager ${options.packageManager}${forgeSpecFlag} --field-test --install`,
336
+ goldenPath: [
337
+ `forge field-test create ${options.name} --auth ${options.auth ?? "none"} --template ${options.template} --package-manager ${options.packageManager}${forgeSpecFlag} --install --git --json`,
338
+ `cd ${options.name}`,
339
+ "forge field-test run --realistic --json",
340
+ "forge field-test report --json",
341
+ "forge deploy plan --target docker --json",
342
+ "forge deploy check --production --json",
343
+ ],
344
+ },
345
+ nextActions: [
346
+ `forge field-test create ${options.name} --auth ${options.auth ?? "none"} --template ${options.template} --package-manager ${options.packageManager}${forgeSpecFlag} --install --git --json`,
347
+ ],
348
+ exitCode: 0,
349
+ });
350
+ }
351
+ const created = await runNewCommand({
352
+ name: options.name,
353
+ template: options.template,
354
+ packageManager: options.packageManager,
355
+ install: true,
356
+ git: true,
357
+ fieldTest: options.auth === "workos",
358
+ forgePackageSpec: options.forgeSpec,
359
+ workspaceRoot: options.workspaceRoot,
360
+ });
361
+ const createdFieldTest = created.fieldTest?.steps ?? [];
362
+ return normalizeForgeCliCommandsInValue(options.workspaceRoot, {
363
+ schemaVersion: "0.1.0",
364
+ ok: created.exitCode === 0,
365
+ kind: "field-test",
366
+ action: "create",
367
+ data: {
368
+ ...created,
369
+ auth: options.auth,
370
+ setup: options.auth === "workos"
371
+ ? {
372
+ applied: createdFieldTest.length > 0 && createdFieldTest.every((step) => step.ok),
373
+ steps: createdFieldTest,
374
+ }
375
+ : {
376
+ applied: false,
377
+ steps: [],
378
+ note: "auth=none creates a plain app; pass --auth workos for WorkOS/AuthKit/auth.md field-test setup.",
379
+ },
380
+ },
381
+ nextActions: [
382
+ `cd ${created.targetDir}`,
383
+ `${options.packageManager} run forge -- agent onboard --target codex --json`,
384
+ `${options.packageManager} run forge -- generate`,
385
+ `${options.packageManager} run forge -- check --json`,
386
+ ...(options.auth === "workos"
387
+ ? [
388
+ `${options.packageManager} run forge -- authmd check --json`,
389
+ `${options.packageManager} run forge -- workos doctor --json`,
390
+ `${options.packageManager} run forge -- workos seed --file workos-seed.yml --dry-run --json`,
391
+ `${options.packageManager} run forge -- workos prove --file workos-seed.yml --json`,
392
+ `${options.packageManager} run forge -- workos setup --file workos-seed.yml --json`,
393
+ ]
394
+ : []),
395
+ `${options.packageManager} run forge -- field-test run --realistic --json`,
396
+ `${options.packageManager} run forge -- field-test report --json`,
397
+ `${options.packageManager} run forge -- dev --once --json`,
398
+ `${options.packageManager} run forge -- verify --smoke --json`,
399
+ `${options.packageManager} run forge -- handoff --json`,
400
+ ],
401
+ exitCode: created.exitCode,
402
+ });
403
+ }
404
+
405
+ function shouldEmitProgress(): boolean {
406
+ return process.env.FORGE_FIELD_TEST_PROGRESS !== "0";
407
+ }
408
+
409
+ function runHarnessProcess(
410
+ options: FieldTestCommandOptions,
411
+ args: string[],
412
+ ): Promise<{ status: number | null; stdout: string; stderr: string }> {
413
+ return new Promise((resolve) => {
414
+ const startedAt = Date.now();
415
+ const emitProgress = shouldEmitProgress();
416
+ const child = spawn(process.execPath, args, {
417
+ cwd: options.workspaceRoot,
418
+ stdio: ["ignore", "pipe", "pipe"],
419
+ windowsHide: true,
420
+ });
421
+ let stdout = "";
422
+ let stderr = "";
423
+ let settled = false;
424
+ child.stdout?.setEncoding("utf8");
425
+ child.stderr?.setEncoding("utf8");
426
+ child.stdout?.on("data", (chunk) => {
427
+ stdout += chunk;
428
+ });
429
+ child.stderr?.on("data", (chunk) => {
430
+ stderr += chunk;
431
+ });
432
+ const heartbeat = emitProgress
433
+ ? setInterval(() => {
434
+ const elapsed = Math.round((Date.now() - startedAt) / 1000);
435
+ process.stderr.write(`[forge] field-test still running after ${elapsed}s; timeout=${options.timeoutMs}ms\n`);
436
+ }, 30_000)
437
+ : undefined;
438
+ const finish = (status: number | null, extraStderr = "") => {
439
+ if (settled) return;
440
+ settled = true;
441
+ if (heartbeat) clearInterval(heartbeat);
442
+ if (extraStderr) stderr += extraStderr;
443
+ resolve({ status, stdout, stderr });
444
+ };
445
+ child.on("error", (error) => {
446
+ finish(1, `${error.message}\n`);
447
+ });
448
+ child.on("close", (status) => {
449
+ finish(status);
450
+ });
451
+ });
452
+ }
453
+
454
+ async function runHarness(options: FieldTestCommandOptions): Promise<FieldTestCommandResult> {
455
+ const script = scriptPath(options.workspaceRoot);
456
+ if (!script) {
457
+ return {
458
+ schemaVersion: "0.1.0",
459
+ ok: false,
460
+ kind: "field-test",
461
+ action: "run",
462
+ data: { error: "field-test harness script not found", searched: scriptCandidates(options.workspaceRoot) },
463
+ nextActions: ["upgrade forgeos to a version that includes scripts/field-test-forgeos.mjs", "run from the ForgeOS framework checkout with npm run field:test"],
464
+ exitCode: 1,
465
+ };
466
+ }
467
+ const reportPath = options.writeReport ?? (options.dryRun ? undefined : defaultReportPath());
468
+ const templates = options.templates?.length ? options.templates : [options.template];
469
+ const packageManagers = options.packageManagers?.length ? options.packageManagers : [options.packageManager];
470
+ const args = [
471
+ script,
472
+ "--templates",
473
+ templates.join(","),
474
+ "--package-managers",
475
+ packageManagers.join(","),
476
+ "--timeout-ms",
477
+ String(options.timeoutMs),
478
+ ];
479
+ if (options.dryRun) args.push("--dry-run");
480
+ if (options.keep) args.push("--keep");
481
+ if (options.runtimeProbes || options.realistic) args.push("--runtime-probes");
482
+ if (options.authProbes || options.realistic) args.push("--auth-probes");
483
+ if (options.uiProbes || options.realistic) args.push("--ui-probes");
484
+ if (options.forgeSpec) args.push("--forge-spec", options.forgeSpec);
485
+ if (reportPath) args.push("--write-report", reportPath);
486
+ if (options.json) args.push("--json");
487
+ const result = await runHarnessProcess(options, args);
488
+ const reportAbsolute = reportPath ? resolveReportPath(options.workspaceRoot, reportPath) : null;
489
+ const reportData = reportAbsolute && existsSync(reportAbsolute)
490
+ ? JSON.parse(readFileSync(reportAbsolute, "utf8")) as unknown
491
+ : parseJsonOutput(result.stdout ?? "");
492
+ return normalizeForgeCliCommandsInValue(options.workspaceRoot, {
493
+ schemaVersion: "0.1.0",
494
+ ok: result.status === 0,
495
+ kind: "field-test",
496
+ action: "run",
497
+ command: [process.execPath, ...args],
498
+ reportPath,
499
+ data: reportData ?? undefined,
500
+ summary: reportData ? summarizeReport(reportData) : undefined,
501
+ stdout: compact(result.stdout ?? ""),
502
+ stderr: compact(result.stderr ?? ""),
503
+ nextActions: result.status === 0
504
+ ? options.dryRun
505
+ ? [runCommandForOptions(templates, packageManagers)]
506
+ : [`forge field-test report --file ${reportPath ?? defaultReportPath()} --json`, "forge deploy check --production --json"]
507
+ : ["inspect field-test stdout/stderr", "forge doctor pglite --json"],
508
+ exitCode: result.status === 0 ? 0 : 1,
509
+ });
510
+ }
511
+
512
+ function readReport(options: FieldTestCommandOptions): FieldTestCommandResult {
513
+ const candidates = [
514
+ options.writeReport,
515
+ ".forge/field-test-report.json",
516
+ "field-reports/full-alpha.json",
517
+ ].filter(Boolean) as string[];
518
+ const report = candidates.find((candidate) => existsSync(resolveReportPath(options.workspaceRoot, candidate)));
519
+ if (!report) {
520
+ return {
521
+ schemaVersion: "0.1.0",
522
+ ok: false,
523
+ kind: "field-test",
524
+ action: "report",
525
+ data: { searched: candidates },
526
+ nextActions: ["forge field-test run --realistic --write-report .forge/field-test-report.json --json"],
527
+ exitCode: 1,
528
+ };
529
+ }
530
+ const data = JSON.parse(readFileSync(resolveReportPath(options.workspaceRoot, report), "utf8")) as unknown;
531
+ const summary = summarizeReport(data);
532
+ const productionEvidence = (summary as { productionEvidence?: { readyForDeployCheck?: boolean } }).productionEvidence;
533
+ return {
534
+ schemaVersion: "0.1.0",
535
+ ok: (data && typeof data === "object" && "ok" in data) ? (data as { ok?: unknown }).ok === true : true,
536
+ kind: "field-test",
537
+ action: "report",
538
+ reportPath: report,
539
+ summary,
540
+ data,
541
+ nextActions: productionEvidence?.readyForDeployCheck
542
+ ? ["forge deploy check --production --json"]
543
+ : ["forge field-test run --realistic --write-report .forge/field-test-report.json --json"],
544
+ exitCode: (data && typeof data === "object" && "ok" in data && (data as { ok?: unknown }).ok !== true) ? 1 : 0,
545
+ };
546
+ }
547
+
548
+ export async function runFieldTestCommand(options: FieldTestCommandOptions): Promise<FieldTestCommandResult> {
549
+ if (options.subcommand === "create") return createFieldTestApp(options);
550
+ if (options.subcommand === "run") return runHarness(options);
551
+ return readReport(options);
552
+ }
553
+
554
+ export function formatFieldTestJson(result: FieldTestCommandResult): string {
555
+ return `${JSON.stringify(result, null, 2)}\n`;
556
+ }
557
+
558
+ export function formatFieldTestHuman(result: FieldTestCommandResult): string {
559
+ const lines = [
560
+ `field-test ${result.action} ${result.ok ? "ok" : "failed"}`,
561
+ ...(result.reportPath ? [`report: ${result.reportPath}`] : []),
562
+ ...(result.command ? [`command: ${result.command.join(" ")}`] : []),
563
+ ...(result.stdout ? ["", result.stdout] : []),
564
+ ...(result.stderr ? ["", result.stderr] : []),
565
+ ...(result.nextActions.length ? ["", "Next:", ...result.nextActions.map((action) => ` ${action}`)] : []),
566
+ ];
567
+ return `${lines.join("\n")}\n`;
568
+ }