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
package/src/forge/dev/types.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { DevRoute } from "../compiler/types/dev-manifest.ts";
|
|
2
2
|
import type { DbAdapter } from "../runtime/db/adapter.ts";
|
|
3
|
+
import type { AmbientDeltaRecorder } from "../delta/recorder.ts";
|
|
4
|
+
import type { Diagnostic } from "../compiler/types/diagnostic.ts";
|
|
3
5
|
|
|
4
|
-
export type DevDbMode = "pglite" | "postgres" | "none";
|
|
6
|
+
export type DevDbMode = "memory" | "pglite" | "postgres" | "none";
|
|
5
7
|
|
|
6
8
|
export interface DevServerOptions {
|
|
7
9
|
workspaceRoot: string;
|
|
@@ -18,6 +20,7 @@ export interface DevServerOptions {
|
|
|
18
20
|
mode?: "dev" | "serve";
|
|
19
21
|
allowDevAuth?: boolean;
|
|
20
22
|
webUrl?: string;
|
|
23
|
+
deltaRecorder?: AmbientDeltaRecorder;
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
export interface DevServerDbState {
|
|
@@ -41,9 +44,20 @@ export interface DevServerHandle {
|
|
|
41
44
|
routes: DevRoute[];
|
|
42
45
|
state: DevServerState;
|
|
43
46
|
outboxWorker?: DevServerState["outboxWorker"];
|
|
47
|
+
reload: (reason?: string) => Promise<DevServerReloadResult>;
|
|
44
48
|
stop: () => void;
|
|
45
49
|
}
|
|
46
50
|
|
|
51
|
+
export interface DevServerReloadResult {
|
|
52
|
+
ok: boolean;
|
|
53
|
+
reason: string;
|
|
54
|
+
migrated: boolean;
|
|
55
|
+
routes: number;
|
|
56
|
+
runtimeEntries: number;
|
|
57
|
+
worker: "running" | "stopped";
|
|
58
|
+
diagnostics: Diagnostic[];
|
|
59
|
+
}
|
|
60
|
+
|
|
47
61
|
export interface DevWatchHandle {
|
|
48
62
|
stop: () => void;
|
|
49
63
|
}
|
package/src/forge/dev/watch.ts
CHANGED
|
@@ -21,28 +21,38 @@ export function shouldSkipWatchPath(absolutePath: string): boolean {
|
|
|
21
21
|
|
|
22
22
|
export function createDebouncedCallback(
|
|
23
23
|
debounceMs: number,
|
|
24
|
-
callback: (changedCount: number) => void | Promise<void>,
|
|
25
|
-
): (
|
|
24
|
+
callback: (changedCount: number, changedPaths: string[]) => void | Promise<void>,
|
|
25
|
+
): (incrementOrPath?: number | string) => void {
|
|
26
26
|
let pendingChanges = 0;
|
|
27
|
+
const pendingPaths = new Set<string>();
|
|
27
28
|
let timer: ReturnType<typeof setTimeout> | null = null;
|
|
28
29
|
|
|
29
|
-
return (
|
|
30
|
-
|
|
30
|
+
return (incrementOrPath) => {
|
|
31
|
+
if (typeof incrementOrPath === "number") {
|
|
32
|
+
pendingChanges += incrementOrPath;
|
|
33
|
+
} else {
|
|
34
|
+
pendingChanges += 1;
|
|
35
|
+
}
|
|
36
|
+
if (typeof incrementOrPath === "string") {
|
|
37
|
+
pendingPaths.add(incrementOrPath);
|
|
38
|
+
}
|
|
31
39
|
if (timer !== null) {
|
|
32
40
|
clearTimeout(timer);
|
|
33
41
|
}
|
|
34
42
|
timer = setTimeout(async () => {
|
|
35
43
|
const count = pendingChanges;
|
|
44
|
+
const paths = [...pendingPaths].sort();
|
|
36
45
|
pendingChanges = 0;
|
|
46
|
+
pendingPaths.clear();
|
|
37
47
|
timer = null;
|
|
38
|
-
await callback(count);
|
|
48
|
+
await callback(count, paths);
|
|
39
49
|
}, debounceMs);
|
|
40
50
|
};
|
|
41
51
|
}
|
|
42
52
|
|
|
43
53
|
export function startDevWatch(
|
|
44
54
|
workspaceRoot: string,
|
|
45
|
-
onRegenerate: (changedCount: number) => void | Promise<void>,
|
|
55
|
+
onRegenerate: (changedCount: number, changedPaths: string[]) => void | Promise<void>,
|
|
46
56
|
): DevWatchHandle {
|
|
47
57
|
const roots = getSourceRoots(workspaceRoot);
|
|
48
58
|
const watchers: FSWatcher[] = [];
|
|
@@ -71,7 +81,7 @@ export function startDevWatch(
|
|
|
71
81
|
return;
|
|
72
82
|
}
|
|
73
83
|
|
|
74
|
-
debounced();
|
|
84
|
+
debounced(relativePath);
|
|
75
85
|
},
|
|
76
86
|
);
|
|
77
87
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { nodeFileSystem } from "../compiler/fs/index.ts";
|
|
2
|
-
import { join } from "node:path";
|
|
2
|
+
import { basename, join } from "node:path";
|
|
3
3
|
import { buildAppGraph } from "../compiler/app-graph/build.ts";
|
|
4
4
|
import { classify } from "../compiler/classifier/classify.ts";
|
|
5
5
|
import { buildRuntimeMatrix } from "../compiler/classifier/runtime-matrix.ts";
|
|
@@ -26,8 +26,12 @@ import { runImpactCommand } from "../impact/index.ts";
|
|
|
26
26
|
import type { TestRunRecord } from "../impact/types.ts";
|
|
27
27
|
import { loadSecretRegistry } from "../runtime/secrets/check.ts";
|
|
28
28
|
import type { UiRunReport } from "../ui/types.ts";
|
|
29
|
+
import { buildDiffPlanFromChangeSummary, categorizeFiles, summarizeChangeTypes } from "../workspace/change-summary.ts";
|
|
30
|
+
import { forgeCliCommandForWorkspace, forgeCliCommandsForWorkspace } from "../workspace/forge-cli.ts";
|
|
29
31
|
import type {
|
|
30
32
|
DevConsoleCycle,
|
|
33
|
+
DevConsoleAgentContext,
|
|
34
|
+
DevConsoleGeneratedSummary,
|
|
31
35
|
DevConsoleNextAction,
|
|
32
36
|
DevConsoleOptions,
|
|
33
37
|
DevConsolePhase,
|
|
@@ -117,17 +121,30 @@ function skippedPhase(
|
|
|
117
121
|
};
|
|
118
122
|
}
|
|
119
123
|
|
|
124
|
+
function compactFileList(files: string[], sampleSize = 12): {
|
|
125
|
+
count: number;
|
|
126
|
+
sample: string[];
|
|
127
|
+
hidden: number;
|
|
128
|
+
} {
|
|
129
|
+
return {
|
|
130
|
+
count: files.length,
|
|
131
|
+
sample: files.slice(0, sampleSize),
|
|
132
|
+
hidden: Math.max(0, files.length - sampleSize),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
120
136
|
async function runGeneratedPhase(workspaceRoot: string): Promise<DevConsolePhase> {
|
|
121
137
|
const start = performance.now();
|
|
122
138
|
const result = await runGenerate({
|
|
123
139
|
workspaceRoot,
|
|
124
|
-
check:
|
|
140
|
+
check: false,
|
|
125
141
|
dryRun: false,
|
|
126
142
|
json: false,
|
|
127
143
|
concurrency: 4,
|
|
128
144
|
});
|
|
129
145
|
const diagnostics = [...result.errors, ...result.warnings];
|
|
130
146
|
const durationMs = msSince(start);
|
|
147
|
+
const changed = compactFileList(result.changed);
|
|
131
148
|
return {
|
|
132
149
|
name: "generated",
|
|
133
150
|
ok: result.exitCode === 0,
|
|
@@ -135,11 +152,18 @@ async function runGeneratedPhase(workspaceRoot: string): Promise<DevConsolePhase
|
|
|
135
152
|
diagnostics,
|
|
136
153
|
durationMs,
|
|
137
154
|
details: {
|
|
138
|
-
changed:
|
|
155
|
+
changed: changed.count,
|
|
156
|
+
sampleChanged: changed.sample,
|
|
157
|
+
hiddenChanged: changed.hidden,
|
|
139
158
|
unchangedCount: result.unchanged.length,
|
|
159
|
+
fullCommand: forgeCliCommandForWorkspace(workspaceRoot, "forge generate --json"),
|
|
140
160
|
...(result.cache ? { cache: result.cache } : {}),
|
|
141
161
|
},
|
|
142
|
-
message: result.exitCode === 0
|
|
162
|
+
message: result.exitCode === 0
|
|
163
|
+
? result.changed.length > 0
|
|
164
|
+
? `regenerated ${result.changed.length} generated artifacts`
|
|
165
|
+
: "generated artifacts are up to date"
|
|
166
|
+
: "generated artifacts could not be regenerated",
|
|
143
167
|
};
|
|
144
168
|
}
|
|
145
169
|
|
|
@@ -179,6 +203,8 @@ function requiredGeneratedArtifacts(workspaceRoot: string): Array<{ name: string
|
|
|
179
203
|
{ name: "agents-md", path: "AGENTS.md", ok: nodeFileSystem.exists(join(workspaceRoot, "AGENTS.md")) },
|
|
180
204
|
{ name: "forge-lock", path: "forge.lock", ok: nodeFileSystem.exists(join(workspaceRoot, "forge.lock")) },
|
|
181
205
|
{ name: "agent-contract", path: `${GENERATED_DIR}/agentContract.json`, ok: nodeFileSystem.exists(join(workspaceRoot, GENERATED_DIR, "agentContract.json")) },
|
|
206
|
+
{ name: "agent-quickstart", path: `${GENERATED_DIR}/agentQuickstart.md`, ok: nodeFileSystem.exists(join(workspaceRoot, GENERATED_DIR, "agentQuickstart.md")) },
|
|
207
|
+
{ name: "agent-cair-guide", path: `${GENERATED_DIR}/agentCairGuide.md`, ok: nodeFileSystem.exists(join(workspaceRoot, GENERATED_DIR, "agentCairGuide.md")) },
|
|
182
208
|
{ name: "capability-map", path: `${GENERATED_DIR}/capabilityMap.json`, ok: nodeFileSystem.exists(join(workspaceRoot, GENERATED_DIR, "capabilityMap.json")) },
|
|
183
209
|
{ name: "runtime-matrix", path: `${GENERATED_DIR}/runtimeMatrix.json`, ok: nodeFileSystem.exists(join(workspaceRoot, GENERATED_DIR, "runtimeMatrix.json")) },
|
|
184
210
|
{ name: "data-graph", path: `${GENERATED_DIR}/dataGraph.json`, ok: nodeFileSystem.exists(join(workspaceRoot, GENERATED_DIR, "dataGraph.json")) },
|
|
@@ -260,7 +286,21 @@ function runDoctorPhase(workspaceRoot: string): DevConsolePhase {
|
|
|
260
286
|
);
|
|
261
287
|
}
|
|
262
288
|
|
|
263
|
-
function
|
|
289
|
+
function withRuntimeFrontendUrls(
|
|
290
|
+
summary: FrontendSummary,
|
|
291
|
+
options: { apiUrl?: string; webUrl?: string },
|
|
292
|
+
): FrontendSummary {
|
|
293
|
+
return {
|
|
294
|
+
...summary,
|
|
295
|
+
...(options.apiUrl ? { apiUrl: options.apiUrl } : {}),
|
|
296
|
+
...(options.webUrl ? { devUrl: options.webUrl } : {}),
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function runFrontendPhase(
|
|
301
|
+
workspaceRoot: string,
|
|
302
|
+
options: { apiUrl?: string; webUrl?: string } = {},
|
|
303
|
+
): DevConsolePhase {
|
|
264
304
|
const start = performance.now();
|
|
265
305
|
const frontend = readJson<FrontendGraph>(workspaceRoot, `${GENERATED_DIR}/frontendGraph.json`);
|
|
266
306
|
if (!frontend) {
|
|
@@ -274,7 +314,7 @@ function runFrontendPhase(workspaceRoot: string): DevConsolePhase {
|
|
|
274
314
|
};
|
|
275
315
|
}
|
|
276
316
|
|
|
277
|
-
const summary: FrontendSummary = {
|
|
317
|
+
const summary: FrontendSummary = withRuntimeFrontendUrls({
|
|
278
318
|
present: frontend.present,
|
|
279
319
|
framework: frontend.framework,
|
|
280
320
|
routes: frontend.routes.map((route) => route.path),
|
|
@@ -282,7 +322,7 @@ function runFrontendPhase(workspaceRoot: string): DevConsolePhase {
|
|
|
282
322
|
bridgeFiles: frontend.bridgeFiles,
|
|
283
323
|
apiUrl: frontend.webManifest.urls.api,
|
|
284
324
|
...(frontend.dev ? { devUrl: frontend.dev.url, apiUrlEnv: frontend.dev.apiUrlEnv } : {}),
|
|
285
|
-
};
|
|
325
|
+
}, options);
|
|
286
326
|
const diagnostics = frontend.diagnostics ?? [];
|
|
287
327
|
const message = frontend.present
|
|
288
328
|
? `frontend ${frontend.framework} with ${frontend.routes.length} routes and ${frontend.clientBindings.length} bindings`
|
|
@@ -305,23 +345,102 @@ function defaultFrontendSummary(workspaceRoot: string): FrontendSummary {
|
|
|
305
345
|
};
|
|
306
346
|
}
|
|
307
347
|
|
|
348
|
+
function nextPreviewPort(webUrl?: string): number {
|
|
349
|
+
if (!webUrl) {
|
|
350
|
+
return 5174;
|
|
351
|
+
}
|
|
352
|
+
try {
|
|
353
|
+
const parsed = new URL(webUrl);
|
|
354
|
+
const port = parsed.port ? Number(parsed.port) : parsed.protocol === "https:" ? 443 : 80;
|
|
355
|
+
return Number.isFinite(port) && port > 0 ? port + 1 : 5174;
|
|
356
|
+
} catch {
|
|
357
|
+
return 5174;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function isForgeStudioWorkspace(workspaceRoot: string): boolean {
|
|
362
|
+
return basename(workspaceRoot).toLowerCase() === "forge-studio";
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function previewSummaryFor(input: {
|
|
366
|
+
workspaceRoot: string;
|
|
367
|
+
webUrl?: string;
|
|
368
|
+
}): DevConsoleSummary["preview"] {
|
|
369
|
+
if (input.webUrl && !isForgeStudioWorkspace(input.workspaceRoot)) {
|
|
370
|
+
const parsed = new URL(input.webUrl);
|
|
371
|
+
const targetAppPort = parsed.port ? Number(parsed.port) : parsed.protocol === "https:" ? 443 : 80;
|
|
372
|
+
return {
|
|
373
|
+
targetAppUrl: input.webUrl,
|
|
374
|
+
targetAppPort,
|
|
375
|
+
isStudioSelfPreview: false,
|
|
376
|
+
note: `Web app preview is running at ${input.webUrl}.`,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const targetAppPort = nextPreviewPort(input.webUrl);
|
|
381
|
+
const targetAppUrl = `http://127.0.0.1:${targetAppPort}`;
|
|
382
|
+
const isStudioSelfPreview = Boolean(input.webUrl && input.webUrl === targetAppUrl);
|
|
383
|
+
return {
|
|
384
|
+
...(input.webUrl ? { studioUrl: input.webUrl } : {}),
|
|
385
|
+
targetAppUrl,
|
|
386
|
+
targetAppPort,
|
|
387
|
+
isStudioSelfPreview,
|
|
388
|
+
note: input.webUrl
|
|
389
|
+
? `Use ${targetAppUrl} for the app being built when ${input.webUrl} is Forge Studio itself.`
|
|
390
|
+
: `No web app was detected; ${targetAppUrl} is the default target app preview URL for Studio attach flows.`,
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function buildGeneratedSummary(workspaceRoot: string, phaseItem: DevConsolePhase | undefined): DevConsoleGeneratedSummary {
|
|
395
|
+
const changedFiles = Number(phaseItem?.details?.changed ?? 0);
|
|
396
|
+
const sampleChanged = Array.isArray(phaseItem?.details?.sampleChanged)
|
|
397
|
+
? phaseItem.details.sampleChanged.filter((item): item is string => typeof item === "string")
|
|
398
|
+
: [];
|
|
399
|
+
const hiddenChanged = Number(phaseItem?.details?.hiddenChanged ?? 0);
|
|
400
|
+
return {
|
|
401
|
+
ok: phaseItem?.ok === true,
|
|
402
|
+
state: phaseItem?.ok === true
|
|
403
|
+
? changedFiles > 0 ? "regenerated" : "fresh"
|
|
404
|
+
: "stale-risk",
|
|
405
|
+
changedFiles,
|
|
406
|
+
sampleChanged,
|
|
407
|
+
hiddenChanged,
|
|
408
|
+
message: phaseItem?.message ?? "generated phase did not report a message",
|
|
409
|
+
command: forgeCliCommandForWorkspace(workspaceRoot, "forge generate"),
|
|
410
|
+
checkCommand: forgeCliCommandForWorkspace(workspaceRoot, "forge generate --check --json"),
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
308
414
|
function buildDevSummary(input: {
|
|
309
415
|
workspaceRoot: string;
|
|
310
416
|
ok: boolean;
|
|
311
417
|
phases: DevConsolePhase[];
|
|
312
418
|
diagnostics: Diagnostic[];
|
|
313
419
|
nextActions: DevConsoleNextAction[];
|
|
420
|
+
apiUrl?: string;
|
|
421
|
+
webUrl?: string;
|
|
314
422
|
}): DevConsoleSummary {
|
|
315
423
|
const frontendPhase = input.phases.find((item) => item.name === "frontend");
|
|
316
|
-
const
|
|
424
|
+
const frontendBase =
|
|
317
425
|
(frontendPhase?.details?.summary as FrontendSummary | undefined) ??
|
|
318
426
|
defaultFrontendSummary(input.workspaceRoot);
|
|
427
|
+
const frontend = withRuntimeFrontendUrls(frontendBase, {
|
|
428
|
+
...(input.apiUrl ? { apiUrl: input.apiUrl } : {}),
|
|
429
|
+
...(input.webUrl ? { webUrl: input.webUrl } : {}),
|
|
430
|
+
});
|
|
319
431
|
const capabilityMap = readJson<AgentCapabilityMap>(
|
|
320
432
|
input.workspaceRoot,
|
|
321
433
|
`${GENERATED_DIR}/capabilityMap.json`,
|
|
322
434
|
);
|
|
323
435
|
const warnings = input.diagnostics.filter((diagnostic) => diagnostic.severity === "warning").length;
|
|
324
436
|
const errors = input.diagnostics.filter((diagnostic) => diagnostic.severity === "error").length;
|
|
437
|
+
const apiUrl = input.apiUrl ?? frontend.apiUrl ?? "http://127.0.0.1:3765";
|
|
438
|
+
const webUrl = input.webUrl ?? frontend.devUrl;
|
|
439
|
+
const generated = buildGeneratedSummary(input.workspaceRoot, input.phases.find((item) => item.name === "generated"));
|
|
440
|
+
const preview = previewSummaryFor({
|
|
441
|
+
workspaceRoot: input.workspaceRoot,
|
|
442
|
+
...(webUrl ? { webUrl } : {}),
|
|
443
|
+
});
|
|
325
444
|
return {
|
|
326
445
|
project: {
|
|
327
446
|
root: input.workspaceRoot,
|
|
@@ -333,9 +452,12 @@ function buildDevSummary(input: {
|
|
|
333
452
|
skipped: input.phases.filter((item) => item.status === "skipped").length,
|
|
334
453
|
},
|
|
335
454
|
urls: {
|
|
336
|
-
api:
|
|
337
|
-
...(
|
|
455
|
+
api: apiUrl,
|
|
456
|
+
...(webUrl ? { web: webUrl } : {}),
|
|
457
|
+
suggestedPreview: preview.targetAppUrl,
|
|
338
458
|
},
|
|
459
|
+
preview,
|
|
460
|
+
generated,
|
|
339
461
|
frontend,
|
|
340
462
|
capabilities: capabilityMap?.summary ?? {
|
|
341
463
|
covered: 0,
|
|
@@ -343,6 +465,12 @@ function buildDevSummary(input: {
|
|
|
343
465
|
frontendOnly: 0,
|
|
344
466
|
warnings: 0,
|
|
345
467
|
},
|
|
468
|
+
agentContext: buildAgentContext({
|
|
469
|
+
workspaceRoot: input.workspaceRoot,
|
|
470
|
+
phases: input.phases,
|
|
471
|
+
diagnostics: input.diagnostics,
|
|
472
|
+
nextActions: input.nextActions,
|
|
473
|
+
}),
|
|
346
474
|
...(input.nextActions[0] ? { primaryAction: input.nextActions[0] } : {}),
|
|
347
475
|
};
|
|
348
476
|
}
|
|
@@ -370,18 +498,28 @@ function runImpactPhase(workspaceRoot: string): DevConsolePhase {
|
|
|
370
498
|
}
|
|
371
499
|
const report = result.report;
|
|
372
500
|
const summary: ImpactSummary | undefined = report
|
|
373
|
-
? {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
501
|
+
? (() => {
|
|
502
|
+
const changeSummary = categorizeFiles(report.changedFiles);
|
|
503
|
+
return {
|
|
504
|
+
changedFiles: report.changedFiles.length,
|
|
505
|
+
sampleChangedFiles: report.changedFiles.slice(0, 12),
|
|
506
|
+
hiddenChangedFiles: Math.max(0, report.changedFiles.length - 12),
|
|
507
|
+
changeSummary,
|
|
508
|
+
risk: report.risk.level,
|
|
509
|
+
recommendedChecks: report.recommendedChecks,
|
|
510
|
+
fullCommand: "forge impact --changed --json",
|
|
511
|
+
};
|
|
512
|
+
})()
|
|
378
513
|
: undefined;
|
|
514
|
+
const changeTypes = summary ? summarizeChangeTypes(summary.changeSummary) : "";
|
|
379
515
|
return phase(
|
|
380
516
|
"impact",
|
|
381
517
|
result.diagnostics,
|
|
382
518
|
msSince(start),
|
|
383
519
|
summary ? { summary } : undefined,
|
|
384
|
-
summary && summary.changedFiles
|
|
520
|
+
summary && summary.changedFiles > 0
|
|
521
|
+
? `${summary.changedFiles} changed files detected${changeTypes ? `: ${changeTypes}` : ""}`
|
|
522
|
+
: "no changed files detected",
|
|
385
523
|
);
|
|
386
524
|
}
|
|
387
525
|
|
|
@@ -469,7 +607,7 @@ function uniqueActions(actions: DevConsoleNextAction[]): DevConsoleNextAction[]
|
|
|
469
607
|
return result;
|
|
470
608
|
}
|
|
471
609
|
|
|
472
|
-
function nextActionsFromPhases(phases: DevConsolePhase[]): DevConsoleNextAction[] {
|
|
610
|
+
function nextActionsFromPhases(workspaceRoot: string, phases: DevConsolePhase[]): DevConsoleNextAction[] {
|
|
473
611
|
const actions: DevConsoleNextAction[] = [];
|
|
474
612
|
const diagnostics = phases.flatMap((item) => item.diagnostics);
|
|
475
613
|
if (diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
|
|
@@ -512,7 +650,12 @@ function nextActionsFromPhases(phases: DevConsolePhase[]): DevConsoleNextAction[
|
|
|
512
650
|
|
|
513
651
|
const impact = phases.find((item) => item.name === "impact");
|
|
514
652
|
const summary = impact?.details?.summary as ImpactSummary | undefined;
|
|
515
|
-
if (summary && summary.changedFiles
|
|
653
|
+
if (summary && summary.changedFiles > 0) {
|
|
654
|
+
actions.push({
|
|
655
|
+
command: "forge changed --json",
|
|
656
|
+
reason: "changed files were detected; inspect grouped human and generated changes first",
|
|
657
|
+
confidence: "high",
|
|
658
|
+
});
|
|
516
659
|
actions.push({
|
|
517
660
|
command: "forge do verify --json",
|
|
518
661
|
reason: "changed files were detected; use the guided verification path",
|
|
@@ -538,7 +681,60 @@ function nextActionsFromPhases(phases: DevConsolePhase[]): DevConsoleNextAction[
|
|
|
538
681
|
});
|
|
539
682
|
}
|
|
540
683
|
|
|
541
|
-
return uniqueActions(actions).slice(0, 12)
|
|
684
|
+
return uniqueActions(actions).slice(0, 12).map((action) => ({
|
|
685
|
+
...action,
|
|
686
|
+
command: forgeCliCommandForWorkspace(workspaceRoot, action.command),
|
|
687
|
+
}));
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
function phaseDetails<T>(phases: DevConsolePhase[], name: DevConsolePhase["name"], key: string): T | undefined {
|
|
691
|
+
return phases.find((item) => item.name === name)?.details?.[key] as T | undefined;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
function buildAgentContext(input: {
|
|
695
|
+
workspaceRoot: string;
|
|
696
|
+
phases: DevConsolePhase[];
|
|
697
|
+
diagnostics: Diagnostic[];
|
|
698
|
+
nextActions: DevConsoleNextAction[];
|
|
699
|
+
}): DevConsoleAgentContext {
|
|
700
|
+
const generated = input.phases.find((item) => item.name === "generated");
|
|
701
|
+
const frontend = phaseDetails<FrontendSummary>(input.phases, "frontend", "summary");
|
|
702
|
+
const impact = phaseDetails<ImpactSummary>(input.phases, "impact", "summary");
|
|
703
|
+
const errorDiagnostics = input.diagnostics.filter((diagnostic) => diagnostic.severity === "error");
|
|
704
|
+
const warningDiagnostics = input.diagnostics.filter((diagnostic) => diagnostic.severity === "warning");
|
|
705
|
+
const generatedChangedFiles = Number(generated?.details?.changed ?? 0);
|
|
706
|
+
const suggestedReadFiles = [
|
|
707
|
+
"AGENTS.md",
|
|
708
|
+
"src/forge/_generated/agentContract.json",
|
|
709
|
+
"src/forge/_generated/appMap.md",
|
|
710
|
+
"src/forge/_generated/runtimeRules.md",
|
|
711
|
+
"src/forge/_generated/operationPlaybooks.md",
|
|
712
|
+
...(frontend?.present ? ["src/forge/_generated/frontendGraph.json"] : []),
|
|
713
|
+
...input.diagnostics.flatMap((diagnostic) => diagnostic.docs ?? []),
|
|
714
|
+
...input.diagnostics.flatMap((diagnostic) => diagnostic.file ? [diagnostic.file] : []),
|
|
715
|
+
];
|
|
716
|
+
const fullCommands = forgeCliCommandsForWorkspace(input.workspaceRoot, [
|
|
717
|
+
"forge inspect all --full --json",
|
|
718
|
+
"forge changed --json",
|
|
719
|
+
"forge impact --changed --json",
|
|
720
|
+
"forge generate --json",
|
|
721
|
+
]);
|
|
722
|
+
return {
|
|
723
|
+
safeToEdit: generated?.ok === true && errorDiagnostics.length === 0,
|
|
724
|
+
generatedFresh: generated?.ok === true,
|
|
725
|
+
generatedChanged: generatedChangedFiles > 0,
|
|
726
|
+
generatedChangedFiles,
|
|
727
|
+
frontendReady: frontend?.present ? frontend.bridgeFiles.length > 0 : false,
|
|
728
|
+
changedFiles: impact?.changedFiles ?? 0,
|
|
729
|
+
...(impact?.changeSummary ? { changeSummary: impact.changeSummary } : {}),
|
|
730
|
+
...(impact?.changeSummary ? { diffPlan: buildDiffPlanFromChangeSummary(impact.changeSummary) } : {}),
|
|
731
|
+
blockingIssues: errorDiagnostics.map((diagnostic) => `${diagnostic.code}: ${diagnostic.message}`).slice(0, 8),
|
|
732
|
+
recommendedReadFiles: [...new Set(suggestedReadFiles)].slice(0, 12),
|
|
733
|
+
recommendedCommands: input.nextActions.map((action) => action.command).slice(0, 8),
|
|
734
|
+
useFullCommands: warningDiagnostics.length > 0 || (impact?.hiddenChangedFiles ?? 0) > 0
|
|
735
|
+
? fullCommands
|
|
736
|
+
: fullCommands.slice(0, 1),
|
|
737
|
+
};
|
|
542
738
|
}
|
|
543
739
|
|
|
544
740
|
export async function runDevConsoleCycle(options: DevConsoleOptions): Promise<DevConsoleCycle> {
|
|
@@ -549,7 +745,10 @@ export async function runDevConsoleCycle(options: DevConsoleOptions): Promise<De
|
|
|
549
745
|
phases.push(generated);
|
|
550
746
|
if (generated.ok) {
|
|
551
747
|
phases.push(await runCheckPhase(workspaceRoot, options.strictSecrets ?? false));
|
|
552
|
-
phases.push(runFrontendPhase(workspaceRoot
|
|
748
|
+
phases.push(runFrontendPhase(workspaceRoot, {
|
|
749
|
+
...(options.apiUrl ? { apiUrl: options.apiUrl } : {}),
|
|
750
|
+
...(options.webUrl ? { webUrl: options.webUrl } : {}),
|
|
751
|
+
}));
|
|
553
752
|
} else {
|
|
554
753
|
phases.push(
|
|
555
754
|
skippedPhase(
|
|
@@ -573,13 +772,15 @@ export async function runDevConsoleCycle(options: DevConsoleOptions): Promise<De
|
|
|
573
772
|
|
|
574
773
|
const diagnostics = phases.flatMap((item) => item.diagnostics);
|
|
575
774
|
const ok = phases.every((item) => item.ok);
|
|
576
|
-
const nextActions = nextActionsFromPhases(phases);
|
|
775
|
+
const nextActions = nextActionsFromPhases(workspaceRoot, phases);
|
|
577
776
|
const summary = buildDevSummary({
|
|
578
777
|
workspaceRoot,
|
|
579
778
|
ok,
|
|
580
779
|
phases,
|
|
581
780
|
diagnostics,
|
|
582
781
|
nextActions,
|
|
782
|
+
...(options.apiUrl ? { apiUrl: options.apiUrl } : {}),
|
|
783
|
+
...(options.webUrl ? { webUrl: options.webUrl } : {}),
|
|
583
784
|
});
|
|
584
785
|
return {
|
|
585
786
|
schemaVersion: "0.1.0",
|
|
@@ -603,6 +804,17 @@ export function formatDevConsoleHuman(cycle: DevConsoleCycle): string {
|
|
|
603
804
|
lines.push(`Project: ${cycle.summary.project.root}`);
|
|
604
805
|
lines.push(`API: ${cycle.summary.urls.api}`);
|
|
605
806
|
lines.push(`Web: ${cycle.summary.urls.web ?? "none detected"}`);
|
|
807
|
+
lines.push(`Target preview: ${cycle.summary.preview.targetAppUrl}`);
|
|
808
|
+
lines.push(
|
|
809
|
+
`Generated: ${cycle.summary.generated.state}` +
|
|
810
|
+
(cycle.summary.generated.changedFiles > 0 ? ` (${cycle.summary.generated.changedFiles} changed)` : ""),
|
|
811
|
+
);
|
|
812
|
+
if (cycle.summary.agentContext.diffPlan) {
|
|
813
|
+
lines.push(`Diff focus: ${cycle.summary.agentContext.diffPlan.summary}`);
|
|
814
|
+
}
|
|
815
|
+
if (cycle.summary.preview.isStudioSelfPreview) {
|
|
816
|
+
lines.push("Preview warning: target preview points at the Studio URL");
|
|
817
|
+
}
|
|
606
818
|
lines.push(
|
|
607
819
|
`Frontend: ${cycle.summary.frontend.present ? cycle.summary.frontend.framework : "none"} ` +
|
|
608
820
|
`(${cycle.summary.frontend.routes.length} routes, ${cycle.summary.frontend.bindings.length} bindings)`,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Diagnostic } from "../compiler/types/diagnostic.ts";
|
|
2
2
|
import type { ImpactRiskLevel } from "../impact/types.ts";
|
|
3
|
+
import type { CategorizedFileSummary, DiffPlan } from "../workspace/change-summary.ts";
|
|
3
4
|
|
|
4
5
|
export type DevConsolePhaseName =
|
|
5
6
|
| "generated"
|
|
@@ -39,7 +40,16 @@ export interface DevConsoleSummary {
|
|
|
39
40
|
urls: {
|
|
40
41
|
api: string;
|
|
41
42
|
web?: string;
|
|
43
|
+
suggestedPreview?: string;
|
|
42
44
|
};
|
|
45
|
+
preview: {
|
|
46
|
+
studioUrl?: string;
|
|
47
|
+
targetAppUrl: string;
|
|
48
|
+
targetAppPort: number;
|
|
49
|
+
isStudioSelfPreview: boolean;
|
|
50
|
+
note: string;
|
|
51
|
+
};
|
|
52
|
+
generated: DevConsoleGeneratedSummary;
|
|
43
53
|
frontend: FrontendSummary;
|
|
44
54
|
capabilities: {
|
|
45
55
|
covered: number;
|
|
@@ -47,6 +57,7 @@ export interface DevConsoleSummary {
|
|
|
47
57
|
frontendOnly: number;
|
|
48
58
|
warnings: number;
|
|
49
59
|
};
|
|
60
|
+
agentContext: DevConsoleAgentContext;
|
|
50
61
|
primaryAction?: DevConsoleNextAction;
|
|
51
62
|
}
|
|
52
63
|
|
|
@@ -66,6 +77,8 @@ export interface DevConsoleOptions {
|
|
|
66
77
|
mode: DevConsoleCycle["mode"];
|
|
67
78
|
strictSecrets?: boolean;
|
|
68
79
|
includeImpact?: boolean;
|
|
80
|
+
apiUrl?: string;
|
|
81
|
+
webUrl?: string;
|
|
69
82
|
}
|
|
70
83
|
|
|
71
84
|
export interface LastTestRunSummary {
|
|
@@ -82,9 +95,41 @@ export interface LastUiRunSummary {
|
|
|
82
95
|
}
|
|
83
96
|
|
|
84
97
|
export interface ImpactSummary {
|
|
85
|
-
changedFiles:
|
|
98
|
+
changedFiles: number;
|
|
99
|
+
sampleChangedFiles: string[];
|
|
100
|
+
hiddenChangedFiles: number;
|
|
101
|
+
changeSummary: CategorizedFileSummary;
|
|
86
102
|
risk: ImpactRiskLevel;
|
|
87
103
|
recommendedChecks: string[];
|
|
104
|
+
fullCommand: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface DevConsoleGeneratedSummary {
|
|
108
|
+
ok: boolean;
|
|
109
|
+
state: "fresh" | "regenerated" | "stale-risk";
|
|
110
|
+
changedFiles: number;
|
|
111
|
+
sampleChanged: string[];
|
|
112
|
+
hiddenChanged: number;
|
|
113
|
+
message: string;
|
|
114
|
+
command: string;
|
|
115
|
+
checkCommand: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export type DevConsoleDiffPlan = DiffPlan;
|
|
119
|
+
|
|
120
|
+
export interface DevConsoleAgentContext {
|
|
121
|
+
safeToEdit: boolean;
|
|
122
|
+
generatedFresh: boolean;
|
|
123
|
+
generatedChanged: boolean;
|
|
124
|
+
generatedChangedFiles: number;
|
|
125
|
+
frontendReady: boolean;
|
|
126
|
+
changedFiles: number;
|
|
127
|
+
changeSummary?: CategorizedFileSummary;
|
|
128
|
+
diffPlan?: DevConsoleDiffPlan;
|
|
129
|
+
blockingIssues: string[];
|
|
130
|
+
recommendedReadFiles: string[];
|
|
131
|
+
recommendedCommands: string[];
|
|
132
|
+
useFullCommands: string[];
|
|
88
133
|
}
|
|
89
134
|
|
|
90
135
|
export interface FrontendSummary {
|