forgeos 0.1.0-alpha.4 → 0.1.0-alpha.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.npmignore +10 -0
- package/AGENTS.md +142 -90
- package/CHANGELOG.md +418 -0
- package/LICENSE +21 -0
- package/README.md +67 -8
- package/adapters/go/README.md +23 -0
- package/adapters/go/go.mod +3 -0
- package/adapters/go/http.go +149 -0
- package/adapters/go/registry.go +234 -0
- package/adapters/go/types.go +136 -0
- package/adapters/java/README.md +68 -0
- package/adapters/java/pom.xml +34 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Auth.java +20 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Diagnostic.java +16 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Entry.java +38 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/EntryKind.java +16 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/ErrorInfo.java +4 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Forge.java +94 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeCall.java +12 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeContext.java +11 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHandler.java +8 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHttpHandler.java +179 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeRegistry.java +121 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Json.java +14 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Manifest.java +14 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/RequestEnvelope.java +6 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/ResponseEnvelope.java +25 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Risk.java +18 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Schemas.java +36 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/Service.java +65 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/TransactionMode.java +18 -0
- package/adapters/java/src/main/java/dev/forgeos/adapter/TypedForgeHandler.java +6 -0
- package/adapters/java-spring-boot-starter/README.md +32 -0
- package/adapters/java-spring-boot-starter/pom.xml +36 -0
- package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeCommand.java +22 -0
- package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeExternalService.java +15 -0
- package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeQuery.java +16 -0
- package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeServiceBeanCondition.java +18 -0
- package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringAutoConfiguration.java +16 -0
- package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringRuntime.java +104 -0
- package/adapters/java-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +1 -0
- package/bin/forge.mjs +18 -0
- package/docs/cair-protocol.md +103 -0
- package/docs/changelog.md +534 -0
- package/docs/forge-protocol.md +189 -0
- package/examples/go-billing/go.mod +7 -0
- package/examples/go-billing/main.go +120 -0
- package/examples/java-billing/pom.xml +52 -0
- package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/CreateInvoiceInput.java +4 -0
- package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Invoice.java +11 -0
- package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Main.java +127 -0
- package/package.json +31 -3
- 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 +1584 -125
- package/src/forge/agent-adapters/types.ts +224 -1
- package/src/forge/agent-memory/bridge.ts +1333 -0
- package/src/forge/agent-memory/context-pack.ts +277 -0
- package/src/forge/agent-memory/hook-runner.ts +312 -0
- package/src/forge/agent-memory/mcp.ts +224 -0
- package/src/forge/agent-memory/normalize.ts +498 -0
- package/src/forge/agent-memory/redaction.ts +103 -0
- package/src/forge/agent-memory/sources/claude-code.ts +51 -0
- package/src/forge/agent-memory/sources/codex-hook-runner.mjs +273 -0
- package/src/forge/agent-memory/sources/codex.ts +119 -0
- package/src/forge/agent-memory/sources/cursor.ts +35 -0
- package/src/forge/agent-memory/types.ts +204 -0
- package/src/forge/bench.ts +248 -0
- package/src/forge/brownfield-import/index.ts +801 -0
- package/src/forge/brownfield-import/types.ts +127 -0
- package/src/forge/cair/action-journal.ts +61 -0
- package/src/forge/cair/action-parser.ts +314 -0
- package/src/forge/cair/action-validator.ts +40 -0
- package/src/forge/cair/actions.ts +1818 -0
- package/src/forge/cair/format.ts +77 -0
- package/src/forge/cair/index.ts +106 -0
- package/src/forge/cair/query.ts +478 -0
- package/src/forge/cair/snapshot.ts +315 -0
- package/src/forge/cair/types.ts +248 -0
- package/src/forge/cli/ai.ts +339 -21
- package/src/forge/cli/auth.ts +348 -10
- package/src/forge/cli/authmd.ts +441 -0
- package/src/forge/cli/baseline.ts +112 -0
- package/src/forge/cli/build.ts +20 -4
- package/src/forge/cli/changed.ts +437 -0
- package/src/forge/cli/codex-app-server.ts +877 -0
- package/src/forge/cli/commands.ts +1620 -20
- package/src/forge/cli/db.ts +209 -2
- package/src/forge/cli/deploy.ts +887 -0
- package/src/forge/cli/deps.ts +82 -13
- package/src/forge/cli/dev.ts +961 -46
- package/src/forge/cli/docs.ts +265 -0
- package/src/forge/cli/doctor.ts +297 -0
- package/src/forge/cli/field-test.ts +329 -0
- package/src/forge/cli/handoff.ts +336 -0
- package/src/forge/cli/index.ts +1 -0
- package/src/forge/cli/last-run.ts +84 -0
- package/src/forge/cli/main.ts +107 -3
- package/src/forge/cli/new.ts +152 -13
- package/src/forge/cli/next-actions.ts +23 -0
- package/src/forge/cli/output.ts +389 -6
- package/src/forge/cli/parse.ts +1050 -34
- package/src/forge/cli/progress.ts +51 -0
- package/src/forge/cli/query.ts +32 -0
- package/src/forge/cli/release.ts +35 -11
- package/src/forge/cli/rls.ts +43 -4
- package/src/forge/cli/run.ts +41 -0
- package/src/forge/cli/security.ts +112 -0
- package/src/forge/cli/self-host.ts +56 -14
- package/src/forge/cli/studio.ts +2218 -0
- package/src/forge/cli/verify.ts +1455 -32
- package/src/forge/cli/windows.ts +23 -0
- package/src/forge/cli/workos.ts +1020 -0
- package/src/forge/compiler/agent-contract/build.ts +670 -64
- package/src/forge/compiler/agent-contract/types.ts +45 -2
- package/src/forge/compiler/ai-registry/parse.ts +71 -2
- package/src/forge/compiler/api-surface/build.ts +47 -0
- package/src/forge/compiler/app-graph/build.ts +112 -9
- package/src/forge/compiler/app-graph/extract.ts +107 -0
- package/src/forge/compiler/app-graph/module-graph.ts +73 -78
- package/src/forge/compiler/app-graph/parser.ts +24 -24
- package/src/forge/compiler/app-graph/profile.ts +26 -0
- package/src/forge/compiler/app-graph/versions.ts +1 -1
- package/src/forge/compiler/classifier/capabilities.ts +3 -2
- package/src/forge/compiler/classifier/classify.ts +32 -8
- package/src/forge/compiler/classifier/secrets.ts +3 -2
- package/src/forge/compiler/classifier/signals.ts +91 -1
- package/src/forge/compiler/client-sdk/build-manifest.ts +59 -0
- package/src/forge/compiler/client-sdk/render-client.ts +295 -13
- package/src/forge/compiler/data-graph/parse.ts +20 -4
- package/src/forge/compiler/data-graph/sql/ddl.ts +144 -31
- package/src/forge/compiler/data-graph/sql/serialize.ts +4 -0
- package/src/forge/compiler/data-graph/sql/types.ts +1 -0
- package/src/forge/compiler/diagnostics/codes.ts +30 -0
- package/src/forge/compiler/diagnostics/create.ts +21 -2
- package/src/forge/compiler/diagnostics/index.ts +2 -0
- package/src/forge/compiler/emitter/barrel.ts +3 -0
- package/src/forge/compiler/emitter/render.ts +9 -0
- package/src/forge/compiler/external-manifest/registry.ts +205 -0
- package/src/forge/compiler/external-manifest/types.ts +91 -0
- package/src/forge/compiler/external-manifest/validate.ts +373 -0
- package/src/forge/compiler/frontend-graph/build.ts +142 -14
- package/src/forge/compiler/integration/add.ts +618 -24
- package/src/forge/compiler/integration/plan.ts +43 -12
- package/src/forge/compiler/integration/render.ts +29 -0
- package/src/forge/compiler/integration/snapshot.ts +2 -0
- package/src/forge/compiler/integration/templates/convex.ts +70 -0
- package/src/forge/compiler/integration/templates/index.ts +1 -0
- package/src/forge/compiler/integration/templates/render.ts +38 -0
- package/src/forge/compiler/integration/templates/types.ts +3 -0
- package/src/forge/compiler/integration/templates/workos.ts +1219 -0
- package/src/forge/compiler/make-registry/build.ts +8 -9
- package/src/forge/compiler/orchestrator/fast-check.ts +4 -0
- package/src/forge/compiler/orchestrator/generate-lock.ts +14 -3
- package/src/forge/compiler/orchestrator/manifest.ts +1 -1
- package/src/forge/compiler/orchestrator/plan-profile.ts +23 -0
- package/src/forge/compiler/orchestrator/plan.ts +247 -10
- package/src/forge/compiler/orchestrator/profile.ts +65 -0
- package/src/forge/compiler/orchestrator/run.ts +97 -31
- package/src/forge/compiler/orchestrator/serialize.ts +33 -8
- package/src/forge/compiler/orchestrator/types.ts +1 -1
- package/src/forge/compiler/package-graph/compiler.ts +3 -1
- package/src/forge/compiler/package-graph/constants.ts +1 -1
- 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/package-upgrades/planner.ts +155 -18
- package/src/forge/compiler/package-upgrades/types.ts +2 -0
- package/src/forge/compiler/policy-registry/build.ts +47 -2
- package/src/forge/compiler/policy-registry/parse.ts +32 -2
- package/src/forge/compiler/recipes/definitions.ts +63 -0
- package/src/forge/compiler/recipes/index.ts +2 -0
- package/src/forge/compiler/recipes/registry.ts +6 -0
- package/src/forge/compiler/test-graph/build.ts +11 -3
- package/src/forge/compiler/types/app-graph.ts +8 -2
- package/src/forge/compiler/types/cli.ts +75 -1
- package/src/forge/compiler/types/dev-manifest.ts +4 -0
- package/src/forge/compiler/types/emit.ts +2 -0
- package/src/forge/compiler/types/frontend-graph.ts +2 -2
- package/src/forge/compiler/types/integration.ts +1 -0
- package/src/forge/compiler/types/package-graph.ts +6 -0
- package/src/forge/compiler/types/policy-registry.ts +3 -1
- package/src/forge/delta/classifier.ts +52 -0
- package/src/forge/delta/explain.ts +238 -0
- package/src/forge/delta/git-observer.ts +43 -0
- package/src/forge/delta/ids.ts +44 -0
- package/src/forge/delta/index.ts +25 -0
- package/src/forge/delta/recorder.ts +540 -0
- package/src/forge/delta/redaction.ts +50 -0
- package/src/forge/delta/schema.ts +240 -0
- package/src/forge/delta/session.ts +142 -0
- package/src/forge/delta/status.ts +1202 -0
- package/src/forge/delta/store.ts +3284 -0
- package/src/forge/delta/timeline.ts +178 -0
- package/src/forge/dev/server.ts +808 -17
- package/src/forge/dev/types.ts +15 -1
- package/src/forge/dev/watch.ts +17 -7
- package/src/forge/dev-console/cycle.ts +280 -33
- package/src/forge/dev-console/types.ts +47 -1
- package/src/forge/impact/index.ts +204 -9
- package/src/forge/impact/types.ts +33 -1
- package/src/forge/intent/index.ts +35 -16
- package/src/forge/make/fields.ts +26 -0
- package/src/forge/make/index.ts +40 -6
- package/src/forge/make/templates.ts +155 -2
- package/src/forge/make/types.ts +2 -1
- package/src/forge/policy.ts +1 -1
- package/src/forge/react/index.ts +160 -2
- package/src/forge/refactor/index.ts +1 -0
- package/src/forge/repair/rules/index.ts +2 -2
- package/src/forge/review/index.ts +158 -12
- package/src/forge/review/types.ts +15 -0
- package/src/forge/runtime/auth/config.ts +17 -0
- package/src/forge/runtime/auth/evaluate.ts +15 -2
- package/src/forge/runtime/auth/resolve.ts +61 -6
- package/src/forge/runtime/auth/types.ts +1 -0
- package/src/forge/runtime/db/factory.ts +1 -3
- package/src/forge/runtime/db/generated-client.ts +13 -2
- package/src/forge/runtime/db/memory-adapter.ts +139 -32
- package/src/forge/runtime/db/pglite-adapter.ts +263 -2
- package/src/forge/runtime/db/postgres-adapter.ts +6 -3
- package/src/forge/runtime/executor.ts +129 -16
- package/src/forge/runtime/external/bridge.ts +649 -0
- package/src/forge/runtime/runner/run-entry.ts +16 -7
- package/src/forge/runtime/telemetry/buffer.ts +4 -1
- package/src/forge/runtime/telemetry/scrubber.ts +35 -5
- package/src/forge/runtime/webhooks/security.ts +12 -7
- package/src/forge/server.ts +17 -3
- package/src/forge/ui/index.ts +209 -0
- package/src/forge/ui/types.ts +1 -0
- package/src/forge/version.ts +1 -1
- package/src/forge/vue/index.ts +422 -0
- package/src/forge/workspace/baseline.ts +112 -0
- package/src/forge/workspace/change-summary.ts +250 -0
- package/src/forge/workspace/forge-cli.ts +42 -0
- package/src/forge/workspace/git-summary.ts +391 -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 +1 -0
- package/templates/b2b-support-web/web/package.json +1 -1
- package/templates/minimal-web/package.json +1 -1
- package/templates/minimal-web/web/package.json +2 -2
- package/templates/nuxt-web/.vscode/settings.json +14 -0
- package/templates/nuxt-web/README.md +30 -0
- package/templates/nuxt-web/forge.config.ts +3 -0
- package/templates/nuxt-web/package.json +33 -0
- package/templates/nuxt-web/src/actions/logNoteCreated.ts +11 -0
- package/templates/nuxt-web/src/commands/createNote.ts +26 -0
- package/templates/nuxt-web/src/forge/schema.ts +12 -0
- package/templates/nuxt-web/src/policies.ts +6 -0
- package/templates/nuxt-web/src/queries/listNotes.ts +8 -0
- package/templates/nuxt-web/src/queries/liveNotes.ts +8 -0
- package/templates/nuxt-web/tsconfig.json +17 -0
- package/templates/nuxt-web/web/app.vue +67 -0
- package/templates/nuxt-web/web/components/LiveNotes.vue +89 -0
- package/templates/nuxt-web/web/components/NoteComposer.vue +100 -0
- package/templates/nuxt-web/web/composables/forge.ts +13 -0
- package/templates/nuxt-web/web/composables/useNotes.ts +24 -0
- package/templates/nuxt-web/web/nuxt.config.ts +11 -0
- package/templates/nuxt-web/web/package.json +18 -0
- package/templates/nuxt-web/web/plugins/forge.client.ts +10 -0
- package/templates/nuxt-web/web/plugins/forge.server.ts +10 -0
- package/templates/nuxt-web/web/server/api/forge-health.get.ts +7 -0
- package/templates/nuxt-web/web/tsconfig.json +6 -0
- package/src/forge/_generated/actionSubscriptions.json +0 -2
- package/src/forge/_generated/actionSubscriptions.ts +0 -10
- package/src/forge/_generated/agentAdapterManifest.json +0 -2
- package/src/forge/_generated/agentAdapterManifest.ts +0 -73
- package/src/forge/_generated/agentContract.json +0 -2
- package/src/forge/_generated/agentContract.ts +0 -7829
- package/src/forge/_generated/agentQuickstart.md +0 -34
- package/src/forge/_generated/agentTools.json +0 -2
- package/src/forge/_generated/agentTools.md +0 -16
- package/src/forge/_generated/agentTools.ts +0 -12
- package/src/forge/_generated/aiContext.ts +0 -125
- package/src/forge/_generated/aiModels.json +0 -2
- package/src/forge/_generated/aiModels.ts +0 -51
- package/src/forge/_generated/aiProviders.json +0 -2
- package/src/forge/_generated/aiProviders.ts +0 -23
- package/src/forge/_generated/aiRegistry.json +0 -2
- package/src/forge/_generated/aiRegistry.ts +0 -31
- package/src/forge/_generated/api.json +0 -2
- package/src/forge/_generated/api.ts +0 -8
- package/src/forge/_generated/appGraph.json +0 -2
- package/src/forge/_generated/appGraph.ts +0 -14919
- package/src/forge/_generated/appMap.md +0 -55
- package/src/forge/_generated/artifactManifest.json +0 -2
- package/src/forge/_generated/artifactManifest.ts +0 -7
- package/src/forge/_generated/authClaims.json +0 -2
- package/src/forge/_generated/authClaims.ts +0 -13
- package/src/forge/_generated/authConfig.json +0 -2
- package/src/forge/_generated/authConfig.ts +0 -17
- package/src/forge/_generated/authContext.ts +0 -23
- package/src/forge/_generated/authRegistry.json +0 -2
- package/src/forge/_generated/authRegistry.ts +0 -25
- package/src/forge/_generated/buildInfo.json +0 -2
- package/src/forge/_generated/buildInfo.ts +0 -9
- package/src/forge/_generated/capabilityMap.json +0 -2
- package/src/forge/_generated/capabilityMap.md +0 -15
- package/src/forge/_generated/capabilityMap.ts +0 -17
- package/src/forge/_generated/client.ts +0 -282
- package/src/forge/_generated/clientApi.ts +0 -9
- package/src/forge/_generated/clientManifest.json +0 -2
- package/src/forge/_generated/clientManifest.ts +0 -39
- package/src/forge/_generated/clientTypes.ts +0 -78
- package/src/forge/_generated/configRegistry.json +0 -2
- package/src/forge/_generated/configRegistry.ts +0 -4
- package/src/forge/_generated/dataGraph.json +0 -2
- package/src/forge/_generated/dataGraph.ts +0 -8
- package/src/forge/_generated/db.json +0 -2
- package/src/forge/_generated/db.ts +0 -2
- package/src/forge/_generated/dbSecurityManifest.json +0 -2
- package/src/forge/_generated/dbSecurityManifest.ts +0 -15
- package/src/forge/_generated/dbSessionContext.json +0 -2
- package/src/forge/_generated/dbSessionContext.ts +0 -39
- package/src/forge/_generated/deployManifest.json +0 -2
- package/src/forge/_generated/deployManifest.ts +0 -14
- package/src/forge/_generated/devManifest.json +0 -2
- package/src/forge/_generated/devManifest.ts +0 -62
- package/src/forge/_generated/envSchema.json +0 -2
- package/src/forge/_generated/envSchema.ts +0 -59
- package/src/forge/_generated/frontendGraph.json +0 -2
- package/src/forge/_generated/frontendGraph.ts +0 -27
- package/src/forge/_generated/importGuards.json +0 -2
- package/src/forge/_generated/importGuards.ts +0 -686
- package/src/forge/_generated/index.ts +0 -68
- package/src/forge/_generated/liveProductionManifest.json +0 -2
- package/src/forge/_generated/liveProductionManifest.ts +0 -23
- package/src/forge/_generated/liveProtocol.json +0 -2
- package/src/forge/_generated/liveProtocol.ts +0 -21
- package/src/forge/_generated/liveQueryRegistry.json +0 -2
- package/src/forge/_generated/liveQueryRegistry.ts +0 -9
- package/src/forge/_generated/liveTransportConfig.json +0 -2
- package/src/forge/_generated/liveTransportConfig.ts +0 -19
- package/src/forge/_generated/makeRegistry.json +0 -2
- package/src/forge/_generated/makeRegistry.ts +0 -177
- package/src/forge/_generated/makeTemplates.json +0 -2
- package/src/forge/_generated/makeTemplates.ts +0 -66
- package/src/forge/_generated/mockMap.json +0 -2
- package/src/forge/_generated/mockMap.ts +0 -7
- package/src/forge/_generated/operationPlaybooks.md +0 -167
- package/src/forge/_generated/packageGraph.json +0 -2
- package/src/forge/_generated/packageGraph.ts +0 -249334
- package/src/forge/_generated/packageUpgradeRegistry.json +0 -2
- package/src/forge/_generated/packageUpgradeRegistry.ts +0 -15
- package/src/forge/_generated/permissionMatrix.json +0 -2
- package/src/forge/_generated/permissionMatrix.ts +0 -7
- package/src/forge/_generated/policyRegistry.json +0 -2
- package/src/forge/_generated/policyRegistry.ts +0 -11
- package/src/forge/_generated/queryRegistry.json +0 -2
- package/src/forge/_generated/queryRegistry.ts +0 -9
- package/src/forge/_generated/react.d.ts +0 -22
- package/src/forge/_generated/react.ts +0 -29
- package/src/forge/_generated/reactManifest.json +0 -2
- package/src/forge/_generated/reactManifest.ts +0 -19
- package/src/forge/_generated/rlsPolicies.json +0 -2
- package/src/forge/_generated/rlsPolicies.sql +0 -34
- package/src/forge/_generated/rlsPolicies.ts +0 -6
- package/src/forge/_generated/runtimeGraph.json +0 -2
- package/src/forge/_generated/runtimeGraph.ts +0 -8
- package/src/forge/_generated/runtimeMatrix.json +0 -2
- package/src/forge/_generated/runtimeMatrix.ts +0 -334130
- package/src/forge/_generated/runtimeRegistry.ts +0 -2
- package/src/forge/_generated/runtimeRules.md +0 -91
- package/src/forge/_generated/secretRegistry.json +0 -2
- package/src/forge/_generated/secretRegistry.ts +0 -50
- package/src/forge/_generated/secretsContext.ts +0 -11
- package/src/forge/_generated/serverApi.ts +0 -10
- package/src/forge/_generated/sourceMapManifest.json +0 -2
- package/src/forge/_generated/sourceMapManifest.ts +0 -7
- package/src/forge/_generated/sqlPlan.json +0 -2
- package/src/forge/_generated/sqlPlan.ts +0 -88
- package/src/forge/_generated/subscriptionManifest.json +0 -2
- package/src/forge/_generated/subscriptionManifest.ts +0 -7
- package/src/forge/_generated/symbolicationManifest.json +0 -2
- package/src/forge/_generated/symbolicationManifest.ts +0 -17
- package/src/forge/_generated/telemetryRegistry.json +0 -2
- package/src/forge/_generated/telemetryRegistry.ts +0 -9
- package/src/forge/_generated/telemetrySinks.json +0 -2
- package/src/forge/_generated/telemetrySinks.ts +0 -11
- package/src/forge/_generated/tenantScope.json +0 -2
- package/src/forge/_generated/tenantScope.ts +0 -8
- package/src/forge/_generated/testGraph.json +0 -2
- package/src/forge/_generated/testGraph.ts +0 -3430
- package/src/forge/_generated/testPlanRegistry.json +0 -2
- package/src/forge/_generated/testPlanRegistry.ts +0 -33
- package/src/forge/_generated/uiRoutes.json +0 -2
- package/src/forge/_generated/uiRoutes.ts +0 -16
- package/src/forge/_generated/uiScenarios.json +0 -2
- package/src/forge/_generated/uiScenarios.ts +0 -30
- package/src/forge/_generated/uiTestManifest.json +0 -2
- package/src/forge/_generated/uiTestManifest.ts +0 -27
- package/src/forge/_generated/workflowRegistry.json +0 -2
- package/src/forge/_generated/workflowRegistry.ts +0 -9
- package/src/forge/_generated/workflowSubscriptions.json +0 -2
- package/src/forge/_generated/workflowSubscriptions.ts +0 -10
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
export interface LastRunRecord {
|
|
5
|
+
schemaVersion: "0.1.0";
|
|
6
|
+
command: string;
|
|
7
|
+
ok: boolean;
|
|
8
|
+
startedAt: string;
|
|
9
|
+
finishedAt: string;
|
|
10
|
+
durationMs: number;
|
|
11
|
+
code?: string;
|
|
12
|
+
failureKind?: string;
|
|
13
|
+
message?: string;
|
|
14
|
+
nextActions: string[];
|
|
15
|
+
details?: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface LastRunCommandResult {
|
|
19
|
+
ok: boolean;
|
|
20
|
+
record: LastRunRecord | null;
|
|
21
|
+
path: string;
|
|
22
|
+
exitCode: 0 | 1;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function lastRunPath(workspaceRoot: string): string {
|
|
26
|
+
return join(workspaceRoot, ".forge", "last-run.json");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function writeLastRunRecord(workspaceRoot: string, record: LastRunRecord): void {
|
|
30
|
+
const file = lastRunPath(workspaceRoot);
|
|
31
|
+
mkdirSync(join(workspaceRoot, ".forge"), { recursive: true });
|
|
32
|
+
writeFileSync(file, `${JSON.stringify(record, null, 2)}\n`, "utf8");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function readLastRunRecord(workspaceRoot: string): LastRunRecord | null {
|
|
36
|
+
const file = lastRunPath(workspaceRoot);
|
|
37
|
+
if (!existsSync(file)) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return JSON.parse(readFileSync(file, "utf8")) as LastRunRecord;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function runLastCommand(options: { workspaceRoot: string }): LastRunCommandResult {
|
|
44
|
+
const path = lastRunPath(options.workspaceRoot);
|
|
45
|
+
const record = readLastRunRecord(options.workspaceRoot);
|
|
46
|
+
return {
|
|
47
|
+
ok: record !== null,
|
|
48
|
+
record,
|
|
49
|
+
path,
|
|
50
|
+
exitCode: record ? 0 : 1,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function formatLastJson(result: LastRunCommandResult): string {
|
|
55
|
+
return `${JSON.stringify(result, null, 2)}\n`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function formatLastHuman(result: LastRunCommandResult): string {
|
|
59
|
+
if (!result.record) {
|
|
60
|
+
return `No last run record found at ${result.path}\n`;
|
|
61
|
+
}
|
|
62
|
+
const lines = [
|
|
63
|
+
`Last Forge run: ${result.record.command}`,
|
|
64
|
+
`OK: ${result.record.ok}`,
|
|
65
|
+
`Finished: ${result.record.finishedAt}`,
|
|
66
|
+
`Duration: ${result.record.durationMs}ms`,
|
|
67
|
+
];
|
|
68
|
+
if (result.record.code) {
|
|
69
|
+
lines.push(`Code: ${result.record.code}`);
|
|
70
|
+
}
|
|
71
|
+
if (result.record.failureKind) {
|
|
72
|
+
lines.push(`Failure: ${result.record.failureKind}`);
|
|
73
|
+
}
|
|
74
|
+
if (result.record.message) {
|
|
75
|
+
lines.push(`Message: ${result.record.message}`);
|
|
76
|
+
}
|
|
77
|
+
if (result.record.nextActions.length > 0) {
|
|
78
|
+
lines.push("Next actions:");
|
|
79
|
+
for (const action of result.record.nextActions) {
|
|
80
|
+
lines.push(` ${action}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return `${lines.join("\n")}\n`;
|
|
84
|
+
}
|
package/src/forge/cli/main.ts
CHANGED
|
@@ -4,28 +4,124 @@ import { isMainModule } from "../platform/module.ts";
|
|
|
4
4
|
import { executeCommand } from "./commands.ts";
|
|
5
5
|
import { hasUnknownOption, parseCli } from "./parse.ts";
|
|
6
6
|
import { formatJsonResult } from "./output.ts";
|
|
7
|
+
import { recordParsedCliCommand } from "../delta/index.ts";
|
|
7
8
|
|
|
8
9
|
function formatHelp(): string {
|
|
9
10
|
return [
|
|
10
11
|
"ForgeOS",
|
|
11
12
|
"",
|
|
12
13
|
"Start with one of these:",
|
|
14
|
+
" forge status --json Compact project health, handoff state, and next actions",
|
|
15
|
+
" forge changed --json Group changed files into human, generated, and risk buckets",
|
|
16
|
+
" forge changed --authored --json Show only authored changed files, excluding generated artifacts",
|
|
17
|
+
" forge changed --review --json Show review-focused app/config/docs changes, excluding local agent/browser artifacts",
|
|
18
|
+
" forge changed --commit-ready --json Show files suitable for git add, excluding generated and operational artifacts",
|
|
19
|
+
" forge new my-app --template minimal-web --field-test Create an installed WorkOS/auth.md field-test app",
|
|
20
|
+
" forge field-test create vendor-access --auth workos --template minimal-web --json Create a real field-test app",
|
|
21
|
+
" forge field-test run --templates minimal-web,nuxt-web --package-managers npm,pnpm --runtime-probes --auth-probes --json",
|
|
22
|
+
" forge field-test report --json Summarize the machine-readable field-test report",
|
|
23
|
+
" forge diff authored Run the authored-only git diff pathspec",
|
|
24
|
+
" forge handoff --json Compact work handoff for the next external code agent",
|
|
25
|
+
" forge agent onboard --target codex --json Prepare adapter, hooks, memory, and dev snapshot",
|
|
26
|
+
" forge doctor agent --target codex --json Check adapter, hooks, and Agent Memory readiness",
|
|
27
|
+
" forge doctor delta --json Check DeltaDB writability, queue drain, redaction, and gitignore posture",
|
|
28
|
+
" forge doctor runtime --json Check generated freshness, local dev lifecycle, and PGlite posture",
|
|
29
|
+
" forge agent ingest codex --watch --file .forge/agent/events.ndjson --json",
|
|
30
|
+
" forge docs check --json Check public docs, ReadTheDocs config, links, and local MkDocs tooling",
|
|
31
|
+
" forge docs check --build --install-venv --json Build docs strictly in a local RTD-style venv",
|
|
32
|
+
" forge release doctor --json Check npm publish readiness plus separate production deploy readiness",
|
|
33
|
+
" forge authmd generate Write public/auth.md from the generated agent/auth contract",
|
|
34
|
+
" forge auth check --production --json Fail unless auth is jwt/oidc production-ready",
|
|
35
|
+
" forge authmd check --json Check public/auth.md drift for CI and agent-ready apps",
|
|
36
|
+
" forge workos install --yes --json Delegate AuthKit setup to npx --yes workos@latest install",
|
|
37
|
+
" forge workos doctor --json Check WorkOS AuthKit/FGA files, claims, seed, webhook, and tenant guards",
|
|
38
|
+
" forge workos doctor --yes --json Run local checks, then delegate to npx --yes workos@latest doctor",
|
|
39
|
+
" forge workos seed --file workos-seed.yml --dry-run --json Validate WorkOS seed without hosted changes",
|
|
40
|
+
" forge workos setup --real --file workos-seed.yml --json Apply redirect/CORS/homepage config and seed WorkOS without dashboard",
|
|
41
|
+
" forge deploy plan --target docker --json Explain production deploy gates and commands",
|
|
42
|
+
" forge deploy check --production --json Gate auth, DB, metadata, generated artifacts, and liveQuery readiness",
|
|
43
|
+
" forge deploy render docker Write Docker production deploy files under deploy/",
|
|
44
|
+
" forge deploy verify --production --url https://app.example.com --json Probe /health and validate public auth metadata",
|
|
45
|
+
" forge release check --allow-missing-local-release --json Gate release readiness without failing on unprepared local artifacts",
|
|
46
|
+
" forge self-host check --prepared-only --json Report compose readiness without creating deploy files",
|
|
47
|
+
" forge delta status --verbose --json Include Delta schema, lock, and aggregate count details",
|
|
48
|
+
" forge delta compact --json Compact redacted local agent queue history",
|
|
49
|
+
" forge delta prune --older-than 30d --dry-run --json Plan local Delta operational retention",
|
|
50
|
+
" forge delta export --redacted --json Export redacted Delta status, timeline, and agent memory",
|
|
51
|
+
" forge studio open <app-path> --preview-port 5174 --target codex --json",
|
|
52
|
+
" forge studio snapshot <app-path> --preview-port 5174 --target codex --probe-codex-server --json",
|
|
53
|
+
" forge studio bridge <app-path> --preview-port 5174 --target codex --studio-url http://127.0.0.1:3765 --probe-codex-server --json",
|
|
54
|
+
" forge studio doctor <app-path> --preview-port 5174 --target codex --json",
|
|
55
|
+
" forge studio codex-server <app-path> --probe --json",
|
|
56
|
+
" forge studio watch <app-path> --preview-port 5174 --target codex --json",
|
|
13
57
|
" forge dev Run API, DB/worker, watch, and web app when present",
|
|
14
58
|
" forge dev --once --json One-shot health/diagnostic loop for agents and CI",
|
|
15
59
|
" forge do \"fix\" --json Ask ForgeOS for the right workflow and commands",
|
|
16
|
-
" forge
|
|
60
|
+
" forge cair snapshot Compact CAIR project snapshot for agents",
|
|
61
|
+
" forge cair query \"Q REFS S#1\" Run a semantic CAIR query",
|
|
62
|
+
" forge cair action --plan \"A RN t=S#1 nn=renamed\" Plan a guarded semantic edit",
|
|
63
|
+
" forge cair action \"A APPLY plan=<P#|path>\" Apply a guarded CAIR plan",
|
|
64
|
+
" forge agent print-context --json Read the generated agent context pack",
|
|
65
|
+
" forge inspect all --brief --json Read the smallest aggregate project contract",
|
|
66
|
+
" forge inspect all --json Read the compact generated machine contract",
|
|
67
|
+
" forge mcp serve Serve ForgeOS Agent Memory tools over MCP stdio",
|
|
68
|
+
" forge agent context --current --json Read the Agent Memory context pack",
|
|
69
|
+
" forge agent timeline --json Read external-agent hook activity as a compact timeline",
|
|
17
70
|
" forge doctor windows --json Diagnose native Windows setup and Bun shims",
|
|
71
|
+
" forge bench compiler --json Measure public compiler phase timings",
|
|
72
|
+
" forge manifest validate ./forge.manifest.json --json Validate an external runtime manifest",
|
|
18
73
|
"",
|
|
19
74
|
"Useful next commands:",
|
|
20
75
|
" forge generate",
|
|
21
76
|
" forge check --json",
|
|
77
|
+
" forge verify App-level default verification for the current project",
|
|
22
78
|
" forge verify --standard",
|
|
23
|
-
" forge verify
|
|
79
|
+
" forge verify quick Alias for smoke/fast local checks",
|
|
80
|
+
" forge verify agent Alias for standard agent-loop verification",
|
|
81
|
+
" forge verify release Alias for strict app release verification",
|
|
82
|
+
" forge verify framework Maintainer-only ForgeOS framework test gate",
|
|
83
|
+
" forge verify --strict --typechecker native --test-jobs 6",
|
|
84
|
+
" forge verify framework --test-plan --json",
|
|
85
|
+
"",
|
|
86
|
+
].join("\n");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function formatDevHelp(): string {
|
|
90
|
+
return [
|
|
91
|
+
"ForgeOS dev",
|
|
92
|
+
"",
|
|
93
|
+
"Usage:",
|
|
94
|
+
" forge dev [status|stop] [options]",
|
|
95
|
+
"",
|
|
96
|
+
"Options:",
|
|
97
|
+
" --db memory|pglite|postgres|none Choose the development database adapter",
|
|
98
|
+
" --port <port> API runtime port; use 0 for an ephemeral port",
|
|
99
|
+
" --web-port <port> Web dev server port",
|
|
100
|
+
" --host <host> Bind host, default 127.0.0.1",
|
|
101
|
+
" --no-web Start API/runtime only",
|
|
102
|
+
" --api-only Start API/runtime only",
|
|
103
|
+
" --web-only Start web server only, expecting an API runtime",
|
|
104
|
+
" --no-worker Disable local worker",
|
|
105
|
+
" --no-watch Disable file watching",
|
|
106
|
+
" --once --json Run one-shot diagnostics without starting servers",
|
|
107
|
+
" --detach --json Start dev in the background with .forge/dev/dev.pid and .forge/dev/dev.log",
|
|
108
|
+
"",
|
|
109
|
+
"Examples:",
|
|
110
|
+
" forge dev --db memory --port 3777 --web-port 5174",
|
|
111
|
+
" forge dev --db pglite --once --json",
|
|
112
|
+
" forge dev --detach --db memory --port 0 --json",
|
|
113
|
+
" forge dev status --json",
|
|
114
|
+
" forge dev stop --json",
|
|
24
115
|
"",
|
|
25
116
|
].join("\n");
|
|
26
117
|
}
|
|
27
118
|
|
|
28
119
|
export async function main(argv: string[] = process.argv.slice(2)): Promise<number> {
|
|
120
|
+
if (argv[0] === "dev" && (argv.includes("--help") || argv.includes("-h"))) {
|
|
121
|
+
process.stdout.write(formatDevHelp());
|
|
122
|
+
return 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
29
125
|
if (argv.length === 0 || argv.includes("--help") || argv.includes("-h")) {
|
|
30
126
|
process.stdout.write(formatHelp());
|
|
31
127
|
return 0;
|
|
@@ -83,7 +179,15 @@ export async function main(argv: string[] = process.argv.slice(2)): Promise<numb
|
|
|
83
179
|
return 1;
|
|
84
180
|
}
|
|
85
181
|
|
|
86
|
-
|
|
182
|
+
const startedAt = Date.now();
|
|
183
|
+
const exitCode = await executeCommand(parsed.command);
|
|
184
|
+
await recordParsedCliCommand({
|
|
185
|
+
command: parsed.command,
|
|
186
|
+
argv,
|
|
187
|
+
exitCode,
|
|
188
|
+
durationMs: Date.now() - startedAt,
|
|
189
|
+
});
|
|
190
|
+
return exitCode;
|
|
87
191
|
}
|
|
88
192
|
|
|
89
193
|
if (isMainModule(import.meta)) {
|
package/src/forge/cli/new.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { cpSync, statSync } from "node:fs";
|
|
3
|
-
import { dirname, join, parse, relative, resolve } from "node:path";
|
|
3
|
+
import { basename, dirname, join, parse, relative, resolve } from "node:path";
|
|
4
4
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
5
5
|
import { pathToFileURL } from "node:url";
|
|
6
6
|
import { nodeFileSystem } from "../compiler/fs/index.ts";
|
|
@@ -8,7 +8,7 @@ import { run as runGenerate } from "../compiler/orchestrator/run.ts";
|
|
|
8
8
|
import { resolvePackageManagerArgv } from "../compiler/package-manager/executor.ts";
|
|
9
9
|
import { moduleDir } from "../platform/module.ts";
|
|
10
10
|
|
|
11
|
-
export type NewTemplateName = "b2b-support-web" | "minimal-web";
|
|
11
|
+
export type NewTemplateName = "agent-workroom" | "b2b-support-web" | "minimal-web" | "nuxt-web";
|
|
12
12
|
export type NewPackageManager = "bun" | "npm" | "pnpm" | "yarn";
|
|
13
13
|
|
|
14
14
|
export interface NewCommandOptions {
|
|
@@ -17,6 +17,7 @@ export interface NewCommandOptions {
|
|
|
17
17
|
packageManager: NewPackageManager;
|
|
18
18
|
install: boolean;
|
|
19
19
|
git: boolean;
|
|
20
|
+
fieldTest?: boolean;
|
|
20
21
|
forgePackageSpec?: string;
|
|
21
22
|
localForge?: boolean;
|
|
22
23
|
workspaceRoot: string;
|
|
@@ -29,6 +30,11 @@ export interface NewCommandResult {
|
|
|
29
30
|
packageManager: NewPackageManager;
|
|
30
31
|
installed: boolean;
|
|
31
32
|
gitInitialized: boolean;
|
|
33
|
+
fieldTest: {
|
|
34
|
+
requested: boolean;
|
|
35
|
+
ok: boolean;
|
|
36
|
+
steps: Array<{ name: string; ok: boolean; command: string }>;
|
|
37
|
+
};
|
|
32
38
|
generated: boolean;
|
|
33
39
|
gitHygiene: {
|
|
34
40
|
ok: boolean;
|
|
@@ -43,9 +49,16 @@ export interface NewCommandResult {
|
|
|
43
49
|
const REQUIRED_GITIGNORE_PATHS = [
|
|
44
50
|
"src/forge/_generated/",
|
|
45
51
|
"forge.lock",
|
|
52
|
+
".codex/",
|
|
46
53
|
".forge/cache/",
|
|
47
54
|
".forge/pglite/",
|
|
55
|
+
".forge/delta/",
|
|
56
|
+
".forge/agent/",
|
|
57
|
+
".forge/agent/*.ndjson",
|
|
58
|
+
".forge/agent/*.history",
|
|
59
|
+
".forge/last-run.json",
|
|
48
60
|
".forge/local/",
|
|
61
|
+
".forge/runtime-cache/",
|
|
49
62
|
".forge/test-cache/",
|
|
50
63
|
".forge/test-runs/",
|
|
51
64
|
".forge/ui-runs/",
|
|
@@ -55,6 +68,8 @@ const REQUIRED_GITIGNORE_PATHS = [
|
|
|
55
68
|
".forge/reviews/",
|
|
56
69
|
".forge/impact/",
|
|
57
70
|
".forge/agent-adapters/",
|
|
71
|
+
".forge/studio/",
|
|
72
|
+
".workos-seed-state.json",
|
|
58
73
|
] as const;
|
|
59
74
|
|
|
60
75
|
const DEFAULT_FORGE_PACKAGE_SPEC = "npm:forgeos@alpha";
|
|
@@ -191,12 +206,49 @@ function ensureProjectName(name: string): string | null {
|
|
|
191
206
|
if (!name.trim()) {
|
|
192
207
|
return "forge new requires a project name";
|
|
193
208
|
}
|
|
194
|
-
if (name
|
|
209
|
+
if (name === ".") {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
if (name.includes("/") || name.includes("\\") || name === "..") {
|
|
195
213
|
return "project name must be a directory name, not a path";
|
|
196
214
|
}
|
|
197
215
|
return null;
|
|
198
216
|
}
|
|
199
217
|
|
|
218
|
+
function isCurrentDirectoryTarget(name: string): boolean {
|
|
219
|
+
return name === ".";
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function targetDirectoryFor(options: NewCommandOptions): string {
|
|
223
|
+
return isCurrentDirectoryTarget(options.name)
|
|
224
|
+
? resolve(options.workspaceRoot)
|
|
225
|
+
: resolve(options.workspaceRoot, options.name);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function sanitizePackageName(name: string): string {
|
|
229
|
+
return name
|
|
230
|
+
.trim()
|
|
231
|
+
.toLowerCase()
|
|
232
|
+
.replace(/[^a-z0-9._-]+/g, "-")
|
|
233
|
+
.replace(/-+/g, "-")
|
|
234
|
+
.replace(/^[._-]+|[._-]+$/g, "") || "forge-app";
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function projectNameForTarget(options: NewCommandOptions, targetDir: string): string {
|
|
238
|
+
return isCurrentDirectoryTarget(options.name)
|
|
239
|
+
? sanitizePackageName(basename(targetDir))
|
|
240
|
+
: options.name;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function blockingExistingEntries(targetDir: string): string[] {
|
|
244
|
+
const allowed = new Set([".git", ".DS_Store", "Thumbs.db"]);
|
|
245
|
+
return nodeFileSystem
|
|
246
|
+
.readDir(targetDir)
|
|
247
|
+
.map((entry) => entry.name)
|
|
248
|
+
.filter((name) => !allowed.has(name))
|
|
249
|
+
.sort();
|
|
250
|
+
}
|
|
251
|
+
|
|
200
252
|
function analyzeGitHygiene(targetDir: string): NewCommandResult["gitHygiene"] {
|
|
201
253
|
const gitignorePath = join(targetDir, ".gitignore");
|
|
202
254
|
const gitignore = nodeFileSystem.exists(gitignorePath)
|
|
@@ -376,6 +428,7 @@ export async function runNewCommand(options: NewCommandOptions): Promise<NewComm
|
|
|
376
428
|
packageManager: options.packageManager,
|
|
377
429
|
installed: false,
|
|
378
430
|
gitInitialized: false,
|
|
431
|
+
fieldTest: { requested: Boolean(options.fieldTest), ok: false, steps: [] },
|
|
379
432
|
generated: false,
|
|
380
433
|
gitHygiene: { ok: false, ignoredPaths: [], missingPaths: [] },
|
|
381
434
|
exitCode: 1,
|
|
@@ -393,6 +446,7 @@ export async function runNewCommand(options: NewCommandOptions): Promise<NewComm
|
|
|
393
446
|
packageManager: options.packageManager,
|
|
394
447
|
installed: false,
|
|
395
448
|
gitInitialized: false,
|
|
449
|
+
fieldTest: { requested: Boolean(options.fieldTest), ok: false, steps: [] },
|
|
396
450
|
generated: false,
|
|
397
451
|
gitHygiene: { ok: false, ignoredPaths: [], missingPaths: [] },
|
|
398
452
|
exitCode: 1,
|
|
@@ -401,15 +455,18 @@ export async function runNewCommand(options: NewCommandOptions): Promise<NewComm
|
|
|
401
455
|
};
|
|
402
456
|
}
|
|
403
457
|
|
|
404
|
-
const targetDir =
|
|
405
|
-
|
|
458
|
+
const targetDir = targetDirectoryFor(options);
|
|
459
|
+
const appName = projectNameForTarget(options, targetDir);
|
|
460
|
+
const currentDirectoryTarget = isCurrentDirectoryTarget(options.name);
|
|
461
|
+
if (nodeFileSystem.exists(targetDir) && !currentDirectoryTarget) {
|
|
406
462
|
return {
|
|
407
|
-
name:
|
|
463
|
+
name: appName,
|
|
408
464
|
template: options.template,
|
|
409
465
|
targetDir,
|
|
410
466
|
packageManager: options.packageManager,
|
|
411
467
|
installed: false,
|
|
412
468
|
gitInitialized: false,
|
|
469
|
+
fieldTest: { requested: Boolean(options.fieldTest), ok: false, steps: [] },
|
|
413
470
|
generated: false,
|
|
414
471
|
gitHygiene: { ok: false, ignoredPaths: [], missingPaths: [] },
|
|
415
472
|
exitCode: 1,
|
|
@@ -417,13 +474,32 @@ export async function runNewCommand(options: NewCommandOptions): Promise<NewComm
|
|
|
417
474
|
nextSteps: [],
|
|
418
475
|
};
|
|
419
476
|
}
|
|
477
|
+
if (nodeFileSystem.exists(targetDir) && currentDirectoryTarget) {
|
|
478
|
+
const blocking = blockingExistingEntries(targetDir);
|
|
479
|
+
if (blocking.length > 0) {
|
|
480
|
+
return {
|
|
481
|
+
name: appName,
|
|
482
|
+
template: options.template,
|
|
483
|
+
targetDir,
|
|
484
|
+
packageManager: options.packageManager,
|
|
485
|
+
installed: false,
|
|
486
|
+
gitInitialized: false,
|
|
487
|
+
fieldTest: { requested: Boolean(options.fieldTest), ok: false, steps: [] },
|
|
488
|
+
generated: false,
|
|
489
|
+
gitHygiene: { ok: false, ignoredPaths: [], missingPaths: [] },
|
|
490
|
+
exitCode: 1,
|
|
491
|
+
message: `current directory is not empty: ${blocking.slice(0, 6).join(", ")}${blocking.length > 6 ? ` (+${blocking.length - 6})` : ""}`,
|
|
492
|
+
nextSteps: [],
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
}
|
|
420
496
|
|
|
421
497
|
nodeFileSystem.mkdirp(targetDir);
|
|
422
498
|
cpSync(source, targetDir, { recursive: true, force: true });
|
|
423
499
|
ensureGitignore(targetDir);
|
|
424
500
|
replaceTokens(
|
|
425
501
|
targetDir,
|
|
426
|
-
|
|
502
|
+
appName,
|
|
427
503
|
options.packageManager,
|
|
428
504
|
forgePackageSpec(targetDir, options),
|
|
429
505
|
);
|
|
@@ -434,12 +510,13 @@ export async function runNewCommand(options: NewCommandOptions): Promise<NewComm
|
|
|
434
510
|
installed = installCode === 0;
|
|
435
511
|
if (!installed) {
|
|
436
512
|
return {
|
|
437
|
-
name:
|
|
513
|
+
name: appName,
|
|
438
514
|
template: options.template,
|
|
439
515
|
targetDir,
|
|
440
516
|
packageManager: options.packageManager,
|
|
441
517
|
installed,
|
|
442
518
|
gitInitialized: false,
|
|
519
|
+
fieldTest: { requested: Boolean(options.fieldTest), ok: false, steps: [] },
|
|
443
520
|
generated: false,
|
|
444
521
|
gitHygiene: analyzeGitHygiene(targetDir),
|
|
445
522
|
exitCode: 1,
|
|
@@ -468,12 +545,13 @@ export async function runNewCommand(options: NewCommandOptions): Promise<NewComm
|
|
|
468
545
|
}
|
|
469
546
|
if (!generated) {
|
|
470
547
|
return {
|
|
471
|
-
name:
|
|
548
|
+
name: appName,
|
|
472
549
|
template: options.template,
|
|
473
550
|
targetDir,
|
|
474
551
|
packageManager: options.packageManager,
|
|
475
552
|
installed,
|
|
476
553
|
gitInitialized: false,
|
|
554
|
+
fieldTest: { requested: Boolean(options.fieldTest), ok: false, steps: [] },
|
|
477
555
|
generated,
|
|
478
556
|
gitHygiene: analyzeGitHygiene(targetDir),
|
|
479
557
|
exitCode: 1,
|
|
@@ -489,26 +567,72 @@ export async function runNewCommand(options: NewCommandOptions): Promise<NewComm
|
|
|
489
567
|
gitInitialized = gitCode === 0;
|
|
490
568
|
}
|
|
491
569
|
|
|
570
|
+
const fieldTestSteps: NewCommandResult["fieldTest"]["steps"] = [];
|
|
571
|
+
if (options.fieldTest && installed) {
|
|
572
|
+
const steps: Array<{ name: string; command: string; args: string[] }> = [
|
|
573
|
+
{ name: "workos", command: options.packageManager, args: ["run", "forge", "--", "add", "auth", "workos", "--json"] },
|
|
574
|
+
{ name: "generate-workos", command: options.packageManager, args: ["run", "forge", "--", "generate"] },
|
|
575
|
+
{ name: "authmd", command: options.packageManager, args: ["run", "forge", "--", "authmd", "generate", "--json"] },
|
|
576
|
+
{ name: "authmd-check", command: options.packageManager, args: ["run", "forge", "--", "authmd", "check", "--json"] },
|
|
577
|
+
{ name: "workos-doctor", command: options.packageManager, args: ["run", "forge", "--", "workos", "doctor", "--json"] },
|
|
578
|
+
{ name: "workos-seed", command: options.packageManager, args: ["run", "forge", "--", "workos", "seed", "--file", "workos-seed.yml", "--dry-run", "--json"] },
|
|
579
|
+
{ name: "check", command: options.packageManager, args: ["run", "forge", "--", "check", "--json"] },
|
|
580
|
+
];
|
|
581
|
+
for (const step of steps) {
|
|
582
|
+
const code = await spawnCommand(step.command, step.args, targetDir);
|
|
583
|
+
fieldTestSteps.push({ name: step.name, ok: code === 0, command: [step.command, ...step.args].join(" ") });
|
|
584
|
+
if (code !== 0) {
|
|
585
|
+
break;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
if (gitInitialized && fieldTestSteps.every((step) => step.ok)) {
|
|
589
|
+
const addCode = await spawnCommand("git", ["add", "-A"], targetDir);
|
|
590
|
+
const commitCode = addCode === 0
|
|
591
|
+
? await spawnCommand("git", [
|
|
592
|
+
"-c",
|
|
593
|
+
"user.name=ForgeOS",
|
|
594
|
+
"-c",
|
|
595
|
+
"user.email=forgeos@example.invalid",
|
|
596
|
+
"commit",
|
|
597
|
+
"-m",
|
|
598
|
+
"Initial ForgeOS field-test scaffold",
|
|
599
|
+
], targetDir)
|
|
600
|
+
: 1;
|
|
601
|
+
fieldTestSteps.push({
|
|
602
|
+
name: "baseline-commit",
|
|
603
|
+
ok: addCode === 0 && commitCode === 0,
|
|
604
|
+
command: 'git add -A && git commit -m "Initial ForgeOS field-test scaffold"',
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
const fieldTest = {
|
|
609
|
+
requested: Boolean(options.fieldTest),
|
|
610
|
+
ok: !options.fieldTest || (installed && fieldTestSteps.length > 0 && fieldTestSteps.every((step) => step.ok)),
|
|
611
|
+
steps: fieldTestSteps,
|
|
612
|
+
};
|
|
613
|
+
|
|
492
614
|
const nextSteps = [
|
|
493
|
-
`cd ${options.name}
|
|
615
|
+
...(currentDirectoryTarget ? [] : [`cd ${options.name}`]),
|
|
494
616
|
...(installed ? [] : [`${options.packageManager} install`]),
|
|
495
617
|
...(generated ? [] : [`${options.packageManager} run generate`]),
|
|
618
|
+
...(options.fieldTest ? [`${options.packageManager} run forge -- agent onboard --target codex --json`] : []),
|
|
496
619
|
`${options.packageManager} run dev -- --open`,
|
|
497
620
|
`${options.packageManager} run verify`,
|
|
498
621
|
];
|
|
499
622
|
const gitHygiene = analyzeGitHygiene(targetDir);
|
|
500
623
|
|
|
501
624
|
return {
|
|
502
|
-
name:
|
|
625
|
+
name: appName,
|
|
503
626
|
template: options.template,
|
|
504
627
|
targetDir,
|
|
505
628
|
packageManager: options.packageManager,
|
|
506
629
|
installed,
|
|
507
630
|
gitInitialized,
|
|
631
|
+
fieldTest,
|
|
508
632
|
generated,
|
|
509
633
|
gitHygiene,
|
|
510
|
-
exitCode: 0,
|
|
511
|
-
message: `Created ${
|
|
634
|
+
exitCode: fieldTest.ok ? 0 : 1,
|
|
635
|
+
message: `Created ${appName} from template ${options.template}.`,
|
|
512
636
|
nextSteps,
|
|
513
637
|
};
|
|
514
638
|
}
|
|
@@ -520,6 +644,13 @@ export function formatNewHuman(result: NewCommandResult): string {
|
|
|
520
644
|
|
|
521
645
|
return [
|
|
522
646
|
result.message,
|
|
647
|
+
...(result.fieldTest.requested
|
|
648
|
+
? [
|
|
649
|
+
result.fieldTest.ok
|
|
650
|
+
? "Field-test setup completed: WorkOS, auth.md, check, and baseline commit are ready."
|
|
651
|
+
: `warning: field-test setup did not complete: ${result.fieldTest.steps.find((step) => !step.ok)?.name ?? "not-run"}`,
|
|
652
|
+
]
|
|
653
|
+
: []),
|
|
523
654
|
...(result.gitHygiene.ok
|
|
524
655
|
? ["Generated and operational Forge files are ignored by git."]
|
|
525
656
|
: [
|
|
@@ -531,3 +662,11 @@ export function formatNewHuman(result: NewCommandResult): string {
|
|
|
531
662
|
"",
|
|
532
663
|
].join("\n");
|
|
533
664
|
}
|
|
665
|
+
|
|
666
|
+
export function formatNewJson(result: NewCommandResult): string {
|
|
667
|
+
return `${JSON.stringify({
|
|
668
|
+
schemaVersion: "0.1.0",
|
|
669
|
+
ok: result.exitCode === 0,
|
|
670
|
+
...result,
|
|
671
|
+
}, null, 2)}\n`;
|
|
672
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function uniqueNextActions(actions: string[]): string[] {
|
|
2
|
+
return [...new Set(actions)].filter(Boolean);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function releasePrepareNextActions(): string[] {
|
|
6
|
+
return ["forge release prepare --env production", "forge release check --json"];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function releaseReadyNextActions(): string[] {
|
|
10
|
+
return ["forge artifacts verify --json", "forge sourcemaps check --json"];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function selfHostPrepareNextActions(): string[] {
|
|
14
|
+
return ["forge self-host compose", "forge self-host env", "forge self-host check --json"];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function selfHostReadyNextActions(): string[] {
|
|
18
|
+
return ["docker compose -f deploy/docker-compose.yml config", "forge release prepare --env production"];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function docsReadyNextActions(): string[] {
|
|
22
|
+
return ["bun test tests/docs/readthedocs.test.ts", "mkdocs build --strict"];
|
|
23
|
+
}
|