forgeos 0.1.0-alpha.3 → 0.1.0-alpha.30
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.
- package/.npmignore +10 -0
- package/AGENTS.md +142 -90
- package/CHANGELOG.md +321 -0
- package/LICENSE +21 -0
- package/README.md +86 -13
- package/adapters/go/README.md +23 -0
- package/adapters/go/go.mod +3 -0
- package/adapters/go/http.go +149 -0
- package/adapters/go/registry.go +234 -0
- package/adapters/go/types.go +136 -0
- package/adapters/java/README.md +68 -0
- package/adapters/java/pom.xml +34 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Auth.java +20 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Diagnostic.java +16 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Entry.java +38 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/EntryKind.java +16 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/ErrorInfo.java +4 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Forge.java +94 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeCall.java +12 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeContext.java +11 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHandler.java +8 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHttpHandler.java +179 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeRegistry.java +121 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Json.java +14 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Manifest.java +14 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/RequestEnvelope.java +6 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/ResponseEnvelope.java +25 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Risk.java +18 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Schemas.java +36 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Service.java +65 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/TransactionMode.java +18 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/TypedForgeHandler.java +6 -0
- package/adapters/java-spring-boot-starter/README.md +32 -0
- package/adapters/java-spring-boot-starter/pom.xml +36 -0
- package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeCommand.java +22 -0
- package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeExternalService.java +15 -0
- package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeQuery.java +16 -0
- package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeServiceBeanCondition.java +18 -0
- package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringAutoConfiguration.java +16 -0
- package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringRuntime.java +104 -0
- package/adapters/java-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +1 -0
- package/bin/forge.mjs +18 -0
- package/docs/cair-protocol.md +103 -0
- package/docs/changelog.md +366 -0
- package/docs/forge-protocol.md +189 -0
- package/examples/go-billing/go.mod +7 -0
- package/examples/go-billing/main.go +120 -0
- package/examples/java-billing/pom.xml +52 -0
- package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/CreateInvoiceInput.java +4 -0
- package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Invoice.java +11 -0
- package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Main.java +127 -0
- package/package.json +34 -4
- package/schemas/forge-manifest.schema.json +57 -0
- package/src/forge/_generated/releaseManifest.json +1 -2
- package/src/forge/_generated/releaseManifest.ts +3 -3
- package/src/forge/agent-adapters/index.ts +1556 -123
- package/src/forge/agent-adapters/types.ts +224 -1
- package/src/forge/agent-memory/bridge.ts +1333 -0
- package/src/forge/agent-memory/context-pack.ts +277 -0
- package/src/forge/agent-memory/hook-runner.ts +312 -0
- package/src/forge/agent-memory/mcp.ts +224 -0
- package/src/forge/agent-memory/normalize.ts +498 -0
- package/src/forge/agent-memory/redaction.ts +103 -0
- package/src/forge/agent-memory/sources/claude-code.ts +51 -0
- package/src/forge/agent-memory/sources/codex-hook-runner.mjs +273 -0
- package/src/forge/agent-memory/sources/codex.ts +119 -0
- package/src/forge/agent-memory/sources/cursor.ts +35 -0
- package/src/forge/agent-memory/types.ts +204 -0
- package/src/forge/bench.ts +248 -0
- package/src/forge/brownfield-import/index.ts +801 -0
- package/src/forge/brownfield-import/types.ts +127 -0
- package/src/forge/cair/action-journal.ts +61 -0
- package/src/forge/cair/action-parser.ts +314 -0
- package/src/forge/cair/action-validator.ts +40 -0
- package/src/forge/cair/actions.ts +1818 -0
- package/src/forge/cair/format.ts +77 -0
- package/src/forge/cair/index.ts +106 -0
- package/src/forge/cair/query.ts +478 -0
- package/src/forge/cair/snapshot.ts +315 -0
- package/src/forge/cair/types.ts +248 -0
- package/src/forge/cli/ai.ts +485 -2
- package/src/forge/cli/auth.ts +92 -2
- package/src/forge/cli/authmd.ts +356 -0
- package/src/forge/cli/build.ts +20 -4
- package/src/forge/cli/changed.ts +306 -0
- package/src/forge/cli/codex-app-server.ts +877 -0
- package/src/forge/cli/commands.ts +1357 -9
- package/src/forge/cli/db.ts +121 -2
- package/src/forge/cli/deps.ts +79 -12
- package/src/forge/cli/dev.ts +502 -38
- package/src/forge/cli/docs.ts +265 -0
- package/src/forge/cli/handoff.ts +253 -0
- package/src/forge/cli/index.ts +1 -0
- package/src/forge/cli/main.ts +59 -3
- package/src/forge/cli/new.ts +13 -1
- package/src/forge/cli/next-actions.ts +23 -0
- package/src/forge/cli/output.ts +302 -1
- package/src/forge/cli/parse.ts +862 -34
- package/src/forge/cli/query.ts +32 -0
- package/src/forge/cli/release.ts +35 -11
- package/src/forge/cli/rls.ts +568 -17
- package/src/forge/cli/run.ts +41 -0
- package/src/forge/cli/secrets.ts +46 -1
- package/src/forge/cli/security.ts +381 -0
- package/src/forge/cli/self-host.ts +56 -14
- package/src/forge/cli/studio.ts +2217 -0
- package/src/forge/cli/verify.ts +1424 -32
- package/src/forge/cli/workos.ts +340 -0
- package/src/forge/compiler/agent-contract/build.ts +637 -51
- package/src/forge/compiler/agent-contract/types.ts +47 -2
- package/src/forge/compiler/ai-registry/parse.ts +71 -2
- package/src/forge/compiler/api-surface/build.ts +47 -0
- package/src/forge/compiler/app-graph/build.ts +68 -8
- package/src/forge/compiler/app-graph/extract.ts +107 -0
- package/src/forge/compiler/app-graph/module-graph.ts +73 -78
- package/src/forge/compiler/app-graph/parser.ts +24 -24
- package/src/forge/compiler/app-graph/profile.ts +26 -0
- package/src/forge/compiler/app-graph/versions.ts +1 -1
- package/src/forge/compiler/classifier/capabilities.ts +3 -2
- package/src/forge/compiler/classifier/classify.ts +32 -8
- package/src/forge/compiler/classifier/secrets.ts +3 -2
- package/src/forge/compiler/classifier/signals.ts +91 -1
- package/src/forge/compiler/client-sdk/build-manifest.ts +59 -0
- package/src/forge/compiler/client-sdk/render-client.ts +188 -13
- package/src/forge/compiler/data-graph/parse.ts +3 -3
- package/src/forge/compiler/data-graph/sql/ddl.ts +60 -2
- package/src/forge/compiler/data-graph/sql/serialize.ts +4 -0
- package/src/forge/compiler/data-graph/sql/types.ts +1 -0
- package/src/forge/compiler/diagnostics/codes.ts +35 -0
- package/src/forge/compiler/diagnostics/create.ts +8 -3
- package/src/forge/compiler/diagnostics/index.ts +2 -0
- package/src/forge/compiler/emitter/barrel.ts +3 -0
- package/src/forge/compiler/emitter/render.ts +9 -0
- package/src/forge/compiler/external-manifest/registry.ts +205 -0
- package/src/forge/compiler/external-manifest/types.ts +91 -0
- package/src/forge/compiler/external-manifest/validate.ts +373 -0
- package/src/forge/compiler/frontend-graph/build.ts +142 -14
- package/src/forge/compiler/integration/add.ts +536 -23
- package/src/forge/compiler/integration/plan.ts +17 -11
- package/src/forge/compiler/integration/render.ts +20 -0
- package/src/forge/compiler/integration/snapshot.ts +2 -0
- package/src/forge/compiler/integration/templates/convex.ts +70 -0
- package/src/forge/compiler/integration/templates/index.ts +1 -0
- package/src/forge/compiler/integration/templates/render.ts +34 -0
- package/src/forge/compiler/integration/templates/workos.ts +1063 -0
- package/src/forge/compiler/make-registry/build.ts +6 -7
- package/src/forge/compiler/orchestrator/fast-check.ts +4 -0
- package/src/forge/compiler/orchestrator/manifest.ts +1 -1
- package/src/forge/compiler/orchestrator/plan-profile.ts +23 -0
- package/src/forge/compiler/orchestrator/plan.ts +240 -10
- package/src/forge/compiler/orchestrator/profile.ts +65 -0
- package/src/forge/compiler/orchestrator/run.ts +97 -31
- package/src/forge/compiler/orchestrator/serialize.ts +33 -8
- package/src/forge/compiler/orchestrator/types.ts +1 -1
- package/src/forge/compiler/package-graph/compiler.ts +13 -3
- package/src/forge/compiler/package-manager/adapter.ts +4 -1
- package/src/forge/compiler/package-manager/commands.ts +4 -0
- package/src/forge/compiler/package-manager/executor.ts +30 -1
- package/src/forge/compiler/policy-registry/build.ts +47 -2
- package/src/forge/compiler/policy-registry/parse.ts +32 -2
- package/src/forge/compiler/recipes/definitions.ts +63 -0
- package/src/forge/compiler/recipes/index.ts +2 -0
- package/src/forge/compiler/recipes/registry.ts +6 -0
- package/src/forge/compiler/test-graph/build.ts +11 -3
- package/src/forge/compiler/types/app-graph.ts +8 -2
- package/src/forge/compiler/types/cli.ts +75 -1
- package/src/forge/compiler/types/dev-manifest.ts +4 -0
- package/src/forge/compiler/types/emit.ts +2 -0
- package/src/forge/compiler/types/frontend-graph.ts +2 -2
- package/src/forge/compiler/types/integration.ts +1 -0
- package/src/forge/compiler/types/policy-registry.ts +3 -1
- package/src/forge/delta/classifier.ts +52 -0
- package/src/forge/delta/explain.ts +238 -0
- package/src/forge/delta/git-observer.ts +43 -0
- package/src/forge/delta/ids.ts +44 -0
- package/src/forge/delta/index.ts +25 -0
- package/src/forge/delta/recorder.ts +540 -0
- package/src/forge/delta/redaction.ts +50 -0
- package/src/forge/delta/schema.ts +240 -0
- package/src/forge/delta/session.ts +142 -0
- package/src/forge/delta/status.ts +1126 -0
- package/src/forge/delta/store.ts +3284 -0
- package/src/forge/delta/timeline.ts +178 -0
- package/src/forge/dev/server.ts +777 -17
- package/src/forge/dev/types.ts +15 -1
- package/src/forge/dev/watch.ts +17 -7
- package/src/forge/dev-console/cycle.ts +233 -21
- package/src/forge/dev-console/types.ts +46 -1
- package/src/forge/impact/index.ts +46 -8
- package/src/forge/impact/types.ts +6 -0
- package/src/forge/intent/index.ts +35 -16
- package/src/forge/make/index.ts +34 -5
- package/src/forge/make/templates.ts +155 -2
- package/src/forge/make/types.ts +2 -1
- package/src/forge/policy.ts +1 -1
- package/src/forge/refactor/index.ts +1 -0
- package/src/forge/repair/rules/index.ts +2 -2
- package/src/forge/review/index.ts +158 -12
- package/src/forge/review/types.ts +15 -0
- package/src/forge/runtime/auth/claims.ts +32 -0
- package/src/forge/runtime/auth/config.ts +17 -0
- package/src/forge/runtime/auth/errors.ts +2 -0
- package/src/forge/runtime/auth/evaluate.ts +15 -2
- package/src/forge/runtime/auth/resolve.ts +29 -4
- package/src/forge/runtime/db/generated-client.ts +13 -2
- package/src/forge/runtime/db/memory-adapter.ts +2 -2
- package/src/forge/runtime/db/pglite-adapter.ts +77 -2
- package/src/forge/runtime/db/postgres-adapter.ts +6 -3
- package/src/forge/runtime/executor.ts +129 -16
- package/src/forge/runtime/external/bridge.ts +649 -0
- package/src/forge/runtime/runner/run-entry.ts +16 -7
- package/src/forge/runtime/telemetry/buffer.ts +4 -1
- package/src/forge/runtime/telemetry/scrubber.ts +91 -10
- package/src/forge/runtime/webhooks/security.ts +189 -0
- package/src/forge/server.ts +23 -2
- package/src/forge/version.ts +1 -1
- package/src/forge/vue/index.ts +407 -0
- package/src/forge/workspace/change-summary.ts +243 -0
- package/src/forge/workspace/forge-cli.ts +14 -0
- package/src/forge/workspace/git-summary.ts +328 -0
- package/templates/agent-workroom/AGENTS.md +29 -0
- package/templates/agent-workroom/README.md +34 -0
- package/templates/agent-workroom/forge.config.ts +3 -0
- package/templates/agent-workroom/package.json +33 -0
- package/templates/agent-workroom/src/actions/indexAgentSignal.ts +10 -0
- package/templates/agent-workroom/src/commands/openWorkroom.ts +61 -0
- package/templates/agent-workroom/src/commands/recordAgentSignal.ts +119 -0
- package/templates/agent-workroom/src/commands/recordCheckRun.ts +52 -0
- package/templates/agent-workroom/src/forge/schema.ts +54 -0
- package/templates/agent-workroom/src/policies.ts +6 -0
- package/templates/agent-workroom/src/queries/listWorkrooms.ts +11 -0
- package/templates/agent-workroom/src/queries/liveWorkroom.ts +63 -0
- package/templates/agent-workroom/tsconfig.json +16 -0
- package/templates/agent-workroom/web/index.html +12 -0
- package/templates/agent-workroom/web/package.json +21 -0
- package/templates/agent-workroom/web/src/App.tsx +345 -0
- package/templates/agent-workroom/web/src/lib/forge.ts +13 -0
- package/templates/agent-workroom/web/src/main.tsx +13 -0
- package/templates/agent-workroom/web/src/styles.css +545 -0
- package/templates/agent-workroom/web/tsconfig.json +27 -0
- package/templates/b2b-support-web/package.json +2 -0
- package/templates/b2b-support-web/tsconfig.json +4 -1
- package/templates/b2b-support-web/web/package.json +1 -1
- package/templates/minimal-web/package.json +2 -1
- package/templates/minimal-web/tsconfig.json +3 -1
- package/templates/minimal-web/web/package.json +2 -2
- package/templates/nuxt-web/.vscode/settings.json +14 -0
- package/templates/nuxt-web/README.md +30 -0
- package/templates/nuxt-web/forge.config.ts +3 -0
- package/templates/nuxt-web/package.json +33 -0
- package/templates/nuxt-web/src/actions/logNoteCreated.ts +11 -0
- package/templates/nuxt-web/src/commands/createNote.ts +26 -0
- package/templates/nuxt-web/src/forge/schema.ts +12 -0
- package/templates/nuxt-web/src/policies.ts +6 -0
- package/templates/nuxt-web/src/queries/listNotes.ts +8 -0
- package/templates/nuxt-web/src/queries/liveNotes.ts +8 -0
- package/templates/nuxt-web/tsconfig.json +17 -0
- package/templates/nuxt-web/web/app.vue +67 -0
- package/templates/nuxt-web/web/components/LiveNotes.vue +89 -0
- package/templates/nuxt-web/web/components/NoteComposer.vue +100 -0
- package/templates/nuxt-web/web/composables/forge.ts +13 -0
- package/templates/nuxt-web/web/composables/useNotes.ts +24 -0
- package/templates/nuxt-web/web/nuxt.config.ts +11 -0
- package/templates/nuxt-web/web/package.json +17 -0
- package/templates/nuxt-web/web/plugins/forge.client.ts +10 -0
- package/templates/nuxt-web/web/plugins/forge.server.ts +10 -0
- package/templates/nuxt-web/web/server/api/forge-health.get.ts +7 -0
- package/templates/nuxt-web/web/tsconfig.json +3 -0
- package/src/forge/_generated/actionSubscriptions.json +0 -2
- package/src/forge/_generated/actionSubscriptions.ts +0 -10
- package/src/forge/_generated/agentAdapterManifest.json +0 -2
- package/src/forge/_generated/agentAdapterManifest.ts +0 -73
- package/src/forge/_generated/agentContract.json +0 -2
- package/src/forge/_generated/agentContract.ts +0 -7829
- package/src/forge/_generated/agentQuickstart.md +0 -34
- package/src/forge/_generated/agentTools.json +0 -2
- package/src/forge/_generated/agentTools.md +0 -16
- package/src/forge/_generated/agentTools.ts +0 -12
- package/src/forge/_generated/aiContext.ts +0 -125
- package/src/forge/_generated/aiModels.json +0 -2
- package/src/forge/_generated/aiModels.ts +0 -51
- package/src/forge/_generated/aiProviders.json +0 -2
- package/src/forge/_generated/aiProviders.ts +0 -23
- package/src/forge/_generated/aiRegistry.json +0 -2
- package/src/forge/_generated/aiRegistry.ts +0 -31
- package/src/forge/_generated/api.json +0 -2
- package/src/forge/_generated/api.ts +0 -8
- package/src/forge/_generated/appGraph.json +0 -2
- package/src/forge/_generated/appGraph.ts +0 -14775
- package/src/forge/_generated/appMap.md +0 -55
- package/src/forge/_generated/artifactManifest.json +0 -2
- package/src/forge/_generated/artifactManifest.ts +0 -7
- package/src/forge/_generated/authClaims.json +0 -2
- package/src/forge/_generated/authClaims.ts +0 -13
- package/src/forge/_generated/authConfig.json +0 -2
- package/src/forge/_generated/authConfig.ts +0 -17
- package/src/forge/_generated/authContext.ts +0 -23
- package/src/forge/_generated/authRegistry.json +0 -2
- package/src/forge/_generated/authRegistry.ts +0 -25
- package/src/forge/_generated/buildInfo.json +0 -2
- package/src/forge/_generated/buildInfo.ts +0 -9
- package/src/forge/_generated/capabilityMap.json +0 -2
- package/src/forge/_generated/capabilityMap.md +0 -15
- package/src/forge/_generated/capabilityMap.ts +0 -17
- package/src/forge/_generated/client.ts +0 -282
- package/src/forge/_generated/clientApi.ts +0 -9
- package/src/forge/_generated/clientManifest.json +0 -2
- package/src/forge/_generated/clientManifest.ts +0 -39
- package/src/forge/_generated/clientTypes.ts +0 -78
- package/src/forge/_generated/configRegistry.json +0 -2
- package/src/forge/_generated/configRegistry.ts +0 -4
- package/src/forge/_generated/dataGraph.json +0 -2
- package/src/forge/_generated/dataGraph.ts +0 -8
- package/src/forge/_generated/db.json +0 -2
- package/src/forge/_generated/db.ts +0 -2
- package/src/forge/_generated/dbSecurityManifest.json +0 -2
- package/src/forge/_generated/dbSecurityManifest.ts +0 -15
- package/src/forge/_generated/dbSessionContext.json +0 -2
- package/src/forge/_generated/dbSessionContext.ts +0 -39
- package/src/forge/_generated/deployManifest.json +0 -2
- package/src/forge/_generated/deployManifest.ts +0 -14
- package/src/forge/_generated/devManifest.json +0 -2
- package/src/forge/_generated/devManifest.ts +0 -62
- package/src/forge/_generated/envSchema.json +0 -2
- package/src/forge/_generated/envSchema.ts +0 -59
- package/src/forge/_generated/frontendGraph.json +0 -2
- package/src/forge/_generated/frontendGraph.ts +0 -27
- package/src/forge/_generated/importGuards.json +0 -2
- package/src/forge/_generated/importGuards.ts +0 -686
- package/src/forge/_generated/index.ts +0 -68
- package/src/forge/_generated/liveProductionManifest.json +0 -2
- package/src/forge/_generated/liveProductionManifest.ts +0 -23
- package/src/forge/_generated/liveProtocol.json +0 -2
- package/src/forge/_generated/liveProtocol.ts +0 -21
- package/src/forge/_generated/liveQueryRegistry.json +0 -2
- package/src/forge/_generated/liveQueryRegistry.ts +0 -9
- package/src/forge/_generated/liveTransportConfig.json +0 -2
- package/src/forge/_generated/liveTransportConfig.ts +0 -19
- package/src/forge/_generated/makeRegistry.json +0 -2
- package/src/forge/_generated/makeRegistry.ts +0 -177
- package/src/forge/_generated/makeTemplates.json +0 -2
- package/src/forge/_generated/makeTemplates.ts +0 -66
- package/src/forge/_generated/mockMap.json +0 -2
- package/src/forge/_generated/mockMap.ts +0 -7
- package/src/forge/_generated/operationPlaybooks.md +0 -167
- package/src/forge/_generated/packageGraph.json +0 -2
- package/src/forge/_generated/packageGraph.ts +0 -249334
- package/src/forge/_generated/packageUpgradeRegistry.json +0 -2
- package/src/forge/_generated/packageUpgradeRegistry.ts +0 -15
- package/src/forge/_generated/permissionMatrix.json +0 -2
- package/src/forge/_generated/permissionMatrix.ts +0 -7
- package/src/forge/_generated/policyRegistry.json +0 -2
- package/src/forge/_generated/policyRegistry.ts +0 -11
- package/src/forge/_generated/queryRegistry.json +0 -2
- package/src/forge/_generated/queryRegistry.ts +0 -9
- package/src/forge/_generated/react.d.ts +0 -22
- package/src/forge/_generated/react.ts +0 -29
- package/src/forge/_generated/reactManifest.json +0 -2
- package/src/forge/_generated/reactManifest.ts +0 -19
- package/src/forge/_generated/rlsPolicies.json +0 -2
- package/src/forge/_generated/rlsPolicies.sql +0 -34
- package/src/forge/_generated/rlsPolicies.ts +0 -6
- package/src/forge/_generated/runtimeGraph.json +0 -2
- package/src/forge/_generated/runtimeGraph.ts +0 -8
- package/src/forge/_generated/runtimeMatrix.json +0 -2
- package/src/forge/_generated/runtimeMatrix.ts +0 -334130
- package/src/forge/_generated/runtimeRegistry.ts +0 -2
- package/src/forge/_generated/runtimeRules.md +0 -91
- package/src/forge/_generated/secretRegistry.json +0 -2
- package/src/forge/_generated/secretRegistry.ts +0 -50
- package/src/forge/_generated/secretsContext.ts +0 -11
- package/src/forge/_generated/serverApi.ts +0 -10
- package/src/forge/_generated/sourceMapManifest.json +0 -2
- package/src/forge/_generated/sourceMapManifest.ts +0 -7
- package/src/forge/_generated/sqlPlan.json +0 -2
- package/src/forge/_generated/sqlPlan.ts +0 -88
- package/src/forge/_generated/subscriptionManifest.json +0 -2
- package/src/forge/_generated/subscriptionManifest.ts +0 -7
- package/src/forge/_generated/symbolicationManifest.json +0 -2
- package/src/forge/_generated/symbolicationManifest.ts +0 -17
- package/src/forge/_generated/telemetryRegistry.json +0 -2
- package/src/forge/_generated/telemetryRegistry.ts +0 -9
- package/src/forge/_generated/telemetrySinks.json +0 -2
- package/src/forge/_generated/telemetrySinks.ts +0 -11
- package/src/forge/_generated/tenantScope.json +0 -2
- package/src/forge/_generated/tenantScope.ts +0 -8
- package/src/forge/_generated/testGraph.json +0 -2
- package/src/forge/_generated/testGraph.ts +0 -3118
- package/src/forge/_generated/testPlanRegistry.json +0 -2
- package/src/forge/_generated/testPlanRegistry.ts +0 -33
- package/src/forge/_generated/uiRoutes.json +0 -2
- package/src/forge/_generated/uiRoutes.ts +0 -16
- package/src/forge/_generated/uiScenarios.json +0 -2
- package/src/forge/_generated/uiScenarios.ts +0 -30
- package/src/forge/_generated/uiTestManifest.json +0 -2
- package/src/forge/_generated/uiTestManifest.ts +0 -27
- package/src/forge/_generated/workflowRegistry.json +0 -2
- package/src/forge/_generated/workflowRegistry.ts +0 -9
- package/src/forge/_generated/workflowSubscriptions.json +0 -2
- package/src/forge/_generated/workflowSubscriptions.ts +0 -10
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
package forge
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"encoding/json"
|
|
6
|
+
"net/http"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
const ProtocolVersion = "1.0"
|
|
10
|
+
|
|
11
|
+
type EntryKind string
|
|
12
|
+
type Risk string
|
|
13
|
+
type Transaction string
|
|
14
|
+
|
|
15
|
+
const (
|
|
16
|
+
KindCommand EntryKind = "command"
|
|
17
|
+
KindQuery EntryKind = "query"
|
|
18
|
+
|
|
19
|
+
RiskRead Risk = "read"
|
|
20
|
+
RiskWrite Risk = "write"
|
|
21
|
+
RiskDestructive Risk = "destructive"
|
|
22
|
+
RiskExternal Risk = "external"
|
|
23
|
+
|
|
24
|
+
TransactionReadOnly Transaction = "read-only"
|
|
25
|
+
TransactionExternalManaged Transaction = "external-managed"
|
|
26
|
+
TransactionForgeManaged Transaction = "forge-managed"
|
|
27
|
+
TransactionSaga Transaction = "saga"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
type Schema map[string]any
|
|
31
|
+
|
|
32
|
+
type Manifest struct {
|
|
33
|
+
ForgeProtocol string `json:"forgeProtocol"`
|
|
34
|
+
Language string `json:"language"`
|
|
35
|
+
Framework string `json:"framework,omitempty"`
|
|
36
|
+
Service Service `json:"service"`
|
|
37
|
+
Entries []Entry `json:"entries"`
|
|
38
|
+
Schemas map[string]any `json:"schemas,omitempty"`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type Service struct {
|
|
42
|
+
Name string `json:"name"`
|
|
43
|
+
Transport string `json:"transport"`
|
|
44
|
+
BaseURL string `json:"baseUrl,omitempty"`
|
|
45
|
+
Command string `json:"command,omitempty"`
|
|
46
|
+
Health string `json:"health,omitempty"`
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type Entry struct {
|
|
50
|
+
Name string `json:"name"`
|
|
51
|
+
Kind EntryKind `json:"kind"`
|
|
52
|
+
Description string `json:"description,omitempty"`
|
|
53
|
+
Path string `json:"path,omitempty"`
|
|
54
|
+
Method string `json:"method,omitempty"`
|
|
55
|
+
InputSchema any `json:"inputSchema,omitempty"`
|
|
56
|
+
OutputSchema any `json:"outputSchema,omitempty"`
|
|
57
|
+
Policy string `json:"policy,omitempty"`
|
|
58
|
+
TenantScoped bool `json:"tenantScoped,omitempty"`
|
|
59
|
+
Transaction Transaction `json:"transaction,omitempty"`
|
|
60
|
+
Risk Risk `json:"risk,omitempty"`
|
|
61
|
+
NeedsApproval *bool `json:"needsApproval,omitempty"`
|
|
62
|
+
Effects []string `json:"effects,omitempty"`
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
type Auth struct {
|
|
66
|
+
Kind string `json:"kind"`
|
|
67
|
+
UserID string `json:"userId,omitempty"`
|
|
68
|
+
TenantID string `json:"tenantId,omitempty"`
|
|
69
|
+
Role string `json:"role,omitempty"`
|
|
70
|
+
Roles []string `json:"roles,omitempty"`
|
|
71
|
+
Permissions []string `json:"permissions,omitempty"`
|
|
72
|
+
Email string `json:"email,omitempty"`
|
|
73
|
+
Name string `json:"name,omitempty"`
|
|
74
|
+
Claims map[string]any `json:"claims,omitempty"`
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
type ForgeCall struct {
|
|
78
|
+
Service string `json:"service"`
|
|
79
|
+
Entry string `json:"entry"`
|
|
80
|
+
Kind string `json:"kind"`
|
|
81
|
+
TraceID string `json:"traceId"`
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
type Context struct {
|
|
85
|
+
Auth Auth
|
|
86
|
+
Forge ForgeCall
|
|
87
|
+
Headers http.Header
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
type HandlerFunc func(context.Context, *Context, json.RawMessage) (any, error)
|
|
91
|
+
|
|
92
|
+
type RequestEnvelope struct {
|
|
93
|
+
Args json.RawMessage `json:"args"`
|
|
94
|
+
Auth Auth `json:"auth"`
|
|
95
|
+
Forge ForgeCall `json:"forge"`
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
type ResponseEnvelope struct {
|
|
99
|
+
OK bool `json:"ok"`
|
|
100
|
+
Result any `json:"result,omitempty"`
|
|
101
|
+
Diagnostics []Diagnostic `json:"diagnostics,omitempty"`
|
|
102
|
+
Error *ErrorInfo `json:"error,omitempty"`
|
|
103
|
+
TraceID string `json:"traceId,omitempty"`
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
type Diagnostic struct {
|
|
107
|
+
Severity string `json:"severity"`
|
|
108
|
+
Code string `json:"code"`
|
|
109
|
+
Message string `json:"message"`
|
|
110
|
+
File string `json:"file,omitempty"`
|
|
111
|
+
FixHint string `json:"fixHint,omitempty"`
|
|
112
|
+
Docs []string `json:"docs,omitempty"`
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
type ErrorInfo struct {
|
|
116
|
+
Code string `json:"code"`
|
|
117
|
+
Message string `json:"message"`
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
func Decode(raw json.RawMessage, target any) error {
|
|
121
|
+
if len(raw) == 0 || string(raw) == "null" {
|
|
122
|
+
raw = json.RawMessage("{}")
|
|
123
|
+
}
|
|
124
|
+
return json.Unmarshal(raw, target)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
func Handle[In any, Out any](handler func(context.Context, *Context, In) (Out, error)) HandlerFunc {
|
|
128
|
+
return func(ctx context.Context, call *Context, raw json.RawMessage) (any, error) {
|
|
129
|
+
var input In
|
|
130
|
+
if err := Decode(raw, &input); err != nil {
|
|
131
|
+
var zero Out
|
|
132
|
+
return zero, err
|
|
133
|
+
}
|
|
134
|
+
return handler(ctx, call, input)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Forge Java Adapter
|
|
2
|
+
|
|
3
|
+
`adapters/java` is the minimal Java SDK for external Forge runtimes. It mirrors
|
|
4
|
+
the Go adapter: register commands and queries, emit a `forge.manifest.json`, and
|
|
5
|
+
serve Forge-compatible HTTP envelopes.
|
|
6
|
+
|
|
7
|
+
```java
|
|
8
|
+
ForgeRegistry app = Forge.service("billing",
|
|
9
|
+
Forge.framework("java/jdk-http"),
|
|
10
|
+
Forge.baseUrl("http://127.0.0.1:8788"));
|
|
11
|
+
|
|
12
|
+
app.command("createInvoice",
|
|
13
|
+
Forge.handle(CreateInvoiceInput.class, Billing::createInvoice),
|
|
14
|
+
Forge.policy("billing.manage"),
|
|
15
|
+
Forge.tenantScoped(true),
|
|
16
|
+
Forge.needsApproval(true),
|
|
17
|
+
Forge.inputSchema(Schemas.object(Map.of("title", Schemas.string()), "title")));
|
|
18
|
+
|
|
19
|
+
app.query("listInvoices",
|
|
20
|
+
Forge.handle(EmptyInput.class, Billing::listInvoices),
|
|
21
|
+
Forge.policy("billing.manage"),
|
|
22
|
+
Forge.tenantScoped(true),
|
|
23
|
+
Forge.readOnly());
|
|
24
|
+
|
|
25
|
+
ForgeHttpHandler.listen(app, "127.0.0.1", 8788);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The HTTP handler exposes:
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
GET /health
|
|
32
|
+
GET /manifest?baseUrl=http://127.0.0.1:8788
|
|
33
|
+
POST /commands/:name
|
|
34
|
+
POST /queries/:name
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The handler accepts Forge runtime envelopes and returns Forge response
|
|
38
|
+
envelopes:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"args": { "title": "Invoice" },
|
|
43
|
+
"auth": { "kind": "user", "userId": "u1", "tenantId": "t1", "role": "admin" },
|
|
44
|
+
"forge": { "service": "billing", "entry": "createInvoice", "kind": "command", "traceId": "trace_..." }
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Build locally:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
mvn -f adapters/java/pom.xml install
|
|
52
|
+
mvn -f examples/java-billing/pom.xml package
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Emit and import a manifest:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
java -jar examples/java-billing/target/java-billing-0.1.0-alpha.11-all.jar --manifest --base-url http://127.0.0.1:8788 > java-billing.manifest.json
|
|
59
|
+
forge manifest import java-billing.manifest.json --json
|
|
60
|
+
forge generate
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Invoke through Forge:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
forge run billing.createInvoice --args '{"title":"Invoice"}' --role admin --tenant-id tenant-a
|
|
67
|
+
forge query billing.listInvoices --args '{}' --role admin --tenant-id tenant-a
|
|
68
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
3
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
4
|
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
5
|
+
<modelVersion>4.0.0</modelVersion>
|
|
6
|
+
|
|
7
|
+
<groupId>dev.forgeos</groupId>
|
|
8
|
+
<artifactId>forge-java-adapter</artifactId>
|
|
9
|
+
<version>0.1.0-alpha.11</version>
|
|
10
|
+
<name>Forge Java Adapter</name>
|
|
11
|
+
<description>Minimal Java SDK for Forge external runtimes.</description>
|
|
12
|
+
<url>https://forgeos.dev</url>
|
|
13
|
+
|
|
14
|
+
<licenses>
|
|
15
|
+
<license>
|
|
16
|
+
<name>Apache License, Version 2.0</name>
|
|
17
|
+
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
|
18
|
+
</license>
|
|
19
|
+
</licenses>
|
|
20
|
+
|
|
21
|
+
<properties>
|
|
22
|
+
<maven.compiler.release>17</maven.compiler.release>
|
|
23
|
+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
24
|
+
<jackson.version>2.17.2</jackson.version>
|
|
25
|
+
</properties>
|
|
26
|
+
|
|
27
|
+
<dependencies>
|
|
28
|
+
<dependency>
|
|
29
|
+
<groupId>com.fasterxml.jackson.core</groupId>
|
|
30
|
+
<artifactId>jackson-databind</artifactId>
|
|
31
|
+
<version>${jackson.version}</version>
|
|
32
|
+
</dependency>
|
|
33
|
+
</dependencies>
|
|
34
|
+
</project>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package dev.forgeos.adapter;
|
|
2
|
+
|
|
3
|
+
import java.util.List;
|
|
4
|
+
import java.util.Map;
|
|
5
|
+
|
|
6
|
+
public record Auth(
|
|
7
|
+
String kind,
|
|
8
|
+
String userId,
|
|
9
|
+
String tenantId,
|
|
10
|
+
String role,
|
|
11
|
+
List<String> roles,
|
|
12
|
+
List<String> permissions,
|
|
13
|
+
String email,
|
|
14
|
+
String name,
|
|
15
|
+
Map<String, Object> claims
|
|
16
|
+
) {
|
|
17
|
+
public static Auth anonymous() {
|
|
18
|
+
return new Auth("anonymous", null, null, null, null, null, null, null, null);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package dev.forgeos.adapter;
|
|
2
|
+
|
|
3
|
+
import java.util.List;
|
|
4
|
+
|
|
5
|
+
public record Diagnostic(
|
|
6
|
+
String severity,
|
|
7
|
+
String code,
|
|
8
|
+
String message,
|
|
9
|
+
String file,
|
|
10
|
+
String fixHint,
|
|
11
|
+
List<String> docs
|
|
12
|
+
) {
|
|
13
|
+
public static Diagnostic error(String code, String message) {
|
|
14
|
+
return new Diagnostic("error", code, message, null, null, List.of("docs/forge-protocol.md"));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
package dev.forgeos.adapter;
|
|
2
|
+
|
|
3
|
+
import java.util.ArrayList;
|
|
4
|
+
import java.util.List;
|
|
5
|
+
|
|
6
|
+
public final class Entry {
|
|
7
|
+
public String name;
|
|
8
|
+
public String kind;
|
|
9
|
+
public String description;
|
|
10
|
+
public String path;
|
|
11
|
+
public String method;
|
|
12
|
+
public Object inputSchema;
|
|
13
|
+
public Object outputSchema;
|
|
14
|
+
public String policy;
|
|
15
|
+
public Boolean tenantScoped;
|
|
16
|
+
public String transaction;
|
|
17
|
+
public String risk;
|
|
18
|
+
public Boolean needsApproval;
|
|
19
|
+
public List<String> effects;
|
|
20
|
+
|
|
21
|
+
public Entry copy() {
|
|
22
|
+
Entry copy = new Entry();
|
|
23
|
+
copy.name = name;
|
|
24
|
+
copy.kind = kind;
|
|
25
|
+
copy.description = description;
|
|
26
|
+
copy.path = path;
|
|
27
|
+
copy.method = method;
|
|
28
|
+
copy.inputSchema = inputSchema;
|
|
29
|
+
copy.outputSchema = outputSchema;
|
|
30
|
+
copy.policy = policy;
|
|
31
|
+
copy.tenantScoped = tenantScoped;
|
|
32
|
+
copy.transaction = transaction;
|
|
33
|
+
copy.risk = risk;
|
|
34
|
+
copy.needsApproval = needsApproval;
|
|
35
|
+
copy.effects = effects == null ? null : new ArrayList<>(effects);
|
|
36
|
+
return copy;
|
|
37
|
+
}
|
|
38
|
+
}
|