forgeos 0.1.0-alpha.2 → 0.1.0-alpha.20

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 +199 -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 +212 -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 +1192 -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 +84 -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 +736 -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
package/README.md CHANGED
@@ -2,9 +2,13 @@
2
2
 
3
3
  Agent-native application framework and compiler for building Forge apps without a mandatory dashboard. ForgeOS turns application source into deterministic runtime contracts, generated clients, safety checks, and machine-readable context that humans and AI coding agents can use safely.
4
4
 
5
- **Status:** private/public alpha MVP, implemented through H42. The core compiler, local runtime, frontend SDK, production auth, RLS compiler, repair/review loops, UI test bridge, guided intent router, full-stack capability map, clean templates, faster generated checks, showcase app, Windows-safe Bun resolution, native Windows diagnostics/setup, Node-compatible CLI/runtime paths, observable verify timeouts, multi-OS Node CI smoke, release packaging smoke, npm alpha publishing, Trusted Publisher/OIDC release wiring, ReadTheDocs-ready public docs, package/version-aligned generator metadata, AST-aware codemods for `extract-action`, `rename field`, and `rename table`, broader field-test automation, and quieter template workspaces are present. Public release hardening is still focused on deeper semantic codemods and more real-project field reports.
5
+ **Status:** private/public alpha MVP, implemented through H49. ForgeOS already includes the compiler, local runtime, frontend SDK, production auth, RLS compiler, liveQuery, self-host artifacts, generated agent contract, guided dev loop, repair/review/test tooling, AST-aware codemods, package intelligence, native AI tools/agents, DeltaDB work memory, external agent memory ingestion, brownfield import analysis, npm alpha publishing, and Read the Docs public docs. Public release hardening is still focused on deeper semantic codemods, broader field reports, and more production mileage.
6
6
 
7
- Public docs are configured for ReadTheDocs with `.readthedocs.yaml` and `mkdocs.yml`. The local docs entrypoint is `docs/index.md`.
7
+ Public docs live at [forgeos.readthedocs.io](https://forgeos.readthedocs.io/). The repo builds them with `.readthedocs.yaml`, `mkdocs.yml`, and `docs/index.md`.
8
+
9
+ Start with [Why ForgeOS](https://forgeos.readthedocs.io/en/latest/why-forgeos/) to understand the agent-native design.
10
+
11
+ For the short version, read [The Five-Minute ForgeOS Model](https://forgeos.readthedocs.io/en/latest/five-minute-model/) and [Alpha Golden Path](https://forgeos.readthedocs.io/en/latest/golden-path/). The important distinction is that external coding agents are the primary ForgeOS workflow; integrated AI SDK features are available for apps that need in-product AI, but they are not the main development loop.
8
12
 
9
13
  ## Agent-First Quickstart
10
14
 
@@ -47,7 +51,7 @@ These files describe the app surface, runtime rules, generated files, policies,
47
51
  Public one-command app creation:
48
52
 
49
53
  ```bash
50
- npm create forge-app@alpha notes-app -- --template minimal-web
54
+ npm create forgeos-app@alpha notes-app -- --template minimal-web
51
55
  cd notes-app
52
56
  npm run dev
53
57
  ```
@@ -89,6 +93,39 @@ npm run field:test -- --package-managers npm --templates minimal-web --forge-spe
89
93
 
90
94
  The scheduled/manual `Field Tests` workflow expands that coverage across Linux, macOS, Windows, Node 22, Node 24, and npm/pnpm/yarn/bun.
91
95
 
96
+ ## External Runtimes And Adapters
97
+
98
+ ForgeOS can import services written outside TypeScript through the Forge Protocol.
99
+ External runtimes publish a `forge.manifest.json` that describes commands, queries,
100
+ transport, policies, risk metadata, tenant scope, and schemas. Forge then emits
101
+ the same machine-readable app/API/agent artifacts and exposes runtime bridge
102
+ endpoints for those entries.
103
+
104
+ The Go example starts a manifest-backed service:
105
+
106
+ ```bash
107
+ cd examples/go-billing
108
+ go run . --manifest --base-url http://127.0.0.1:8787 > forge.manifest.json
109
+ go run . --addr 127.0.0.1:8787 --base-url http://127.0.0.1:8787
110
+ ```
111
+
112
+ In a Forge app:
113
+
114
+ ```bash
115
+ forge manifest validate ./forge.manifest.json --json
116
+ forge manifest import ./forge.manifest.json --json
117
+ forge generate
118
+ forge run billing.createInvoice --args '{"title":"Invoice"}' --user-id u1 --tenant-id tenant-a --role admin
119
+ forge query billing.listInvoices --args '{}' --user-id u1 --tenant-id tenant-a --role admin
120
+ ```
121
+
122
+ For Java, see [`adapters/java`](adapters/java/README.md),
123
+ [`adapters/java-spring-boot-starter`](adapters/java-spring-boot-starter/README.md),
124
+ and [`examples/java-billing`](examples/java-billing/README.md).
125
+
126
+ See [`docs/forge-protocol.md`](docs/forge-protocol.md), [`schemas/forge-manifest.schema.json`](schemas/forge-manifest.schema.json),
127
+ and [`adapters/go`](adapters/go/README.md).
128
+
92
129
  ## What ForgeOS Generates
93
130
 
94
131
  ```txt
@@ -138,14 +175,17 @@ forge.lock
138
175
  | Auth | dev headers, JWT, OIDC discovery/JWKS verification via `jose`, production-mode guardrails |
139
176
  | RLS | Postgres RLS SQL compiler/checks for DB-enforced tenant isolation |
140
177
  | Secrets/env | secret registry, env schema, redaction, strict `process.env` checks |
141
- | AI | provider registry, `ctx.ai`, mock mode, telemetry without prompt/output retention by default |
178
+ | AI | Vercel AI SDK v6 engine, provider registry, `ctx.ai`, `ctx.agent.run`, `aiTool`, `agent`, `/ai/agents/run` JSON automation, `/ai/agents/chat` UIMessage streaming, `forge ai trace`, structural and model-level redteam probes, mock mode, telemetry without prompt/output retention by default |
142
179
  | Frontend | generated client SDK, React/Next hooks, template app, liveQuery client support |
143
180
  | LiveQuery | durable invalidation log, reconnect/resume semantics, production hardening checks |
181
+ | DeltaDB | ambient local recorder plus inferred work sessions and semantic timelines for Forge commands, dev file saves, generated artifacts, runtime calls, policies, proofs, diagnostics, `forge timeline`, `forge explain`, and optional `forge session` correction |
182
+ | Agent memory | opt-in Codex and Claude Code hooks, Cursor MCP/rules setup, normalized external agent events, redacted local memory, and `forge mcp serve` |
183
+ | Brownfield import | static TypeScript/JavaScript app inventory with routes, frontend calls, env usage, candidate entries, risk report, migration plan, and hidden-by-default imported agent contract |
144
184
  | Self-host | compose/deploy artifacts and self-host checks |
145
185
  | Agent contract | `AGENTS.md`, `agentContract.json`, app maps, runtime rules, playbooks, inspect/doctor |
146
186
  | Authoring | `forge make`, feature blueprints, safe refactor plans, package upgrade plans |
147
187
  | Testing/repair | impact-based test planner, repair loop, structured review, UI/browser test bridge |
148
- | Adapters | agent adapter export for external AI tools |
188
+ | Adapters | Forge Protocol manifest import plus Go, Java, and Spring Boot adapter support for executable external commands and queries |
149
189
  | Intent router | `forge do` maps objectives like fix, verify, connect UI, and add feature into plans, files, risks, and next commands |
150
190
  | Full-stack map | `frontendGraph` + `capabilityMap` connect routes, components, hooks, runtime entries, tables, policies, and gaps |
151
191
  | Dev loop | `forge dev` prints API/Web URLs, phase health, capability coverage, cache status, diagnostics, and next action |
@@ -166,6 +206,16 @@ forge dev
166
206
  forge inspect all --json
167
207
  forge inspect framework --json
168
208
  forge inspect capabilities --json
209
+ forge delta status
210
+ forge timeline
211
+ forge timeline --session current
212
+ forge explain <thing>
213
+ forge explain session current
214
+ forge session list
215
+ forge agent memory --json
216
+ forge mcp serve
217
+ forge import analyze --json
218
+ forge inspect imported --json
169
219
  forge doctor
170
220
  forge verify --standard
171
221
  forge verify --strict
@@ -187,8 +237,10 @@ Common command groups:
187
237
  | `forge check --json` | Validate guardrails and emit diagnostics with fix hints |
188
238
  | `forge verify --smoke` | Fast local gate: generated drift, Forge checks, typecheck when present, no tests/lint |
189
239
  | `forge verify --standard` | Agent development gate: generated drift, Forge/security checks, typecheck, and impact-selected tests |
190
- | `forge verify --strict` | Full handoff/CI gate: generated drift, Forge/security checks, typecheck, full test script, lint |
240
+ | `forge verify --strict` | Full handoff/CI gate: generated drift, Forge/security checks, typecheck, full TestGraph in bounded parallel/isolated chunks, lint |
191
241
  | `forge verify --script-timeout-ms <ms>` | Run package scripts with a predictable timeout and machine-readable timeout diagnostics |
242
+ | `forge verify --test-jobs <n>` | Tune strict TestGraph chunk parallelism; `FORGE_VERIFY_TEST_JOBS` is also supported |
243
+ | `forge verify --strict --test-plan --json` | Print the strict TestGraph scheduler plan without running tests |
192
244
  | `forge do "<objective>" --json` | Guided intent router: choose the right workflow, files, risks, and next action |
193
245
  | `forge inspect <target> --json` | Inspect generated app/data/runtime/policy/client/agent/UI surfaces |
194
246
  | `forge inspect framework --json` | Inspect ForgeOS framework modules, CLI commands, templates, examples, tests, and preferred entrypoints |
@@ -208,12 +260,16 @@ Common command groups:
208
260
  | `forge ui` | Browser/UI smoke, scenario, route, snapshot, doctor, and reports |
209
261
  | `forge deps` | Package upgrade planning and application |
210
262
  | `forge release` | Release/source-map bridge and symbolication |
211
- | `forge agent`, `forge agent-contract` | Agent-facing contract and adapter exports |
263
+ | `forge agent`, `forge agent-contract` | Agent-facing contract, adapter exports, context, install, ingest, and memory commands |
264
+ | `forge mcp serve` | MCP server for external agents to read Forge context, memory, timeline, and inspect surfaces |
265
+ | `forge import analyze`, `forge import inspect` | Brownfield TypeScript/JavaScript app inventory and reviewed migration planning |
266
+ | `forge inspect imported --json` | Inspect `.forge/import` analysis artifacts |
212
267
  | `forge self-host` | Self-host packaging and checks |
213
268
 
214
269
  Refactor codemods are AST-aware where safety matters most:
215
270
 
216
271
  - `forge refactor extract-action` is binding-aware and preserves unrelated imports, type-only imports, and shadowed locals.
272
+ - `forge refactor rename command <oldName> <newName>` rewrites command declarations, generated client references, React hook usage, tests, and safe string references while preserving unrelated symbols.
217
273
  - `forge refactor rename field <table.field> <table.field>` rewrites structured TS/JS/JSX/TSX and JSON references, preserves locals, and scopes the field change to files/objects linked to the target table. For example, `tickets.priority -> tickets.urgency` does not rewrite a generic `priority` prop in a component with no `tickets` binding.
218
274
  - `forge refactor rename table <from> <to>` rewrites table definitions, `ctx.db.<table>` access, policy strings, JSON/blueprints, and import/export specifiers while preserving unrelated locals with the same name.
219
275
 
@@ -242,12 +298,23 @@ See [`examples/showcase-forge-app`](examples/showcase-forge-app/README.md).
242
298
 
243
299
  ```bash
244
300
  cd examples/showcase-forge-app
245
- bun install
246
- bun run generate
247
- bun run dev
301
+ npm install
302
+ npm run generate
303
+ npm run dev
248
304
  ```
249
305
 
250
- Examples are source-only where practical: generated artifacts, `forge.lock`, package lockfiles, and operational `.forge/**` state are recreated locally. The showcase demonstrates tenant-scoped data, policies, commands, queries, liveQueries, outbox actions, workflows, mock AI, telemetry trace IDs, generated React hooks, `agentContract`, `frontendGraph`, and `capabilityMap`.
306
+ For the reproducible public proof path:
307
+
308
+ ```bash
309
+ npm run proof:inspect
310
+ npm run proof:dev
311
+ npm run proof:capabilities
312
+ npm run proof:verify
313
+ ```
314
+
315
+ Read [`examples/showcase-forge-app/PUBLIC_PROOF.md`](examples/showcase-forge-app/PUBLIC_PROOF.md) for the full walkthrough.
316
+
317
+ Examples are source-only where practical: generated artifacts, `forge.lock`, package lockfiles, and operational `.forge/**` state are recreated locally. The showcase demonstrates tenant-scoped data, policies, commands, queries, liveQueries, outbox actions, workflows, mock AI, telemetry trace IDs, generated React hooks, `agentContract`, `frontendGraph`, `capabilityMap`, and the standard agent handoff loop.
251
318
 
252
319
  ## Platform Support
253
320
 
@@ -323,7 +390,7 @@ For the first prerelease publish, use the alpha dist-tag explicitly:
323
390
 
324
391
  ```bash
325
392
  npm run release:publish-local-alpha -- --dry-run
326
- npm run release:publish-local-alpha -- --yes
393
+ npm run release:publish-alpha
327
394
  ```
328
395
 
329
396
  The normal path is:
@@ -346,7 +413,7 @@ Configure npm Trusted Publisher for package `forgeos`:
346
413
  | Environment | blank |
347
414
  | Allowed action | `npm publish` |
348
415
 
349
- Do not add `NPM_TOKEN` for normal releases. Alpha releases publish with the `alpha` dist-tag so prerelease builds do not become `latest` accidentally. The first manual package creation uses `release:publish-local-alpha`, which publishes from a temporary hardlink-free staging copy and disables provenance because local shells do not have a GitHub OIDC provider. The workflow uses `id-token: write`, Node 24/npm 11+, and provenance for subsequent releases. `npm run release:smoke` runs `npm pack`, creates a fresh app with the packed tarball, installs dependencies, runs `forge dev --once --json`, and verifies the app smoke path.
416
+ Do not add `NPM_TOKEN` for normal releases. Alpha releases publish with the `alpha` dist-tag so prerelease builds do not become `latest` accidentally. Use `release:publish-local-alpha -- --dry-run` only to validate the staged tarball locally; real npm publishing should go through `release:publish-alpha`, which dispatches `publish.yml` and uses npm OIDC Trusted Publisher. The workflow checks whether the package version already exists before installing dependencies or running tests, then uses `id-token: write`, Node 24/npm 11+, and provenance for the actual publish. `npm run release:smoke` runs `npm pack`, creates a fresh app with the packed tarball, installs dependencies, runs `forge dev --once --json`, and verifies the app smoke path.
350
417
 
351
418
  ## Milestone History
352
419
 
@@ -393,11 +460,18 @@ H39 Showcase app
393
460
  H40 Windows/runtime hardening
394
461
  H41 Node-compatible CLI/runtime
395
462
  H42 Verify observability and quieter app workspaces
463
+ H43 Native AI tools and agent loop
464
+ H44 Ambient DeltaDB recorder
465
+ H45 Automatic work-session inference
466
+ H46 Automatic change grouping
467
+ H47 Semantic timeline
468
+ H48 Agent Memory Bridge
469
+ H49 Brownfield import analysis
396
470
  ```
397
471
 
398
472
  ## Remaining Hardening Before Public Release
399
473
 
400
- - Keep expanding semantic codemods beyond the current AST-aware `extract-action`, `rename field`, and `rename table` paths.
474
+ - Keep expanding semantic codemods beyond the current AST-aware `extract-action`, `rename command`, `rename field`, and `rename table` paths.
401
475
  - Reduce command-selection risk with more task routers and richer inline diagnostics.
402
476
  - Keep hardening native Windows setup beyond diagnostics and safe automatic environment fixes.
403
477
  - Keep broadening package manager CI from template smoke toward install/build smoke for pnpm and yarn apps.
@@ -0,0 +1,23 @@
1
+ # Forge Go Adapter
2
+
3
+ `adapters/go` is the minimal Go SDK for external Forge runtimes. It registers
4
+ commands and queries, emits `forge.manifest.json`, and exposes a Forge-compatible
5
+ HTTP handler.
6
+
7
+ ```go
8
+ app := forge.New("billing", forge.BaseURL("http://127.0.0.1:8787"))
9
+
10
+ app.Command("createInvoice", forge.Handle(createInvoice),
11
+ forge.Policy("billing.manage"),
12
+ forge.TenantScoped(true),
13
+ forge.NeedsApproval(true),
14
+ )
15
+
16
+ app.Query("listInvoices", forge.Handle(listInvoices),
17
+ forge.Policy("billing.manage"),
18
+ forge.TenantScoped(true),
19
+ )
20
+ ```
21
+
22
+ The HTTP handler accepts Forge runtime envelopes on `/commands/:name` and
23
+ `/queries/:name`, then returns `{ "ok": true, "result": ... }` envelopes.
@@ -0,0 +1,3 @@
1
+ module github.com/Stahldavid/forge/adapters/go
2
+
3
+ go 1.22
@@ -0,0 +1,149 @@
1
+ package forge
2
+
3
+ import (
4
+ "encoding/json"
5
+ "errors"
6
+ "net/http"
7
+ "strings"
8
+ )
9
+
10
+ func (registry *Registry) HTTPHandler() http.Handler {
11
+ mux := http.NewServeMux()
12
+ mux.HandleFunc(registry.service.Health, registry.handleHealth)
13
+ mux.HandleFunc("/manifest", registry.handleManifest)
14
+ mux.HandleFunc("/commands/", registry.handleRuntime(KindCommand, "/commands/"))
15
+ mux.HandleFunc("/queries/", registry.handleRuntime(KindQuery, "/queries/"))
16
+ return mux
17
+ }
18
+
19
+ func (registry *Registry) handleHealth(response http.ResponseWriter, request *http.Request) {
20
+ writeJSON(response, http.StatusOK, map[string]any{
21
+ "ok": true,
22
+ "service": registry.service.Name,
23
+ })
24
+ }
25
+
26
+ func (registry *Registry) handleManifest(response http.ResponseWriter, request *http.Request) {
27
+ baseURL := request.URL.Query().Get("baseUrl")
28
+ if baseURL == "" {
29
+ baseURL = registry.service.BaseURL
30
+ }
31
+ writeJSON(response, http.StatusOK, registry.Manifest(baseURL))
32
+ }
33
+
34
+ func (registry *Registry) handleRuntime(kind EntryKind, prefix string) http.HandlerFunc {
35
+ return func(response http.ResponseWriter, request *http.Request) {
36
+ name := strings.TrimPrefix(request.URL.Path, prefix)
37
+ registered, ok := registry.lookup[lookupKey(kind, name)]
38
+ if !ok {
39
+ writeError(response, http.StatusNotFound, "", "FORGE_GO_ENTRY_NOT_FOUND", "external entry not found")
40
+ return
41
+ }
42
+ if request.Method != http.MethodPost && request.Method != http.MethodGet {
43
+ writeError(response, http.StatusMethodNotAllowed, "", "FORGE_GO_METHOD_NOT_ALLOWED", "external entry only accepts GET or POST")
44
+ return
45
+ }
46
+
47
+ envelope, err := readRequestEnvelope(request)
48
+ traceID := traceIDFrom(request, envelope)
49
+ if err != nil {
50
+ writeError(response, http.StatusBadRequest, traceID, "FORGE_GO_BAD_REQUEST", err.Error())
51
+ return
52
+ }
53
+ if envelope.Forge.Service == "" {
54
+ envelope.Forge.Service = registry.service.Name
55
+ }
56
+ if envelope.Forge.Entry == "" {
57
+ envelope.Forge.Entry = name
58
+ }
59
+ if envelope.Forge.Kind == "" {
60
+ envelope.Forge.Kind = string(kind)
61
+ }
62
+ if envelope.Forge.TraceID == "" {
63
+ envelope.Forge.TraceID = traceID
64
+ }
65
+ if envelope.Auth.Kind == "" {
66
+ envelope.Auth = authFromHeaders(request.Header)
67
+ }
68
+
69
+ call := &Context{
70
+ Auth: envelope.Auth,
71
+ Forge: envelope.Forge,
72
+ Headers: request.Header,
73
+ }
74
+ result, err := registered.handler(request.Context(), call, envelope.Args)
75
+ if err != nil {
76
+ writeError(response, http.StatusInternalServerError, envelope.Forge.TraceID, "FORGE_GO_HANDLER_FAILED", err.Error())
77
+ return
78
+ }
79
+ writeJSON(response, http.StatusOK, ResponseEnvelope{
80
+ OK: true,
81
+ Result: result,
82
+ TraceID: envelope.Forge.TraceID,
83
+ })
84
+ }
85
+ }
86
+
87
+ func readRequestEnvelope(request *http.Request) (RequestEnvelope, error) {
88
+ if request.Method == http.MethodGet {
89
+ args := request.URL.Query().Get("args")
90
+ if args == "" {
91
+ args = "{}"
92
+ }
93
+ return RequestEnvelope{Args: json.RawMessage(args)}, nil
94
+ }
95
+ defer request.Body.Close()
96
+ var envelope RequestEnvelope
97
+ decoder := json.NewDecoder(request.Body)
98
+ if err := decoder.Decode(&envelope); err != nil {
99
+ return envelope, err
100
+ }
101
+ if len(envelope.Args) == 0 {
102
+ envelope.Args = json.RawMessage("{}")
103
+ }
104
+ if !json.Valid(envelope.Args) {
105
+ return envelope, errors.New("request args must be valid JSON")
106
+ }
107
+ return envelope, nil
108
+ }
109
+
110
+ func authFromHeaders(headers http.Header) Auth {
111
+ auth := Auth{Kind: headers.Get("x-forge-auth-kind")}
112
+ if auth.Kind == "" {
113
+ auth.Kind = "anonymous"
114
+ }
115
+ auth.UserID = headers.Get("x-forge-user-id")
116
+ auth.TenantID = headers.Get("x-forge-tenant-id")
117
+ auth.Role = headers.Get("x-forge-role")
118
+ return auth
119
+ }
120
+
121
+ func traceIDFrom(request *http.Request, envelope RequestEnvelope) string {
122
+ if envelope.Forge.TraceID != "" {
123
+ return envelope.Forge.TraceID
124
+ }
125
+ return request.Header.Get("x-forge-trace-id")
126
+ }
127
+
128
+ func writeError(response http.ResponseWriter, status int, traceID string, code string, message string) {
129
+ writeJSON(response, status, ResponseEnvelope{
130
+ OK: false,
131
+ Diagnostics: []Diagnostic{{
132
+ Severity: "error",
133
+ Code: code,
134
+ Message: message,
135
+ Docs: []string{"docs/forge-protocol.md"},
136
+ }},
137
+ Error: &ErrorInfo{
138
+ Code: code,
139
+ Message: message,
140
+ },
141
+ TraceID: traceID,
142
+ })
143
+ }
144
+
145
+ func writeJSON(response http.ResponseWriter, status int, body any) {
146
+ response.Header().Set("content-type", "application/json")
147
+ response.WriteHeader(status)
148
+ _ = json.NewEncoder(response).Encode(body)
149
+ }
@@ -0,0 +1,234 @@
1
+ package forge
2
+
3
+ import (
4
+ "encoding/json"
5
+ "io"
6
+ )
7
+
8
+ type Registry struct {
9
+ service Service
10
+ framework string
11
+ schemas map[string]any
12
+ entries []registeredEntry
13
+ lookup map[string]registeredEntry
14
+ }
15
+
16
+ type registeredEntry struct {
17
+ entry Entry
18
+ handler HandlerFunc
19
+ }
20
+
21
+ type RegistryOption func(*Registry)
22
+ type EntryOption func(*Entry)
23
+
24
+ func New(serviceName string, options ...RegistryOption) *Registry {
25
+ registry := &Registry{
26
+ service: Service{
27
+ Name: serviceName,
28
+ Transport: "http",
29
+ Health: "/health",
30
+ },
31
+ framework: "net/http",
32
+ schemas: map[string]any{},
33
+ lookup: map[string]registeredEntry{},
34
+ }
35
+ for _, option := range options {
36
+ option(registry)
37
+ }
38
+ return registry
39
+ }
40
+
41
+ func Framework(value string) RegistryOption {
42
+ return func(registry *Registry) {
43
+ registry.framework = value
44
+ }
45
+ }
46
+
47
+ func BaseURL(value string) RegistryOption {
48
+ return func(registry *Registry) {
49
+ registry.service.BaseURL = value
50
+ }
51
+ }
52
+
53
+ func Health(path string) RegistryOption {
54
+ return func(registry *Registry) {
55
+ registry.service.Health = path
56
+ }
57
+ }
58
+
59
+ func SchemaRef(name string, schema any) RegistryOption {
60
+ return func(registry *Registry) {
61
+ registry.schemas[name] = schema
62
+ }
63
+ }
64
+
65
+ func (registry *Registry) Command(name string, handler HandlerFunc, options ...EntryOption) {
66
+ entry := Entry{
67
+ Name: name,
68
+ Kind: KindCommand,
69
+ Path: "/commands/" + name,
70
+ Method: "POST",
71
+ Transaction: TransactionExternalManaged,
72
+ Risk: RiskWrite,
73
+ }
74
+ registry.add(entry, handler, options...)
75
+ }
76
+
77
+ func (registry *Registry) Query(name string, handler HandlerFunc, options ...EntryOption) {
78
+ entry := Entry{
79
+ Name: name,
80
+ Kind: KindQuery,
81
+ Path: "/queries/" + name,
82
+ Method: "POST",
83
+ Transaction: TransactionReadOnly,
84
+ Risk: RiskRead,
85
+ }
86
+ registry.add(entry, handler, options...)
87
+ }
88
+
89
+ func (registry *Registry) add(entry Entry, handler HandlerFunc, options ...EntryOption) {
90
+ for _, option := range options {
91
+ option(&entry)
92
+ }
93
+ registered := registeredEntry{entry: entry, handler: handler}
94
+ registry.entries = append(registry.entries, registered)
95
+ registry.lookup[lookupKey(entry.Kind, entry.Name)] = registered
96
+ }
97
+
98
+ func Description(value string) EntryOption {
99
+ return func(entry *Entry) {
100
+ entry.Description = value
101
+ }
102
+ }
103
+
104
+ func Path(value string) EntryOption {
105
+ return func(entry *Entry) {
106
+ entry.Path = value
107
+ }
108
+ }
109
+
110
+ func Method(value string) EntryOption {
111
+ return func(entry *Entry) {
112
+ entry.Method = value
113
+ }
114
+ }
115
+
116
+ func InputSchema(schema any) EntryOption {
117
+ return func(entry *Entry) {
118
+ entry.InputSchema = schema
119
+ }
120
+ }
121
+
122
+ func OutputSchema(schema any) EntryOption {
123
+ return func(entry *Entry) {
124
+ entry.OutputSchema = schema
125
+ }
126
+ }
127
+
128
+ func Policy(value string) EntryOption {
129
+ return func(entry *Entry) {
130
+ entry.Policy = value
131
+ }
132
+ }
133
+
134
+ func TenantScoped(value bool) EntryOption {
135
+ return func(entry *Entry) {
136
+ entry.TenantScoped = value
137
+ }
138
+ }
139
+
140
+ func TransactionMode(value Transaction) EntryOption {
141
+ return func(entry *Entry) {
142
+ entry.Transaction = value
143
+ }
144
+ }
145
+
146
+ func EntryRisk(value Risk) EntryOption {
147
+ return func(entry *Entry) {
148
+ entry.Risk = value
149
+ }
150
+ }
151
+
152
+ func NeedsApproval(value bool) EntryOption {
153
+ return func(entry *Entry) {
154
+ entry.NeedsApproval = &value
155
+ }
156
+ }
157
+
158
+ func Effects(values ...string) EntryOption {
159
+ return func(entry *Entry) {
160
+ entry.Effects = append([]string{}, values...)
161
+ }
162
+ }
163
+
164
+ func ReadOnly() EntryOption {
165
+ return func(entry *Entry) {
166
+ entry.Transaction = TransactionReadOnly
167
+ entry.Risk = RiskRead
168
+ }
169
+ }
170
+
171
+ func (registry *Registry) Manifest(baseURL string) Manifest {
172
+ service := registry.service
173
+ if baseURL != "" {
174
+ service.BaseURL = baseURL
175
+ }
176
+ entries := make([]Entry, 0, len(registry.entries))
177
+ for _, registered := range registry.entries {
178
+ entries = append(entries, registered.entry)
179
+ }
180
+ manifest := Manifest{
181
+ ForgeProtocol: ProtocolVersion,
182
+ Language: "go",
183
+ Framework: registry.framework,
184
+ Service: service,
185
+ Entries: entries,
186
+ }
187
+ if len(registry.schemas) > 0 {
188
+ manifest.Schemas = registry.schemas
189
+ }
190
+ return manifest
191
+ }
192
+
193
+ func (registry *Registry) MarshalManifest(baseURL string) ([]byte, error) {
194
+ return json.MarshalIndent(registry.Manifest(baseURL), "", " ")
195
+ }
196
+
197
+ func (registry *Registry) WriteManifest(writer io.Writer, baseURL string) error {
198
+ encoded, err := registry.MarshalManifest(baseURL)
199
+ if err != nil {
200
+ return err
201
+ }
202
+ if _, err := writer.Write(encoded); err != nil {
203
+ return err
204
+ }
205
+ _, err = writer.Write([]byte("\n"))
206
+ return err
207
+ }
208
+
209
+ func Object(properties map[string]any, required ...string) Schema {
210
+ schema := Schema{
211
+ "type": "object",
212
+ "properties": properties,
213
+ }
214
+ if len(required) > 0 {
215
+ schema["required"] = required
216
+ }
217
+ return schema
218
+ }
219
+
220
+ func String() Schema {
221
+ return Schema{"type": "string"}
222
+ }
223
+
224
+ func Boolean() Schema {
225
+ return Schema{"type": "boolean"}
226
+ }
227
+
228
+ func Array(items any) Schema {
229
+ return Schema{"type": "array", "items": items}
230
+ }
231
+
232
+ func lookupKey(kind EntryKind, name string) string {
233
+ return string(kind) + ":" + name
234
+ }