@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,43 @@
|
|
|
1
|
+
import type { MountResolver } from '../mount-resolver';
|
|
2
|
+
import type { MountSource } from '../mount-source';
|
|
3
|
+
import type { ResolveContext, ResolveSlotContext, ResolvedMountEntries } from './types';
|
|
4
|
+
import type { ScmClient } from './clients';
|
|
5
|
+
import { assertAuthHeaders } from './utils/auth';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* `scm-repo` mount kind — returns clone instructions only; the writer
|
|
9
|
+
* phase invokes `git clone` as a subprocess that streams directly into
|
|
10
|
+
* the staging directory. This avoids piping multi-hundred-MB clones
|
|
11
|
+
* through workspace-proxy's request body.
|
|
12
|
+
*
|
|
13
|
+
* Default flags: `--depth=1 --filter=blob:none` for fast checkouts.
|
|
14
|
+
* Workflow YAML can override depth/filter when full history is needed.
|
|
15
|
+
*/
|
|
16
|
+
export class ScmRepoResolver implements MountResolver<'scm-repo'> {
|
|
17
|
+
readonly kind = 'scm-repo' as const;
|
|
18
|
+
|
|
19
|
+
constructor(private readonly client: ScmClient) {}
|
|
20
|
+
|
|
21
|
+
async *resolve(
|
|
22
|
+
source: Extract<MountSource, { kind: 'scm-repo' }>,
|
|
23
|
+
slotCtx: ResolveSlotContext,
|
|
24
|
+
ctx: ResolveContext,
|
|
25
|
+
): ResolvedMountEntries {
|
|
26
|
+
const headers = assertAuthHeaders(ctx);
|
|
27
|
+
const instruction = await this.client.resolveCheckout(source.repoRef, source.ref, headers);
|
|
28
|
+
yield {
|
|
29
|
+
// empty relPath — the slot's entryRelPath already targets the
|
|
30
|
+
// repo's directory (e.g. `<repoName>/`); the writer drops the
|
|
31
|
+
// checkout into that directory.
|
|
32
|
+
relPath: '',
|
|
33
|
+
mode: slotCtx.mode,
|
|
34
|
+
body: {
|
|
35
|
+
kind: 'gitClone',
|
|
36
|
+
cloneUrl: instruction.cloneUrl,
|
|
37
|
+
ref: instruction.ref,
|
|
38
|
+
depth: instruction.depth,
|
|
39
|
+
filter: instruction.filter,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { MountResolver } from '../mount-resolver';
|
|
2
|
+
import type { MountSource } from '../mount-source';
|
|
3
|
+
import type { ResolveContext, ResolveSlotContext, ResolvedMountEntries } from './types';
|
|
4
|
+
import type { SessionAttachmentClient } from './clients';
|
|
5
|
+
import { assertAuthHeaders } from './utils/auth';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* `session-attachment` mount kind — streams every attachment that the
|
|
9
|
+
* user uploaded for the session into the slot. Each attachment lands
|
|
10
|
+
* at the relPath the upstream service returns (typically the original
|
|
11
|
+
* filename, sanitized).
|
|
12
|
+
*/
|
|
13
|
+
export class SessionAttachmentResolver implements MountResolver<'session-attachment'> {
|
|
14
|
+
readonly kind = 'session-attachment' as const;
|
|
15
|
+
|
|
16
|
+
constructor(private readonly client: SessionAttachmentClient) {}
|
|
17
|
+
|
|
18
|
+
async *resolve(
|
|
19
|
+
source: Extract<MountSource, { kind: 'session-attachment' }>,
|
|
20
|
+
slotCtx: ResolveSlotContext,
|
|
21
|
+
ctx: ResolveContext,
|
|
22
|
+
): ResolvedMountEntries {
|
|
23
|
+
const headers = assertAuthHeaders(ctx);
|
|
24
|
+
const items = await this.client.streamSessionAttachments(source.sessionId, headers);
|
|
25
|
+
for await (const item of items) {
|
|
26
|
+
yield {
|
|
27
|
+
relPath: item.relPath,
|
|
28
|
+
mode: slotCtx.mode,
|
|
29
|
+
body: {
|
|
30
|
+
kind: 'stream',
|
|
31
|
+
readable: item.readable,
|
|
32
|
+
sizeHint: item.sizeBytes,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { MountResolver } from '../mount-resolver';
|
|
2
|
+
import type { MountSource } from '../mount-source';
|
|
3
|
+
import type { SkillRegistryClient } from './clients';
|
|
4
|
+
import type { ResolveContext, ResolveSlotContext, ResolvedMountEntries } from './types';
|
|
5
|
+
import { assertAuthHeaders } from './utils/auth';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* `skill-bundle` mount kind — fetches a complete multi-file skill bundle
|
|
9
|
+
* from skill-registry-api and emits `SKILL.md` plus one file per bundled
|
|
10
|
+
* resource (reference docs, scripts, assets, templates) under the
|
|
11
|
+
* `skill-bundles` slot (`/workspace/.opencode/skills/<skillKey>/`).
|
|
12
|
+
*
|
|
13
|
+
* Per OpenCode convention each skill lives in its own folder named after
|
|
14
|
+
* the skill key; the mount entry's `relPath` is that folder and the
|
|
15
|
+
* per-file `relPath`s yielded here land the bundle members inside it.
|
|
16
|
+
*/
|
|
17
|
+
export class SkillBundleResolver implements MountResolver<'skill-bundle'> {
|
|
18
|
+
readonly kind = 'skill-bundle' as const;
|
|
19
|
+
|
|
20
|
+
constructor(private readonly client: SkillRegistryClient) {}
|
|
21
|
+
|
|
22
|
+
async *resolve(
|
|
23
|
+
source: Extract<MountSource, { kind: 'skill-bundle' }>,
|
|
24
|
+
slotCtx: ResolveSlotContext,
|
|
25
|
+
ctx: ResolveContext,
|
|
26
|
+
): ResolvedMountEntries {
|
|
27
|
+
const headers = assertAuthHeaders(ctx);
|
|
28
|
+
const bundle = await this.client.fetchSkillBundle(source.skillKey, headers);
|
|
29
|
+
yield {
|
|
30
|
+
relPath: 'SKILL.md',
|
|
31
|
+
mode: slotCtx.mode,
|
|
32
|
+
body: { kind: 'literal', bytes: Buffer.from(bundle.skillMarkdown, 'utf8') },
|
|
33
|
+
};
|
|
34
|
+
for (const resource of bundle.resources) {
|
|
35
|
+
yield {
|
|
36
|
+
relPath: resource.relPath,
|
|
37
|
+
mode: slotCtx.mode,
|
|
38
|
+
body: { kind: 'literal', bytes: Buffer.from(resource.contentBase64, 'base64') },
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { MountResolver } from '../mount-resolver';
|
|
2
|
+
import type { MountSource } from '../mount-source';
|
|
3
|
+
import type { ResolveContext, ResolveSlotContext, ResolvedMountEntries, MountEntry } from './types';
|
|
4
|
+
import { MountPlanInvalidError } from '../errors';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `static-literal` mount kind — emits the inline base64 bytes at the
|
|
8
|
+
* entry's own location within the slot.
|
|
9
|
+
*
|
|
10
|
+
* Path semantics: the file's location is determined by the PLAN entry's
|
|
11
|
+
* `relPath` (composed by the writer as `<slot>/<entry.relPath>`).
|
|
12
|
+
* `source.pathWithinWorkspace` is identity metadata only — it must be
|
|
13
|
+
* a syntactically-valid relative path (we still fail-fast on absolute /
|
|
14
|
+
* traversal / NUL) but the resolver does NOT use it to nest the file.
|
|
15
|
+
* Doing so would produce `<slot>/<entry.relPath>/<pathWithinWorkspace>`,
|
|
16
|
+
* doubly-nesting when (as is the convention in every caller) both
|
|
17
|
+
* fields carry the same path string.
|
|
18
|
+
*
|
|
19
|
+
* The yielded sub-entry's `relPath` is therefore `''`, meaning "land at
|
|
20
|
+
* the entry root". The plan validator's `(slot, entry.relPath)` dedup
|
|
21
|
+
* remains the single source of truth for "two seedFiles must not target
|
|
22
|
+
* the same path".
|
|
23
|
+
*/
|
|
24
|
+
export class StaticLiteralResolver implements MountResolver<'static-literal'> {
|
|
25
|
+
readonly kind = 'static-literal' as const;
|
|
26
|
+
|
|
27
|
+
// eslint-disable-next-line require-yield
|
|
28
|
+
async *resolve(
|
|
29
|
+
source: Extract<MountSource, { kind: 'static-literal' }>,
|
|
30
|
+
slotCtx: ResolveSlotContext,
|
|
31
|
+
_ctx: ResolveContext,
|
|
32
|
+
): ResolvedMountEntries {
|
|
33
|
+
yield this.toEntry(source, slotCtx);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private toEntry(
|
|
37
|
+
source: Extract<MountSource, { kind: 'static-literal' }>,
|
|
38
|
+
slotCtx: ResolveSlotContext,
|
|
39
|
+
): MountEntry {
|
|
40
|
+
const { pathWithinWorkspace, bytes } = source;
|
|
41
|
+
if (
|
|
42
|
+
pathWithinWorkspace.length === 0 ||
|
|
43
|
+
pathWithinWorkspace.startsWith('/') ||
|
|
44
|
+
pathWithinWorkspace.includes('..') ||
|
|
45
|
+
pathWithinWorkspace.includes('\0')
|
|
46
|
+
) {
|
|
47
|
+
throw new MountPlanInvalidError(
|
|
48
|
+
`static-literal: invalid relative path '${pathWithinWorkspace}'`,
|
|
49
|
+
{ pathWithinWorkspace },
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
let decoded: Uint8Array;
|
|
53
|
+
try {
|
|
54
|
+
decoded = Buffer.from(bytes, 'base64');
|
|
55
|
+
} catch (error) {
|
|
56
|
+
throw new MountPlanInvalidError(
|
|
57
|
+
`static-literal: bytes are not valid base64 — ${(error as Error).message}`,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
// Sub-entry sits at the entry root. The plan entry's `relPath`
|
|
62
|
+
// (echoed back to us as `slotCtx.entryRelPath`) is the file's
|
|
63
|
+
// location within the slot.
|
|
64
|
+
relPath: '',
|
|
65
|
+
mode: slotCtx.mode,
|
|
66
|
+
body: { kind: 'literal', bytes: decoded },
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { Readable } from 'node:stream';
|
|
2
|
+
import type {
|
|
3
|
+
WorkspaceMount,
|
|
4
|
+
WorkspaceMountMode,
|
|
5
|
+
} from '@xemahq/kernel-contracts/agent-workspace';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Authenticated context passed to every `MountResolver.resolve()` call.
|
|
9
|
+
* `authHeaders` is the verbatim header bag the resolver MUST forward to
|
|
10
|
+
* its upstream Orval client — that is how cross-tenant access is
|
|
11
|
+
* prevented at the upstream service.
|
|
12
|
+
*
|
|
13
|
+
* `authHeaders` always contains `Authorization` + `X-Org-Id` +
|
|
14
|
+
* `X-Project-Id`; resolvers assert their presence and refuse to call
|
|
15
|
+
* upstream without them (defense-in-depth even though the proxy already
|
|
16
|
+
* built them).
|
|
17
|
+
*/
|
|
18
|
+
export interface ResolveContext {
|
|
19
|
+
readonly orgId: string;
|
|
20
|
+
readonly projectId: string;
|
|
21
|
+
readonly userId: string;
|
|
22
|
+
readonly correlationId: string;
|
|
23
|
+
/**
|
|
24
|
+
* Header bag — `Authorization`, `X-Org-Id`, `X-Project-Id`, plus any
|
|
25
|
+
* downstream headers the proxy decided to thread (e.g. correlation
|
|
26
|
+
* id). Keys preserve casing as upstream services expect.
|
|
27
|
+
*/
|
|
28
|
+
readonly authHeaders: Readonly<Record<string, string>>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* One byte-payload variant per resolver shape. Streamed for any
|
|
33
|
+
* not-trivially-small payload to keep workspace-proxy memory bounded
|
|
34
|
+
* even when mounts are hundreds of MB.
|
|
35
|
+
*/
|
|
36
|
+
export type ResolverBody =
|
|
37
|
+
| {
|
|
38
|
+
readonly kind: 'stream';
|
|
39
|
+
readonly readable: Readable;
|
|
40
|
+
readonly sizeHint: number | undefined;
|
|
41
|
+
}
|
|
42
|
+
| { readonly kind: 'literal'; readonly bytes: Uint8Array }
|
|
43
|
+
| {
|
|
44
|
+
readonly kind: 'gitClone';
|
|
45
|
+
readonly cloneUrl: string;
|
|
46
|
+
readonly ref: string;
|
|
47
|
+
readonly depth: number;
|
|
48
|
+
/** Optional partial-clone filter — defaults to `'blob:none'`. */
|
|
49
|
+
readonly filter: string | undefined;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* One file (or git checkout) the resolver wants the writer phase to
|
|
54
|
+
* materialize. The writer composes `${slot}/${entryRelPath}/${relPath}`
|
|
55
|
+
* to get the absolute path; both segments are validated against the
|
|
56
|
+
* slot allowlist + path-traversal sanitizer.
|
|
57
|
+
*
|
|
58
|
+
* `mode` is per-entry (NOT per-slot) so a single read-only `references/`
|
|
59
|
+
* mount can coexist with a read-write `repos/<repo>/` mount in the same
|
|
60
|
+
* apply.
|
|
61
|
+
*/
|
|
62
|
+
export interface MountEntry {
|
|
63
|
+
/** Path within the entry's slot — no leading `/`, no `..`, no NUL. */
|
|
64
|
+
readonly relPath: string;
|
|
65
|
+
readonly mode: WorkspaceMountMode;
|
|
66
|
+
readonly body: ResolverBody;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Resolver output. Returning an `AsyncIterable` lets each entry be
|
|
71
|
+
* fetched + streamed to disk independently, without buffering the whole
|
|
72
|
+
* mount in memory.
|
|
73
|
+
*/
|
|
74
|
+
export type ResolvedMountEntries = AsyncIterable<MountEntry>;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Echo of the slot the resolver was invoked for, so the writer phase
|
|
78
|
+
* knows where to root the entries. Set by the workspace-proxy
|
|
79
|
+
* orchestrator before invoking the resolver.
|
|
80
|
+
*
|
|
81
|
+
* `mode` is the plan-entry's mount mode — the SINGLE source of truth.
|
|
82
|
+
* Resolvers yield `mode: ctx.mode` so they cannot silently disagree
|
|
83
|
+
* with the composer's per-slot decision (e.g. yielding `ReadOnly` for
|
|
84
|
+
* a `repos/` plan entry the composer marked `ReadWrite` would deny
|
|
85
|
+
* the agent its writes without a code path that says so). The writer
|
|
86
|
+
* applies `entry.mode` directly; the resolver's echo is for symmetry
|
|
87
|
+
* and tests.
|
|
88
|
+
*/
|
|
89
|
+
export interface ResolveSlotContext {
|
|
90
|
+
readonly slot: WorkspaceMount;
|
|
91
|
+
/** Sub-path inside `slot` rooted at the entry's `WorkspaceMountPlanEntry.relPath`. */
|
|
92
|
+
readonly entryRelPath: string;
|
|
93
|
+
readonly mode: WorkspaceMountMode;
|
|
94
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
AgentRunContextRender,
|
|
5
|
+
LlmRegistryClient,
|
|
6
|
+
} from '../clients';
|
|
7
|
+
import type { AuthHeaders } from './auth';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Coalesces the three rendered-* resolvers (agents-md, context-json,
|
|
11
|
+
* system-overlay) onto a single `agent-run-context/render` HTTP call
|
|
12
|
+
* per mount-apply.
|
|
13
|
+
*
|
|
14
|
+
* Cache key: stable hash of the render params. The keys include
|
|
15
|
+
* `runId`/`jobRunId`/`sessionId` and `agentSlug`/`role`, so a single
|
|
16
|
+
* apply's three calls collide deterministically while cross-apply
|
|
17
|
+
* collision is impossible (different scope ids → different key).
|
|
18
|
+
*
|
|
19
|
+
* TTL is short (90s) and the cache is process-local — long enough to
|
|
20
|
+
* cover the same apply's three resolver invocations even under a slow
|
|
21
|
+
* mount, short enough that a reused process can't serve stale renders
|
|
22
|
+
* after a deliverable-spec edit. The render itself is deterministic;
|
|
23
|
+
* accidental hit on a redispatch with identical inputs returns the
|
|
24
|
+
* same bytes anyway.
|
|
25
|
+
*/
|
|
26
|
+
const CACHE_TTL_MS = 90_000;
|
|
27
|
+
|
|
28
|
+
interface CacheEntry {
|
|
29
|
+
readonly storedAt: number;
|
|
30
|
+
readonly value: Promise<AgentRunContextRender>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface RenderAgentRunContextParams {
|
|
34
|
+
readonly agentSlug: string;
|
|
35
|
+
readonly projectId: string;
|
|
36
|
+
readonly role: string;
|
|
37
|
+
readonly deliverableSpecRef?: string;
|
|
38
|
+
readonly workflowRunId?: string;
|
|
39
|
+
readonly jobRunId?: string;
|
|
40
|
+
readonly sessionId?: string;
|
|
41
|
+
readonly workflowInputs?: Readonly<Record<string, unknown>>;
|
|
42
|
+
readonly mounts?: ReadonlyArray<{
|
|
43
|
+
readonly mount: string;
|
|
44
|
+
readonly mode: 'read-only' | 'read-write';
|
|
45
|
+
}>;
|
|
46
|
+
readonly inputArtifacts?: ReadonlyArray<{
|
|
47
|
+
readonly path: string;
|
|
48
|
+
readonly contentType?: string;
|
|
49
|
+
readonly sourceArtifactId: string;
|
|
50
|
+
readonly sourceVersion: number;
|
|
51
|
+
}>;
|
|
52
|
+
readonly workingFiles?: ReadonlyArray<{
|
|
53
|
+
readonly slug: string;
|
|
54
|
+
readonly path: string;
|
|
55
|
+
readonly format: 'markdown' | 'html' | 'json' | 'yaml' | 'text';
|
|
56
|
+
readonly syncDirection: 'down-only' | 'up-only' | 'bidirectional';
|
|
57
|
+
readonly sourceKind: string;
|
|
58
|
+
readonly sourceRef: Readonly<Record<string, string>>;
|
|
59
|
+
}>;
|
|
60
|
+
readonly hasRetryContext?: boolean;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Shape the three rendered-* MountSource variants share at the wire
|
|
65
|
+
* level. Promoted to the SDK so the resolver-shared helper
|
|
66
|
+
* `renderParamsFromSource` can build a normalized `RenderAgentRunContextParams`
|
|
67
|
+
* without each resolver re-implementing the same field map (and
|
|
68
|
+
* silently diverging again — the divergence was the original cache
|
|
69
|
+
* bug).
|
|
70
|
+
*/
|
|
71
|
+
export interface RenderedAgentRunContextSourceShape {
|
|
72
|
+
readonly orgId: string;
|
|
73
|
+
readonly projectId: string;
|
|
74
|
+
readonly agentSlug: string;
|
|
75
|
+
readonly role: string;
|
|
76
|
+
readonly sessionId?: string;
|
|
77
|
+
readonly runId?: string;
|
|
78
|
+
readonly jobRunId?: string;
|
|
79
|
+
readonly deliverableSpecRef?: string;
|
|
80
|
+
readonly workflowInputs?: Readonly<Record<string, unknown>>;
|
|
81
|
+
readonly mounts?: ReadonlyArray<{
|
|
82
|
+
readonly mount: string;
|
|
83
|
+
readonly mode: 'read-only' | 'read-write';
|
|
84
|
+
}>;
|
|
85
|
+
readonly inputArtifacts?: ReadonlyArray<{
|
|
86
|
+
readonly path: string;
|
|
87
|
+
readonly contentType?: string;
|
|
88
|
+
readonly sourceArtifactId: string;
|
|
89
|
+
readonly sourceVersion: number;
|
|
90
|
+
}>;
|
|
91
|
+
readonly workingFiles?: ReadonlyArray<{
|
|
92
|
+
readonly slug: string;
|
|
93
|
+
readonly path: string;
|
|
94
|
+
readonly format: 'markdown' | 'html' | 'json' | 'yaml' | 'text';
|
|
95
|
+
readonly syncDirection: 'down-only' | 'up-only' | 'bidirectional';
|
|
96
|
+
readonly sourceKind: string;
|
|
97
|
+
readonly sourceRef: Readonly<Record<string, string>>;
|
|
98
|
+
}>;
|
|
99
|
+
readonly hasRetryContext?: boolean;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Single source of truth for `MountSource → RenderAgentRunContextParams`.
|
|
104
|
+
* Every rendered-* resolver MUST go through this helper so the cache
|
|
105
|
+
* key is computed from the same shape — diverging field sets across
|
|
106
|
+
* resolvers (the historical bug) hash to different keys and defeat
|
|
107
|
+
* coalescing.
|
|
108
|
+
*/
|
|
109
|
+
export function renderParamsFromSource(
|
|
110
|
+
source: RenderedAgentRunContextSourceShape,
|
|
111
|
+
): RenderAgentRunContextParams {
|
|
112
|
+
return {
|
|
113
|
+
agentSlug: source.agentSlug,
|
|
114
|
+
projectId: source.projectId,
|
|
115
|
+
role: source.role,
|
|
116
|
+
...(source.deliverableSpecRef === undefined
|
|
117
|
+
? {}
|
|
118
|
+
: { deliverableSpecRef: source.deliverableSpecRef }),
|
|
119
|
+
...(source.runId === undefined ? {} : { workflowRunId: source.runId }),
|
|
120
|
+
...(source.jobRunId === undefined ? {} : { jobRunId: source.jobRunId }),
|
|
121
|
+
...(source.sessionId === undefined ? {} : { sessionId: source.sessionId }),
|
|
122
|
+
...(source.workflowInputs === undefined
|
|
123
|
+
? {}
|
|
124
|
+
: { workflowInputs: source.workflowInputs }),
|
|
125
|
+
...(source.mounts === undefined ? {} : { mounts: source.mounts }),
|
|
126
|
+
...(source.inputArtifacts === undefined
|
|
127
|
+
? {}
|
|
128
|
+
: { inputArtifacts: source.inputArtifacts }),
|
|
129
|
+
...(source.workingFiles === undefined
|
|
130
|
+
? {}
|
|
131
|
+
: { workingFiles: source.workingFiles }),
|
|
132
|
+
...(source.hasRetryContext === undefined
|
|
133
|
+
? {}
|
|
134
|
+
: { hasRetryContext: source.hasRetryContext }),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export class RenderedAgentRunContextCache {
|
|
139
|
+
private readonly entries = new Map<string, CacheEntry>();
|
|
140
|
+
|
|
141
|
+
constructor(private readonly client: LlmRegistryClient) {}
|
|
142
|
+
|
|
143
|
+
async render(
|
|
144
|
+
params: RenderAgentRunContextParams,
|
|
145
|
+
headers: AuthHeaders,
|
|
146
|
+
): Promise<AgentRunContextRender> {
|
|
147
|
+
const key = this.cacheKey(params, headers);
|
|
148
|
+
const now = Date.now();
|
|
149
|
+
const existing = this.entries.get(key);
|
|
150
|
+
if (existing && now - existing.storedAt < CACHE_TTL_MS) {
|
|
151
|
+
return existing.value;
|
|
152
|
+
}
|
|
153
|
+
const value = this.client.renderAgentRunContext(params, headers);
|
|
154
|
+
this.entries.set(key, { storedAt: now, value });
|
|
155
|
+
// Clean up stale entries opportunistically — bounded scan.
|
|
156
|
+
if (this.entries.size > 64) {
|
|
157
|
+
for (const [k, e] of this.entries) {
|
|
158
|
+
if (now - e.storedAt >= CACHE_TTL_MS) {
|
|
159
|
+
this.entries.delete(k);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
return await value;
|
|
165
|
+
} catch (err) {
|
|
166
|
+
// Drop failed renders so the next call retries upstream.
|
|
167
|
+
this.entries.delete(key);
|
|
168
|
+
throw err;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private cacheKey(
|
|
173
|
+
params: RenderAgentRunContextParams,
|
|
174
|
+
headers: AuthHeaders,
|
|
175
|
+
): string {
|
|
176
|
+
// Defense-in-depth: hash a stable principal fingerprint into the key
|
|
177
|
+
// so two callers in the same org with different identity-side
|
|
178
|
+
// claims cannot share a cached promise. Today the upstream render is
|
|
179
|
+
// project/role-deterministic and orgId+param fields uniquely
|
|
180
|
+
// identify the render — but the moment the upstream adds per-actor
|
|
181
|
+
// capability filtering (KB scoping, role-based mount narrowing,
|
|
182
|
+
// …) a key without an actor binding becomes a cross-actor leak.
|
|
183
|
+
// We hash the bearer token (never store / log it raw) to fold in the
|
|
184
|
+
// full claim set without coupling this kernel package to JWT parsing.
|
|
185
|
+
const principalFingerprint = headers.Authorization
|
|
186
|
+
? createHash('sha256').update(headers.Authorization).digest('hex')
|
|
187
|
+
: '<anon>';
|
|
188
|
+
const canonical = JSON.stringify({
|
|
189
|
+
params: stableSort(params as unknown as Record<string, unknown>),
|
|
190
|
+
orgId: headers['X-Org-Id'] ?? null,
|
|
191
|
+
principal: principalFingerprint,
|
|
192
|
+
});
|
|
193
|
+
return createHash('sha256').update(canonical).digest('hex');
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function stableSort(value: unknown): unknown {
|
|
198
|
+
if (value === null || typeof value !== 'object') {return value;}
|
|
199
|
+
if (Array.isArray(value)) {return value.map(stableSort);}
|
|
200
|
+
const obj = value as Record<string, unknown>;
|
|
201
|
+
const sorted: Record<string, unknown> = {};
|
|
202
|
+
for (const key of Object.keys(obj).sort()) {
|
|
203
|
+
sorted[key] = stableSort(obj[key]);
|
|
204
|
+
}
|
|
205
|
+
return sorted;
|
|
206
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ResolveContext } from '../types';
|
|
2
|
+
import { MountActorForbiddenError } from '../../errors';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Required header keys that every resolver MUST forward to its upstream
|
|
6
|
+
* Orval client. Workspace-proxy builds these from the validated actor JWT
|
|
7
|
+
* before invoking the resolver.
|
|
8
|
+
*
|
|
9
|
+
* Defense-in-depth: even though the proxy already populated them, a
|
|
10
|
+
* resolver bug that strips/overwrites any of these is a tenancy bug, so
|
|
11
|
+
* the assertion is a first-class guard rather than an `if`-skip.
|
|
12
|
+
*/
|
|
13
|
+
export const REQUIRED_AUTH_HEADERS = ['Authorization', 'X-Org-Id', 'X-Project-Id'] as const;
|
|
14
|
+
|
|
15
|
+
export type AuthHeaders = Readonly<Record<string, string>>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Asserts the resolver's `ResolveContext` carries every required header
|
|
19
|
+
* with non-empty value. Throws fail-fast (mapped to 403 by the proxy)
|
|
20
|
+
* when any is missing.
|
|
21
|
+
*/
|
|
22
|
+
export function assertAuthHeaders(ctx: ResolveContext): AuthHeaders {
|
|
23
|
+
if (!ctx.orgId || !ctx.projectId) {
|
|
24
|
+
throw new MountActorForbiddenError(
|
|
25
|
+
'resolver invoked without orgId/projectId — refusing upstream call',
|
|
26
|
+
{ orgId: ctx.orgId, projectId: ctx.projectId },
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
for (const key of REQUIRED_AUTH_HEADERS) {
|
|
30
|
+
const value = ctx.authHeaders[key];
|
|
31
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
32
|
+
throw new MountActorForbiddenError(
|
|
33
|
+
`resolver invoked with missing or empty '${key}' header — refusing upstream call`,
|
|
34
|
+
{ missingHeader: key },
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return ctx.authHeaders;
|
|
39
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Transform, TransformCallback } from 'node:stream';
|
|
2
|
+
import { MountSourcePayloadTooLargeError } from '../../errors';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* `Transform` stream that aborts mid-stream once the cumulative byte
|
|
6
|
+
* count exceeds `maxBytes`. The error is a `MountSourcePayloadTooLarge
|
|
7
|
+
* Error`; the writer phase catches it and rolls back staging.
|
|
8
|
+
*
|
|
9
|
+
* Use this in the streaming chain — never accumulate bytes in a Buffer
|
|
10
|
+
* "just to check the size." That would defeat the streaming guarantee.
|
|
11
|
+
*/
|
|
12
|
+
export function createSizeCapTransform(
|
|
13
|
+
maxBytes: number,
|
|
14
|
+
identity: string,
|
|
15
|
+
): Transform {
|
|
16
|
+
if (!Number.isFinite(maxBytes) || maxBytes <= 0) {
|
|
17
|
+
throw new RangeError(
|
|
18
|
+
`createSizeCapTransform: maxBytes must be a positive finite number (got ${maxBytes})`,
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
let observed = 0;
|
|
22
|
+
return new Transform({
|
|
23
|
+
transform(chunk: Buffer | string, _enc, cb: TransformCallback) {
|
|
24
|
+
const buf = typeof chunk === 'string' ? Buffer.from(chunk) : chunk;
|
|
25
|
+
observed += buf.length;
|
|
26
|
+
if (observed > maxBytes) {
|
|
27
|
+
cb(
|
|
28
|
+
new MountSourcePayloadTooLargeError(
|
|
29
|
+
`mount '${identity}' exceeded ${maxBytes} byte cap`,
|
|
30
|
+
{ identity, maxBytes, observedAtAbort: observed },
|
|
31
|
+
),
|
|
32
|
+
);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
cb(null, buf);
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Readable } from 'node:stream';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Convert a Web `ReadableStream<Uint8Array>` (the body of a `Response`
|
|
5
|
+
* returned by the SDK's narrow `*BlobFetcher` interface) into a Node
|
|
6
|
+
* `Readable`. The conversion is allocation-free per chunk — Node's
|
|
7
|
+
* built-in adapter is used directly.
|
|
8
|
+
*
|
|
9
|
+
* Throws if the body is `null` (the upstream returned an empty body
|
|
10
|
+
* where one was expected).
|
|
11
|
+
*/
|
|
12
|
+
export function webBodyToNodeReadable(
|
|
13
|
+
body: ReadableStream<Uint8Array> | null,
|
|
14
|
+
context: string,
|
|
15
|
+
): Readable {
|
|
16
|
+
if (body === null) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
`webBodyToNodeReadable(${context}): upstream response had no body`,
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
return Readable.fromWeb(body as unknown as import('node:stream/web').ReadableStream);
|
|
22
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { WorkspaceMountPlan } from '@xemahq/kernel-contracts/agent-workspace';
|
|
2
|
+
import type { ResolveContext } from './mount-resolver';
|
|
3
|
+
|
|
4
|
+
export interface RenderedWorkspaceMount {
|
|
5
|
+
readonly mount: string;
|
|
6
|
+
readonly bytesWritten: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface RenderedWorkspace {
|
|
10
|
+
readonly mounts: readonly RenderedWorkspaceMount[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Composes a workspace tree on disk by dispatching each mount-plan entry
|
|
15
|
+
* to the matching `MountResolver` and writing the result through
|
|
16
|
+
* `workspace-proxy`.
|
|
17
|
+
*
|
|
18
|
+
* Concrete implementation lives in this package; orchestrator-specific
|
|
19
|
+
* post-processing (e.g. `.opencode/` generation) is added by the
|
|
20
|
+
* orchestrator adapter (`@xemahq/agent-workspace-opencode`,
|
|
21
|
+
* `@xemahq/agent-workspace-claude-code`, …).
|
|
22
|
+
*/
|
|
23
|
+
export interface WorkspaceRenderer {
|
|
24
|
+
render(plan: WorkspaceMountPlan, ctx: ResolveContext): Promise<RenderedWorkspace>;
|
|
25
|
+
}
|
package/src/api/index.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './lib/api-manifest';
|
|
2
|
+
export * from './lib/code-tool-context';
|
|
3
|
+
export * from './lib/code-tool-descriptor';
|
|
4
|
+
export * from './lib/code-tool.decorator';
|
|
5
|
+
export * from './lib/mutation-context';
|
|
6
|
+
export * from './lib/pagination';
|
|
7
|
+
export * from './lib/biome-db';
|
|
8
|
+
export * from './lib/provider-kind-mirror';
|
|
9
|
+
export * from './lib/request-context';
|
|
10
|
+
export * from './lib/route-registry-entry';
|