forgeos 0.1.0-alpha.7 → 0.1.0-alpha.71
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/.agents/skills/forge-agent-fabric/SKILL.md +178 -0
- package/.agents/skills/forge-agent-fabric/references/managed-workflows.md +95 -0
- package/.agents/skills/forge-agent-fabric/references/repository-analysis.md +102 -0
- package/.agents/skills/forge-agent-fabric/scripts/fabric.mjs +46 -0
- package/.agents/skills/forge-agent-fabric/scripts/repository.mjs +44 -0
- package/.npmignore +10 -0
- package/AGENTS.md +142 -90
- package/CHANGELOG.md +870 -9
- package/LICENSE +21 -0
- package/README.md +121 -6
- 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 +47 -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 +49 -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/agent-fabric-programs.md +151 -0
- package/docs/agent-fabric.md +582 -0
- package/docs/architecture/agent-fabric/PORTABLE_PROJECTS_PLAN.md +136 -0
- package/docs/architecture/agent-fabric/README.md +180 -0
- package/docs/architecture/agent-fabric/REPOSITORY_MANIFEST_PLAN.md +284 -0
- package/docs/architecture/agent-fabric/WORKFLOW_PROGRAM_V2_ADR.md +81 -0
- package/docs/architecture/agent-fabric/WORKFLOW_PROGRAM_V2_CORRECTIONS.md +39 -0
- package/docs/architecture/agent-fabric/WORKFLOW_PROGRAM_V2_CORRECTIONS_EVIDENCE.md +53 -0
- package/docs/architecture/agent-fabric/WORKFLOW_PROGRAM_V2_EVIDENCE.md +49 -0
- package/docs/architecture/agent-fabric/WORKFLOW_PROGRAM_V2_PLAN.md +590 -0
- package/docs/cair-protocol.md +103 -0
- package/docs/changelog.md +1070 -0
- package/docs/forge-protocol.md +189 -0
- package/docs/repository-agent-benchmark.md +179 -0
- package/docs/repository-analysis.md +139 -0
- package/docs/repository-context-quality.md +179 -0
- package/docs/repository-runtime-observation.md +82 -0
- package/examples/agent-fabric-v2/README.md +70 -0
- package/examples/agent-fabric-v2/item-child.workflow.ts +11 -0
- package/examples/agent-fabric-v2/make-request.mjs +4 -0
- package/examples/agent-fabric-v2/map-child.workflow.ts +10 -0
- package/examples/agent-fabric-v2/migrate.workflow.ts +35 -0
- package/examples/agent-fabric-v2/registry.example.json +256 -0
- package/examples/agent-fabric-v2/run-ui-fixture.ts +48 -0
- package/examples/agent-fabric-v2/ui-audit.workflow.ts +28 -0
- package/examples/agent-fabric-v2/ui-fixture-worker.cjs +36 -0
- package/examples/agent-fabric-v2/visual-population.json +13 -0
- package/examples/agent-fabric-v2/workers/check.mjs +2 -0
- package/examples/agent-fabric-v2/workers/common.mjs +7 -0
- package/examples/agent-fabric-v2/workers/discover.mjs +2 -0
- package/examples/agent-fabric-v2/workers/migrate.mjs +4 -0
- package/examples/agent-fabric-v2/workers/review.mjs +3 -0
- package/examples/go-billing/go.mod +7 -0
- package/examples/go-billing/main.go +120 -0
- package/examples/java-billing/pom.xml +60 -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 +60 -5
- package/schemas/agent-fabric/v0.1/control-event.schema.json +281 -0
- package/schemas/forge-manifest.schema.json +389 -0
- package/scripts/field-test-forgeos.mjs +1021 -0
- package/scripts/install-agent-fabric-skill.mjs +105 -0
- package/src/forge/_generated/releaseManifest.json +1 -2
- package/src/forge/_generated/releaseManifest.ts +3 -3
- package/src/forge/agent-adapters/index.ts +1592 -125
- package/src/forge/agent-adapters/types.ts +225 -1
- package/src/forge/agent-fabric/adapter.ts +131 -0
- package/src/forge/agent-fabric/attached-snapshot.ts +55 -0
- package/src/forge/agent-fabric/attached-task-contract.ts +105 -0
- package/src/forge/agent-fabric/attached-task-service.ts +127 -0
- package/src/forge/agent-fabric/attached-task-store.ts +109 -0
- package/src/forge/agent-fabric/authority.ts +298 -0
- package/src/forge/agent-fabric/canonical.ts +135 -0
- package/src/forge/agent-fabric/codex-adversarial-review.ts +229 -0
- package/src/forge/agent-fabric/codex-sdk-worker.ts +203 -0
- package/src/forge/agent-fabric/conductor.ts +754 -0
- package/src/forge/agent-fabric/dictionary.ts +12 -0
- package/src/forge/agent-fabric/errors.ts +32 -0
- package/src/forge/agent-fabric/hardened-conductor.ts +485 -0
- package/src/forge/agent-fabric/hardened-reducer.ts +211 -0
- package/src/forge/agent-fabric/index.ts +48 -0
- package/src/forge/agent-fabric/journal.ts +116 -0
- package/src/forge/agent-fabric/local-adaptive-digest-worker.mjs +26 -0
- package/src/forge/agent-fabric/local-adaptive-harness.ts +343 -0
- package/src/forge/agent-fabric/local-adaptive-service.ts +398 -0
- package/src/forge/agent-fabric/local-adaptive-worker.ts +146 -0
- package/src/forge/agent-fabric/local-approval-window.ts +211 -0
- package/src/forge/agent-fabric/local-change-review-service.ts +374 -0
- package/src/forge/agent-fabric/local-coding-worker.ts +285 -0
- package/src/forge/agent-fabric/local-control-store.ts +239 -0
- package/src/forge/agent-fabric/local-effect-broker.ts +348 -0
- package/src/forge/agent-fabric/local-evolution-approval.ts +81 -0
- package/src/forge/agent-fabric/local-evolution-profile.ts +87 -0
- package/src/forge/agent-fabric/local-evolution-registry.ts +427 -0
- package/src/forge/agent-fabric/local-evolution-service.ts +200 -0
- package/src/forge/agent-fabric/local-intelligence.ts +281 -0
- package/src/forge/agent-fabric/local-paths.ts +18 -0
- package/src/forge/agent-fabric/local-task-contract.ts +203 -0
- package/src/forge/agent-fabric/local-task-inbox.ts +543 -0
- package/src/forge/agent-fabric/local-task-server.ts +374 -0
- package/src/forge/agent-fabric/local-task-service.ts +982 -0
- package/src/forge/agent-fabric/local-verification.ts +551 -0
- package/src/forge/agent-fabric/managed-environment.ts +205 -0
- package/src/forge/agent-fabric/managed-run-contract.ts +103 -0
- package/src/forge/agent-fabric/managed-run-service.ts +401 -0
- package/src/forge/agent-fabric/managed-run-store.ts +165 -0
- package/src/forge/agent-fabric/managed-workspace.ts +253 -0
- package/src/forge/agent-fabric/p0a.ts +104 -0
- package/src/forge/agent-fabric/p0b-model-adapter.ts +434 -0
- package/src/forge/agent-fabric/planning.ts +155 -0
- package/src/forge/agent-fabric/program-api.ts +37 -0
- package/src/forge/agent-fabric/program-contract.ts +283 -0
- package/src/forge/agent-fabric/program-dsl.ts +126 -0
- package/src/forge/agent-fabric/program-evidence.ts +22 -0
- package/src/forge/agent-fabric/program-image.ts +15 -0
- package/src/forge/agent-fabric/program-lock.ts +50 -0
- package/src/forge/agent-fabric/program-owner.ts +16 -0
- package/src/forge/agent-fabric/program-scheduler.ts +38 -0
- package/src/forge/agent-fabric/program-service.ts +793 -0
- package/src/forge/agent-fabric/program-store.ts +142 -0
- package/src/forge/agent-fabric/program-structure.ts +65 -0
- package/src/forge/agent-fabric/program-types.ts +110 -0
- package/src/forge/agent-fabric/program-view.ts +12 -0
- package/src/forge/agent-fabric/program-worker.ts +108 -0
- package/src/forge/agent-fabric/project-profile.ts +50 -0
- package/src/forge/agent-fabric/project-registry.ts +120 -0
- package/src/forge/agent-fabric/project-runtime.ts +85 -0
- package/src/forge/agent-fabric/readiness.ts +26 -0
- package/src/forge/agent-fabric/reducer.ts +863 -0
- package/src/forge/agent-fabric/repository-context.ts +83 -0
- package/src/forge/agent-fabric/resource-ledger.ts +266 -0
- package/src/forge/agent-fabric/serialized-local-adapter.ts +60 -0
- package/src/forge/agent-fabric/types.ts +424 -0
- package/src/forge/agent-fabric/validation.ts +500 -0
- package/src/forge/agent-fabric/workflow-engine.ts +218 -0
- package/src/forge/agent-fabric/workflow-task-actions.ts +104 -0
- package/src/forge/agent-fabric/workflow-templates.ts +11 -0
- package/src/forge/agent-memory/bridge.ts +1728 -0
- package/src/forge/agent-memory/context-pack.ts +284 -0
- package/src/forge/agent-memory/hook-runner.ts +331 -0
- package/src/forge/agent-memory/mcp.ts +597 -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 +343 -0
- package/src/forge/agent-memory/sources/codex.ts +161 -0
- package/src/forge/agent-memory/sources/cursor.ts +35 -0
- package/src/forge/agent-memory/types.ts +215 -0
- package/src/forge/bench.ts +248 -0
- package/src/forge/brownfield-import/index.ts +896 -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 +118 -0
- package/src/forge/cair/query.ts +478 -0
- package/src/forge/cair/snapshot.ts +315 -0
- package/src/forge/cair/types.ts +255 -0
- package/src/forge/cli/adaptive.ts +51 -0
- package/src/forge/cli/ai.ts +16 -1
- package/src/forge/cli/auth.ts +459 -15
- 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 +418 -0
- package/src/forge/cli/codex-app-server.ts +877 -0
- package/src/forge/cli/commands.ts +1859 -20
- package/src/forge/cli/db.ts +209 -2
- package/src/forge/cli/deploy.ts +1339 -0
- package/src/forge/cli/deps.ts +150 -23
- package/src/forge/cli/dev.ts +1137 -53
- package/src/forge/cli/docs.ts +265 -0
- package/src/forge/cli/doctor.ts +297 -0
- package/src/forge/cli/env-placeholders.ts +62 -0
- package/src/forge/cli/evolution.ts +40 -0
- package/src/forge/cli/fabric.ts +253 -0
- package/src/forge/cli/field-test.ts +568 -0
- package/src/forge/cli/golden-path.ts +487 -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 +196 -3
- package/src/forge/cli/new.ts +169 -17
- package/src/forge/cli/next-actions.ts +23 -0
- package/src/forge/cli/output.ts +398 -6
- package/src/forge/cli/parse.ts +1377 -38
- 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/repository.ts +151 -0
- package/src/forge/cli/run.ts +42 -0
- package/src/forge/cli/secrets.ts +137 -1
- package/src/forge/cli/seed.ts +581 -0
- package/src/forge/cli/self-host.ts +56 -14
- package/src/forge/cli/studio.ts +2282 -0
- package/src/forge/cli/verify.ts +1458 -32
- package/src/forge/cli/windows.ts +23 -0
- package/src/forge/cli/workos.ts +3509 -0
- package/src/forge/compiler/agent-contract/build.ts +728 -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/tsconfig-hash.ts +41 -4
- 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/build.ts +29 -1
- 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 +38 -0
- package/src/forge/compiler/diagnostics/create.ts +28 -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 +217 -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 +991 -33
- 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 +1439 -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 +249 -10
- package/src/forge/compiler/orchestrator/profile.ts +65 -0
- package/src/forge/compiler/orchestrator/run.ts +101 -33
- 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-graph/dts-extractor.ts +14 -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-manager/version.ts +36 -12
- 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/profiles.ts +81 -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 +76 -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/broker-runner.mjs +5 -0
- package/src/forge/delta/broker.ts +429 -0
- package/src/forge/delta/classifier.ts +52 -0
- package/src/forge/delta/explain.ts +238 -0
- package/src/forge/delta/git-observer.ts +67 -0
- package/src/forge/delta/ids.ts +44 -0
- package/src/forge/delta/index.ts +25 -0
- package/src/forge/delta/process-identity.ts +37 -0
- package/src/forge/delta/queue-status.ts +190 -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 +1139 -0
- package/src/forge/delta/store.ts +3329 -0
- package/src/forge/delta/timeline.ts +178 -0
- package/src/forge/dev/server.ts +1061 -22
- package/src/forge/dev/types.ts +15 -1
- package/src/forge/dev/watch.ts +17 -7
- package/src/forge/dev-console/cycle.ts +285 -33
- package/src/forge/dev-console/types.ts +47 -1
- package/src/forge/impact/index.ts +222 -30
- 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 +42 -6
- package/src/forge/make/templates.ts +211 -4
- 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/repository-analysis/adapters/common.ts +72 -0
- package/src/forge/repository-analysis/adapters/docker.ts +185 -0
- package/src/forge/repository-analysis/adapters/java.ts +133 -0
- package/src/forge/repository-analysis/adapters/typescript.ts +350 -0
- package/src/forge/repository-analysis/adapters/vue.ts +71 -0
- package/src/forge/repository-analysis/analyze.ts +434 -0
- package/src/forge/repository-analysis/benchmark.ts +336 -0
- package/src/forge/repository-analysis/cache-gc.ts +154 -0
- package/src/forge/repository-analysis/check-selection.ts +123 -0
- package/src/forge/repository-analysis/context-node.ts +17 -0
- package/src/forge/repository-analysis/context.ts +456 -0
- package/src/forge/repository-analysis/http-resolution.ts +135 -0
- package/src/forge/repository-analysis/identity.ts +45 -0
- package/src/forge/repository-analysis/index.ts +18 -0
- package/src/forge/repository-analysis/nuxt-resolution.ts +188 -0
- package/src/forge/repository-analysis/quality.ts +60 -0
- package/src/forge/repository-analysis/retrieval.ts +309 -0
- package/src/forge/repository-analysis/runtime-artifacts.ts +195 -0
- package/src/forge/repository-analysis/runtime-observation.ts +325 -0
- package/src/forge/repository-analysis/scanner.ts +174 -0
- package/src/forge/repository-analysis/storage.ts +193 -0
- package/src/forge/repository-analysis/test-associations.ts +59 -0
- package/src/forge/repository-analysis/types.ts +99 -0
- package/src/forge/repository-manifest/index.ts +178 -0
- package/src/forge/repository-manifest/types.ts +63 -0
- package/src/forge/review/index.ts +162 -12
- package/src/forge/review/types.ts +15 -0
- package/src/forge/runtime/ai/providers.ts +19 -4
- 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 +285 -2
- package/src/forge/runtime/executor.ts +129 -16
- package/src/forge/runtime/external/bridge.ts +663 -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 +71 -7
- package/src/forge/ui/index.ts +831 -19
- package/src/forge/ui/types.ts +3 -1
- 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 +292 -0
- package/src/forge/workspace/forge-cli.ts +42 -0
- package/src/forge/workspace/git-summary.ts +393 -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 +34 -0
- package/templates/agent-workroom/pnpm-workspace.yaml +2 -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 +13 -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 +20 -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/agent-workroom/web/vite.config.ts +36 -0
- package/templates/b2b-support-web/package.json +2 -0
- package/templates/b2b-support-web/pnpm-workspace.yaml +2 -0
- package/templates/b2b-support-web/web/app/page.tsx +2 -2
- package/templates/b2b-support-web/web/lib/forge.ts +9 -2
- package/templates/b2b-support-web/web/next.config.ts +24 -0
- package/templates/b2b-support-web/web/package.json +1 -1
- package/templates/minimal-web/package.json +2 -1
- package/templates/minimal-web/pnpm-workspace.yaml +2 -0
- package/templates/minimal-web/web/index.html +1 -0
- package/templates/minimal-web/web/src/App.tsx +12 -6
- package/templates/minimal-web/web/src/lib/forge.ts +9 -2
- package/templates/minimal-web/web/src/styles.css +34 -0
- package/templates/minimal-web/web/vite.config.ts +36 -0
- package/templates/nuxt-web/.vscode/settings.json +14 -0
- package/templates/nuxt-web/.yarnrc.yml +1 -0
- package/templates/nuxt-web/README.md +30 -0
- package/templates/nuxt-web/forge.config.ts +3 -0
- package/templates/nuxt-web/package.json +37 -0
- package/templates/nuxt-web/pnpm-workspace.yaml +2 -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 +22 -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/templates/vendor-access/.vscode/settings.json +14 -0
- package/templates/vendor-access/README.md +30 -0
- package/templates/vendor-access/forge.config.ts +3 -0
- package/templates/vendor-access/package.json +35 -0
- package/templates/vendor-access/pnpm-workspace.yaml +2 -0
- package/templates/vendor-access/src/commands/addEvidence.ts +42 -0
- package/templates/vendor-access/src/commands/approveAccessRequest.ts +43 -0
- package/templates/vendor-access/src/commands/createAccessRequest.ts +49 -0
- package/templates/vendor-access/src/commands/seedVendorAccessDemo.ts +200 -0
- package/templates/vendor-access/src/forge/schema.ts +74 -0
- package/templates/vendor-access/src/policies.ts +11 -0
- package/templates/vendor-access/src/queries/listVendorAccessDashboard.ts +24 -0
- package/templates/vendor-access/src/queries/liveVendorAccessDashboard.ts +24 -0
- package/templates/vendor-access/tsconfig.json +17 -0
- package/templates/vendor-access/web/index.html +13 -0
- package/templates/vendor-access/web/package.json +21 -0
- package/templates/vendor-access/web/src/App.tsx +573 -0
- package/templates/vendor-access/web/src/lib/forge.ts +20 -0
- package/templates/vendor-access/web/src/main.tsx +205 -0
- package/templates/vendor-access/web/src/styles.css +682 -0
- package/templates/vendor-access/web/tsconfig.json +18 -0
- package/templates/vendor-access/web/vite.config.ts +36 -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 -14937
- 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 -3452
- 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,120 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { lstat, mkdir, readFile, realpath, rename, unlink, writeFile } from "node:fs/promises";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { basename, dirname, isAbsolute, join, resolve } from "node:path";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
|
|
8
|
+
const execute = promisify(execFile);
|
|
9
|
+
export interface FabricProject { id: string; root: string }
|
|
10
|
+
export interface FabricRegistryOptions { registryDirectory?: string; id?: string }
|
|
11
|
+
const validId = (id: string) => /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$/.test(id);
|
|
12
|
+
const identity = (root: string) => process.platform === "win32" ? root.toLowerCase() : root;
|
|
13
|
+
const absent = (error: unknown) => (error as NodeJS.ErrnoException).code === "ENOENT";
|
|
14
|
+
const busy = (error: unknown) => ["EEXIST", "EPERM", "EACCES"].includes((error as NodeJS.ErrnoException).code ?? "");
|
|
15
|
+
|
|
16
|
+
/** Recover only a validated startup lock whose process demonstrably no longer exists. */
|
|
17
|
+
export async function recoverFabricLock(path: string): Promise<boolean> {
|
|
18
|
+
const recovery = `${path}.recovery`;
|
|
19
|
+
await checkPath(recovery);
|
|
20
|
+
try { await writeFile(recovery, JSON.stringify({ pid: process.pid }), { flag: "wx", mode: 0o600 }); }
|
|
21
|
+
catch (error) { if (busy(error)) return false; throw error; }
|
|
22
|
+
try {
|
|
23
|
+
let contents: string;
|
|
24
|
+
try {
|
|
25
|
+
const stat = await lstat(path);
|
|
26
|
+
if (stat.isSymbolicLink() || !stat.isFile() || stat.size > 1024) throw new Error("Invalid Agent Fabric startup lock");
|
|
27
|
+
contents = await readFile(path, "utf8");
|
|
28
|
+
} catch (error) { if (absent(error)) return true; if (busy(error)) return false; throw error; }
|
|
29
|
+
if (!contents) return false; // Another process may still be completing exclusive creation.
|
|
30
|
+
let pid: unknown;
|
|
31
|
+
try { pid = (JSON.parse(contents) as { pid?: unknown })?.pid; } catch { throw new Error("Invalid Agent Fabric startup lock"); }
|
|
32
|
+
if (!Number.isSafeInteger(pid) || (pid as number) <= 0) throw new Error("Invalid Agent Fabric startup lock pid");
|
|
33
|
+
try { process.kill(pid as number, 0); return false; }
|
|
34
|
+
catch (error) { if ((error as NodeJS.ErrnoException).code !== "ESRCH") return false; }
|
|
35
|
+
// Locks are only replaced after removal. Compare bytes before deleting our observed lock.
|
|
36
|
+
try { if (await readFile(path, "utf8") !== contents) return false; await unlink(path); return true; }
|
|
37
|
+
catch (error) { if (absent(error)) return true; throw error; }
|
|
38
|
+
} finally { await unlink(recovery); }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Git is the project authority, including when invoked from a monorepo subdirectory. */
|
|
42
|
+
export async function resolveFabricRoot(directory: string): Promise<string> {
|
|
43
|
+
const cwd = await realpath(resolve(directory));
|
|
44
|
+
const { stdout } = await execute("git", ["rev-parse", "--show-toplevel"], { cwd, encoding: "utf8", windowsHide: true, timeout: 10_000, maxBuffer: 16_384 });
|
|
45
|
+
const root = await realpath(stdout.trim());
|
|
46
|
+
await execute("git", ["rev-parse", "--verify", "HEAD"], { cwd: root, windowsHide: true, timeout: 10_000, maxBuffer: 16_384 });
|
|
47
|
+
return root;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function fabricRegistryDirectory(options: FabricRegistryOptions = {}): string {
|
|
51
|
+
return resolve(options.registryDirectory ?? join(homedir(), ".forge", "agent-fabric"));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function checkPath(path: string): Promise<void> {
|
|
55
|
+
const parent = dirname(path);
|
|
56
|
+
if (parent !== path) await checkPath(parent);
|
|
57
|
+
const stat = await lstat(path).catch(error => { if (absent(error)) return undefined; throw error; });
|
|
58
|
+
if (stat?.isSymbolicLink()) throw new Error("Agent Fabric registry cannot traverse symbolic links");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function readRegistry(directory: string): Promise<FabricProject[]> {
|
|
62
|
+
const path = join(directory, "projects.json");
|
|
63
|
+
await checkPath(path);
|
|
64
|
+
let data: Buffer;
|
|
65
|
+
try { const stat = await lstat(path); if (!stat.isFile() || stat.size > 256 * 1024) throw new Error("Invalid Agent Fabric registry file"); data = await readFile(path); }
|
|
66
|
+
catch (error) { if (absent(error)) return []; throw error; }
|
|
67
|
+
const value = JSON.parse(data.toString("utf8")) as { schemaVersion?: unknown; projects?: unknown };
|
|
68
|
+
if (!value || value.schemaVersion !== 1 || !Array.isArray(value.projects) || value.projects.length > 1000) throw new Error("Invalid Agent Fabric project registry");
|
|
69
|
+
const entries = value.projects as FabricProject[];
|
|
70
|
+
const ids = new Set<string>(), roots = new Set<string>();
|
|
71
|
+
for (const entry of entries) {
|
|
72
|
+
if (!entry || Object.keys(entry).sort().join(",") !== "id,root" || typeof entry.id !== "string" || !validId(entry.id) || typeof entry.root !== "string" || !isAbsolute(entry.root) || ids.has(entry.id) || roots.has(identity(entry.root))) throw new Error("Invalid or duplicate Agent Fabric project registration");
|
|
73
|
+
ids.add(entry.id); roots.add(identity(entry.root));
|
|
74
|
+
}
|
|
75
|
+
return entries;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export async function listFabricProjects(options: FabricRegistryOptions = {}): Promise<FabricProject[]> {
|
|
79
|
+
return readRegistry(fabricRegistryDirectory(options));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export async function registerFabricProject(directory: string, options: FabricRegistryOptions = {}): Promise<FabricProject> {
|
|
83
|
+
const root = await resolveFabricRoot(directory);
|
|
84
|
+
const registry = fabricRegistryDirectory(options);
|
|
85
|
+
const id = options.id ?? `${basename(root).replace(/[^a-zA-Z0-9._-]/g, "-").replace(/^[^a-zA-Z0-9]+/, "").slice(0, 48) || "project"}-${createHash("sha256").update(identity(root)).digest("hex").slice(0, 12)}`;
|
|
86
|
+
if (!validId(id)) throw new Error("Invalid Agent Fabric project id");
|
|
87
|
+
await checkPath(registry); await mkdir(registry, { recursive: true, mode: 0o700 });
|
|
88
|
+
const lock = join(registry, "projects.lock");
|
|
89
|
+
const deadline = Date.now() + 5000;
|
|
90
|
+
for (;;) {
|
|
91
|
+
await checkPath(lock);
|
|
92
|
+
try { await writeFile(lock, JSON.stringify({ pid: process.pid }), { flag: "wx", mode: 0o600 }); break; }
|
|
93
|
+
catch (error) { if (!busy(error)) throw error; if (Date.now() >= deadline) throw new Error("Agent Fabric project registry is busy; retry or inspect projects.lock and projects.lock.recovery after their owners exit"); if (await recoverFabricLock(lock)) continue; await new Promise(resolve => setTimeout(resolve, 30)); }
|
|
94
|
+
}
|
|
95
|
+
const stage = join(registry, `projects-${randomUUID()}.tmp`);
|
|
96
|
+
try {
|
|
97
|
+
const entries = await readRegistry(registry);
|
|
98
|
+
const sameRoot = entries.find(entry => identity(entry.root) === identity(root));
|
|
99
|
+
if (sameRoot) { if (options.id && sameRoot.id !== options.id) throw new Error("Project already registered with another id"); return sameRoot; }
|
|
100
|
+
if (entries.some(entry => entry.id === id)) throw new Error("Project id already belongs to another repository");
|
|
101
|
+
if (entries.length >= 1000) throw new Error("Agent Fabric project registry is full");
|
|
102
|
+
const project = { id, root }; entries.push(project); entries.sort((a, b) => a.id.localeCompare(b.id));
|
|
103
|
+
await writeFile(stage, `${JSON.stringify({ schemaVersion: 1, projects: entries }, null, 2)}\n`, { flag: "wx", mode: 0o600 });
|
|
104
|
+
await rename(stage, join(registry, "projects.json"));
|
|
105
|
+
return project;
|
|
106
|
+
} finally {
|
|
107
|
+
try { await unlink(stage).catch(error => { if (!absent(error)) throw error; }); }
|
|
108
|
+
finally { if (await readFile(lock, "utf8") === JSON.stringify({ pid: process.pid })) await unlink(lock); }
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Recheck the registration so moved paths or replaced symlinks cannot redirect a run. */
|
|
113
|
+
export async function resolveFabricProject(id: string, options: FabricRegistryOptions = {}): Promise<string> {
|
|
114
|
+
if (!validId(id)) throw new Error("Invalid Agent Fabric project id");
|
|
115
|
+
const project = (await listFabricProjects(options)).find(entry => entry.id === id);
|
|
116
|
+
if (!project) throw new Error("Agent Fabric project is not registered");
|
|
117
|
+
const root = await resolveFabricRoot(project.root);
|
|
118
|
+
if (identity(root) !== identity(project.root)) throw new Error("Agent Fabric registered repository root changed; register its new location explicitly");
|
|
119
|
+
return root;
|
|
120
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { spawn, execFile } from "node:child_process";
|
|
2
|
+
import { lstat, mkdir, open, readFile, unlink, writeFile } from "node:fs/promises";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import { localFabricPath } from "./local-paths.ts";
|
|
6
|
+
import { probeLocalOwner } from "./local-task-server.ts";
|
|
7
|
+
import { recoverFabricLock, resolveFabricRoot } from "./project-registry.ts";
|
|
8
|
+
import { readFabricProfile } from "./project-profile.ts";
|
|
9
|
+
|
|
10
|
+
const execute = promisify(execFile);
|
|
11
|
+
const cliPath = fileURLToPath(new URL("../../../bin/forge.mjs", import.meta.url));
|
|
12
|
+
export interface FabricOwnerOptions { cliPath?: string; nodeExecutable?: string; startupTimeoutMs?: number }
|
|
13
|
+
const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
|
14
|
+
|
|
15
|
+
export async function fabricProjectDoctor(directory: string) {
|
|
16
|
+
const root = await resolveFabricRoot(directory);
|
|
17
|
+
const profile = await readFabricProfile(root);
|
|
18
|
+
const owner = await probeLocalOwner(root).then(value => ({ running: value !== null, ...(value ?? {}) })).catch(error => ({ running: false, error: error instanceof Error ? error.message : "Owner probe failed" }));
|
|
19
|
+
const sdkAvailable = await import("@openai/codex-sdk").then(module => typeof module.Codex === "function").catch(() => false);
|
|
20
|
+
const auth = await execute("codex", ["login", "status"], { windowsHide: true, timeout: 5000, maxBuffer: 8192 }).then(() => "authenticated" as const).catch(() => "not_verified" as const);
|
|
21
|
+
return { ok: sdkAvailable && !("error" in owner), repositoryRoot: root,
|
|
22
|
+
runtime: { cliPath, nodeExecutable: process.execPath, sdkAvailable }, owner, profile,
|
|
23
|
+
codexAuthentication: auth, managedExecution: true, hooksRequired: false,
|
|
24
|
+
nextActions: [...(!sdkAvailable ? ["Install the selected Forge runtime's dependencies"] : []), ...(!owner.running ? ["forge fabric ensure-owner --json"] : []), ...(auth !== "authenticated" ? ["codex login status"] : [])] };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Start only an owner, never a worker, and reuse an authenticated owner for this exact root. */
|
|
28
|
+
export async function ensureFabricOwner(directory: string, options: FabricOwnerOptions = {}): Promise<{ repositoryRoot: string; pid: number; port: number; started: boolean }> {
|
|
29
|
+
const root = await resolveFabricRoot(directory);
|
|
30
|
+
const existing = await probeLocalOwner(root);
|
|
31
|
+
if (existing) return { ...existing, started: false };
|
|
32
|
+
const state = localFabricPath(root);
|
|
33
|
+
await mkdir(state, { recursive: true, mode: 0o700 });
|
|
34
|
+
const lock = localFabricPath(root, "owner-start.lock");
|
|
35
|
+
const deadline = Date.now() + (options.startupTimeoutMs ?? 30_000);
|
|
36
|
+
for (;;) {
|
|
37
|
+
try { await writeFile(lock, JSON.stringify({ pid: process.pid }), { flag: "wx", mode: 0o600 }); break; }
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (!["EEXIST", "EPERM", "EACCES"].includes((error as NodeJS.ErrnoException).code ?? "")) throw error;
|
|
40
|
+
const peer = await probeLocalOwner(root); if (peer) return { ...peer, started: false };
|
|
41
|
+
// Never recover a live or unverified process's lock solely on a timer.
|
|
42
|
+
if (Date.now() >= deadline) throw new Error("Agent Fabric owner startup is busy; inspect owner-start.lock and owner-start.lock.recovery after their processes exit");
|
|
43
|
+
if (await recoverFabricLock(lock)) continue;
|
|
44
|
+
await delay(100);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const peer = await probeLocalOwner(root); if (peer) return { ...peer, started: false };
|
|
49
|
+
const logPath = localFabricPath(root, "owner.log");
|
|
50
|
+
const stat = await lstat(logPath).catch(error => { if ((error as NodeJS.ErrnoException).code === "ENOENT") return undefined; throw error; });
|
|
51
|
+
if (stat && !stat.isFile()) throw new Error("Agent Fabric owner log is not a regular file");
|
|
52
|
+
let node = options.nodeExecutable ?? process.execPath;
|
|
53
|
+
if (!options.nodeExecutable && process.versions.bun) node = (await execute("node", ["-p", "process.execPath"], { windowsHide: true, timeout: 5000 })).stdout.trim();
|
|
54
|
+
const log = await open(logPath, "a", 0o600);
|
|
55
|
+
let child: ReturnType<typeof spawn>;
|
|
56
|
+
let failure: string | undefined;
|
|
57
|
+
try {
|
|
58
|
+
child = spawn(node, [options.cliPath ?? cliPath, "fabric", "serve", "--json"], {
|
|
59
|
+
cwd: root, detached: true, windowsHide: true, stdio: ["ignore", log.fd, log.fd],
|
|
60
|
+
});
|
|
61
|
+
child.once("error", error => { failure = error.message; });
|
|
62
|
+
child.once("exit", (code, signal) => { failure = `owner exited (${code ?? signal})`; });
|
|
63
|
+
} finally { await log.close(); }
|
|
64
|
+
child.unref();
|
|
65
|
+
try {
|
|
66
|
+
while (Date.now() < deadline) {
|
|
67
|
+
const owner = await probeLocalOwner(root);
|
|
68
|
+
if (owner) {
|
|
69
|
+
if (owner.pid !== child.pid) child.kill();
|
|
70
|
+
return { ...owner, started: owner.pid === child.pid };
|
|
71
|
+
}
|
|
72
|
+
if (failure) throw new Error(`Agent Fabric ${failure}; inspect ${logPath}`);
|
|
73
|
+
await delay(100);
|
|
74
|
+
}
|
|
75
|
+
throw new Error(`Agent Fabric owner startup timed out; inspect ${logPath}`);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
// Only this exact spawned child is ours to stop if startup did not complete.
|
|
78
|
+
child.kill();
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
} finally {
|
|
82
|
+
const contents = await readFile(lock, "utf8");
|
|
83
|
+
if (contents === JSON.stringify({ pid: process.pid })) await unlink(lock);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AttachedSnapshot, AttachedTaskState } from "./attached-task-contract.ts";
|
|
2
|
+
import { nextWorkflow } from "./workflow-engine.ts";
|
|
3
|
+
import { workflowSourceProblems } from "./workflow-task-actions.ts";
|
|
4
|
+
|
|
5
|
+
export interface AttachedReadiness { ready: boolean; snapshotDigest: string; provenance: "agent_reported"; unmet: { code: string; detail: string }[] }
|
|
6
|
+
/** A gate over attributed reports; this service never claims to have run their commands. */
|
|
7
|
+
export function attachedReadiness(state: AttachedTaskState, snapshot: AttachedSnapshot): AttachedReadiness {
|
|
8
|
+
const unmet: AttachedReadiness["unmet"] = [];
|
|
9
|
+
const add = (code: string, detail: string) => unmet.push({ code, detail });
|
|
10
|
+
if (!state.review) add("missing_review", "A distinct reviewer must report on this snapshot");
|
|
11
|
+
else {
|
|
12
|
+
if (state.review.snapshotDigest !== snapshot.digest) add("stale_review", "Working tree changed after review");
|
|
13
|
+
if (state.review.verdict !== "approved") add("changes_requested", "Review requests changes");
|
|
14
|
+
for (const finding of state.review.findings) if (!finding.resolved) add("unresolved_finding", finding.findingId);
|
|
15
|
+
}
|
|
16
|
+
for (const checkId of state.requiredChecks) {
|
|
17
|
+
const check = state.verifications.find((item) => item.checkId === checkId && item.snapshotDigest === snapshot.digest);
|
|
18
|
+
if (!check) add("missing_verification", checkId);
|
|
19
|
+
else if (check.outcome !== "passed") add(`${check.outcome}_verification`, checkId);
|
|
20
|
+
}
|
|
21
|
+
for (const criterion of state.criteria) if (!state.coverage.some((item) => item.criterionId === criterion.criterionId && item.snapshotDigest === snapshot.digest)) add("uncovered_criterion", criterion.criterionId);
|
|
22
|
+
for (const attempt of state.attempts) if (attempt.status === "running" || attempt.status === "uncertain") add(`${attempt.status}_attempt`, attempt.attemptId);
|
|
23
|
+
if (state.workflow && !nextWorkflow(state.workflow).complete) add("incomplete_workflow", "Required workflow steps remain incomplete");
|
|
24
|
+
for (const problem of workflowSourceProblems(state, snapshot.digest)) add("stale_workflow", String(problem));
|
|
25
|
+
return { ready: unmet.length === 0, snapshotDigest: snapshot.digest, provenance: "agent_reported", unmet };
|
|
26
|
+
}
|