@xemahq/biome-sdk 0.1.1
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/LICENSE +201 -0
- package/README.md +62 -0
- package/dist/adapter/index.d.ts +7 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/adapter/index.js +23 -0
- package/dist/adapter/index.js.map +1 -0
- package/dist/adapter/lib/action.d.ts +25 -0
- package/dist/adapter/lib/action.d.ts.map +1 -0
- package/dist/adapter/lib/action.js +3 -0
- package/dist/adapter/lib/action.js.map +1 -0
- package/dist/adapter/lib/provider-module.d.ts +41 -0
- package/dist/adapter/lib/provider-module.d.ts.map +1 -0
- package/dist/adapter/lib/provider-module.js +7 -0
- package/dist/adapter/lib/provider-module.js.map +1 -0
- package/dist/adapter/lib/resource.d.ts +25 -0
- package/dist/adapter/lib/resource.d.ts.map +1 -0
- package/dist/adapter/lib/resource.js +3 -0
- package/dist/adapter/lib/resource.js.map +1 -0
- package/dist/adapter/lib/result.d.ts +18 -0
- package/dist/adapter/lib/result.d.ts.map +1 -0
- package/dist/adapter/lib/result.js +12 -0
- package/dist/adapter/lib/result.js.map +1 -0
- package/dist/adapter/lib/sidecar-contract.d.ts +91 -0
- package/dist/adapter/lib/sidecar-contract.d.ts.map +1 -0
- package/dist/adapter/lib/sidecar-contract.js +19 -0
- package/dist/adapter/lib/sidecar-contract.js.map +1 -0
- package/dist/adapter/lib/webhook.d.ts +49 -0
- package/dist/adapter/lib/webhook.d.ts.map +1 -0
- package/dist/adapter/lib/webhook.js +3 -0
- package/dist/adapter/lib/webhook.js.map +1 -0
- package/dist/agent-workspace/index.d.ts +8 -0
- package/dist/agent-workspace/index.d.ts.map +1 -0
- package/dist/agent-workspace/index.js +24 -0
- package/dist/agent-workspace/index.js.map +1 -0
- package/dist/agent-workspace/lib/errors/error-codes.d.ts +16 -0
- package/dist/agent-workspace/lib/errors/error-codes.d.ts.map +1 -0
- package/dist/agent-workspace/lib/errors/error-codes.js +37 -0
- package/dist/agent-workspace/lib/errors/error-codes.js.map +1 -0
- package/dist/agent-workspace/lib/errors/index.d.ts +4 -0
- package/dist/agent-workspace/lib/errors/index.d.ts.map +1 -0
- package/dist/agent-workspace/lib/errors/index.js +20 -0
- package/dist/agent-workspace/lib/errors/index.js.map +1 -0
- package/dist/agent-workspace/lib/errors/mount-plan-error.d.ts +16 -0
- package/dist/agent-workspace/lib/errors/mount-plan-error.d.ts.map +1 -0
- package/dist/agent-workspace/lib/errors/mount-plan-error.js +26 -0
- package/dist/agent-workspace/lib/errors/mount-plan-error.js.map +1 -0
- package/dist/agent-workspace/lib/errors/mount-resolver-error.d.ts +34 -0
- package/dist/agent-workspace/lib/errors/mount-resolver-error.d.ts.map +1 -0
- package/dist/agent-workspace/lib/errors/mount-resolver-error.js +50 -0
- package/dist/agent-workspace/lib/errors/mount-resolver-error.js.map +1 -0
- package/dist/agent-workspace/lib/mount-resolver.d.ts +10 -0
- package/dist/agent-workspace/lib/mount-resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/mount-resolver.js +3 -0
- package/dist/agent-workspace/lib/mount-resolver.js.map +1 -0
- package/dist/agent-workspace/lib/mount-source.d.ts +4 -0
- package/dist/agent-workspace/lib/mount-source.d.ts.map +1 -0
- package/dist/agent-workspace/lib/mount-source.js +3 -0
- package/dist/agent-workspace/lib/mount-source.js.map +1 -0
- package/dist/agent-workspace/lib/refid-resolver.d.ts +23 -0
- package/dist/agent-workspace/lib/refid-resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/refid-resolver.js +103 -0
- package/dist/agent-workspace/lib/refid-resolver.js.map +1 -0
- package/dist/agent-workspace/lib/registries.d.ts +30 -0
- package/dist/agent-workspace/lib/registries.d.ts.map +1 -0
- package/dist/agent-workspace/lib/registries.js +88 -0
- package/dist/agent-workspace/lib/registries.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/agent-definition.resolver.d.ts +13 -0
- package/dist/agent-workspace/lib/resolvers/agent-definition.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/agent-definition.resolver.js +25 -0
- package/dist/agent-workspace/lib/resolvers/agent-definition.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/artifact-store-collection.resolver.d.ts +13 -0
- package/dist/agent-workspace/lib/resolvers/artifact-store-collection.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/artifact-store-collection.resolver.js +28 -0
- package/dist/agent-workspace/lib/resolvers/artifact-store-collection.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/artifact-version.resolver.d.ts +13 -0
- package/dist/agent-workspace/lib/resolvers/artifact-version.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/artifact-version.resolver.js +25 -0
- package/dist/agent-workspace/lib/resolvers/artifact-version.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/clients.d.ts +122 -0
- package/dist/agent-workspace/lib/resolvers/clients.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/clients.js +3 -0
- package/dist/agent-workspace/lib/resolvers/clients.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/deliverable-specs.resolver.d.ts +13 -0
- package/dist/agent-workspace/lib/resolvers/deliverable-specs.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/deliverable-specs.resolver.js +24 -0
- package/dist/agent-workspace/lib/resolvers/deliverable-specs.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/deliverables.resolver.d.ts +13 -0
- package/dist/agent-workspace/lib/resolvers/deliverables.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/deliverables.resolver.js +28 -0
- package/dist/agent-workspace/lib/resolvers/deliverables.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/index.d.ts +20 -0
- package/dist/agent-workspace/lib/resolvers/index.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/index.js +36 -0
- package/dist/agent-workspace/lib/resolvers/index.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/instruction-section.resolver.d.ts +13 -0
- package/dist/agent-workspace/lib/resolvers/instruction-section.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/instruction-section.resolver.js +22 -0
- package/dist/agent-workspace/lib/resolvers/instruction-section.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/kb-pages.resolver.d.ts +13 -0
- package/dist/agent-workspace/lib/resolvers/kb-pages.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/kb-pages.resolver.js +36 -0
- package/dist/agent-workspace/lib/resolvers/kb-pages.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/kb-space.resolver.d.ts +13 -0
- package/dist/agent-workspace/lib/resolvers/kb-space.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/kb-space.resolver.js +26 -0
- package/dist/agent-workspace/lib/resolvers/kb-space.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/rendered-agents-md.resolver.d.ts +13 -0
- package/dist/agent-workspace/lib/resolvers/rendered-agents-md.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/rendered-agents-md.resolver.js +23 -0
- package/dist/agent-workspace/lib/resolvers/rendered-agents-md.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/rendered-context-json.resolver.d.ts +13 -0
- package/dist/agent-workspace/lib/resolvers/rendered-context-json.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/rendered-context-json.resolver.js +24 -0
- package/dist/agent-workspace/lib/resolvers/rendered-context-json.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/rendered-system-overlay.resolver.d.ts +13 -0
- package/dist/agent-workspace/lib/resolvers/rendered-system-overlay.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/rendered-system-overlay.resolver.js +23 -0
- package/dist/agent-workspace/lib/resolvers/rendered-system-overlay.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/scm-repo.resolver.d.ts +13 -0
- package/dist/agent-workspace/lib/resolvers/scm-repo.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/scm-repo.resolver.js +28 -0
- package/dist/agent-workspace/lib/resolvers/scm-repo.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/session-attachment.resolver.d.ts +13 -0
- package/dist/agent-workspace/lib/resolvers/session-attachment.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/session-attachment.resolver.js +28 -0
- package/dist/agent-workspace/lib/resolvers/session-attachment.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/skill-bundle.resolver.d.ts +13 -0
- package/dist/agent-workspace/lib/resolvers/skill-bundle.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/skill-bundle.resolver.js +29 -0
- package/dist/agent-workspace/lib/resolvers/skill-bundle.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/static-literal.resolver.d.ts +11 -0
- package/dist/agent-workspace/lib/resolvers/static-literal.resolver.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/static-literal.resolver.js +33 -0
- package/dist/agent-workspace/lib/resolvers/static-literal.resolver.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/types.d.ts +35 -0
- package/dist/agent-workspace/lib/resolvers/types.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/types.js +3 -0
- package/dist/agent-workspace/lib/resolvers/types.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/utils/agent-run-context-cache.d.ts +70 -0
- package/dist/agent-workspace/lib/resolvers/utils/agent-run-context-cache.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/utils/agent-run-context-cache.js +90 -0
- package/dist/agent-workspace/lib/resolvers/utils/agent-run-context-cache.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/utils/auth.d.ts +5 -0
- package/dist/agent-workspace/lib/resolvers/utils/auth.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/utils/auth.js +19 -0
- package/dist/agent-workspace/lib/resolvers/utils/auth.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/utils/size-cap.d.ts +3 -0
- package/dist/agent-workspace/lib/resolvers/utils/size-cap.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/utils/size-cap.js +23 -0
- package/dist/agent-workspace/lib/resolvers/utils/size-cap.js.map +1 -0
- package/dist/agent-workspace/lib/resolvers/utils/streaming.d.ts +3 -0
- package/dist/agent-workspace/lib/resolvers/utils/streaming.d.ts.map +1 -0
- package/dist/agent-workspace/lib/resolvers/utils/streaming.js +11 -0
- package/dist/agent-workspace/lib/resolvers/utils/streaming.js.map +1 -0
- package/dist/agent-workspace/lib/workspace-renderer.d.ts +13 -0
- package/dist/agent-workspace/lib/workspace-renderer.d.ts.map +1 -0
- package/dist/agent-workspace/lib/workspace-renderer.js +3 -0
- package/dist/agent-workspace/lib/workspace-renderer.js.map +1 -0
- package/dist/api/index.d.ts +11 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +27 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/lib/api-manifest.d.ts +29 -0
- package/dist/api/lib/api-manifest.d.ts.map +1 -0
- package/dist/api/lib/api-manifest.js +28 -0
- package/dist/api/lib/api-manifest.js.map +1 -0
- package/dist/api/lib/biome-db.d.ts +2 -0
- package/dist/api/lib/biome-db.d.ts.map +1 -0
- package/dist/api/lib/biome-db.js +13 -0
- package/dist/api/lib/biome-db.js.map +1 -0
- package/dist/api/lib/code-tool-context.d.ts +16 -0
- package/dist/api/lib/code-tool-context.d.ts.map +1 -0
- package/dist/api/lib/code-tool-context.js +12 -0
- package/dist/api/lib/code-tool-context.js.map +1 -0
- package/dist/api/lib/code-tool-descriptor.d.ts +49 -0
- package/dist/api/lib/code-tool-descriptor.d.ts.map +1 -0
- package/dist/api/lib/code-tool-descriptor.js +3 -0
- package/dist/api/lib/code-tool-descriptor.js.map +1 -0
- package/dist/api/lib/code-tool.decorator.d.ts +17 -0
- package/dist/api/lib/code-tool.decorator.d.ts.map +1 -0
- package/dist/api/lib/code-tool.decorator.js +38 -0
- package/dist/api/lib/code-tool.decorator.js.map +1 -0
- package/dist/api/lib/mutation-context.d.ts +16 -0
- package/dist/api/lib/mutation-context.d.ts.map +1 -0
- package/dist/api/lib/mutation-context.js +17 -0
- package/dist/api/lib/mutation-context.js.map +1 -0
- package/dist/api/lib/pagination.d.ts +8 -0
- package/dist/api/lib/pagination.d.ts.map +1 -0
- package/dist/api/lib/pagination.js +7 -0
- package/dist/api/lib/pagination.js.map +1 -0
- package/dist/api/lib/provider-kind-mirror.d.ts +7 -0
- package/dist/api/lib/provider-kind-mirror.d.ts.map +1 -0
- package/dist/api/lib/provider-kind-mirror.js +11 -0
- package/dist/api/lib/provider-kind-mirror.js.map +1 -0
- package/dist/api/lib/request-context.d.ts +21 -0
- package/dist/api/lib/request-context.d.ts.map +1 -0
- package/dist/api/lib/request-context.js +51 -0
- package/dist/api/lib/request-context.js.map +1 -0
- package/dist/api/lib/route-registry-entry.d.ts +11 -0
- package/dist/api/lib/route-registry-entry.d.ts.map +1 -0
- package/dist/api/lib/route-registry-entry.js +3 -0
- package/dist/api/lib/route-registry-entry.js.map +1 -0
- package/dist/api/nest/controller-base.d.ts +6 -0
- package/dist/api/nest/controller-base.d.ts.map +1 -0
- package/dist/api/nest/controller-base.js +28 -0
- package/dist/api/nest/controller-base.js.map +1 -0
- package/dist/api/nest/events/events.controller.d.ts +10 -0
- package/dist/api/nest/events/events.controller.d.ts.map +1 -0
- package/dist/api/nest/events/events.controller.js +56 -0
- package/dist/api/nest/events/events.controller.js.map +1 -0
- package/dist/api/nest/health/health.controller.d.ts +19 -0
- package/dist/api/nest/health/health.controller.d.ts.map +1 -0
- package/dist/api/nest/health/health.controller.js +63 -0
- package/dist/api/nest/health/health.controller.js.map +1 -0
- package/dist/api/nest/health/health.module.d.ts +6 -0
- package/dist/api/nest/health/health.module.d.ts.map +1 -0
- package/dist/api/nest/health/health.module.js +29 -0
- package/dist/api/nest/health/health.module.js.map +1 -0
- package/dist/api/nest/index.d.ts +7 -0
- package/dist/api/nest/index.d.ts.map +1 -0
- package/dist/api/nest/index.js +23 -0
- package/dist/api/nest/index.js.map +1 -0
- package/dist/api/nest/module.d.ts +6 -0
- package/dist/api/nest/module.d.ts.map +1 -0
- package/dist/api/nest/module.js +34 -0
- package/dist/api/nest/module.js.map +1 -0
- package/dist/api/nest/request-context.d.ts +17 -0
- package/dist/api/nest/request-context.d.ts.map +1 -0
- package/dist/api/nest/request-context.js +75 -0
- package/dist/api/nest/request-context.js.map +1 -0
- package/dist/builder/index.d.ts +7 -0
- package/dist/builder/index.d.ts.map +1 -0
- package/dist/builder/index.js +23 -0
- package/dist/builder/index.js.map +1 -0
- package/dist/builder/lib/content-walker.d.ts +27 -0
- package/dist/builder/lib/content-walker.d.ts.map +1 -0
- package/dist/builder/lib/content-walker.js +274 -0
- package/dist/builder/lib/content-walker.js.map +1 -0
- package/dist/builder/lib/contribution-schemas.d.ts +348 -0
- package/dist/builder/lib/contribution-schemas.d.ts.map +1 -0
- package/dist/builder/lib/contribution-schemas.js +301 -0
- package/dist/builder/lib/contribution-schemas.js.map +1 -0
- package/dist/builder/lib/define-biome.d.ts +17 -0
- package/dist/builder/lib/define-biome.d.ts.map +1 -0
- package/dist/builder/lib/define-biome.js +11 -0
- package/dist/builder/lib/define-biome.js.map +1 -0
- package/dist/builder/lib/define-helpers.d.ts +6 -0
- package/dist/builder/lib/define-helpers.d.ts.map +1 -0
- package/dist/builder/lib/define-helpers.js +20 -0
- package/dist/builder/lib/define-helpers.js.map +1 -0
- package/dist/builder/lib/extends-precedence.d.ts +14 -0
- package/dist/builder/lib/extends-precedence.d.ts.map +1 -0
- package/dist/builder/lib/extends-precedence.js +113 -0
- package/dist/builder/lib/extends-precedence.js.map +1 -0
- package/dist/builder/lib/workflow-phase-config-loader.d.ts +18 -0
- package/dist/builder/lib/workflow-phase-config-loader.d.ts.map +1 -0
- package/dist/builder/lib/workflow-phase-config-loader.js +78 -0
- package/dist/builder/lib/workflow-phase-config-loader.js.map +1 -0
- package/dist/host/index.d.ts +11 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +38 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/lib/agents-cross-validate.d.ts +7 -0
- package/dist/host/lib/agents-cross-validate.d.ts.map +1 -0
- package/dist/host/lib/agents-cross-validate.js +157 -0
- package/dist/host/lib/agents-cross-validate.js.map +1 -0
- package/dist/host/lib/biome-manifest.d.ts +808 -0
- package/dist/host/lib/biome-manifest.d.ts.map +1 -0
- package/dist/host/lib/biome-manifest.js +490 -0
- package/dist/host/lib/biome-manifest.js.map +1 -0
- package/dist/host/lib/bootstrap-contributions-service.d.ts +35 -0
- package/dist/host/lib/bootstrap-contributions-service.d.ts.map +1 -0
- package/dist/host/lib/bootstrap-contributions-service.js +79 -0
- package/dist/host/lib/bootstrap-contributions-service.js.map +1 -0
- package/dist/host/lib/default-state.d.ts +3 -0
- package/dist/host/lib/default-state.d.ts.map +1 -0
- package/dist/host/lib/default-state.js +20 -0
- package/dist/host/lib/default-state.js.map +1 -0
- package/dist/host/lib/integration-cross-validate.d.ts +12 -0
- package/dist/host/lib/integration-cross-validate.d.ts.map +1 -0
- package/dist/host/lib/integration-cross-validate.js +66 -0
- package/dist/host/lib/integration-cross-validate.js.map +1 -0
- package/dist/host/lib/system-overlay-contribution.d.ts +14 -0
- package/dist/host/lib/system-overlay-contribution.d.ts.map +1 -0
- package/dist/host/lib/system-overlay-contribution.js +3 -0
- package/dist/host/lib/system-overlay-contribution.js.map +1 -0
- package/dist/host/lib/topology.d.ts +7 -0
- package/dist/host/lib/topology.d.ts.map +1 -0
- package/dist/host/lib/topology.js +105 -0
- package/dist/host/lib/topology.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator-adapter/index.d.ts +3 -0
- package/dist/orchestrator-adapter/index.d.ts.map +1 -0
- package/dist/orchestrator-adapter/index.js +19 -0
- package/dist/orchestrator-adapter/index.js.map +1 -0
- package/dist/orchestrator-adapter/lib/orchestrator-adapter-registry.d.ts +6 -0
- package/dist/orchestrator-adapter/lib/orchestrator-adapter-registry.d.ts.map +1 -0
- package/dist/orchestrator-adapter/lib/orchestrator-adapter-registry.js +11 -0
- package/dist/orchestrator-adapter/lib/orchestrator-adapter-registry.js.map +1 -0
- package/dist/orchestrator-adapter/lib/orchestrator-adapter.d.ts +11 -0
- package/dist/orchestrator-adapter/lib/orchestrator-adapter.d.ts.map +1 -0
- package/dist/orchestrator-adapter/lib/orchestrator-adapter.js +3 -0
- package/dist/orchestrator-adapter/lib/orchestrator-adapter.js.map +1 -0
- package/package.json +110 -0
- package/src/adapter/index.ts +6 -0
- package/src/adapter/lib/action.ts +60 -0
- package/src/adapter/lib/provider-module.ts +140 -0
- package/src/adapter/lib/resource.ts +52 -0
- package/src/adapter/lib/result.ts +53 -0
- package/src/adapter/lib/sidecar-contract.ts +169 -0
- package/src/adapter/lib/webhook.ts +142 -0
- package/src/agent-workspace/index.ts +7 -0
- package/src/agent-workspace/lib/errors/error-codes.ts +44 -0
- package/src/agent-workspace/lib/errors/index.ts +3 -0
- package/src/agent-workspace/lib/errors/mount-plan-error.ts +29 -0
- package/src/agent-workspace/lib/errors/mount-resolver-error.ts +56 -0
- package/src/agent-workspace/lib/mount-resolver.ts +35 -0
- package/src/agent-workspace/lib/mount-source.ts +11 -0
- package/src/agent-workspace/lib/refid-resolver.ts +135 -0
- package/src/agent-workspace/lib/registries.ts +150 -0
- package/src/agent-workspace/lib/resolvers/agent-definition.resolver.ts +45 -0
- package/src/agent-workspace/lib/resolvers/artifact-store-collection.resolver.ts +43 -0
- package/src/agent-workspace/lib/resolvers/artifact-version.resolver.ts +52 -0
- package/src/agent-workspace/lib/resolvers/clients.ts +297 -0
- package/src/agent-workspace/lib/resolvers/deliverable-specs.resolver.ts +33 -0
- package/src/agent-workspace/lib/resolvers/deliverables.resolver.ts +41 -0
- package/src/agent-workspace/lib/resolvers/index.ts +19 -0
- package/src/agent-workspace/lib/resolvers/instruction-section.resolver.ts +36 -0
- package/src/agent-workspace/lib/resolvers/kb-pages.resolver.ts +62 -0
- package/src/agent-workspace/lib/resolvers/kb-space.resolver.ts +34 -0
- package/src/agent-workspace/lib/resolvers/rendered-agents-md.resolver.ts +40 -0
- package/src/agent-workspace/lib/resolvers/rendered-context-json.resolver.ts +41 -0
- package/src/agent-workspace/lib/resolvers/rendered-system-overlay.resolver.ts +39 -0
- package/src/agent-workspace/lib/resolvers/scm-repo.resolver.ts +43 -0
- package/src/agent-workspace/lib/resolvers/session-attachment.resolver.ts +37 -0
- package/src/agent-workspace/lib/resolvers/skill-bundle.resolver.ts +42 -0
- package/src/agent-workspace/lib/resolvers/static-literal.resolver.ts +69 -0
- package/src/agent-workspace/lib/resolvers/types.ts +94 -0
- package/src/agent-workspace/lib/resolvers/utils/agent-run-context-cache.ts +206 -0
- package/src/agent-workspace/lib/resolvers/utils/auth.ts +39 -0
- package/src/agent-workspace/lib/resolvers/utils/size-cap.ts +38 -0
- package/src/agent-workspace/lib/resolvers/utils/streaming.ts +22 -0
- package/src/agent-workspace/lib/workspace-renderer.ts +25 -0
- package/src/api/index.ts +10 -0
- package/src/api/lib/api-manifest.ts +54 -0
- package/src/api/lib/biome-db.ts +28 -0
- package/src/api/lib/code-tool-context.ts +45 -0
- package/src/api/lib/code-tool-descriptor.ts +102 -0
- package/src/api/lib/code-tool.decorator.ts +111 -0
- package/src/api/lib/mutation-context.ts +49 -0
- package/src/api/lib/pagination.ts +17 -0
- package/src/api/lib/provider-kind-mirror.ts +16 -0
- package/src/api/lib/request-context.ts +90 -0
- package/src/api/lib/route-registry-entry.ts +35 -0
- package/src/api/nest/controller-base.ts +59 -0
- package/src/api/nest/events/events.controller.ts +48 -0
- package/src/api/nest/health/health.controller.ts +36 -0
- package/src/api/nest/health/health.module.ts +29 -0
- package/src/api/nest/index.ts +6 -0
- package/src/api/nest/module.ts +51 -0
- package/src/api/nest/request-context.ts +166 -0
- package/src/builder/index.ts +26 -0
- package/src/builder/lib/content-walker.ts +383 -0
- package/src/builder/lib/contribution-schemas.ts +572 -0
- package/src/builder/lib/define-biome.ts +84 -0
- package/src/builder/lib/define-helpers.ts +42 -0
- package/src/builder/lib/extends-precedence.ts +195 -0
- package/src/builder/lib/workflow-phase-config-loader.ts +163 -0
- package/src/host/index.ts +39 -0
- package/src/host/lib/agents-cross-validate.ts +283 -0
- package/src/host/lib/biome-manifest.ts +1060 -0
- package/src/host/lib/bootstrap-contributions-service.ts +233 -0
- package/src/host/lib/default-state.ts +40 -0
- package/src/host/lib/integration-cross-validate.ts +140 -0
- package/src/host/lib/system-overlay-contribution.ts +53 -0
- package/src/host/lib/topology.ts +174 -0
- package/src/index.ts +58 -0
- package/src/orchestrator-adapter/index.ts +2 -0
- package/src/orchestrator-adapter/lib/orchestrator-adapter-registry.ts +8 -0
- package/src/orchestrator-adapter/lib/orchestrator-adapter.ts +20 -0
|
@@ -0,0 +1,1060 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CAPABILITY_SLUG_PATTERN,
|
|
3
|
+
FilterExprSchema,
|
|
4
|
+
} from '@xemahq/kernel-contracts/connector';
|
|
5
|
+
import { ContributionKindSchema } from '@xemahq/kernel-contracts/contribution';
|
|
6
|
+
import { CapabilityRefSchema } from '@xemahq/kernel-contracts/capability';
|
|
7
|
+
import {
|
|
8
|
+
BiomeEnginesSchema,
|
|
9
|
+
BiomeEventSubscriptionSchema,
|
|
10
|
+
BiomeLifecycleHooksSchema,
|
|
11
|
+
BiomePermissionsManifestSchema,
|
|
12
|
+
type BiomeEventSubscription,
|
|
13
|
+
} from '@xemahq/kernel-contracts/biome';
|
|
14
|
+
import {
|
|
15
|
+
ProvisioningGuardSchema,
|
|
16
|
+
ProvisioningStepKindSchema,
|
|
17
|
+
ProvisioningTriggerSchema,
|
|
18
|
+
} from '@xemahq/kernel-contracts/provisioning';
|
|
19
|
+
import {
|
|
20
|
+
MigrationRunnerKind,
|
|
21
|
+
OrgDatabasePurpose,
|
|
22
|
+
} from '@xemahq/kernel-contracts/org-database';
|
|
23
|
+
import {
|
|
24
|
+
DataLocalitySchema,
|
|
25
|
+
RuntimeIsolationLevelSchema,
|
|
26
|
+
RunnerTrustTier,
|
|
27
|
+
} from '@xemahq/kernel-contracts/runner';
|
|
28
|
+
import { z } from 'zod';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* `xema-biome.json` — declarative description of a Xema biome's
|
|
32
|
+
* identity and the contributions it ships. The schema is a discriminated
|
|
33
|
+
* union on `xema.target`.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Biome tier (Layered Biome Architecture — plan-of-record v4.6 §22.5.7,
|
|
38
|
+
* "Linux-faithful" model):
|
|
39
|
+
* - `kernel` — L1 universal, mandatory. Must boot before any other biome.
|
|
40
|
+
* Analogue: vmlinuz / the Linux kernel image.
|
|
41
|
+
* - `system` — L2 system biomes (Wave 18): the systemd / dbus / sshd /
|
|
42
|
+
* libc analogues. Independent biomes that boot after the
|
|
43
|
+
* kernel and before any base/domain biome. Examples:
|
|
44
|
+
* identity (referenced as external submodule), audit,
|
|
45
|
+
* biome-host, biome-fetcher, public-gateway,
|
|
46
|
+
* workload-runtime, authorization, …
|
|
47
|
+
* - `base` — L2.5 base biomes (Wave 16E-3, Wave 17): foundational
|
|
48
|
+
* user-facing primitives any domain biome may depend on
|
|
49
|
+
* (agent-runtime, integration-platform, document-rendering,
|
|
50
|
+
* workflow-runtime). Linux analogy: shared libraries +
|
|
51
|
+
* high-level daemons (libsystemd, libdbus).
|
|
52
|
+
* - `platform` — L3 first-party domain biomes (software-dev, …) and
|
|
53
|
+
* integration biomes (integration-<provider>/…).
|
|
54
|
+
* - `third-party` — external (future: npm or git).
|
|
55
|
+
*/
|
|
56
|
+
export const BiomeScopeSchema = z.enum([
|
|
57
|
+
'kernel',
|
|
58
|
+
'system',
|
|
59
|
+
'base',
|
|
60
|
+
'platform',
|
|
61
|
+
'third-party',
|
|
62
|
+
]);
|
|
63
|
+
export type BiomeScope = z.infer<typeof BiomeScopeSchema>;
|
|
64
|
+
|
|
65
|
+
/** Target the biome executes in. */
|
|
66
|
+
export const BiomeTargetSchema = z.enum(['server', 'web']);
|
|
67
|
+
export type BiomeTarget = z.infer<typeof BiomeTargetSchema>;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The Contribution Protocol (`@xemahq/kernel-contracts/contribution`) is the
|
|
71
|
+
* single authoritative enum for kinds a biome may ship; `ContributionKind`
|
|
72
|
+
* is re-exported from this package's `index.ts`.
|
|
73
|
+
*
|
|
74
|
+
* Conventional on-disk directory name per `ships.content[]` / `ships.modules[]`
|
|
75
|
+
* string. Used ONLY for the `ships`-based file-walk seeders that have not yet
|
|
76
|
+
* migrated to the `contributions/` directory protocol. New code MUST use the
|
|
77
|
+
* `xema.contributions` block (or inline contributions) instead of
|
|
78
|
+
* `ships.content` / `ships.modules`.
|
|
79
|
+
*
|
|
80
|
+
* Keys are the camelCase tokens accepted in `xema-biome.json`; the mapping
|
|
81
|
+
* returns `null` for any key it does not recognise so callers can fail fast.
|
|
82
|
+
*/
|
|
83
|
+
const LEGACY_SHIPS_CONTENT_DIR: Readonly<Record<string, string>> = {
|
|
84
|
+
agents: 'agents',
|
|
85
|
+
workflowConfig: 'workflow-config',
|
|
86
|
+
deliverableSpecs: 'deliverable-specs',
|
|
87
|
+
workspaceManifests: 'workspace-manifests',
|
|
88
|
+
workspaceManifestTemplates: 'workspace-manifest-templates',
|
|
89
|
+
toolProfiles: 'tool-profiles',
|
|
90
|
+
mcpCatalog: 'mcp-catalog',
|
|
91
|
+
mcpTools: 'mcp-tools',
|
|
92
|
+
openCodeSkills: 'skills',
|
|
93
|
+
openCodeTools: 'opencode-tools',
|
|
94
|
+
openCodePlugins: 'opencode-plugins',
|
|
95
|
+
roleCapabilities: 'role-capabilities',
|
|
96
|
+
artifactTypes: 'artifact-types',
|
|
97
|
+
biomeInstallSchema: 'install-schema',
|
|
98
|
+
icons: 'icons',
|
|
99
|
+
projectKits: 'project-kits',
|
|
100
|
+
provisioningScaffolds: 'provisioning',
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const LEGACY_SHIPS_MODULES_DIR: Readonly<Record<string, string>> = {
|
|
104
|
+
agents: 'agents',
|
|
105
|
+
actions: 'actions',
|
|
106
|
+
mountSourceKinds: 'mount-source-kinds',
|
|
107
|
+
deliverableSpecKinds: 'deliverable-spec-kinds',
|
|
108
|
+
runtimeMountKinds: 'runtime-mount-kinds',
|
|
109
|
+
workspaceSpecOverlay: 'workspace-spec-overlay',
|
|
110
|
+
systemOverlayContributions: 'system-overlay-contributions',
|
|
111
|
+
adapterKinds: 'adapter-kinds',
|
|
112
|
+
integrationProviders: 'integration-providers',
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Resolve a legacy `ships.content[]` value to its conventional directory
|
|
117
|
+
* name, or `null` for unknown tokens. Used by the legacy file-walk
|
|
118
|
+
* catalog/seeders; new code should use the contributions protocol.
|
|
119
|
+
*/
|
|
120
|
+
export function contentKindToDir(kind: string): string {
|
|
121
|
+
const dir = LEGACY_SHIPS_CONTENT_DIR[kind];
|
|
122
|
+
if (!dir) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
`biome-host-sdk: unknown legacy ships.content[] value "${kind}". ` +
|
|
125
|
+
`Either migrate the biome to xema.contributions or extend LEGACY_SHIPS_CONTENT_DIR.`,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
return dir;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Resolve a legacy `ships.modules[]` value to its conventional directory
|
|
133
|
+
* name. Same legacy-only scope as `contentKindToDir`.
|
|
134
|
+
*/
|
|
135
|
+
export function moduleKindToDir(kind: string): string {
|
|
136
|
+
const dir = LEGACY_SHIPS_MODULES_DIR[kind];
|
|
137
|
+
if (!dir) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`biome-host-sdk: unknown legacy ships.modules[] value "${kind}". ` +
|
|
140
|
+
`Either migrate the biome to xema.contributions or extend LEGACY_SHIPS_MODULES_DIR.`,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
return dir;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Org-managed database declaration for biomes that need a dedicated
|
|
148
|
+
* schema in a provisioned org database.
|
|
149
|
+
*/
|
|
150
|
+
export const BiomeDatabaseDeclarationSchema = z
|
|
151
|
+
.object({
|
|
152
|
+
purpose: z.literal(OrgDatabasePurpose.Biome),
|
|
153
|
+
runnerKind: z.literal(MigrationRunnerKind.Prisma),
|
|
154
|
+
})
|
|
155
|
+
.strict();
|
|
156
|
+
export type BiomeDatabaseDeclaration = z.infer<typeof BiomeDatabaseDeclarationSchema>;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Per-API declaration shipped under `xema.ships.apis[]` (Phase 9).
|
|
160
|
+
* Each entry becomes one subdomain (`<name>.api.<base-domain>`)
|
|
161
|
+
* served by a biome-shipped NestJS service. biome-host-api applies
|
|
162
|
+
* the Helm sub-chart at install time and writes a route-registry
|
|
163
|
+
* entry the ingress shim consults. Validated structurally here;
|
|
164
|
+
* detailed contract semantics live in `@xemahq/biome-api-sdk`.
|
|
165
|
+
*/
|
|
166
|
+
export const BiomeApiDeclarationSchema = z
|
|
167
|
+
.object({
|
|
168
|
+
name: z
|
|
169
|
+
.string()
|
|
170
|
+
.min(1)
|
|
171
|
+
.regex(
|
|
172
|
+
/^[a-z][a-z0-9-]*$/,
|
|
173
|
+
'API name must be lowercase kebab-case; becomes the subdomain slug',
|
|
174
|
+
),
|
|
175
|
+
basePath: z
|
|
176
|
+
.string()
|
|
177
|
+
.regex(/^\/.*$/)
|
|
178
|
+
.optional(),
|
|
179
|
+
/** Workspace package name + port — the deployment image. */
|
|
180
|
+
image: z
|
|
181
|
+
.object({
|
|
182
|
+
package: z.string().min(1),
|
|
183
|
+
port: z.number().int().min(1).max(65_535),
|
|
184
|
+
})
|
|
185
|
+
.strict(),
|
|
186
|
+
openapiSpec: z.string().optional(),
|
|
187
|
+
scopes: z.array(z.enum(['public', 'org', 'project', 'installation'])).min(1),
|
|
188
|
+
})
|
|
189
|
+
.strict();
|
|
190
|
+
export type BiomeApiDeclaration = z.infer<typeof BiomeApiDeclarationSchema>;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Phase-C Contribution Protocol entry. The body of an
|
|
194
|
+
* `*.contribution.json` file under a biome's `contributions/` directory,
|
|
195
|
+
* or an inline entry under `xema.contributions.inline[]` in
|
|
196
|
+
* `xema-biome.json`.
|
|
197
|
+
*
|
|
198
|
+
* Validated structurally here (kind + slug + opaque manifest). The
|
|
199
|
+
* authoritative per-kind manifest validation lives in the kind-specific
|
|
200
|
+
* contracts package and is exercised at boot by the generic
|
|
201
|
+
* `BootstrapContributionsService` template (see
|
|
202
|
+
* `bootstrap-contributions-service.ts`).
|
|
203
|
+
*
|
|
204
|
+
* See `.claude/plans/following-up-the-xema-os-plan-md-abstract-stream.md` §6.C.1.
|
|
205
|
+
*/
|
|
206
|
+
export const BiomeContributionEntrySchema = z
|
|
207
|
+
.object({
|
|
208
|
+
kind: ContributionKindSchema,
|
|
209
|
+
/**
|
|
210
|
+
* Kind-local slug; uniqueness is per `(kind, biomeId)`. The full
|
|
211
|
+
* `<namespace>/<local-slug>` slug expected by the kernel
|
|
212
|
+
* `ContributionSlugSchema` is composed at install time by the biome
|
|
213
|
+
* host (`namespace = biomeId`).
|
|
214
|
+
*/
|
|
215
|
+
id: z
|
|
216
|
+
.string()
|
|
217
|
+
.min(1)
|
|
218
|
+
.regex(
|
|
219
|
+
/^[a-z0-9][a-z0-9._-]*(?:\/[a-z0-9][a-z0-9._-]*)*$/,
|
|
220
|
+
'Contribution id must be lowercase kebab/dot-case, optionally with nested `/` segments',
|
|
221
|
+
),
|
|
222
|
+
manifest: z.unknown(),
|
|
223
|
+
})
|
|
224
|
+
.strict();
|
|
225
|
+
export type BiomeContributionEntry = z.infer<typeof BiomeContributionEntrySchema>;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Per-biome Contribution Protocol declaration. Either points at a
|
|
229
|
+
* `contributions/` directory containing one `*.contribution.json` per
|
|
230
|
+
* entry, OR carries the entries inline. Both forms are allowed in one
|
|
231
|
+
* manifest — directory entries are walked first, inline entries layered
|
|
232
|
+
* on top with last-write-wins on `(kind, id)` collision (the host fails
|
|
233
|
+
* fast on duplicates at boot).
|
|
234
|
+
*
|
|
235
|
+
* Phase C plan-of-record: §6.C.1.
|
|
236
|
+
*/
|
|
237
|
+
export const BiomeContributionsSchema = z
|
|
238
|
+
.object({
|
|
239
|
+
/**
|
|
240
|
+
* Directory under the biome root (relative path). Defaults to
|
|
241
|
+
* `./contributions` when omitted but the block is present. The host
|
|
242
|
+
* silently ignores a missing directory — empty contribution sets are
|
|
243
|
+
* legal.
|
|
244
|
+
*/
|
|
245
|
+
directory: z.string().min(1).optional(),
|
|
246
|
+
/** Inline contribution entries. */
|
|
247
|
+
inline: z.array(BiomeContributionEntrySchema).optional(),
|
|
248
|
+
})
|
|
249
|
+
.strict();
|
|
250
|
+
export type BiomeContributions = z.infer<typeof BiomeContributionsSchema>;
|
|
251
|
+
|
|
252
|
+
export const BiomeShipsSchema = z
|
|
253
|
+
.object({
|
|
254
|
+
/**
|
|
255
|
+
* @deprecated PHASE-C-SWEEP: superseded by top-level
|
|
256
|
+
* `xema.contributions`. Kept as a free-form string array until the
|
|
257
|
+
* codemod sweep migrates every biome to the Contribution Protocol.
|
|
258
|
+
* Values are matched against `ContributionKind` at registration time.
|
|
259
|
+
*/
|
|
260
|
+
content: z.array(z.string().min(1)).optional(),
|
|
261
|
+
/**
|
|
262
|
+
* @deprecated PHASE-C-SWEEP: superseded by top-level
|
|
263
|
+
* `xema.contributions`. See `content` above — same rationale.
|
|
264
|
+
*/
|
|
265
|
+
modules: z.array(z.string().min(1)).optional(),
|
|
266
|
+
apis: z.array(BiomeApiDeclarationSchema).optional(),
|
|
267
|
+
})
|
|
268
|
+
.strict();
|
|
269
|
+
export type BiomeShips = z.infer<typeof BiomeShipsSchema>;
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Hosting/trust posture for a server biome. Used by integration-host
|
|
273
|
+
* plumbing (Phase 7) to decide whether to load adapter-contribution
|
|
274
|
+
* modules in-process or via a sidecar deployment. Manifests authored
|
|
275
|
+
* by Xema and audited third parties may set `first-party`; everything
|
|
276
|
+
* else defaults to `third-party`.
|
|
277
|
+
*/
|
|
278
|
+
export const BiomeTrustTierSchema = z.enum(['first-party', 'third-party']);
|
|
279
|
+
export type BiomeTrustTier = z.infer<typeof BiomeTrustTierSchema>;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* AdapterKind slug — accepts a built-in slug verbatim, plus any
|
|
283
|
+
* lowercase kebab-case slug a biome-contributed kind could register.
|
|
284
|
+
* The runtime registry in integration-adapters-api is the authority on
|
|
285
|
+
* which slugs actually resolve; manifest parsing only enforces shape.
|
|
286
|
+
*/
|
|
287
|
+
const AdapterKindRefSchema = z
|
|
288
|
+
.string()
|
|
289
|
+
.min(1)
|
|
290
|
+
.regex(/^[a-z][a-z0-9-]*$/, 'adapterKind must be lowercase kebab-case');
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Execution mode for a shipped agent. Mirrors the `mode:` field in the
|
|
294
|
+
* agent .md frontmatter (and the `executionMode` column in
|
|
295
|
+
* llm-registry's `agent_definitions` table). Closed enum — every agent
|
|
296
|
+
* is either the session's primary or a delegate available via the
|
|
297
|
+
* `task` tool.
|
|
298
|
+
*
|
|
299
|
+
* The on-disk convention for backwards compatibility is that a missing
|
|
300
|
+
* frontmatter `mode:` is treated as `primary`. The manifest declaration
|
|
301
|
+
* is the authoritative answer; the cross-validator
|
|
302
|
+
* (`crossValidateAgentDeclarations`) accepts a declared `primary` against
|
|
303
|
+
* a missing frontmatter mode but rejects any other mismatch.
|
|
304
|
+
*/
|
|
305
|
+
export const BiomeAgentModeSchema = z.enum(['primary', 'subagent']);
|
|
306
|
+
export type BiomeAgentMode = z.infer<typeof BiomeAgentModeSchema>;
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Declaration of a single agent shipped by a biome. Path is implicit:
|
|
310
|
+
* `<biomeRoot>/agents/<slug>.md` (the convention enforced by
|
|
311
|
+
* `enumerateContentAcrossBiomeTree`). The slug also becomes the
|
|
312
|
+
* agent's canonical id in llm-registry, so it must match the filename.
|
|
313
|
+
*
|
|
314
|
+
* `mode` is duplicated between the manifest and the .md frontmatter on
|
|
315
|
+
* purpose: the manifest field makes the agent roster greppable and
|
|
316
|
+
* lets biome-host refuse to boot on drift; the frontmatter is what
|
|
317
|
+
* the agent-definition seeder consumes when materialising the agent
|
|
318
|
+
* into the registry. The boot-time cross-validator ensures both agree.
|
|
319
|
+
*/
|
|
320
|
+
export const BiomeAgentDeclarationSchema = z
|
|
321
|
+
.object({
|
|
322
|
+
slug: z
|
|
323
|
+
.string()
|
|
324
|
+
.min(1)
|
|
325
|
+
.regex(
|
|
326
|
+
/^[a-z][a-z0-9-_]*$/,
|
|
327
|
+
'agent slug must be lowercase kebab/underscore-case and match the .md basename',
|
|
328
|
+
),
|
|
329
|
+
mode: BiomeAgentModeSchema,
|
|
330
|
+
})
|
|
331
|
+
.strict();
|
|
332
|
+
export type BiomeAgentDeclaration = z.infer<typeof BiomeAgentDeclarationSchema>;
|
|
333
|
+
|
|
334
|
+
const CapabilitySlugSchema = z
|
|
335
|
+
.string()
|
|
336
|
+
.min(1)
|
|
337
|
+
.regex(CAPABILITY_SLUG_PATTERN, 'capability slug must be <domain>.<verb-qualifier>');
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Declared integration dependency. The install wizard surfaces these
|
|
341
|
+
* as a consent screen; `biome-host-api` refuses to activate a
|
|
342
|
+
* `BiomeInstallation` whose non-optional requirements are not bound.
|
|
343
|
+
* `purpose` is mandatory (one short sentence) so users see *why* the
|
|
344
|
+
* biome needs the integration.
|
|
345
|
+
*/
|
|
346
|
+
export const IntegrationRequirementSchema = z
|
|
347
|
+
.object({
|
|
348
|
+
adapterKind: AdapterKindRefSchema,
|
|
349
|
+
optional: z.boolean().optional(),
|
|
350
|
+
purpose: z.string().min(1),
|
|
351
|
+
capabilities: z.array(CapabilitySlugSchema).min(1),
|
|
352
|
+
})
|
|
353
|
+
.strict();
|
|
354
|
+
export type IntegrationRequirement = z.infer<typeof IntegrationRequirementSchema>;
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Per-(workflow, event) filter expression. The workflow YAML's
|
|
358
|
+
* `on.webhook[].event` value must match `event` here; the workflow
|
|
359
|
+
* compiler enforces this at publish time. `workflowId` is the
|
|
360
|
+
* shipped-workflow id (the `id` field inside the YAML), not a runtime
|
|
361
|
+
* `WorkflowDefinition.id`. At install time `biome-host-api` resolves
|
|
362
|
+
* the bundle and copies the relevant entries onto the
|
|
363
|
+
* `WorkflowDefinition.biomeWebhookFilters` column so the dispatcher
|
|
364
|
+
* can evaluate without re-reading the manifest.
|
|
365
|
+
*/
|
|
366
|
+
export const WebhookFilterSchema = z
|
|
367
|
+
.object({
|
|
368
|
+
workflowId: z
|
|
369
|
+
.string()
|
|
370
|
+
.min(1)
|
|
371
|
+
.regex(/^[a-z][a-z0-9-]*$/, 'workflowId must be lowercase kebab-case'),
|
|
372
|
+
event: z.string().min(1),
|
|
373
|
+
/**
|
|
374
|
+
* Optional canonical entity kind the filter targets (e.g. `push`,
|
|
375
|
+
* `change_request`, `item`). When set, the manifest cross-validator
|
|
376
|
+
* narrows `$envelope.*` path checking to that entity kind's
|
|
377
|
+
* payload — typos against the specific kind fail fast at boot.
|
|
378
|
+
* Omitted = union path check across every entity kind under the
|
|
379
|
+
* referenced workflow's required adapter kinds (over-permissive
|
|
380
|
+
* but still catches the obvious typo class).
|
|
381
|
+
*/
|
|
382
|
+
entityKind: z.string().min(1).optional(),
|
|
383
|
+
predicate: FilterExprSchema,
|
|
384
|
+
})
|
|
385
|
+
.strict();
|
|
386
|
+
export type WebhookFilter = z.infer<typeof WebhookFilterSchema>;
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Server-side capability declarations. Validated at boot for shape +
|
|
390
|
+
* closed-set membership; runtime enforcement is Phase 4 (network
|
|
391
|
+
* allow-list, MCP ACL, secret scope). Declaring intent now means every
|
|
392
|
+
* biome already states it — no migration when enforcement turns on.
|
|
393
|
+
*/
|
|
394
|
+
export const ServerBiomeCapabilitiesSchema = z
|
|
395
|
+
.object({
|
|
396
|
+
mcp: z.array(z.string().min(1)).optional(),
|
|
397
|
+
network: z
|
|
398
|
+
.object({ allowList: z.array(z.string().min(1)) })
|
|
399
|
+
.strict()
|
|
400
|
+
.optional(),
|
|
401
|
+
secrets: z.array(z.string().min(1)).optional(),
|
|
402
|
+
})
|
|
403
|
+
.strict();
|
|
404
|
+
export type ServerBiomeCapabilities = z.infer<typeof ServerBiomeCapabilitiesSchema>;
|
|
405
|
+
|
|
406
|
+
/** Web-side capability declarations. Same Phase-4 timing as server. */
|
|
407
|
+
export const WebBiomeCapabilitiesSchema = z
|
|
408
|
+
.object({
|
|
409
|
+
slots: z.array(z.string().min(1)).optional(),
|
|
410
|
+
apiClients: z.array(z.string().min(1)).optional(),
|
|
411
|
+
})
|
|
412
|
+
.strict();
|
|
413
|
+
export type WebBiomeCapabilities = z.infer<typeof WebBiomeCapabilitiesSchema>;
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* How the `provisioning-plan-resolver` expands one scaffold declaration
|
|
417
|
+
* into resolved steps. Closed enum — `each-app-target` evaluates
|
|
418
|
+
* `selector.configPointer` against the session's `customConfig` and emits
|
|
419
|
+
* one step per matched array element (webapp-studio's `/appTargets`).
|
|
420
|
+
* Adding a strategy is a one-line schema change here plus a matching
|
|
421
|
+
* branch in the resolver.
|
|
422
|
+
*/
|
|
423
|
+
export const ProvisioningScaffoldMatchKindSchema = z.enum(['each-app-target']);
|
|
424
|
+
export type ProvisioningScaffoldMatchKind = z.infer<
|
|
425
|
+
typeof ProvisioningScaffoldMatchKindSchema
|
|
426
|
+
>;
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Declaration of one provisioning scaffold a biome ships. The scaffold
|
|
430
|
+
* *content* (command spec + template files) lives at
|
|
431
|
+
* `<biomeRoot>/provisioning/<id>.yaml`; this manifest entry is the
|
|
432
|
+
* lightweight "I ship this scaffold, and here is when/whether it runs"
|
|
433
|
+
* declaration the resolver reads.
|
|
434
|
+
*
|
|
435
|
+
* `selector` is what makes provisioning "run only if instructed" — a
|
|
436
|
+
* scaffold whose `configPointer` resolves to nothing in the session's
|
|
437
|
+
* `customConfig` never enters the plan.
|
|
438
|
+
*/
|
|
439
|
+
export const ProvisioningScaffoldDeclarationSchema = z
|
|
440
|
+
.object({
|
|
441
|
+
id: z
|
|
442
|
+
.string()
|
|
443
|
+
.min(1)
|
|
444
|
+
.regex(
|
|
445
|
+
/^[a-z][a-z0-9-]*$/,
|
|
446
|
+
'scaffold id must be lowercase kebab-case and match the provisioning/<id>.yaml basename',
|
|
447
|
+
),
|
|
448
|
+
kind: ProvisioningStepKindSchema,
|
|
449
|
+
triggers: z.array(ProvisioningTriggerSchema).min(1),
|
|
450
|
+
guard: ProvisioningGuardSchema,
|
|
451
|
+
selector: z
|
|
452
|
+
.object({
|
|
453
|
+
/**
|
|
454
|
+
* JSON Pointer (RFC 6901) into the session's `customConfig`. The
|
|
455
|
+
* resolver expands the scaffold only when this resolves; for
|
|
456
|
+
* `each-app-target` it must resolve to an array.
|
|
457
|
+
*/
|
|
458
|
+
configPointer: z.string().min(1),
|
|
459
|
+
matchKind: ProvisioningScaffoldMatchKindSchema,
|
|
460
|
+
})
|
|
461
|
+
.strict(),
|
|
462
|
+
})
|
|
463
|
+
.strict();
|
|
464
|
+
export type ProvisioningScaffoldDeclaration = z.infer<
|
|
465
|
+
typeof ProvisioningScaffoldDeclarationSchema
|
|
466
|
+
>;
|
|
467
|
+
|
|
468
|
+
const BiomeIdSchema = z
|
|
469
|
+
.string()
|
|
470
|
+
.min(1)
|
|
471
|
+
.regex(/^[a-z][a-z0-9-]*$/, 'biome id must be kebab-case');
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Per-handler declarative event subscription. Type-aliased to the kernel
|
|
475
|
+
* `BiomeEventSubscription` so the SDK's manifest field and the eventual
|
|
476
|
+
* `xema-biome.json` parser share one shape. See plan §12.4.
|
|
477
|
+
*/
|
|
478
|
+
export type BiomeManifestSubscribe = BiomeEventSubscription;
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* `requires`: biome id → semver range. Same shape as the kernel biome
|
|
482
|
+
* manifest's `requires` block (plan §12.4); the platform refuses to
|
|
483
|
+
* enable a biome/biome whose `requires` cannot be satisfied by the
|
|
484
|
+
* other enabled biomes/biomes in the org.
|
|
485
|
+
*/
|
|
486
|
+
export type BiomeManifestRequires = Readonly<Record<string, string>>;
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Additive XSI fields layered onto the per-target `xema` block in Phase
|
|
490
|
+
* 1A (plan §17.2 item 2). Pure additive — no rename of the SDK package
|
|
491
|
+
* itself yet (that happens in Phase 6). All fields are OPTIONAL at this
|
|
492
|
+
* phase; `engines` is promoted to required in Phase 6.
|
|
493
|
+
*
|
|
494
|
+
* - `subscribes[]` — declarative event wiring (§12.4). Each entry binds
|
|
495
|
+
* one CloudEvents `type` to a handler module path.
|
|
496
|
+
* - `requires` — typed semver dependency declaration on other
|
|
497
|
+
* biomes/biomes (§12.4).
|
|
498
|
+
* - `contributes[]` — closed `ContributionKind` enum from
|
|
499
|
+
* `@xemahq/kernel-contracts/contribution`. The biome-host uses this to know
|
|
500
|
+
* which slot registries to walk on install (§12.1).
|
|
501
|
+
* - `requiresCapabilities[]` — capability refs the biome needs the host
|
|
502
|
+
* to grant before any of its handlers/contributions execute (§30.2).
|
|
503
|
+
* - `exposesCapabilities[]` — capability refs the biome itself
|
|
504
|
+
* implements and offers to others (§30.2).
|
|
505
|
+
* - `permissions` — install-time consent metadata (default profile +
|
|
506
|
+
* per-ref hints + UX groupings) for `requiresCapabilities[]` (§30.2).
|
|
507
|
+
* - `lifecycle` — module paths the host invokes on
|
|
508
|
+
* install/upgrade/enable/disable/uninstall transitions (§24.5).
|
|
509
|
+
* - `engines.xema` — semver range the host enforces against the running
|
|
510
|
+
* platform version (§24.4). Optional in 1A; required in Phase 6.
|
|
511
|
+
*
|
|
512
|
+
* Kernel-owned types are referenced through the kernel packages — never
|
|
513
|
+
* redefined here.
|
|
514
|
+
*/
|
|
515
|
+
const XsiManifestExtensionsShape = {
|
|
516
|
+
subscribes: z.array(BiomeEventSubscriptionSchema).optional(),
|
|
517
|
+
requires: z.record(z.string().min(1), z.string().min(1)).optional(),
|
|
518
|
+
contributes: z.array(ContributionKindSchema).optional(),
|
|
519
|
+
/**
|
|
520
|
+
* Phase-C Contribution Protocol entries (the actual envelopes, not just
|
|
521
|
+
* the kind whitelist). Replaces the legacy `ships.content` +
|
|
522
|
+
* `ships.modules` per-kind file-walk seeders with a single generic
|
|
523
|
+
* `BootstrapContributionsService` template; see Phase C.1 of the
|
|
524
|
+
* plan-of-record. Either inline entries or a pointer to a
|
|
525
|
+
* `contributions/` directory at the biome root.
|
|
526
|
+
*/
|
|
527
|
+
contributions: BiomeContributionsSchema.optional(),
|
|
528
|
+
requiresCapabilities: z.array(CapabilityRefSchema).optional(),
|
|
529
|
+
exposesCapabilities: z.array(CapabilityRefSchema).optional(),
|
|
530
|
+
permissions: BiomePermissionsManifestSchema.optional(),
|
|
531
|
+
lifecycle: BiomeLifecycleHooksSchema.optional(),
|
|
532
|
+
engines: BiomeEnginesSchema.optional(),
|
|
533
|
+
} as const;
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* `runtimeRequirements` — what a biome NEEDS from the runtime/runner that
|
|
537
|
+
* executes it. This is the *requirements* half of the scheduling contract:
|
|
538
|
+
* the package states constraints; the installer decides who installs it;
|
|
539
|
+
* the runtime binding decides where it may run; the router schedules onto a
|
|
540
|
+
* matching healthy runner.
|
|
541
|
+
*
|
|
542
|
+
* HARD RULE — requirements, NEVER placement. A manifest MAY declare
|
|
543
|
+
* required/preferred labels, resource hints, allowed isolation levels,
|
|
544
|
+
* allowed data localities, and a minimum runner trust tier. It MUST NOT
|
|
545
|
+
* name a concrete target: `runtimeId`, `runnerId`, `runnerName`, `host`,
|
|
546
|
+
* `serverUrl`, or any infra address. Those are placement decisions owned by
|
|
547
|
+
* the scheduler, never the package. Enforced two ways: this object is
|
|
548
|
+
* `.strict()` (an unknown key — including any placement field — fails the
|
|
549
|
+
* parse fast) AND `tooling/boundaries/check-biome-no-placement.mjs` scans
|
|
550
|
+
* the raw manifest for forbidden keys anywhere in the tree with an
|
|
551
|
+
* actionable message.
|
|
552
|
+
*
|
|
553
|
+
* Enums are reused from `@xemahq/kernel-contracts/runner` so the requirement side
|
|
554
|
+
* (this manifest) and the capability side (a runtime/runner descriptor)
|
|
555
|
+
* speak the same closed vocabulary and can never drift.
|
|
556
|
+
*/
|
|
557
|
+
const RuntimeRequirementsSchema = z
|
|
558
|
+
.object({
|
|
559
|
+
/**
|
|
560
|
+
* Capability/tag labels the executing runner must (`required`) or
|
|
561
|
+
* preferably should (`preferred`) advertise — e.g.
|
|
562
|
+
* `xema.runner/docker`, `xema.runner/gpu`, `region`. Matched against a
|
|
563
|
+
* runner's advertised `labels` by the router's selector.
|
|
564
|
+
*/
|
|
565
|
+
labels: z
|
|
566
|
+
.object({
|
|
567
|
+
required: z.array(z.string().min(1)).optional(),
|
|
568
|
+
preferred: z.array(z.string().min(1)).optional(),
|
|
569
|
+
})
|
|
570
|
+
.strict()
|
|
571
|
+
.optional(),
|
|
572
|
+
/**
|
|
573
|
+
* Coarse resource hints (Kubernetes-style quantity strings). Advisory
|
|
574
|
+
* scheduling input, not a hard guarantee at this phase.
|
|
575
|
+
*/
|
|
576
|
+
resources: z
|
|
577
|
+
.object({
|
|
578
|
+
cpu: z.string().min(1).optional(),
|
|
579
|
+
memory: z.string().min(1).optional(),
|
|
580
|
+
})
|
|
581
|
+
.strict()
|
|
582
|
+
.optional(),
|
|
583
|
+
/**
|
|
584
|
+
* Isolation boundaries the biome ACCEPTS. A runtime whose provided
|
|
585
|
+
* isolation is not in this set is ineligible. Omit to accept any.
|
|
586
|
+
*/
|
|
587
|
+
isolation: z
|
|
588
|
+
.object({
|
|
589
|
+
allowed: z.array(RuntimeIsolationLevelSchema).min(1),
|
|
590
|
+
})
|
|
591
|
+
.strict()
|
|
592
|
+
.optional(),
|
|
593
|
+
/**
|
|
594
|
+
* Data localities the biome ACCEPTS (e.g. pin to `customer-private`).
|
|
595
|
+
* A runtime/runner whose locality is not in this set is ineligible.
|
|
596
|
+
*/
|
|
597
|
+
locality: z
|
|
598
|
+
.object({
|
|
599
|
+
allowed: z.array(DataLocalitySchema).min(1),
|
|
600
|
+
})
|
|
601
|
+
.strict()
|
|
602
|
+
.optional(),
|
|
603
|
+
/**
|
|
604
|
+
* Minimum attestation trust tier the executing runner must meet.
|
|
605
|
+
*/
|
|
606
|
+
trustTier: z
|
|
607
|
+
.object({
|
|
608
|
+
minimum: z.nativeEnum(RunnerTrustTier),
|
|
609
|
+
})
|
|
610
|
+
.strict()
|
|
611
|
+
.optional(),
|
|
612
|
+
})
|
|
613
|
+
.strict();
|
|
614
|
+
|
|
615
|
+
export type RuntimeRequirements = z.infer<typeof RuntimeRequirementsSchema>;
|
|
616
|
+
|
|
617
|
+
const ServerBiomeXemaSchema = z
|
|
618
|
+
.object({
|
|
619
|
+
id: BiomeIdSchema,
|
|
620
|
+
displayName: z.string().min(1),
|
|
621
|
+
description: z.string().optional(),
|
|
622
|
+
scope: BiomeScopeSchema,
|
|
623
|
+
target: z.literal('server'),
|
|
624
|
+
/**
|
|
625
|
+
* What this biome needs from the runtime/runner that executes it
|
|
626
|
+
* (labels, resources, isolation, locality, trust). Requirements only —
|
|
627
|
+
* a manifest may NOT name a concrete runtime/runner/host (see
|
|
628
|
+
* {@link RuntimeRequirementsSchema}). Server biomes only; web biomes are
|
|
629
|
+
* static bundles served by the host shell and never run on a runner.
|
|
630
|
+
*/
|
|
631
|
+
runtimeRequirements: RuntimeRequirementsSchema.optional(),
|
|
632
|
+
/**
|
|
633
|
+
* Whether biome-host must refuse to start without this biome
|
|
634
|
+
* resolving. Defaults to `true` for `scope: 'kernel'` and `false`
|
|
635
|
+
* for every other scope. Manifests may set this explicitly.
|
|
636
|
+
*/
|
|
637
|
+
mandatory: z.boolean().optional(),
|
|
638
|
+
/**
|
|
639
|
+
* Server biome ids this biome depends on. Biome-host topologically
|
|
640
|
+
* sorts the server set at boot and fails fast on cycles or unsatisfied
|
|
641
|
+
* dependencies. A kernel biome may only depend on other kernel
|
|
642
|
+
* biomes (enforced by biome-host).
|
|
643
|
+
*/
|
|
644
|
+
dependencies: z.array(BiomeIdSchema).optional(),
|
|
645
|
+
/**
|
|
646
|
+
* Biome id(s) this biome EXTENDS. An extending biome is the
|
|
647
|
+
* same-or-upgraded variant of the biome(s) it extends and MAY re-ship
|
|
648
|
+
* their content (agent slugs, workspace manifests, skills); when both
|
|
649
|
+
* are installed the extending biome's version takes precedence. This is
|
|
650
|
+
* the machine-readable form of the "the commercial cultivar extends this
|
|
651
|
+
* community reference biome" relationship — e.g. `document-buddy`
|
|
652
|
+
* (platform cultivar) extends `document-buddy-reference` (community
|
|
653
|
+
* reference). Distinct from `dependencies`: an extended biome need NOT be
|
|
654
|
+
* installed (the extension is self-contained), whereas a dependency must
|
|
655
|
+
* resolve at boot. `extends` is what lets the agent-slug uniqueness
|
|
656
|
+
* invariant tolerate the re-shipped slug — see
|
|
657
|
+
* tooling/boundaries/check-agent-duplication.mjs.
|
|
658
|
+
*/
|
|
659
|
+
extends: z.union([BiomeIdSchema, z.array(BiomeIdSchema)]).optional(),
|
|
660
|
+
ships: BiomeShipsSchema.optional(),
|
|
661
|
+
capabilities: ServerBiomeCapabilitiesSchema.optional(),
|
|
662
|
+
/**
|
|
663
|
+
* Hosting posture for adapter-contribution modules (Phase 7). Other
|
|
664
|
+
* biome kinds ignore this field. Defaults to `third-party`.
|
|
665
|
+
*/
|
|
666
|
+
trustTier: BiomeTrustTierSchema.optional(),
|
|
667
|
+
/**
|
|
668
|
+
* Integration dependencies the biome needs to be useful. Surfaced
|
|
669
|
+
* to the install wizard as a consent screen. Non-optional entries
|
|
670
|
+
* gate the `BiomeInstallation` state transition to `active`.
|
|
671
|
+
*/
|
|
672
|
+
integrationRequirements: z.array(IntegrationRequirementSchema).optional(),
|
|
673
|
+
/**
|
|
674
|
+
* Per-(workflow, event) filter expressions evaluated by the
|
|
675
|
+
* workflow-engine dispatcher at webhook time. Each entry MUST
|
|
676
|
+
* resolve to a workflow shipped by this biome and an event that
|
|
677
|
+
* workflow declares under `on.webhook[].event`. The DSL compiler
|
|
678
|
+
* cross-validates at publish time; manifest parsing only enforces
|
|
679
|
+
* shape.
|
|
680
|
+
*/
|
|
681
|
+
webhookFilters: z.array(WebhookFilterSchema).optional(),
|
|
682
|
+
/**
|
|
683
|
+
* Workflows the biome wants exposed as MCP tools. The MCP gateway
|
|
684
|
+
* (`mcp-gateway-api`) projects each entry into the catalog-mode
|
|
685
|
+
* tool listing surfaced to agents via OpenCode. When an agent
|
|
686
|
+
* invokes the tool, the gateway dispatches the workflow run
|
|
687
|
+
* (auto-attaching the calling installation's id, JWT-derived org
|
|
688
|
+
* + actor context) and returns the named deliverable plus an
|
|
689
|
+
* optional workspace mount entry so the result lands on disk
|
|
690
|
+
* automatically.
|
|
691
|
+
*
|
|
692
|
+
* Each `key` is unique within the biome and becomes the MCP tool
|
|
693
|
+
* id (`<biomeId>__<key>`). `workflowSlug` MUST resolve to a
|
|
694
|
+
* workflow this biome ships; the workflow-engine cross-validates
|
|
695
|
+
* at publish time. `outputProjection.deliverable.slug` picks one
|
|
696
|
+
* of the workflow's declared `produces:` entries to surface as the
|
|
697
|
+
* tool's primary content payload. The optional `mount` block
|
|
698
|
+
* issues a `POST /workspace/mounts/apply` on the calling agent's
|
|
699
|
+
* session so the result file appears under `/workspace/<slot>/...`
|
|
700
|
+
* — seamless from the agent's point of view.
|
|
701
|
+
*/
|
|
702
|
+
mcpWorkflowTools: z
|
|
703
|
+
.array(
|
|
704
|
+
z
|
|
705
|
+
.object({
|
|
706
|
+
key: z
|
|
707
|
+
.string()
|
|
708
|
+
.min(1)
|
|
709
|
+
.regex(/^[a-z][a-z0-9-]*$/, 'key must be lowercase-kebab'),
|
|
710
|
+
workflowSlug: z.string().min(1),
|
|
711
|
+
displayName: z.string().min(1),
|
|
712
|
+
description: z.string().min(1),
|
|
713
|
+
outputProjection: z
|
|
714
|
+
.object({
|
|
715
|
+
kind: z.literal('deliverable'),
|
|
716
|
+
slug: z.string().min(1),
|
|
717
|
+
})
|
|
718
|
+
.strict(),
|
|
719
|
+
mount: z
|
|
720
|
+
.object({
|
|
721
|
+
slot: z.enum(['inputs', 'references', 'deliverables']),
|
|
722
|
+
as: z.string().min(1),
|
|
723
|
+
})
|
|
724
|
+
.strict()
|
|
725
|
+
.optional(),
|
|
726
|
+
})
|
|
727
|
+
.strict(),
|
|
728
|
+
)
|
|
729
|
+
.optional(),
|
|
730
|
+
/**
|
|
731
|
+
* Plain handler functions the biome's API service exposes as MCP
|
|
732
|
+
* tools. The platform wraps them via the `biome_code_tools`
|
|
733
|
+
* provider — biome authors never see MCP protocol bytes.
|
|
734
|
+
*
|
|
735
|
+
* Each entry's `key` is unique within the biome and maps to a
|
|
736
|
+
* decorated method on the biome's API service via the
|
|
737
|
+
* `@BiomeCodeTool` decorator from `@xemahq/biome-api-sdk`. The
|
|
738
|
+
* full descriptor (inputSchema, displayName, output kind) is
|
|
739
|
+
* authoritative on the biome API side and surfaced through
|
|
740
|
+
* `GET /code-tools-manifest`; this manifest entry is the
|
|
741
|
+
* lightweight "I ship this tool" declaration the platform reads
|
|
742
|
+
* at install time.
|
|
743
|
+
*/
|
|
744
|
+
mcpTools: z
|
|
745
|
+
.array(
|
|
746
|
+
z
|
|
747
|
+
.object({
|
|
748
|
+
key: z
|
|
749
|
+
.string()
|
|
750
|
+
.min(1)
|
|
751
|
+
.regex(/^[a-z][a-z0-9-]*$/, 'key must be lowercase-kebab'),
|
|
752
|
+
handler: z
|
|
753
|
+
.object({
|
|
754
|
+
kind: z.literal('biome_api'),
|
|
755
|
+
method: z.enum(['POST']).default('POST'),
|
|
756
|
+
})
|
|
757
|
+
.strict(),
|
|
758
|
+
})
|
|
759
|
+
.strict(),
|
|
760
|
+
)
|
|
761
|
+
.optional(),
|
|
762
|
+
/**
|
|
763
|
+
* Tools the biome recommends are made available when a user
|
|
764
|
+
* adopts it. Surfaced in the install UX as "this biome recommends
|
|
765
|
+
* these tools" — NOT auto-injected into every session. Each entry
|
|
766
|
+
* matches the kernel `ToolSelectionEntry` shape from
|
|
767
|
+
* `@xemahq/kernel-contracts/mcp-tool`. The frontend picker drops these
|
|
768
|
+
* directly into the session's selection on user opt-in.
|
|
769
|
+
*
|
|
770
|
+
* Validation: shape-only at boot. `resourceId` references resolve
|
|
771
|
+
* at install time (e.g. biome-installation-id is materialized by
|
|
772
|
+
* biome-host-api when the installation is created). Cross-tenant
|
|
773
|
+
* misuse is blocked downstream by the resolver (Layer 2) and the
|
|
774
|
+
* PATCH-time validator (Layer 1) when the user actually adopts the
|
|
775
|
+
* selection.
|
|
776
|
+
*/
|
|
777
|
+
defaultToolSelection: z
|
|
778
|
+
.array(
|
|
779
|
+
z
|
|
780
|
+
.discriminatedUnion('kind', [
|
|
781
|
+
z
|
|
782
|
+
.object({
|
|
783
|
+
kind: z.literal('provider'),
|
|
784
|
+
providerKind: z.enum([
|
|
785
|
+
'mcp_server',
|
|
786
|
+
'catalog',
|
|
787
|
+
'biome_workflow_tools',
|
|
788
|
+
'biome_code_tools',
|
|
789
|
+
]),
|
|
790
|
+
resourceId: z.string().min(1).max(256),
|
|
791
|
+
})
|
|
792
|
+
.strict(),
|
|
793
|
+
z
|
|
794
|
+
.object({
|
|
795
|
+
kind: z.literal('tool'),
|
|
796
|
+
providerKind: z.enum([
|
|
797
|
+
'mcp_server',
|
|
798
|
+
'catalog',
|
|
799
|
+
'biome_workflow_tools',
|
|
800
|
+
'biome_code_tools',
|
|
801
|
+
]),
|
|
802
|
+
resourceId: z.string().min(1).max(256),
|
|
803
|
+
toolName: z.string().min(1).max(256),
|
|
804
|
+
})
|
|
805
|
+
.strict(),
|
|
806
|
+
]),
|
|
807
|
+
)
|
|
808
|
+
.max(64)
|
|
809
|
+
.optional(),
|
|
810
|
+
/**
|
|
811
|
+
* Explicit roster of agents this biome ships. Required when
|
|
812
|
+
* `ships.content` includes `'agents'`; forbidden otherwise. Each
|
|
813
|
+
* entry pins one `agents/<slug>.md` file with its execution mode
|
|
814
|
+
* (primary vs subagent).
|
|
815
|
+
*
|
|
816
|
+
* Why both this field AND the on-disk `agents/` scan exist:
|
|
817
|
+
* - The declaration makes the roster greppable from outside the
|
|
818
|
+
* biome tree (`grep '"slug": "build"' biomes/*\/xema-biome.json`).
|
|
819
|
+
* - It lets biome-host fail fast at boot when an agent file is
|
|
820
|
+
* added or removed without updating the manifest — the prior
|
|
821
|
+
* convention silently accepted drift.
|
|
822
|
+
* - The closed `mode` enum surfaces primary-vs-subagent intent at
|
|
823
|
+
* install time instead of requiring readers to parse YAML
|
|
824
|
+
* frontmatter from every .md.
|
|
825
|
+
*
|
|
826
|
+
* Cross-validated by `crossValidateAgentDeclarations` at
|
|
827
|
+
* biome-host boot; the seeder still reads frontmatter for the rest
|
|
828
|
+
* of each agent's attributes.
|
|
829
|
+
*/
|
|
830
|
+
agents: z.array(BiomeAgentDeclarationSchema).optional(),
|
|
831
|
+
/**
|
|
832
|
+
* Workspace-provisioning scaffolds the biome ships (Epic A). Each
|
|
833
|
+
* entry pins one `provisioning/<id>.yaml` recipe and declares when it
|
|
834
|
+
* runs + how the resolver expands it. Required ⟺ `ships.content`
|
|
835
|
+
* includes `provisioningScaffolds`; cross-validated in `superRefine`.
|
|
836
|
+
*/
|
|
837
|
+
provisioning: z.array(ProvisioningScaffoldDeclarationSchema).optional(),
|
|
838
|
+
/**
|
|
839
|
+
* Biome-specific org-managed database declaration. When present the
|
|
840
|
+
* host provisions an org database, runs the declared migrations, and
|
|
841
|
+
* injects the org database identifiers into the runtime workload env.
|
|
842
|
+
*/
|
|
843
|
+
database: BiomeDatabaseDeclarationSchema.optional(),
|
|
844
|
+
/** Reserved for Phase 4 third-party signing. Validated only when present. */
|
|
845
|
+
signature: z
|
|
846
|
+
.object({
|
|
847
|
+
algorithm: z.string().min(1),
|
|
848
|
+
value: z.string().min(1),
|
|
849
|
+
keyId: z.string().min(1),
|
|
850
|
+
})
|
|
851
|
+
.strict()
|
|
852
|
+
.optional(),
|
|
853
|
+
// XSI Phase 1A additive fields. See `XsiManifestExtensionsShape`
|
|
854
|
+
// doc-comment above for the per-field meaning + plan citations.
|
|
855
|
+
...XsiManifestExtensionsShape,
|
|
856
|
+
})
|
|
857
|
+
.strict()
|
|
858
|
+
.superRefine((value, ctx) => {
|
|
859
|
+
validateServerPluginWebhookAndIntegrationRequirements(value, ctx);
|
|
860
|
+
validateServerBiomeAgentDeclarations(value, ctx);
|
|
861
|
+
validateServerPluginProvisioningDeclarations(value, ctx);
|
|
862
|
+
});
|
|
863
|
+
|
|
864
|
+
const WebBiomeXemaSchema = z
|
|
865
|
+
.object({
|
|
866
|
+
id: BiomeIdSchema,
|
|
867
|
+
displayName: z.string().min(1),
|
|
868
|
+
description: z.string().optional(),
|
|
869
|
+
scope: BiomeScopeSchema,
|
|
870
|
+
target: z.literal('web'),
|
|
871
|
+
mandatory: z.boolean().optional(),
|
|
872
|
+
/**
|
|
873
|
+
* Server biomes this web biome REQUIRES — its backend counterpart(s).
|
|
874
|
+
* Web biomes never depend on other web biomes — intentional, keeps the
|
|
875
|
+
* dependency graph two-tiered (web → server). Cross-target validation at
|
|
876
|
+
* boot ensures every referenced server id resolves in the catalog;
|
|
877
|
+
* otherwise biome-host refuses to start. Per-org, a web biome whose
|
|
878
|
+
* required server biomes are not all enabled resolves to ORPHANED.
|
|
879
|
+
*/
|
|
880
|
+
requiresServerBiomes: z.array(BiomeIdSchema).optional(),
|
|
881
|
+
/**
|
|
882
|
+
* Server biomes this web biome can OPTIONALLY integrate with (e.g. a
|
|
883
|
+
* GitHub/Jira connector). The web biome stays active without them; they
|
|
884
|
+
* are NOT part of the cross-target boot validation and never cause an
|
|
885
|
+
* ORPHANED state.
|
|
886
|
+
*/
|
|
887
|
+
optionalServerBiomes: z.array(BiomeIdSchema).optional(),
|
|
888
|
+
capabilities: WebBiomeCapabilitiesSchema.optional(),
|
|
889
|
+
signature: z
|
|
890
|
+
.object({
|
|
891
|
+
algorithm: z.string().min(1),
|
|
892
|
+
value: z.string().min(1),
|
|
893
|
+
keyId: z.string().min(1),
|
|
894
|
+
})
|
|
895
|
+
.strict()
|
|
896
|
+
.optional(),
|
|
897
|
+
// XSI Phase 1A additive fields — same shape on both targets so the
|
|
898
|
+
// biome-host can read them uniformly regardless of where the biome
|
|
899
|
+
// executes. See `XsiManifestExtensionsShape` above.
|
|
900
|
+
...XsiManifestExtensionsShape,
|
|
901
|
+
})
|
|
902
|
+
.strict();
|
|
903
|
+
|
|
904
|
+
export const BiomeXemaSchema = z.discriminatedUnion('target', [
|
|
905
|
+
ServerBiomeXemaSchema,
|
|
906
|
+
WebBiomeXemaSchema,
|
|
907
|
+
]);
|
|
908
|
+
export type BiomeXema = z.infer<typeof BiomeXemaSchema>;
|
|
909
|
+
export type ServerBiomeXema = z.infer<typeof ServerBiomeXemaSchema>;
|
|
910
|
+
export type WebBiomeXema = z.infer<typeof WebBiomeXemaSchema>;
|
|
911
|
+
|
|
912
|
+
function validateServerPluginWebhookAndIntegrationRequirements(
|
|
913
|
+
value: ServerBiomeXema,
|
|
914
|
+
ctx: z.RefinementCtx,
|
|
915
|
+
): void {
|
|
916
|
+
if (value.webhookFilters && value.webhookFilters.length > 0) {
|
|
917
|
+
const requirements = value.integrationRequirements ?? [];
|
|
918
|
+
if (requirements.length === 0) {
|
|
919
|
+
ctx.addIssue({
|
|
920
|
+
code: 'custom',
|
|
921
|
+
path: ['webhookFilters'],
|
|
922
|
+
message:
|
|
923
|
+
'webhookFilters is set but integrationRequirements is empty — a biome gating workflows on webhook events must declare which integration(s) it requires',
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
if (value.integrationRequirements && value.integrationRequirements.length > 0) {
|
|
928
|
+
const shipsInstallSchema = value.ships?.content?.includes('biomeInstallSchema') ?? false;
|
|
929
|
+
if (!shipsInstallSchema) {
|
|
930
|
+
ctx.addIssue({
|
|
931
|
+
code: 'custom',
|
|
932
|
+
path: ['ships', 'content'],
|
|
933
|
+
message:
|
|
934
|
+
'biomes declaring integrationRequirements must also ship a `biomeInstallSchema` content kind so the install wizard can render a resource-selection form',
|
|
935
|
+
});
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
function validateServerBiomeAgentDeclarations(
|
|
941
|
+
value: ServerBiomeXema,
|
|
942
|
+
ctx: z.RefinementCtx,
|
|
943
|
+
): void {
|
|
944
|
+
const shipsAgents = value.ships?.content?.includes('agents') ?? false;
|
|
945
|
+
const hasAgents = (value.agents?.length ?? 0) > 0;
|
|
946
|
+
if (shipsAgents && !hasAgents) {
|
|
947
|
+
ctx.addIssue({
|
|
948
|
+
code: 'custom',
|
|
949
|
+
path: ['agents'],
|
|
950
|
+
message:
|
|
951
|
+
'ships.content includes "agents" — manifest must declare each shipped agent under `agents[]` (slug + mode). The boot-time cross-validator enforces parity with on-disk agents/*.md files.',
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
if (!shipsAgents && hasAgents) {
|
|
955
|
+
ctx.addIssue({
|
|
956
|
+
code: 'custom',
|
|
957
|
+
path: ['agents'],
|
|
958
|
+
message:
|
|
959
|
+
'agents[] is declared but ships.content does not include "agents" — add "agents" to ships.content or remove the agents[] block',
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
if (hasAgents) {
|
|
963
|
+
const slugs = new Set<string>();
|
|
964
|
+
value.agents?.forEach((decl, idx) => {
|
|
965
|
+
if (slugs.has(decl.slug)) {
|
|
966
|
+
ctx.addIssue({
|
|
967
|
+
code: 'custom',
|
|
968
|
+
path: ['agents', idx, 'slug'],
|
|
969
|
+
message: `duplicate agent slug "${decl.slug}" — each slug maps to a single agents/<slug>.md file`,
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
slugs.add(decl.slug);
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
function validateServerPluginProvisioningDeclarations(
|
|
978
|
+
value: ServerBiomeXema,
|
|
979
|
+
ctx: z.RefinementCtx,
|
|
980
|
+
): void {
|
|
981
|
+
const shipsProvisioning = value.ships?.content?.includes('provisioningScaffolds') ?? false;
|
|
982
|
+
const hasProvisioning = (value.provisioning?.length ?? 0) > 0;
|
|
983
|
+
if (shipsProvisioning && !hasProvisioning) {
|
|
984
|
+
ctx.addIssue({
|
|
985
|
+
code: 'custom',
|
|
986
|
+
path: ['provisioning'],
|
|
987
|
+
message:
|
|
988
|
+
'ships.content includes "provisioningScaffolds" — manifest must declare each scaffold under `provisioning[]`',
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
if (!shipsProvisioning && hasProvisioning) {
|
|
992
|
+
ctx.addIssue({
|
|
993
|
+
code: 'custom',
|
|
994
|
+
path: ['provisioning'],
|
|
995
|
+
message:
|
|
996
|
+
'provisioning[] is declared but ships.content does not include "provisioningScaffolds" — add it or remove the provisioning[] block',
|
|
997
|
+
});
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
const ManifestNameSchema = z
|
|
1002
|
+
.string()
|
|
1003
|
+
.min(1)
|
|
1004
|
+
.regex(/^@[^/]+\/[^/]+$/, 'biome package name must be scoped');
|
|
1005
|
+
|
|
1006
|
+
export const BiomeManifestSchema = z
|
|
1007
|
+
.object({
|
|
1008
|
+
name: ManifestNameSchema,
|
|
1009
|
+
version: z.string().min(1),
|
|
1010
|
+
xema: BiomeXemaSchema,
|
|
1011
|
+
})
|
|
1012
|
+
.passthrough(); // tolerate extra top-level npm fields
|
|
1013
|
+
|
|
1014
|
+
export type BiomeManifest = z.infer<typeof BiomeManifestSchema>;
|
|
1015
|
+
export type ServerBiomeManifest = BiomeManifest & { xema: ServerBiomeXema };
|
|
1016
|
+
export type WebBiomeManifest = BiomeManifest & { xema: WebBiomeXema };
|
|
1017
|
+
|
|
1018
|
+
export class BiomeManifestParseError extends Error {
|
|
1019
|
+
readonly issues: readonly z.core.$ZodIssue[];
|
|
1020
|
+
constructor(issues: readonly z.core.$ZodIssue[]) {
|
|
1021
|
+
super(
|
|
1022
|
+
`Invalid xema-biome.json: ${issues
|
|
1023
|
+
.map((i) => `[${i.path.join('.')}] ${i.message}`)
|
|
1024
|
+
.join('; ')}`,
|
|
1025
|
+
);
|
|
1026
|
+
this.name = 'BiomeManifestParseError';
|
|
1027
|
+
this.issues = issues;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
export function parseBiomeManifest(raw: unknown): BiomeManifest {
|
|
1032
|
+
const result = BiomeManifestSchema.safeParse(raw);
|
|
1033
|
+
if (!result.success) {
|
|
1034
|
+
throw new BiomeManifestParseError(result.error.issues);
|
|
1035
|
+
}
|
|
1036
|
+
return result.data;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
export function isServerBiomeManifest(
|
|
1040
|
+
manifest: BiomeManifest,
|
|
1041
|
+
): manifest is ServerBiomeManifest {
|
|
1042
|
+
return manifest.xema.target === 'server';
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
export function isWebBiomeManifest(
|
|
1046
|
+
manifest: BiomeManifest,
|
|
1047
|
+
): manifest is WebBiomeManifest {
|
|
1048
|
+
return manifest.xema.target === 'web';
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
/**
|
|
1052
|
+
* Whether `mandatory` is true for this manifest, applying the default
|
|
1053
|
+
* (kernel → true; everything else → false) when the field is omitted.
|
|
1054
|
+
*/
|
|
1055
|
+
export function isBiomeMandatory(manifest: BiomeManifest): boolean {
|
|
1056
|
+
if (typeof manifest.xema.mandatory === 'boolean') {
|
|
1057
|
+
return manifest.xema.mandatory;
|
|
1058
|
+
}
|
|
1059
|
+
return manifest.xema.scope === 'kernel';
|
|
1060
|
+
}
|