@exaudeus/workrail 0.8.6 → 0.9.0
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/README.md +157 -403
- package/dist/application/services/enhanced-loop-validator.d.ts +2 -2
- package/dist/application/services/enhanced-loop-validator.js +12 -2
- package/dist/application/services/validation-engine.d.ts +8 -29
- package/dist/application/services/validation-engine.js +38 -21
- package/dist/application/services/workflow-compiler.d.ts +18 -0
- package/dist/application/services/workflow-compiler.js +79 -0
- package/dist/application/services/workflow-interpreter.d.ts +31 -0
- package/dist/application/services/workflow-interpreter.js +280 -0
- package/dist/application/services/workflow-service.d.ts +34 -32
- package/dist/application/services/workflow-service.js +93 -425
- package/dist/application/use-cases/get-next-step.d.ts +6 -10
- package/dist/application/use-cases/get-next-step.js +2 -6
- package/dist/application/use-cases/get-workflow.d.ts +8 -6
- package/dist/application/use-cases/get-workflow.js +42 -33
- package/dist/application/use-cases/list-workflows.d.ts +3 -3
- package/dist/application/use-cases/validate-step-output.d.ts +4 -4
- package/dist/application/use-cases/validate-workflow-file.d.ts +46 -0
- package/dist/application/use-cases/validate-workflow-file.js +57 -0
- package/dist/cli/commands/cleanup.d.ts +8 -0
- package/dist/cli/commands/cleanup.js +20 -0
- package/dist/cli/commands/index.d.ts +7 -0
- package/dist/cli/commands/index.js +21 -0
- package/dist/cli/commands/init.d.ts +11 -0
- package/dist/cli/commands/init.js +49 -0
- package/dist/cli/commands/list.d.ts +9 -0
- package/dist/cli/commands/list.js +34 -0
- package/dist/cli/commands/migrate.d.ts +78 -0
- package/dist/cli/commands/migrate.js +248 -0
- package/dist/cli/commands/sources.d.ts +21 -0
- package/dist/cli/commands/sources.js +87 -0
- package/dist/cli/commands/start.d.ts +8 -0
- package/dist/cli/commands/start.js +16 -0
- package/dist/cli/commands/validate.d.ts +6 -0
- package/dist/cli/commands/validate.js +55 -0
- package/dist/cli/interpret-result.d.ts +4 -0
- package/dist/cli/interpret-result.js +24 -0
- package/dist/cli/output-formatter.d.ts +10 -0
- package/dist/cli/output-formatter.js +97 -0
- package/dist/cli/types/cli-result.d.ts +23 -0
- package/dist/cli/types/cli-result.js +30 -0
- package/dist/cli/types/exit-code.d.ts +13 -0
- package/dist/cli/types/exit-code.js +23 -0
- package/dist/cli/types/index.d.ts +4 -0
- package/dist/cli/types/index.js +11 -0
- package/dist/cli.js +84 -278
- package/dist/config/app-config.d.ts +40 -0
- package/dist/config/app-config.js +58 -0
- package/dist/config/feature-flags.d.ts +10 -2
- package/dist/config/feature-flags.js +74 -12
- package/dist/core/error-handler.d.ts +18 -27
- package/dist/core/error-handler.js +24 -218
- package/dist/di/container.d.ts +12 -0
- package/dist/di/container.js +244 -0
- package/dist/di/tokens.d.ts +40 -0
- package/dist/di/tokens.js +42 -0
- package/dist/domain/execution/error.d.ts +32 -0
- package/dist/domain/execution/error.js +24 -0
- package/dist/domain/execution/event.d.ts +7 -0
- package/dist/domain/execution/event.js +11 -0
- package/dist/domain/execution/ids.d.ts +9 -0
- package/dist/domain/execution/ids.js +9 -0
- package/dist/domain/execution/result.d.ts +3 -0
- package/dist/domain/execution/result.js +10 -0
- package/dist/domain/execution/state.d.ts +57 -0
- package/dist/domain/execution/state.js +28 -0
- package/dist/errors/app-error.d.ts +23 -0
- package/dist/errors/factories.d.ts +6 -0
- package/dist/errors/factories.js +21 -0
- package/dist/errors/formatter.d.ts +2 -0
- package/dist/errors/formatter.js +32 -0
- package/dist/errors/index.d.ts +3 -0
- package/dist/errors/index.js +7 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.js +10 -25
- package/dist/infrastructure/index.d.ts +0 -1
- package/dist/infrastructure/index.js +0 -1
- package/dist/infrastructure/session/DashboardHeartbeat.d.ts +8 -0
- package/dist/infrastructure/session/DashboardHeartbeat.js +39 -0
- package/dist/infrastructure/session/DashboardLockRelease.d.ts +2 -0
- package/dist/infrastructure/session/DashboardLockRelease.js +29 -0
- package/dist/infrastructure/session/HttpServer.d.ts +25 -6
- package/dist/infrastructure/session/HttpServer.js +245 -90
- package/dist/infrastructure/session/SessionDataNormalizer.js +12 -2
- package/dist/infrastructure/session/SessionDataValidator.js +12 -2
- package/dist/infrastructure/session/SessionManager.d.ts +5 -3
- package/dist/infrastructure/session/SessionManager.js +52 -6
- package/dist/infrastructure/storage/caching-workflow-storage.d.ts +30 -6
- package/dist/infrastructure/storage/caching-workflow-storage.js +105 -23
- package/dist/infrastructure/storage/enhanced-multi-source-workflow-storage.d.ts +13 -9
- package/dist/infrastructure/storage/enhanced-multi-source-workflow-storage.js +45 -39
- package/dist/infrastructure/storage/file-workflow-storage.d.ts +10 -8
- package/dist/infrastructure/storage/file-workflow-storage.js +48 -56
- package/dist/infrastructure/storage/git-workflow-storage.d.ts +7 -22
- package/dist/infrastructure/storage/git-workflow-storage.js +48 -103
- package/dist/infrastructure/storage/in-memory-storage.d.ts +10 -6
- package/dist/infrastructure/storage/in-memory-storage.js +18 -13
- package/dist/infrastructure/storage/plugin-workflow-storage.d.ts +6 -18
- package/dist/infrastructure/storage/plugin-workflow-storage.js +29 -51
- package/dist/infrastructure/storage/remote-workflow-storage.d.ts +8 -17
- package/dist/infrastructure/storage/remote-workflow-storage.js +33 -156
- package/dist/infrastructure/storage/schema-validating-workflow-storage.d.ts +21 -13
- package/dist/infrastructure/storage/schema-validating-workflow-storage.js +86 -24
- package/dist/infrastructure/storage/storage.d.ts +7 -5
- package/dist/infrastructure/storage/storage.js +7 -6
- package/dist/manifest.json +1093 -0
- package/dist/mcp/error-mapper.d.ts +9 -0
- package/dist/mcp/error-mapper.js +66 -0
- package/dist/mcp/handlers/session.d.ts +34 -0
- package/dist/mcp/handlers/session.js +135 -0
- package/dist/mcp/handlers/v2-workflow.d.ts +4 -0
- package/dist/mcp/handlers/v2-workflow.js +112 -0
- package/dist/mcp/handlers/workflow.d.ts +45 -0
- package/dist/mcp/handlers/workflow.js +167 -0
- package/dist/mcp/index.d.ts +16 -0
- package/dist/mcp/index.js +51 -0
- package/dist/mcp/output-schemas.d.ts +317 -0
- package/dist/mcp/output-schemas.js +91 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.js +258 -0
- package/dist/mcp/tool-description-provider.d.ts +16 -0
- package/dist/mcp/tool-description-provider.js +43 -0
- package/dist/mcp/tool-descriptions.d.ts +2 -0
- package/dist/mcp/tool-descriptions.js +109 -0
- package/dist/mcp/tool-factory.d.ts +23 -0
- package/dist/mcp/tool-factory.js +14 -0
- package/dist/mcp/tools.d.ts +156 -0
- package/dist/mcp/tools.js +196 -0
- package/dist/mcp/types/tool-description-types.d.ts +8 -0
- package/dist/mcp/types/tool-description-types.js +24 -0
- package/dist/mcp/types.d.ts +25 -0
- package/dist/mcp/types.js +15 -0
- package/dist/mcp/v2/tool-registry.d.ts +11 -0
- package/dist/mcp/v2/tool-registry.js +26 -0
- package/dist/mcp/v2/tools.d.ts +20 -0
- package/dist/mcp/v2/tools.js +17 -0
- package/dist/mcp/validation/bounded-json.d.ts +3 -0
- package/dist/mcp/validation/bounded-json.js +22 -0
- package/dist/mcp/validation/workflow-next-prevalidate.d.ts +9 -0
- package/dist/mcp/validation/workflow-next-prevalidate.js +83 -0
- package/dist/mcp/zod-to-json-schema.d.ts +17 -0
- package/dist/mcp/zod-to-json-schema.js +134 -0
- package/dist/mcp-server.d.ts +1 -1
- package/dist/mcp-server.js +6 -424
- package/dist/runtime/adapters/in-memory-shutdown-events.d.ts +6 -0
- package/dist/runtime/adapters/in-memory-shutdown-events.js +20 -0
- package/dist/runtime/adapters/node-process-signals.d.ts +4 -0
- package/dist/runtime/adapters/node-process-signals.js +11 -0
- package/dist/runtime/adapters/node-process-terminator.d.ts +4 -0
- package/dist/runtime/adapters/node-process-terminator.js +17 -0
- package/dist/runtime/adapters/noop-process-signals.d.ts +4 -0
- package/dist/runtime/adapters/noop-process-signals.js +8 -0
- package/dist/runtime/adapters/throwing-process-terminator.d.ts +4 -0
- package/dist/runtime/adapters/throwing-process-terminator.js +9 -0
- package/dist/runtime/assert-never.d.ts +1 -0
- package/dist/runtime/assert-never.js +6 -0
- package/dist/runtime/brand.d.ts +5 -0
- package/dist/runtime/ports/process-signals.d.ts +4 -0
- package/dist/runtime/ports/process-signals.js +2 -0
- package/dist/runtime/ports/process-terminator.d.ts +8 -0
- package/dist/runtime/ports/process-terminator.js +2 -0
- package/dist/runtime/ports/shutdown-events.d.ts +11 -0
- package/dist/runtime/ports/shutdown-events.js +2 -0
- package/dist/runtime/process-lifecycle-policy.d.ts +5 -0
- package/dist/runtime/process-lifecycle-policy.js +2 -0
- package/dist/runtime/result.d.ts +17 -0
- package/dist/runtime/result.js +31 -0
- package/dist/runtime/runtime-mode.d.ts +9 -0
- package/dist/runtime/runtime-mode.js +2 -0
- package/dist/types/storage.d.ts +16 -5
- package/dist/types/storage.js +8 -0
- package/dist/types/validation.d.ts +27 -0
- package/dist/types/validation.js +10 -0
- package/dist/types/workflow-definition.d.ts +63 -0
- package/dist/types/workflow-definition.js +33 -0
- package/dist/types/workflow-source.d.ts +51 -0
- package/dist/types/workflow-source.js +128 -0
- package/dist/types/workflow.d.ts +28 -0
- package/dist/types/workflow.js +96 -0
- package/dist/utils/workflow-init.d.ts +1 -0
- package/dist/utils/workflow-init.js +38 -0
- package/dist/v2/durable-core/canonical/hashing.d.ts +11 -0
- package/dist/v2/durable-core/canonical/hashing.js +13 -0
- package/dist/v2/durable-core/canonical/jcs.d.ts +11 -0
- package/dist/v2/durable-core/canonical/jcs.js +65 -0
- package/dist/v2/durable-core/canonical/json-types.d.ts +6 -0
- package/dist/v2/durable-core/canonical/json-types.js +2 -0
- package/dist/v2/durable-core/canonical/json-zod.d.ts +2 -0
- package/dist/v2/durable-core/canonical/json-zod.js +7 -0
- package/dist/v2/durable-core/canonical/jsonl.d.ts +4 -0
- package/dist/v2/durable-core/canonical/jsonl.js +13 -0
- package/dist/v2/durable-core/ids/index.d.ts +23 -0
- package/dist/v2/durable-core/ids/index.js +46 -0
- package/dist/v2/durable-core/schemas/compiled-workflow/index.d.ts +47 -0
- package/dist/v2/durable-core/schemas/compiled-workflow/index.js +17 -0
- package/dist/v2/durable-core/schemas/session/events.d.ts +1812 -0
- package/dist/v2/durable-core/schemas/session/events.js +328 -0
- package/dist/v2/durable-core/schemas/session/index.d.ts +2 -0
- package/dist/v2/durable-core/schemas/session/index.js +8 -0
- package/dist/v2/durable-core/schemas/session/manifest.d.ts +57 -0
- package/dist/v2/durable-core/schemas/session/manifest.js +30 -0
- package/dist/v2/infra/local/crypto/index.d.ts +5 -0
- package/dist/v2/infra/local/crypto/index.js +12 -0
- package/dist/v2/infra/local/data-dir/index.d.ts +13 -0
- package/dist/v2/infra/local/data-dir/index.js +69 -0
- package/dist/v2/infra/local/fs/index.d.ts +26 -0
- package/dist/v2/infra/local/fs/index.js +156 -0
- package/dist/v2/infra/local/pinned-workflow-store/index.d.ts +11 -0
- package/dist/v2/infra/local/pinned-workflow-store/index.js +85 -0
- package/dist/v2/infra/local/session-lock/index.d.ts +12 -0
- package/dist/v2/infra/local/session-lock/index.js +44 -0
- package/dist/v2/infra/local/session-store/index.d.ts +22 -0
- package/dist/v2/infra/local/session-store/index.js +358 -0
- package/dist/v2/infra/local/sha256/index.d.ts +5 -0
- package/dist/v2/infra/local/sha256/index.js +12 -0
- package/dist/v2/ports/data-dir.port.d.ts +9 -0
- package/dist/v2/ports/data-dir.port.js +2 -0
- package/dist/v2/ports/fs.port.d.ts +41 -0
- package/dist/v2/ports/fs.port.js +2 -0
- package/dist/v2/ports/pinned-workflow-store.port.d.ts +11 -0
- package/dist/v2/ports/pinned-workflow-store.port.js +2 -0
- package/dist/v2/ports/session-event-log-store.port.d.ts +37 -0
- package/dist/v2/ports/session-event-log-store.port.js +2 -0
- package/dist/v2/ports/session-lock.port.d.ts +23 -0
- package/dist/v2/ports/session-lock.port.js +2 -0
- package/dist/v2/ports/sha256.port.d.ts +4 -0
- package/dist/v2/ports/sha256.port.js +2 -0
- package/dist/v2/projections/advance-outcomes.d.ts +23 -0
- package/dist/v2/projections/advance-outcomes.js +23 -0
- package/dist/v2/projections/capabilities.d.ts +27 -0
- package/dist/v2/projections/capabilities.js +33 -0
- package/dist/v2/projections/gaps.d.ts +29 -0
- package/dist/v2/projections/gaps.js +49 -0
- package/dist/v2/projections/node-outputs.d.ts +34 -0
- package/dist/v2/projections/node-outputs.js +73 -0
- package/dist/v2/projections/preferences.d.ts +28 -0
- package/dist/v2/projections/preferences.js +50 -0
- package/dist/v2/projections/run-dag.d.ts +42 -0
- package/dist/v2/projections/run-dag.js +186 -0
- package/dist/v2/projections/run-status-signals.d.ts +26 -0
- package/dist/v2/projections/run-status-signals.js +49 -0
- package/dist/v2/projections/session-health.d.ts +18 -0
- package/dist/v2/projections/session-health.js +15 -0
- package/dist/v2/read-only/v1-to-v2-shim.d.ts +3 -0
- package/dist/v2/read-only/v1-to-v2-shim.js +38 -0
- package/package.json +35 -10
- package/spec/mcp-api-v1.0.md +5 -5
- package/web/assets/services/data-normalizer.js +17 -2
- package/web/assets/services/pattern-recognizer.js +3 -1
- package/web/assets/services/session-data.js +13 -8
- package/web/assets/utils/formatters.js +34 -23
- package/workflows/CHANGELOG-bug-investigation.md +4 -4
- package/workflows/coding-task-workflow-agentic.json +262 -0
- package/workflows/design-thinking-workflow-autonomous.agentic.json +215 -0
- package/workflows/design-thinking-workflow.json +198 -0
- package/workflows/mr-review-workflow.agentic.json +538 -0
- package/workflows/routines/context-gathering.json +0 -4
- package/dist/application/app.d.ts +0 -29
- package/dist/application/app.d.ts.map +0 -1
- package/dist/application/app.js +0 -114
- package/dist/application/app.js.map +0 -1
- package/dist/application/decorators/simple-output-decorator.d.ts +0 -8
- package/dist/application/decorators/simple-output-decorator.js +0 -89
- package/dist/application/services/classification-engine.d.ts +0 -33
- package/dist/application/services/classification-engine.js +0 -258
- package/dist/application/services/compression-service.d.ts +0 -20
- package/dist/application/services/compression-service.js +0 -312
- package/dist/application/services/context-management-service.d.ts +0 -38
- package/dist/application/services/context-management-service.js +0 -301
- package/dist/application/services/context-optimizer.d.ts +0 -11
- package/dist/application/services/context-optimizer.js +0 -62
- package/dist/application/services/context-persistence-service.d.ts +0 -45
- package/dist/application/services/context-persistence-service.js +0 -273
- package/dist/application/services/documentation-service.d.ts +0 -20
- package/dist/application/services/documentation-service.js +0 -155
- package/dist/application/services/enhanced-error-service.d.ts.map +0 -1
- package/dist/application/services/enhanced-error-service.js.map +0 -1
- package/dist/application/services/loop-context-optimizer.d.ts +0 -8
- package/dist/application/services/loop-context-optimizer.js +0 -114
- package/dist/application/services/loop-execution-context.d.ts +0 -23
- package/dist/application/services/loop-execution-context.js +0 -188
- package/dist/application/services/loop-step-resolver.d.ts +0 -11
- package/dist/application/services/loop-step-resolver.js +0 -70
- package/dist/application/services/validation-engine.d.ts.map +0 -1
- package/dist/application/services/validation-engine.js.map +0 -1
- package/dist/application/services/workflow-service.d.ts.map +0 -1
- package/dist/application/services/workflow-service.js.map +0 -1
- package/dist/application/use-cases/get-next-step.d.ts.map +0 -1
- package/dist/application/use-cases/get-next-step.js.map +0 -1
- package/dist/application/use-cases/get-workflow-docs.d.ts +0 -4
- package/dist/application/use-cases/get-workflow-docs.js +0 -12
- package/dist/application/use-cases/get-workflow.d.ts.map +0 -1
- package/dist/application/use-cases/get-workflow.js.map +0 -1
- package/dist/application/use-cases/get-workrail-help.d.ts +0 -4
- package/dist/application/use-cases/get-workrail-help.js +0 -12
- package/dist/application/use-cases/list-workflows.d.ts.map +0 -1
- package/dist/application/use-cases/list-workflows.js.map +0 -1
- package/dist/application/use-cases/validate-step-output.d.ts.map +0 -1
- package/dist/application/use-cases/validate-step-output.js.map +0 -1
- package/dist/application/use-cases/validate-workflow-json.d.ts.map +0 -1
- package/dist/application/use-cases/validate-workflow-json.js.map +0 -1
- package/dist/application/validation.d.ts.map +0 -1
- package/dist/application/validation.js.map +0 -1
- package/dist/cli/migrate-workflow.d.ts +0 -22
- package/dist/cli/migrate-workflow.js +0 -196
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/container.d.ts +0 -15
- package/dist/container.d.ts.map +0 -1
- package/dist/container.js +0 -25
- package/dist/container.js.map +0 -1
- package/dist/core/error-handler.d.ts.map +0 -1
- package/dist/core/error-handler.js.map +0 -1
- package/dist/domain/index.d.ts +0 -2
- package/dist/domain/index.d.ts.map +0 -1
- package/dist/domain/index.js +0 -18
- package/dist/domain/index.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/infrastructure/index.d.ts.map +0 -1
- package/dist/infrastructure/index.js.map +0 -1
- package/dist/infrastructure/rpc/handler.d.ts +0 -17
- package/dist/infrastructure/rpc/handler.d.ts.map +0 -1
- package/dist/infrastructure/rpc/handler.js +0 -78
- package/dist/infrastructure/rpc/handler.js.map +0 -1
- package/dist/infrastructure/rpc/index.d.ts +0 -1
- package/dist/infrastructure/rpc/index.d.ts.map +0 -1
- package/dist/infrastructure/rpc/index.js +0 -17
- package/dist/infrastructure/rpc/index.js.map +0 -1
- package/dist/infrastructure/rpc/server.d.ts +0 -3
- package/dist/infrastructure/rpc/server.d.ts.map +0 -1
- package/dist/infrastructure/rpc/server.js +0 -37
- package/dist/infrastructure/rpc/server.js.map +0 -1
- package/dist/infrastructure/storage/caching-workflow-storage.d.ts.map +0 -1
- package/dist/infrastructure/storage/caching-workflow-storage.js.map +0 -1
- package/dist/infrastructure/storage/context-storage.d.ts +0 -150
- package/dist/infrastructure/storage/context-storage.js +0 -40
- package/dist/infrastructure/storage/file-workflow-storage.d.ts.map +0 -1
- package/dist/infrastructure/storage/file-workflow-storage.js.map +0 -1
- package/dist/infrastructure/storage/filesystem-blob-storage.d.ts +0 -27
- package/dist/infrastructure/storage/filesystem-blob-storage.js +0 -363
- package/dist/infrastructure/storage/git-workflow-storage.d.ts.map +0 -1
- package/dist/infrastructure/storage/git-workflow-storage.js.map +0 -1
- package/dist/infrastructure/storage/hybrid-context-storage.d.ts +0 -29
- package/dist/infrastructure/storage/hybrid-context-storage.js +0 -400
- package/dist/infrastructure/storage/in-memory-storage.d.ts.map +0 -1
- package/dist/infrastructure/storage/in-memory-storage.js.map +0 -1
- package/dist/infrastructure/storage/index.d.ts.map +0 -1
- package/dist/infrastructure/storage/index.js.map +0 -1
- package/dist/infrastructure/storage/migrations/001_initial_schema.sql +0 -38
- package/dist/infrastructure/storage/migrations/002_context_concurrency_enhancements.sql +0 -234
- package/dist/infrastructure/storage/migrations/003_classification_overrides.sql +0 -20
- package/dist/infrastructure/storage/multi-directory-workflow-storage.d.ts +0 -32
- package/dist/infrastructure/storage/multi-directory-workflow-storage.d.ts.map +0 -1
- package/dist/infrastructure/storage/multi-directory-workflow-storage.js +0 -184
- package/dist/infrastructure/storage/multi-directory-workflow-storage.js.map +0 -1
- package/dist/infrastructure/storage/plugin-workflow-storage.d.ts.map +0 -1
- package/dist/infrastructure/storage/plugin-workflow-storage.js.map +0 -1
- package/dist/infrastructure/storage/remote-workflow-storage.d.ts.map +0 -1
- package/dist/infrastructure/storage/remote-workflow-storage.js.map +0 -1
- package/dist/infrastructure/storage/schema-validating-workflow-storage.d.ts.map +0 -1
- package/dist/infrastructure/storage/schema-validating-workflow-storage.js.map +0 -1
- package/dist/infrastructure/storage/sqlite-metadata-storage.d.ts +0 -35
- package/dist/infrastructure/storage/sqlite-metadata-storage.js +0 -410
- package/dist/infrastructure/storage/sqlite-migrator.d.ts +0 -46
- package/dist/infrastructure/storage/sqlite-migrator.js +0 -293
- package/dist/infrastructure/storage/storage.d.ts.map +0 -1
- package/dist/infrastructure/storage/storage.js.map +0 -1
- package/dist/mcp-server.d.ts.map +0 -1
- package/dist/mcp-server.js.map +0 -1
- package/dist/tools/mcp_initialize.d.ts +0 -2
- package/dist/tools/mcp_initialize.d.ts.map +0 -1
- package/dist/tools/mcp_initialize.js +0 -45
- package/dist/tools/mcp_initialize.js.map +0 -1
- package/dist/tools/mcp_shutdown.d.ts +0 -2
- package/dist/tools/mcp_shutdown.d.ts.map +0 -1
- package/dist/tools/mcp_shutdown.js +0 -10
- package/dist/tools/mcp_shutdown.js.map +0 -1
- package/dist/tools/mcp_tools_list.d.ts +0 -2
- package/dist/tools/mcp_tools_list.d.ts.map +0 -1
- package/dist/tools/mcp_tools_list.js +0 -60
- package/dist/tools/mcp_tools_list.js.map +0 -1
- package/dist/tools/session-tools.d.ts +0 -5
- package/dist/tools/session-tools.js +0 -270
- package/dist/types/context-types.d.ts +0 -236
- package/dist/types/context-types.js +0 -10
- package/dist/types/documentation-types.d.ts +0 -37
- package/dist/types/loop-context-optimizer.d.ts +0 -7
- package/dist/types/mcp-types.d.ts +0 -273
- package/dist/types/mcp-types.d.ts.map +0 -1
- package/dist/types/mcp-types.js +0 -19
- package/dist/types/mcp-types.js.map +0 -1
- package/dist/types/server.d.ts.map +0 -1
- package/dist/types/server.js.map +0 -1
- package/dist/types/storage.d.ts.map +0 -1
- package/dist/types/storage.js.map +0 -1
- package/dist/types/workflow-types.d.ts +0 -336
- package/dist/types/workflow-types.d.ts.map +0 -1
- package/dist/types/workflow-types.js +0 -20
- package/dist/types/workflow-types.js.map +0 -1
- package/dist/utils/condition-evaluator.d.ts.map +0 -1
- package/dist/utils/condition-evaluator.js.map +0 -1
- package/dist/utils/config.d.ts +0 -149
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js +0 -251
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/storage-security.d.ts.map +0 -1
- package/dist/utils/storage-security.js.map +0 -1
- package/dist/validation/request-validator.d.ts +0 -8
- package/dist/validation/request-validator.d.ts.map +0 -1
- package/dist/validation/request-validator.js +0 -32
- package/dist/validation/request-validator.js.map +0 -1
- package/dist/validation/response-validator.d.ts +0 -8
- package/dist/validation/response-validator.d.ts.map +0 -1
- package/dist/validation/response-validator.js +0 -110
- package/dist/validation/response-validator.js.map +0 -1
- package/dist/validation/schemas.d.ts +0 -1
- package/dist/validation/schemas.d.ts.map +0 -1
- package/dist/validation/schemas.js +0 -53
- package/dist/validation/schemas.js.map +0 -1
- /package/dist/{types/documentation-types.js → errors/app-error.js} +0 -0
- /package/dist/{types/loop-context-optimizer.js → runtime/brand.js} +0 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LocalSessionEventLogStoreV2 = void 0;
|
|
4
|
+
const neverthrow_1 = require("neverthrow");
|
|
5
|
+
const jsonl_js_1 = require("../../../durable-core/canonical/jsonl.js");
|
|
6
|
+
const index_js_1 = require("../../../durable-core/schemas/session/index.js");
|
|
7
|
+
class StoreFailure extends Error {
|
|
8
|
+
constructor(storeError) {
|
|
9
|
+
super(storeError.message);
|
|
10
|
+
this.storeError = storeError;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
class LocalSessionEventLogStoreV2 {
|
|
14
|
+
constructor(dataDir, fs, sha256, lock) {
|
|
15
|
+
this.dataDir = dataDir;
|
|
16
|
+
this.fs = fs;
|
|
17
|
+
this.sha256 = sha256;
|
|
18
|
+
this.lock = lock;
|
|
19
|
+
}
|
|
20
|
+
append(sessionId, plan) {
|
|
21
|
+
return neverthrow_1.ResultAsync.fromPromise(this.appendImpl(sessionId, plan), (e) => {
|
|
22
|
+
if (e instanceof StoreFailure)
|
|
23
|
+
return e.storeError;
|
|
24
|
+
return { code: 'SESSION_STORE_IO_ERROR', message: e instanceof Error ? e.message : String(e) };
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
load(sessionId) {
|
|
28
|
+
return neverthrow_1.ResultAsync.fromPromise(this.loadImpl(sessionId), (e) => {
|
|
29
|
+
if (e instanceof StoreFailure)
|
|
30
|
+
return e.storeError;
|
|
31
|
+
return { code: 'SESSION_STORE_IO_ERROR', message: e instanceof Error ? e.message : String(e) };
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
async appendImpl(sessionId, plan) {
|
|
35
|
+
const lockHandle = await this.unwrap(this.lock.acquire(sessionId), mapLockError);
|
|
36
|
+
try {
|
|
37
|
+
const sessionDir = this.dataDir.sessionDir(sessionId);
|
|
38
|
+
const eventsDir = this.dataDir.sessionEventsDir(sessionId);
|
|
39
|
+
const manifestPath = this.dataDir.sessionManifestPath(sessionId);
|
|
40
|
+
await this.unwrap(this.fs.mkdirp(eventsDir), mapFsToStoreError);
|
|
41
|
+
const { manifest, events: existingEvents } = await this.loadTruthOrEmpty(sessionId);
|
|
42
|
+
validateManifestContiguityOrThrow(manifest);
|
|
43
|
+
const existingByDedupeKey = new Set(existingEvents.map((e) => e.dedupeKey));
|
|
44
|
+
const allExist = plan.events.every((e) => existingByDedupeKey.has(e.dedupeKey));
|
|
45
|
+
if (allExist) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const anyExist = plan.events.some((e) => existingByDedupeKey.has(e.dedupeKey));
|
|
49
|
+
if (anyExist && !allExist) {
|
|
50
|
+
throw new StoreFailure({
|
|
51
|
+
code: 'SESSION_STORE_INVARIANT_VIOLATION',
|
|
52
|
+
message: 'Partial dedupeKey collision detected (some events exist, some do not); this is an invariant violation',
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
const expectedFirstEventIndex = nextEventIndexFromManifest(manifest);
|
|
56
|
+
validateAppendPlanOrThrow(sessionId, plan, expectedFirstEventIndex);
|
|
57
|
+
const first = plan.events[0].eventIndex;
|
|
58
|
+
const last = plan.events[plan.events.length - 1].eventIndex;
|
|
59
|
+
const segmentRelPath = segmentRelPathFor(first, last);
|
|
60
|
+
const segmentPath = `${sessionDir}/${segmentRelPath}`;
|
|
61
|
+
const tmpPath = `${segmentPath}.tmp`;
|
|
62
|
+
const segmentBytes = concatJsonlRecords(plan.events);
|
|
63
|
+
const tmpHandle = await this.unwrap(this.fs.openWriteTruncate(tmpPath), mapFsToStoreError);
|
|
64
|
+
await this.unwrap(this.fs.writeAll(tmpHandle.fd, segmentBytes), mapFsToStoreError);
|
|
65
|
+
await this.unwrap(this.fs.fsyncFile(tmpHandle.fd), mapFsToStoreError);
|
|
66
|
+
await this.unwrap(this.fs.closeFile(tmpHandle.fd), mapFsToStoreError);
|
|
67
|
+
await this.unwrap(this.fs.rename(tmpPath, segmentPath), mapFsToStoreError);
|
|
68
|
+
await this.unwrap(this.fs.fsyncDir(eventsDir), mapFsToStoreError);
|
|
69
|
+
const digest = this.sha256.sha256(segmentBytes);
|
|
70
|
+
const segClosed = {
|
|
71
|
+
v: 1,
|
|
72
|
+
manifestIndex: nextManifestIndex(manifest),
|
|
73
|
+
sessionId,
|
|
74
|
+
kind: 'segment_closed',
|
|
75
|
+
firstEventIndex: first,
|
|
76
|
+
lastEventIndex: last,
|
|
77
|
+
segmentRelPath,
|
|
78
|
+
sha256: digest,
|
|
79
|
+
bytes: segmentBytes.length,
|
|
80
|
+
};
|
|
81
|
+
await this.appendManifestRecords(manifestPath, [segClosed]);
|
|
82
|
+
const pins = sortedPins(plan.snapshotPins);
|
|
83
|
+
if (pins.length > 0) {
|
|
84
|
+
const startIndex = segClosed.manifestIndex + 1;
|
|
85
|
+
const records = pins.map((p, i) => ({
|
|
86
|
+
v: 1,
|
|
87
|
+
manifestIndex: startIndex + i,
|
|
88
|
+
sessionId,
|
|
89
|
+
kind: 'snapshot_pinned',
|
|
90
|
+
eventIndex: p.eventIndex,
|
|
91
|
+
snapshotRef: p.snapshotRef,
|
|
92
|
+
createdByEventId: p.createdByEventId,
|
|
93
|
+
}));
|
|
94
|
+
await this.appendManifestRecords(manifestPath, records);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
await this.lock.release(lockHandle).match(() => undefined, () => undefined);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async loadImpl(sessionId) {
|
|
102
|
+
const lockHandle = await this.unwrap(this.lock.acquire(sessionId), mapLockError);
|
|
103
|
+
try {
|
|
104
|
+
const sessionDir = this.dataDir.sessionDir(sessionId);
|
|
105
|
+
const manifestPath = this.dataDir.sessionManifestPath(sessionId);
|
|
106
|
+
const manifest = await this.readManifestOrEmpty(sessionId);
|
|
107
|
+
validateManifestContiguityOrThrow(manifest);
|
|
108
|
+
validateSegmentClosedContiguityOrThrow(manifest);
|
|
109
|
+
const segments = manifest.filter((m) => m.kind === 'segment_closed');
|
|
110
|
+
const events = [];
|
|
111
|
+
for (const seg of segments) {
|
|
112
|
+
const segmentPath = `${sessionDir}/${seg.segmentRelPath}`;
|
|
113
|
+
const bytes = await this.unwrap(this.fs.readFileBytes(segmentPath), mapFsToStoreError);
|
|
114
|
+
const actual = this.sha256.sha256(bytes);
|
|
115
|
+
if (actual !== seg.sha256) {
|
|
116
|
+
throw new StoreFailure({
|
|
117
|
+
code: 'SESSION_STORE_CORRUPTION_DETECTED',
|
|
118
|
+
message: `Segment digest mismatch: ${seg.segmentRelPath}`,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
const parsed = parseJsonlLines(bytes, index_js_1.DomainEventV1Schema);
|
|
122
|
+
if (parsed.length === 0) {
|
|
123
|
+
throw new StoreFailure({
|
|
124
|
+
code: 'SESSION_STORE_CORRUPTION_DETECTED',
|
|
125
|
+
message: `Empty segment referenced by manifest: ${seg.segmentRelPath}`,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
if (parsed[0].eventIndex !== seg.firstEventIndex || parsed[parsed.length - 1].eventIndex !== seg.lastEventIndex) {
|
|
129
|
+
throw new StoreFailure({
|
|
130
|
+
code: 'SESSION_STORE_CORRUPTION_DETECTED',
|
|
131
|
+
message: `Segment bounds mismatch: ${seg.segmentRelPath}`,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
for (let i = 1; i < parsed.length; i++) {
|
|
135
|
+
if (parsed[i].eventIndex !== parsed[i - 1].eventIndex + 1) {
|
|
136
|
+
throw new StoreFailure({
|
|
137
|
+
code: 'SESSION_STORE_CORRUPTION_DETECTED',
|
|
138
|
+
message: `Non-contiguous eventIndex inside segment: ${seg.segmentRelPath}`,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
events.push(...parsed);
|
|
143
|
+
}
|
|
144
|
+
const expectedPins = extractSnapshotPinsFromEvents(events);
|
|
145
|
+
const actualPins = new Set(manifest
|
|
146
|
+
.filter((m) => m.kind === 'snapshot_pinned')
|
|
147
|
+
.map((p) => `${p.eventIndex}:${p.createdByEventId}:${p.snapshotRef}`));
|
|
148
|
+
for (const ep of expectedPins) {
|
|
149
|
+
const key = `${ep.eventIndex}:${ep.createdByEventId}:${ep.snapshotRef}`;
|
|
150
|
+
if (!actualPins.has(key)) {
|
|
151
|
+
throw new StoreFailure({
|
|
152
|
+
code: 'SESSION_STORE_CORRUPTION_DETECTED',
|
|
153
|
+
message: `Missing snapshot_pinned for introduced snapshotRef (pin-after-close violation): ${key}`,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return { manifest, events };
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
await this.lock.release(lockHandle).match(() => undefined, () => undefined);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async readManifestOrEmpty(sessionId) {
|
|
164
|
+
const manifestPath = this.dataDir.sessionManifestPath(sessionId);
|
|
165
|
+
const raw = await this.fs.readFileUtf8(manifestPath).match((v) => v, (e) => {
|
|
166
|
+
if (e.code === 'FS_NOT_FOUND')
|
|
167
|
+
return '';
|
|
168
|
+
throw new StoreFailure(mapFsToStoreError(e));
|
|
169
|
+
});
|
|
170
|
+
if (raw.trim() === '')
|
|
171
|
+
return [];
|
|
172
|
+
return parseJsonlText(raw, index_js_1.ManifestRecordV1Schema);
|
|
173
|
+
}
|
|
174
|
+
async loadTruthOrEmpty(sessionId) {
|
|
175
|
+
const manifest = await this.readManifestOrEmpty(sessionId);
|
|
176
|
+
if (manifest.length === 0)
|
|
177
|
+
return { manifest: [], events: [] };
|
|
178
|
+
const segments = manifest.filter((m) => m.kind === 'segment_closed');
|
|
179
|
+
const sessionDir = this.dataDir.sessionDir(sessionId);
|
|
180
|
+
const events = [];
|
|
181
|
+
for (const seg of segments) {
|
|
182
|
+
const segmentPath = `${sessionDir}/${seg.segmentRelPath}`;
|
|
183
|
+
const bytes = await this.unwrap(this.fs.readFileBytes(segmentPath), mapFsToStoreError);
|
|
184
|
+
const parsed = parseJsonlLines(bytes, index_js_1.DomainEventV1Schema);
|
|
185
|
+
events.push(...parsed);
|
|
186
|
+
}
|
|
187
|
+
return { manifest, events };
|
|
188
|
+
}
|
|
189
|
+
async appendManifestRecords(manifestPath, records) {
|
|
190
|
+
const handle = await this.unwrap(this.fs.openAppend(manifestPath), mapFsToStoreError);
|
|
191
|
+
const bytes = concatJsonlRecords(records);
|
|
192
|
+
await this.unwrap(this.fs.writeAll(handle.fd, bytes), mapFsToStoreError);
|
|
193
|
+
await this.unwrap(this.fs.fsyncFile(handle.fd), mapFsToStoreError);
|
|
194
|
+
await this.unwrap(this.fs.closeFile(handle.fd), mapFsToStoreError);
|
|
195
|
+
}
|
|
196
|
+
async unwrap(ra, map) {
|
|
197
|
+
return ra.match((v) => v, (e) => {
|
|
198
|
+
throw new StoreFailure(map(e));
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
exports.LocalSessionEventLogStoreV2 = LocalSessionEventLogStoreV2;
|
|
203
|
+
function mapLockError(e) {
|
|
204
|
+
if (e.code === 'SESSION_LOCK_BUSY') {
|
|
205
|
+
return { code: 'SESSION_STORE_LOCK_BUSY', message: e.message, retry: e.retry };
|
|
206
|
+
}
|
|
207
|
+
return { code: 'SESSION_STORE_IO_ERROR', message: e.message };
|
|
208
|
+
}
|
|
209
|
+
function mapFsToStoreError(e) {
|
|
210
|
+
return { code: 'SESSION_STORE_IO_ERROR', message: e.message };
|
|
211
|
+
}
|
|
212
|
+
function nextManifestIndex(manifest) {
|
|
213
|
+
if (manifest.length === 0)
|
|
214
|
+
return 0;
|
|
215
|
+
return manifest[manifest.length - 1].manifestIndex + 1;
|
|
216
|
+
}
|
|
217
|
+
function nextEventIndexFromManifest(manifest) {
|
|
218
|
+
const segments = manifest.filter((m) => m.kind === 'segment_closed');
|
|
219
|
+
if (segments.length === 0)
|
|
220
|
+
return 0;
|
|
221
|
+
return segments[segments.length - 1].lastEventIndex + 1;
|
|
222
|
+
}
|
|
223
|
+
function validateManifestContiguityOrThrow(manifest) {
|
|
224
|
+
for (let i = 0; i < manifest.length; i++) {
|
|
225
|
+
const expected = i;
|
|
226
|
+
if (manifest[i].manifestIndex !== expected) {
|
|
227
|
+
throw new StoreFailure({
|
|
228
|
+
code: 'SESSION_STORE_CORRUPTION_DETECTED',
|
|
229
|
+
message: `Non-contiguous manifestIndex at position ${i} (expected ${expected}, got ${manifest[i].manifestIndex})`,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function validateSegmentClosedContiguityOrThrow(manifest) {
|
|
235
|
+
const segments = manifest.filter((m) => m.kind === 'segment_closed');
|
|
236
|
+
for (let i = 1; i < segments.length; i++) {
|
|
237
|
+
const prev = segments[i - 1];
|
|
238
|
+
const cur = segments[i];
|
|
239
|
+
if (cur.firstEventIndex !== prev.lastEventIndex + 1) {
|
|
240
|
+
throw new StoreFailure({
|
|
241
|
+
code: 'SESSION_STORE_CORRUPTION_DETECTED',
|
|
242
|
+
message: `Non-contiguous segment_closed bounds (expected firstEventIndex=${prev.lastEventIndex + 1}, got ${cur.firstEventIndex})`,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function validateAppendPlanOrThrow(sessionId, plan, expectedFirstEventIndex) {
|
|
248
|
+
if (plan.events.length === 0) {
|
|
249
|
+
throw new StoreFailure({ code: 'SESSION_STORE_INVARIANT_VIOLATION', message: 'AppendPlan.events must be non-empty' });
|
|
250
|
+
}
|
|
251
|
+
const first = plan.events[0];
|
|
252
|
+
if (first.eventIndex !== expectedFirstEventIndex) {
|
|
253
|
+
throw new StoreFailure({
|
|
254
|
+
code: 'SESSION_STORE_INVARIANT_VIOLATION',
|
|
255
|
+
message: `AppendPlan.eventIndex must start at ${expectedFirstEventIndex} (got ${first.eventIndex})`,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
for (let i = 0; i < plan.events.length; i++) {
|
|
259
|
+
const e = index_js_1.DomainEventV1Schema.safeParse(plan.events[i]);
|
|
260
|
+
if (!e.success) {
|
|
261
|
+
throw new StoreFailure({ code: 'SESSION_STORE_INVARIANT_VIOLATION', message: `Invalid domain event at index ${i}` });
|
|
262
|
+
}
|
|
263
|
+
if (e.data.sessionId !== sessionId) {
|
|
264
|
+
throw new StoreFailure({
|
|
265
|
+
code: 'SESSION_STORE_INVARIANT_VIOLATION',
|
|
266
|
+
message: `Domain event sessionId mismatch at index ${i}`,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
if (i > 0 && plan.events[i].eventIndex !== plan.events[i - 1].eventIndex + 1) {
|
|
270
|
+
throw new StoreFailure({
|
|
271
|
+
code: 'SESSION_STORE_INVARIANT_VIOLATION',
|
|
272
|
+
message: `Non-contiguous eventIndex in AppendPlan at index ${i}`,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const pins = sortedPins(plan.snapshotPins);
|
|
277
|
+
for (const p of pins) {
|
|
278
|
+
if (p.eventIndex < first.eventIndex || p.eventIndex > plan.events[plan.events.length - 1].eventIndex) {
|
|
279
|
+
throw new StoreFailure({
|
|
280
|
+
code: 'SESSION_STORE_INVARIANT_VIOLATION',
|
|
281
|
+
message: `SnapshotPin.eventIndex must refer to an event in the appended segment`,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function sortedPins(pins) {
|
|
287
|
+
return [...pins].sort((a, b) => {
|
|
288
|
+
const sr = String(a.snapshotRef).localeCompare(String(b.snapshotRef));
|
|
289
|
+
if (sr !== 0)
|
|
290
|
+
return sr;
|
|
291
|
+
const ei = a.eventIndex - b.eventIndex;
|
|
292
|
+
if (ei !== 0)
|
|
293
|
+
return ei;
|
|
294
|
+
return a.createdByEventId.localeCompare(b.createdByEventId);
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
function segmentRelPathFor(firstEventIndex, lastEventIndex) {
|
|
298
|
+
const first = String(firstEventIndex).padStart(8, '0');
|
|
299
|
+
const last = String(lastEventIndex).padStart(8, '0');
|
|
300
|
+
return `events/${first}-${last}.jsonl`;
|
|
301
|
+
}
|
|
302
|
+
function concatJsonlRecords(records) {
|
|
303
|
+
const parts = [];
|
|
304
|
+
let total = 0;
|
|
305
|
+
for (const r of records) {
|
|
306
|
+
const encoded = (0, jsonl_js_1.toJsonlLineBytes)(r).match((v) => v, (e) => {
|
|
307
|
+
throw new StoreFailure({ code: 'SESSION_STORE_INVARIANT_VIOLATION', message: e.message });
|
|
308
|
+
});
|
|
309
|
+
parts.push(encoded);
|
|
310
|
+
total += encoded.length;
|
|
311
|
+
}
|
|
312
|
+
const out = new Uint8Array(total);
|
|
313
|
+
let offset = 0;
|
|
314
|
+
for (const p of parts) {
|
|
315
|
+
out.set(p, offset);
|
|
316
|
+
offset += p.length;
|
|
317
|
+
}
|
|
318
|
+
return out;
|
|
319
|
+
}
|
|
320
|
+
function parseJsonlText(text, schema) {
|
|
321
|
+
const lines = text.split('\n').filter((l) => l.trim() !== '');
|
|
322
|
+
const out = [];
|
|
323
|
+
for (let i = 0; i < lines.length; i++) {
|
|
324
|
+
const raw = lines[i];
|
|
325
|
+
let parsed;
|
|
326
|
+
try {
|
|
327
|
+
parsed = JSON.parse(raw);
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
throw new StoreFailure({ code: 'SESSION_STORE_CORRUPTION_DETECTED', message: `Invalid JSONL at line ${i}` });
|
|
331
|
+
}
|
|
332
|
+
const validated = schema.safeParse(parsed);
|
|
333
|
+
if (!validated.success) {
|
|
334
|
+
throw new StoreFailure({ code: 'SESSION_STORE_CORRUPTION_DETECTED', message: `Invalid record at line ${i}` });
|
|
335
|
+
}
|
|
336
|
+
out.push(validated.data);
|
|
337
|
+
}
|
|
338
|
+
return out;
|
|
339
|
+
}
|
|
340
|
+
function parseJsonlLines(bytes, schema) {
|
|
341
|
+
const text = new TextDecoder().decode(bytes);
|
|
342
|
+
return parseJsonlText(text, schema);
|
|
343
|
+
}
|
|
344
|
+
function extractSnapshotPinsFromEvents(events) {
|
|
345
|
+
const out = [];
|
|
346
|
+
for (const e of events) {
|
|
347
|
+
if (e.kind !== 'node_created')
|
|
348
|
+
continue;
|
|
349
|
+
const data = e.data;
|
|
350
|
+
if (typeof data !== 'object' || data === null)
|
|
351
|
+
continue;
|
|
352
|
+
const snap = data.snapshotRef;
|
|
353
|
+
if (typeof snap === 'string') {
|
|
354
|
+
out.push({ snapshotRef: snap, eventIndex: e.eventIndex, createdByEventId: e.eventId });
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return out;
|
|
358
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NodeSha256V2 = void 0;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
const index_js_1 = require("../../../durable-core/ids/index.js");
|
|
6
|
+
class NodeSha256V2 {
|
|
7
|
+
sha256(bytes) {
|
|
8
|
+
const hex = (0, crypto_1.createHash)('sha256').update(Buffer.from(bytes)).digest('hex');
|
|
9
|
+
return (0, index_js_1.asSha256Digest)(`sha256:${hex}`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.NodeSha256V2 = NodeSha256V2;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface DataDirPortV2 {
|
|
2
|
+
pinnedWorkflowsDir(): string;
|
|
3
|
+
pinnedWorkflowPath(workflowHash: string): string;
|
|
4
|
+
sessionsDir(): string;
|
|
5
|
+
sessionDir(sessionId: string): string;
|
|
6
|
+
sessionEventsDir(sessionId: string): string;
|
|
7
|
+
sessionManifestPath(sessionId: string): string;
|
|
8
|
+
sessionLockPath(sessionId: string): string;
|
|
9
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ResultAsync } from 'neverthrow';
|
|
2
|
+
export type FsError = {
|
|
3
|
+
readonly code: 'FS_IO_ERROR';
|
|
4
|
+
readonly message: string;
|
|
5
|
+
} | {
|
|
6
|
+
readonly code: 'FS_NOT_FOUND';
|
|
7
|
+
readonly message: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly code: 'FS_ALREADY_EXISTS';
|
|
10
|
+
readonly message: string;
|
|
11
|
+
} | {
|
|
12
|
+
readonly code: 'FS_PERMISSION_DENIED';
|
|
13
|
+
readonly message: string;
|
|
14
|
+
} | {
|
|
15
|
+
readonly code: 'FS_UNSUPPORTED';
|
|
16
|
+
readonly message: string;
|
|
17
|
+
};
|
|
18
|
+
export interface FileSystemPortV2 {
|
|
19
|
+
mkdirp(dirPath: string): ResultAsync<void, FsError>;
|
|
20
|
+
readFileUtf8(filePath: string): ResultAsync<string, FsError>;
|
|
21
|
+
readFileBytes(filePath: string): ResultAsync<Uint8Array, FsError>;
|
|
22
|
+
writeFileBytes(filePath: string, bytes: Uint8Array): ResultAsync<void, FsError>;
|
|
23
|
+
openWriteTruncate(filePath: string): ResultAsync<{
|
|
24
|
+
readonly fd: number;
|
|
25
|
+
}, FsError>;
|
|
26
|
+
openAppend(filePath: string): ResultAsync<{
|
|
27
|
+
readonly fd: number;
|
|
28
|
+
}, FsError>;
|
|
29
|
+
writeAll(fd: number, bytes: Uint8Array): ResultAsync<void, FsError>;
|
|
30
|
+
openExclusive(filePath: string, bytes: Uint8Array): ResultAsync<{
|
|
31
|
+
readonly fd: number;
|
|
32
|
+
}, FsError>;
|
|
33
|
+
fsyncFile(fd: number): ResultAsync<void, FsError>;
|
|
34
|
+
fsyncDir(dirPath: string): ResultAsync<void, FsError>;
|
|
35
|
+
closeFile(fd: number): ResultAsync<void, FsError>;
|
|
36
|
+
rename(fromPath: string, toPath: string): ResultAsync<void, FsError>;
|
|
37
|
+
unlink(filePath: string): ResultAsync<void, FsError>;
|
|
38
|
+
stat(filePath: string): ResultAsync<{
|
|
39
|
+
readonly sizeBytes: number;
|
|
40
|
+
}, FsError>;
|
|
41
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ResultAsync } from 'neverthrow';
|
|
2
|
+
import type { WorkflowHash } from '../durable-core/ids/index.js';
|
|
3
|
+
import type { CompiledWorkflowSnapshotV1 } from '../durable-core/schemas/compiled-workflow/index.js';
|
|
4
|
+
export type PinnedWorkflowStoreError = {
|
|
5
|
+
readonly code: 'PINNED_WORKFLOW_IO_ERROR';
|
|
6
|
+
readonly message: string;
|
|
7
|
+
};
|
|
8
|
+
export interface PinnedWorkflowStorePortV2 {
|
|
9
|
+
get(workflowHash: WorkflowHash): ResultAsync<CompiledWorkflowSnapshotV1 | null, PinnedWorkflowStoreError>;
|
|
10
|
+
put(workflowHash: WorkflowHash, compiled: CompiledWorkflowSnapshotV1): ResultAsync<void, PinnedWorkflowStoreError>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ResultAsync } from 'neverthrow';
|
|
2
|
+
import type { SessionId, SnapshotRef } from '../durable-core/ids/index.js';
|
|
3
|
+
import type { DomainEventV1, ManifestRecordV1 } from '../durable-core/schemas/session/index.js';
|
|
4
|
+
export interface SnapshotPinV2 {
|
|
5
|
+
readonly snapshotRef: SnapshotRef;
|
|
6
|
+
readonly eventIndex: number;
|
|
7
|
+
readonly createdByEventId: string;
|
|
8
|
+
}
|
|
9
|
+
export interface AppendPlanV2 {
|
|
10
|
+
readonly events: readonly DomainEventV1[];
|
|
11
|
+
readonly snapshotPins: readonly SnapshotPinV2[];
|
|
12
|
+
}
|
|
13
|
+
export type SessionEventLogStoreError = {
|
|
14
|
+
readonly code: 'SESSION_STORE_LOCK_BUSY';
|
|
15
|
+
readonly message: string;
|
|
16
|
+
readonly retry: {
|
|
17
|
+
readonly kind: 'retryable';
|
|
18
|
+
readonly afterMs: number;
|
|
19
|
+
};
|
|
20
|
+
} | {
|
|
21
|
+
readonly code: 'SESSION_STORE_IO_ERROR';
|
|
22
|
+
readonly message: string;
|
|
23
|
+
} | {
|
|
24
|
+
readonly code: 'SESSION_STORE_CORRUPTION_DETECTED';
|
|
25
|
+
readonly message: string;
|
|
26
|
+
} | {
|
|
27
|
+
readonly code: 'SESSION_STORE_INVARIANT_VIOLATION';
|
|
28
|
+
readonly message: string;
|
|
29
|
+
};
|
|
30
|
+
export interface LoadedSessionTruthV2 {
|
|
31
|
+
readonly manifest: readonly ManifestRecordV1[];
|
|
32
|
+
readonly events: readonly DomainEventV1[];
|
|
33
|
+
}
|
|
34
|
+
export interface SessionEventLogStorePortV2 {
|
|
35
|
+
append(sessionId: SessionId, plan: AppendPlanV2): ResultAsync<void, SessionEventLogStoreError>;
|
|
36
|
+
load(sessionId: SessionId): ResultAsync<LoadedSessionTruthV2, SessionEventLogStoreError>;
|
|
37
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ResultAsync } from 'neverthrow';
|
|
2
|
+
import type { SessionId } from '../durable-core/ids/index.js';
|
|
3
|
+
export type SessionLockError = {
|
|
4
|
+
readonly code: 'SESSION_LOCK_BUSY';
|
|
5
|
+
readonly message: string;
|
|
6
|
+
readonly retry: {
|
|
7
|
+
readonly kind: 'retryable';
|
|
8
|
+
readonly afterMs: number;
|
|
9
|
+
};
|
|
10
|
+
readonly lockPath: string;
|
|
11
|
+
} | {
|
|
12
|
+
readonly code: 'SESSION_LOCK_IO_ERROR';
|
|
13
|
+
readonly message: string;
|
|
14
|
+
readonly lockPath: string;
|
|
15
|
+
};
|
|
16
|
+
export interface SessionLockHandleV2 {
|
|
17
|
+
readonly kind: 'v2_session_lock_handle';
|
|
18
|
+
readonly sessionId: SessionId;
|
|
19
|
+
}
|
|
20
|
+
export interface SessionLockPortV2 {
|
|
21
|
+
acquire(sessionId: SessionId): ResultAsync<SessionLockHandleV2, SessionLockError>;
|
|
22
|
+
release(handle: SessionLockHandleV2): ResultAsync<void, SessionLockError>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Result } from 'neverthrow';
|
|
2
|
+
import type { DomainEventV1 } from '../durable-core/schemas/session/index.js';
|
|
3
|
+
export type ProjectionError = {
|
|
4
|
+
readonly code: 'PROJECTION_INVARIANT_VIOLATION';
|
|
5
|
+
readonly message: string;
|
|
6
|
+
} | {
|
|
7
|
+
readonly code: 'PROJECTION_CORRUPTION_DETECTED';
|
|
8
|
+
readonly message: string;
|
|
9
|
+
};
|
|
10
|
+
type AdvanceRecordedEventV1 = Extract<DomainEventV1, {
|
|
11
|
+
kind: 'advance_recorded';
|
|
12
|
+
}>;
|
|
13
|
+
export interface NodeAdvanceOutcomeV2 {
|
|
14
|
+
readonly nodeId: string;
|
|
15
|
+
readonly latestAttemptId: string;
|
|
16
|
+
readonly outcome: AdvanceRecordedEventV1['data']['outcome'];
|
|
17
|
+
readonly recordedAtEventIndex: number;
|
|
18
|
+
}
|
|
19
|
+
export interface AdvanceOutcomesProjectionV2 {
|
|
20
|
+
readonly byNodeId: Readonly<Record<string, NodeAdvanceOutcomeV2>>;
|
|
21
|
+
}
|
|
22
|
+
export declare function projectAdvanceOutcomesV2(events: readonly DomainEventV1[]): Result<AdvanceOutcomesProjectionV2, ProjectionError>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.projectAdvanceOutcomesV2 = projectAdvanceOutcomesV2;
|
|
4
|
+
const neverthrow_1 = require("neverthrow");
|
|
5
|
+
function projectAdvanceOutcomesV2(events) {
|
|
6
|
+
for (let i = 1; i < events.length; i++) {
|
|
7
|
+
if (events[i].eventIndex < events[i - 1].eventIndex) {
|
|
8
|
+
return (0, neverthrow_1.err)({ code: 'PROJECTION_INVARIANT_VIOLATION', message: 'Events must be sorted by eventIndex ascending' });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const byNodeId = {};
|
|
12
|
+
for (const e of events) {
|
|
13
|
+
if (e.kind !== 'advance_recorded')
|
|
14
|
+
continue;
|
|
15
|
+
byNodeId[e.scope.nodeId] = {
|
|
16
|
+
nodeId: e.scope.nodeId,
|
|
17
|
+
latestAttemptId: e.data.attemptId,
|
|
18
|
+
outcome: e.data.outcome,
|
|
19
|
+
recordedAtEventIndex: e.eventIndex,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return (0, neverthrow_1.ok)({ byNodeId });
|
|
23
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Result } from 'neverthrow';
|
|
2
|
+
import type { DomainEventV1 } from '../durable-core/schemas/session/index.js';
|
|
3
|
+
export type ProjectionError = {
|
|
4
|
+
readonly code: 'PROJECTION_INVARIANT_VIOLATION';
|
|
5
|
+
readonly message: string;
|
|
6
|
+
} | {
|
|
7
|
+
readonly code: 'PROJECTION_CORRUPTION_DETECTED';
|
|
8
|
+
readonly message: string;
|
|
9
|
+
};
|
|
10
|
+
export type CapabilityV2 = 'delegation' | 'web_browsing';
|
|
11
|
+
export type CapabilityStatusV2 = 'unknown' | 'available' | 'unavailable';
|
|
12
|
+
type CapabilityObservedEventV1 = Extract<DomainEventV1, {
|
|
13
|
+
kind: 'capability_observed';
|
|
14
|
+
}>;
|
|
15
|
+
export interface CapabilityObservationV2 {
|
|
16
|
+
readonly status: CapabilityStatusV2;
|
|
17
|
+
readonly provenance: CapabilityObservedEventV1['data']['provenance'];
|
|
18
|
+
readonly observedAtEventIndex: number;
|
|
19
|
+
}
|
|
20
|
+
export interface NodeCapabilitiesViewV2 {
|
|
21
|
+
readonly byCapability: Readonly<Record<CapabilityV2, CapabilityObservationV2 | null>>;
|
|
22
|
+
}
|
|
23
|
+
export interface CapabilitiesProjectionV2 {
|
|
24
|
+
readonly nodesById: Readonly<Record<string, NodeCapabilitiesViewV2>>;
|
|
25
|
+
}
|
|
26
|
+
export declare function projectCapabilitiesV2(events: readonly DomainEventV1[]): Result<CapabilitiesProjectionV2, ProjectionError>;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.projectCapabilitiesV2 = projectCapabilitiesV2;
|
|
4
|
+
const neverthrow_1 = require("neverthrow");
|
|
5
|
+
function projectCapabilitiesV2(events) {
|
|
6
|
+
for (let i = 1; i < events.length; i++) {
|
|
7
|
+
if (events[i].eventIndex < events[i - 1].eventIndex) {
|
|
8
|
+
return (0, neverthrow_1.err)({ code: 'PROJECTION_INVARIANT_VIOLATION', message: 'Events must be sorted by eventIndex ascending' });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const nodes = {};
|
|
12
|
+
const ensure = (nodeId) => {
|
|
13
|
+
const existing = nodes[nodeId];
|
|
14
|
+
if (existing)
|
|
15
|
+
return existing;
|
|
16
|
+
const created = { byCapability: { delegation: null, web_browsing: null } };
|
|
17
|
+
nodes[nodeId] = created;
|
|
18
|
+
return created;
|
|
19
|
+
};
|
|
20
|
+
for (const e of events) {
|
|
21
|
+
if (e.kind !== 'capability_observed')
|
|
22
|
+
continue;
|
|
23
|
+
const nodeId = e.scope.nodeId;
|
|
24
|
+
const cap = e.data.capability;
|
|
25
|
+
const observation = {
|
|
26
|
+
status: e.data.status,
|
|
27
|
+
provenance: e.data.provenance,
|
|
28
|
+
observedAtEventIndex: e.eventIndex,
|
|
29
|
+
};
|
|
30
|
+
ensure(nodeId).byCapability[cap] = observation;
|
|
31
|
+
}
|
|
32
|
+
return (0, neverthrow_1.ok)({ nodesById: nodes });
|
|
33
|
+
}
|