@imgly/codesign-mcp 0.1.6 → 0.1.7
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 +5 -10
- package/dist/cli/http.d.ts.map +1 -1
- package/dist/cli/http.js +12 -2
- package/dist/cli/http.js.map +1 -1
- package/dist/cli/stdio.d.ts.map +1 -1
- package/dist/cli/stdio.js +103 -35
- package/dist/cli/stdio.js.map +1 -1
- package/dist/config.d.ts +11 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -1
- package/dist/config.js.map +1 -1
- package/dist/diagnostics/events.d.ts +6 -0
- package/dist/diagnostics/events.d.ts.map +1 -1
- package/dist/diagnostics/events.js.map +1 -1
- package/dist/engine/cesdk-adapter.d.ts +5 -1
- package/dist/engine/cesdk-adapter.d.ts.map +1 -1
- package/dist/engine/cesdk-adapter.js +8 -1
- package/dist/engine/cesdk-adapter.js.map +1 -1
- package/dist/engine/engine-capacity.d.ts +16 -0
- package/dist/engine/engine-capacity.d.ts.map +1 -0
- package/dist/engine/engine-capacity.js +48 -0
- package/dist/engine/engine-capacity.js.map +1 -0
- package/dist/engine/engine-slots.d.ts +48 -0
- package/dist/engine/engine-slots.d.ts.map +1 -0
- package/dist/engine/engine-slots.js +182 -0
- package/dist/engine/engine-slots.js.map +1 -0
- package/dist/tools/engine.d.ts +13 -0
- package/dist/tools/engine.d.ts.map +1 -1
- package/dist/tools/engine.js +28 -0
- package/dist/tools/engine.js.map +1 -1
- package/package.json +2 -2
- package/dist/dashboard/router.d.ts +0 -3
- package/dist/dashboard/router.d.ts.map +0 -1
- package/dist/dashboard/router.js +0 -19
- package/dist/dashboard/router.js.map +0 -1
- package/dist/dashboard/spa-assets.generated.d.ts +0 -2
- package/dist/dashboard/spa-assets.generated.d.ts.map +0 -1
- package/dist/dashboard/spa-assets.generated.js +0 -220
- package/dist/dashboard/spa-assets.generated.js.map +0 -1
- package/dist/metrics/mount.d.ts +0 -11
- package/dist/metrics/mount.d.ts.map +0 -1
- package/dist/metrics/mount.js +0 -13
- package/dist/metrics/mount.js.map +0 -1
- package/dist/metrics/recorder.d.ts +0 -55
- package/dist/metrics/recorder.d.ts.map +0 -1
- package/dist/metrics/recorder.js +0 -97
- package/dist/metrics/recorder.js.map +0 -1
- package/dist/test/scripts/changelog-add.d.ts +0 -8
- package/dist/test/scripts/changelog-add.d.ts.map +0 -1
- package/dist/test/scripts/changelog-add.js +0 -50
- package/dist/test/scripts/changelog-add.js.map +0 -1
- package/dist/test/scripts/changelog-collate.d.ts +0 -38
- package/dist/test/scripts/changelog-collate.d.ts.map +0 -1
- package/dist/test/scripts/changelog-collate.js +0 -171
- package/dist/test/scripts/changelog-collate.js.map +0 -1
- package/dist/test/test/changelog.test.d.ts +0 -2
- package/dist/test/test/changelog.test.d.ts.map +0 -1
- package/dist/test/test/changelog.test.js +0 -293
- package/dist/test/test/changelog.test.js.map +0 -1
- package/dist/test/test/cli/dispatcher.test.d.ts +0 -2
- package/dist/test/test/cli/dispatcher.test.d.ts.map +0 -1
- package/dist/test/test/cli/dispatcher.test.js +0 -54
- package/dist/test/test/cli/dispatcher.test.js.map +0 -1
- package/dist/test/test/cli/redirect-console.test.d.ts +0 -2
- package/dist/test/test/cli/redirect-console.test.d.ts.map +0 -1
- package/dist/test/test/cli/redirect-console.test.js +0 -78
- package/dist/test/test/cli/redirect-console.test.js.map +0 -1
- package/dist/test/test/cli/resolve-license.test.d.ts +0 -2
- package/dist/test/test/cli/resolve-license.test.d.ts.map +0 -1
- package/dist/test/test/cli/resolve-license.test.js +0 -29
- package/dist/test/test/cli/resolve-license.test.js.map +0 -1
- package/dist/test/test/cli/stdio-diagnostics.test.d.ts +0 -2
- package/dist/test/test/cli/stdio-diagnostics.test.d.ts.map +0 -1
- package/dist/test/test/cli/stdio-diagnostics.test.js +0 -31
- package/dist/test/test/cli/stdio-diagnostics.test.js.map +0 -1
- package/dist/test/test/cli/stdio-license.test.d.ts +0 -2
- package/dist/test/test/cli/stdio-license.test.d.ts.map +0 -1
- package/dist/test/test/cli/stdio-license.test.js +0 -19
- package/dist/test/test/cli/stdio-license.test.js.map +0 -1
- package/dist/test/test/config.test.d.ts +0 -2
- package/dist/test/test/config.test.d.ts.map +0 -1
- package/dist/test/test/config.test.js +0 -95
- package/dist/test/test/config.test.js.map +0 -1
- package/dist/test/test/cross-ref.test.d.ts +0 -2
- package/dist/test/test/cross-ref.test.d.ts.map +0 -1
- package/dist/test/test/cross-ref.test.js +0 -39
- package/dist/test/test/cross-ref.test.js.map +0 -1
- package/dist/test/test/diagnostics/bundle.test.d.ts +0 -2
- package/dist/test/test/diagnostics/bundle.test.d.ts.map +0 -1
- package/dist/test/test/diagnostics/bundle.test.js +0 -53
- package/dist/test/test/diagnostics/bundle.test.js.map +0 -1
- package/dist/test/test/diagnostics/compose.test.d.ts +0 -2
- package/dist/test/test/diagnostics/compose.test.d.ts.map +0 -1
- package/dist/test/test/diagnostics/compose.test.js +0 -31
- package/dist/test/test/diagnostics/compose.test.js.map +0 -1
- package/dist/test/test/diagnostics/file-sink.test.d.ts +0 -2
- package/dist/test/test/diagnostics/file-sink.test.d.ts.map +0 -1
- package/dist/test/test/diagnostics/file-sink.test.js +0 -113
- package/dist/test/test/diagnostics/file-sink.test.js.map +0 -1
- package/dist/test/test/diagnostics/redact.test.d.ts +0 -2
- package/dist/test/test/diagnostics/redact.test.d.ts.map +0 -1
- package/dist/test/test/diagnostics/redact.test.js +0 -59
- package/dist/test/test/diagnostics/redact.test.js.map +0 -1
- package/dist/test/test/diagnostics/tool-call-adapter.test.d.ts +0 -2
- package/dist/test/test/diagnostics/tool-call-adapter.test.d.ts.map +0 -1
- package/dist/test/test/diagnostics/tool-call-adapter.test.js +0 -34
- package/dist/test/test/diagnostics/tool-call-adapter.test.js.map +0 -1
- package/dist/test/test/engine/asset-sources.test.d.ts +0 -2
- package/dist/test/test/engine/asset-sources.test.d.ts.map +0 -1
- package/dist/test/test/engine/asset-sources.test.js +0 -100
- package/dist/test/test/engine/asset-sources.test.js.map +0 -1
- package/dist/test/test/engine/cesdk-adapter.test.d.ts +0 -2
- package/dist/test/test/engine/cesdk-adapter.test.d.ts.map +0 -1
- package/dist/test/test/engine/cesdk-adapter.test.js +0 -32
- package/dist/test/test/engine/cesdk-adapter.test.js.map +0 -1
- package/dist/test/test/engine/mutex.test.d.ts +0 -2
- package/dist/test/test/engine/mutex.test.d.ts.map +0 -1
- package/dist/test/test/engine/mutex.test.js +0 -63
- package/dist/test/test/engine/mutex.test.js.map +0 -1
- package/dist/test/test/engine/session.test.d.ts +0 -2
- package/dist/test/test/engine/session.test.d.ts.map +0 -1
- package/dist/test/test/engine/session.test.js +0 -159
- package/dist/test/test/engine/session.test.js.map +0 -1
- package/dist/test/test/engine/unsplash-source.test.d.ts +0 -2
- package/dist/test/test/engine/unsplash-source.test.d.ts.map +0 -1
- package/dist/test/test/engine/unsplash-source.test.js +0 -129
- package/dist/test/test/engine/unsplash-source.test.js.map +0 -1
- package/dist/test/test/engine/uri-resolver.test.d.ts +0 -2
- package/dist/test/test/engine/uri-resolver.test.d.ts.map +0 -1
- package/dist/test/test/engine/uri-resolver.test.js +0 -38
- package/dist/test/test/engine/uri-resolver.test.js.map +0 -1
- package/dist/test/test/gateway/hosted-stub.test.d.ts +0 -2
- package/dist/test/test/gateway/hosted-stub.test.d.ts.map +0 -1
- package/dist/test/test/gateway/hosted-stub.test.js +0 -11
- package/dist/test/test/gateway/hosted-stub.test.js.map +0 -1
- package/dist/test/test/gateway/local.test.d.ts +0 -2
- package/dist/test/test/gateway/local.test.d.ts.map +0 -1
- package/dist/test/test/gateway/local.test.js +0 -29
- package/dist/test/test/gateway/local.test.js.map +0 -1
- package/dist/test/test/handbook-contract.test.d.ts +0 -2
- package/dist/test/test/handbook-contract.test.d.ts.map +0 -1
- package/dist/test/test/handbook-contract.test.js +0 -79
- package/dist/test/test/handbook-contract.test.js.map +0 -1
- package/dist/test/test/http/server.test.d.ts +0 -2
- package/dist/test/test/http/server.test.d.ts.map +0 -1
- package/dist/test/test/http/server.test.js +0 -338
- package/dist/test/test/http/server.test.js.map +0 -1
- package/dist/test/test/http/session-id-header.test.d.ts +0 -2
- package/dist/test/test/http/session-id-header.test.d.ts.map +0 -1
- package/dist/test/test/http/session-id-header.test.js +0 -76
- package/dist/test/test/http/session-id-header.test.js.map +0 -1
- package/dist/test/test/http/session-manager.test.d.ts +0 -2
- package/dist/test/test/http/session-manager.test.d.ts.map +0 -1
- package/dist/test/test/http/session-manager.test.js +0 -97
- package/dist/test/test/http/session-manager.test.js.map +0 -1
- package/dist/test/test/http/workspace-auth.test.d.ts +0 -2
- package/dist/test/test/http/workspace-auth.test.d.ts.map +0 -1
- package/dist/test/test/http/workspace-auth.test.js +0 -40
- package/dist/test/test/http/workspace-auth.test.js.map +0 -1
- package/dist/test/test/metrics/mount.test.d.ts +0 -2
- package/dist/test/test/metrics/mount.test.d.ts.map +0 -1
- package/dist/test/test/metrics/mount.test.js +0 -59
- package/dist/test/test/metrics/mount.test.js.map +0 -1
- package/dist/test/test/metrics/recorder.test.d.ts +0 -2
- package/dist/test/test/metrics/recorder.test.d.ts.map +0 -1
- package/dist/test/test/metrics/recorder.test.js +0 -118
- package/dist/test/test/metrics/recorder.test.js.map +0 -1
- package/dist/test/test/revisions/hash.test.d.ts +0 -2
- package/dist/test/test/revisions/hash.test.d.ts.map +0 -1
- package/dist/test/test/revisions/hash.test.js +0 -33
- package/dist/test/test/revisions/hash.test.js.map +0 -1
- package/dist/test/test/revisions/store.test.d.ts +0 -2
- package/dist/test/test/revisions/store.test.d.ts.map +0 -1
- package/dist/test/test/revisions/store.test.js +0 -315
- package/dist/test/test/revisions/store.test.js.map +0 -1
- package/dist/test/test/server.metrics.test.d.ts +0 -2
- package/dist/test/test/server.metrics.test.d.ts.map +0 -1
- package/dist/test/test/server.metrics.test.js +0 -87
- package/dist/test/test/server.metrics.test.js.map +0 -1
- package/dist/test/test/server.test.d.ts +0 -2
- package/dist/test/test/server.test.d.ts.map +0 -1
- package/dist/test/test/server.test.js +0 -146
- package/dist/test/test/server.test.js.map +0 -1
- package/dist/test/test/skill-tools.test.d.ts +0 -2
- package/dist/test/test/skill-tools.test.d.ts.map +0 -1
- package/dist/test/test/skill-tools.test.js +0 -84
- package/dist/test/test/skill-tools.test.js.map +0 -1
- package/dist/test/test/smoke.test.d.ts +0 -2
- package/dist/test/test/smoke.test.d.ts.map +0 -1
- package/dist/test/test/smoke.test.js +0 -8
- package/dist/test/test/smoke.test.js.map +0 -1
- package/dist/test/test/tools/asset-generate.test.d.ts +0 -2
- package/dist/test/test/tools/asset-generate.test.d.ts.map +0 -1
- package/dist/test/test/tools/asset-generate.test.js +0 -66
- package/dist/test/test/tools/asset-generate.test.js.map +0 -1
- package/dist/test/test/tools/asset-search.test.d.ts +0 -2
- package/dist/test/test/tools/asset-search.test.d.ts.map +0 -1
- package/dist/test/test/tools/asset-search.test.js +0 -121
- package/dist/test/test/tools/asset-search.test.js.map +0 -1
- package/dist/test/test/tools/edit-harness.d.ts +0 -14
- package/dist/test/test/tools/edit-harness.d.ts.map +0 -1
- package/dist/test/test/tools/edit-harness.js +0 -30
- package/dist/test/test/tools/edit-harness.js.map +0 -1
- package/dist/test/test/tools/edit.telemetry.test.d.ts +0 -2
- package/dist/test/test/tools/edit.telemetry.test.d.ts.map +0 -1
- package/dist/test/test/tools/edit.telemetry.test.js +0 -46
- package/dist/test/test/tools/edit.telemetry.test.js.map +0 -1
- package/dist/test/test/tools/edit.test.d.ts +0 -2
- package/dist/test/test/tools/edit.test.d.ts.map +0 -1
- package/dist/test/test/tools/edit.test.js +0 -267
- package/dist/test/test/tools/edit.test.js.map +0 -1
- package/dist/test/test/tools/export-harness.d.ts +0 -13
- package/dist/test/test/tools/export-harness.d.ts.map +0 -1
- package/dist/test/test/tools/export-harness.js +0 -27
- package/dist/test/test/tools/export-harness.js.map +0 -1
- package/dist/test/test/tools/export.telemetry.test.d.ts +0 -2
- package/dist/test/test/tools/export.telemetry.test.d.ts.map +0 -1
- package/dist/test/test/tools/export.telemetry.test.js +0 -65
- package/dist/test/test/tools/export.telemetry.test.js.map +0 -1
- package/dist/test/test/tools/export.test.d.ts +0 -2
- package/dist/test/test/tools/export.test.d.ts.map +0 -1
- package/dist/test/test/tools/export.test.js +0 -174
- package/dist/test/test/tools/export.test.js.map +0 -1
- package/dist/test/test/tools/history.test.d.ts +0 -2
- package/dist/test/test/tools/history.test.d.ts.map +0 -1
- package/dist/test/test/tools/history.test.js +0 -29
- package/dist/test/test/tools/history.test.js.map +0 -1
- package/dist/test/test/tools/import.test.d.ts +0 -2
- package/dist/test/test/tools/import.test.d.ts.map +0 -1
- package/dist/test/test/tools/import.test.js +0 -122
- package/dist/test/test/tools/import.test.js.map +0 -1
- package/dist/test/test/tools/index.test.d.ts +0 -2
- package/dist/test/test/tools/index.test.d.ts.map +0 -1
- package/dist/test/test/tools/index.test.js +0 -117
- package/dist/test/test/tools/index.test.js.map +0 -1
- package/dist/test/test/tools/inspect.test.d.ts +0 -2
- package/dist/test/test/tools/inspect.test.d.ts.map +0 -1
- package/dist/test/test/tools/inspect.test.js +0 -62
- package/dist/test/test/tools/inspect.test.js.map +0 -1
- package/dist/test/test/tools/list.test.d.ts +0 -2
- package/dist/test/test/tools/list.test.d.ts.map +0 -1
- package/dist/test/test/tools/list.test.js +0 -23
- package/dist/test/test/tools/list.test.js.map +0 -1
- package/dist/test/test/tools/load.integration.test.d.ts +0 -2
- package/dist/test/test/tools/load.integration.test.d.ts.map +0 -1
- package/dist/test/test/tools/load.integration.test.js +0 -165
- package/dist/test/test/tools/load.integration.test.js.map +0 -1
- package/dist/test/test/tools/load.test.d.ts +0 -2
- package/dist/test/test/tools/load.test.d.ts.map +0 -1
- package/dist/test/test/tools/load.test.js +0 -387
- package/dist/test/test/tools/load.test.js.map +0 -1
- package/dist/test/test/tools/metrics.test.d.ts +0 -2
- package/dist/test/test/tools/metrics.test.d.ts.map +0 -1
- package/dist/test/test/tools/metrics.test.js +0 -29
- package/dist/test/test/tools/metrics.test.js.map +0 -1
- package/dist/test/test/tools/open-editor.test.d.ts +0 -2
- package/dist/test/test/tools/open-editor.test.d.ts.map +0 -1
- package/dist/test/test/tools/open-editor.test.js +0 -53
- package/dist/test/test/tools/open-editor.test.js.map +0 -1
- package/dist/test/test/tools/preview-harness.d.ts +0 -9
- package/dist/test/test/tools/preview-harness.d.ts.map +0 -1
- package/dist/test/test/tools/preview-harness.js +0 -23
- package/dist/test/test/tools/preview-harness.js.map +0 -1
- package/dist/test/test/tools/preview.telemetry.test.d.ts +0 -2
- package/dist/test/test/tools/preview.telemetry.test.d.ts.map +0 -1
- package/dist/test/test/tools/preview.telemetry.test.js +0 -36
- package/dist/test/test/tools/preview.telemetry.test.js.map +0 -1
- package/dist/test/test/tools/preview.test.d.ts +0 -2
- package/dist/test/test/tools/preview.test.d.ts.map +0 -1
- package/dist/test/test/tools/preview.test.js +0 -75
- package/dist/test/test/tools/preview.test.js.map +0 -1
- package/dist/test/test/tools/rename.test.d.ts +0 -2
- package/dist/test/test/tools/rename.test.d.ts.map +0 -1
- package/dist/test/test/tools/rename.test.js +0 -16
- package/dist/test/test/tools/rename.test.js.map +0 -1
- package/dist/test/test/tools/save.test.d.ts +0 -2
- package/dist/test/test/tools/save.test.d.ts.map +0 -1
- package/dist/test/test/tools/save.test.js +0 -137
- package/dist/test/test/tools/save.test.js.map +0 -1
- package/dist/test/test/tools/schema-best-practices.d.ts +0 -13
- package/dist/test/test/tools/schema-best-practices.d.ts.map +0 -1
- package/dist/test/test/tools/schema-best-practices.js +0 -169
- package/dist/test/test/tools/schema-best-practices.js.map +0 -1
- package/dist/test/test/tools/schema-best-practices.test.d.ts +0 -3
- package/dist/test/test/tools/schema-best-practices.test.d.ts.map +0 -1
- package/dist/test/test/tools/schema-best-practices.test.js +0 -194
- package/dist/test/test/tools/schema-best-practices.test.js.map +0 -1
- package/dist/test/test/tools/spans.test.d.ts +0 -2
- package/dist/test/test/tools/spans.test.d.ts.map +0 -1
- package/dist/test/test/tools/spans.test.js +0 -84
- package/dist/test/test/tools/spans.test.js.map +0 -1
- package/dist/test/test/viewer/broadcaster.test.d.ts +0 -2
- package/dist/test/test/viewer/broadcaster.test.d.ts.map +0 -1
- package/dist/test/test/viewer/broadcaster.test.js +0 -53
- package/dist/test/test/viewer/broadcaster.test.js.map +0 -1
- package/dist/test/test/viewer/cesdk-cdn.test.d.ts +0 -2
- package/dist/test/test/viewer/cesdk-cdn.test.d.ts.map +0 -1
- package/dist/test/test/viewer/cesdk-cdn.test.js +0 -19
- package/dist/test/test/viewer/cesdk-cdn.test.js.map +0 -1
- package/dist/test/test/viewer/config-route.test.d.ts +0 -2
- package/dist/test/test/viewer/config-route.test.d.ts.map +0 -1
- package/dist/test/test/viewer/config-route.test.js +0 -28
- package/dist/test/test/viewer/config-route.test.js.map +0 -1
- package/dist/test/test/viewer/resource-route.test.d.ts +0 -2
- package/dist/test/test/viewer/resource-route.test.d.ts.map +0 -1
- package/dist/test/test/viewer/resource-route.test.js +0 -70
- package/dist/test/test/viewer/resource-route.test.js.map +0 -1
- package/dist/test/test/viewer/router.test.d.ts +0 -2
- package/dist/test/test/viewer/router.test.d.ts.map +0 -1
- package/dist/test/test/viewer/router.test.js +0 -227
- package/dist/test/test/viewer/router.test.js.map +0 -1
- package/dist/test/test/viewer/session-mount.test.d.ts +0 -2
- package/dist/test/test/viewer/session-mount.test.d.ts.map +0 -1
- package/dist/test/test/viewer/session-mount.test.js +0 -52
- package/dist/test/test/viewer/session-mount.test.js.map +0 -1
- package/dist/test/test/viewer/spa-version.test.d.ts +0 -2
- package/dist/test/test/viewer/spa-version.test.d.ts.map +0 -1
- package/dist/test/test/viewer/spa-version.test.js +0 -14
- package/dist/test/test/viewer/spa-version.test.js.map +0 -1
- package/dist/test/test/viewer/url-builder.test.d.ts +0 -2
- package/dist/test/test/viewer/url-builder.test.d.ts.map +0 -1
- package/dist/test/test/viewer/url-builder.test.js +0 -98
- package/dist/test/test/viewer/url-builder.test.js.map +0 -1
- package/dist/test/test/workspace/content-hash.test.d.ts +0 -2
- package/dist/test/test/workspace/content-hash.test.d.ts.map +0 -1
- package/dist/test/test/workspace/content-hash.test.js +0 -17
- package/dist/test/test/workspace/content-hash.test.js.map +0 -1
- package/dist/test/test/workspace/hosted-stub.test.d.ts +0 -2
- package/dist/test/test/workspace/hosted-stub.test.d.ts.map +0 -1
- package/dist/test/test/workspace/hosted-stub.test.js +0 -30
- package/dist/test/test/workspace/hosted-stub.test.js.map +0 -1
- package/dist/test/test/workspace/in-memory.test.d.ts +0 -2
- package/dist/test/test/workspace/in-memory.test.d.ts.map +0 -1
- package/dist/test/test/workspace/in-memory.test.js +0 -4
- package/dist/test/test/workspace/in-memory.test.js.map +0 -1
- package/dist/test/test/workspace/node-fs.test.d.ts +0 -2
- package/dist/test/test/workspace/node-fs.test.d.ts.map +0 -1
- package/dist/test/test/workspace/node-fs.test.js +0 -20
- package/dist/test/test/workspace/node-fs.test.js.map +0 -1
- package/dist/test/test/workspace/s3.test.d.ts +0 -2
- package/dist/test/test/workspace/s3.test.d.ts.map +0 -1
- package/dist/test/test/workspace/s3.test.js +0 -153
- package/dist/test/test/workspace/s3.test.js.map +0 -1
- package/dist/test/test/workspace/scoped.test.d.ts +0 -2
- package/dist/test/test/workspace/scoped.test.d.ts.map +0 -1
- package/dist/test/test/workspace/scoped.test.js +0 -59
- package/dist/test/test/workspace/scoped.test.js.map +0 -1
- package/dist/test/test/workspace/shared-contract.d.ts +0 -3
- package/dist/test/test/workspace/shared-contract.d.ts.map +0 -1
- package/dist/test/test/workspace/shared-contract.js +0 -92
- package/dist/test/test/workspace/shared-contract.js.map +0 -1
- package/dist/test/tsconfig.test.tsbuildinfo +0 -1
- package/dist/test/vitest.config.d.ts +0 -3
- package/dist/test/vitest.config.d.ts.map +0 -1
- package/dist/test/vitest.config.js +0 -8
- package/dist/test/vitest.config.js.map +0 -1
- package/dist/tools/metrics.d.ts +0 -11
- package/dist/tools/metrics.d.ts.map +0 -1
- package/dist/tools/metrics.js +0 -28
- package/dist/tools/metrics.js.map +0 -1
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import { mkdtemp, rm, readFile, readdir, writeFile, stat, utimes } from 'node:fs/promises';
|
|
3
|
-
import { tmpdir } from 'node:os';
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
-
import { FileDiagnosticsSink } from '../../src/diagnostics/file-sink.js';
|
|
6
|
-
let dir;
|
|
7
|
-
beforeEach(async () => {
|
|
8
|
-
dir = await mkdtemp(join(tmpdir(), 'diag-'));
|
|
9
|
-
});
|
|
10
|
-
afterEach(async () => {
|
|
11
|
-
await rm(dir, { recursive: true, force: true });
|
|
12
|
-
});
|
|
13
|
-
const lifecycle = (text) => ({
|
|
14
|
-
kind: 'lifecycle',
|
|
15
|
-
timestamp: 1,
|
|
16
|
-
text
|
|
17
|
-
});
|
|
18
|
-
describe('FileDiagnosticsSink', () => {
|
|
19
|
-
it('appends one redacted NDJSON line per event', async () => {
|
|
20
|
-
const sink = new FileDiagnosticsSink({ dir });
|
|
21
|
-
sink.emit(lifecycle('boot'));
|
|
22
|
-
sink.emit({
|
|
23
|
-
kind: 'engine_log',
|
|
24
|
-
timestamp: 2,
|
|
25
|
-
level: 'warn',
|
|
26
|
-
text: 'key sk-ant-abcdefghijklmnopqrstuvwxyz01'
|
|
27
|
-
});
|
|
28
|
-
await sink.flush();
|
|
29
|
-
const body = await readFile(join(dir, 'diagnostics.ndjson'), 'utf8');
|
|
30
|
-
const lines = body.trimEnd().split('\n');
|
|
31
|
-
expect(lines).toHaveLength(2);
|
|
32
|
-
expect(JSON.parse(lines[0])).toMatchObject({
|
|
33
|
-
kind: 'lifecycle',
|
|
34
|
-
text: 'boot'
|
|
35
|
-
});
|
|
36
|
-
expect(body).not.toContain('sk-ant');
|
|
37
|
-
expect(body).toContain('[REDACTED]');
|
|
38
|
-
});
|
|
39
|
-
it('drops a .gitignore(*) on first write', async () => {
|
|
40
|
-
const sink = new FileDiagnosticsSink({ dir });
|
|
41
|
-
sink.emit(lifecycle('x'));
|
|
42
|
-
await sink.flush();
|
|
43
|
-
expect(await readFile(join(dir, '.gitignore'), 'utf8')).toContain('*');
|
|
44
|
-
});
|
|
45
|
-
it('rotates when the active file exceeds maxFileBytes and keeps last K', async () => {
|
|
46
|
-
const sink = new FileDiagnosticsSink({ dir, maxFileBytes: 200, keep: 2 });
|
|
47
|
-
for (let i = 0; i < 50; i++)
|
|
48
|
-
sink.emit(lifecycle(`event-number-${i}-padding-padding`));
|
|
49
|
-
await sink.flush();
|
|
50
|
-
const files = (await readdir(dir))
|
|
51
|
-
.filter((f) => f.startsWith('diagnostics'))
|
|
52
|
-
.sort();
|
|
53
|
-
// active + at most `keep` rotated
|
|
54
|
-
expect(files).toContain('diagnostics.ndjson');
|
|
55
|
-
expect(files.filter((f) => /^diagnostics\.\d+\.ndjson$/.test(f)).length).toBeLessThanOrEqual(2);
|
|
56
|
-
});
|
|
57
|
-
it('enforces the total-size budget on rotation (oldest first)', async () => {
|
|
58
|
-
const sink = new FileDiagnosticsSink({
|
|
59
|
-
dir,
|
|
60
|
-
maxFileBytes: 200,
|
|
61
|
-
keep: 10,
|
|
62
|
-
totalBudgetBytes: 600
|
|
63
|
-
});
|
|
64
|
-
for (let i = 0; i < 100; i++)
|
|
65
|
-
sink.emit(lifecycle(`event-number-${i}-padding-padding`));
|
|
66
|
-
await sink.flush();
|
|
67
|
-
const files = (await readdir(dir)).filter((f) => f.startsWith('diagnostics') && f.endsWith('.ndjson'));
|
|
68
|
-
let total = 0;
|
|
69
|
-
for (const f of files)
|
|
70
|
-
total += (await stat(join(dir, f))).size;
|
|
71
|
-
// budget is a ceiling on the ROTATED set; active file may exceed transiently
|
|
72
|
-
expect(total).toBeLessThanOrEqual(600 + 200);
|
|
73
|
-
});
|
|
74
|
-
it('pruneOnStartup deletes rotated files older than maxAgeMs', async () => {
|
|
75
|
-
const oldFile = join(dir, 'diagnostics.9.ndjson');
|
|
76
|
-
await writeFile(oldFile, 'stale\n');
|
|
77
|
-
const past = new Date(Date.now() - 40 * 24 * 60 * 60 * 1000);
|
|
78
|
-
await utimes(oldFile, past, past);
|
|
79
|
-
await writeFile(join(dir, 'diagnostics.ndjson'), 'active\n');
|
|
80
|
-
await FileDiagnosticsSink.pruneOnStartup({
|
|
81
|
-
dir,
|
|
82
|
-
maxAgeMs: 14 * 24 * 60 * 60 * 1000
|
|
83
|
-
});
|
|
84
|
-
const files = await readdir(dir);
|
|
85
|
-
expect(files).not.toContain('diagnostics.9.ndjson');
|
|
86
|
-
expect(files).toContain('diagnostics.ndjson');
|
|
87
|
-
});
|
|
88
|
-
it('swallows write errors (bad dir) without throwing to the caller', async () => {
|
|
89
|
-
const sink = new FileDiagnosticsSink({ dir: '/dev/null/nope' });
|
|
90
|
-
expect(() => sink.emit(lifecycle('x'))).not.toThrow();
|
|
91
|
-
await expect(sink.flush()).resolves.toBeUndefined();
|
|
92
|
-
});
|
|
93
|
-
it('writes a stub line (not the raw event) when redaction throws', async () => {
|
|
94
|
-
const sink = new FileDiagnosticsSink({ dir });
|
|
95
|
-
// A circular structure makes redactValue overflow the stack — a synchronous
|
|
96
|
-
// throw that emit() must catch and turn into a stub, never a raw write.
|
|
97
|
-
const circular = {
|
|
98
|
-
kind: 'lifecycle',
|
|
99
|
-
timestamp: 7,
|
|
100
|
-
text: 'x'
|
|
101
|
-
};
|
|
102
|
-
circular.self = circular;
|
|
103
|
-
expect(() => sink.emit(circular)).not.toThrow();
|
|
104
|
-
await sink.flush();
|
|
105
|
-
const body = await readFile(join(dir, 'diagnostics.ndjson'), 'utf8');
|
|
106
|
-
const line = JSON.parse(body.trim());
|
|
107
|
-
expect(line.redactionError).toBe(true);
|
|
108
|
-
expect(line.kind).toBe('lifecycle');
|
|
109
|
-
expect(line.timestamp).toBe(7);
|
|
110
|
-
expect(body).not.toContain('"self"'); // the raw circular payload never reached disk
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
//# sourceMappingURL=file-sink.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"file-sink.test.js","sourceRoot":"","sources":["../../../../test/diagnostics/file-sink.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect, beforeEach, afterEach } from 'vitest';\nimport {\n mkdtemp,\n rm,\n readFile,\n readdir,\n writeFile,\n stat,\n utimes\n} from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport type { DiagnosticEvent } from '../../src/diagnostics/events.js';\nimport { FileDiagnosticsSink } from '../../src/diagnostics/file-sink.js';\n\nlet dir: string;\nbeforeEach(async () => {\n dir = await mkdtemp(join(tmpdir(), 'diag-'));\n});\nafterEach(async () => {\n await rm(dir, { recursive: true, force: true });\n});\n\nconst lifecycle = (text: string): DiagnosticEvent => ({\n kind: 'lifecycle',\n timestamp: 1,\n text\n});\n\ndescribe('FileDiagnosticsSink', () => {\n it('appends one redacted NDJSON line per event', async () => {\n const sink = new FileDiagnosticsSink({ dir });\n sink.emit(lifecycle('boot'));\n sink.emit({\n kind: 'engine_log',\n timestamp: 2,\n level: 'warn',\n text: 'key sk-ant-abcdefghijklmnopqrstuvwxyz01'\n });\n await sink.flush();\n const body = await readFile(join(dir, 'diagnostics.ndjson'), 'utf8');\n const lines = body.trimEnd().split('\\n');\n expect(lines).toHaveLength(2);\n expect(JSON.parse(lines[0])).toMatchObject({\n kind: 'lifecycle',\n text: 'boot'\n });\n expect(body).not.toContain('sk-ant');\n expect(body).toContain('[REDACTED]');\n });\n\n it('drops a .gitignore(*) on first write', async () => {\n const sink = new FileDiagnosticsSink({ dir });\n sink.emit(lifecycle('x'));\n await sink.flush();\n expect(await readFile(join(dir, '.gitignore'), 'utf8')).toContain('*');\n });\n\n it('rotates when the active file exceeds maxFileBytes and keeps last K', async () => {\n const sink = new FileDiagnosticsSink({ dir, maxFileBytes: 200, keep: 2 });\n for (let i = 0; i < 50; i++)\n sink.emit(lifecycle(`event-number-${i}-padding-padding`));\n await sink.flush();\n const files = (await readdir(dir))\n .filter((f) => f.startsWith('diagnostics'))\n .sort();\n // active + at most `keep` rotated\n expect(files).toContain('diagnostics.ndjson');\n expect(\n files.filter((f) => /^diagnostics\\.\\d+\\.ndjson$/.test(f)).length\n ).toBeLessThanOrEqual(2);\n });\n\n it('enforces the total-size budget on rotation (oldest first)', async () => {\n const sink = new FileDiagnosticsSink({\n dir,\n maxFileBytes: 200,\n keep: 10,\n totalBudgetBytes: 600\n });\n for (let i = 0; i < 100; i++)\n sink.emit(lifecycle(`event-number-${i}-padding-padding`));\n await sink.flush();\n const files = (await readdir(dir)).filter(\n (f) => f.startsWith('diagnostics') && f.endsWith('.ndjson')\n );\n let total = 0;\n for (const f of files) total += (await stat(join(dir, f))).size;\n // budget is a ceiling on the ROTATED set; active file may exceed transiently\n expect(total).toBeLessThanOrEqual(600 + 200);\n });\n\n it('pruneOnStartup deletes rotated files older than maxAgeMs', async () => {\n const oldFile = join(dir, 'diagnostics.9.ndjson');\n await writeFile(oldFile, 'stale\\n');\n const past = new Date(Date.now() - 40 * 24 * 60 * 60 * 1000);\n await utimes(oldFile, past, past);\n await writeFile(join(dir, 'diagnostics.ndjson'), 'active\\n');\n await FileDiagnosticsSink.pruneOnStartup({\n dir,\n maxAgeMs: 14 * 24 * 60 * 60 * 1000\n });\n const files = await readdir(dir);\n expect(files).not.toContain('diagnostics.9.ndjson');\n expect(files).toContain('diagnostics.ndjson');\n });\n\n it('swallows write errors (bad dir) without throwing to the caller', async () => {\n const sink = new FileDiagnosticsSink({ dir: '/dev/null/nope' });\n expect(() => sink.emit(lifecycle('x'))).not.toThrow();\n await expect(sink.flush()).resolves.toBeUndefined();\n });\n\n it('writes a stub line (not the raw event) when redaction throws', async () => {\n const sink = new FileDiagnosticsSink({ dir });\n // A circular structure makes redactValue overflow the stack — a synchronous\n // throw that emit() must catch and turn into a stub, never a raw write.\n const circular: Record<string, unknown> = {\n kind: 'lifecycle',\n timestamp: 7,\n text: 'x'\n };\n circular.self = circular;\n expect(() =>\n sink.emit(circular as unknown as DiagnosticEvent)\n ).not.toThrow();\n await sink.flush();\n const body = await readFile(join(dir, 'diagnostics.ndjson'), 'utf8');\n const line = JSON.parse(body.trim());\n expect(line.redactionError).toBe(true);\n expect(line.kind).toBe('lifecycle');\n expect(line.timestamp).toBe(7);\n expect(body).not.toContain('\"self\"'); // the raw circular payload never reached disk\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"redact.test.d.ts","sourceRoot":"","sources":["../../../../test/diagnostics/redact.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { homedir } from 'node:os';
|
|
3
|
-
import { redactText, redactValue } from '../../src/diagnostics/redact.js';
|
|
4
|
-
describe('redactText', () => {
|
|
5
|
-
it('scrubs known secret patterns', () => {
|
|
6
|
-
const samples = [
|
|
7
|
-
'sk-or-v1-abcdefghijklmnopqrstuvwxyz0123',
|
|
8
|
-
'xai-abcdefghijklmnopqrstuvwxyz0123',
|
|
9
|
-
'AKIA1234567890ABCDEF',
|
|
10
|
-
'ghp_abcdefghijklmnopqrstuvwxyz0123456789',
|
|
11
|
-
'AIzaSyABCDEFGHIJKLMNOPQRSTUVWXYZ0123456'
|
|
12
|
-
];
|
|
13
|
-
for (const s of samples) {
|
|
14
|
-
expect(redactText(`token=${s} end`)).not.toContain(s);
|
|
15
|
-
expect(redactText(`token=${s} end`)).toContain('[REDACTED]');
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
it('replaces the home-dir prefix with ~', () => {
|
|
19
|
-
const p = `${homedir()}/.codesign/workspace/logs`;
|
|
20
|
-
expect(redactText(`path ${p}`)).toBe('path ~/.codesign/workspace/logs');
|
|
21
|
-
});
|
|
22
|
-
it('leaves ordinary text untouched', () => {
|
|
23
|
-
expect(redactText('engine loaded page 0')).toBe('engine loaded page 0');
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
describe('redactValue', () => {
|
|
27
|
-
it('drops values under secret-named keys (case-insensitive)', () => {
|
|
28
|
-
const out = redactValue({
|
|
29
|
-
License: 'anything',
|
|
30
|
-
apiKey: 'x',
|
|
31
|
-
Authorization: 'Bearer y',
|
|
32
|
-
nested: { token: 'z', keep: 'ok' }
|
|
33
|
-
});
|
|
34
|
-
expect(out.License).toBe('[REDACTED]');
|
|
35
|
-
expect(out.apiKey).toBe('[REDACTED]');
|
|
36
|
-
expect(out.Authorization).toBe('[REDACTED]');
|
|
37
|
-
expect(out.nested.token).toBe('[REDACTED]');
|
|
38
|
-
expect(out.nested.keep).toBe('ok');
|
|
39
|
-
});
|
|
40
|
-
it('scrubs secret patterns inside string values and arrays', () => {
|
|
41
|
-
const out = redactValue({
|
|
42
|
-
code: 'const k = "sk-ant-abcdefghijklmnopqrstuvwxyz0123";',
|
|
43
|
-
list: ['AKIA1234567890ABCDEF', 'fine']
|
|
44
|
-
});
|
|
45
|
-
expect(out.code).not.toContain('sk-ant');
|
|
46
|
-
expect(out.list[0]).toBe('[REDACTED]');
|
|
47
|
-
expect(out.list[1]).toBe('fine');
|
|
48
|
-
});
|
|
49
|
-
it('property: an injected secret never survives anywhere', () => {
|
|
50
|
-
const secret = 'sk-or-v1-DEADBEEFdeadbeef0123456789abcd';
|
|
51
|
-
const event = {
|
|
52
|
-
kind: 'tool_call',
|
|
53
|
-
args: { deep: [{ note: secret }] },
|
|
54
|
-
text: secret
|
|
55
|
-
};
|
|
56
|
-
expect(JSON.stringify(redactValue(event))).not.toContain(secret);
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
//# sourceMappingURL=redact.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"redact.test.js","sourceRoot":"","sources":["../../../../test/diagnostics/redact.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect } from 'vitest';\nimport { homedir } from 'node:os';\nimport { redactText, redactValue } from '../../src/diagnostics/redact.js';\n\ndescribe('redactText', () => {\n it('scrubs known secret patterns', () => {\n const samples = [\n 'sk-or-v1-abcdefghijklmnopqrstuvwxyz0123',\n 'xai-abcdefghijklmnopqrstuvwxyz0123',\n 'AKIA1234567890ABCDEF',\n 'ghp_abcdefghijklmnopqrstuvwxyz0123456789',\n 'AIzaSyABCDEFGHIJKLMNOPQRSTUVWXYZ0123456'\n ];\n for (const s of samples) {\n expect(redactText(`token=${s} end`)).not.toContain(s);\n expect(redactText(`token=${s} end`)).toContain('[REDACTED]');\n }\n });\n\n it('replaces the home-dir prefix with ~', () => {\n const p = `${homedir()}/.codesign/workspace/logs`;\n expect(redactText(`path ${p}`)).toBe('path ~/.codesign/workspace/logs');\n });\n\n it('leaves ordinary text untouched', () => {\n expect(redactText('engine loaded page 0')).toBe('engine loaded page 0');\n });\n});\n\ndescribe('redactValue', () => {\n it('drops values under secret-named keys (case-insensitive)', () => {\n const out = redactValue({\n License: 'anything',\n apiKey: 'x',\n Authorization: 'Bearer y',\n nested: { token: 'z', keep: 'ok' }\n }) as Record<string, unknown>;\n expect(out.License).toBe('[REDACTED]');\n expect(out.apiKey).toBe('[REDACTED]');\n expect(out.Authorization).toBe('[REDACTED]');\n expect((out.nested as Record<string, unknown>).token).toBe('[REDACTED]');\n expect((out.nested as Record<string, unknown>).keep).toBe('ok');\n });\n\n it('scrubs secret patterns inside string values and arrays', () => {\n const out = redactValue({\n code: 'const k = \"sk-ant-abcdefghijklmnopqrstuvwxyz0123\";',\n list: ['AKIA1234567890ABCDEF', 'fine']\n }) as Record<string, unknown>;\n expect(out.code).not.toContain('sk-ant');\n expect((out.list as string[])[0]).toBe('[REDACTED]');\n expect((out.list as string[])[1]).toBe('fine');\n });\n\n it('property: an injected secret never survives anywhere', () => {\n const secret = 'sk-or-v1-DEADBEEFdeadbeef0123456789abcd';\n const event = {\n kind: 'tool_call',\n args: { deep: [{ note: secret }] },\n text: secret\n };\n expect(JSON.stringify(redactValue(event))).not.toContain(secret);\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-call-adapter.test.d.ts","sourceRoot":"","sources":["../../../../test/diagnostics/tool-call-adapter.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { toolCallSink } from '../../src/diagnostics/tool-call-adapter.js';
|
|
3
|
-
function capture() {
|
|
4
|
-
const events = [];
|
|
5
|
-
return { events, emit: (e) => events.push(e) };
|
|
6
|
-
}
|
|
7
|
-
describe('toolCallSink', () => {
|
|
8
|
-
it('wraps a ToolCallReport into a stamped tool_call event', () => {
|
|
9
|
-
const sink = capture();
|
|
10
|
-
const telemetry = toolCallSink(sink, () => 123);
|
|
11
|
-
const report = {
|
|
12
|
-
tool: 'edit',
|
|
13
|
-
succeeded: true,
|
|
14
|
-
totalMs: 12,
|
|
15
|
-
spans: [{ phase: 'engine_execute', ms: 8 }],
|
|
16
|
-
revision: 'abc',
|
|
17
|
-
args: { parent: null }
|
|
18
|
-
};
|
|
19
|
-
telemetry.record(report);
|
|
20
|
-
expect(sink.events).toEqual([
|
|
21
|
-
{
|
|
22
|
-
kind: 'tool_call',
|
|
23
|
-
timestamp: 123,
|
|
24
|
-
tool: 'edit',
|
|
25
|
-
succeeded: true,
|
|
26
|
-
totalMs: 12,
|
|
27
|
-
spans: [{ phase: 'engine_execute', ms: 8 }],
|
|
28
|
-
revision: 'abc',
|
|
29
|
-
args: { parent: null }
|
|
30
|
-
}
|
|
31
|
-
]);
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
//# sourceMappingURL=tool-call-adapter.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-call-adapter.test.js","sourceRoot":"","sources":["../../../../test/diagnostics/tool-call-adapter.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAK9C,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAG1E,SAAS,OAAO;IACd,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AACjD,CAAC;AAED,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QAChD,MAAM,MAAM,GAAmB;YAC7B,IAAI,EAAE,MAAM;YACZ,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,EAAE;YACX,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;YAC3C,QAAQ,EAAE,KAAK;YACf,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;SACvB,CAAC;QACF,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YAC1B;gBACE,IAAI,EAAE,WAAW;gBACjB,SAAS,EAAE,GAAG;gBACd,IAAI,EAAE,MAAM;gBACZ,SAAS,EAAE,IAAI;gBACf,OAAO,EAAE,EAAE;gBACX,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;gBAC3C,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;aACvB;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, it, expect } from 'vitest';\nimport type {\n DiagnosticEvent,\n DiagnosticsSink\n} from '../../src/diagnostics/events.js';\nimport { toolCallSink } from '../../src/diagnostics/tool-call-adapter.js';\nimport type { ToolCallReport } from '../../src/tools/spans.js';\n\nfunction capture(): DiagnosticsSink & { events: DiagnosticEvent[] } {\n const events: DiagnosticEvent[] = [];\n return { events, emit: (e) => events.push(e) };\n}\n\ndescribe('toolCallSink', () => {\n it('wraps a ToolCallReport into a stamped tool_call event', () => {\n const sink = capture();\n const telemetry = toolCallSink(sink, () => 123);\n const report: ToolCallReport = {\n tool: 'edit',\n succeeded: true,\n totalMs: 12,\n spans: [{ phase: 'engine_execute', ms: 8 }],\n revision: 'abc',\n args: { parent: null }\n };\n telemetry.record(report);\n expect(sink.events).toEqual([\n {\n kind: 'tool_call',\n timestamp: 123,\n tool: 'edit',\n succeeded: true,\n totalMs: 12,\n spans: [{ phase: 'engine_execute', ms: 8 }],\n revision: 'abc',\n args: { parent: null }\n }\n ]);\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"asset-sources.test.d.ts","sourceRoot":"","sources":["../../../../test/engine/asset-sources.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { ensureEngineAssetSources, resetEngineAssetSourcesForTest } from '../../src/engine/asset-sources.js';
|
|
3
|
-
function makeEngine(existingSources) {
|
|
4
|
-
return {
|
|
5
|
-
asset: { findAllSources: vi.fn(() => existingSources) },
|
|
6
|
-
addDefaultAssetSources: vi.fn(async () => { }),
|
|
7
|
-
addDemoAssetSources: vi.fn(async () => { })
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
describe('ensureEngineAssetSources', () => {
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
resetEngineAssetSourcesForTest();
|
|
13
|
-
});
|
|
14
|
-
it('registers default + demo sources on a fresh engine', async () => {
|
|
15
|
-
const engine = makeEngine([]);
|
|
16
|
-
await ensureEngineAssetSources(engine);
|
|
17
|
-
expect(engine.addDefaultAssetSources).toHaveBeenCalledOnce();
|
|
18
|
-
expect(engine.addDefaultAssetSources).toHaveBeenCalledWith({
|
|
19
|
-
baseURL: 'https://cdn.img.ly/assets/v3',
|
|
20
|
-
excludeAssetSourceIds: ['ly.img.text']
|
|
21
|
-
});
|
|
22
|
-
expect(engine.addDemoAssetSources).toHaveBeenCalledOnce();
|
|
23
|
-
expect(engine.addDemoAssetSources).toHaveBeenCalledWith({
|
|
24
|
-
baseURL: 'https://cdn.img.ly/assets/demo/v3'
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
it('honours self-hosted manifest roots from the environment', async () => {
|
|
28
|
-
vi.stubEnv('IMGLY_DEFAULT_ASSETS_BASE_URL', 'https://assets.example.com/v3');
|
|
29
|
-
vi.stubEnv('IMGLY_DEMO_ASSETS_BASE_URL', 'https://assets.example.com/demo/v3');
|
|
30
|
-
try {
|
|
31
|
-
const engine = makeEngine([]);
|
|
32
|
-
await ensureEngineAssetSources(engine);
|
|
33
|
-
expect(engine.addDefaultAssetSources).toHaveBeenCalledWith({
|
|
34
|
-
baseURL: 'https://assets.example.com/v3',
|
|
35
|
-
excludeAssetSourceIds: ['ly.img.text']
|
|
36
|
-
});
|
|
37
|
-
expect(engine.addDemoAssetSources).toHaveBeenCalledWith({
|
|
38
|
-
baseURL: 'https://assets.example.com/demo/v3'
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
finally {
|
|
42
|
-
vi.unstubAllEnvs();
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
it('skips registration when the demo image source is already present', async () => {
|
|
46
|
-
const engine = makeEngine(['ly.img.image']);
|
|
47
|
-
await ensureEngineAssetSources(engine);
|
|
48
|
-
expect(engine.addDefaultAssetSources).not.toHaveBeenCalled();
|
|
49
|
-
expect(engine.addDemoAssetSources).not.toHaveBeenCalled();
|
|
50
|
-
});
|
|
51
|
-
it('swallows CDN failures (best-effort) without throwing', async () => {
|
|
52
|
-
const stderrSpy = vi
|
|
53
|
-
.spyOn(process.stderr, 'write')
|
|
54
|
-
.mockImplementation(() => true);
|
|
55
|
-
const engine = makeEngine([]);
|
|
56
|
-
engine.addDefaultAssetSources.mockRejectedValueOnce(new Error('offline'));
|
|
57
|
-
await expect(ensureEngineAssetSources(engine)).resolves.toBeUndefined();
|
|
58
|
-
expect(stderrSpy.mock.calls[0][0]).toContain('asset_search will see fewer sources');
|
|
59
|
-
stderrSpy.mockRestore();
|
|
60
|
-
});
|
|
61
|
-
it('concurrent calls share one in-flight registration', async () => {
|
|
62
|
-
const engine = makeEngine([]);
|
|
63
|
-
const p1 = ensureEngineAssetSources(engine);
|
|
64
|
-
const p2 = ensureEngineAssetSources(engine);
|
|
65
|
-
await Promise.all([p1, p2]);
|
|
66
|
-
expect(engine.addDefaultAssetSources).toHaveBeenCalledOnce();
|
|
67
|
-
});
|
|
68
|
-
it('total failure (sentinel absent) clears the guard so the next call retries', async () => {
|
|
69
|
-
const stderrSpy = vi
|
|
70
|
-
.spyOn(process.stderr, 'write')
|
|
71
|
-
.mockImplementation(() => true);
|
|
72
|
-
const engine = makeEngine([]);
|
|
73
|
-
engine.addDefaultAssetSources.mockRejectedValueOnce(new Error('offline'));
|
|
74
|
-
await ensureEngineAssetSources(engine);
|
|
75
|
-
await ensureEngineAssetSources(engine);
|
|
76
|
-
expect(engine.addDefaultAssetSources).toHaveBeenCalledTimes(2);
|
|
77
|
-
stderrSpy.mockRestore();
|
|
78
|
-
});
|
|
79
|
-
it('keeps the guard when demo sources land despite default-source failure', async () => {
|
|
80
|
-
const stderrSpy = vi
|
|
81
|
-
.spyOn(process.stderr, 'write')
|
|
82
|
-
.mockImplementation(() => true);
|
|
83
|
-
const sources = [];
|
|
84
|
-
const engine = {
|
|
85
|
-
asset: { findAllSources: vi.fn(() => [...sources]) },
|
|
86
|
-
addDefaultAssetSources: vi.fn(async () => {
|
|
87
|
-
throw new Error('ENOENT');
|
|
88
|
-
}),
|
|
89
|
-
addDemoAssetSources: vi.fn(async () => {
|
|
90
|
-
sources.push('ly.img.image');
|
|
91
|
-
})
|
|
92
|
-
};
|
|
93
|
-
await ensureEngineAssetSources(engine);
|
|
94
|
-
await ensureEngineAssetSources(engine);
|
|
95
|
-
expect(engine.addDefaultAssetSources).toHaveBeenCalledOnce();
|
|
96
|
-
expect(engine.addDemoAssetSources).toHaveBeenCalledOnce();
|
|
97
|
-
stderrSpy.mockRestore();
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
//# sourceMappingURL=asset-sources.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"asset-sources.test.js","sourceRoot":"","sources":["../../../../test/engine/asset-sources.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { beforeEach, describe, expect, it, vi } from 'vitest';\nimport {\n ensureEngineAssetSources,\n resetEngineAssetSourcesForTest\n} from '../../src/engine/asset-sources.js';\n\nfunction makeEngine(existingSources: string[]) {\n return {\n asset: { findAllSources: vi.fn(() => existingSources) },\n addDefaultAssetSources: vi.fn(async () => {}),\n addDemoAssetSources: vi.fn(async () => {})\n };\n}\n\ndescribe('ensureEngineAssetSources', () => {\n beforeEach(() => {\n resetEngineAssetSourcesForTest();\n });\n\n it('registers default + demo sources on a fresh engine', async () => {\n const engine = makeEngine([]);\n await ensureEngineAssetSources(engine);\n expect(engine.addDefaultAssetSources).toHaveBeenCalledOnce();\n expect(engine.addDefaultAssetSources).toHaveBeenCalledWith({\n baseURL: 'https://cdn.img.ly/assets/v3',\n excludeAssetSourceIds: ['ly.img.text']\n });\n expect(engine.addDemoAssetSources).toHaveBeenCalledOnce();\n expect(engine.addDemoAssetSources).toHaveBeenCalledWith({\n baseURL: 'https://cdn.img.ly/assets/demo/v3'\n });\n });\n\n it('honours self-hosted manifest roots from the environment', async () => {\n vi.stubEnv(\n 'IMGLY_DEFAULT_ASSETS_BASE_URL',\n 'https://assets.example.com/v3'\n );\n vi.stubEnv(\n 'IMGLY_DEMO_ASSETS_BASE_URL',\n 'https://assets.example.com/demo/v3'\n );\n try {\n const engine = makeEngine([]);\n await ensureEngineAssetSources(engine);\n expect(engine.addDefaultAssetSources).toHaveBeenCalledWith({\n baseURL: 'https://assets.example.com/v3',\n excludeAssetSourceIds: ['ly.img.text']\n });\n expect(engine.addDemoAssetSources).toHaveBeenCalledWith({\n baseURL: 'https://assets.example.com/demo/v3'\n });\n } finally {\n vi.unstubAllEnvs();\n }\n });\n\n it('skips registration when the demo image source is already present', async () => {\n const engine = makeEngine(['ly.img.image']);\n await ensureEngineAssetSources(engine);\n expect(engine.addDefaultAssetSources).not.toHaveBeenCalled();\n expect(engine.addDemoAssetSources).not.toHaveBeenCalled();\n });\n\n it('swallows CDN failures (best-effort) without throwing', async () => {\n const stderrSpy = vi\n .spyOn(process.stderr, 'write')\n .mockImplementation(() => true);\n const engine = makeEngine([]);\n engine.addDefaultAssetSources.mockRejectedValueOnce(new Error('offline'));\n await expect(ensureEngineAssetSources(engine)).resolves.toBeUndefined();\n expect(stderrSpy.mock.calls[0][0]).toContain(\n 'asset_search will see fewer sources'\n );\n stderrSpy.mockRestore();\n });\n\n it('concurrent calls share one in-flight registration', async () => {\n const engine = makeEngine([]);\n const p1 = ensureEngineAssetSources(engine);\n const p2 = ensureEngineAssetSources(engine);\n await Promise.all([p1, p2]);\n expect(engine.addDefaultAssetSources).toHaveBeenCalledOnce();\n });\n\n it('total failure (sentinel absent) clears the guard so the next call retries', async () => {\n const stderrSpy = vi\n .spyOn(process.stderr, 'write')\n .mockImplementation(() => true);\n const engine = makeEngine([]);\n engine.addDefaultAssetSources.mockRejectedValueOnce(new Error('offline'));\n await ensureEngineAssetSources(engine);\n await ensureEngineAssetSources(engine);\n expect(engine.addDefaultAssetSources).toHaveBeenCalledTimes(2);\n stderrSpy.mockRestore();\n });\n\n it('keeps the guard when demo sources land despite default-source failure', async () => {\n const stderrSpy = vi\n .spyOn(process.stderr, 'write')\n .mockImplementation(() => true);\n const sources: string[] = [];\n const engine = {\n asset: { findAllSources: vi.fn(() => [...sources]) },\n addDefaultAssetSources: vi.fn(async () => {\n throw new Error('ENOENT');\n }),\n addDemoAssetSources: vi.fn(async () => {\n sources.push('ly.img.image');\n })\n };\n await ensureEngineAssetSources(engine);\n await ensureEngineAssetSources(engine);\n expect(engine.addDefaultAssetSources).toHaveBeenCalledOnce();\n expect(engine.addDemoAssetSources).toHaveBeenCalledOnce();\n stderrSpy.mockRestore();\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cesdk-adapter.test.d.ts","sourceRoot":"","sources":["../../../../test/engine/cesdk-adapter.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { cesdkAdapter } from '../../src/engine/cesdk-adapter.js';
|
|
3
|
-
import { SCENE_ALLOWED_RESOURCE_SCHEMES } from '../../src/engine/scene-resource-schemes.js';
|
|
4
|
-
// Regression guard: a scene that references an imported/generated/loaded asset
|
|
5
|
-
// stores a durable `workspace://` URI. CE.SDK's default saveToString schemes
|
|
6
|
-
// omit `workspace`, so committing such a scene used to fail with "disallowed
|
|
7
|
-
// schemes: workspace". The adapter must opt the scheme in via the shared
|
|
8
|
-
// allowlist. (Caught only here — edit's own tests use a fake adapter that
|
|
9
|
-
// skips scheme validation.)
|
|
10
|
-
describe('cesdkAdapter.saveToString', () => {
|
|
11
|
-
it('passes the shared scheme allowlist (workspace in, buffer out)', async () => {
|
|
12
|
-
const fake = {
|
|
13
|
-
scene: {
|
|
14
|
-
create: vi.fn(),
|
|
15
|
-
loadFromString: vi.fn(async () => 1),
|
|
16
|
-
saveToString: vi.fn(async () => 'S')
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
const result = await cesdkAdapter(fake).saveToString(fake);
|
|
20
|
-
expect(result).toBe('S');
|
|
21
|
-
expect(fake.scene.saveToString).toHaveBeenCalledWith({
|
|
22
|
-
allowedResourceSchemes: SCENE_ALLOWED_RESOURCE_SCHEMES
|
|
23
|
-
});
|
|
24
|
-
expect(SCENE_ALLOWED_RESOURCE_SCHEMES).toContain('workspace');
|
|
25
|
-
expect(SCENE_ALLOWED_RESOURCE_SCHEMES).not.toContain('buffer');
|
|
26
|
-
// Still allows CE.SDK's own defaults (didn't narrow the list).
|
|
27
|
-
for (const scheme of ['blob', 'bundle', 'file', 'http', 'https', 'opfs']) {
|
|
28
|
-
expect(SCENE_ALLOWED_RESOURCE_SCHEMES).toContain(scheme);
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
//# sourceMappingURL=cesdk-adapter.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cesdk-adapter.test.js","sourceRoot":"","sources":["../../../../test/engine/cesdk-adapter.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,8BAA8B,EAAE,MAAM,4CAA4C,CAAC;AAE5F,+EAA+E;AAC/E,6EAA6E;AAC7E,6EAA6E;AAC7E,yEAAyE;AACzE,0EAA0E;AAC1E,4BAA4B;AAC5B,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,IAAI,GAAG;YACX,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE;gBACf,cAAc,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;gBACpC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,CAAC;aACrC;SAC2B,CAAC;QAE/B,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAE3D,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,oBAAoB,CAAC;YACnD,sBAAsB,EAAE,8BAA8B;SACvD,CAAC,CAAC;QACH,MAAM,CAAC,8BAA8B,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC9D,MAAM,CAAC,8BAA8B,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC/D,+DAA+D;QAC/D,KAAK,MAAM,MAAM,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;YACzE,MAAM,CAAC,8BAA8B,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import type CreativeEngine from '@cesdk/engine';\nimport { describe, expect, it, vi } from 'vitest';\nimport { cesdkAdapter } from '../../src/engine/cesdk-adapter.js';\nimport { SCENE_ALLOWED_RESOURCE_SCHEMES } from '../../src/engine/scene-resource-schemes.js';\n\n// Regression guard: a scene that references an imported/generated/loaded asset\n// stores a durable `workspace://` URI. CE.SDK's default saveToString schemes\n// omit `workspace`, so committing such a scene used to fail with \"disallowed\n// schemes: workspace\". The adapter must opt the scheme in via the shared\n// allowlist. (Caught only here — edit's own tests use a fake adapter that\n// skips scheme validation.)\ndescribe('cesdkAdapter.saveToString', () => {\n it('passes the shared scheme allowlist (workspace in, buffer out)', async () => {\n const fake = {\n scene: {\n create: vi.fn(),\n loadFromString: vi.fn(async () => 1),\n saveToString: vi.fn(async () => 'S')\n }\n } as unknown as CreativeEngine;\n\n const result = await cesdkAdapter(fake).saveToString(fake);\n\n expect(result).toBe('S');\n expect(fake.scene.saveToString).toHaveBeenCalledWith({\n allowedResourceSchemes: SCENE_ALLOWED_RESOURCE_SCHEMES\n });\n expect(SCENE_ALLOWED_RESOURCE_SCHEMES).toContain('workspace');\n expect(SCENE_ALLOWED_RESOURCE_SCHEMES).not.toContain('buffer');\n // Still allows CE.SDK's own defaults (didn't narrow the list).\n for (const scheme of ['blob', 'bundle', 'file', 'http', 'https', 'opfs']) {\n expect(SCENE_ALLOWED_RESOURCE_SCHEMES).toContain(scheme);\n }\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mutex.test.d.ts","sourceRoot":"","sources":["../../../../test/engine/mutex.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { Mutex } from '../../src/engine/mutex.js';
|
|
3
|
-
const tick = (ms = 0) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
4
|
-
describe('Mutex', () => {
|
|
5
|
-
it('runs sections one at a time — never two in their critical region at once', async () => {
|
|
6
|
-
const mutex = new Mutex();
|
|
7
|
-
let active = 0;
|
|
8
|
-
let maxActive = 0;
|
|
9
|
-
const section = async () => {
|
|
10
|
-
active++;
|
|
11
|
-
maxActive = Math.max(maxActive, active);
|
|
12
|
-
await tick(5); // hold the section open across an await
|
|
13
|
-
active--;
|
|
14
|
-
};
|
|
15
|
-
await Promise.all([
|
|
16
|
-
mutex.runExclusive(section),
|
|
17
|
-
mutex.runExclusive(section),
|
|
18
|
-
mutex.runExclusive(section),
|
|
19
|
-
mutex.runExclusive(section)
|
|
20
|
-
]);
|
|
21
|
-
expect(maxActive).toBe(1);
|
|
22
|
-
expect(active).toBe(0);
|
|
23
|
-
});
|
|
24
|
-
it('preserves FIFO order', async () => {
|
|
25
|
-
const mutex = new Mutex();
|
|
26
|
-
const order = [];
|
|
27
|
-
await Promise.all([0, 1, 2, 3].map((i) => mutex.runExclusive(async () => {
|
|
28
|
-
await tick(1);
|
|
29
|
-
order.push(i);
|
|
30
|
-
})));
|
|
31
|
-
expect(order).toEqual([0, 1, 2, 3]);
|
|
32
|
-
});
|
|
33
|
-
it('returns the section result to its caller', async () => {
|
|
34
|
-
const mutex = new Mutex();
|
|
35
|
-
await expect(mutex.runExclusive(async () => 42)).resolves.toBe(42);
|
|
36
|
-
});
|
|
37
|
-
it('a throwing section rejects its caller but does not wedge the queue', async () => {
|
|
38
|
-
const mutex = new Mutex();
|
|
39
|
-
const boom = mutex.runExclusive(async () => {
|
|
40
|
-
throw new Error('boom');
|
|
41
|
-
});
|
|
42
|
-
await expect(boom).rejects.toThrow('boom');
|
|
43
|
-
// The next section must still run after a rejection.
|
|
44
|
-
await expect(mutex.runExclusive(async () => 'ok')).resolves.toBe('ok');
|
|
45
|
-
});
|
|
46
|
-
it('stays mutually exclusive under heavy interleaving (multiple yields per section)', async () => {
|
|
47
|
-
const mutex = new Mutex();
|
|
48
|
-
let active = 0;
|
|
49
|
-
let maxActive = 0;
|
|
50
|
-
const section = async () => {
|
|
51
|
-
active++;
|
|
52
|
-
maxActive = Math.max(maxActive, active);
|
|
53
|
-
await tick(0);
|
|
54
|
-
await Promise.resolve();
|
|
55
|
-
await tick(0);
|
|
56
|
-
active--;
|
|
57
|
-
};
|
|
58
|
-
await Promise.all(Array.from({ length: 12 }, () => mutex.runExclusive(section)));
|
|
59
|
-
expect(maxActive).toBe(1);
|
|
60
|
-
expect(active).toBe(0);
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
//# sourceMappingURL=mutex.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mutex.test.js","sourceRoot":"","sources":["../../../../test/engine/mutex.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it } from 'vitest';\nimport { Mutex } from '../../src/engine/mutex.js';\n\nconst tick = (ms = 0): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\ndescribe('Mutex', () => {\n it('runs sections one at a time — never two in their critical region at once', async () => {\n const mutex = new Mutex();\n let active = 0;\n let maxActive = 0;\n const section = async () => {\n active++;\n maxActive = Math.max(maxActive, active);\n await tick(5); // hold the section open across an await\n active--;\n };\n await Promise.all([\n mutex.runExclusive(section),\n mutex.runExclusive(section),\n mutex.runExclusive(section),\n mutex.runExclusive(section)\n ]);\n expect(maxActive).toBe(1);\n expect(active).toBe(0);\n });\n\n it('preserves FIFO order', async () => {\n const mutex = new Mutex();\n const order: number[] = [];\n await Promise.all(\n [0, 1, 2, 3].map((i) =>\n mutex.runExclusive(async () => {\n await tick(1);\n order.push(i);\n })\n )\n );\n expect(order).toEqual([0, 1, 2, 3]);\n });\n\n it('returns the section result to its caller', async () => {\n const mutex = new Mutex();\n await expect(mutex.runExclusive(async () => 42)).resolves.toBe(42);\n });\n\n it('a throwing section rejects its caller but does not wedge the queue', async () => {\n const mutex = new Mutex();\n const boom = mutex.runExclusive(async () => {\n throw new Error('boom');\n });\n await expect(boom).rejects.toThrow('boom');\n // The next section must still run after a rejection.\n await expect(mutex.runExclusive(async () => 'ok')).resolves.toBe('ok');\n });\n\n it('stays mutually exclusive under heavy interleaving (multiple yields per section)', async () => {\n const mutex = new Mutex();\n let active = 0;\n let maxActive = 0;\n const section = async () => {\n active++;\n maxActive = Math.max(maxActive, active);\n await tick(0);\n await Promise.resolve();\n await tick(0);\n active--;\n };\n await Promise.all(\n Array.from({ length: 12 }, () => mutex.runExclusive(section))\n );\n expect(maxActive).toBe(1);\n expect(active).toBe(0);\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session.test.d.ts","sourceRoot":"","sources":["../../../../test/engine/session.test.ts"],"names":[],"mappings":""}
|