@imgly/codesign-mcp 0.1.6 → 0.1.8
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/assets/docs/api/index.d.ts +9 -3
- package/assets/docs/guide/SKILL.md +2 -2
- package/assets/docs/guide/api/node/classes/creativeengine.md +13 -13
- package/assets/docs/guide/edit-image/transform/scale.md +1 -3
- package/assets/docs/guide/filters-and-effects/duotone.md +1 -1
- package/assets/docs/guide/get-started/bun.md +0 -2
- package/assets/docs/guide/get-started/deno.md +0 -1
- package/assets/docs/guide/get-started/vanilla.md +0 -2
- package/assets/docs/guide/import-media/default-assets.md +20 -24
- package/assets/docs/guide/plugins/print-ready-pdf.md +0 -2
- package/assets/docs/guide/serve-assets.md +80 -23
- package/assets/docs/handbook/SKILL.md +6 -7
- package/dist/assets/inline.generated.js +12 -12
- package/dist/assets/inline.generated.js.map +1 -1
- package/dist/cli/http.d.ts.map +1 -1
- package/dist/cli/http.js +29 -5
- package/dist/cli/http.js.map +1 -1
- package/dist/cli/stdio.d.ts.map +1 -1
- package/dist/cli/stdio.js +145 -48
- package/dist/cli/stdio.js.map +1 -1
- package/dist/cli/trial-license.generated.d.ts +1 -1
- package/dist/cli/trial-license.generated.js +1 -1
- package/dist/cli/trial-license.generated.js.map +1 -1
- package/dist/config.d.ts +17 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +20 -1
- package/dist/config.js.map +1 -1
- package/dist/diagnostics/bundle.d.ts +3 -0
- package/dist/diagnostics/bundle.d.ts.map +1 -1
- package/dist/diagnostics/bundle.js +25 -22
- package/dist/diagnostics/bundle.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/diagnostics/prompt.d.ts +3 -0
- package/dist/diagnostics/prompt.d.ts.map +1 -0
- package/dist/diagnostics/prompt.js +21 -0
- package/dist/diagnostics/prompt.js.map +1 -0
- package/dist/diagnostics/router.d.ts +12 -0
- package/dist/diagnostics/router.d.ts.map +1 -0
- package/dist/diagnostics/router.js +64 -0
- package/dist/diagnostics/router.js.map +1 -0
- package/dist/diagnostics/spa-assets.generated.d.ts.map +1 -0
- package/dist/diagnostics/spa-assets.generated.js +1231 -0
- package/dist/diagnostics/spa-assets.generated.js.map +1 -0
- package/dist/diagnostics/status.d.ts +38 -0
- package/dist/diagnostics/status.d.ts.map +1 -0
- package/dist/diagnostics/status.js +53 -0
- package/dist/diagnostics/status.js.map +1 -0
- package/dist/diagnostics/summary.d.ts +48 -0
- package/dist/diagnostics/summary.d.ts.map +1 -0
- package/dist/diagnostics/summary.js +116 -0
- package/dist/diagnostics/summary.js.map +1 -0
- package/dist/diagnostics/tool.d.ts +16 -0
- package/dist/diagnostics/tool.d.ts.map +1 -0
- package/dist/diagnostics/tool.js +90 -0
- package/dist/diagnostics/tool.js.map +1 -0
- package/dist/engine/asset-sources.d.ts +8 -0
- package/dist/engine/asset-sources.d.ts.map +1 -1
- package/dist/engine/asset-sources.js +9 -2
- package/dist/engine/asset-sources.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/engine/uri-resolver.js.map +1 -1
- package/dist/server.d.ts +25 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +24 -4
- package/dist/server.js.map +1 -1
- package/dist/tools/engine.d.ts +92 -14
- package/dist/tools/engine.d.ts.map +1 -1
- package/dist/tools/engine.js +147 -20
- package/dist/tools/engine.js.map +1 -1
- package/dist/tools/export.d.ts.map +1 -1
- package/dist/tools/export.js +34 -4
- package/dist/tools/export.js.map +1 -1
- package/dist/tools/index.js +2 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/load.d.ts.map +1 -1
- package/dist/tools/load.js +26 -19
- package/dist/tools/load.js.map +1 -1
- package/dist/tools/preview.d.ts.map +1 -1
- package/dist/tools/preview.js +60 -40
- package/dist/tools/preview.js.map +1 -1
- package/dist/tools/{open-editor.d.ts → view.d.ts} +3 -3
- package/dist/tools/view.d.ts.map +1 -0
- package/dist/tools/{open-editor.js → view.js} +20 -18
- package/dist/tools/view.js.map +1 -0
- package/dist/viewer/listener.d.ts +2 -0
- package/dist/viewer/listener.d.ts.map +1 -1
- package/dist/viewer/listener.js +2 -0
- package/dist/viewer/listener.js.map +1 -1
- package/dist/viewer/presigned-r2-url-builder.d.ts +1 -1
- package/dist/viewer/presigned-r2-url-builder.js +1 -1
- package/dist/viewer/presigned-r2-url-builder.js.map +1 -1
- package/dist/viewer/router.d.ts.map +1 -1
- package/dist/viewer/router.js +8 -17
- package/dist/viewer/router.js.map +1 -1
- package/dist/viewer/session-mount.js.map +1 -1
- package/dist/viewer/spa-assets.generated.d.ts.map +1 -1
- package/dist/viewer/spa-assets.generated.js +750 -869
- package/dist/viewer/spa-assets.generated.js.map +1 -1
- package/dist/viewer/url-builder.d.ts +4 -3
- package/dist/viewer/url-builder.d.ts.map +1 -1
- package/dist/viewer/url-builder.js +4 -4
- package/dist/viewer/url-builder.js.map +1 -1
- package/package.json +7 -6
- 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.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
- package/dist/tools/open-editor.d.ts.map +0 -1
- package/dist/tools/open-editor.js.map +0 -1
- /package/dist/{dashboard → diagnostics}/spa-assets.generated.d.ts +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../../src/metrics/mount.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAW/D,MAAM,UAAU,qBAAqB,CACnC,GAAY,EACZ,IAAyB;IAEzB,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAChC,GAAG,CAAC,IAAI,CAAC;YACP,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;YAC3B,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE;YACrC,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;SAC9C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,qBAAqB,EAAE,CAAC,CAAC;AACjD,CAAC","sourcesContent":["// packages/codesign-mcp/src/metrics/mount.ts\n//\n// Mounts the metrics surface — GET /metrics (JSON) + the /dashboard SPA — onto\n// an Express app. Factored out of the HTTP composition root so the route and\n// its merged-snapshot shape are unit-testable without booting a real engine.\n// The route reads server-level facts (active sessions, uptime) LIVE at request\n// time; the recorder owns only the per-tool/memory state.\nimport type { Express } from 'express';\nimport { createDashboardRouter } from '../dashboard/router.js';\nimport type { MetricsRecorder } from './recorder.js';\n\nexport interface MountMetricsOptions {\n recorder: MetricsRecorder;\n /** The session/RAM cap (ServerConfig.maxEngines) — the gauge denominator. */\n maxSessions: number;\n /** Live active-session count, read at request time. */\n activeSessions: () => number;\n}\n\nexport function mountMetricsEndpoints(\n app: Express,\n opts: MountMetricsOptions\n): void {\n app.get('/metrics', (_req, res) => {\n res.json({\n ...opts.recorder.snapshot(),\n activeSessions: opts.activeSessions(),\n maxSessions: opts.maxSessions,\n uptimeMs: Math.round(process.uptime() * 1000)\n });\n });\n app.use('/dashboard', createDashboardRouter());\n}\n"]}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
export interface MetricsRecorderOptions {
|
|
2
|
-
/** Max tool-call records kept in the recent-calls ring. Default 100. */
|
|
3
|
-
recentLimit?: number;
|
|
4
|
-
/** Max per-tool durations retained for percentile math. Default 256. */
|
|
5
|
-
sampleSize?: number;
|
|
6
|
-
/** Process-memory sampling interval in ms. Default 5000. */
|
|
7
|
-
memorySampleMs?: number;
|
|
8
|
-
}
|
|
9
|
-
export interface ToolStat {
|
|
10
|
-
tool: string;
|
|
11
|
-
count: number;
|
|
12
|
-
errorCount: number;
|
|
13
|
-
min: number;
|
|
14
|
-
max: number;
|
|
15
|
-
mean: number;
|
|
16
|
-
p50: number;
|
|
17
|
-
p95: number;
|
|
18
|
-
}
|
|
19
|
-
export interface MemorySample {
|
|
20
|
-
rss: number;
|
|
21
|
-
heapUsed: number;
|
|
22
|
-
external: number;
|
|
23
|
-
arrayBuffers: number;
|
|
24
|
-
}
|
|
25
|
-
export interface ToolCallRecord {
|
|
26
|
-
tool: string;
|
|
27
|
-
durationMs: number;
|
|
28
|
-
ok: boolean;
|
|
29
|
-
ts: number;
|
|
30
|
-
}
|
|
31
|
-
export interface MetricsSnapshot {
|
|
32
|
-
tools: ToolStat[];
|
|
33
|
-
recent: ToolCallRecord[];
|
|
34
|
-
memory: MemorySample | null;
|
|
35
|
-
}
|
|
36
|
-
export declare class MetricsRecorder {
|
|
37
|
-
private readonly recentLimit;
|
|
38
|
-
private readonly sampleSize;
|
|
39
|
-
private readonly memorySampleMs;
|
|
40
|
-
private readonly recent;
|
|
41
|
-
private readonly tools;
|
|
42
|
-
private memory;
|
|
43
|
-
private timer;
|
|
44
|
-
constructor(opts?: MetricsRecorderOptions);
|
|
45
|
-
record(event: {
|
|
46
|
-
tool: string;
|
|
47
|
-
durationMs: number;
|
|
48
|
-
ok: boolean;
|
|
49
|
-
}): void;
|
|
50
|
-
sampleMemory(): void;
|
|
51
|
-
start(): void;
|
|
52
|
-
stop(): void;
|
|
53
|
-
snapshot(): MetricsSnapshot;
|
|
54
|
-
}
|
|
55
|
-
//# sourceMappingURL=recorder.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/metrics/recorder.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,sBAAsB;IACrC,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,OAAO,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;CAC7B;AAiBD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8B;IACpD,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,KAAK,CAA+C;gBAEhD,IAAI,GAAE,sBAA2B;IAM7C,MAAM,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAoBtE,YAAY,IAAI,IAAI;IAUpB,KAAK,IAAI,IAAI;IAQb,IAAI,IAAI,IAAI;IAMZ,QAAQ,IAAI,eAAe;CAmB5B"}
|
package/dist/metrics/recorder.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
// packages/codesign-mcp/src/metrics/recorder.ts
|
|
2
|
-
//
|
|
3
|
-
// In-memory, process-global performance recorder for the MCP server. Times
|
|
4
|
-
// every tool call (TOTAL wall-time only — "Approach A"), samples process
|
|
5
|
-
// memory on a timer, and exposes a point-in-time snapshot for the /metrics
|
|
6
|
-
// route and the dashboard SPA. Ephemeral: all state lives in memory and resets
|
|
7
|
-
// on restart. No persistence, no time-series, no secrets.
|
|
8
|
-
//
|
|
9
|
-
// APPROACH-A LIMITATION (deliberate, design §3): the recorder is fed by a
|
|
10
|
-
// single wrapper AROUND each tool call (see server.ts), so it observes only
|
|
11
|
-
// total wall-time. It cannot split engine-lock wait from execution, nor detect
|
|
12
|
-
// a cold engine reload — those happen INSIDE the call and are invisible to an
|
|
13
|
-
// outer wrapper. The deeper splits are a future addition (design §8) and must
|
|
14
|
-
// NOT couple Mutex / EngineSession to this recorder.
|
|
15
|
-
/** Nearest-rank percentile over an ascending-sorted sample. */
|
|
16
|
-
function percentile(sorted, p) {
|
|
17
|
-
if (sorted.length === 0)
|
|
18
|
-
return 0;
|
|
19
|
-
const rank = Math.ceil((p / 100) * sorted.length);
|
|
20
|
-
const idx = Math.min(sorted.length - 1, Math.max(0, rank - 1));
|
|
21
|
-
return sorted[idx];
|
|
22
|
-
}
|
|
23
|
-
export class MetricsRecorder {
|
|
24
|
-
constructor(opts = {}) {
|
|
25
|
-
this.recent = [];
|
|
26
|
-
this.tools = new Map();
|
|
27
|
-
this.memory = null;
|
|
28
|
-
this.timer = null;
|
|
29
|
-
this.recentLimit = opts.recentLimit ?? 100;
|
|
30
|
-
this.sampleSize = opts.sampleSize ?? 256;
|
|
31
|
-
this.memorySampleMs = opts.memorySampleMs ?? 5000;
|
|
32
|
-
}
|
|
33
|
-
record(event) {
|
|
34
|
-
this.recent.push({
|
|
35
|
-
tool: event.tool,
|
|
36
|
-
durationMs: event.durationMs,
|
|
37
|
-
ok: event.ok,
|
|
38
|
-
ts: Date.now()
|
|
39
|
-
});
|
|
40
|
-
if (this.recent.length > this.recentLimit)
|
|
41
|
-
this.recent.shift();
|
|
42
|
-
let agg = this.tools.get(event.tool);
|
|
43
|
-
if (!agg) {
|
|
44
|
-
agg = { count: 0, errorCount: 0, durations: [] };
|
|
45
|
-
this.tools.set(event.tool, agg);
|
|
46
|
-
}
|
|
47
|
-
agg.count += 1;
|
|
48
|
-
if (!event.ok)
|
|
49
|
-
agg.errorCount += 1;
|
|
50
|
-
agg.durations.push(event.durationMs);
|
|
51
|
-
if (agg.durations.length > this.sampleSize)
|
|
52
|
-
agg.durations.shift();
|
|
53
|
-
}
|
|
54
|
-
sampleMemory() {
|
|
55
|
-
const m = process.memoryUsage();
|
|
56
|
-
this.memory = {
|
|
57
|
-
rss: m.rss,
|
|
58
|
-
heapUsed: m.heapUsed,
|
|
59
|
-
external: m.external,
|
|
60
|
-
arrayBuffers: m.arrayBuffers
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
start() {
|
|
64
|
-
if (this.timer)
|
|
65
|
-
return;
|
|
66
|
-
this.sampleMemory(); // seed so the first snapshot isn't null
|
|
67
|
-
this.timer = setInterval(() => this.sampleMemory(), this.memorySampleMs);
|
|
68
|
-
// Never keep the event loop alive on the metrics timer alone.
|
|
69
|
-
this.timer.unref();
|
|
70
|
-
}
|
|
71
|
-
stop() {
|
|
72
|
-
if (!this.timer)
|
|
73
|
-
return;
|
|
74
|
-
clearInterval(this.timer);
|
|
75
|
-
this.timer = null;
|
|
76
|
-
}
|
|
77
|
-
snapshot() {
|
|
78
|
-
const tools = [];
|
|
79
|
-
for (const [tool, agg] of this.tools) {
|
|
80
|
-
const sorted = [...agg.durations].sort((a, b) => a - b);
|
|
81
|
-
const n = sorted.length;
|
|
82
|
-
const sum = sorted.reduce((s, d) => s + d, 0);
|
|
83
|
-
tools.push({
|
|
84
|
-
tool,
|
|
85
|
-
count: agg.count,
|
|
86
|
-
errorCount: agg.errorCount,
|
|
87
|
-
min: n ? sorted[0] : 0,
|
|
88
|
-
max: n ? sorted[n - 1] : 0,
|
|
89
|
-
mean: n ? sum / n : 0,
|
|
90
|
-
p50: percentile(sorted, 50),
|
|
91
|
-
p95: percentile(sorted, 95)
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
return { tools, recent: [...this.recent], memory: this.memory };
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
//# sourceMappingURL=recorder.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../src/metrics/recorder.ts"],"names":[],"mappings":"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","sourcesContent":["// packages/codesign-mcp/src/metrics/recorder.ts\n//\n// In-memory, process-global performance recorder for the MCP server. Times\n// every tool call (TOTAL wall-time only — \"Approach A\"), samples process\n// memory on a timer, and exposes a point-in-time snapshot for the /metrics\n// route and the dashboard SPA. Ephemeral: all state lives in memory and resets\n// on restart. No persistence, no time-series, no secrets.\n//\n// APPROACH-A LIMITATION (deliberate, design §3): the recorder is fed by a\n// single wrapper AROUND each tool call (see server.ts), so it observes only\n// total wall-time. It cannot split engine-lock wait from execution, nor detect\n// a cold engine reload — those happen INSIDE the call and are invisible to an\n// outer wrapper. The deeper splits are a future addition (design §8) and must\n// NOT couple Mutex / EngineSession to this recorder.\n\nexport interface MetricsRecorderOptions {\n /** Max tool-call records kept in the recent-calls ring. Default 100. */\n recentLimit?: number;\n /** Max per-tool durations retained for percentile math. Default 256. */\n sampleSize?: number;\n /** Process-memory sampling interval in ms. Default 5000. */\n memorySampleMs?: number;\n}\n\nexport interface ToolStat {\n tool: string;\n count: number;\n errorCount: number;\n min: number;\n max: number;\n mean: number;\n p50: number;\n p95: number;\n}\n\nexport interface MemorySample {\n rss: number;\n heapUsed: number;\n external: number;\n arrayBuffers: number;\n}\n\nexport interface ToolCallRecord {\n tool: string;\n durationMs: number;\n ok: boolean;\n ts: number;\n}\n\nexport interface MetricsSnapshot {\n tools: ToolStat[];\n recent: ToolCallRecord[];\n memory: MemorySample | null;\n}\n\n/** Per-tool running aggregate. `durations` is a bounded, most-recent sample. */\ninterface ToolAgg {\n count: number; // lifetime\n errorCount: number; // lifetime\n durations: number[]; // bounded to sampleSize; oldest shifted out\n}\n\n/** Nearest-rank percentile over an ascending-sorted sample. */\nfunction percentile(sorted: number[], p: number): number {\n if (sorted.length === 0) return 0;\n const rank = Math.ceil((p / 100) * sorted.length);\n const idx = Math.min(sorted.length - 1, Math.max(0, rank - 1));\n return sorted[idx];\n}\n\nexport class MetricsRecorder {\n private readonly recentLimit: number;\n private readonly sampleSize: number;\n private readonly memorySampleMs: number;\n private readonly recent: ToolCallRecord[] = [];\n private readonly tools = new Map<string, ToolAgg>();\n private memory: MemorySample | null = null;\n private timer: ReturnType<typeof setInterval> | null = null;\n\n constructor(opts: MetricsRecorderOptions = {}) {\n this.recentLimit = opts.recentLimit ?? 100;\n this.sampleSize = opts.sampleSize ?? 256;\n this.memorySampleMs = opts.memorySampleMs ?? 5000;\n }\n\n record(event: { tool: string; durationMs: number; ok: boolean }): void {\n this.recent.push({\n tool: event.tool,\n durationMs: event.durationMs,\n ok: event.ok,\n ts: Date.now()\n });\n if (this.recent.length > this.recentLimit) this.recent.shift();\n\n let agg = this.tools.get(event.tool);\n if (!agg) {\n agg = { count: 0, errorCount: 0, durations: [] };\n this.tools.set(event.tool, agg);\n }\n agg.count += 1;\n if (!event.ok) agg.errorCount += 1;\n agg.durations.push(event.durationMs);\n if (agg.durations.length > this.sampleSize) agg.durations.shift();\n }\n\n sampleMemory(): void {\n const m = process.memoryUsage();\n this.memory = {\n rss: m.rss,\n heapUsed: m.heapUsed,\n external: m.external,\n arrayBuffers: m.arrayBuffers\n };\n }\n\n start(): void {\n if (this.timer) return;\n this.sampleMemory(); // seed so the first snapshot isn't null\n this.timer = setInterval(() => this.sampleMemory(), this.memorySampleMs);\n // Never keep the event loop alive on the metrics timer alone.\n this.timer.unref();\n }\n\n stop(): void {\n if (!this.timer) return;\n clearInterval(this.timer);\n this.timer = null;\n }\n\n snapshot(): MetricsSnapshot {\n const tools: ToolStat[] = [];\n for (const [tool, agg] of this.tools) {\n const sorted = [...agg.durations].sort((a, b) => a - b);\n const n = sorted.length;\n const sum = sorted.reduce((s, d) => s + d, 0);\n tools.push({\n tool,\n count: agg.count,\n errorCount: agg.errorCount,\n min: n ? sorted[0] : 0,\n max: n ? sorted[n - 1] : 0,\n mean: n ? sum / n : 0,\n p50: percentile(sorted, 50),\n p95: percentile(sorted, 95)\n });\n }\n return { tools, recent: [...this.recent], memory: this.memory };\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"changelog-add.d.ts","sourceRoot":"","sources":["../../../scripts/changelog-add.ts"],"names":[],"mappings":";AAOA,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,MAAM,CAAC,CAWlB"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// Create a new changelog-next entry from the template.
|
|
3
|
-
// Run via `node --experimental-strip-types` (see package.json).
|
|
4
|
-
import { copyFile, access } from 'node:fs/promises';
|
|
5
|
-
import { dirname, join } from 'node:path';
|
|
6
|
-
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
7
|
-
export function entryFileName(name) {
|
|
8
|
-
const sanitized = name
|
|
9
|
-
.replace(/[\\/]/g, '-')
|
|
10
|
-
.replace(/^-+/, '')
|
|
11
|
-
.replace(/\.md$/i, '');
|
|
12
|
-
return `${sanitized}.md`;
|
|
13
|
-
}
|
|
14
|
-
export async function addEntry(opts) {
|
|
15
|
-
const target = join(opts.entriesDir, entryFileName(opts.name));
|
|
16
|
-
let exists = true;
|
|
17
|
-
try {
|
|
18
|
-
await access(target);
|
|
19
|
-
}
|
|
20
|
-
catch {
|
|
21
|
-
exists = false;
|
|
22
|
-
}
|
|
23
|
-
if (exists)
|
|
24
|
-
throw new Error(`entry already exists: ${target}`);
|
|
25
|
-
await copyFile(opts.templatePath, target);
|
|
26
|
-
return target;
|
|
27
|
-
}
|
|
28
|
-
async function main() {
|
|
29
|
-
const name = process.argv[2];
|
|
30
|
-
if (!name) {
|
|
31
|
-
console.error('usage: node --experimental-strip-types scripts/changelog-add.ts <name>');
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
34
|
-
const here = dirname(fileURLToPath(import.meta.url));
|
|
35
|
-
const entriesDir = join(here, '..', 'changelog-next');
|
|
36
|
-
const target = await addEntry({
|
|
37
|
-
templatePath: join(entriesDir, '-template.md'),
|
|
38
|
-
entriesDir,
|
|
39
|
-
name
|
|
40
|
-
});
|
|
41
|
-
console.log(`created ${target} — edit it and commit.`);
|
|
42
|
-
}
|
|
43
|
-
if (process.argv[1] &&
|
|
44
|
-
import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
45
|
-
main().catch((err) => {
|
|
46
|
-
console.error(err instanceof Error ? err.message : String(err));
|
|
47
|
-
process.exit(1);
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
//# sourceMappingURL=changelog-add.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"changelog-add.js","sourceRoot":"","sources":["../../../scripts/changelog-add.ts"],"names":[],"mappings":";AACA,uDAAuD;AACvD,gEAAgE;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAExD,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,SAAS,GAAG,IAAI;SACnB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;SAClB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACzB,OAAO,GAAG,SAAS,KAAK,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAI9B;IACC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/D,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,GAAG,KAAK,CAAC;IACjB,CAAC;IACD,IAAI,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,MAAM,EAAE,CAAC,CAAC;IAC/D,MAAM,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CACX,wEAAwE,CACzE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC;QAC5B,YAAY,EAAE,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC;QAC9C,UAAU;QACV,IAAI;KACL,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,wBAAwB,CAAC,CAAC;AACzD,CAAC;AAED,IACE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACf,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EACvD,CAAC;IACD,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QAC5B,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["#!/usr/bin/env node\n// Create a new changelog-next entry from the template.\n// Run via `node --experimental-strip-types` (see package.json).\nimport { copyFile, access } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\n\nexport function entryFileName(name: string): string {\n const sanitized = name\n .replace(/[\\\\/]/g, '-')\n .replace(/^-+/, '')\n .replace(/\\.md$/i, '');\n return `${sanitized}.md`;\n}\n\nexport async function addEntry(opts: {\n templatePath: string;\n entriesDir: string;\n name: string;\n}): Promise<string> {\n const target = join(opts.entriesDir, entryFileName(opts.name));\n let exists = true;\n try {\n await access(target);\n } catch {\n exists = false;\n }\n if (exists) throw new Error(`entry already exists: ${target}`);\n await copyFile(opts.templatePath, target);\n return target;\n}\n\nasync function main(): Promise<void> {\n const name = process.argv[2];\n if (!name) {\n console.error(\n 'usage: node --experimental-strip-types scripts/changelog-add.ts <name>'\n );\n process.exit(1);\n }\n const here = dirname(fileURLToPath(import.meta.url));\n const entriesDir = join(here, '..', 'changelog-next');\n const target = await addEntry({\n templatePath: join(entriesDir, '-template.md'),\n entriesDir,\n name\n });\n console.log(`created ${target} — edit it and commit.`);\n}\n\nif (\n process.argv[1] &&\n import.meta.url === pathToFileURL(process.argv[1]).href\n) {\n main().catch((err: unknown) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n });\n}\n"]}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
export interface ChangelogEntry {
|
|
3
|
-
name: string;
|
|
4
|
-
type: string;
|
|
5
|
-
breaking: boolean;
|
|
6
|
-
body: string;
|
|
7
|
-
}
|
|
8
|
-
export interface GroupedEntries {
|
|
9
|
-
breaking: string[];
|
|
10
|
-
changes: string[];
|
|
11
|
-
fixed: string[];
|
|
12
|
-
deprecated: string[];
|
|
13
|
-
}
|
|
14
|
-
export declare function parseEntry(text: string): {
|
|
15
|
-
type: string;
|
|
16
|
-
breaking: boolean;
|
|
17
|
-
body: string;
|
|
18
|
-
};
|
|
19
|
-
export declare function groupEntries(entries: ChangelogEntry[]): GroupedEntries;
|
|
20
|
-
export declare function renderVersionSection(version: string, grouped: GroupedEntries, absorbedBody?: string): string;
|
|
21
|
-
export declare function extractUnreleased(md: string): {
|
|
22
|
-
body: string;
|
|
23
|
-
md: string;
|
|
24
|
-
};
|
|
25
|
-
export declare function hasVersion(md: string, version: string): boolean;
|
|
26
|
-
export declare function insertVersionSection(md: string, sectionMd: string): string;
|
|
27
|
-
export type CollateResult = {
|
|
28
|
-
noop: true;
|
|
29
|
-
} | {
|
|
30
|
-
noop: false;
|
|
31
|
-
section: string;
|
|
32
|
-
};
|
|
33
|
-
export declare function collateFiles(opts: {
|
|
34
|
-
entriesDir: string;
|
|
35
|
-
changelogPath: string;
|
|
36
|
-
version: string;
|
|
37
|
-
}): Promise<CollateResult>;
|
|
38
|
-
//# sourceMappingURL=changelog-collate.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"changelog-collate.d.ts","sourceRoot":"","sources":["../../../scripts/changelog-collate.ts"],"names":[],"mappings":";AAKA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AASD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd,CAiBA;AAGD,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,cAAc,CActE;AASD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,cAAc,EACvB,YAAY,SAAK,GAChB,MAAM,CAQR;AAmCD,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAO1E;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAI/D;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAI1E;AAMD,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAqB9E,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,aAAa,CAAC,CAkBzB"}
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// Collate changelog-next/*.md entries into CHANGELOG.md under `## Version <v>`.
|
|
3
|
-
// Run via `node --experimental-strip-types` (see package.json) — no build step.
|
|
4
|
-
// See docs/specs/2026-06-30-changelog-system-design.md.
|
|
5
|
-
const FENCE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
6
|
-
// Minimal frontmatter read for the two scalar keys we need. We intentionally do
|
|
7
|
-
// NOT reuse src/frontmatter.ts: it whitelists name/description, and importing it
|
|
8
|
-
// (a `.js` specifier resolving to src/frontmatter.js) would require a build
|
|
9
|
-
// before this script could run. Keeping it self-contained keeps collate
|
|
10
|
-
// build-free. Lines starting with `#` are comments; inline `# ...` is stripped.
|
|
11
|
-
export function parseEntry(text) {
|
|
12
|
-
const match = text.match(FENCE);
|
|
13
|
-
const block = match ? match[1] : '';
|
|
14
|
-
const body = (match ? text.slice(match[0].length) : text).trim();
|
|
15
|
-
let type = '';
|
|
16
|
-
let breaking = false;
|
|
17
|
-
for (const line of block.split(/\r?\n/)) {
|
|
18
|
-
const m = line.match(/^(type|breaking)\s*:\s*(.*)$/);
|
|
19
|
-
if (!m)
|
|
20
|
-
continue;
|
|
21
|
-
const value = m[2]
|
|
22
|
-
.replace(/\s+#.*$/, '')
|
|
23
|
-
.trim()
|
|
24
|
-
.toLowerCase();
|
|
25
|
-
if (m[1] === 'type')
|
|
26
|
-
type = value;
|
|
27
|
-
else
|
|
28
|
-
breaking = value === 'true';
|
|
29
|
-
}
|
|
30
|
-
return { type, breaking, body };
|
|
31
|
-
}
|
|
32
|
-
// Breaking entries go to `breaking` only (Option A). Unknown type -> changes.
|
|
33
|
-
export function groupEntries(entries) {
|
|
34
|
-
const grouped = {
|
|
35
|
-
breaking: [],
|
|
36
|
-
changes: [],
|
|
37
|
-
fixed: [],
|
|
38
|
-
deprecated: []
|
|
39
|
-
};
|
|
40
|
-
for (const e of [...entries].sort((a, b) => a.name.localeCompare(b.name))) {
|
|
41
|
-
if (e.breaking)
|
|
42
|
-
grouped.breaking.push(e.body);
|
|
43
|
-
else if (e.type === 'fixed')
|
|
44
|
-
grouped.fixed.push(e.body);
|
|
45
|
-
else if (e.type === 'deprecated')
|
|
46
|
-
grouped.deprecated.push(e.body);
|
|
47
|
-
else
|
|
48
|
-
grouped.changes.push(e.body);
|
|
49
|
-
}
|
|
50
|
-
return grouped;
|
|
51
|
-
}
|
|
52
|
-
const SECTIONS = [
|
|
53
|
-
{ key: 'breaking', heading: '### ⚠ Breaking' },
|
|
54
|
-
{ key: 'changes', heading: '### Changes' },
|
|
55
|
-
{ key: 'fixed', heading: '### Fixed' },
|
|
56
|
-
{ key: 'deprecated', heading: '### Deprecated' }
|
|
57
|
-
];
|
|
58
|
-
export function renderVersionSection(version, grouped, absorbedBody = '') {
|
|
59
|
-
const parts = [`## Version ${version}`];
|
|
60
|
-
for (const { key, heading } of SECTIONS) {
|
|
61
|
-
const bodies = grouped[key];
|
|
62
|
-
if (bodies.length)
|
|
63
|
-
parts.push(`${heading}\n\n${bodies.join('\n')}`);
|
|
64
|
-
}
|
|
65
|
-
if (absorbedBody.trim())
|
|
66
|
-
parts.push(absorbedBody.trim());
|
|
67
|
-
return parts.join('\n\n') + '\n';
|
|
68
|
-
}
|
|
69
|
-
// Split a CHANGELOG into the leading header (before the first `## `) and the
|
|
70
|
-
// `## `-delimited sections. `### ` subheadings stay inside a section's body.
|
|
71
|
-
function parseSections(md) {
|
|
72
|
-
let header = '';
|
|
73
|
-
const sections = [];
|
|
74
|
-
for (const part of md.split(/^(?=## )/m)) {
|
|
75
|
-
if (part.startsWith('## ')) {
|
|
76
|
-
const nl = part.indexOf('\n');
|
|
77
|
-
const heading = (nl === -1 ? part : part.slice(0, nl)).trim();
|
|
78
|
-
const body = (nl === -1 ? '' : part.slice(nl + 1)).trim();
|
|
79
|
-
sections.push({ heading, body });
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
header = part.replace(/\s+$/, '');
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return { header, sections };
|
|
86
|
-
}
|
|
87
|
-
function renderChangelog(header, sections) {
|
|
88
|
-
const blocks = sections.map((s) => s.body ? `${s.heading}\n\n${s.body}` : s.heading);
|
|
89
|
-
return [header, ...blocks].filter(Boolean).join('\n\n') + '\n';
|
|
90
|
-
}
|
|
91
|
-
export function extractUnreleased(md) {
|
|
92
|
-
const { header, sections } = parseSections(md);
|
|
93
|
-
const idx = sections.findIndex((s) => s.heading === '## Unreleased');
|
|
94
|
-
if (idx === -1)
|
|
95
|
-
return { body: '', md };
|
|
96
|
-
const body = sections[idx].body;
|
|
97
|
-
sections.splice(idx, 1);
|
|
98
|
-
return { body, md: renderChangelog(header, sections) };
|
|
99
|
-
}
|
|
100
|
-
export function hasVersion(md, version) {
|
|
101
|
-
return parseSections(md).sections.some((s) => s.heading === `## Version ${version}`);
|
|
102
|
-
}
|
|
103
|
-
export function insertVersionSection(md, sectionMd) {
|
|
104
|
-
const { header, sections } = parseSections(md);
|
|
105
|
-
const newSection = parseSections(sectionMd).sections[0];
|
|
106
|
-
return renderChangelog(header, [newSection, ...sections]);
|
|
107
|
-
}
|
|
108
|
-
import { readFile, writeFile, readdir, rm } from 'node:fs/promises';
|
|
109
|
-
import { dirname, join } from 'node:path';
|
|
110
|
-
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
111
|
-
async function readEntries(entriesDir) {
|
|
112
|
-
let names;
|
|
113
|
-
try {
|
|
114
|
-
names = await readdir(entriesDir);
|
|
115
|
-
}
|
|
116
|
-
catch (err) {
|
|
117
|
-
if (err.code === 'ENOENT')
|
|
118
|
-
return [];
|
|
119
|
-
throw err;
|
|
120
|
-
}
|
|
121
|
-
const files = names
|
|
122
|
-
.filter((n) => n.endsWith('.md') && !n.startsWith('-'))
|
|
123
|
-
.sort();
|
|
124
|
-
const entries = [];
|
|
125
|
-
for (const name of files) {
|
|
126
|
-
const text = await readFile(join(entriesDir, name), 'utf8');
|
|
127
|
-
entries.push({ name, ...parseEntry(text) });
|
|
128
|
-
}
|
|
129
|
-
return entries;
|
|
130
|
-
}
|
|
131
|
-
export async function collateFiles(opts) {
|
|
132
|
-
const { entriesDir, changelogPath, version } = opts;
|
|
133
|
-
const entries = await readEntries(entriesDir);
|
|
134
|
-
const existing = await readFile(changelogPath, 'utf8');
|
|
135
|
-
const { body: unreleasedBody, md: mdNoUnreleased } = extractUnreleased(existing);
|
|
136
|
-
if (entries.length === 0 && !unreleasedBody)
|
|
137
|
-
return { noop: true };
|
|
138
|
-
if (hasVersion(mdNoUnreleased, version)) {
|
|
139
|
-
throw new Error(`## Version ${version} already exists in ${changelogPath}`);
|
|
140
|
-
}
|
|
141
|
-
const section = renderVersionSection(version, groupEntries(entries), unreleasedBody);
|
|
142
|
-
await writeFile(changelogPath, insertVersionSection(mdNoUnreleased, section));
|
|
143
|
-
await Promise.all(entries.map((e) => rm(join(entriesDir, e.name))));
|
|
144
|
-
return { noop: false, section };
|
|
145
|
-
}
|
|
146
|
-
async function main() {
|
|
147
|
-
const version = process.argv[2];
|
|
148
|
-
if (!version) {
|
|
149
|
-
console.error('usage: node --experimental-strip-types scripts/changelog-collate.ts <version>');
|
|
150
|
-
process.exit(1);
|
|
151
|
-
}
|
|
152
|
-
const here = dirname(fileURLToPath(import.meta.url));
|
|
153
|
-
const result = await collateFiles({
|
|
154
|
-
entriesDir: join(here, '..', 'changelog-next'),
|
|
155
|
-
changelogPath: join(here, '..', 'CHANGELOG.md'),
|
|
156
|
-
version
|
|
157
|
-
});
|
|
158
|
-
if (result.noop) {
|
|
159
|
-
console.error('changelog: nothing to collate');
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
process.stdout.write(result.section);
|
|
163
|
-
}
|
|
164
|
-
if (process.argv[1] &&
|
|
165
|
-
import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
166
|
-
main().catch((err) => {
|
|
167
|
-
console.error(err instanceof Error ? err.message : String(err));
|
|
168
|
-
process.exit(1);
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
//# sourceMappingURL=changelog-collate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"changelog-collate.js","sourceRoot":"","sources":["../../../scripts/changelog-collate.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n// Collate changelog-next/*.md entries into CHANGELOG.md under `## Version <v>`.\n// Run via `node --experimental-strip-types` (see package.json) — no build step.\n// See docs/specs/2026-06-30-changelog-system-design.md.\n\nexport interface ChangelogEntry {\n name: string;\n type: string;\n breaking: boolean;\n body: string;\n}\n\nexport interface GroupedEntries {\n breaking: string[];\n changes: string[];\n fixed: string[];\n deprecated: string[];\n}\n\nconst FENCE = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?/;\n\n// Minimal frontmatter read for the two scalar keys we need. We intentionally do\n// NOT reuse src/frontmatter.ts: it whitelists name/description, and importing it\n// (a `.js` specifier resolving to src/frontmatter.js) would require a build\n// before this script could run. Keeping it self-contained keeps collate\n// build-free. Lines starting with `#` are comments; inline `# ...` is stripped.\nexport function parseEntry(text: string): {\n type: string;\n breaking: boolean;\n body: string;\n} {\n const match = text.match(FENCE);\n const block = match ? match[1] : '';\n const body = (match ? text.slice(match[0].length) : text).trim();\n let type = '';\n let breaking = false;\n for (const line of block.split(/\\r?\\n/)) {\n const m = line.match(/^(type|breaking)\\s*:\\s*(.*)$/);\n if (!m) continue;\n const value = m[2]\n .replace(/\\s+#.*$/, '')\n .trim()\n .toLowerCase();\n if (m[1] === 'type') type = value;\n else breaking = value === 'true';\n }\n return { type, breaking, body };\n}\n\n// Breaking entries go to `breaking` only (Option A). Unknown type -> changes.\nexport function groupEntries(entries: ChangelogEntry[]): GroupedEntries {\n const grouped: GroupedEntries = {\n breaking: [],\n changes: [],\n fixed: [],\n deprecated: []\n };\n for (const e of [...entries].sort((a, b) => a.name.localeCompare(b.name))) {\n if (e.breaking) grouped.breaking.push(e.body);\n else if (e.type === 'fixed') grouped.fixed.push(e.body);\n else if (e.type === 'deprecated') grouped.deprecated.push(e.body);\n else grouped.changes.push(e.body);\n }\n return grouped;\n}\n\nconst SECTIONS: { key: keyof GroupedEntries; heading: string }[] = [\n { key: 'breaking', heading: '### ⚠ Breaking' },\n { key: 'changes', heading: '### Changes' },\n { key: 'fixed', heading: '### Fixed' },\n { key: 'deprecated', heading: '### Deprecated' }\n];\n\nexport function renderVersionSection(\n version: string,\n grouped: GroupedEntries,\n absorbedBody = ''\n): string {\n const parts = [`## Version ${version}`];\n for (const { key, heading } of SECTIONS) {\n const bodies = grouped[key];\n if (bodies.length) parts.push(`${heading}\\n\\n${bodies.join('\\n')}`);\n }\n if (absorbedBody.trim()) parts.push(absorbedBody.trim());\n return parts.join('\\n\\n') + '\\n';\n}\n\ninterface MarkdownSection {\n heading: string;\n body: string;\n}\n\n// Split a CHANGELOG into the leading header (before the first `## `) and the\n// `## `-delimited sections. `### ` subheadings stay inside a section's body.\nfunction parseSections(md: string): {\n header: string;\n sections: MarkdownSection[];\n} {\n let header = '';\n const sections: MarkdownSection[] = [];\n for (const part of md.split(/^(?=## )/m)) {\n if (part.startsWith('## ')) {\n const nl = part.indexOf('\\n');\n const heading = (nl === -1 ? part : part.slice(0, nl)).trim();\n const body = (nl === -1 ? '' : part.slice(nl + 1)).trim();\n sections.push({ heading, body });\n } else {\n header = part.replace(/\\s+$/, '');\n }\n }\n return { header, sections };\n}\n\nfunction renderChangelog(header: string, sections: MarkdownSection[]): string {\n const blocks = sections.map((s) =>\n s.body ? `${s.heading}\\n\\n${s.body}` : s.heading\n );\n return [header, ...blocks].filter(Boolean).join('\\n\\n') + '\\n';\n}\n\nexport function extractUnreleased(md: string): { body: string; md: string } {\n const { header, sections } = parseSections(md);\n const idx = sections.findIndex((s) => s.heading === '## Unreleased');\n if (idx === -1) return { body: '', md };\n const body = sections[idx].body;\n sections.splice(idx, 1);\n return { body, md: renderChangelog(header, sections) };\n}\n\nexport function hasVersion(md: string, version: string): boolean {\n return parseSections(md).sections.some(\n (s) => s.heading === `## Version ${version}`\n );\n}\n\nexport function insertVersionSection(md: string, sectionMd: string): string {\n const { header, sections } = parseSections(md);\n const newSection = parseSections(sectionMd).sections[0];\n return renderChangelog(header, [newSection, ...sections]);\n}\n\nimport { readFile, writeFile, readdir, rm } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\n\nexport type CollateResult = { noop: true } | { noop: false; section: string };\n\nasync function readEntries(entriesDir: string): Promise<ChangelogEntry[]> {\n let names: string[];\n try {\n names = await readdir(entriesDir);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n throw err;\n }\n const files = names\n .filter((n) => n.endsWith('.md') && !n.startsWith('-'))\n .sort();\n const entries: ChangelogEntry[] = [];\n for (const name of files) {\n const text = await readFile(join(entriesDir, name), 'utf8');\n entries.push({ name, ...parseEntry(text) });\n }\n return entries;\n}\n\nexport async function collateFiles(opts: {\n entriesDir: string;\n changelogPath: string;\n version: string;\n}): Promise<CollateResult> {\n const { entriesDir, changelogPath, version } = opts;\n const entries = await readEntries(entriesDir);\n const existing = await readFile(changelogPath, 'utf8');\n const { body: unreleasedBody, md: mdNoUnreleased } =\n extractUnreleased(existing);\n if (entries.length === 0 && !unreleasedBody) return { noop: true };\n if (hasVersion(mdNoUnreleased, version)) {\n throw new Error(`## Version ${version} already exists in ${changelogPath}`);\n }\n const section = renderVersionSection(\n version,\n groupEntries(entries),\n unreleasedBody\n );\n await writeFile(changelogPath, insertVersionSection(mdNoUnreleased, section));\n await Promise.all(entries.map((e) => rm(join(entriesDir, e.name))));\n return { noop: false, section };\n}\n\nasync function main(): Promise<void> {\n const version = process.argv[2];\n if (!version) {\n console.error(\n 'usage: node --experimental-strip-types scripts/changelog-collate.ts <version>'\n );\n process.exit(1);\n }\n const here = dirname(fileURLToPath(import.meta.url));\n const result = await collateFiles({\n entriesDir: join(here, '..', 'changelog-next'),\n changelogPath: join(here, '..', 'CHANGELOG.md'),\n version\n });\n if (result.noop) {\n console.error('changelog: nothing to collate');\n return;\n }\n process.stdout.write(result.section);\n}\n\nif (\n process.argv[1] &&\n import.meta.url === pathToFileURL(process.argv[1]).href\n) {\n main().catch((err: unknown) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n });\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"changelog.test.d.ts","sourceRoot":"","sources":["../../../test/changelog.test.ts"],"names":[],"mappings":""}
|