forgeos 0.1.0-alpha.0 → 0.1.0-alpha.10
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 +9 -1
- package/AGENTS.md +43 -3
- package/CHANGELOG.md +109 -0
- package/CONTRIBUTING.md +22 -1
- package/README.md +82 -11
- 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/bin/forge.mjs +4 -3
- package/docs/changelog.md +116 -0
- package/docs/forge-protocol.md +156 -0
- package/examples/go-billing/go.mod +7 -0
- package/examples/go-billing/main.go +120 -0
- package/package.json +18 -7
- package/packages/eslint-plugin-forge/index.ts +15 -15
- package/packages/eslint-plugin-forge/package.json +10 -10
- package/packages/eslint-plugin-forge/src/check-source.ts +95 -95
- package/packages/eslint-plugin-forge/src/load-artifacts.ts +24 -24
- package/packages/eslint-plugin-forge/src/rule-no-forge-guard-violation.ts +93 -93
- package/schemas/forge-manifest.schema.json +57 -0
- package/src/forge/_generated/actionSubscriptions.json +1 -2
- package/src/forge/_generated/actionSubscriptions.ts +3 -3
- package/src/forge/_generated/agentAdapterManifest.json +1 -2
- package/src/forge/_generated/agentAdapterManifest.ts +3 -3
- package/src/forge/_generated/agentContract.json +1 -2
- package/src/forge/_generated/agentContract.ts +6927 -7
- package/src/forge/_generated/agentQuickstart.md +3 -1
- package/src/forge/_generated/agentTools.json +1 -0
- package/src/forge/_generated/agentTools.md +16 -0
- package/src/forge/_generated/agentTools.ts +12 -0
- package/src/forge/_generated/aiContext.ts +67 -1
- package/src/forge/_generated/aiModels.json +1 -2
- package/src/forge/_generated/aiModels.ts +17 -1
- package/src/forge/_generated/aiProviders.json +0 -1
- package/src/forge/_generated/aiProviders.ts +1 -1
- package/src/forge/_generated/aiRegistry.json +1 -2
- package/src/forge/_generated/aiRegistry.ts +7 -5
- package/src/forge/_generated/api.json +1 -2
- package/src/forge/_generated/api.ts +7 -2
- package/src/forge/_generated/appGraph.json +1 -2
- package/src/forge/_generated/appGraph.ts +2186 -1346
- package/src/forge/_generated/appMap.md +21 -1
- package/src/forge/_generated/artifactManifest.json +1 -2
- package/src/forge/_generated/artifactManifest.ts +2 -2
- package/src/forge/_generated/authClaims.json +0 -1
- package/src/forge/_generated/authClaims.ts +1 -1
- package/src/forge/_generated/authConfig.json +0 -1
- package/src/forge/_generated/authConfig.ts +1 -1
- package/src/forge/_generated/authContext.ts +1 -1
- package/src/forge/_generated/authRegistry.json +0 -1
- package/src/forge/_generated/authRegistry.ts +1 -1
- package/src/forge/_generated/buildInfo.json +1 -2
- package/src/forge/_generated/buildInfo.ts +4 -4
- package/src/forge/_generated/capabilityMap.json +1 -2
- package/src/forge/_generated/capabilityMap.md +1 -1
- package/src/forge/_generated/capabilityMap.ts +2 -2
- package/src/forge/_generated/client.ts +88 -1
- package/src/forge/_generated/clientApi.ts +2 -1
- package/src/forge/_generated/clientManifest.json +1 -2
- package/src/forge/_generated/clientManifest.ts +6 -4
- package/src/forge/_generated/clientTypes.ts +19 -1
- package/src/forge/_generated/configRegistry.json +0 -1
- package/src/forge/_generated/configRegistry.ts +1 -1
- package/src/forge/_generated/dataGraph.json +1 -2
- package/src/forge/_generated/dataGraph.ts +3 -3
- package/src/forge/_generated/db.json +0 -1
- package/src/forge/_generated/db.ts +1 -1
- package/src/forge/_generated/dbSecurityManifest.json +0 -1
- package/src/forge/_generated/dbSecurityManifest.ts +1 -1
- package/src/forge/_generated/dbSessionContext.json +0 -1
- package/src/forge/_generated/dbSessionContext.ts +1 -1
- package/src/forge/_generated/deployManifest.json +1 -2
- package/src/forge/_generated/deployManifest.ts +7 -7
- package/src/forge/_generated/devManifest.json +1 -2
- package/src/forge/_generated/devManifest.ts +18 -3
- package/src/forge/_generated/envSchema.json +0 -1
- package/src/forge/_generated/envSchema.ts +1 -1
- package/src/forge/_generated/externalServices.json +1 -0
- package/src/forge/_generated/externalServices.ts +9 -0
- package/src/forge/_generated/frontendGraph.json +0 -1
- package/src/forge/_generated/frontendGraph.ts +1 -1
- package/src/forge/_generated/importGuards.json +1 -2
- package/src/forge/_generated/importGuards.ts +35 -1
- package/src/forge/_generated/index.ts +3 -1
- package/src/forge/_generated/liveProductionManifest.json +0 -1
- package/src/forge/_generated/liveProductionManifest.ts +1 -1
- package/src/forge/_generated/liveProtocol.json +0 -1
- package/src/forge/_generated/liveProtocol.ts +1 -1
- package/src/forge/_generated/liveQueryRegistry.json +1 -2
- package/src/forge/_generated/liveQueryRegistry.ts +3 -3
- package/src/forge/_generated/liveTransportConfig.json +0 -1
- package/src/forge/_generated/liveTransportConfig.ts +1 -1
- package/src/forge/_generated/makeRegistry.json +1 -2
- package/src/forge/_generated/makeRegistry.ts +16 -2
- package/src/forge/_generated/makeTemplates.json +1 -2
- package/src/forge/_generated/makeTemplates.ts +6 -1
- package/src/forge/_generated/mockMap.json +0 -1
- package/src/forge/_generated/mockMap.ts +1 -1
- package/src/forge/_generated/operationPlaybooks.md +40 -18
- package/src/forge/_generated/packageGraph.json +1 -2
- package/src/forge/_generated/packageGraph.ts +114376 -33611
- package/src/forge/_generated/packageUpgradeRegistry.json +1 -2
- package/src/forge/_generated/packageUpgradeRegistry.ts +2 -2
- package/src/forge/_generated/permissionMatrix.json +1 -2
- package/src/forge/_generated/permissionMatrix.ts +3 -3
- package/src/forge/_generated/policyRegistry.json +1 -2
- package/src/forge/_generated/policyRegistry.ts +3 -3
- package/src/forge/_generated/queryRegistry.json +1 -2
- package/src/forge/_generated/queryRegistry.ts +3 -3
- package/src/forge/_generated/react.d.ts +1 -1
- package/src/forge/_generated/react.ts +1 -1
- package/src/forge/_generated/reactManifest.json +1 -2
- package/src/forge/_generated/reactManifest.ts +3 -3
- package/src/forge/_generated/releaseManifest.json +1 -2
- package/src/forge/_generated/releaseManifest.ts +3 -3
- package/src/forge/_generated/rlsPolicies.json +0 -1
- package/src/forge/_generated/rlsPolicies.sql +1 -1
- package/src/forge/_generated/rlsPolicies.ts +1 -1
- package/src/forge/_generated/runtimeGraph.json +1 -2
- package/src/forge/_generated/runtimeGraph.ts +3 -3
- package/src/forge/_generated/runtimeMatrix.json +1 -2
- package/src/forge/_generated/runtimeMatrix.ts +118936 -13931
- package/src/forge/_generated/runtimeRegistry.ts +1 -1
- package/src/forge/_generated/runtimeRules.md +13 -1
- package/src/forge/_generated/secretRegistry.json +0 -1
- package/src/forge/_generated/secretRegistry.ts +1 -1
- package/src/forge/_generated/secretsContext.ts +1 -1
- package/src/forge/_generated/serverApi.ts +2 -1
- package/src/forge/_generated/sourceMapManifest.json +1 -2
- package/src/forge/_generated/sourceMapManifest.ts +2 -2
- package/src/forge/_generated/sqlPlan.json +0 -1
- package/src/forge/_generated/sqlPlan.ts +1 -1
- package/src/forge/_generated/subscriptionManifest.json +1 -2
- package/src/forge/_generated/subscriptionManifest.ts +3 -3
- package/src/forge/_generated/symbolicationManifest.json +1 -2
- package/src/forge/_generated/symbolicationManifest.ts +2 -2
- package/src/forge/_generated/telemetryRegistry.json +1 -2
- package/src/forge/_generated/telemetryRegistry.ts +3 -3
- package/src/forge/_generated/telemetrySinks.json +1 -2
- package/src/forge/_generated/telemetrySinks.ts +2 -2
- package/src/forge/_generated/tenantScope.json +1 -2
- package/src/forge/_generated/tenantScope.ts +3 -3
- package/src/forge/_generated/testGraph.json +1 -2
- package/src/forge/_generated/testGraph.ts +565 -113
- package/src/forge/_generated/testPlanRegistry.json +1 -2
- package/src/forge/_generated/testPlanRegistry.ts +2 -2
- package/src/forge/_generated/uiRoutes.json +0 -1
- package/src/forge/_generated/uiRoutes.ts +1 -1
- package/src/forge/_generated/uiScenarios.json +0 -1
- package/src/forge/_generated/uiScenarios.ts +1 -1
- package/src/forge/_generated/uiTestManifest.json +1 -2
- package/src/forge/_generated/uiTestManifest.ts +2 -2
- package/src/forge/_generated/workflowRegistry.json +1 -2
- package/src/forge/_generated/workflowRegistry.ts +3 -3
- package/src/forge/_generated/workflowSubscriptions.json +1 -2
- package/src/forge/_generated/workflowSubscriptions.ts +3 -3
- package/src/forge/bench.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 +1 -1
- package/src/forge/cli/commands.ts +1013 -861
- package/src/forge/cli/deps.ts +178 -11
- package/src/forge/cli/dev.ts +32 -5
- package/src/forge/cli/index.ts +7 -7
- package/src/forge/cli/main.ts +57 -55
- package/src/forge/cli/new.ts +29 -1
- package/src/forge/cli/output.ts +97 -97
- package/src/forge/cli/parse.ts +867 -677
- package/src/forge/cli/query.ts +32 -0
- 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/verify.ts +201 -24
- package/src/forge/cli/version.ts +1 -1
- package/src/forge/compiler/agent-contract/build.ts +435 -12
- package/src/forge/compiler/agent-contract/types.ts +88 -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 +98 -4
- package/src/forge/compiler/api-surface/build.ts +47 -0
- package/src/forge/compiler/app-graph/build.ts +141 -113
- package/src/forge/compiler/app-graph/classify.ts +10 -10
- package/src/forge/compiler/app-graph/dup-symbol.ts +29 -29
- package/src/forge/compiler/app-graph/extract.ts +123 -123
- package/src/forge/compiler/app-graph/forge-apis.ts +30 -29
- package/src/forge/compiler/app-graph/index.ts +11 -11
- package/src/forge/compiler/app-graph/module-graph.ts +312 -317
- package/src/forge/compiler/app-graph/parser.ts +119 -119
- package/src/forge/compiler/app-graph/profile.ts +26 -0
- package/src/forge/compiler/app-graph/symbols.ts +48 -48
- package/src/forge/compiler/app-graph/tsconfig-hash.ts +62 -62
- package/src/forge/compiler/app-graph/types.ts +43 -43
- package/src/forge/compiler/app-graph/versions.ts +14 -14
- package/src/forge/compiler/cache/index.ts +17 -17
- package/src/forge/compiler/cache/key.ts +46 -46
- package/src/forge/compiler/cache/scheduler.ts +72 -72
- package/src/forge/compiler/cache/store.ts +78 -78
- package/src/forge/compiler/classifier/capabilities.ts +79 -78
- package/src/forge/compiler/classifier/classify.ts +137 -113
- package/src/forge/compiler/classifier/contexts.ts +188 -188
- package/src/forge/compiler/classifier/index.ts +18 -18
- package/src/forge/compiler/classifier/runtime-matrix.ts +45 -45
- package/src/forge/compiler/classifier/secrets.ts +42 -41
- package/src/forge/compiler/classifier/signals.ts +219 -129
- package/src/forge/compiler/client-sdk/build-manifest.ts +4 -0
- package/src/forge/compiler/client-sdk/render-client.ts +105 -0
- package/src/forge/compiler/dev-manifest/build.ts +3 -0
- package/src/forge/compiler/diagnostics/codes.ts +152 -120
- package/src/forge/compiler/diagnostics/create.ts +88 -88
- package/src/forge/compiler/diagnostics/index.ts +41 -41
- package/src/forge/compiler/emitter/artifact-kind.ts +14 -14
- package/src/forge/compiler/emitter/barrel.ts +38 -38
- package/src/forge/compiler/emitter/constants.ts +7 -7
- package/src/forge/compiler/emitter/emit.ts +234 -237
- package/src/forge/compiler/emitter/index.ts +24 -24
- package/src/forge/compiler/emitter/lock.ts +61 -61
- package/src/forge/compiler/emitter/render.ts +78 -73
- package/src/forge/compiler/external-manifest/registry.ts +204 -0
- package/src/forge/compiler/external-manifest/types.ts +89 -0
- package/src/forge/compiler/external-manifest/validate.ts +335 -0
- package/src/forge/compiler/guards/artifacts.ts +96 -96
- package/src/forge/compiler/guards/check-import-guards.ts +106 -106
- package/src/forge/compiler/guards/index.ts +11 -11
- package/src/forge/compiler/guards/propagate-contexts.ts +57 -57
- package/src/forge/compiler/index.ts +17 -17
- package/src/forge/compiler/integration/add.ts +493 -493
- package/src/forge/compiler/integration/index.ts +17 -17
- package/src/forge/compiler/integration/plan.ts +279 -279
- package/src/forge/compiler/integration/render.ts +189 -189
- package/src/forge/compiler/integration/snapshot.ts +52 -52
- package/src/forge/compiler/make-registry/build.ts +13 -0
- package/src/forge/compiler/orchestrator/discover.ts +214 -214
- package/src/forge/compiler/orchestrator/guards.ts +5 -5
- package/src/forge/compiler/orchestrator/index.ts +27 -27
- package/src/forge/compiler/orchestrator/manifest.ts +69 -69
- package/src/forge/compiler/orchestrator/orphans.ts +51 -51
- package/src/forge/compiler/orchestrator/plan-profile.ts +23 -0
- package/src/forge/compiler/orchestrator/plan.ts +857 -805
- package/src/forge/compiler/orchestrator/profile.ts +65 -0
- package/src/forge/compiler/orchestrator/run.ts +244 -178
- package/src/forge/compiler/orchestrator/serialize.ts +934 -859
- package/src/forge/compiler/orchestrator/types.ts +23 -23
- package/src/forge/compiler/orchestrator/verify.ts +35 -35
- package/src/forge/compiler/package-graph/capabilities-stub.ts +33 -33
- package/src/forge/compiler/package-graph/checksum.ts +107 -97
- package/src/forge/compiler/package-graph/compiler.ts +454 -363
- package/src/forge/compiler/package-graph/constants.ts +4 -4
- package/src/forge/compiler/package-graph/exports-discovery.ts +91 -84
- package/src/forge/compiler/package-graph/extract-dts.ts +32 -32
- package/src/forge/compiler/package-graph/index.ts +24 -24
- package/src/forge/compiler/package-graph/jsdoc.ts +50 -50
- package/src/forge/compiler/package-graph/oracle.ts +326 -0
- package/src/forge/compiler/package-graph/read-file.ts +21 -21
- package/src/forge/compiler/package-graph/resolve.ts +131 -127
- package/src/forge/compiler/package-manager/adapter.ts +232 -232
- package/src/forge/compiler/package-manager/commands.ts +47 -47
- package/src/forge/compiler/package-manager/detect.ts +65 -65
- package/src/forge/compiler/package-manager/executor.ts +29 -29
- package/src/forge/compiler/package-manager/index.ts +22 -22
- package/src/forge/compiler/package-manager/parse-spec.ts +16 -16
- package/src/forge/compiler/package-manager/version.ts +20 -20
- package/src/forge/compiler/policy-registry/build.ts +44 -1
- package/src/forge/compiler/primitives/compare.ts +26 -26
- package/src/forge/compiler/primitives/hash.ts +42 -33
- package/src/forge/compiler/primitives/header.ts +43 -43
- package/src/forge/compiler/primitives/index.ts +45 -45
- package/src/forge/compiler/primitives/paths.ts +24 -24
- package/src/forge/compiler/primitives/serialize.ts +66 -66
- package/src/forge/compiler/primitives/sort.ts +87 -87
- package/src/forge/compiler/recipes/definitions.ts +269 -269
- package/src/forge/compiler/recipes/helpers.ts +37 -37
- package/src/forge/compiler/recipes/index.ts +21 -21
- package/src/forge/compiler/recipes/registry.ts +87 -87
- package/src/forge/compiler/sandbox/artifact-sanitize.ts +26 -26
- package/src/forge/compiler/sandbox/backends/child.ts +123 -123
- package/src/forge/compiler/sandbox/backends/docker.ts +173 -173
- package/src/forge/compiler/sandbox/index.ts +51 -51
- package/src/forge/compiler/sandbox/inspect.ts +143 -143
- package/src/forge/compiler/sandbox/inspector-entry.ts +115 -115
- package/src/forge/compiler/sandbox/limits.ts +31 -31
- package/src/forge/compiler/sandbox/scrub-env.ts +60 -60
- package/src/forge/compiler/sandbox/secret-scan.ts +54 -54
- package/src/forge/compiler/sandbox/serialize.ts +106 -106
- package/src/forge/compiler/sandbox/types.ts +7 -7
- 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 +72 -71
- package/src/forge/compiler/types/capability.ts +29 -29
- package/src/forge/compiler/types/classification.ts +9 -9
- package/src/forge/compiler/types/cli.ts +89 -85
- package/src/forge/compiler/types/dev-manifest.ts +3 -0
- package/src/forge/compiler/types/diagnostic.ts +2 -2
- package/src/forge/compiler/types/emit.ts +25 -25
- package/src/forge/compiler/types/import-guards.ts +19 -19
- package/src/forge/compiler/types/index.ts +98 -98
- package/src/forge/compiler/types/integration.ts +25 -25
- package/src/forge/compiler/types/json.ts +3 -3
- package/src/forge/compiler/types/lock.ts +37 -37
- package/src/forge/compiler/types/package-graph.ts +122 -77
- package/src/forge/compiler/types/runtime-matrix.ts +16 -16
- package/src/forge/compiler/types/runtime.ts +30 -30
- package/src/forge/compiler/types/sandbox.ts +24 -24
- package/src/forge/dev/server.ts +592 -3
- package/src/forge/make/index.ts +126 -3
- package/src/forge/make/templates.ts +190 -2
- package/src/forge/make/types.ts +1 -0
- package/src/forge/refactor/index.ts +10 -2
- package/src/forge/refactor/runtime-rename.ts +598 -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/memory-adapter.ts +2 -2
- package/src/forge/runtime/db/postgres-adapter.ts +6 -3
- package/src/forge/runtime/executor.ts +3 -2
- package/src/forge/runtime/external/bridge.ts +553 -0
- package/src/forge/runtime/live/live-query-runner.ts +2 -1
- package/src/forge/runtime/outbox/process.ts +2 -1
- package/src/forge/runtime/query/run-query.ts +2 -1
- package/src/forge/runtime/runner/run-entry.ts +2 -1
- package/src/forge/runtime/telemetry/scrubber.ts +56 -5
- package/src/forge/runtime/telemetry/sinks/posthog.ts +4 -5
- package/src/forge/runtime/telemetry/sinks/sentry.ts +4 -5
- package/src/forge/runtime/webhooks/security.ts +184 -0
- package/src/forge/runtime/workflows/resolve-step.ts +2 -1
- package/src/forge/server.ts +93 -0
- package/src/forge/version.ts +3 -0
- package/templates/b2b-support-web/package.json +2 -0
- package/templates/b2b-support-web/src/actions/captureTicketCreated.ts +7 -2
- package/templates/b2b-support-web/src/commands/closeTicket.ts +6 -1
- package/templates/b2b-support-web/src/commands/createTicket.ts +8 -2
- package/templates/b2b-support-web/src/queries/getTicket.ts +8 -1
- package/templates/b2b-support-web/tsconfig.json +4 -1
- package/templates/b2b-support-web/web/components/CreateTicketForm.tsx +1 -2
- package/templates/b2b-support-web/web/components/PolicyDeniedDemo.tsx +1 -2
- package/templates/b2b-support-web/web/components/TicketList.tsx +1 -2
- package/templates/b2b-support-web/web/components/TraceDetails.tsx +1 -1
- package/templates/b2b-support-web/web/lib/forge.ts +1 -0
- 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
|
@@ -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
|
+
}
|
package/bin/forge.mjs
CHANGED
|
@@ -5,15 +5,16 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
|
|
5
5
|
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
6
6
|
const entrypoint = join(root, "src", "forge", "cli", "main.ts");
|
|
7
7
|
|
|
8
|
-
let
|
|
8
|
+
let register;
|
|
9
9
|
try {
|
|
10
|
-
({
|
|
10
|
+
({ register } = await import("tsx/esm/api"));
|
|
11
11
|
} catch {
|
|
12
12
|
console.error("error: Forge requires the 'tsx' package to run under Node.");
|
|
13
13
|
console.error("Install dependencies with your package manager, then retry.");
|
|
14
14
|
process.exit(1);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
register();
|
|
18
|
+
const module = await import(pathToFileURL(entrypoint).href);
|
|
18
19
|
const exitCode = await module.main(process.argv.slice(2));
|
|
19
20
|
process.exit(exitCode);
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Release history for the `forgeos` npm package (`alpha` dist-tag).
|
|
4
|
+
|
|
5
|
+
The canonical source file in the repository is `CHANGELOG.md`.
|
|
6
|
+
|
|
7
|
+
## 0.1.0-alpha.10
|
|
8
|
+
|
|
9
|
+
Launch polish:
|
|
10
|
+
|
|
11
|
+
- Fixed `forge run <external-command> --args ...` so CLI arguments reach the external runtime bridge.
|
|
12
|
+
- Added direct external query CLI support through `forge query <service.query> --args ...`.
|
|
13
|
+
- Emit generated `.json` artifacts as pure JSON while keeping deterministic headers on code/text artifacts.
|
|
14
|
+
- Relaxed the `minimal-web` template verify script to `forge verify --smoke` and added the missing `check` script to `b2b-support-web`.
|
|
15
|
+
- Updated public protocol/changelog docs for the external runtime and Go adapter alpha line.
|
|
16
|
+
- Bumped the create-app wrapper package line to `create-forgeos-app@0.1.0-alpha.4`.
|
|
17
|
+
|
|
18
|
+
## 0.1.0-alpha.9
|
|
19
|
+
|
|
20
|
+
Compiler, external runtime, and Go adapter:
|
|
21
|
+
|
|
22
|
+
- Added the Forge external runtime protocol bridge for manifest-backed commands and queries.
|
|
23
|
+
- Added the Go adapter MVP with a real `go-billing` conformance example.
|
|
24
|
+
- Emitted external service metadata into inspect/API/agent artifacts, including `needsApproval` for agent tools.
|
|
25
|
+
- Reuse compiler classifier package signals across export classification, dropping repeated package signal scans.
|
|
26
|
+
- Reuse serialized graph JSON when rendering the largest generated TypeScript graph artifacts.
|
|
27
|
+
- Keep generated Forge artifacts aligned with the `0.1.0-alpha.9` compiler/runtime version.
|
|
28
|
+
|
|
29
|
+
## 0.1.0-alpha.8
|
|
30
|
+
|
|
31
|
+
Publishing:
|
|
32
|
+
|
|
33
|
+
- Publish prerelease packages through the ForgeOS alpha publisher so npm dist-tags stay aligned.
|
|
34
|
+
|
|
35
|
+
## 0.1.0-alpha.7
|
|
36
|
+
|
|
37
|
+
Publishing:
|
|
38
|
+
|
|
39
|
+
- Keep npm prerelease publishing on the public alpha dist-tag.
|
|
40
|
+
|
|
41
|
+
## 0.1.0-alpha.6
|
|
42
|
+
|
|
43
|
+
Release and packaging hardening:
|
|
44
|
+
|
|
45
|
+
- Added `forge --version` / `forge --version --json`.
|
|
46
|
+
- Updated `create-forgeos-app` help to read the wrapper package version instead of a hardcoded string and bumped the wrapper to `0.1.0-alpha.2`.
|
|
47
|
+
- Added dependency vulnerability evidence with an explicit waiver file and CI release gate.
|
|
48
|
+
- Updated generated web template dependencies to current Vite/plugin-react and Next majors.
|
|
49
|
+
|
|
50
|
+
## 0.1.0-alpha.5
|
|
51
|
+
|
|
52
|
+
Release alignment for the public alpha channel:
|
|
53
|
+
|
|
54
|
+
- Added `forge ai redteam --model-level --json` with deterministic prompt-injection, secret-exfiltration, approval-bypass, cross-tenant, and indirect tool-injection probes.
|
|
55
|
+
- Added `forge security prove --full --json` support for source checkouts, with graceful structural-proof fallback when packaged apps do not include ForgeOS test fixtures.
|
|
56
|
+
- Strengthened npm publish workflows to run `security prove --db postgres --full --json`.
|
|
57
|
+
- Added public registry smoke coverage for `forgeos@alpha` and `create-forgeos-app@alpha`.
|
|
58
|
+
- Bumped the create-app wrapper package line to `create-forgeos-app@0.1.0-alpha.1`.
|
|
59
|
+
|
|
60
|
+
## 0.1.0-alpha.4
|
|
61
|
+
|
|
62
|
+
Security assurance and release evidence hardening:
|
|
63
|
+
|
|
64
|
+
- Added value-aware telemetry redaction for known secret values in safe-looking fields, messages, details, outputs, and stack traces.
|
|
65
|
+
- Added webhook signature, timestamp, and replay protection helpers with Stripe/GitHub/generic HMAC coverage.
|
|
66
|
+
- Added HTTP tenant-isolation tests that exercise the dev server/API boundary, not only the internal runtime executor.
|
|
67
|
+
- Added `forge rls mutate-test --json` to kill dangerous generated RLS mutations such as missing FORCE RLS, missing policies, unconditional predicates, and `BYPASSRLS`.
|
|
68
|
+
- Extended `forge security prove --json` with RLS mutation proof and invariant-level evidence metadata.
|
|
69
|
+
- Added scripts to split security evidence by invariant and emit basic release supply-chain evidence plus CycloneDX SBOM.
|
|
70
|
+
- Strengthened publish/security workflows so release gates use Postgres-backed security proof, RLS mutation proof, release evidence, and SBOM generation.
|
|
71
|
+
|
|
72
|
+
## 0.1.0-alpha.3
|
|
73
|
+
|
|
74
|
+
Native Forge AI agents on top of Vercel AI SDK v6:
|
|
75
|
+
|
|
76
|
+
- Added `aiTool` and `agent` primitives with generated `agentTools.json` / `agentTools.md`.
|
|
77
|
+
- Added `ctx.agent.run` and `ctx.ai.runAgent` using AI SDK `ToolLoopAgent`.
|
|
78
|
+
- Added auto-tools for commands, queries, and liveQueries with read-only vs approval-required writes.
|
|
79
|
+
- Added dev agent endpoints: `POST /ai/agents/run` and `POST /ai/agents/chat`.
|
|
80
|
+
- Extended `forge ai` CLI with `tools`, `agents`, and `trace` subcommands.
|
|
81
|
+
- Added `forge inspect agent-tools` and agent tool metadata in `agentContract.json`.
|
|
82
|
+
- Upgraded runtime dependency to AI SDK v6 for tool calling, streaming UI, and MCP compatibility.
|
|
83
|
+
|
|
84
|
+
Documentation:
|
|
85
|
+
|
|
86
|
+
- Added public [AI](ai.md) page and AST-aware `rename command` codemod docs.
|
|
87
|
+
- Full RTD expansion: [Agent Workflow](agent-workflow.md), [Frontend](frontend.md), [Security & Data](security-and-data.md), [Authoring](authoring.md), [Testing & Repair](testing-and-repair.md), [Self-Host](self-host.md), [Templates](templates.md), Material theme, search, and Mermaid diagrams.
|
|
88
|
+
|
|
89
|
+
## 0.1.0-alpha.2
|
|
90
|
+
|
|
91
|
+
Windows and generated-app hardening:
|
|
92
|
+
|
|
93
|
+
- Fixed Node ESM handler loading on Windows by importing generated app modules through `file://` URLs across commands, queries, liveQueries, outbox actions, workflow steps, mocks, and telemetry adapters.
|
|
94
|
+
- Fixed `forge dev` SSE streaming on the Node HTTP fallback so liveQuery snapshots are flushed immediately instead of buffering forever.
|
|
95
|
+
- Hardened generated app scaffolding and web dev spawning on Windows.
|
|
96
|
+
- Updated the B2B support template to route frontend imports through `web/lib/forge.ts` and use safer handler input validation.
|
|
97
|
+
- Added focused tests for Node compatibility, template scaffolding, runtime imports, and streaming responses.
|
|
98
|
+
- Added `create-forgeos-app@alpha` for `npm create forgeos-app@alpha`.
|
|
99
|
+
- Added GitHub Packages mirror workflow for scoped package publishing.
|
|
100
|
+
|
|
101
|
+
## 0.1.0-alpha.1
|
|
102
|
+
|
|
103
|
+
Republish alpha with the dependency/API oracle improvements:
|
|
104
|
+
|
|
105
|
+
- Added dependency API inspection commands for agents: `forge deps api`, `forge deps trace`, and `forge deps runtime-compat`.
|
|
106
|
+
- Added dependency API summaries to `agentContract.json`.
|
|
107
|
+
- Added package resolution traces, runtime compatibility metadata, and runtime/type mismatch diagnostics to `packageGraph`.
|
|
108
|
+
- Reduced package graph warning noise for `package.json` metadata exports, declaration-file subpaths, and pattern exports.
|
|
109
|
+
|
|
110
|
+
## 0.1.0-alpha.0
|
|
111
|
+
|
|
112
|
+
Initial alpha packaging baseline for ForgeOS.
|
|
113
|
+
|
|
114
|
+
This release line validates npm installation, the `forge` CLI binary, template creation, generated contracts, and the agent-native local development loop.
|
|
115
|
+
|
|
116
|
+
Added Read the Docs-ready public documentation, generator/package version alignment checks, and a broad generated-app field-test harness for release hardening.
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Forge External Runtime Protocol
|
|
2
|
+
|
|
3
|
+
Forge apps can import and call services written outside TypeScript through a
|
|
4
|
+
`forge.manifest.json` compatible manifest. The manifest is the source of truth
|
|
5
|
+
for external commands and queries:
|
|
6
|
+
|
|
7
|
+
- validate and import external service metadata;
|
|
8
|
+
- expose external services in generated inspect/API/agent artifacts;
|
|
9
|
+
- execute external commands and queries through the Forge runtime bridge.
|
|
10
|
+
|
|
11
|
+
This lets Java/Spring, Go, Rust, C#, Python, and other runtimes join the Forge
|
|
12
|
+
contract without requiring the Forge compiler to parse every language AST.
|
|
13
|
+
|
|
14
|
+
## Manifest
|
|
15
|
+
|
|
16
|
+
External services publish JSON that matches
|
|
17
|
+
`schemas/forge-manifest.schema.json`.
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"forgeProtocol": "1.0",
|
|
22
|
+
"language": "java",
|
|
23
|
+
"framework": "spring-boot",
|
|
24
|
+
"service": {
|
|
25
|
+
"name": "billing",
|
|
26
|
+
"transport": "http",
|
|
27
|
+
"baseUrl": "http://localhost:8080",
|
|
28
|
+
"health": "/actuator/health"
|
|
29
|
+
},
|
|
30
|
+
"entries": [
|
|
31
|
+
{
|
|
32
|
+
"name": "createInvoice",
|
|
33
|
+
"kind": "command",
|
|
34
|
+
"path": "/invoices",
|
|
35
|
+
"policy": "billing.write",
|
|
36
|
+
"transaction": "external-managed",
|
|
37
|
+
"risk": "write",
|
|
38
|
+
"needsApproval": true,
|
|
39
|
+
"effects": ["invoice.created"]
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"name": "listInvoices",
|
|
43
|
+
"kind": "query",
|
|
44
|
+
"path": "/invoices",
|
|
45
|
+
"policy": "billing.read",
|
|
46
|
+
"transaction": "read-only",
|
|
47
|
+
"risk": "read",
|
|
48
|
+
"tenantScoped": true
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Queries must stay read-only. Commands can declare write, destructive, or
|
|
55
|
+
external risk. Policies are metadata until the runtime bridge enforces them for
|
|
56
|
+
the external transport.
|
|
57
|
+
|
|
58
|
+
## CLI
|
|
59
|
+
|
|
60
|
+
Validate a manifest:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
forge manifest validate ./forge.manifest.json --json
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Import or update a service in the app registry:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
forge manifest import ./forge.manifest.json --json
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Imports are stored in `.forge/external-manifests.json`. A root
|
|
73
|
+
`forge.manifest.json` is also discovered automatically for single-service
|
|
74
|
+
experiments.
|
|
75
|
+
|
|
76
|
+
## Generated Artifacts
|
|
77
|
+
|
|
78
|
+
After `forge generate`, external services are emitted to:
|
|
79
|
+
|
|
80
|
+
- `src/forge/_generated/externalServices.json`
|
|
81
|
+
- `src/forge/_generated/api.json` under `external`
|
|
82
|
+
- `src/forge/_generated/agentContract.json`
|
|
83
|
+
- `src/forge/_generated/agentTools.json`
|
|
84
|
+
- `src/forge/_generated/capabilityMap.json`
|
|
85
|
+
|
|
86
|
+
External auto-tools use `execution: "external-runtime-endpoint"`. Forge exposes
|
|
87
|
+
runtime bridge endpoints for these tools:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
POST /external/:service/commands/:name
|
|
91
|
+
POST /external/:service/queries/:name
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The generated client exposes the same bridge through:
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
await client.externalCommand("billing.createInvoice", args);
|
|
98
|
+
await client.externalQuery(api.external.queries["billing.listInvoices"], args);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Command entries can also be invoked from the CLI with a qualified external
|
|
102
|
+
name:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
forge run billing.createInvoice --args '{"title":"Invoice"}'
|
|
106
|
+
forge query billing.listInvoices --args '{}'
|
|
107
|
+
forge run query billing.listInvoices --args '{}'
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Runtime Bridge
|
|
111
|
+
|
|
112
|
+
Forge accepts the normal JSON body:
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{ "args": {} }
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
For HTTP services, Forge forwards a JSON envelope:
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"args": {},
|
|
123
|
+
"auth": { "kind": "user", "userId": "u1", "tenantId": "t1", "role": "member" },
|
|
124
|
+
"forge": {
|
|
125
|
+
"service": "billing",
|
|
126
|
+
"entry": "createInvoice",
|
|
127
|
+
"kind": "command",
|
|
128
|
+
"traceId": "trace_..."
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Forge also forwards runtime headers such as `x-forge-trace-id`,
|
|
134
|
+
`x-forge-auth-kind`, `x-forge-user-id`, `x-forge-tenant-id`, `x-forge-role`,
|
|
135
|
+
and the inbound `Authorization` header when present.
|
|
136
|
+
|
|
137
|
+
External services can return either a Forge envelope:
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{ "ok": true, "result": { "id": "inv_1" } }
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
or a raw JSON value, which Forge treats as the result for successful HTTP
|
|
144
|
+
responses. Error envelopes should include `ok: false`, `diagnostics`, or
|
|
145
|
+
`error`.
|
|
146
|
+
|
|
147
|
+
Supported runtime transports:
|
|
148
|
+
|
|
149
|
+
- `http`: calls `service.baseUrl + entry.path`.
|
|
150
|
+
- `stdio`: starts `service.command`, writes the JSON envelope to stdin, and
|
|
151
|
+
reads a JSON envelope or raw JSON result from stdout.
|
|
152
|
+
- `grpc`: accepted in manifests for forward compatibility, but not executable
|
|
153
|
+
by the built-in runtime bridge yet.
|
|
154
|
+
|
|
155
|
+
Manifest `policy` values are added to Forge policy bindings during generation.
|
|
156
|
+
Use a named Forge policy, or `public`, `user`, or `system`.
|