@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,159 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { EngineSession } from '../../src/engine/session.js';
|
|
3
|
-
function makeFakeEngine(scene = 'INITIAL') {
|
|
4
|
-
const engine = { _scene: scene };
|
|
5
|
-
const adapter = {
|
|
6
|
-
create: () => engine,
|
|
7
|
-
reset: vi.fn(async () => {
|
|
8
|
-
engine._scene = 'RESET';
|
|
9
|
-
}),
|
|
10
|
-
loadFromString: vi.fn(async (eng, s) => {
|
|
11
|
-
eng._scene = s;
|
|
12
|
-
}),
|
|
13
|
-
saveToString: vi.fn(async (eng) => eng._scene)
|
|
14
|
-
};
|
|
15
|
-
return { engine, adapter };
|
|
16
|
-
}
|
|
17
|
-
describe('EngineSession (single slot)', () => {
|
|
18
|
-
it('acquire(parent=null) resets the engine and sets currentRevision=null', async () => {
|
|
19
|
-
const { adapter } = makeFakeEngine();
|
|
20
|
-
const session = new EngineSession({ size: 1, adapter });
|
|
21
|
-
const slot = await session.acquire(null);
|
|
22
|
-
expect(adapter.reset).toHaveBeenCalledOnce();
|
|
23
|
-
expect(slot.currentRevision).toBeNull();
|
|
24
|
-
});
|
|
25
|
-
it('acquire(parent=X) loads scene X when slot currentRevision is different', async () => {
|
|
26
|
-
const { adapter } = makeFakeEngine();
|
|
27
|
-
const session = new EngineSession({ size: 1, adapter });
|
|
28
|
-
await session.populate('rev_abc', 'SCENE_ABC'); // pre-stage the loadable scene
|
|
29
|
-
const slot = await session.acquire('rev_abc');
|
|
30
|
-
expect(adapter.loadFromString).toHaveBeenCalledWith(slot.engine, 'SCENE_ABC');
|
|
31
|
-
expect(slot.currentRevision).toBe('rev_abc');
|
|
32
|
-
});
|
|
33
|
-
it('acquire(parent=X) is a no-op when slot.currentRevision === X (linear edit)', async () => {
|
|
34
|
-
const { adapter } = makeFakeEngine();
|
|
35
|
-
const session = new EngineSession({ size: 1, adapter });
|
|
36
|
-
await session.populate('rev_abc', 'SCENE_ABC');
|
|
37
|
-
await session.acquire('rev_abc');
|
|
38
|
-
adapter.loadFromString.mockClear();
|
|
39
|
-
const slot2 = await session.acquire('rev_abc');
|
|
40
|
-
expect(adapter.loadFromString).not.toHaveBeenCalled();
|
|
41
|
-
expect(slot2.currentRevision).toBe('rev_abc');
|
|
42
|
-
});
|
|
43
|
-
it('commit(slot, newRev) updates currentRevision (linear edit succeeded)', async () => {
|
|
44
|
-
const { adapter } = makeFakeEngine();
|
|
45
|
-
const session = new EngineSession({ size: 1, adapter });
|
|
46
|
-
const slot = await session.acquire(null);
|
|
47
|
-
session.commit(slot, 'rev_new');
|
|
48
|
-
expect(slot.currentRevision).toBe('rev_new');
|
|
49
|
-
});
|
|
50
|
-
it('markDirty(slot) sets currentRevision=null (failed edit forces reload next time)', async () => {
|
|
51
|
-
const { adapter } = makeFakeEngine();
|
|
52
|
-
const session = new EngineSession({ size: 1, adapter });
|
|
53
|
-
await session.populate('rev_abc', 'SCENE_ABC');
|
|
54
|
-
const slot = await session.acquire('rev_abc');
|
|
55
|
-
session.markDirty(slot);
|
|
56
|
-
expect(slot.currentRevision).toBeNull();
|
|
57
|
-
// next acquire even of the SAME parent must reload
|
|
58
|
-
await session.populate('rev_abc', 'SCENE_ABC');
|
|
59
|
-
const slot2 = await session.acquire('rev_abc');
|
|
60
|
-
expect(adapter.loadFromString).toHaveBeenCalledTimes(2);
|
|
61
|
-
expect(slot2.currentRevision).toBe('rev_abc');
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
describe('EngineSession cold-instance reconstruction (spec §8.6)', () => {
|
|
65
|
-
it('reconstructs a cold engine by loading a staged revision scene', async () => {
|
|
66
|
-
// Regression guard: a cold session (no warm slot) must load the staged
|
|
67
|
-
// scene via loadFromString before returning the slot. This documents the
|
|
68
|
-
// edit-tool contract: populate(parent, scene) → acquire(parent) always
|
|
69
|
-
// calls loadFromString, never assumes a warm engine.
|
|
70
|
-
const { adapter } = makeFakeEngine();
|
|
71
|
-
const session = new EngineSession({ size: 1, adapter });
|
|
72
|
-
// Cold: no slots exist yet, so no warm engine.
|
|
73
|
-
await session.populate('rev-1', '<scene-for-rev-1/>');
|
|
74
|
-
const slot = await session.acquire('rev-1');
|
|
75
|
-
expect(adapter.loadFromString).toHaveBeenCalledWith(slot.engine, '<scene-for-rev-1/>');
|
|
76
|
-
expect(slot.currentRevision).toBe('rev-1');
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
describe('EngineSession (multi-slot sticky routing)', () => {
|
|
80
|
-
function makeAdapterWithCounter() {
|
|
81
|
-
let id = 0;
|
|
82
|
-
const counters = { creates: 0 };
|
|
83
|
-
const adapter = {
|
|
84
|
-
create: () => {
|
|
85
|
-
counters.creates++;
|
|
86
|
-
return { _id: id++, _scene: 'INITIAL' };
|
|
87
|
-
},
|
|
88
|
-
reset: async (eng) => {
|
|
89
|
-
eng._scene = 'RESET';
|
|
90
|
-
},
|
|
91
|
-
loadFromString: async (eng, s) => {
|
|
92
|
-
eng._scene = s;
|
|
93
|
-
},
|
|
94
|
-
saveToString: async (eng) => eng._scene
|
|
95
|
-
};
|
|
96
|
-
return { adapter, createCount: () => counters.creates };
|
|
97
|
-
}
|
|
98
|
-
it('returns warm slot whose currentRevision matches the requested parent', async () => {
|
|
99
|
-
const { adapter, createCount } = makeAdapterWithCounter();
|
|
100
|
-
const session = new EngineSession({ size: 2, adapter });
|
|
101
|
-
await session.populate('rev_A', 'SCENE_A');
|
|
102
|
-
const slotA = await session.acquire('rev_A');
|
|
103
|
-
session.commit(slotA, 'rev_A2');
|
|
104
|
-
await session.populate('rev_B', 'SCENE_B');
|
|
105
|
-
const slotB = await session.acquire('rev_B');
|
|
106
|
-
session.commit(slotB, 'rev_B2');
|
|
107
|
-
expect(createCount()).toBe(2);
|
|
108
|
-
// Sticky: re-acquire rev_A2 → reuse slotA, no new create, no reload.
|
|
109
|
-
const reuse = await session.acquire('rev_A2');
|
|
110
|
-
expect(reuse.engine).toBe(slotA.engine);
|
|
111
|
-
expect(createCount()).toBe(2);
|
|
112
|
-
});
|
|
113
|
-
it('evicts a dirty slot before a warm slot when over cap', async () => {
|
|
114
|
-
const { adapter } = makeAdapterWithCounter();
|
|
115
|
-
const session = new EngineSession({ size: 1, adapter });
|
|
116
|
-
const slot1 = await session.acquire(null);
|
|
117
|
-
session.commit(slot1, 'rev_X');
|
|
118
|
-
session.markDirty(slot1);
|
|
119
|
-
await session.populate('rev_Y', 'SCENE_Y');
|
|
120
|
-
const slot2 = await session.acquire('rev_Y');
|
|
121
|
-
expect(slot2).toBe(slot1); // reused
|
|
122
|
-
expect(slot2.currentRevision).toBe('rev_Y');
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
describe('EngineSession.currentSlot', () => {
|
|
126
|
-
it('returns undefined when no slot is warm', () => {
|
|
127
|
-
const { adapter } = (function makeFakeEngine() {
|
|
128
|
-
const engine = { _scene: 'INITIAL' };
|
|
129
|
-
const adapter = {
|
|
130
|
-
create: () => engine,
|
|
131
|
-
reset: vi.fn(async () => {
|
|
132
|
-
engine._scene = 'RESET';
|
|
133
|
-
}),
|
|
134
|
-
loadFromString: vi.fn(async () => { }),
|
|
135
|
-
saveToString: vi.fn(async () => engine._scene)
|
|
136
|
-
};
|
|
137
|
-
return { adapter };
|
|
138
|
-
})();
|
|
139
|
-
const session = new EngineSession({ size: 1, adapter });
|
|
140
|
-
expect(session.currentSlot()).toBeUndefined();
|
|
141
|
-
});
|
|
142
|
-
it('returns the slot once it has been committed to a revision', async () => {
|
|
143
|
-
const engine = { _scene: 'INITIAL' };
|
|
144
|
-
const adapter = {
|
|
145
|
-
create: () => engine,
|
|
146
|
-
reset: vi.fn(async () => {
|
|
147
|
-
engine._scene = 'RESET';
|
|
148
|
-
}),
|
|
149
|
-
loadFromString: vi.fn(async () => { }),
|
|
150
|
-
saveToString: vi.fn(async () => engine._scene)
|
|
151
|
-
};
|
|
152
|
-
const session = new EngineSession({ size: 1, adapter });
|
|
153
|
-
const slot = await session.acquire(null);
|
|
154
|
-
expect(session.currentSlot()).toBeUndefined(); // currentRevision is null after acquire(null)
|
|
155
|
-
session.commit(slot, 'rev_X');
|
|
156
|
-
expect(session.currentSlot()).toBe(slot);
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
//# sourceMappingURL=session.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session.test.js","sourceRoot":"","sources":["../../../../test/engine/session.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it, vi } from 'vitest';\nimport { type EngineAdapter, EngineSession } from '../../src/engine/session.js';\n\nfunction makeFakeEngine(scene = 'INITIAL'): {\n engine: { _scene: string };\n adapter: EngineAdapter;\n} {\n const engine = { _scene: scene };\n const adapter: EngineAdapter = {\n create: () => engine,\n reset: vi.fn(async () => {\n engine._scene = 'RESET';\n }),\n loadFromString: vi.fn(async (eng, s) => {\n (eng as typeof engine)._scene = s;\n }),\n saveToString: vi.fn(async (eng) => (eng as typeof engine)._scene)\n };\n return { engine, adapter };\n}\n\ndescribe('EngineSession (single slot)', () => {\n it('acquire(parent=null) resets the engine and sets currentRevision=null', async () => {\n const { adapter } = makeFakeEngine();\n const session = new EngineSession({ size: 1, adapter });\n const slot = await session.acquire(null);\n expect(adapter.reset).toHaveBeenCalledOnce();\n expect(slot.currentRevision).toBeNull();\n });\n\n it('acquire(parent=X) loads scene X when slot currentRevision is different', async () => {\n const { adapter } = makeFakeEngine();\n const session = new EngineSession({ size: 1, adapter });\n await session.populate('rev_abc', 'SCENE_ABC'); // pre-stage the loadable scene\n const slot = await session.acquire('rev_abc');\n expect(adapter.loadFromString).toHaveBeenCalledWith(\n slot.engine,\n 'SCENE_ABC'\n );\n expect(slot.currentRevision).toBe('rev_abc');\n });\n\n it('acquire(parent=X) is a no-op when slot.currentRevision === X (linear edit)', async () => {\n const { adapter } = makeFakeEngine();\n const session = new EngineSession({ size: 1, adapter });\n await session.populate('rev_abc', 'SCENE_ABC');\n await session.acquire('rev_abc');\n (adapter.loadFromString as ReturnType<typeof vi.fn>).mockClear();\n const slot2 = await session.acquire('rev_abc');\n expect(adapter.loadFromString).not.toHaveBeenCalled();\n expect(slot2.currentRevision).toBe('rev_abc');\n });\n\n it('commit(slot, newRev) updates currentRevision (linear edit succeeded)', async () => {\n const { adapter } = makeFakeEngine();\n const session = new EngineSession({ size: 1, adapter });\n const slot = await session.acquire(null);\n session.commit(slot, 'rev_new');\n expect(slot.currentRevision).toBe('rev_new');\n });\n\n it('markDirty(slot) sets currentRevision=null (failed edit forces reload next time)', async () => {\n const { adapter } = makeFakeEngine();\n const session = new EngineSession({ size: 1, adapter });\n await session.populate('rev_abc', 'SCENE_ABC');\n const slot = await session.acquire('rev_abc');\n session.markDirty(slot);\n expect(slot.currentRevision).toBeNull();\n // next acquire even of the SAME parent must reload\n await session.populate('rev_abc', 'SCENE_ABC');\n const slot2 = await session.acquire('rev_abc');\n expect(adapter.loadFromString).toHaveBeenCalledTimes(2);\n expect(slot2.currentRevision).toBe('rev_abc');\n });\n});\n\ndescribe('EngineSession cold-instance reconstruction (spec §8.6)', () => {\n it('reconstructs a cold engine by loading a staged revision scene', async () => {\n // Regression guard: a cold session (no warm slot) must load the staged\n // scene via loadFromString before returning the slot. This documents the\n // edit-tool contract: populate(parent, scene) → acquire(parent) always\n // calls loadFromString, never assumes a warm engine.\n const { adapter } = makeFakeEngine();\n const session = new EngineSession({ size: 1, adapter });\n // Cold: no slots exist yet, so no warm engine.\n await session.populate('rev-1', '<scene-for-rev-1/>');\n const slot = await session.acquire('rev-1');\n expect(adapter.loadFromString).toHaveBeenCalledWith(\n slot.engine,\n '<scene-for-rev-1/>'\n );\n expect(slot.currentRevision).toBe('rev-1');\n });\n});\n\ndescribe('EngineSession (multi-slot sticky routing)', () => {\n function makeAdapterWithCounter(): {\n adapter: EngineAdapter;\n createCount: () => number;\n } {\n let id = 0;\n const counters = { creates: 0 };\n const adapter: EngineAdapter = {\n create: () => {\n counters.creates++;\n return { _id: id++, _scene: 'INITIAL' };\n },\n reset: async (eng) => {\n (eng as { _scene: string })._scene = 'RESET';\n },\n loadFromString: async (eng, s) => {\n (eng as { _scene: string })._scene = s;\n },\n saveToString: async (eng) => (eng as { _scene: string })._scene\n };\n return { adapter, createCount: () => counters.creates };\n }\n\n it('returns warm slot whose currentRevision matches the requested parent', async () => {\n const { adapter, createCount } = makeAdapterWithCounter();\n const session = new EngineSession({ size: 2, adapter });\n await session.populate('rev_A', 'SCENE_A');\n const slotA = await session.acquire('rev_A');\n session.commit(slotA, 'rev_A2');\n await session.populate('rev_B', 'SCENE_B');\n const slotB = await session.acquire('rev_B');\n session.commit(slotB, 'rev_B2');\n\n expect(createCount()).toBe(2);\n // Sticky: re-acquire rev_A2 → reuse slotA, no new create, no reload.\n const reuse = await session.acquire('rev_A2');\n expect(reuse.engine).toBe(slotA.engine);\n expect(createCount()).toBe(2);\n });\n\n it('evicts a dirty slot before a warm slot when over cap', async () => {\n const { adapter } = makeAdapterWithCounter();\n const session = new EngineSession({ size: 1, adapter });\n const slot1 = await session.acquire(null);\n session.commit(slot1, 'rev_X');\n session.markDirty(slot1);\n await session.populate('rev_Y', 'SCENE_Y');\n const slot2 = await session.acquire('rev_Y');\n expect(slot2).toBe(slot1); // reused\n expect(slot2.currentRevision).toBe('rev_Y');\n });\n});\n\ndescribe('EngineSession.currentSlot', () => {\n it('returns undefined when no slot is warm', () => {\n const { adapter } = (function makeFakeEngine() {\n const engine = { _scene: 'INITIAL' };\n const adapter: EngineAdapter = {\n create: () => engine,\n reset: vi.fn(async () => {\n engine._scene = 'RESET';\n }),\n loadFromString: vi.fn(async () => {}),\n saveToString: vi.fn(async () => engine._scene)\n };\n return { adapter };\n })();\n const session = new EngineSession({ size: 1, adapter });\n expect(session.currentSlot()).toBeUndefined();\n });\n\n it('returns the slot once it has been committed to a revision', async () => {\n const engine = { _scene: 'INITIAL' };\n const adapter: EngineAdapter = {\n create: () => engine,\n reset: vi.fn(async () => {\n engine._scene = 'RESET';\n }),\n loadFromString: vi.fn(async () => {}),\n saveToString: vi.fn(async () => engine._scene)\n };\n const session = new EngineSession({ size: 1, adapter });\n const slot = await session.acquire(null);\n expect(session.currentSlot()).toBeUndefined(); // currentRevision is null after acquire(null)\n session.commit(slot, 'rev_X');\n expect(session.currentSlot()).toBe(slot);\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"unsplash-source.test.d.ts","sourceRoot":"","sources":["../../../../test/engine/unsplash-source.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { registerUnsplashSource } from '../../src/engine/unsplash-source.js';
|
|
3
|
-
// Minimal engine double: registerUnsplashSource only touches engine.asset.
|
|
4
|
-
function makeEngine(existingSources = []) {
|
|
5
|
-
const added = [];
|
|
6
|
-
const engine = {
|
|
7
|
-
asset: {
|
|
8
|
-
findAllSources: vi.fn(() => [
|
|
9
|
-
...existingSources,
|
|
10
|
-
...added.map((s) => s.id)
|
|
11
|
-
]),
|
|
12
|
-
addSource: vi.fn((source) => added.push(source)),
|
|
13
|
-
defaultApplyAsset: vi.fn(async () => 1)
|
|
14
|
-
}
|
|
15
|
-
};
|
|
16
|
-
// registerUnsplashSource is typed against CreativeEngine; the double only
|
|
17
|
-
// implements the slice it uses.
|
|
18
|
-
return {
|
|
19
|
-
engine: engine,
|
|
20
|
-
added
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
function mockFetch(payload, ok = true, status = 200) {
|
|
24
|
-
const fetchMock = vi.fn(async (_url) => ({
|
|
25
|
-
ok,
|
|
26
|
-
status,
|
|
27
|
-
json: async () => payload
|
|
28
|
-
}));
|
|
29
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
30
|
-
return fetchMock;
|
|
31
|
-
}
|
|
32
|
-
const PHOTO = {
|
|
33
|
-
id: 'abc',
|
|
34
|
-
description: 'A cat',
|
|
35
|
-
width: 800,
|
|
36
|
-
height: 600,
|
|
37
|
-
urls: { regular: 'https://img/regular.jpg', thumb: 'https://img/thumb.jpg' },
|
|
38
|
-
user: { name: 'Jane', links: { html: 'https://unsplash.com/@jane' } },
|
|
39
|
-
tags: [{ title: 'cat' }, { title: 'pet' }]
|
|
40
|
-
};
|
|
41
|
-
function findAssetsOf(added) {
|
|
42
|
-
return added[0].findAssets;
|
|
43
|
-
}
|
|
44
|
-
afterEach(() => {
|
|
45
|
-
vi.unstubAllGlobals();
|
|
46
|
-
});
|
|
47
|
-
describe('registerUnsplashSource', () => {
|
|
48
|
-
it('registers the unsplash source on a fresh engine', () => {
|
|
49
|
-
const { engine, added } = makeEngine();
|
|
50
|
-
registerUnsplashSource(engine);
|
|
51
|
-
expect(added).toHaveLength(1);
|
|
52
|
-
expect(added[0].id).toBe('unsplash');
|
|
53
|
-
});
|
|
54
|
-
it('is idempotent — skips when the source is already present', () => {
|
|
55
|
-
const { engine, added } = makeEngine(['unsplash']);
|
|
56
|
-
registerUnsplashSource(engine);
|
|
57
|
-
expect(added).toHaveLength(0);
|
|
58
|
-
});
|
|
59
|
-
it('searches via /search/photos when a query is set and maps the result', async () => {
|
|
60
|
-
const fetchMock = mockFetch({
|
|
61
|
-
results: [PHOTO],
|
|
62
|
-
total: 50,
|
|
63
|
-
total_pages: 5
|
|
64
|
-
});
|
|
65
|
-
const { engine, added } = makeEngine();
|
|
66
|
-
registerUnsplashSource(engine);
|
|
67
|
-
const query = {
|
|
68
|
-
query: 'cats',
|
|
69
|
-
page: 0,
|
|
70
|
-
perPage: 10,
|
|
71
|
-
locale: 'en'
|
|
72
|
-
};
|
|
73
|
-
const res = (await findAssetsOf(added)(query));
|
|
74
|
-
const url = fetchMock.mock.calls[0][0];
|
|
75
|
-
expect(url).toContain('/search/photos');
|
|
76
|
-
expect(url).toContain('query=cats');
|
|
77
|
-
expect(url).toContain('page=1'); // 0-based query → 1-based Unsplash
|
|
78
|
-
expect(url).toContain('per_page=10');
|
|
79
|
-
expect(res.assets).toHaveLength(1);
|
|
80
|
-
expect(res.assets[0]).toMatchObject({
|
|
81
|
-
id: 'abc',
|
|
82
|
-
label: 'A cat',
|
|
83
|
-
tags: ['cat', 'pet'],
|
|
84
|
-
meta: {
|
|
85
|
-
uri: 'https://img/regular.jpg',
|
|
86
|
-
thumbUri: 'https://img/thumb.jpg'
|
|
87
|
-
},
|
|
88
|
-
credits: { name: 'Jane', url: 'https://unsplash.com/@jane' }
|
|
89
|
-
});
|
|
90
|
-
expect(res.nextPage).toBe(1); // page 0 of 5 → next is 1
|
|
91
|
-
});
|
|
92
|
-
it('browses popular photos via /photos when no query is set', async () => {
|
|
93
|
-
const fetchMock = mockFetch([PHOTO, PHOTO]);
|
|
94
|
-
const { engine, added } = makeEngine();
|
|
95
|
-
registerUnsplashSource(engine);
|
|
96
|
-
const query = {
|
|
97
|
-
page: 0,
|
|
98
|
-
perPage: 2,
|
|
99
|
-
locale: 'en'
|
|
100
|
-
};
|
|
101
|
-
const res = (await findAssetsOf(added)(query));
|
|
102
|
-
const url = fetchMock.mock.calls[0][0];
|
|
103
|
-
expect(url).toContain('/photos?order_by=popular');
|
|
104
|
-
expect(res.assets).toHaveLength(2);
|
|
105
|
-
expect(res.nextPage).toBe(1); // full page → there may be more
|
|
106
|
-
});
|
|
107
|
-
it('stops paginating when a partial page comes back', async () => {
|
|
108
|
-
mockFetch([PHOTO]); // 1 < perPage(2)
|
|
109
|
-
const { engine, added } = makeEngine();
|
|
110
|
-
registerUnsplashSource(engine);
|
|
111
|
-
const res = (await findAssetsOf(added)({
|
|
112
|
-
page: 0,
|
|
113
|
-
perPage: 2,
|
|
114
|
-
locale: 'en'
|
|
115
|
-
}));
|
|
116
|
-
expect(res.nextPage).toBeUndefined();
|
|
117
|
-
});
|
|
118
|
-
it('throws when the proxy returns a non-OK status', async () => {
|
|
119
|
-
mockFetch({}, false, 502);
|
|
120
|
-
const { engine, added } = makeEngine();
|
|
121
|
-
registerUnsplashSource(engine);
|
|
122
|
-
await expect(findAssetsOf(added)({
|
|
123
|
-
page: 0,
|
|
124
|
-
perPage: 5,
|
|
125
|
-
locale: 'en'
|
|
126
|
-
})).rejects.toThrow('unsplash proxy: HTTP 502');
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
//# sourceMappingURL=unsplash-source.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"unsplash-source.test.js","sourceRoot":"","sources":["../../../../test/engine/unsplash-source.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { afterEach, describe, expect, it, vi } from 'vitest';\nimport type {\n AssetQueryData,\n AssetsQueryResult,\n AssetSource\n} from '@cesdk/engine';\nimport { registerUnsplashSource } from '../../src/engine/unsplash-source.js';\n\n// Minimal engine double: registerUnsplashSource only touches engine.asset.\nfunction makeEngine(existingSources: string[] = []) {\n const added: AssetSource[] = [];\n const engine = {\n asset: {\n findAllSources: vi.fn(() => [\n ...existingSources,\n ...added.map((s) => s.id)\n ]),\n addSource: vi.fn((source: AssetSource) => added.push(source)),\n defaultApplyAsset: vi.fn(async () => 1)\n }\n };\n // registerUnsplashSource is typed against CreativeEngine; the double only\n // implements the slice it uses.\n return {\n engine: engine as unknown as Parameters<typeof registerUnsplashSource>[0],\n added\n };\n}\n\nfunction mockFetch(payload: unknown, ok = true, status = 200) {\n const fetchMock = vi.fn(async (_url: string) => ({\n ok,\n status,\n json: async () => payload\n }));\n vi.stubGlobal('fetch', fetchMock);\n return fetchMock;\n}\n\nconst PHOTO = {\n id: 'abc',\n description: 'A cat',\n width: 800,\n height: 600,\n urls: { regular: 'https://img/regular.jpg', thumb: 'https://img/thumb.jpg' },\n user: { name: 'Jane', links: { html: 'https://unsplash.com/@jane' } },\n tags: [{ title: 'cat' }, { title: 'pet' }]\n};\n\nfunction findAssetsOf(added: AssetSource[]): AssetSource['findAssets'] {\n return added[0].findAssets;\n}\n\nafterEach(() => {\n vi.unstubAllGlobals();\n});\n\ndescribe('registerUnsplashSource', () => {\n it('registers the unsplash source on a fresh engine', () => {\n const { engine, added } = makeEngine();\n registerUnsplashSource(engine);\n expect(added).toHaveLength(1);\n expect(added[0].id).toBe('unsplash');\n });\n\n it('is idempotent — skips when the source is already present', () => {\n const { engine, added } = makeEngine(['unsplash']);\n registerUnsplashSource(engine);\n expect(added).toHaveLength(0);\n });\n\n it('searches via /search/photos when a query is set and maps the result', async () => {\n const fetchMock = mockFetch({\n results: [PHOTO],\n total: 50,\n total_pages: 5\n });\n const { engine, added } = makeEngine();\n registerUnsplashSource(engine);\n\n const query: AssetQueryData = {\n query: 'cats',\n page: 0,\n perPage: 10,\n locale: 'en'\n } as AssetQueryData;\n const res = (await findAssetsOf(added)(query)) as AssetsQueryResult;\n\n const url = fetchMock.mock.calls[0][0];\n expect(url).toContain('/search/photos');\n expect(url).toContain('query=cats');\n expect(url).toContain('page=1'); // 0-based query → 1-based Unsplash\n expect(url).toContain('per_page=10');\n\n expect(res.assets).toHaveLength(1);\n expect(res.assets[0]).toMatchObject({\n id: 'abc',\n label: 'A cat',\n tags: ['cat', 'pet'],\n meta: {\n uri: 'https://img/regular.jpg',\n thumbUri: 'https://img/thumb.jpg'\n },\n credits: { name: 'Jane', url: 'https://unsplash.com/@jane' }\n });\n expect(res.nextPage).toBe(1); // page 0 of 5 → next is 1\n });\n\n it('browses popular photos via /photos when no query is set', async () => {\n const fetchMock = mockFetch([PHOTO, PHOTO]);\n const { engine, added } = makeEngine();\n registerUnsplashSource(engine);\n\n const query: AssetQueryData = {\n page: 0,\n perPage: 2,\n locale: 'en'\n } as AssetQueryData;\n const res = (await findAssetsOf(added)(query)) as AssetsQueryResult;\n\n const url = fetchMock.mock.calls[0][0];\n expect(url).toContain('/photos?order_by=popular');\n expect(res.assets).toHaveLength(2);\n expect(res.nextPage).toBe(1); // full page → there may be more\n });\n\n it('stops paginating when a partial page comes back', async () => {\n mockFetch([PHOTO]); // 1 < perPage(2)\n const { engine, added } = makeEngine();\n registerUnsplashSource(engine);\n const res = (await findAssetsOf(added)({\n page: 0,\n perPage: 2,\n locale: 'en'\n } as AssetQueryData)) as AssetsQueryResult;\n expect(res.nextPage).toBeUndefined();\n });\n\n it('throws when the proxy returns a non-OK status', async () => {\n mockFetch({}, false, 502);\n const { engine, added } = makeEngine();\n registerUnsplashSource(engine);\n await expect(\n findAssetsOf(added)({\n page: 0,\n perPage: 5,\n locale: 'en'\n } as AssetQueryData)\n ).rejects.toThrow('unsplash proxy: HTTP 502');\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"uri-resolver.test.d.ts","sourceRoot":"","sources":["../../../../test/engine/uri-resolver.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { registerWorkspaceUriResolver } from '../../src/engine/uri-resolver.js';
|
|
3
|
-
import { LocalViewerUrlBuilder } from '../../src/viewer/url-builder.js';
|
|
4
|
-
function captureResolver() {
|
|
5
|
-
let resolver;
|
|
6
|
-
const engine = {
|
|
7
|
-
editor: {
|
|
8
|
-
setURIResolver: (fn) => {
|
|
9
|
-
resolver = fn;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
return {
|
|
14
|
-
engine,
|
|
15
|
-
invoke: (uri) => {
|
|
16
|
-
if (!resolver)
|
|
17
|
-
throw new Error('resolver was not registered');
|
|
18
|
-
return resolver(uri, (u) => `DEFAULT:${u}`);
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
describe('registerWorkspaceUriResolver', () => {
|
|
23
|
-
const urlBuilder = new LocalViewerUrlBuilder({
|
|
24
|
-
base: 'http://127.0.0.1:8745'
|
|
25
|
-
});
|
|
26
|
-
it('rewrites a workspace:// URI to the /r/ route', () => {
|
|
27
|
-
const { engine, invoke } = captureResolver();
|
|
28
|
-
registerWorkspaceUriResolver(engine, urlBuilder);
|
|
29
|
-
expect(invoke('workspace://assets/9f2a1c.png')).toBe('http://127.0.0.1:8745/r/assets/9f2a1c.png');
|
|
30
|
-
});
|
|
31
|
-
it('delegates non-workspace URIs to the default resolver', () => {
|
|
32
|
-
const { engine, invoke } = captureResolver();
|
|
33
|
-
registerWorkspaceUriResolver(engine, urlBuilder);
|
|
34
|
-
expect(invoke('https://cdn.img.ly/fonts/Roboto.ttf')).toBe('DEFAULT:https://cdn.img.ly/fonts/Roboto.ttf');
|
|
35
|
-
expect(invoke('/relative/path.png')).toBe('DEFAULT:/relative/path.png');
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
//# sourceMappingURL=uri-resolver.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"uri-resolver.test.js","sourceRoot":"","sources":["../../../../test/engine/uri-resolver.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,4BAA4B,EAE7B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAExE,SAAS,eAAe;IACtB,IAAI,QAES,CAAC;IACd,MAAM,MAAM,GAAwB;QAClC,MAAM,EAAE;YACN,cAAc,EAAE,CAAC,EAAE,EAAE,EAAE;gBACrB,QAAQ,GAAG,EAAE,CAAC;YAChB,CAAC;SACF;KACF,CAAC;IACF,OAAO;QACL,MAAM;QACN,MAAM,EAAE,CAAC,GAAW,EAAE,EAAE;YACtB,IAAI,CAAC,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAC9D,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAC9C,CAAC;KACF,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,MAAM,UAAU,GAAG,IAAI,qBAAqB,CAAC;QAC3C,IAAI,EAAE,uBAAuB;KAC9B,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC;QAC7C,4BAA4B,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACjD,MAAM,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC,CAAC,IAAI,CAClD,2CAA2C,CAC5C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC;QAC7C,4BAA4B,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACjD,MAAM,CAAC,MAAM,CAAC,qCAAqC,CAAC,CAAC,CAAC,IAAI,CACxD,6CAA6C,CAC9C,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from 'vitest';\nimport {\n registerWorkspaceUriResolver,\n type UriResolvableEngine\n} from '../../src/engine/uri-resolver.js';\nimport { LocalViewerUrlBuilder } from '../../src/viewer/url-builder.js';\n\nfunction captureResolver() {\n let resolver:\n | ((uri: string, def: (u: string) => string) => string)\n | undefined;\n const engine: UriResolvableEngine = {\n editor: {\n setURIResolver: (fn) => {\n resolver = fn;\n }\n }\n };\n return {\n engine,\n invoke: (uri: string) => {\n if (!resolver) throw new Error('resolver was not registered');\n return resolver(uri, (u) => `DEFAULT:${u}`);\n }\n };\n}\n\ndescribe('registerWorkspaceUriResolver', () => {\n const urlBuilder = new LocalViewerUrlBuilder({\n base: 'http://127.0.0.1:8745'\n });\n\n it('rewrites a workspace:// URI to the /r/ route', () => {\n const { engine, invoke } = captureResolver();\n registerWorkspaceUriResolver(engine, urlBuilder);\n expect(invoke('workspace://assets/9f2a1c.png')).toBe(\n 'http://127.0.0.1:8745/r/assets/9f2a1c.png'\n );\n });\n\n it('delegates non-workspace URIs to the default resolver', () => {\n const { engine, invoke } = captureResolver();\n registerWorkspaceUriResolver(engine, urlBuilder);\n expect(invoke('https://cdn.img.ly/fonts/Roboto.ttf')).toBe(\n 'DEFAULT:https://cdn.img.ly/fonts/Roboto.ttf'\n );\n expect(invoke('/relative/path.png')).toBe('DEFAULT:/relative/path.png');\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hosted-stub.test.d.ts","sourceRoot":"","sources":["../../../../test/gateway/hosted-stub.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { HostedStubGatewayClient } from '../../src/gateway/hosted-stub.js';
|
|
3
|
-
describe('HostedStubGatewayClient', () => {
|
|
4
|
-
it('throws not-implemented for Phase 1', async () => {
|
|
5
|
-
const client = new HostedStubGatewayClient();
|
|
6
|
-
await expect(client.generateImage({ prompt: 'x' })).rejects.toMatchObject({
|
|
7
|
-
message: expect.stringContaining('Phase 2')
|
|
8
|
-
});
|
|
9
|
-
});
|
|
10
|
-
});
|
|
11
|
-
//# sourceMappingURL=hosted-stub.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hosted-stub.test.js","sourceRoot":"","sources":["../../../../test/gateway/hosted-stub.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAE3E,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,MAAM,GAAG,IAAI,uBAAuB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;YACxE,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC;SAC5C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from 'vitest';\nimport { HostedStubGatewayClient } from '../../src/gateway/hosted-stub.js';\n\ndescribe('HostedStubGatewayClient', () => {\n it('throws not-implemented for Phase 1', async () => {\n const client = new HostedStubGatewayClient();\n await expect(client.generateImage({ prompt: 'x' })).rejects.toMatchObject({\n message: expect.stringContaining('Phase 2')\n });\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local.test.d.ts","sourceRoot":"","sources":["../../../../test/gateway/local.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { LocalGatewayClient } from '../../src/gateway/local.js';
|
|
3
|
-
describe('LocalGatewayClient', () => {
|
|
4
|
-
it('throws GatewayDisabledError when no API_KEY is configured', async () => {
|
|
5
|
-
const client = new LocalGatewayClient({ apiKey: undefined });
|
|
6
|
-
await expect(client.generateImage({ prompt: 'a cat' })).rejects.toMatchObject({ name: 'GatewayDisabledError' });
|
|
7
|
-
});
|
|
8
|
-
it('calls the configured endpoint with the API key and returns bytes', async () => {
|
|
9
|
-
const fetch = async (url, init) => {
|
|
10
|
-
const headers = init?.headers;
|
|
11
|
-
expect(url).toBe('https://gateway.example/v1/images/generate');
|
|
12
|
-
expect(headers.Authorization).toBe('Bearer test-key');
|
|
13
|
-
const body = JSON.parse(init?.body);
|
|
14
|
-
expect(body).toMatchObject({ prompt: 'a cat' });
|
|
15
|
-
return new Response(new Uint8Array([1, 2, 3, 4]), {
|
|
16
|
-
headers: { 'content-type': 'image/png' }
|
|
17
|
-
});
|
|
18
|
-
};
|
|
19
|
-
const client = new LocalGatewayClient({
|
|
20
|
-
apiKey: 'test-key',
|
|
21
|
-
endpoint: 'https://gateway.example/v1/images/generate',
|
|
22
|
-
fetch: fetch
|
|
23
|
-
});
|
|
24
|
-
const out = await client.generateImage({ prompt: 'a cat' });
|
|
25
|
-
expect(out.mimeType).toBe('image/png');
|
|
26
|
-
expect(Array.from(out.bytes)).toEqual([1, 2, 3, 4]);
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
//# sourceMappingURL=local.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local.test.js","sourceRoot":"","sources":["../../../../test/gateway/local.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,MAAM,GAAG,IAAI,kBAAkB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7D,MAAM,MAAM,CACV,MAAM,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAC1C,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,MAAM,KAAK,GAAG,KAAK,EAAE,GAAW,EAAE,IAAkB,EAAE,EAAE;YACtD,MAAM,OAAO,GAAG,IAAI,EAAE,OAAiC,CAAC;YACxD,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;YAC/D,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACtD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAc,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;YAChD,OAAO,IAAI,QAAQ,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;gBAChD,OAAO,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE;aACzC,CAAC,CAAC;QACL,CAAC,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,kBAAkB,CAAC;YACpC,MAAM,EAAE,UAAU;YAClB,QAAQ,EAAE,4CAA4C;YACtD,KAAK,EAAE,KAAgC;SACxC,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from 'vitest';\nimport { LocalGatewayClient } from '../../src/gateway/local.js';\n\ndescribe('LocalGatewayClient', () => {\n it('throws GatewayDisabledError when no API_KEY is configured', async () => {\n const client = new LocalGatewayClient({ apiKey: undefined });\n await expect(\n client.generateImage({ prompt: 'a cat' })\n ).rejects.toMatchObject({ name: 'GatewayDisabledError' });\n });\n\n it('calls the configured endpoint with the API key and returns bytes', async () => {\n const fetch = async (url: string, init?: RequestInit) => {\n const headers = init?.headers as Record<string, string>;\n expect(url).toBe('https://gateway.example/v1/images/generate');\n expect(headers.Authorization).toBe('Bearer test-key');\n const body = JSON.parse(init?.body as string);\n expect(body).toMatchObject({ prompt: 'a cat' });\n return new Response(new Uint8Array([1, 2, 3, 4]), {\n headers: { 'content-type': 'image/png' }\n });\n };\n const client = new LocalGatewayClient({\n apiKey: 'test-key',\n endpoint: 'https://gateway.example/v1/images/generate',\n fetch: fetch as typeof globalThis.fetch\n });\n const out = await client.generateImage({ prompt: 'a cat' });\n expect(out.mimeType).toBe('image/png');\n expect(Array.from(out.bytes)).toEqual([1, 2, 3, 4]);\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"handbook-contract.test.d.ts","sourceRoot":"","sources":["../../../test/handbook-contract.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
-
import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
|
|
3
|
-
import { describe, expect, it } from 'vitest';
|
|
4
|
-
import { loadNodeAssets } from '../src/assets/load-node.js';
|
|
5
|
-
import { createCodesignMcpServer } from '../src/server.js';
|
|
6
|
-
// asset_generate is intentionally absent: it is hidden for the beta (see the
|
|
7
|
-
// ASSET_GENERATE_ENABLED kill-switch in src/tools/index.ts and the commented-out
|
|
8
|
-
// section in the handbook). Re-add it here when the feature ships.
|
|
9
|
-
const TOOL_NAMES_IN_HANDBOOK = [
|
|
10
|
-
'handbook',
|
|
11
|
-
'api',
|
|
12
|
-
'guide',
|
|
13
|
-
'edit',
|
|
14
|
-
'preview',
|
|
15
|
-
'export',
|
|
16
|
-
'save',
|
|
17
|
-
'load',
|
|
18
|
-
'list',
|
|
19
|
-
'history',
|
|
20
|
-
'inspect',
|
|
21
|
-
'rename',
|
|
22
|
-
'open_editor',
|
|
23
|
-
'asset_search',
|
|
24
|
-
'import'
|
|
25
|
-
];
|
|
26
|
-
describe('handbook contract', () => {
|
|
27
|
-
it('the handbook prose references every tool name we ship', () => {
|
|
28
|
-
const assets = loadNodeAssets();
|
|
29
|
-
const handbookText = assets['docs/handbook/SKILL.md'];
|
|
30
|
-
expect(handbookText).toBeTruthy();
|
|
31
|
-
for (const tool of TOOL_NAMES_IN_HANDBOOK) {
|
|
32
|
-
expect(handbookText, `handbook is missing tool name "${tool}"`).toContain(tool);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
it('every tool the handbook names is in tools/list', async () => {
|
|
36
|
-
const server = createCodesignMcpServer({
|
|
37
|
-
assets: loadNodeAssets(),
|
|
38
|
-
tools: [
|
|
39
|
-
// Stubs with the right names so tools/list returns them. The
|
|
40
|
-
// handbook contract checks NAMES, not behaviour — full behaviour
|
|
41
|
-
// is covered in tools/*.test.ts and the evals.
|
|
42
|
-
...[
|
|
43
|
-
'edit',
|
|
44
|
-
'preview',
|
|
45
|
-
'export',
|
|
46
|
-
'save',
|
|
47
|
-
'load',
|
|
48
|
-
'list',
|
|
49
|
-
'history',
|
|
50
|
-
'inspect',
|
|
51
|
-
'rename',
|
|
52
|
-
'open_editor',
|
|
53
|
-
'asset_search',
|
|
54
|
-
'import'
|
|
55
|
-
].map((name) => ({
|
|
56
|
-
name,
|
|
57
|
-
description: `${name} tool stub for handbook-contract check`,
|
|
58
|
-
inputSchema: { type: 'object', properties: {} },
|
|
59
|
-
call: async () => ({ content: [{ type: 'text', text: '' }] })
|
|
60
|
-
}))
|
|
61
|
-
]
|
|
62
|
-
});
|
|
63
|
-
const [c, s] = InMemoryTransport.createLinkedPair();
|
|
64
|
-
await server.connect(s);
|
|
65
|
-
const client = new Client({ name: 'test', version: '0' });
|
|
66
|
-
await client.connect(c);
|
|
67
|
-
const tools = await client.listTools();
|
|
68
|
-
const names = tools.tools.map((t) => t.name);
|
|
69
|
-
for (const expected of TOOL_NAMES_IN_HANDBOOK) {
|
|
70
|
-
expect(names, `tools/list missing "${expected}"`).toContain(expected);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
it('documents the httpUrl field for export and save', () => {
|
|
74
|
-
const assets = loadNodeAssets();
|
|
75
|
-
const handbookText = assets['docs/handbook/SKILL.md'];
|
|
76
|
-
expect(handbookText).toContain('httpUrl');
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
//# sourceMappingURL=handbook-contract.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"handbook-contract.test.js","sourceRoot":"","sources":["../../../test/handbook-contract.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,6EAA6E;AAC7E,iFAAiF;AACjF,mEAAmE;AACnE,MAAM,sBAAsB,GAAG;IAC7B,UAAU;IACV,KAAK;IACL,OAAO;IACP,MAAM;IACN,SAAS;IACT,QAAQ;IACR,MAAM;IACN,MAAM;IACN,MAAM;IACN,SAAS;IACT,SAAS;IACT,QAAQ;IACR,aAAa;IACb,cAAc;IACd,QAAQ;CACT,CAAC;AAEF,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,MAAM,GAAG,cAAc,EAAE,CAAC;QAChC,MAAM,YAAY,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;QACtD,MAAM,CAAC,YAAY,CAAC,CAAC,UAAU,EAAE,CAAC;QAClC,KAAK,MAAM,IAAI,IAAI,sBAAsB,EAAE,CAAC;YAC1C,MAAM,CAAC,YAAY,EAAE,kCAAkC,IAAI,GAAG,CAAC,CAAC,SAAS,CACvE,IAAI,CACL,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,MAAM,GAAG,uBAAuB,CAAC;YACrC,MAAM,EAAE,cAAc,EAAE;YACxB,KAAK,EAAE;gBACL,6DAA6D;gBAC7D,iEAAiE;gBACjE,+CAA+C;gBAC/C,GAAG;oBACD,MAAM;oBACN,SAAS;oBACT,QAAQ;oBACR,MAAM;oBACN,MAAM;oBACN,MAAM;oBACN,SAAS;oBACT,SAAS;oBACT,QAAQ;oBACR,aAAa;oBACb,cAAc;oBACd,QAAQ;iBACT,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBACf,IAAI;oBACJ,WAAW,EAAE,GAAG,IAAI,wCAAwC;oBAC5D,WAAW,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,UAAU,EAAE,EAAE,EAAE;oBACxD,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;iBACvE,CAAC,CAAC;aACJ;SACF,CAAC,CAAC;QACH,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,CAAC;QACpD,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QAC1D,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC7C,KAAK,MAAM,QAAQ,IAAI,sBAAsB,EAAE,CAAC;YAC9C,MAAM,CAAC,KAAK,EAAE,uBAAuB,QAAQ,GAAG,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACxE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,MAAM,GAAG,cAAc,EAAE,CAAC;QAChC,MAAM,YAAY,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;QACtD,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';\nimport { describe, expect, it } from 'vitest';\nimport { loadNodeAssets } from '../src/assets/load-node.js';\nimport { createCodesignMcpServer } from '../src/server.js';\n\n// asset_generate is intentionally absent: it is hidden for the beta (see the\n// ASSET_GENERATE_ENABLED kill-switch in src/tools/index.ts and the commented-out\n// section in the handbook). Re-add it here when the feature ships.\nconst TOOL_NAMES_IN_HANDBOOK = [\n 'handbook',\n 'api',\n 'guide',\n 'edit',\n 'preview',\n 'export',\n 'save',\n 'load',\n 'list',\n 'history',\n 'inspect',\n 'rename',\n 'open_editor',\n 'asset_search',\n 'import'\n];\n\ndescribe('handbook contract', () => {\n it('the handbook prose references every tool name we ship', () => {\n const assets = loadNodeAssets();\n const handbookText = assets['docs/handbook/SKILL.md'];\n expect(handbookText).toBeTruthy();\n for (const tool of TOOL_NAMES_IN_HANDBOOK) {\n expect(handbookText, `handbook is missing tool name \"${tool}\"`).toContain(\n tool\n );\n }\n });\n\n it('every tool the handbook names is in tools/list', async () => {\n const server = createCodesignMcpServer({\n assets: loadNodeAssets(),\n tools: [\n // Stubs with the right names so tools/list returns them. The\n // handbook contract checks NAMES, not behaviour — full behaviour\n // is covered in tools/*.test.ts and the evals.\n ...[\n 'edit',\n 'preview',\n 'export',\n 'save',\n 'load',\n 'list',\n 'history',\n 'inspect',\n 'rename',\n 'open_editor',\n 'asset_search',\n 'import'\n ].map((name) => ({\n name,\n description: `${name} tool stub for handbook-contract check`,\n inputSchema: { type: 'object' as const, properties: {} },\n call: async () => ({ content: [{ type: 'text' as const, text: '' }] })\n }))\n ]\n });\n const [c, s] = InMemoryTransport.createLinkedPair();\n await server.connect(s);\n const client = new Client({ name: 'test', version: '0' });\n await client.connect(c);\n const tools = await client.listTools();\n const names = tools.tools.map((t) => t.name);\n for (const expected of TOOL_NAMES_IN_HANDBOOK) {\n expect(names, `tools/list missing \"${expected}\"`).toContain(expected);\n }\n });\n\n it('documents the httpUrl field for export and save', () => {\n const assets = loadNodeAssets();\n const handbookText = assets['docs/handbook/SKILL.md'];\n expect(handbookText).toContain('httpUrl');\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.test.d.ts","sourceRoot":"","sources":["../../../../test/http/server.test.ts"],"names":[],"mappings":""}
|