forgeos 0.1.0-alpha.2 → 0.1.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.npmignore +4 -0
- package/AGENTS.md +168 -81
- package/CHANGELOG.md +211 -0
- package/README.md +88 -14
- 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/target/classes/dev/forgeos/adapter/Auth.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/Diagnostic.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/Entry.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/EntryKind.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/ErrorInfo.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/Forge.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/ForgeCall.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/ForgeContext.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/ForgeHandler.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/ForgeHttpHandler.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/ForgeRegistry$EntryOption.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/ForgeRegistry$RegisteredEntry.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/ForgeRegistry$RegistryOption.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/ForgeRegistry.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/Json.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/Manifest.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/RequestEnvelope.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/ResponseEnvelope.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/Risk.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/Schemas.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/Service.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/TransactionMode.class +0 -0
- package/adapters/java/target/classes/dev/forgeos/adapter/TypedForgeHandler.class +0 -0
- package/adapters/java/target/forge-java-adapter-0.1.0-alpha.11.jar +0 -0
- package/adapters/java/target/maven-archiver/pom.properties +3 -0
- package/adapters/java/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +23 -0
- package/adapters/java/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +20 -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/adapters/java-spring-boot-starter/target/classes/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +1 -0
- package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeCommand.class +0 -0
- package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeExternalService.class +0 -0
- package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeQuery.class +0 -0
- package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeServiceBeanCondition.class +0 -0
- package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeSpringAutoConfiguration.class +0 -0
- package/adapters/java-spring-boot-starter/target/classes/dev/forgeos/adapter/spring/ForgeSpringRuntime.class +0 -0
- package/adapters/java-spring-boot-starter/target/forge-java-spring-boot-starter-0.1.0-alpha.11.jar +0 -0
- package/adapters/java-spring-boot-starter/target/maven-archiver/pom.properties +3 -0
- package/adapters/java-spring-boot-starter/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +6 -0
- package/adapters/java-spring-boot-starter/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +6 -0
- package/bin/forge.mjs +18 -0
- package/docs/changelog.md +242 -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/examples/java-billing/target/classes/dev/forgeos/examples/billing/CreateInvoiceInput.class +0 -0
- package/examples/java-billing/target/classes/dev/forgeos/examples/billing/Invoice.class +0 -0
- package/examples/java-billing/target/classes/dev/forgeos/examples/billing/Main$EmptyInput.class +0 -0
- package/examples/java-billing/target/classes/dev/forgeos/examples/billing/Main$Options.class +0 -0
- package/examples/java-billing/target/classes/dev/forgeos/examples/billing/Main.class +0 -0
- package/examples/java-billing/target/java-billing-0.1.0-alpha.11-all.jar +0 -0
- package/examples/java-billing/target/java-billing-0.1.0-alpha.11.jar +0 -0
- package/examples/java-billing/target/maven-archiver/pom.properties +3 -0
- package/examples/java-billing/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +5 -0
- package/examples/java-billing/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +3 -0
- package/package.json +29 -7
- 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 +1511 -123
- package/src/forge/agent-adapters/types.ts +216 -1
- package/src/forge/agent-memory/bridge.ts +1245 -0
- package/src/forge/agent-memory/context-pack.ts +151 -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 +191 -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 +671 -3
- package/src/forge/cli/auth.ts +36 -1
- package/src/forge/cli/build.ts +20 -4
- package/src/forge/cli/changed.ts +300 -0
- package/src/forge/cli/codex-app-server.ts +877 -0
- package/src/forge/cli/commands.ts +1285 -7
- 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 +250 -0
- package/src/forge/cli/index.ts +1 -0
- package/src/forge/cli/main.ts +49 -3
- package/src/forge/cli/new.ts +3 -1
- package/src/forge/cli/next-actions.ts +23 -0
- package/src/forge/cli/output.ts +290 -1
- package/src/forge/cli/parse.ts +770 -36
- 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 +2163 -0
- package/src/forge/cli/verify.ts +1422 -32
- package/src/forge/compiler/agent-contract/build.ts +725 -41
- package/src/forge/compiler/agent-contract/types.ts +85 -0
- package/src/forge/compiler/ai-registry/build.ts +62 -1
- package/src/forge/compiler/ai-registry/constants.ts +1 -1
- package/src/forge/compiler/ai-registry/parse.ts +168 -5
- 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/forge-apis.ts +1 -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/dev-manifest/build.ts +3 -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 +5 -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 +85 -13
- package/src/forge/compiler/integration/add.ts +498 -22
- package/src/forge/compiler/integration/snapshot.ts +2 -0
- package/src/forge/compiler/make-registry/build.ts +19 -7
- package/src/forge/compiler/orchestrator/plan-profile.ts +23 -0
- package/src/forge/compiler/orchestrator/plan.ts +78 -7
- 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 +101 -8
- 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 +44 -1
- package/src/forge/compiler/test-graph/build.ts +11 -3
- package/src/forge/compiler/types/ai-registry.ts +25 -1
- package/src/forge/compiler/types/app-graph.ts +9 -2
- package/src/forge/compiler/types/cli.ts +76 -1
- package/src/forge/compiler/types/dev-manifest.ts +3 -0
- package/src/forge/compiler/types/frontend-graph.ts +2 -2
- package/src/forge/delta/classifier.ts +52 -0
- package/src/forge/delta/explain.ts +126 -0
- package/src/forge/delta/git-observer.ts +43 -0
- package/src/forge/delta/ids.ts +44 -0
- package/src/forge/delta/index.ts +13 -0
- package/src/forge/delta/recorder.ts +402 -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 +489 -0
- package/src/forge/delta/store.ts +2975 -0
- package/src/forge/delta/timeline.ts +104 -0
- package/src/forge/dev/server.ts +768 -15
- 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 +149 -6
- package/src/forge/make/templates.ts +343 -2
- package/src/forge/make/types.ts +3 -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/ai/context.ts +210 -5
- package/src/forge/runtime/ai/types.ts +70 -0
- package/src/forge/runtime/auth/claims.ts +32 -0
- package/src/forge/runtime/auth/errors.ts +2 -0
- package/src/forge/runtime/context/create-context.ts +30 -6
- 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 +112 -2
- package/src/forge/runtime/external/bridge.ts +649 -0
- package/src/forge/runtime/runner/run-entry.ts +16 -7
- package/src/forge/runtime/telemetry/scrubber.ts +91 -10
- package/src/forge/runtime/webhooks/security.ts +184 -0
- package/src/forge/server.ts +100 -2
- package/src/forge/version.ts +1 -1
- package/src/forge/vue/index.ts +407 -0
- package/src/forge/workspace/change-summary.ts +209 -0
- package/src/forge/workspace/forge-cli.ts +14 -0
- package/src/forge/workspace/git-summary.ts +279 -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/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 -7696
- package/src/forge/_generated/agentQuickstart.md +0 -32
- package/src/forge/_generated/aiContext.ts +0 -59
- package/src/forge/_generated/aiModels.json +0 -2
- package/src/forge/_generated/aiModels.ts +0 -35
- 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 -29
- 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 -14667
- package/src/forge/_generated/appMap.md +0 -35
- 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 -47
- 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 -67
- 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 -163
- package/src/forge/_generated/makeTemplates.json +0 -2
- package/src/forge/_generated/makeTemplates.ts +0 -61
- package/src/forge/_generated/mockMap.json +0 -2
- package/src/forge/_generated/mockMap.ts +0 -7
- package/src/forge/_generated/operationPlaybooks.md +0 -147
- package/src/forge/_generated/packageGraph.json +0 -2
- package/src/forge/_generated/packageGraph.ts +0 -245249
- 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 -327385
- package/src/forge/_generated/runtimeRegistry.ts +0 -2
- package/src/forge/_generated/runtimeRules.md +0 -79
- 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 -3108
- 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,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
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
package dev.forgeos.adapter;
|
|
2
|
+
|
|
3
|
+
import com.fasterxml.jackson.databind.JsonNode;
|
|
4
|
+
import java.util.Arrays;
|
|
5
|
+
import java.util.List;
|
|
6
|
+
|
|
7
|
+
public final class Forge {
|
|
8
|
+
private Forge() {
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public static ForgeRegistry service(String serviceName, ForgeRegistry.RegistryOption... options) {
|
|
12
|
+
return new ForgeRegistry(serviceName, options);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public static ForgeRegistry.RegistryOption framework(String value) {
|
|
16
|
+
return registry -> registry.setFramework(value);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public static ForgeRegistry.RegistryOption baseUrl(String value) {
|
|
20
|
+
return registry -> registry.setBaseUrl(value);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public static ForgeRegistry.RegistryOption health(String path) {
|
|
24
|
+
return registry -> registry.setHealth(path);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public static ForgeRegistry.RegistryOption schemaRef(String name, Object schema) {
|
|
28
|
+
return registry -> registry.addSchema(name, schema);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public static ForgeRegistry.EntryOption description(String value) {
|
|
32
|
+
return entry -> entry.description = value;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public static ForgeRegistry.EntryOption path(String value) {
|
|
36
|
+
return entry -> entry.path = value;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public static ForgeRegistry.EntryOption method(String value) {
|
|
40
|
+
return entry -> entry.method = value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public static ForgeRegistry.EntryOption inputSchema(Object schema) {
|
|
44
|
+
return entry -> entry.inputSchema = schema;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public static ForgeRegistry.EntryOption outputSchema(Object schema) {
|
|
48
|
+
return entry -> entry.outputSchema = schema;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public static ForgeRegistry.EntryOption policy(String value) {
|
|
52
|
+
return entry -> entry.policy = value;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public static ForgeRegistry.EntryOption tenantScoped(boolean value) {
|
|
56
|
+
return entry -> entry.tenantScoped = value;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public static ForgeRegistry.EntryOption transaction(TransactionMode value) {
|
|
60
|
+
return entry -> entry.transaction = value.value();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public static ForgeRegistry.EntryOption risk(Risk value) {
|
|
64
|
+
return entry -> entry.risk = value.value();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public static ForgeRegistry.EntryOption needsApproval(boolean value) {
|
|
68
|
+
return entry -> entry.needsApproval = value;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public static ForgeRegistry.EntryOption effects(String... values) {
|
|
72
|
+
return entry -> entry.effects = List.copyOf(Arrays.asList(values));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public static ForgeRegistry.EntryOption readOnly() {
|
|
76
|
+
return entry -> {
|
|
77
|
+
entry.transaction = TransactionMode.READ_ONLY.value();
|
|
78
|
+
entry.risk = Risk.READ.value();
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public static <In, Out> ForgeHandler handle(
|
|
83
|
+
Class<In> inputClass,
|
|
84
|
+
TypedForgeHandler<In, Out> handler
|
|
85
|
+
) {
|
|
86
|
+
return (context, rawArgs) -> {
|
|
87
|
+
JsonNode args = rawArgs == null || rawArgs.isNull()
|
|
88
|
+
? Json.MAPPER.createObjectNode()
|
|
89
|
+
: rawArgs;
|
|
90
|
+
In input = Json.MAPPER.treeToValue(args, inputClass);
|
|
91
|
+
return handler.handle(context, input);
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package dev.forgeos.adapter;
|
|
2
|
+
|
|
3
|
+
public record ForgeCall(String service, String entry, String kind, String traceId) {
|
|
4
|
+
public ForgeCall withDefaults(String serviceName, String entryName, String entryKind, String fallbackTraceId) {
|
|
5
|
+
return new ForgeCall(
|
|
6
|
+
service == null || service.isBlank() ? serviceName : service,
|
|
7
|
+
entry == null || entry.isBlank() ? entryName : entry,
|
|
8
|
+
kind == null || kind.isBlank() ? entryKind : kind,
|
|
9
|
+
traceId == null || traceId.isBlank() ? fallbackTraceId : traceId
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
package dev.forgeos.adapter;
|
|
2
|
+
|
|
3
|
+
import com.fasterxml.jackson.databind.JsonNode;
|
|
4
|
+
import com.sun.net.httpserver.Headers;
|
|
5
|
+
import com.sun.net.httpserver.HttpExchange;
|
|
6
|
+
import com.sun.net.httpserver.HttpHandler;
|
|
7
|
+
import com.sun.net.httpserver.HttpServer;
|
|
8
|
+
import java.io.IOException;
|
|
9
|
+
import java.io.InputStream;
|
|
10
|
+
import java.io.OutputStream;
|
|
11
|
+
import java.net.InetSocketAddress;
|
|
12
|
+
import java.net.URI;
|
|
13
|
+
import java.net.URLDecoder;
|
|
14
|
+
import java.nio.charset.StandardCharsets;
|
|
15
|
+
import java.util.HashMap;
|
|
16
|
+
import java.util.List;
|
|
17
|
+
import java.util.Map;
|
|
18
|
+
|
|
19
|
+
public final class ForgeHttpHandler implements HttpHandler {
|
|
20
|
+
private final ForgeRegistry registry;
|
|
21
|
+
|
|
22
|
+
public ForgeHttpHandler(ForgeRegistry registry) {
|
|
23
|
+
this.registry = registry;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public static HttpServer listen(ForgeRegistry registry, String host, int port) throws IOException {
|
|
27
|
+
HttpServer server = HttpServer.create(new InetSocketAddress(host, port), 0);
|
|
28
|
+
ForgeHttpHandler handler = new ForgeHttpHandler(registry);
|
|
29
|
+
server.createContext("/", handler);
|
|
30
|
+
server.start();
|
|
31
|
+
return server;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@Override
|
|
35
|
+
public void handle(HttpExchange exchange) throws IOException {
|
|
36
|
+
String path = exchange.getRequestURI().getPath();
|
|
37
|
+
try {
|
|
38
|
+
if (registry.healthPath().equals(path)) {
|
|
39
|
+
writeJson(exchange, 200, Map.of("ok", true, "service", registry.serviceName()));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if ("/manifest".equals(path)) {
|
|
43
|
+
String baseUrl = queryParams(exchange.getRequestURI()).getOrDefault("baseUrl", registry.baseUrl());
|
|
44
|
+
writeJson(exchange, 200, registry.manifest(baseUrl));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (path.startsWith("/commands/")) {
|
|
48
|
+
handleRuntime(exchange, EntryKind.COMMAND, path.substring("/commands/".length()));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (path.startsWith("/queries/")) {
|
|
52
|
+
handleRuntime(exchange, EntryKind.QUERY, path.substring("/queries/".length()));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
writeError(exchange, 404, traceIdFrom(exchange, null), "FORGE_JAVA_ROUTE_NOT_FOUND", "route not found");
|
|
56
|
+
} catch (Exception error) {
|
|
57
|
+
writeError(exchange, 500, traceIdFrom(exchange, null), "FORGE_JAVA_HANDLER_FAILED", error.getMessage());
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private void handleRuntime(HttpExchange exchange, EntryKind kind, String rawName) throws IOException {
|
|
62
|
+
String name = decode(rawName);
|
|
63
|
+
if (!"POST".equals(exchange.getRequestMethod()) && !"GET".equals(exchange.getRequestMethod())) {
|
|
64
|
+
writeError(exchange, 405, traceIdFrom(exchange, null), "FORGE_JAVA_METHOD_NOT_ALLOWED", "external entry only accepts GET or POST");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
ForgeRegistry.RegisteredEntry registered = registry.lookup(kind, name);
|
|
69
|
+
if (registered == null) {
|
|
70
|
+
writeError(exchange, 404, traceIdFrom(exchange, null), "FORGE_JAVA_ENTRY_NOT_FOUND", "external entry not found");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
RequestEnvelope envelope;
|
|
75
|
+
try {
|
|
76
|
+
envelope = readEnvelope(exchange);
|
|
77
|
+
} catch (Exception error) {
|
|
78
|
+
writeError(exchange, 400, traceIdFrom(exchange, null), "FORGE_JAVA_BAD_REQUEST", error.getMessage());
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
String traceId = traceIdFrom(exchange, envelope);
|
|
83
|
+
ForgeCall forge = envelope.forge() == null
|
|
84
|
+
? new ForgeCall(registry.serviceName(), name, kind.value(), traceId)
|
|
85
|
+
: envelope.forge().withDefaults(registry.serviceName(), name, kind.value(), traceId);
|
|
86
|
+
Auth auth = envelope.auth() == null || envelope.auth().kind() == null
|
|
87
|
+
? authFromHeaders(exchange.getRequestHeaders())
|
|
88
|
+
: envelope.auth();
|
|
89
|
+
|
|
90
|
+
ForgeContext context = new ForgeContext(auth, forge, exchange.getRequestHeaders());
|
|
91
|
+
try {
|
|
92
|
+
Object result = registered.handler().handle(context, envelope.args());
|
|
93
|
+
writeJson(exchange, 200, ResponseEnvelope.ok(result, forge.traceId()));
|
|
94
|
+
} catch (Exception error) {
|
|
95
|
+
writeError(exchange, 500, forge.traceId(), "FORGE_JAVA_HANDLER_FAILED", error.getMessage());
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private RequestEnvelope readEnvelope(HttpExchange exchange) throws IOException {
|
|
100
|
+
if ("GET".equals(exchange.getRequestMethod())) {
|
|
101
|
+
String args = queryParams(exchange.getRequestURI()).getOrDefault("args", "{}");
|
|
102
|
+
JsonNode argsNode = Json.MAPPER.readTree(args);
|
|
103
|
+
return new RequestEnvelope(argsNode, null, null);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
try (InputStream body = exchange.getRequestBody()) {
|
|
107
|
+
byte[] bytes = body.readAllBytes();
|
|
108
|
+
if (bytes.length == 0) {
|
|
109
|
+
return new RequestEnvelope(Json.MAPPER.createObjectNode(), null, null);
|
|
110
|
+
}
|
|
111
|
+
RequestEnvelope envelope = Json.MAPPER.readValue(bytes, RequestEnvelope.class);
|
|
112
|
+
JsonNode args = envelope.args() == null ? Json.MAPPER.createObjectNode() : envelope.args();
|
|
113
|
+
return new RequestEnvelope(args, envelope.auth(), envelope.forge());
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private static Auth authFromHeaders(Headers headers) {
|
|
118
|
+
String kind = firstHeader(headers, "x-forge-auth-kind");
|
|
119
|
+
if (kind == null || kind.isBlank()) {
|
|
120
|
+
kind = "anonymous";
|
|
121
|
+
}
|
|
122
|
+
return new Auth(
|
|
123
|
+
kind,
|
|
124
|
+
firstHeader(headers, "x-forge-user-id"),
|
|
125
|
+
firstHeader(headers, "x-forge-tenant-id"),
|
|
126
|
+
firstHeader(headers, "x-forge-role"),
|
|
127
|
+
null,
|
|
128
|
+
null,
|
|
129
|
+
null,
|
|
130
|
+
null,
|
|
131
|
+
null
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private static String traceIdFrom(HttpExchange exchange, RequestEnvelope envelope) {
|
|
136
|
+
if (envelope != null && envelope.forge() != null && envelope.forge().traceId() != null) {
|
|
137
|
+
return envelope.forge().traceId();
|
|
138
|
+
}
|
|
139
|
+
return firstHeader(exchange.getRequestHeaders(), "x-forge-trace-id");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private static String firstHeader(Headers headers, String name) {
|
|
143
|
+
List<String> values = headers.get(name);
|
|
144
|
+
if (values == null || values.isEmpty()) {
|
|
145
|
+
values = headers.get(name.toLowerCase());
|
|
146
|
+
}
|
|
147
|
+
return values == null || values.isEmpty() ? null : values.get(0);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private static Map<String, String> queryParams(URI uri) {
|
|
151
|
+
Map<String, String> params = new HashMap<>();
|
|
152
|
+
String query = uri.getRawQuery();
|
|
153
|
+
if (query == null || query.isBlank()) {
|
|
154
|
+
return params;
|
|
155
|
+
}
|
|
156
|
+
for (String part : query.split("&")) {
|
|
157
|
+
String[] pieces = part.split("=", 2);
|
|
158
|
+
params.put(decode(pieces[0]), pieces.length > 1 ? decode(pieces[1]) : "");
|
|
159
|
+
}
|
|
160
|
+
return params;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private static String decode(String value) {
|
|
164
|
+
return URLDecoder.decode(value, StandardCharsets.UTF_8);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private static void writeError(HttpExchange exchange, int status, String traceId, String code, String message) throws IOException {
|
|
168
|
+
writeJson(exchange, status, ResponseEnvelope.error(code, message, traceId));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private static void writeJson(HttpExchange exchange, int status, Object body) throws IOException {
|
|
172
|
+
byte[] bytes = Json.MAPPER.writeValueAsBytes(body);
|
|
173
|
+
exchange.getResponseHeaders().set("content-type", "application/json");
|
|
174
|
+
exchange.sendResponseHeaders(status, bytes.length);
|
|
175
|
+
try (OutputStream response = exchange.getResponseBody()) {
|
|
176
|
+
response.write(bytes);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|