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
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { nodeFileSystem } from "../compiler/fs/index.ts";
|
|
2
|
-
import {
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
3
4
|
import { stripDeterministicHeader } from "../compiler/primitives/header.ts";
|
|
4
5
|
import { classify } from "../compiler/classifier/classify.ts";
|
|
5
6
|
import { buildRuntimeMatrix } from "../compiler/classifier/runtime-matrix.ts";
|
|
7
|
+
import { FORGE_RELEASE_PACKAGE_PACK_FAILED } from "../compiler/diagnostics/codes.ts";
|
|
6
8
|
import { createDiagnostic } from "../compiler/diagnostics/create.ts";
|
|
7
9
|
import { forgeAdd } from "../compiler/integration/add.ts";
|
|
8
10
|
import { checkImportGuards } from "../compiler/guards/check-import-guards.ts";
|
|
@@ -29,10 +31,14 @@ import type {
|
|
|
29
31
|
} from "../compiler/types/cli.ts";
|
|
30
32
|
import type { RuntimeMatrix } from "../compiler/types/runtime-matrix.ts";
|
|
31
33
|
import type { FrontendGraph } from "../compiler/types/frontend-graph.ts";
|
|
34
|
+
import type { DataGraph } from "../compiler/types/data-graph.ts";
|
|
35
|
+
import type { SqlPlan } from "../compiler/data-graph/sql/types.ts";
|
|
36
|
+
import type { TableMapEntry } from "../compiler/data-graph/sql/serialize.ts";
|
|
32
37
|
import { GENERATED_DIR } from "../compiler/emitter/constants.ts";
|
|
33
38
|
import {
|
|
34
39
|
attachFailureKind,
|
|
35
40
|
buildAddJson,
|
|
41
|
+
buildCheckJson,
|
|
36
42
|
buildGenerateJson,
|
|
37
43
|
buildInspectJson,
|
|
38
44
|
formatJsonResult,
|
|
@@ -44,6 +50,26 @@ import {
|
|
|
44
50
|
} from "./output.ts";
|
|
45
51
|
import { INSPECT_TARGETS, TOP_LEVEL_COMMANDS, type ForgeCommand } from "./parse.ts";
|
|
46
52
|
import { runVerifyCommand } from "./verify.ts";
|
|
53
|
+
import {
|
|
54
|
+
buildExternalServiceGraph,
|
|
55
|
+
importExternalManifest,
|
|
56
|
+
readExternalManifestFile,
|
|
57
|
+
} from "../compiler/external-manifest/registry.ts";
|
|
58
|
+
import {
|
|
59
|
+
resolveExternalQualifiedName,
|
|
60
|
+
runExternalEntry,
|
|
61
|
+
} from "../runtime/external/bridge.ts";
|
|
62
|
+
import {
|
|
63
|
+
formatCompilerBenchHuman,
|
|
64
|
+
formatCompilerBenchJson,
|
|
65
|
+
runCompilerBenchCommand,
|
|
66
|
+
} from "../bench.ts";
|
|
67
|
+
import {
|
|
68
|
+
formatCairHuman,
|
|
69
|
+
formatCairJson,
|
|
70
|
+
runCairCommand,
|
|
71
|
+
} from "../cair/index.ts";
|
|
72
|
+
import { uniqueNextActions } from "./next-actions.ts";
|
|
47
73
|
import {
|
|
48
74
|
formatRunJson,
|
|
49
75
|
formatRunListHuman,
|
|
@@ -51,6 +77,41 @@ import {
|
|
|
51
77
|
runRunCommand,
|
|
52
78
|
} from "./run.ts";
|
|
53
79
|
import { runDevCommand } from "./dev.ts";
|
|
80
|
+
import {
|
|
81
|
+
formatHandoffHuman,
|
|
82
|
+
formatHandoffJson,
|
|
83
|
+
runHandoffCommand,
|
|
84
|
+
} from "./handoff.ts";
|
|
85
|
+
import {
|
|
86
|
+
formatStudioAttachHuman,
|
|
87
|
+
formatStudioAttachJson,
|
|
88
|
+
formatStudioBridgeEventJson,
|
|
89
|
+
formatStudioBridgeHuman,
|
|
90
|
+
formatStudioBridgeJson,
|
|
91
|
+
formatStudioCodexServerHuman,
|
|
92
|
+
formatStudioCodexServerJson,
|
|
93
|
+
formatStudioDoctorHuman,
|
|
94
|
+
formatStudioDoctorJson,
|
|
95
|
+
formatStudioOpenHuman,
|
|
96
|
+
formatStudioOpenJson,
|
|
97
|
+
formatStudioSnapshotHuman,
|
|
98
|
+
formatStudioSnapshotJson,
|
|
99
|
+
formatStudioWatchHuman,
|
|
100
|
+
formatStudioWatchJson,
|
|
101
|
+
runStudioAttachCommand,
|
|
102
|
+
runStudioBridgeCommand,
|
|
103
|
+
runStudioBridgeLoop,
|
|
104
|
+
runStudioCodexServerCommand,
|
|
105
|
+
runStudioDoctorCommand,
|
|
106
|
+
runStudioOpenCommand,
|
|
107
|
+
runStudioSnapshotCommand,
|
|
108
|
+
runStudioWatchCommand,
|
|
109
|
+
runStudioWatchLoop,
|
|
110
|
+
} from "./studio.ts";
|
|
111
|
+
import {
|
|
112
|
+
formatChangedHuman,
|
|
113
|
+
runChangedCommand,
|
|
114
|
+
} from "./changed.ts";
|
|
54
115
|
import { initializeRuntimeEnv } from "../runtime/context/create-context.ts";
|
|
55
116
|
import { formatDbHuman, formatDbJson, runDbCommand } from "./db.ts";
|
|
56
117
|
import { formatOutboxHuman, formatOutboxJson, runOutboxCommand } from "./outbox.ts";
|
|
@@ -64,6 +125,23 @@ import {
|
|
|
64
125
|
formatTelemetryJson,
|
|
65
126
|
runTelemetryCommand,
|
|
66
127
|
} from "./telemetry.ts";
|
|
128
|
+
import {
|
|
129
|
+
formatDeltaExplainHuman,
|
|
130
|
+
formatDeltaExplainJson,
|
|
131
|
+
formatDeltaRepairHuman,
|
|
132
|
+
formatDeltaRepairJson,
|
|
133
|
+
formatDeltaStatusHuman,
|
|
134
|
+
formatDeltaStatusJson,
|
|
135
|
+
formatDeltaSessionHuman,
|
|
136
|
+
formatDeltaSessionJson,
|
|
137
|
+
formatDeltaTimelineHuman,
|
|
138
|
+
formatDeltaTimelineJson,
|
|
139
|
+
runDeltaExplain,
|
|
140
|
+
runDeltaRepair,
|
|
141
|
+
runDeltaSessionCommand,
|
|
142
|
+
runDeltaStatus,
|
|
143
|
+
runDeltaTimeline,
|
|
144
|
+
} from "../delta/index.ts";
|
|
67
145
|
import {
|
|
68
146
|
formatPolicyHuman,
|
|
69
147
|
formatPolicyJson,
|
|
@@ -82,7 +160,8 @@ import { formatNewHuman, runNewCommand } from "./new.ts";
|
|
|
82
160
|
import { formatBuildHuman, runBuildCommand } from "./build.ts";
|
|
83
161
|
import { runServeCommand } from "./serve.ts";
|
|
84
162
|
import { runWorkerCommand } from "./worker.ts";
|
|
85
|
-
import { formatSelfHostHuman, runSelfHostCommand } from "./self-host.ts";
|
|
163
|
+
import { formatSelfHostHuman, runSelfHostCommand, type SelfHostCommandResult } from "./self-host.ts";
|
|
164
|
+
import { formatDocsCheckHuman, runDocsCheckCommand, type DocsCheckResult } from "./docs.ts";
|
|
86
165
|
import {
|
|
87
166
|
formatAgentContractHuman,
|
|
88
167
|
runAgentContractPrint,
|
|
@@ -102,10 +181,16 @@ import {
|
|
|
102
181
|
} from "./windows.ts";
|
|
103
182
|
import { formatAuthHuman, formatAuthJson, runAuthCommand } from "./auth.ts";
|
|
104
183
|
import { formatRlsHuman, formatRlsJson, runRlsCommand } from "./rls.ts";
|
|
184
|
+
import {
|
|
185
|
+
formatSecurityHuman,
|
|
186
|
+
formatSecurityJson,
|
|
187
|
+
runSecurityCommand,
|
|
188
|
+
} from "./security.ts";
|
|
105
189
|
import { formatDepsHuman, formatDepsJson, runDepsCommand } from "./deps.ts";
|
|
106
190
|
import {
|
|
107
191
|
formatReleaseHuman,
|
|
108
192
|
formatReleaseJson,
|
|
193
|
+
type ReleaseCommandResult,
|
|
109
194
|
runReleaseCommand,
|
|
110
195
|
} from "./release.ts";
|
|
111
196
|
import { formatMakeHuman, formatMakeJson, runMakeCommand } from "./make.ts";
|
|
@@ -127,11 +212,18 @@ import {
|
|
|
127
212
|
formatForgeDoJson,
|
|
128
213
|
runForgeDoCommand,
|
|
129
214
|
} from "../intent/index.ts";
|
|
215
|
+
import {
|
|
216
|
+
formatBrownfieldImportHuman,
|
|
217
|
+
formatBrownfieldImportJson,
|
|
218
|
+
inspectBrownfieldImport,
|
|
219
|
+
runBrownfieldImportCommand,
|
|
220
|
+
} from "../brownfield-import/index.ts";
|
|
130
221
|
import {
|
|
131
222
|
formatAgentHuman,
|
|
132
223
|
formatAgentJson,
|
|
133
224
|
runAgentCommand,
|
|
134
225
|
} from "../agent-adapters/index.ts";
|
|
226
|
+
import { runMcpServe } from "../agent-memory/mcp.ts";
|
|
135
227
|
import {
|
|
136
228
|
formatReviewHuman,
|
|
137
229
|
formatReviewJson,
|
|
@@ -155,6 +247,9 @@ import { runLiveCommand } from "./live.ts";
|
|
|
155
247
|
import { runQuery } from "../runtime/query/run-query.ts";
|
|
156
248
|
import { resolveAuthFromCli } from "../runtime/auth/resolve.ts";
|
|
157
249
|
import { getActiveDbAdapter } from "../runtime/executor.ts";
|
|
250
|
+
import { CLI_VERSION, FORGEOS_VERSION } from "../version.ts";
|
|
251
|
+
import type { CategorizedFileSummary } from "../workspace/change-summary.ts";
|
|
252
|
+
import { buildWorkspaceGitSummary } from "../workspace/git-summary.ts";
|
|
158
253
|
|
|
159
254
|
function readGeneratedJson<T>(workspaceRoot: string, relative: string): T | null {
|
|
160
255
|
const absolute = join(workspaceRoot, relative);
|
|
@@ -238,9 +333,14 @@ function buildFrameworkInspect(workspaceRoot: string): Record<string, unknown> {
|
|
|
238
333
|
topLevelCommands: [...TOP_LEVEL_COMMANDS],
|
|
239
334
|
inspectTargets: [...INSPECT_TARGETS],
|
|
240
335
|
preferredEntryPoints: [
|
|
336
|
+
"forge status --json",
|
|
337
|
+
"forge changed --json",
|
|
338
|
+
"forge agent onboard --target codex --json",
|
|
241
339
|
"forge do <objective> --json",
|
|
242
340
|
"forge dev --once --json",
|
|
341
|
+
"forge inspect all --brief --json",
|
|
243
342
|
"forge inspect all --json",
|
|
343
|
+
"forge agent print-context --json",
|
|
244
344
|
"forge inspect framework --json",
|
|
245
345
|
"forge verify --strict",
|
|
246
346
|
],
|
|
@@ -270,13 +370,519 @@ function buildFrameworkInspect(workspaceRoot: string): Record<string, unknown> {
|
|
|
270
370
|
};
|
|
271
371
|
}
|
|
272
372
|
|
|
373
|
+
function readGeneratedArtifactStatus(workspaceRoot: string): Array<{ name: string; path: string; present: boolean }> {
|
|
374
|
+
const artifacts = [
|
|
375
|
+
["app", `${GENERATED_DIR}/appGraph.json`],
|
|
376
|
+
["data", `${GENERATED_DIR}/dataGraph.json`],
|
|
377
|
+
["sql", `${GENERATED_DIR}/sqlPlan.json`],
|
|
378
|
+
["db", `${GENERATED_DIR}/db.json`],
|
|
379
|
+
["runtime", `${GENERATED_DIR}/runtimeGraph.json`],
|
|
380
|
+
["frontend", `${GENERATED_DIR}/frontendGraph.json`],
|
|
381
|
+
["client", `${GENERATED_DIR}/clientManifest.json`],
|
|
382
|
+
["agent-contract", `${GENERATED_DIR}/agentContract.json`],
|
|
383
|
+
["agent-adapters", `${GENERATED_DIR}/agentAdapterManifest.json`],
|
|
384
|
+
["capability-map", `${GENERATED_DIR}/capabilityMap.json`],
|
|
385
|
+
["test-graph", `${GENERATED_DIR}/testGraph.json`],
|
|
386
|
+
["agents-md", "AGENTS.md"],
|
|
387
|
+
["forge-lock", "forge.lock"],
|
|
388
|
+
] as const;
|
|
389
|
+
|
|
390
|
+
return artifacts.map(([name, path]) => ({
|
|
391
|
+
name,
|
|
392
|
+
path,
|
|
393
|
+
present: hasPath(workspaceRoot, path),
|
|
394
|
+
}));
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function buildInspectSummary(workspaceRoot: string): Record<string, unknown> {
|
|
398
|
+
const framework = buildFrameworkInspect(workspaceRoot);
|
|
399
|
+
const dataGraph = readGeneratedJson<DataGraph>(workspaceRoot, `${GENERATED_DIR}/dataGraph.json`);
|
|
400
|
+
const frontend = readGeneratedJson<FrontendGraph>(workspaceRoot, `${GENERATED_DIR}/frontendGraph.json`);
|
|
401
|
+
const agentAdapters = readGeneratedJson<{ targets?: Array<{ name?: string; files?: string[]; default?: boolean; optional?: boolean }> }>(
|
|
402
|
+
workspaceRoot,
|
|
403
|
+
`${GENERATED_DIR}/agentAdapterManifest.json`,
|
|
404
|
+
);
|
|
405
|
+
const artifacts = readGeneratedArtifactStatus(workspaceRoot);
|
|
406
|
+
const missingArtifacts = artifacts.filter((artifact) => !artifact.present);
|
|
407
|
+
|
|
408
|
+
return {
|
|
409
|
+
schemaVersion: "0.1.0",
|
|
410
|
+
summary: {
|
|
411
|
+
project: (framework.project as Record<string, unknown> | undefined)?.name ?? "unknown",
|
|
412
|
+
tables: dataGraph?.tables.length ?? 0,
|
|
413
|
+
frontendPresent: frontend?.present === true,
|
|
414
|
+
routes: frontend?.routes.length ?? 0,
|
|
415
|
+
agentTargets: agentAdapters?.targets?.map((target) => target.name).filter(Boolean) ?? [],
|
|
416
|
+
missingArtifacts: missingArtifacts.length,
|
|
417
|
+
},
|
|
418
|
+
artifacts,
|
|
419
|
+
nextActions: [
|
|
420
|
+
"forge inspect schema --json",
|
|
421
|
+
"forge inspect handoff --json",
|
|
422
|
+
"forge inspect drift --json",
|
|
423
|
+
"forge check --json",
|
|
424
|
+
],
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
function buildInspectBrief(workspaceRoot: string): Record<string, unknown> {
|
|
429
|
+
const summary = buildInspectSummary(workspaceRoot);
|
|
430
|
+
const framework = buildFrameworkInspect(workspaceRoot);
|
|
431
|
+
const cli = framework.cli as { preferredEntryPoints?: string[]; inspectTargets?: string[] } | undefined;
|
|
432
|
+
const artifacts = readGeneratedArtifactStatus(workspaceRoot);
|
|
433
|
+
const missingArtifacts = artifacts.filter((artifact) => !artifact.present);
|
|
434
|
+
return {
|
|
435
|
+
schemaVersion: "0.1.0",
|
|
436
|
+
brief: true,
|
|
437
|
+
payload: {
|
|
438
|
+
mode: "brief",
|
|
439
|
+
purpose: "orientation",
|
|
440
|
+
includes: ["summary", "entrypoints", "refs", "artifact counts"],
|
|
441
|
+
omitted: ["schema table details", "framework module lists", "generated registries"],
|
|
442
|
+
fullCommand: "forge inspect all --full --json",
|
|
443
|
+
compactCommand: "forge inspect all --json",
|
|
444
|
+
},
|
|
445
|
+
summary: summary.summary,
|
|
446
|
+
entrypoints: {
|
|
447
|
+
preferred: cli?.preferredEntryPoints ?? [],
|
|
448
|
+
inspect: [
|
|
449
|
+
"forge inspect summary --json",
|
|
450
|
+
"forge inspect schema --json",
|
|
451
|
+
"forge inspect handoff --json",
|
|
452
|
+
"forge inspect all --json",
|
|
453
|
+
"forge inspect all --full --json",
|
|
454
|
+
],
|
|
455
|
+
},
|
|
456
|
+
refs: [
|
|
457
|
+
"AGENTS.md",
|
|
458
|
+
`${GENERATED_DIR}/agentContract.json`,
|
|
459
|
+
`${GENERATED_DIR}/appMap.md`,
|
|
460
|
+
`${GENERATED_DIR}/runtimeRules.md`,
|
|
461
|
+
`${GENERATED_DIR}/operationPlaybooks.md`,
|
|
462
|
+
`${GENERATED_DIR}/frontendGraph.json`,
|
|
463
|
+
],
|
|
464
|
+
artifacts: {
|
|
465
|
+
total: artifacts.length,
|
|
466
|
+
present: artifacts.length - missingArtifacts.length,
|
|
467
|
+
missing: missingArtifacts,
|
|
468
|
+
},
|
|
469
|
+
nextActions: [
|
|
470
|
+
"forge status --json",
|
|
471
|
+
"forge changed --json",
|
|
472
|
+
"forge agent onboard --target codex --json",
|
|
473
|
+
"forge dev --once --json",
|
|
474
|
+
"forge inspect all --json",
|
|
475
|
+
],
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
function buildSchemaInspect(workspaceRoot: string): { data: Record<string, unknown>; errors: ReturnType<typeof createDiagnostic>[] } {
|
|
480
|
+
const dataGraph = readGeneratedJson<DataGraph>(workspaceRoot, `${GENERATED_DIR}/dataGraph.json`);
|
|
481
|
+
const sqlPlan = readGeneratedJson<SqlPlan>(workspaceRoot, `${GENERATED_DIR}/sqlPlan.json`);
|
|
482
|
+
const db = readGeneratedJson<{ tableMap?: Record<string, TableMapEntry> }>(workspaceRoot, `${GENERATED_DIR}/db.json`);
|
|
483
|
+
const errors: ReturnType<typeof createDiagnostic>[] = [];
|
|
484
|
+
|
|
485
|
+
if (!dataGraph) {
|
|
486
|
+
errors.push(createDiagnostic({
|
|
487
|
+
severity: "error",
|
|
488
|
+
code: "FORGE_INSPECT_MISSING",
|
|
489
|
+
message: `missing generated artifact: ${GENERATED_DIR}/dataGraph.json; run forge generate first`,
|
|
490
|
+
file: `${GENERATED_DIR}/dataGraph.json`,
|
|
491
|
+
}));
|
|
492
|
+
}
|
|
493
|
+
if (!sqlPlan) {
|
|
494
|
+
errors.push(createDiagnostic({
|
|
495
|
+
severity: "error",
|
|
496
|
+
code: "FORGE_INSPECT_MISSING",
|
|
497
|
+
message: `missing generated artifact: ${GENERATED_DIR}/sqlPlan.json; run forge generate first`,
|
|
498
|
+
file: `${GENERATED_DIR}/sqlPlan.json`,
|
|
499
|
+
}));
|
|
500
|
+
}
|
|
501
|
+
if (!db?.tableMap) {
|
|
502
|
+
errors.push(createDiagnostic({
|
|
503
|
+
severity: "error",
|
|
504
|
+
code: "FORGE_INSPECT_MISSING",
|
|
505
|
+
message: `missing generated artifact: ${GENERATED_DIR}/db.json; run forge generate first`,
|
|
506
|
+
file: `${GENERATED_DIR}/db.json`,
|
|
507
|
+
}));
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
const sqlByAccessName = new Map(
|
|
511
|
+
(sqlPlan?.tables ?? [])
|
|
512
|
+
.filter((table) => table.kind === "create_table")
|
|
513
|
+
.map((table) => [table.accessName ?? table.table ?? "", table]),
|
|
514
|
+
);
|
|
515
|
+
const tableMap = db?.tableMap ?? {};
|
|
516
|
+
const dataGraphDiagnostics = dataGraph?.diagnostics ?? [];
|
|
517
|
+
const sqlPlanDiagnostics = sqlPlan?.diagnostics ?? [];
|
|
518
|
+
const tables = (dataGraph?.tables ?? []).map((table) => {
|
|
519
|
+
const sql = sqlByAccessName.get(table.name);
|
|
520
|
+
const runtime = sql?.table ? tableMap[sql.table] ?? tableMap[table.name] : tableMap[table.name];
|
|
521
|
+
const sourceFields = table.fields.map((field) => field.name).sort();
|
|
522
|
+
const sqlColumns = (sql?.columns ?? []).map((column) => ({
|
|
523
|
+
name: column.name,
|
|
524
|
+
fieldName: column.fieldName,
|
|
525
|
+
sqlType: column.sqlType,
|
|
526
|
+
primaryKey: column.primaryKey === true,
|
|
527
|
+
}));
|
|
528
|
+
const runtimeFields = (runtime?.columns ?? []).map((column) => column.fieldName ?? column.name).sort();
|
|
529
|
+
const missingRuntimeFields = sourceFields.filter((field) => !runtimeFields.includes(field));
|
|
530
|
+
|
|
531
|
+
return {
|
|
532
|
+
name: table.name,
|
|
533
|
+
file: table.file,
|
|
534
|
+
sourceFields,
|
|
535
|
+
sqlTable: sql?.table ?? null,
|
|
536
|
+
sqlColumns,
|
|
537
|
+
runtimeAccessors: Object.entries(tableMap)
|
|
538
|
+
.filter(([, entry]) => entry.tableName === (sql?.table ?? table.name))
|
|
539
|
+
.map(([name]) => name)
|
|
540
|
+
.sort(),
|
|
541
|
+
missingRuntimeFields,
|
|
542
|
+
};
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
return {
|
|
546
|
+
data: {
|
|
547
|
+
schemaVersion: "0.1.0",
|
|
548
|
+
summary: {
|
|
549
|
+
tables: tables.length,
|
|
550
|
+
missingRuntimeFields: tables.reduce(
|
|
551
|
+
(count, table) => count + (table.missingRuntimeFields as string[]).length,
|
|
552
|
+
0,
|
|
553
|
+
),
|
|
554
|
+
diagnostics: dataGraphDiagnostics.length + sqlPlanDiagnostics.length + errors.length,
|
|
555
|
+
},
|
|
556
|
+
tables,
|
|
557
|
+
diagnostics: [
|
|
558
|
+
...dataGraphDiagnostics,
|
|
559
|
+
...sqlPlanDiagnostics,
|
|
560
|
+
...errors,
|
|
561
|
+
],
|
|
562
|
+
},
|
|
563
|
+
errors,
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
function buildDriftInspect(workspaceRoot: string): Record<string, unknown> {
|
|
568
|
+
const schema = buildSchemaInspect(workspaceRoot);
|
|
569
|
+
const artifacts = readGeneratedArtifactStatus(workspaceRoot);
|
|
570
|
+
const missingArtifacts = artifacts.filter((artifact) => !artifact.present);
|
|
571
|
+
const tableDrift = ((schema.data.tables as Array<{ name: string; missingRuntimeFields: string[] }> | undefined) ?? [])
|
|
572
|
+
.filter((table) => table.missingRuntimeFields.length > 0)
|
|
573
|
+
.map((table) => ({
|
|
574
|
+
table: table.name,
|
|
575
|
+
missingRuntimeFields: table.missingRuntimeFields,
|
|
576
|
+
suggestedCommand: "forge generate && forge check --json",
|
|
577
|
+
}));
|
|
578
|
+
const staleAgentContext = hasPath(workspaceRoot, ".forge/agent/context.json")
|
|
579
|
+
? "run forge agent check --target codex --json or forge agent export --target codex"
|
|
580
|
+
: null;
|
|
581
|
+
|
|
582
|
+
return {
|
|
583
|
+
schemaVersion: "0.1.0",
|
|
584
|
+
summary: {
|
|
585
|
+
ok: missingArtifacts.length === 0 && tableDrift.length === 0,
|
|
586
|
+
missingArtifacts: missingArtifacts.length,
|
|
587
|
+
tableDrift: tableDrift.length,
|
|
588
|
+
agentContextPresent: hasPath(workspaceRoot, ".forge/agent/context.json"),
|
|
589
|
+
},
|
|
590
|
+
missingArtifacts,
|
|
591
|
+
tableDrift,
|
|
592
|
+
agentContext: staleAgentContext,
|
|
593
|
+
nextActions: [
|
|
594
|
+
...(missingArtifacts.length > 0 || tableDrift.length > 0 ? ["forge generate", "forge check --json"] : []),
|
|
595
|
+
"forge agent check --target codex --json",
|
|
596
|
+
],
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
function buildHandoffInspect(workspaceRoot: string): Record<string, unknown> {
|
|
601
|
+
const manifest = readGeneratedJson<{
|
|
602
|
+
targets?: Array<{
|
|
603
|
+
name?: string;
|
|
604
|
+
files?: string[];
|
|
605
|
+
default?: boolean;
|
|
606
|
+
optional?: boolean;
|
|
607
|
+
formatVersion?: string;
|
|
608
|
+
adapterVersion?: string;
|
|
609
|
+
}>;
|
|
610
|
+
}>(workspaceRoot, `${GENERATED_DIR}/agentAdapterManifest.json`);
|
|
611
|
+
const targets = (manifest?.targets ?? []).map((target) => {
|
|
612
|
+
const files = target.files ?? [];
|
|
613
|
+
const missingFiles = files.filter((file) => !hasPath(workspaceRoot, file));
|
|
614
|
+
return {
|
|
615
|
+
name: target.name,
|
|
616
|
+
default: target.default === true,
|
|
617
|
+
optional: target.optional === true,
|
|
618
|
+
formatVersion: target.formatVersion,
|
|
619
|
+
adapterVersion: target.adapterVersion,
|
|
620
|
+
files,
|
|
621
|
+
filesPresent: files.length - missingFiles.length,
|
|
622
|
+
missingFiles,
|
|
623
|
+
exportCommand: target.name ? `forge agent export --target ${target.name}` : null,
|
|
624
|
+
checkCommand: target.name ? `forge agent check --target ${target.name} --json` : null,
|
|
625
|
+
prepareCommand: target.name ? `forge agent prepare --target ${target.name} --json` : null,
|
|
626
|
+
};
|
|
627
|
+
});
|
|
628
|
+
const missingRequiredFiles = targets.reduce(
|
|
629
|
+
(count, target) => count + (target.optional ? 0 : target.missingFiles.length),
|
|
630
|
+
0,
|
|
631
|
+
);
|
|
632
|
+
const missingOptionalFiles = targets.reduce(
|
|
633
|
+
(count, target) => count + (target.optional ? target.missingFiles.length : 0),
|
|
634
|
+
0,
|
|
635
|
+
);
|
|
636
|
+
const defaultTarget = targets.find((target) => target.default);
|
|
637
|
+
const defaultTargetMissingFiles = defaultTarget?.missingFiles.length ?? missingRequiredFiles;
|
|
638
|
+
|
|
639
|
+
return {
|
|
640
|
+
schemaVersion: "0.1.0",
|
|
641
|
+
summary: {
|
|
642
|
+
targets: targets.length,
|
|
643
|
+
defaultTarget: defaultTarget?.name ?? "generic",
|
|
644
|
+
missingFiles: missingRequiredFiles + missingOptionalFiles,
|
|
645
|
+
missingDefaultFiles: defaultTargetMissingFiles,
|
|
646
|
+
missingRequiredFiles,
|
|
647
|
+
missingOptionalFiles,
|
|
648
|
+
defaultReady: defaultTargetMissingFiles === 0,
|
|
649
|
+
requiredReady: missingRequiredFiles === 0,
|
|
650
|
+
},
|
|
651
|
+
targets,
|
|
652
|
+
commands: [
|
|
653
|
+
"forge agent list-targets --json",
|
|
654
|
+
"forge agent prepare --target codex --json",
|
|
655
|
+
"forge agent hooks smoke --target codex --json",
|
|
656
|
+
"forge agent ingest codex --event PostToolUse --json",
|
|
657
|
+
],
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
export interface StatusCommandResult {
|
|
662
|
+
ok: boolean;
|
|
663
|
+
data: Record<string, unknown>;
|
|
664
|
+
exitCode: 0 | 1;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
export function runStatusCommand(workspaceRoot: string): StatusCommandResult {
|
|
668
|
+
const summary = buildInspectSummary(workspaceRoot);
|
|
669
|
+
const drift = buildDriftInspect(workspaceRoot);
|
|
670
|
+
const handoff = buildHandoffInspect(workspaceRoot);
|
|
671
|
+
const gitSummary = buildWorkspaceGitSummary(workspaceRoot);
|
|
672
|
+
const git = {
|
|
673
|
+
available: gitSummary.available,
|
|
674
|
+
...(gitSummary.error ? { error: gitSummary.error } : {}),
|
|
675
|
+
changed: gitSummary.changeSummary.changed,
|
|
676
|
+
staged: gitSummary.changeSummary.staged,
|
|
677
|
+
unstaged: gitSummary.changeSummary.unstaged,
|
|
678
|
+
untracked: gitSummary.changeSummary.untracked,
|
|
679
|
+
};
|
|
680
|
+
const summaryBlock = summary.summary as Record<string, unknown>;
|
|
681
|
+
const driftSummary = drift.summary as Record<string, unknown>;
|
|
682
|
+
const handoffSummary = handoff.summary as Record<string, unknown>;
|
|
683
|
+
const missingArtifacts = Number(summaryBlock.missingArtifacts ?? 0);
|
|
684
|
+
const tableDrift = Number(driftSummary.tableDrift ?? 0);
|
|
685
|
+
const generatedReady = missingArtifacts === 0;
|
|
686
|
+
const driftClean = driftSummary.ok === true;
|
|
687
|
+
const ok = driftClean && generatedReady;
|
|
688
|
+
const handoffDefaultReady = handoffSummary.defaultReady === true;
|
|
689
|
+
const generatedState = !generatedReady
|
|
690
|
+
? "missing-artifacts"
|
|
691
|
+
: driftClean
|
|
692
|
+
? "ready"
|
|
693
|
+
: "drift";
|
|
694
|
+
const generatedNextActions = generatedState === "ready"
|
|
695
|
+
? ["forge dev", "forge generate --check --json"]
|
|
696
|
+
: ["forge generate", "forge check --json", "forge inspect drift --json"];
|
|
697
|
+
const changed = gitSummary.changeSummary.changed;
|
|
698
|
+
const generatedGitFiles = changed.byType.generated.count;
|
|
699
|
+
const authoredGitFiles = changed.total.count - generatedGitFiles;
|
|
700
|
+
const generatedGitExplanation = generatedGitFiles === 0
|
|
701
|
+
? "git status has no generated artifact changes"
|
|
702
|
+
: authoredGitFiles === 0
|
|
703
|
+
? "forge generate --check can be clean while git shows generated artifacts changed: generated files match current workspace inputs but differ from HEAD"
|
|
704
|
+
: "git status includes generated artifacts alongside authored changes; review authored inputs first";
|
|
705
|
+
const frontendPresent = summaryBlock.frontendPresent === true;
|
|
706
|
+
const studio = {
|
|
707
|
+
openCommand: "forge studio open . --preview-port 5174 --target codex --json",
|
|
708
|
+
attachCommand: "forge studio attach . --preview-port 5174 --target codex --json",
|
|
709
|
+
snapshotCommand: "forge studio snapshot . --preview-port 5174 --target codex --json",
|
|
710
|
+
watchCommand: "forge studio watch . --preview-port 5174 --target codex --json",
|
|
711
|
+
bridgeCommand: "forge studio bridge . --preview-port 5174 --target codex --studio-url http://127.0.0.1:3765 --json",
|
|
712
|
+
doctorCommand: "forge studio doctor . --preview-port 5174 --target codex --json",
|
|
713
|
+
targetPreviewUrl: "http://127.0.0.1:5174",
|
|
714
|
+
startTargetAppCommand: "forge dev --port 3766 --web-port 5174",
|
|
715
|
+
probeCommand: "forge dev --once --json",
|
|
716
|
+
useful: frontendPresent,
|
|
717
|
+
note: frontendPresent
|
|
718
|
+
? "Attach this app to Forge Studio as an external-agent workroom; Studio should preview the target app on 5174."
|
|
719
|
+
: "No frontend was detected, but Studio can still attach for hooks, posture, and agent context.",
|
|
720
|
+
};
|
|
721
|
+
|
|
722
|
+
return {
|
|
723
|
+
ok,
|
|
724
|
+
data: {
|
|
725
|
+
schemaVersion: "0.1.0",
|
|
726
|
+
ok,
|
|
727
|
+
generated: {
|
|
728
|
+
state: generatedState,
|
|
729
|
+
ready: generatedReady,
|
|
730
|
+
driftClean,
|
|
731
|
+
missingArtifacts,
|
|
732
|
+
tableDrift,
|
|
733
|
+
safeDevCommand: "forge dev",
|
|
734
|
+
checkCommand: "forge generate --check --json",
|
|
735
|
+
repairCommand: "forge generate",
|
|
736
|
+
git: {
|
|
737
|
+
changedFiles: changed.total.count,
|
|
738
|
+
authoredFiles: authoredGitFiles,
|
|
739
|
+
generatedFiles: generatedGitFiles,
|
|
740
|
+
explanation: generatedGitExplanation,
|
|
741
|
+
},
|
|
742
|
+
nextActions: generatedNextActions,
|
|
743
|
+
},
|
|
744
|
+
studio,
|
|
745
|
+
summary: {
|
|
746
|
+
project: summaryBlock.project,
|
|
747
|
+
generated: generatedState,
|
|
748
|
+
tables: summaryBlock.tables,
|
|
749
|
+
frontendPresent,
|
|
750
|
+
routes: summaryBlock.routes,
|
|
751
|
+
drift: driftClean ? "clean" : "attention",
|
|
752
|
+
agentTargets: summaryBlock.agentTargets,
|
|
753
|
+
missingAgentFiles: handoffSummary.missingRequiredFiles,
|
|
754
|
+
missingDefaultAgentFiles: handoffSummary.missingDefaultFiles,
|
|
755
|
+
missingRequiredAgentFiles: handoffSummary.missingRequiredFiles,
|
|
756
|
+
missingOptionalAgentFiles: handoffSummary.missingOptionalFiles,
|
|
757
|
+
},
|
|
758
|
+
checks: {
|
|
759
|
+
artifacts: {
|
|
760
|
+
missing: missingArtifacts,
|
|
761
|
+
},
|
|
762
|
+
schema: {
|
|
763
|
+
tableDrift,
|
|
764
|
+
},
|
|
765
|
+
handoff: {
|
|
766
|
+
targets: handoffSummary.targets,
|
|
767
|
+
missingFiles: handoffSummary.missingFiles,
|
|
768
|
+
missingDefaultFiles: handoffSummary.missingDefaultFiles,
|
|
769
|
+
missingRequiredFiles: handoffSummary.missingRequiredFiles,
|
|
770
|
+
missingOptionalFiles: handoffSummary.missingOptionalFiles,
|
|
771
|
+
defaultReady: handoffSummary.defaultReady,
|
|
772
|
+
requiredReady: handoffSummary.requiredReady,
|
|
773
|
+
},
|
|
774
|
+
},
|
|
775
|
+
git,
|
|
776
|
+
nextActions: ok
|
|
777
|
+
? [
|
|
778
|
+
"forge handoff --json",
|
|
779
|
+
"forge changed --json",
|
|
780
|
+
"forge dev",
|
|
781
|
+
...(frontendPresent ? [studio.openCommand, studio.bridgeCommand, studio.doctorCommand] : []),
|
|
782
|
+
...(!handoffDefaultReady ? ["forge agent prepare --target generic --json"] : []),
|
|
783
|
+
"forge inspect handoff --json",
|
|
784
|
+
"forge verify --changed",
|
|
785
|
+
]
|
|
786
|
+
: [
|
|
787
|
+
"forge generate",
|
|
788
|
+
"forge handoff --json",
|
|
789
|
+
"forge changed --json",
|
|
790
|
+
...(frontendPresent ? [studio.openCommand, studio.bridgeCommand, studio.doctorCommand] : []),
|
|
791
|
+
"forge inspect drift --json",
|
|
792
|
+
"forge agent prepare --target codex --json",
|
|
793
|
+
],
|
|
794
|
+
},
|
|
795
|
+
exitCode: ok ? 0 : 1,
|
|
796
|
+
};
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
export function formatStatusHuman(result: StatusCommandResult): string {
|
|
800
|
+
const summary = result.data.summary as Record<string, unknown>;
|
|
801
|
+
const generated = result.data.generated as
|
|
802
|
+
| {
|
|
803
|
+
state?: string;
|
|
804
|
+
missingArtifacts?: number;
|
|
805
|
+
tableDrift?: number;
|
|
806
|
+
safeDevCommand?: string;
|
|
807
|
+
checkCommand?: string;
|
|
808
|
+
repairCommand?: string;
|
|
809
|
+
}
|
|
810
|
+
| undefined;
|
|
811
|
+
const git = result.data.git as
|
|
812
|
+
| {
|
|
813
|
+
available?: boolean;
|
|
814
|
+
changed?: CategorizedFileSummary;
|
|
815
|
+
}
|
|
816
|
+
| undefined;
|
|
817
|
+
const studio = result.data.studio as
|
|
818
|
+
| {
|
|
819
|
+
attachCommand?: string;
|
|
820
|
+
openCommand?: string;
|
|
821
|
+
doctorCommand?: string;
|
|
822
|
+
bridgeCommand?: string;
|
|
823
|
+
targetPreviewUrl?: string;
|
|
824
|
+
startTargetAppCommand?: string;
|
|
825
|
+
useful?: boolean;
|
|
826
|
+
}
|
|
827
|
+
| undefined;
|
|
828
|
+
const lines = [
|
|
829
|
+
`Forge status: ${result.ok ? "ready" : "needs attention"}`,
|
|
830
|
+
`Project: ${summary.project ?? "unknown"}`,
|
|
831
|
+
`Generated: ${summary.generated}`,
|
|
832
|
+
...(generated
|
|
833
|
+
? [
|
|
834
|
+
`Generated detail: missing artifacts ${generated.missingArtifacts ?? 0}, table drift ${generated.tableDrift ?? 0}`,
|
|
835
|
+
`Generated check: ${generated.checkCommand ?? "forge generate --check --json"}`,
|
|
836
|
+
`Generated repair: ${generated.repairCommand ?? "forge generate"}`,
|
|
837
|
+
`Generated dev: ${generated.safeDevCommand ?? "forge dev"}`,
|
|
838
|
+
]
|
|
839
|
+
: []),
|
|
840
|
+
`Drift: ${summary.drift}`,
|
|
841
|
+
`Frontend: ${summary.frontendPresent ? `${summary.routes ?? 0} routes` : "none"}`,
|
|
842
|
+
...(studio
|
|
843
|
+
? [
|
|
844
|
+
`Studio open: ${studio.openCommand ?? "forge studio open . --preview-port 5174 --target codex --json"}`,
|
|
845
|
+
`Studio attach: ${studio.attachCommand ?? "forge studio attach . --preview-port 5174 --target codex --json"}`,
|
|
846
|
+
`Studio bridge: ${studio.bridgeCommand ?? "forge studio bridge . --preview-port 5174 --target codex --studio-url http://127.0.0.1:3765 --json"}`,
|
|
847
|
+
`Studio doctor: ${studio.doctorCommand ?? "forge studio doctor . --preview-port 5174 --target codex --json"}`,
|
|
848
|
+
`Studio preview: ${studio.targetPreviewUrl ?? "http://127.0.0.1:5174"}`,
|
|
849
|
+
`Studio start: ${studio.startTargetAppCommand ?? "forge dev --port 3766 --web-port 5174"}`,
|
|
850
|
+
]
|
|
851
|
+
: []),
|
|
852
|
+
...(git?.available && git.changed
|
|
853
|
+
? [`Changed: ${git.changed.total.count}${git.changed.total.count > 0 ? ` (${git.changed.primaryTypes.slice(0, 5).join(", ")})` : ""}`]
|
|
854
|
+
: []),
|
|
855
|
+
`Agent default missing files: ${summary.missingDefaultAgentFiles ?? 0}`,
|
|
856
|
+
`Agent required missing files: ${summary.missingRequiredAgentFiles ?? summary.missingAgentFiles ?? 0}`,
|
|
857
|
+
`Agent optional missing files: ${summary.missingOptionalAgentFiles ?? 0}`,
|
|
858
|
+
"",
|
|
859
|
+
"Next:",
|
|
860
|
+
...((result.data.nextActions as string[] | undefined) ?? []).map((command) => ` ${command}`),
|
|
861
|
+
];
|
|
862
|
+
return `${lines.join("\n")}\n`;
|
|
863
|
+
}
|
|
864
|
+
|
|
273
865
|
export async function runGenerateCommand(
|
|
274
866
|
options: GenerateOptions,
|
|
275
867
|
): Promise<GenerateResult> {
|
|
276
|
-
const result = await run(options);
|
|
868
|
+
const result = await withWorkspaceCwd(options.workspaceRoot, () => run(options));
|
|
277
869
|
return attachFailureKind(result);
|
|
278
870
|
}
|
|
279
871
|
|
|
872
|
+
async function withWorkspaceCwd<T>(workspaceRoot: string, fn: () => Promise<T>): Promise<T> {
|
|
873
|
+
const previous = process.cwd();
|
|
874
|
+
const target = resolve(workspaceRoot);
|
|
875
|
+
if (resolve(previous).toLowerCase() === target.toLowerCase()) {
|
|
876
|
+
return fn();
|
|
877
|
+
}
|
|
878
|
+
process.chdir(target);
|
|
879
|
+
try {
|
|
880
|
+
return await fn();
|
|
881
|
+
} finally {
|
|
882
|
+
process.chdir(previous);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
|
|
280
886
|
export async function runAddCommand(
|
|
281
887
|
alias: string,
|
|
282
888
|
options: Extract<ForgeCommand, { kind: "add" }>["options"],
|
|
@@ -343,6 +949,7 @@ export async function runCheckCommand(
|
|
|
343
949
|
workspaceRoot,
|
|
344
950
|
`${GENERATED_DIR}/capabilityMap.json`,
|
|
345
951
|
)?.diagnostics ?? [];
|
|
952
|
+
const externalDiagnostics = buildExternalServiceGraph(workspaceRoot).diagnostics;
|
|
346
953
|
|
|
347
954
|
const allDiagnostics = [
|
|
348
955
|
...guardDiagnostics,
|
|
@@ -351,6 +958,7 @@ export async function runCheckCommand(
|
|
|
351
958
|
...queryDiagnostics,
|
|
352
959
|
...frontendDiagnostics,
|
|
353
960
|
...capabilityDiagnostics,
|
|
961
|
+
...externalDiagnostics,
|
|
354
962
|
];
|
|
355
963
|
const errors = allDiagnostics.filter(
|
|
356
964
|
(diagnostic) => diagnostic.severity === "error",
|
|
@@ -369,9 +977,265 @@ export async function runCheckCommand(
|
|
|
369
977
|
});
|
|
370
978
|
}
|
|
371
979
|
|
|
980
|
+
interface ReleaseDoctorCheck {
|
|
981
|
+
name: string;
|
|
982
|
+
ok: boolean;
|
|
983
|
+
requiredForPublish: boolean;
|
|
984
|
+
state?: string;
|
|
985
|
+
result: ReleaseCommandResult | SelfHostCommandResult | DocsCheckResult | PackagePackCheckResult;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
interface PackagePackCheckResult {
|
|
989
|
+
ok: boolean;
|
|
990
|
+
data: {
|
|
991
|
+
command: "npm pack --dry-run --json";
|
|
992
|
+
dryRun: true;
|
|
993
|
+
tarball: string | null;
|
|
994
|
+
fileCount: number;
|
|
995
|
+
};
|
|
996
|
+
diagnostics: ReturnType<typeof createDiagnostic>[];
|
|
997
|
+
nextActions?: string[];
|
|
998
|
+
failureKind?: string;
|
|
999
|
+
exitCode: 0 | 1;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
interface ReleaseDoctorResult {
|
|
1003
|
+
schemaVersion: "0.1.0";
|
|
1004
|
+
ok: boolean;
|
|
1005
|
+
readyToPublish: boolean;
|
|
1006
|
+
summary: {
|
|
1007
|
+
checks: number;
|
|
1008
|
+
failed: string[];
|
|
1009
|
+
notPrepared: string[];
|
|
1010
|
+
};
|
|
1011
|
+
checks: ReleaseDoctorCheck[];
|
|
1012
|
+
nextActions: string[];
|
|
1013
|
+
exitCode: 0 | 1;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
function runPackagePackDryRun(workspaceRoot: string): PackagePackCheckResult {
|
|
1017
|
+
const result = spawnSync("npm", ["pack", "--dry-run", "--json"], {
|
|
1018
|
+
cwd: workspaceRoot,
|
|
1019
|
+
encoding: "utf8",
|
|
1020
|
+
windowsHide: true,
|
|
1021
|
+
});
|
|
1022
|
+
const command = "npm pack --dry-run --json" as const;
|
|
1023
|
+
if (result.status !== 0) {
|
|
1024
|
+
const failureDetail = result.error instanceof Error ? result.error.message : null;
|
|
1025
|
+
return {
|
|
1026
|
+
ok: false,
|
|
1027
|
+
data: { command, dryRun: true, tarball: null, fileCount: 0 },
|
|
1028
|
+
diagnostics: [
|
|
1029
|
+
createDiagnostic({
|
|
1030
|
+
severity: "error",
|
|
1031
|
+
code: FORGE_RELEASE_PACKAGE_PACK_FAILED,
|
|
1032
|
+
message: "npm pack dry-run failed; release package contents could not be validated",
|
|
1033
|
+
fixHint: (result.stderr || result.stdout || failureDetail || "Run npm pack --dry-run --json locally for details.").trim(),
|
|
1034
|
+
suggestedCommands: ["npm pack --dry-run --json"],
|
|
1035
|
+
}),
|
|
1036
|
+
],
|
|
1037
|
+
nextActions: ["npm pack --dry-run --json"],
|
|
1038
|
+
failureKind: "package-pack-failed",
|
|
1039
|
+
exitCode: 1,
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
try {
|
|
1043
|
+
const parsed = JSON.parse(result.stdout || "[]") as unknown;
|
|
1044
|
+
const pack = Array.isArray(parsed)
|
|
1045
|
+
? (parsed[0] as { filename?: unknown; files?: unknown[] } | undefined)
|
|
1046
|
+
: undefined;
|
|
1047
|
+
if (typeof pack?.filename !== "string" || !Array.isArray(pack.files)) {
|
|
1048
|
+
return {
|
|
1049
|
+
ok: false,
|
|
1050
|
+
data: { command, dryRun: true, tarball: null, fileCount: 0 },
|
|
1051
|
+
diagnostics: [
|
|
1052
|
+
createDiagnostic({
|
|
1053
|
+
severity: "error",
|
|
1054
|
+
code: FORGE_RELEASE_PACKAGE_PACK_FAILED,
|
|
1055
|
+
message: "npm pack dry-run did not report package contents",
|
|
1056
|
+
fixHint: "Run npm pack --dry-run --json locally and confirm it returns a tarball with file entries.",
|
|
1057
|
+
suggestedCommands: ["npm pack --dry-run --json"],
|
|
1058
|
+
}),
|
|
1059
|
+
],
|
|
1060
|
+
nextActions: ["npm pack --dry-run --json"],
|
|
1061
|
+
failureKind: "package-pack-missing-contents",
|
|
1062
|
+
exitCode: 1,
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
return {
|
|
1066
|
+
ok: true,
|
|
1067
|
+
data: {
|
|
1068
|
+
command,
|
|
1069
|
+
dryRun: true,
|
|
1070
|
+
tarball: pack.filename,
|
|
1071
|
+
fileCount: pack.files.length,
|
|
1072
|
+
},
|
|
1073
|
+
diagnostics: [],
|
|
1074
|
+
exitCode: 0,
|
|
1075
|
+
};
|
|
1076
|
+
} catch (error) {
|
|
1077
|
+
return {
|
|
1078
|
+
ok: false,
|
|
1079
|
+
data: { command, dryRun: true, tarball: null, fileCount: 0 },
|
|
1080
|
+
diagnostics: [
|
|
1081
|
+
createDiagnostic({
|
|
1082
|
+
severity: "error",
|
|
1083
|
+
code: FORGE_RELEASE_PACKAGE_PACK_FAILED,
|
|
1084
|
+
message: "npm pack dry-run returned invalid JSON",
|
|
1085
|
+
fixHint: error instanceof Error ? error.message : String(error),
|
|
1086
|
+
suggestedCommands: ["npm pack --dry-run --json"],
|
|
1087
|
+
}),
|
|
1088
|
+
],
|
|
1089
|
+
nextActions: ["npm pack --dry-run --json"],
|
|
1090
|
+
failureKind: "package-pack-invalid-json",
|
|
1091
|
+
exitCode: 1,
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
export async function runReleaseDoctorCommand(command: Extract<ForgeCommand, { kind: "release" }>): Promise<ReleaseDoctorResult> {
|
|
1097
|
+
const release = await runReleaseCommand({
|
|
1098
|
+
...command,
|
|
1099
|
+
action: "check",
|
|
1100
|
+
allowMissingLocalRelease: true,
|
|
1101
|
+
provider: command.provider as import("../compiler/release/types.ts").ReleaseExportProvider | undefined,
|
|
1102
|
+
target: command.target as import("../compiler/release/types.ts").ReleaseExportProvider | undefined,
|
|
1103
|
+
});
|
|
1104
|
+
const sourcemaps = await runReleaseCommand({
|
|
1105
|
+
...command,
|
|
1106
|
+
area: "sourcemaps",
|
|
1107
|
+
action: "check",
|
|
1108
|
+
provider: command.provider as import("../compiler/release/types.ts").ReleaseExportProvider | undefined,
|
|
1109
|
+
target: command.target as import("../compiler/release/types.ts").ReleaseExportProvider | undefined,
|
|
1110
|
+
});
|
|
1111
|
+
const selfHost = await runSelfHostCommand({
|
|
1112
|
+
subcommand: "check",
|
|
1113
|
+
workspaceRoot: command.workspaceRoot,
|
|
1114
|
+
json: command.json,
|
|
1115
|
+
withWeb: true,
|
|
1116
|
+
postgresVersion: "16",
|
|
1117
|
+
runtimePort: 3765,
|
|
1118
|
+
webPort: 3000,
|
|
1119
|
+
preparedOnly: true,
|
|
1120
|
+
});
|
|
1121
|
+
const docs = runDocsCheckCommand({
|
|
1122
|
+
workspaceRoot: command.workspaceRoot,
|
|
1123
|
+
json: command.json,
|
|
1124
|
+
});
|
|
1125
|
+
const packagePack = runPackagePackDryRun(command.workspaceRoot);
|
|
1126
|
+
const checks: ReleaseDoctorCheck[] = [
|
|
1127
|
+
{
|
|
1128
|
+
name: "release-prepared",
|
|
1129
|
+
ok: release.ok,
|
|
1130
|
+
requiredForPublish: true,
|
|
1131
|
+
state: (release.data as { state?: string } | undefined)?.state,
|
|
1132
|
+
result: release,
|
|
1133
|
+
},
|
|
1134
|
+
{
|
|
1135
|
+
name: "sourcemaps",
|
|
1136
|
+
ok: sourcemaps.ok,
|
|
1137
|
+
requiredForPublish: true,
|
|
1138
|
+
result: sourcemaps,
|
|
1139
|
+
},
|
|
1140
|
+
{
|
|
1141
|
+
name: "self-host",
|
|
1142
|
+
ok: selfHost.ok,
|
|
1143
|
+
requiredForPublish: false,
|
|
1144
|
+
state: selfHost.state,
|
|
1145
|
+
result: selfHost,
|
|
1146
|
+
},
|
|
1147
|
+
{
|
|
1148
|
+
name: "docs",
|
|
1149
|
+
ok: docs.ok,
|
|
1150
|
+
requiredForPublish: true,
|
|
1151
|
+
result: docs,
|
|
1152
|
+
},
|
|
1153
|
+
{
|
|
1154
|
+
name: "npm-pack-dry-run",
|
|
1155
|
+
ok: packagePack.ok,
|
|
1156
|
+
requiredForPublish: true,
|
|
1157
|
+
result: packagePack,
|
|
1158
|
+
},
|
|
1159
|
+
];
|
|
1160
|
+
const failed = checks.filter((check) => !check.ok).map((check) => check.name);
|
|
1161
|
+
const notPrepared = checks
|
|
1162
|
+
.filter((check) => check.state === "missing-prepared-release" || check.state === "not-prepared")
|
|
1163
|
+
.map((check) => check.name);
|
|
1164
|
+
const readyToPublish = failed.length === 0 && notPrepared.length === 0;
|
|
1165
|
+
return {
|
|
1166
|
+
schemaVersion: "0.1.0",
|
|
1167
|
+
ok: failed.length === 0,
|
|
1168
|
+
readyToPublish,
|
|
1169
|
+
summary: {
|
|
1170
|
+
checks: checks.length,
|
|
1171
|
+
failed,
|
|
1172
|
+
notPrepared,
|
|
1173
|
+
},
|
|
1174
|
+
checks,
|
|
1175
|
+
nextActions: uniqueNextActions(checks.flatMap((check) => check.result.nextActions ?? [])),
|
|
1176
|
+
exitCode: failed.length === 0 ? 0 : 1,
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
function formatManifestHuman(result: {
|
|
1181
|
+
subcommand: "validate" | "import";
|
|
1182
|
+
path: string;
|
|
1183
|
+
imported?: boolean;
|
|
1184
|
+
serviceCount?: number;
|
|
1185
|
+
diagnostics: import("../compiler/types/diagnostic.ts").Diagnostic[];
|
|
1186
|
+
exitCode: number;
|
|
1187
|
+
}): string {
|
|
1188
|
+
const errors = result.diagnostics.filter((diagnostic) => diagnostic.severity === "error");
|
|
1189
|
+
const warnings = result.diagnostics.filter((diagnostic) => diagnostic.severity === "warning");
|
|
1190
|
+
const lines = [
|
|
1191
|
+
`manifest: ${result.subcommand}`,
|
|
1192
|
+
`path: ${result.path}`,
|
|
1193
|
+
result.subcommand === "import" ? `imported: ${result.imported ? "yes" : "no"}` : null,
|
|
1194
|
+
result.serviceCount !== undefined ? `external services: ${result.serviceCount}` : null,
|
|
1195
|
+
`errors: ${errors.length}`,
|
|
1196
|
+
`warnings: ${warnings.length}`,
|
|
1197
|
+
].filter((line): line is string => line !== null);
|
|
1198
|
+
for (const diagnostic of result.diagnostics) {
|
|
1199
|
+
lines.push(`${diagnostic.severity} ${diagnostic.code}: ${diagnostic.message}`);
|
|
1200
|
+
}
|
|
1201
|
+
return `${lines.join("\n")}\n`;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
function runManifestCommand(command: Extract<ForgeCommand, { kind: "manifest" }>): {
|
|
1205
|
+
subcommand: "validate" | "import";
|
|
1206
|
+
path: string;
|
|
1207
|
+
imported?: boolean;
|
|
1208
|
+
serviceCount?: number;
|
|
1209
|
+
diagnostics: import("../compiler/types/diagnostic.ts").Diagnostic[];
|
|
1210
|
+
exitCode: number;
|
|
1211
|
+
} {
|
|
1212
|
+
if (command.subcommand === "validate") {
|
|
1213
|
+
const result = readExternalManifestFile(command.path);
|
|
1214
|
+
const hasErrors = result.diagnostics.some((diagnostic) => diagnostic.severity === "error");
|
|
1215
|
+
return {
|
|
1216
|
+
subcommand: "validate",
|
|
1217
|
+
path: command.path,
|
|
1218
|
+
diagnostics: result.diagnostics,
|
|
1219
|
+
exitCode: hasErrors ? 1 : 0,
|
|
1220
|
+
};
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
const result = importExternalManifest(command.workspaceRoot, command.path);
|
|
1224
|
+
const hasErrors = result.diagnostics.some((diagnostic) => diagnostic.severity === "error");
|
|
1225
|
+
return {
|
|
1226
|
+
subcommand: "import",
|
|
1227
|
+
path: result.path,
|
|
1228
|
+
imported: result.imported,
|
|
1229
|
+
serviceCount: result.graph.services.length,
|
|
1230
|
+
diagnostics: result.diagnostics,
|
|
1231
|
+
exitCode: hasErrors ? 1 : 0,
|
|
1232
|
+
};
|
|
1233
|
+
}
|
|
1234
|
+
|
|
372
1235
|
export async function runInspectCommand(
|
|
373
1236
|
target: InspectTarget,
|
|
374
1237
|
workspaceRoot: string,
|
|
1238
|
+
options: { full?: boolean; brief?: boolean } = {},
|
|
375
1239
|
): Promise<InspectResult> {
|
|
376
1240
|
const dataPaths: Partial<Record<InspectTarget, string>> = {
|
|
377
1241
|
app: `${GENERATED_DIR}/appGraph.json`,
|
|
@@ -390,6 +1254,7 @@ export async function runInspectCommand(
|
|
|
390
1254
|
ai: `${GENERATED_DIR}/aiRegistry.json`,
|
|
391
1255
|
queries: `${GENERATED_DIR}/queryRegistry.json`,
|
|
392
1256
|
api: `${GENERATED_DIR}/api.json`,
|
|
1257
|
+
external: `${GENERATED_DIR}/externalServices.json`,
|
|
393
1258
|
client: `${GENERATED_DIR}/clientManifest.json`,
|
|
394
1259
|
frontend: `${GENERATED_DIR}/frontendGraph.json`,
|
|
395
1260
|
auth: `${GENERATED_DIR}/authRegistry.json`,
|
|
@@ -405,6 +1270,7 @@ export async function runInspectCommand(
|
|
|
405
1270
|
"test-graph": `${GENERATED_DIR}/testGraph.json`,
|
|
406
1271
|
"test-plans": `${GENERATED_DIR}/testPlanRegistry.json`,
|
|
407
1272
|
"agent-contract": `${GENERATED_DIR}/agentContract.json`,
|
|
1273
|
+
"agent-tools": `${GENERATED_DIR}/agentTools.json`,
|
|
408
1274
|
"agent-adapters": `${GENERATED_DIR}/agentAdapterManifest.json`,
|
|
409
1275
|
"capability-map": `${GENERATED_DIR}/capabilityMap.json`,
|
|
410
1276
|
ui: `${GENERATED_DIR}/uiTestManifest.json`,
|
|
@@ -424,7 +1290,114 @@ export async function runInspectCommand(
|
|
|
424
1290
|
};
|
|
425
1291
|
}
|
|
426
1292
|
|
|
1293
|
+
if (target === "summary") {
|
|
1294
|
+
return {
|
|
1295
|
+
target,
|
|
1296
|
+
data: buildInspectSummary(workspaceRoot),
|
|
1297
|
+
warnings: [],
|
|
1298
|
+
errors: [],
|
|
1299
|
+
exitCode: 0,
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
if (target === "schema") {
|
|
1304
|
+
const result = buildSchemaInspect(workspaceRoot);
|
|
1305
|
+
return {
|
|
1306
|
+
target,
|
|
1307
|
+
data: result.data,
|
|
1308
|
+
warnings: [],
|
|
1309
|
+
errors: result.errors,
|
|
1310
|
+
exitCode: result.errors.length > 0 ? 1 : 0,
|
|
1311
|
+
failureKind: result.errors.length > 0 ? "missing_artifact" : undefined,
|
|
1312
|
+
};
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
if (target === "drift") {
|
|
1316
|
+
return {
|
|
1317
|
+
target,
|
|
1318
|
+
data: buildDriftInspect(workspaceRoot),
|
|
1319
|
+
warnings: [],
|
|
1320
|
+
errors: [],
|
|
1321
|
+
exitCode: 0,
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
if (target === "handoff") {
|
|
1326
|
+
return {
|
|
1327
|
+
target,
|
|
1328
|
+
data: buildHandoffInspect(workspaceRoot),
|
|
1329
|
+
warnings: [],
|
|
1330
|
+
errors: [],
|
|
1331
|
+
exitCode: 0,
|
|
1332
|
+
};
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
if (target === "imported") {
|
|
1336
|
+
const result = inspectBrownfieldImport(workspaceRoot);
|
|
1337
|
+
return {
|
|
1338
|
+
target,
|
|
1339
|
+
data: formatBrownfieldImportJson(result),
|
|
1340
|
+
warnings: [],
|
|
1341
|
+
errors: [],
|
|
1342
|
+
exitCode: result.exitCode,
|
|
1343
|
+
failureKind: result.failureKind,
|
|
1344
|
+
};
|
|
1345
|
+
}
|
|
1346
|
+
|
|
427
1347
|
if (target === "all") {
|
|
1348
|
+
if (options.brief) {
|
|
1349
|
+
const brief = buildInspectBrief(workspaceRoot);
|
|
1350
|
+
return {
|
|
1351
|
+
target,
|
|
1352
|
+
data: brief,
|
|
1353
|
+
warnings: [],
|
|
1354
|
+
errors: [],
|
|
1355
|
+
exitCode: 0,
|
|
1356
|
+
};
|
|
1357
|
+
}
|
|
1358
|
+
if (!options.full) {
|
|
1359
|
+
const summary = buildInspectSummary(workspaceRoot);
|
|
1360
|
+
const schema = buildSchemaInspect(workspaceRoot);
|
|
1361
|
+
const drift = buildDriftInspect(workspaceRoot);
|
|
1362
|
+
const handoff = buildHandoffInspect(workspaceRoot);
|
|
1363
|
+
const framework = buildFrameworkInspect(workspaceRoot);
|
|
1364
|
+
const errors = [
|
|
1365
|
+
...schema.errors,
|
|
1366
|
+
];
|
|
1367
|
+
return {
|
|
1368
|
+
target,
|
|
1369
|
+
data: {
|
|
1370
|
+
schemaVersion: "0.1.0",
|
|
1371
|
+
compact: true,
|
|
1372
|
+
payload: {
|
|
1373
|
+
mode: "compact",
|
|
1374
|
+
purpose: "agent diagnostic bundle",
|
|
1375
|
+
includes: ["summary", "schema", "drift", "handoff", "framework"],
|
|
1376
|
+
omitted: ["large generated registries", "module graph", "full runtime graph payloads"],
|
|
1377
|
+
fullCommand: "forge inspect all --full --json",
|
|
1378
|
+
briefCommand: "forge inspect all --brief --json",
|
|
1379
|
+
},
|
|
1380
|
+
summary: summary.summary,
|
|
1381
|
+
inspections: {
|
|
1382
|
+
summary,
|
|
1383
|
+
schema: schema.data,
|
|
1384
|
+
drift,
|
|
1385
|
+
handoff,
|
|
1386
|
+
framework,
|
|
1387
|
+
},
|
|
1388
|
+
nextActions: [
|
|
1389
|
+
"forge inspect summary --json",
|
|
1390
|
+
"forge inspect schema --json",
|
|
1391
|
+
"forge inspect handoff --json",
|
|
1392
|
+
"forge inspect all --full --json",
|
|
1393
|
+
],
|
|
1394
|
+
},
|
|
1395
|
+
warnings: [],
|
|
1396
|
+
errors,
|
|
1397
|
+
exitCode: errors.length > 0 ? 1 : 0,
|
|
1398
|
+
failureKind: errors.length > 0 ? "missing_artifact" : undefined,
|
|
1399
|
+
};
|
|
1400
|
+
}
|
|
428
1401
|
const aggregatePaths: Array<[string, string]> = [
|
|
429
1402
|
["app", `${GENERATED_DIR}/appGraph.json`],
|
|
430
1403
|
["data", `${GENERATED_DIR}/dataGraph.json`],
|
|
@@ -436,6 +1409,7 @@ export async function runInspectCommand(
|
|
|
436
1409
|
["workflows", `${GENERATED_DIR}/workflowRegistry.json`],
|
|
437
1410
|
["telemetry", `${GENERATED_DIR}/telemetryRegistry.json`],
|
|
438
1411
|
["ai", `${GENERATED_DIR}/aiRegistry.json`],
|
|
1412
|
+
["externalServices", `${GENERATED_DIR}/externalServices.json`],
|
|
439
1413
|
["client", `${GENERATED_DIR}/clientManifest.json`],
|
|
440
1414
|
["frontend", `${GENERATED_DIR}/frontendGraph.json`],
|
|
441
1415
|
["auth", `${GENERATED_DIR}/authRegistry.json`],
|
|
@@ -451,6 +1425,7 @@ export async function runInspectCommand(
|
|
|
451
1425
|
["testGraph", `${GENERATED_DIR}/testGraph.json`],
|
|
452
1426
|
["testPlanRegistry", `${GENERATED_DIR}/testPlanRegistry.json`],
|
|
453
1427
|
["agentContract", `${GENERATED_DIR}/agentContract.json`],
|
|
1428
|
+
["agentTools", `${GENERATED_DIR}/agentTools.json`],
|
|
454
1429
|
["agentAdapters", `${GENERATED_DIR}/agentAdapterManifest.json`],
|
|
455
1430
|
["capabilityMap", `${GENERATED_DIR}/capabilityMap.json`],
|
|
456
1431
|
["ui", `${GENERATED_DIR}/uiTestManifest.json`],
|
|
@@ -459,6 +1434,7 @@ export async function runInspectCommand(
|
|
|
459
1434
|
];
|
|
460
1435
|
const data: Record<string, unknown> = {};
|
|
461
1436
|
const errors = [];
|
|
1437
|
+
data.summary = buildInspectSummary(workspaceRoot).summary;
|
|
462
1438
|
for (const [key, relative] of aggregatePaths) {
|
|
463
1439
|
const value = readGeneratedJson<unknown>(workspaceRoot, relative);
|
|
464
1440
|
if (value === null) {
|
|
@@ -476,6 +1452,17 @@ export async function runInspectCommand(
|
|
|
476
1452
|
}
|
|
477
1453
|
data.framework = buildFrameworkInspect(workspaceRoot);
|
|
478
1454
|
data.diagnostics = errors;
|
|
1455
|
+
data.compact = false;
|
|
1456
|
+
data.payload = {
|
|
1457
|
+
mode: "full",
|
|
1458
|
+
purpose: "complete generated machine contract",
|
|
1459
|
+
includes: aggregatePaths.map(([key]) => key),
|
|
1460
|
+
compactCommand: "forge inspect all --json",
|
|
1461
|
+
briefCommand: "forge inspect all --brief --json",
|
|
1462
|
+
};
|
|
1463
|
+
data.nextActions = errors.length > 0
|
|
1464
|
+
? ["forge status --json", "forge generate", "forge check --json"]
|
|
1465
|
+
: ["forge inspect all --json", "forge check --json"];
|
|
479
1466
|
return {
|
|
480
1467
|
target,
|
|
481
1468
|
data,
|
|
@@ -537,6 +1524,18 @@ export async function runInspectCommand(
|
|
|
537
1524
|
|
|
538
1525
|
export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
539
1526
|
switch (command.kind) {
|
|
1527
|
+
case "version": {
|
|
1528
|
+
if (command.json) {
|
|
1529
|
+
process.stdout.write(`${JSON.stringify({
|
|
1530
|
+
version: CLI_VERSION,
|
|
1531
|
+
cliVersion: CLI_VERSION,
|
|
1532
|
+
forgeosVersion: FORGEOS_VERSION,
|
|
1533
|
+
}, null, 2)}\n`);
|
|
1534
|
+
} else {
|
|
1535
|
+
process.stdout.write(`${CLI_VERSION}\n`);
|
|
1536
|
+
}
|
|
1537
|
+
return 0;
|
|
1538
|
+
}
|
|
540
1539
|
case "new": {
|
|
541
1540
|
const result = await runNewCommand({
|
|
542
1541
|
name: command.name,
|
|
@@ -578,6 +1577,15 @@ export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
|
578
1577
|
}
|
|
579
1578
|
return result.exitCode;
|
|
580
1579
|
}
|
|
1580
|
+
case "docs": {
|
|
1581
|
+
const result = runDocsCheckCommand(command);
|
|
1582
|
+
if (command.json) {
|
|
1583
|
+
process.stdout.write(formatJsonResult(result));
|
|
1584
|
+
} else {
|
|
1585
|
+
process.stdout.write(formatDocsCheckHuman(result));
|
|
1586
|
+
}
|
|
1587
|
+
return result.exitCode;
|
|
1588
|
+
}
|
|
581
1589
|
case "agent-contract": {
|
|
582
1590
|
if (command.subcommand === "print") {
|
|
583
1591
|
const result = runAgentContractPrint(command.workspaceRoot);
|
|
@@ -605,6 +1613,25 @@ export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
|
605
1613
|
return result.exitCode;
|
|
606
1614
|
}
|
|
607
1615
|
case "doctor": {
|
|
1616
|
+
if (command.target === "agent") {
|
|
1617
|
+
const result = await runAgentCommand({
|
|
1618
|
+
subcommand: "doctor",
|
|
1619
|
+
workspaceRoot: command.workspaceRoot,
|
|
1620
|
+
json: command.json,
|
|
1621
|
+
target: command.agentTarget ?? "codex",
|
|
1622
|
+
dryRun: false,
|
|
1623
|
+
force: false,
|
|
1624
|
+
preserveUserSections: true,
|
|
1625
|
+
skills: true,
|
|
1626
|
+
rules: true,
|
|
1627
|
+
});
|
|
1628
|
+
if (command.json) {
|
|
1629
|
+
process.stdout.write(formatAgentJson(result));
|
|
1630
|
+
} else {
|
|
1631
|
+
process.stdout.write(formatAgentHuman(result));
|
|
1632
|
+
}
|
|
1633
|
+
return result.exitCode;
|
|
1634
|
+
}
|
|
608
1635
|
if (command.target === "windows") {
|
|
609
1636
|
const result = await runWindowsDoctorCommand({ workspaceRoot: command.workspaceRoot });
|
|
610
1637
|
if (command.json) {
|
|
@@ -634,6 +1661,15 @@ export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
|
634
1661
|
}
|
|
635
1662
|
return result.exitCode;
|
|
636
1663
|
}
|
|
1664
|
+
case "security": {
|
|
1665
|
+
const result = await runSecurityCommand(command);
|
|
1666
|
+
if (command.json) {
|
|
1667
|
+
process.stdout.write(formatSecurityJson(result));
|
|
1668
|
+
} else {
|
|
1669
|
+
process.stdout.write(formatSecurityHuman(result));
|
|
1670
|
+
}
|
|
1671
|
+
return result.exitCode;
|
|
1672
|
+
}
|
|
637
1673
|
case "auth": {
|
|
638
1674
|
const result = await runAuthCommand(command);
|
|
639
1675
|
if (command.json) {
|
|
@@ -662,6 +1698,22 @@ export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
|
662
1698
|
return result.exitCode;
|
|
663
1699
|
}
|
|
664
1700
|
case "release": {
|
|
1701
|
+
if (command.action === "doctor") {
|
|
1702
|
+
const result = await runReleaseDoctorCommand(command);
|
|
1703
|
+
if (command.json) {
|
|
1704
|
+
process.stdout.write(formatJsonResult(result));
|
|
1705
|
+
} else {
|
|
1706
|
+
process.stdout.write(
|
|
1707
|
+
[
|
|
1708
|
+
`release doctor ${result.ok ? "ok" : "failed"}`,
|
|
1709
|
+
`ready to publish: ${result.readyToPublish ? "yes" : "no"}`,
|
|
1710
|
+
...result.checks.map((check) => `${check.ok ? "ok" : "fail"} ${check.name}${check.state ? ` (${check.state})` : ""}`),
|
|
1711
|
+
...(result.nextActions.length > 0 ? ["", "Next:", ...result.nextActions.map((action) => ` ${action}`)] : []),
|
|
1712
|
+
].join("\n").concat("\n"),
|
|
1713
|
+
);
|
|
1714
|
+
}
|
|
1715
|
+
return result.exitCode;
|
|
1716
|
+
}
|
|
665
1717
|
const result = await runReleaseCommand({
|
|
666
1718
|
...command,
|
|
667
1719
|
provider: command.provider as import("../compiler/release/types.ts").ReleaseExportProvider | undefined,
|
|
@@ -737,6 +1789,71 @@ export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
|
737
1789
|
}
|
|
738
1790
|
return result.exitCode;
|
|
739
1791
|
}
|
|
1792
|
+
case "bench": {
|
|
1793
|
+
const result = await runCompilerBenchCommand(command.options);
|
|
1794
|
+
process.stdout.write(
|
|
1795
|
+
command.options.json
|
|
1796
|
+
? formatCompilerBenchJson(result)
|
|
1797
|
+
: formatCompilerBenchHuman(result),
|
|
1798
|
+
);
|
|
1799
|
+
return result.exitCode;
|
|
1800
|
+
}
|
|
1801
|
+
case "cair": {
|
|
1802
|
+
const result = runCairCommand(command.options);
|
|
1803
|
+
process.stdout.write(
|
|
1804
|
+
command.options.json || command.options.format === "json"
|
|
1805
|
+
? formatCairJson(result)
|
|
1806
|
+
: formatCairHuman(result),
|
|
1807
|
+
);
|
|
1808
|
+
return result.exitCode;
|
|
1809
|
+
}
|
|
1810
|
+
case "delta": {
|
|
1811
|
+
if (command.subcommand === "repair") {
|
|
1812
|
+
const result = await runDeltaRepair({
|
|
1813
|
+
workspaceRoot: command.workspaceRoot,
|
|
1814
|
+
dryRun: command.dryRun,
|
|
1815
|
+
yes: command.yes,
|
|
1816
|
+
});
|
|
1817
|
+
process.stdout.write(command.json ? formatDeltaRepairJson(result) : formatDeltaRepairHuman(result));
|
|
1818
|
+
return result.exitCode;
|
|
1819
|
+
}
|
|
1820
|
+
const result = await runDeltaStatus(command.workspaceRoot, { verbose: command.verbose });
|
|
1821
|
+
process.stdout.write(command.json ? formatDeltaStatusJson(result) : formatDeltaStatusHuman(result));
|
|
1822
|
+
return result.exitCode;
|
|
1823
|
+
}
|
|
1824
|
+
case "session": {
|
|
1825
|
+
const result = await runDeltaSessionCommand({
|
|
1826
|
+
workspaceRoot: command.workspaceRoot,
|
|
1827
|
+
subcommand: command.subcommand,
|
|
1828
|
+
sessionId: command.sessionId,
|
|
1829
|
+
sourceSessionId: command.sourceSessionId,
|
|
1830
|
+
operationId: command.operationId,
|
|
1831
|
+
title: command.title,
|
|
1832
|
+
limit: command.limit,
|
|
1833
|
+
});
|
|
1834
|
+
process.stdout.write(command.json ? formatDeltaSessionJson(result) : formatDeltaSessionHuman(result));
|
|
1835
|
+
return result.exitCode;
|
|
1836
|
+
}
|
|
1837
|
+
case "timeline": {
|
|
1838
|
+
const result = await runDeltaTimeline({
|
|
1839
|
+
workspaceRoot: command.workspaceRoot,
|
|
1840
|
+
target: command.target,
|
|
1841
|
+
kind: command.kindFilter,
|
|
1842
|
+
session: command.sessionId,
|
|
1843
|
+
limit: command.limit,
|
|
1844
|
+
rebuild: command.rebuild,
|
|
1845
|
+
});
|
|
1846
|
+
process.stdout.write(command.json ? formatDeltaTimelineJson(result) : formatDeltaTimelineHuman(result));
|
|
1847
|
+
return result.exitCode;
|
|
1848
|
+
}
|
|
1849
|
+
case "explain": {
|
|
1850
|
+
const result = await runDeltaExplain({
|
|
1851
|
+
workspaceRoot: command.workspaceRoot,
|
|
1852
|
+
thing: command.thing,
|
|
1853
|
+
});
|
|
1854
|
+
process.stdout.write(command.json ? formatDeltaExplainJson(result) : formatDeltaExplainHuman(result));
|
|
1855
|
+
return result.exitCode;
|
|
1856
|
+
}
|
|
740
1857
|
case "agent": {
|
|
741
1858
|
const result = await runAgentCommand(command.options);
|
|
742
1859
|
if (command.options.json) {
|
|
@@ -746,10 +1863,13 @@ export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
|
746
1863
|
}
|
|
747
1864
|
return result.exitCode;
|
|
748
1865
|
}
|
|
1866
|
+
case "mcp": {
|
|
1867
|
+
return runMcpServe(command.workspaceRoot);
|
|
1868
|
+
}
|
|
749
1869
|
case "review": {
|
|
750
1870
|
const result = runReviewCommand(command.options);
|
|
751
1871
|
if (command.options.json) {
|
|
752
|
-
process.stdout.write(formatReviewJson(result));
|
|
1872
|
+
process.stdout.write(formatReviewJson(result, { full: command.options.full }));
|
|
753
1873
|
} else if (command.options.md && result.report) {
|
|
754
1874
|
process.stdout.write(renderReviewMarkdown(result.report));
|
|
755
1875
|
} else if (command.options.sarif && result.report && !command.options.write) {
|
|
@@ -773,7 +1893,7 @@ export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
|
773
1893
|
}
|
|
774
1894
|
case "generate": {
|
|
775
1895
|
const result = await runGenerateCommand({
|
|
776
|
-
workspaceRoot:
|
|
1896
|
+
workspaceRoot: command.workspaceRoot,
|
|
777
1897
|
check: command.check,
|
|
778
1898
|
dryRun: command.dryRun,
|
|
779
1899
|
json: command.json,
|
|
@@ -797,10 +1917,135 @@ export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
|
797
1917
|
}
|
|
798
1918
|
return result.exitCode;
|
|
799
1919
|
}
|
|
1920
|
+
case "manifest": {
|
|
1921
|
+
const result = runManifestCommand(command);
|
|
1922
|
+
if (command.json) {
|
|
1923
|
+
process.stdout.write(formatJsonResult(result));
|
|
1924
|
+
} else {
|
|
1925
|
+
process.stdout.write(formatManifestHuman(result));
|
|
1926
|
+
}
|
|
1927
|
+
return result.exitCode;
|
|
1928
|
+
}
|
|
1929
|
+
case "import": {
|
|
1930
|
+
const result = runBrownfieldImportCommand(command.options);
|
|
1931
|
+
if (command.options.json) {
|
|
1932
|
+
process.stdout.write(formatJsonResult(formatBrownfieldImportJson(result)));
|
|
1933
|
+
} else {
|
|
1934
|
+
process.stdout.write(formatBrownfieldImportHuman(result));
|
|
1935
|
+
}
|
|
1936
|
+
return result.exitCode;
|
|
1937
|
+
}
|
|
1938
|
+
case "status": {
|
|
1939
|
+
const result = runStatusCommand(command.workspaceRoot);
|
|
1940
|
+
if (command.json) {
|
|
1941
|
+
process.stdout.write(formatJsonResult(result.data));
|
|
1942
|
+
} else {
|
|
1943
|
+
process.stdout.write(formatStatusHuman(result));
|
|
1944
|
+
}
|
|
1945
|
+
return result.exitCode;
|
|
1946
|
+
}
|
|
1947
|
+
case "changed": {
|
|
1948
|
+
const result = runChangedCommand(command.workspaceRoot, {
|
|
1949
|
+
authoredOnly: command.authoredOnly,
|
|
1950
|
+
});
|
|
1951
|
+
if (command.json) {
|
|
1952
|
+
process.stdout.write(formatJsonResult(result.data));
|
|
1953
|
+
} else {
|
|
1954
|
+
process.stdout.write(formatChangedHuman(result));
|
|
1955
|
+
}
|
|
1956
|
+
return result.exitCode;
|
|
1957
|
+
}
|
|
1958
|
+
case "diff": {
|
|
1959
|
+
const changed = runChangedCommand(command.workspaceRoot);
|
|
1960
|
+
const diffPlan = changed.data.diffPlan as { authoredDiffCommand: string; generatedDiffCommand: string; fullDiffCommand: string };
|
|
1961
|
+
const commandText = command.target === "generated"
|
|
1962
|
+
? diffPlan.generatedDiffCommand
|
|
1963
|
+
: command.target === "full"
|
|
1964
|
+
? diffPlan.fullDiffCommand
|
|
1965
|
+
: diffPlan.authoredDiffCommand;
|
|
1966
|
+
if (command.json) {
|
|
1967
|
+
process.stdout.write(formatJsonResult({
|
|
1968
|
+
schemaVersion: "0.1.0",
|
|
1969
|
+
ok: changed.ok,
|
|
1970
|
+
target: command.target,
|
|
1971
|
+
command: commandText,
|
|
1972
|
+
exitCode: changed.exitCode,
|
|
1973
|
+
}));
|
|
1974
|
+
return changed.exitCode;
|
|
1975
|
+
}
|
|
1976
|
+
const result = spawnSync(commandText, {
|
|
1977
|
+
cwd: command.workspaceRoot,
|
|
1978
|
+
shell: true,
|
|
1979
|
+
stdio: "inherit",
|
|
1980
|
+
windowsHide: true,
|
|
1981
|
+
});
|
|
1982
|
+
return result.status === 0 ? 0 : 1;
|
|
1983
|
+
}
|
|
1984
|
+
case "handoff": {
|
|
1985
|
+
const result = await runHandoffCommand(command);
|
|
1986
|
+
process.stdout.write(command.json ? formatHandoffJson(result) : formatHandoffHuman(result));
|
|
1987
|
+
return result.exitCode;
|
|
1988
|
+
}
|
|
1989
|
+
case "studio": {
|
|
1990
|
+
if (command.subcommand === "bridge" && !command.once && !command.dryRun) {
|
|
1991
|
+
return runStudioBridgeLoop(command, (result) => {
|
|
1992
|
+
process.stdout.write(command.json ? formatStudioBridgeEventJson(result) : formatStudioBridgeHuman(result));
|
|
1993
|
+
});
|
|
1994
|
+
}
|
|
1995
|
+
if (command.subcommand === "watch" && !command.once && !command.dryRun) {
|
|
1996
|
+
return runStudioWatchLoop(command, (result) => {
|
|
1997
|
+
process.stdout.write(command.json ? formatStudioWatchJson(result) : formatStudioWatchHuman(result));
|
|
1998
|
+
});
|
|
1999
|
+
}
|
|
2000
|
+
const result = command.subcommand === "snapshot"
|
|
2001
|
+
? await runStudioSnapshotCommand(command)
|
|
2002
|
+
: command.subcommand === "watch"
|
|
2003
|
+
? await runStudioWatchCommand(command)
|
|
2004
|
+
: command.subcommand === "bridge"
|
|
2005
|
+
? await runStudioBridgeCommand(command)
|
|
2006
|
+
: command.subcommand === "codex-server"
|
|
2007
|
+
? await runStudioCodexServerCommand(command)
|
|
2008
|
+
: command.subcommand === "doctor"
|
|
2009
|
+
? await runStudioDoctorCommand(command)
|
|
2010
|
+
: command.subcommand === "open"
|
|
2011
|
+
? await runStudioOpenCommand(command)
|
|
2012
|
+
: await runStudioAttachCommand(command);
|
|
2013
|
+
process.stdout.write(
|
|
2014
|
+
command.json
|
|
2015
|
+
? command.subcommand === "snapshot"
|
|
2016
|
+
? formatStudioSnapshotJson(result as Awaited<ReturnType<typeof runStudioSnapshotCommand>>)
|
|
2017
|
+
: command.subcommand === "watch"
|
|
2018
|
+
? formatStudioWatchJson(result as Awaited<ReturnType<typeof runStudioWatchCommand>>)
|
|
2019
|
+
: command.subcommand === "bridge"
|
|
2020
|
+
? formatStudioBridgeJson(result as Awaited<ReturnType<typeof runStudioBridgeCommand>>)
|
|
2021
|
+
: command.subcommand === "codex-server"
|
|
2022
|
+
? formatStudioCodexServerJson(result as Awaited<ReturnType<typeof runStudioCodexServerCommand>>)
|
|
2023
|
+
: command.subcommand === "doctor"
|
|
2024
|
+
? formatStudioDoctorJson(result as Awaited<ReturnType<typeof runStudioDoctorCommand>>)
|
|
2025
|
+
: command.subcommand === "open"
|
|
2026
|
+
? formatStudioOpenJson(result as Awaited<ReturnType<typeof runStudioOpenCommand>>)
|
|
2027
|
+
: formatStudioAttachJson(result as Awaited<ReturnType<typeof runStudioAttachCommand>>)
|
|
2028
|
+
: command.subcommand === "snapshot"
|
|
2029
|
+
? formatStudioSnapshotHuman(result as Awaited<ReturnType<typeof runStudioSnapshotCommand>>)
|
|
2030
|
+
: command.subcommand === "watch"
|
|
2031
|
+
? formatStudioWatchHuman(result as Awaited<ReturnType<typeof runStudioWatchCommand>>)
|
|
2032
|
+
: command.subcommand === "bridge"
|
|
2033
|
+
? formatStudioBridgeHuman(result as Awaited<ReturnType<typeof runStudioBridgeCommand>>)
|
|
2034
|
+
: command.subcommand === "codex-server"
|
|
2035
|
+
? formatStudioCodexServerHuman(result as Awaited<ReturnType<typeof runStudioCodexServerCommand>>)
|
|
2036
|
+
: command.subcommand === "doctor"
|
|
2037
|
+
? formatStudioDoctorHuman(result as Awaited<ReturnType<typeof runStudioDoctorCommand>>)
|
|
2038
|
+
: command.subcommand === "open"
|
|
2039
|
+
? formatStudioOpenHuman(result as Awaited<ReturnType<typeof runStudioOpenCommand>>)
|
|
2040
|
+
: formatStudioAttachHuman(result as Awaited<ReturnType<typeof runStudioAttachCommand>>),
|
|
2041
|
+
);
|
|
2042
|
+
return result.exitCode;
|
|
2043
|
+
}
|
|
800
2044
|
case "inspect": {
|
|
801
2045
|
const result = await runInspectCommand(
|
|
802
2046
|
command.target,
|
|
803
2047
|
process.cwd(),
|
|
2048
|
+
{ full: command.full, brief: command.brief },
|
|
804
2049
|
);
|
|
805
2050
|
if (command.json) {
|
|
806
2051
|
process.stdout.write(formatJsonResult(buildInspectJson(result)));
|
|
@@ -816,7 +2061,7 @@ export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
|
816
2061
|
strictSecrets: command.strictSecrets,
|
|
817
2062
|
});
|
|
818
2063
|
if (command.json) {
|
|
819
|
-
process.stdout.write(formatJsonResult(
|
|
2064
|
+
process.stdout.write(formatJsonResult(buildCheckJson(result)));
|
|
820
2065
|
} else {
|
|
821
2066
|
writeHumanGenerate(result);
|
|
822
2067
|
}
|
|
@@ -838,6 +2083,32 @@ export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
|
838
2083
|
);
|
|
839
2084
|
|
|
840
2085
|
if (command.queryMode && command.name) {
|
|
2086
|
+
const external = resolveExternalQualifiedName(command.workspaceRoot, command.name, "query");
|
|
2087
|
+
if (external) {
|
|
2088
|
+
const run = await runExternalEntry(command.workspaceRoot, {
|
|
2089
|
+
kind: "query",
|
|
2090
|
+
serviceName: external.serviceName,
|
|
2091
|
+
entryName: external.entryName,
|
|
2092
|
+
args: command.args,
|
|
2093
|
+
auth: resolveAuthFromCli({
|
|
2094
|
+
userId: command.userId,
|
|
2095
|
+
tenantId: command.tenantId,
|
|
2096
|
+
role: command.role,
|
|
2097
|
+
}),
|
|
2098
|
+
});
|
|
2099
|
+
const payload = { run };
|
|
2100
|
+
if (command.json) {
|
|
2101
|
+
process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
|
|
2102
|
+
} else {
|
|
2103
|
+
process.stdout.write(
|
|
2104
|
+
run.ok
|
|
2105
|
+
? `${JSON.stringify(run.result, null, 2)}\n`
|
|
2106
|
+
: `${run.diagnostics.map((diagnostic) => `error ${diagnostic.code}: ${diagnostic.message}`).join("\n")}\n`,
|
|
2107
|
+
);
|
|
2108
|
+
}
|
|
2109
|
+
return run.exitCode;
|
|
2110
|
+
}
|
|
2111
|
+
|
|
841
2112
|
const tableMap = readGeneratedJson<{ tableMap: Record<string, import("../compiler/data-graph/sql/serialize.ts").TableMapEntry> }>(
|
|
842
2113
|
command.workspaceRoot,
|
|
843
2114
|
`${GENERATED_DIR}/db.json`,
|
|
@@ -876,6 +2147,7 @@ export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
|
876
2147
|
userId: command.userId,
|
|
877
2148
|
tenantId: command.tenantId,
|
|
878
2149
|
role: command.role,
|
|
2150
|
+
args: command.args,
|
|
879
2151
|
workspaceRoot: command.workspaceRoot,
|
|
880
2152
|
});
|
|
881
2153
|
|
|
@@ -913,6 +2185,7 @@ export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
|
913
2185
|
webPort: command.webPort,
|
|
914
2186
|
telemetry: command.telemetry,
|
|
915
2187
|
envFile: command.envFile,
|
|
2188
|
+
skipStartupConsole: command.skipStartupConsole,
|
|
916
2189
|
});
|
|
917
2190
|
return result.exitCode;
|
|
918
2191
|
}
|
|
@@ -1111,6 +2384,11 @@ export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
|
1111
2384
|
model: command.model,
|
|
1112
2385
|
prompt: command.prompt,
|
|
1113
2386
|
mock: command.mock,
|
|
2387
|
+
modelLevel: command.modelLevel,
|
|
2388
|
+
live: command.live,
|
|
2389
|
+
traceId: command.traceId,
|
|
2390
|
+
db: command.db,
|
|
2391
|
+
databaseUrl: command.databaseUrl,
|
|
1114
2392
|
});
|
|
1115
2393
|
|
|
1116
2394
|
if (command.json) {
|
|
@@ -1126,5 +2404,5 @@ export async function executeCommand(command: ForgeCommand): Promise<number> {
|
|
|
1126
2404
|
}
|
|
1127
2405
|
}
|
|
1128
2406
|
|
|
1129
|
-
export { runVerifyCommand };
|
|
2407
|
+
export { runChangedCommand, runVerifyCommand };
|
|
1130
2408
|
export type { VerifyOptions, VerifyResult };
|