@imgly/codesign-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +16 -0
- package/README.md +158 -0
- package/assets/docs/api/SKILL.md +49 -0
- package/assets/docs/api/index.d.ts +10518 -0
- package/assets/docs/guide/SKILL.md +142 -0
- package/assets/docs/guide/actions.md +1038 -0
- package/assets/docs/guide/animation/create/base.md +467 -0
- package/assets/docs/guide/animation/create/text.md +453 -0
- package/assets/docs/guide/animation/create.md +558 -0
- package/assets/docs/guide/animation/edit.md +501 -0
- package/assets/docs/guide/animation/overview.md +22 -0
- package/assets/docs/guide/animation/types.md +430 -0
- package/assets/docs/guide/animation.md +23 -0
- package/assets/docs/guide/api/AssetAPI.md +602 -0
- package/assets/docs/guide/api/BlockAPI.md +6152 -0
- package/assets/docs/guide/api/CreativeEngine.md +180 -0
- package/assets/docs/guide/api/EditorAPI.md +1261 -0
- package/assets/docs/guide/api/EventAPI.md +25 -0
- package/assets/docs/guide/api/SceneAPI.md +729 -0
- package/assets/docs/guide/api/VariableAPI.md +59 -0
- package/assets/docs/guide/api/types.md +71 -0
- package/assets/docs/guide/api-reference/overview.md +20 -0
- package/assets/docs/guide/automation/auto-resize.md +412 -0
- package/assets/docs/guide/automation/batch-processing.md +474 -0
- package/assets/docs/guide/automation/data-merge.md +406 -0
- package/assets/docs/guide/automation/design-generation.md +107 -0
- package/assets/docs/guide/automation/overview.md +16 -0
- package/assets/docs/guide/automation.md +24 -0
- package/assets/docs/guide/browser-support.md +38 -0
- package/assets/docs/guide/capabilities.md +18 -0
- package/assets/docs/guide/colors/adjust.md +551 -0
- package/assets/docs/guide/colors/apply.md +349 -0
- package/assets/docs/guide/colors/basics.md +440 -0
- package/assets/docs/guide/colors/conversion.md +504 -0
- package/assets/docs/guide/colors/create-color-palette.md +426 -0
- package/assets/docs/guide/colors/for-print/cmyk.md +577 -0
- package/assets/docs/guide/colors/for-print/spot.md +751 -0
- package/assets/docs/guide/colors/for-print.md +21 -0
- package/assets/docs/guide/colors/for-screen/p3.md +60 -0
- package/assets/docs/guide/colors/for-screen/srgb.md +463 -0
- package/assets/docs/guide/colors/for-screen.md +21 -0
- package/assets/docs/guide/colors/overview.md +20 -0
- package/assets/docs/guide/colors/replace.md +535 -0
- package/assets/docs/guide/colors.md +28 -0
- package/assets/docs/guide/compatibility.md +27 -0
- package/assets/docs/guide/concepts/architecture.md +99 -0
- package/assets/docs/guide/concepts/assets.md +360 -0
- package/assets/docs/guide/concepts/blocks.md +750 -0
- package/assets/docs/guide/concepts/buffers.md +546 -0
- package/assets/docs/guide/concepts/design-units.md +333 -0
- package/assets/docs/guide/concepts/edit-modes.md +431 -0
- package/assets/docs/guide/concepts/editing-workflow.md +303 -0
- package/assets/docs/guide/concepts/events.md +466 -0
- package/assets/docs/guide/concepts/headless-mode/browser.md +291 -0
- package/assets/docs/guide/concepts/pages.md +396 -0
- package/assets/docs/guide/concepts/resources.md +496 -0
- package/assets/docs/guide/concepts/scenes.md +443 -0
- package/assets/docs/guide/concepts/templating.md +194 -0
- package/assets/docs/guide/concepts/terminology.md +296 -0
- package/assets/docs/guide/concepts/undo-and-history.md +461 -0
- package/assets/docs/guide/concepts.md +38 -0
- package/assets/docs/guide/configuration.md +469 -0
- package/assets/docs/guide/conversion/overview.md +22 -0
- package/assets/docs/guide/conversion/to-base64.md +234 -0
- package/assets/docs/guide/conversion/to-pdf.md +616 -0
- package/assets/docs/guide/conversion/to-png.md +290 -0
- package/assets/docs/guide/conversion.md +23 -0
- package/assets/docs/guide/create-audio/audio/add-music.md +430 -0
- package/assets/docs/guide/create-audio/audio/add-sound-effects.md +664 -0
- package/assets/docs/guide/create-audio/audio/loop.md +370 -0
- package/assets/docs/guide/create-audio/audio.md +336 -0
- package/assets/docs/guide/create-composition/add-background.md +395 -0
- package/assets/docs/guide/create-composition/blend-modes.md +372 -0
- package/assets/docs/guide/create-composition/collage.md +432 -0
- package/assets/docs/guide/create-composition/group-and-ungroup.md +388 -0
- package/assets/docs/guide/create-composition/layer-management.md +503 -0
- package/assets/docs/guide/create-composition/layout.md +396 -0
- package/assets/docs/guide/create-composition/lock-design.md +362 -0
- package/assets/docs/guide/create-composition/multi-page.md +204 -0
- package/assets/docs/guide/create-composition/overview.md +18 -0
- package/assets/docs/guide/create-composition/programmatic.md +593 -0
- package/assets/docs/guide/create-composition.md +30 -0
- package/assets/docs/guide/create-templates/add-dynamic-content/placeholders.md +688 -0
- package/assets/docs/guide/create-templates/add-dynamic-content/set-editing-constraints.md +600 -0
- package/assets/docs/guide/create-templates/add-dynamic-content/text-variables.md +647 -0
- package/assets/docs/guide/create-templates/add-dynamic-content.md +307 -0
- package/assets/docs/guide/create-templates/add-to-template-library.md +297 -0
- package/assets/docs/guide/create-templates/edit-or-remove.md +441 -0
- package/assets/docs/guide/create-templates/from-scratch.md +558 -0
- package/assets/docs/guide/create-templates/import/from-scene-file.md +440 -0
- package/assets/docs/guide/create-templates/import.md +244 -0
- package/assets/docs/guide/create-templates/lock.md +325 -0
- package/assets/docs/guide/create-templates/overview.md +16 -0
- package/assets/docs/guide/create-templates.md +32 -0
- package/assets/docs/guide/create-video/audio/adjust-speed.md +302 -0
- package/assets/docs/guide/create-video/audio/adjust-volume.md +346 -0
- package/assets/docs/guide/create-video/control.md +285 -0
- package/assets/docs/guide/create-video/limitations.md +396 -0
- package/assets/docs/guide/create-video/overview.md +224 -0
- package/assets/docs/guide/create-video/timeline-editor.md +622 -0
- package/assets/docs/guide/create-video/update-caption-presets.md +676 -0
- package/assets/docs/guide/create-video.md +32 -0
- package/assets/docs/guide/edit-image/add-watermark.md +497 -0
- package/assets/docs/guide/edit-image/overview.md +22 -0
- package/assets/docs/guide/edit-image/remove-bg.md +420 -0
- package/assets/docs/guide/edit-image/replace-colors.md +680 -0
- package/assets/docs/guide/edit-image/transform/crop.md +523 -0
- package/assets/docs/guide/edit-image/transform/move.md +279 -0
- package/assets/docs/guide/edit-image/transform/resize.md +301 -0
- package/assets/docs/guide/edit-image/transform/rotate.md +408 -0
- package/assets/docs/guide/edit-image/transform/scale.md +278 -0
- package/assets/docs/guide/edit-image/transform.md +24 -0
- package/assets/docs/guide/edit-image/vectorize.md +204 -0
- package/assets/docs/guide/edit-image.md +25 -0
- package/assets/docs/guide/edit-video/add-captions.md +589 -0
- package/assets/docs/guide/edit-video/add-watermark.md +429 -0
- package/assets/docs/guide/edit-video/join-and-arrange.md +540 -0
- package/assets/docs/guide/edit-video/redaction.md +544 -0
- package/assets/docs/guide/edit-video/split.md +634 -0
- package/assets/docs/guide/edit-video/transform/crop.md +380 -0
- package/assets/docs/guide/edit-video/transform/flip.md +182 -0
- package/assets/docs/guide/edit-video/transform/move.md +413 -0
- package/assets/docs/guide/edit-video/transform/resize.md +534 -0
- package/assets/docs/guide/edit-video/transform/rotate.md +312 -0
- package/assets/docs/guide/edit-video/transform/scale.md +603 -0
- package/assets/docs/guide/edit-video/transform.md +25 -0
- package/assets/docs/guide/edit-video/trim.md +773 -0
- package/assets/docs/guide/engine-interface.md +108 -0
- package/assets/docs/guide/export-save-publish/create-thumbnail.md +292 -0
- package/assets/docs/guide/export-save-publish/export/compress.md +639 -0
- package/assets/docs/guide/export-save-publish/export/overview.md +576 -0
- package/assets/docs/guide/export-save-publish/export/partial-export.md +694 -0
- package/assets/docs/guide/export-save-publish/export/size-limits.md +401 -0
- package/assets/docs/guide/export-save-publish/export/to-html5.md +474 -0
- package/assets/docs/guide/export-save-publish/export/to-jpeg.md +312 -0
- package/assets/docs/guide/export-save-publish/export/to-mp4.md +364 -0
- package/assets/docs/guide/export-save-publish/export/to-pdf.md +389 -0
- package/assets/docs/guide/export-save-publish/export/to-png.md +255 -0
- package/assets/docs/guide/export-save-publish/export/to-raw-data.md +303 -0
- package/assets/docs/guide/export-save-publish/export/to-webp.md +261 -0
- package/assets/docs/guide/export-save-publish/export/with-color-mask.md +278 -0
- package/assets/docs/guide/export-save-publish/export.md +36 -0
- package/assets/docs/guide/export-save-publish/for-printing.md +423 -0
- package/assets/docs/guide/export-save-publish/for-social-media.md +318 -0
- package/assets/docs/guide/export-save-publish/pre-export-validation.md +698 -0
- package/assets/docs/guide/export-save-publish/save.md +340 -0
- package/assets/docs/guide/export-save-publish/store-custom-metadata.md +367 -0
- package/assets/docs/guide/file-format-support.md +34 -0
- package/assets/docs/guide/fills/color.md +678 -0
- package/assets/docs/guide/fills/image.md +539 -0
- package/assets/docs/guide/fills/overview.md +144 -0
- package/assets/docs/guide/fills/video.md +641 -0
- package/assets/docs/guide/fills.md +24 -0
- package/assets/docs/guide/filters-and-effects/apply.md +1019 -0
- package/assets/docs/guide/filters-and-effects/blur.md +382 -0
- package/assets/docs/guide/filters-and-effects/chroma-key-green-screen.md +445 -0
- package/assets/docs/guide/filters-and-effects/create-custom-filters.md +614 -0
- package/assets/docs/guide/filters-and-effects/create-custom-lut-filter.md +426 -0
- package/assets/docs/guide/filters-and-effects/distortion.md +527 -0
- package/assets/docs/guide/filters-and-effects/duotone.md +602 -0
- package/assets/docs/guide/filters-and-effects/gradients.md +1311 -0
- package/assets/docs/guide/filters-and-effects/overview.md +22 -0
- package/assets/docs/guide/filters-and-effects/support.md +623 -0
- package/assets/docs/guide/filters-and-effects.md +28 -0
- package/assets/docs/guide/get-started/agent-skills.md +119 -0
- package/assets/docs/guide/get-started/build-with-ai.md +45 -0
- package/assets/docs/guide/get-started/mcp-server.md +119 -0
- package/assets/docs/guide/get-started/overview.md +28 -0
- package/assets/docs/guide/get-started/vanilla-js/quickstart.md +175 -0
- package/assets/docs/guide/grid-and-rulers.md +222 -0
- package/assets/docs/guide/guides/export-save-publish/export/audio.md +224 -0
- package/assets/docs/guide/guides/text/rendering-internals.md +796 -0
- package/assets/docs/guide/guides.md +49 -0
- package/assets/docs/guide/import-media/asset-library.md +23 -0
- package/assets/docs/guide/import-media/asset-panel/basics.md +324 -0
- package/assets/docs/guide/import-media/asset-panel/customize.md +478 -0
- package/assets/docs/guide/import-media/asset-panel/refresh-assets.md +415 -0
- package/assets/docs/guide/import-media/asset-panel/thumbnails.md +633 -0
- package/assets/docs/guide/import-media/capture-from-camera/record-video.md +137 -0
- package/assets/docs/guide/import-media/capture-from-camera.md +20 -0
- package/assets/docs/guide/import-media/concepts.md +173 -0
- package/assets/docs/guide/import-media/content-json-schema.md +615 -0
- package/assets/docs/guide/import-media/default-assets.md +381 -0
- package/assets/docs/guide/import-media/edit-or-remove-assets.md +489 -0
- package/assets/docs/guide/import-media/file-format-support.md +178 -0
- package/assets/docs/guide/import-media/from-local-source/user-upload.md +438 -0
- package/assets/docs/guide/import-media/from-local-source.md +20 -0
- package/assets/docs/guide/import-media/from-remote-source/asset-versioning.md +390 -0
- package/assets/docs/guide/import-media/from-remote-source/getty-images.md +627 -0
- package/assets/docs/guide/import-media/from-remote-source/imgly-premium-assets.md +625 -0
- package/assets/docs/guide/import-media/from-remote-source/pexels.md +692 -0
- package/assets/docs/guide/import-media/from-remote-source/remote-asset.md +473 -0
- package/assets/docs/guide/import-media/from-remote-source/soundstripe.md +497 -0
- package/assets/docs/guide/import-media/from-remote-source/third-party.md +51 -0
- package/assets/docs/guide/import-media/from-remote-source/unsplash.md +914 -0
- package/assets/docs/guide/import-media/from-remote-source/your-server.md +764 -0
- package/assets/docs/guide/import-media/from-remote-source.md +28 -0
- package/assets/docs/guide/import-media/overview.md +32 -0
- package/assets/docs/guide/import-media/retrieve-mimetype.md +274 -0
- package/assets/docs/guide/import-media/size-limits.md +20 -0
- package/assets/docs/guide/import-media/source-sets.md +476 -0
- package/assets/docs/guide/import-media.md +32 -0
- package/assets/docs/guide/insert-media/audio.md +291 -0
- package/assets/docs/guide/insert-media/images.md +380 -0
- package/assets/docs/guide/insert-media/position-and-align.md +734 -0
- package/assets/docs/guide/insert-media/shapes-or-stickers.md +799 -0
- package/assets/docs/guide/insert-media/videos.md +308 -0
- package/assets/docs/guide/insert-media.md +24 -0
- package/assets/docs/guide/key-capabilities.md +24 -0
- package/assets/docs/guide/key-concepts.md +83 -0
- package/assets/docs/guide/licensing.md +45 -0
- package/assets/docs/guide/llms-txt.md +53 -0
- package/assets/docs/guide/open-the-editor/blank-canvas.md +124 -0
- package/assets/docs/guide/open-the-editor/from-htmlcanvas.md +228 -0
- package/assets/docs/guide/open-the-editor/from-image.md +205 -0
- package/assets/docs/guide/open-the-editor/from-template.md +189 -0
- package/assets/docs/guide/open-the-editor/from-video.md +274 -0
- package/assets/docs/guide/open-the-editor/import-design/from-archive.md +504 -0
- package/assets/docs/guide/open-the-editor/import-design/from-indesign.md +680 -0
- package/assets/docs/guide/open-the-editor/import-design/from-photoshop.md +865 -0
- package/assets/docs/guide/open-the-editor/import-design.md +481 -0
- package/assets/docs/guide/open-the-editor/load-scene.md +178 -0
- package/assets/docs/guide/open-the-editor/overview.md +20 -0
- package/assets/docs/guide/open-the-editor/set-zoom-level.md +303 -0
- package/assets/docs/guide/open-the-editor/uri-resolver.md +347 -0
- package/assets/docs/guide/open-the-editor.md +29 -0
- package/assets/docs/guide/outlines/overview.md +14 -0
- package/assets/docs/guide/outlines/shadows-and-glows.md +515 -0
- package/assets/docs/guide/outlines/strokes.md +292 -0
- package/assets/docs/guide/outlines.md +22 -0
- package/assets/docs/guide/overview.md +22 -0
- package/assets/docs/guide/performance.md +217 -0
- package/assets/docs/guide/plugins/asset-sources.md +553 -0
- package/assets/docs/guide/plugins/print-ready-pdf.md +549 -0
- package/assets/docs/guide/plugins.md +36 -0
- package/assets/docs/guide/rules/asset-handling.md +180 -0
- package/assets/docs/guide/rules/common-pitfalls.md +272 -0
- package/assets/docs/guide/rules/content-fill-mode.md +29 -0
- package/assets/docs/guide/rules/enforce-brand-guidelines.md +672 -0
- package/assets/docs/guide/rules/lock-content.md +478 -0
- package/assets/docs/guide/rules/moderate-content.md +761 -0
- package/assets/docs/guide/rules/overview.md +514 -0
- package/assets/docs/guide/rules/silent-init-errors.md +137 -0
- package/assets/docs/guide/rules/verify-properties-before-use.md +78 -0
- package/assets/docs/guide/rules.md +23 -0
- package/assets/docs/guide/security.md +199 -0
- package/assets/docs/guide/serve-assets.md +332 -0
- package/assets/docs/guide/settings.md +199 -0
- package/assets/docs/guide/shapes.md +23 -0
- package/assets/docs/guide/starterkits/3d-mockup-editor.md +748 -0
- package/assets/docs/guide/starterkits/advanced-editor.md +698 -0
- package/assets/docs/guide/starterkits/advanced-video-editor.md +696 -0
- package/assets/docs/guide/starterkits/ai-editor.md +749 -0
- package/assets/docs/guide/starterkits/airtable-image-editor.md +672 -0
- package/assets/docs/guide/starterkits/apparel-ui.md +188 -0
- package/assets/docs/guide/starterkits/assets.md +27 -0
- package/assets/docs/guide/starterkits/auto-resize.md +586 -0
- package/assets/docs/guide/starterkits/automated-video-generation.md +692 -0
- package/assets/docs/guide/starterkits/background-removal-editor.md +480 -0
- package/assets/docs/guide/starterkits/content-moderation.md +863 -0
- package/assets/docs/guide/starterkits/creative-automation.md +28 -0
- package/assets/docs/guide/starterkits/custom-built-uis.md +26 -0
- package/assets/docs/guide/starterkits/customization.md +29 -0
- package/assets/docs/guide/starterkits/cutout-lines-editor.md +470 -0
- package/assets/docs/guide/starterkits/data-merge.md +850 -0
- package/assets/docs/guide/starterkits/design-editor.md +698 -0
- package/assets/docs/guide/starterkits/design-generation.md +719 -0
- package/assets/docs/guide/starterkits/design-validation.md +808 -0
- package/assets/docs/guide/starterkits/editor-ui-configurations.md +14 -0
- package/assets/docs/guide/starterkits/export-options.md +724 -0
- package/assets/docs/guide/starterkits/export-using-renderer.md +708 -0
- package/assets/docs/guide/starterkits/extensibility.md +28 -0
- package/assets/docs/guide/starterkits/force-crop-editor.md +675 -0
- package/assets/docs/guide/starterkits/form-based-template-adoption.md +522 -0
- package/assets/docs/guide/starterkits/getty-images-editor.md +700 -0
- package/assets/docs/guide/starterkits/html5-ads-exporter.md +719 -0
- package/assets/docs/guide/starterkits/indesign-template-import.md +580 -0
- package/assets/docs/guide/starterkits/layouts-editor.md +724 -0
- package/assets/docs/guide/starterkits/mobile-ui.md +185 -0
- package/assets/docs/guide/starterkits/mockup-editor.md +745 -0
- package/assets/docs/guide/starterkits/multi-image-generation.md +542 -0
- package/assets/docs/guide/starterkits/page-sizes-editor.md +657 -0
- package/assets/docs/guide/starterkits/pexels-image-editor.md +665 -0
- package/assets/docs/guide/starterkits/photo-editor.md +755 -0
- package/assets/docs/guide/starterkits/photo-ui.md +186 -0
- package/assets/docs/guide/starterkits/photobook-ui.md +188 -0
- package/assets/docs/guide/starterkits/placeholders.md +678 -0
- package/assets/docs/guide/starterkits/player.md +405 -0
- package/assets/docs/guide/starterkits/plugins.md +25 -0
- package/assets/docs/guide/starterkits/postcard-editor.md +202 -0
- package/assets/docs/guide/starterkits/pptx-template-import.md +581 -0
- package/assets/docs/guide/starterkits/print-ready-pdf-editor.md +746 -0
- package/assets/docs/guide/starterkits/product-editor.md +773 -0
- package/assets/docs/guide/starterkits/psd-template-import.md +580 -0
- package/assets/docs/guide/starterkits/qr-code-editor.md +470 -0
- package/assets/docs/guide/starterkits/single-page-editor.md +661 -0
- package/assets/docs/guide/starterkits/start-with-image.md +684 -0
- package/assets/docs/guide/starterkits/start-with-video.md +651 -0
- package/assets/docs/guide/starterkits/t-shirt-designer.md +742 -0
- package/assets/docs/guide/starterkits/templating.md +23 -0
- package/assets/docs/guide/starterkits/theming.md +662 -0
- package/assets/docs/guide/starterkits/translation-internationalization.md +662 -0
- package/assets/docs/guide/starterkits/unsplash-editor.md +839 -0
- package/assets/docs/guide/starterkits/vectorizer-editor.md +466 -0
- package/assets/docs/guide/starterkits/version-history.md +745 -0
- package/assets/docs/guide/starterkits/video-animations.md +853 -0
- package/assets/docs/guide/starterkits/video-captions.md +884 -0
- package/assets/docs/guide/starterkits/video-editing.md +25 -0
- package/assets/docs/guide/starterkits/video-editor.md +696 -0
- package/assets/docs/guide/starterkits/video-export-options.md +676 -0
- package/assets/docs/guide/starterkits/viewer.md +400 -0
- package/assets/docs/guide/starterkits.md +41 -0
- package/assets/docs/guide/stickers-and-shapes/combine.md +743 -0
- package/assets/docs/guide/stickers-and-shapes/create-cutout.md +425 -0
- package/assets/docs/guide/stickers-and-shapes/create-edit/create-shapes.md +794 -0
- package/assets/docs/guide/stickers-and-shapes/create-edit/create-stickers.md +290 -0
- package/assets/docs/guide/stickers-and-shapes/create-edit/edit-shapes.md +211 -0
- package/assets/docs/guide/stickers-and-shapes/create-edit/vector-edit.md +362 -0
- package/assets/docs/guide/stickers-and-shapes/insert-qr-code.md +208 -0
- package/assets/docs/guide/stickers.md +21 -0
- package/assets/docs/guide/text/add.md +641 -0
- package/assets/docs/guide/text/adjust-spacing.md +288 -0
- package/assets/docs/guide/text/auto-size.md +404 -0
- package/assets/docs/guide/text/custom-fonts.md +401 -0
- package/assets/docs/guide/text/decorations.md +330 -0
- package/assets/docs/guide/text/edit.md +458 -0
- package/assets/docs/guide/text/effects.md +244 -0
- package/assets/docs/guide/text/emojis.md +310 -0
- package/assets/docs/guide/text/enumerations.md +258 -0
- package/assets/docs/guide/text/language-support.md +604 -0
- package/assets/docs/guide/text/overview.md +14 -0
- package/assets/docs/guide/text/styling.md +390 -0
- package/assets/docs/guide/text/text-designs.md +834 -0
- package/assets/docs/guide/text.md +33 -0
- package/assets/docs/guide/to-v1-10.md +131 -0
- package/assets/docs/guide/to-v1-13.md +165 -0
- package/assets/docs/guide/to-v1-19.md +315 -0
- package/assets/docs/guide/to-v1-32.md +110 -0
- package/assets/docs/guide/to-v1-69.md +468 -0
- package/assets/docs/guide/to-v1-72.md +193 -0
- package/assets/docs/guide/upgrade.md +25 -0
- package/assets/docs/guide/use-templates/apply-template.md +279 -0
- package/assets/docs/guide/use-templates/generate.md +405 -0
- package/assets/docs/guide/use-templates/library.md +450 -0
- package/assets/docs/guide/use-templates/overview.md +20 -0
- package/assets/docs/guide/use-templates/programmatic.md +482 -0
- package/assets/docs/guide/use-templates/replace-content.md +399 -0
- package/assets/docs/guide/user-interface/ai-integration/audio-generation.md +428 -0
- package/assets/docs/guide/user-interface/ai-integration/auto-captions.md +337 -0
- package/assets/docs/guide/user-interface/ai-integration/custom-provider.md +853 -0
- package/assets/docs/guide/user-interface/ai-integration/gateway-provider.md +1045 -0
- package/assets/docs/guide/user-interface/ai-integration/image-generation.md +641 -0
- package/assets/docs/guide/user-interface/ai-integration/integrate.md +966 -0
- package/assets/docs/guide/user-interface/ai-integration/proxy-server.md +99 -0
- package/assets/docs/guide/user-interface/ai-integration/text-generation.md +498 -0
- package/assets/docs/guide/user-interface/ai-integration/video-generation.md +493 -0
- package/assets/docs/guide/user-interface/ai-integration.md +30 -0
- package/assets/docs/guide/user-interface/appearance/change-ui-font.md +316 -0
- package/assets/docs/guide/user-interface/appearance/custom-labels.md +509 -0
- package/assets/docs/guide/user-interface/appearance/icons.md +373 -0
- package/assets/docs/guide/user-interface/appearance/theming.md +665 -0
- package/assets/docs/guide/user-interface/appearance.md +23 -0
- package/assets/docs/guide/user-interface/build-your-own-ui.md +620 -0
- package/assets/docs/guide/user-interface/customization/canvas-menu.md +412 -0
- package/assets/docs/guide/user-interface/customization/canvas.md +281 -0
- package/assets/docs/guide/user-interface/customization/color-palette.md +413 -0
- package/assets/docs/guide/user-interface/customization/crop-presets.md +384 -0
- package/assets/docs/guide/user-interface/customization/disable-or-enable.md +676 -0
- package/assets/docs/guide/user-interface/customization/dock.md +399 -0
- package/assets/docs/guide/user-interface/customization/force-crop.md +289 -0
- package/assets/docs/guide/user-interface/customization/inspector-bar.md +371 -0
- package/assets/docs/guide/user-interface/customization/navigation-bar.md +516 -0
- package/assets/docs/guide/user-interface/customization/page-format.md +436 -0
- package/assets/docs/guide/user-interface/customization/panel.md +605 -0
- package/assets/docs/guide/user-interface/customization/quick-start/add-action-buttons.md +531 -0
- package/assets/docs/guide/user-interface/customization/quick-start/add-dock-buttons.md +358 -0
- package/assets/docs/guide/user-interface/customization/quick-start/create-custom-components.md +374 -0
- package/assets/docs/guide/user-interface/customization/quick-start/reorder-components.md +323 -0
- package/assets/docs/guide/user-interface/customization/quick-start/show-hide-components.md +294 -0
- package/assets/docs/guide/user-interface/customization/quick-start.md +12 -0
- package/assets/docs/guide/user-interface/customization/reference/component-order-api.md +519 -0
- package/assets/docs/guide/user-interface/customization/reference/component-reference.md +333 -0
- package/assets/docs/guide/user-interface/customization/reference.md +12 -0
- package/assets/docs/guide/user-interface/customization.md +39 -0
- package/assets/docs/guide/user-interface/localization.md +633 -0
- package/assets/docs/guide/user-interface/overview.md +167 -0
- package/assets/docs/guide/user-interface/ui-extensions/add-custom-feature.md +411 -0
- package/assets/docs/guide/user-interface/ui-extensions/asset-library.md +721 -0
- package/assets/docs/guide/user-interface/ui-extensions/create-custom-panel.md +331 -0
- package/assets/docs/guide/user-interface/ui-extensions/customize-behaviour.md +553 -0
- package/assets/docs/guide/user-interface/ui-extensions/notifications-and-dialogs.md +672 -0
- package/assets/docs/guide/user-interface/ui-extensions/quick-actions.md +415 -0
- package/assets/docs/guide/user-interface/ui-extensions/register-new-component.md +521 -0
- package/assets/docs/guide/user-interface/ui-extensions.md +26 -0
- package/assets/docs/guide/user-interface.md +25 -0
- package/assets/docs/guide/what-is-cesdk.md +319 -0
- package/assets/docs/handbook/SKILL.md +521 -0
- package/assets/prompts/evals-assetGenerate.md +12 -0
- package/assets/prompts/evals-brutalistCore.md +34 -0
- package/assets/prompts/evals-danskCatalogue.md +31 -0
- package/assets/prompts/evals-exportRoundTrip.md +12 -0
- package/assets/prompts/evals-inspectPriorCode.md +16 -0
- package/assets/prompts/evals-listProjectFiles.md +6 -0
- package/assets/prompts/evals-readAndExplainScript.md +6 -0
- package/assets/prompts/evals-resumeAcrossRestart.md +15 -0
- package/assets/prompts/evals-rewindRecovery.md +10 -0
- package/assets/prompts/evals-searchAcrossFiles.md +6 -0
- package/assets/prompts/evals-weddingCard.md +20 -0
- package/assets/prompts/explain.md +6 -0
- package/assets/prompts/review.md +6 -0
- package/dist/assets/inline.generated.d.ts +2 -0
- package/dist/assets/inline.generated.d.ts.map +1 -0
- package/dist/assets/inline.generated.js +413 -0
- package/dist/assets/inline.generated.js.map +1 -0
- package/dist/assets/load-browser.d.ts +8 -0
- package/dist/assets/load-browser.d.ts.map +1 -0
- package/dist/assets/load-browser.js +11 -0
- package/dist/assets/load-browser.js.map +1 -0
- package/dist/assets/load-node.d.ts +8 -0
- package/dist/assets/load-node.d.ts.map +1 -0
- package/dist/assets/load-node.js +11 -0
- package/dist/assets/load-node.js.map +1 -0
- package/dist/cli/http.d.ts +2 -0
- package/dist/cli/http.d.ts.map +1 -0
- package/dist/cli/http.js +231 -0
- package/dist/cli/http.js.map +1 -0
- package/dist/cli/redirect-console.d.ts +10 -0
- package/dist/cli/redirect-console.d.ts.map +1 -0
- package/dist/cli/redirect-console.js +18 -0
- package/dist/cli/redirect-console.js.map +1 -0
- package/dist/cli/resolve-license.d.ts +2 -0
- package/dist/cli/resolve-license.d.ts.map +1 -0
- package/dist/cli/resolve-license.js +13 -0
- package/dist/cli/resolve-license.js.map +1 -0
- package/dist/cli/stdio.d.ts +2 -0
- package/dist/cli/stdio.d.ts.map +1 -0
- package/dist/cli/stdio.js +124 -0
- package/dist/cli/stdio.js.map +1 -0
- package/dist/cli/trial-license.generated.d.ts +2 -0
- package/dist/cli/trial-license.generated.d.ts.map +1 -0
- package/dist/cli/trial-license.generated.js +4 -0
- package/dist/cli/trial-license.generated.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +64 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +61 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +102 -0
- package/dist/config.js.map +1 -0
- package/dist/cross-ref.d.ts +2 -0
- package/dist/cross-ref.d.ts.map +1 -0
- package/dist/cross-ref.js +31 -0
- package/dist/cross-ref.js.map +1 -0
- package/dist/dashboard/router.d.ts +3 -0
- package/dist/dashboard/router.d.ts.map +1 -0
- package/dist/dashboard/router.js +19 -0
- package/dist/dashboard/router.js.map +1 -0
- package/dist/dashboard/spa-assets.generated.d.ts +2 -0
- package/dist/dashboard/spa-assets.generated.d.ts.map +1 -0
- package/dist/dashboard/spa-assets.generated.js +220 -0
- package/dist/dashboard/spa-assets.generated.js.map +1 -0
- package/dist/engine/asset-sources.d.ts +17 -0
- package/dist/engine/asset-sources.d.ts.map +1 -0
- package/dist/engine/asset-sources.js +75 -0
- package/dist/engine/asset-sources.js.map +1 -0
- package/dist/engine/cesdk-adapter.d.ts +10 -0
- package/dist/engine/cesdk-adapter.d.ts.map +1 -0
- package/dist/engine/cesdk-adapter.js +19 -0
- package/dist/engine/cesdk-adapter.js.map +1 -0
- package/dist/engine/index.d.ts +3 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +3 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/mutex.d.ts +5 -0
- package/dist/engine/mutex.d.ts.map +1 -0
- package/dist/engine/mutex.js +42 -0
- package/dist/engine/mutex.js.map +1 -0
- package/dist/engine/session.d.ts +50 -0
- package/dist/engine/session.d.ts.map +1 -0
- package/dist/engine/session.js +95 -0
- package/dist/engine/session.js.map +1 -0
- package/dist/engine/uri-resolver.d.ts +14 -0
- package/dist/engine/uri-resolver.d.ts.map +1 -0
- package/dist/engine/uri-resolver.js +12 -0
- package/dist/engine/uri-resolver.js.map +1 -0
- package/dist/frontmatter.d.ts +15 -0
- package/dist/frontmatter.d.ts.map +1 -0
- package/dist/frontmatter.js +46 -0
- package/dist/frontmatter.js.map +1 -0
- package/dist/gateway/hosted-stub.d.ts +6 -0
- package/dist/gateway/hosted-stub.d.ts.map +1 -0
- package/dist/gateway/hosted-stub.js +11 -0
- package/dist/gateway/hosted-stub.js.map +1 -0
- package/dist/gateway/index.d.ts +4 -0
- package/dist/gateway/index.d.ts.map +1 -0
- package/dist/gateway/index.js +4 -0
- package/dist/gateway/index.js.map +1 -0
- package/dist/gateway/local.d.ts +14 -0
- package/dist/gateway/local.d.ts.map +1 -0
- package/dist/gateway/local.js +41 -0
- package/dist/gateway/local.js.map +1 -0
- package/dist/gateway/types.d.ts +24 -0
- package/dist/gateway/types.d.ts.map +1 -0
- package/dist/gateway/types.js +7 -0
- package/dist/gateway/types.js.map +1 -0
- package/dist/http/server.d.ts +80 -0
- package/dist/http/server.d.ts.map +1 -0
- package/dist/http/server.js +183 -0
- package/dist/http/server.js.map +1 -0
- package/dist/http/session-manager.d.ts +42 -0
- package/dist/http/session-manager.d.ts.map +1 -0
- package/dist/http/session-manager.js +82 -0
- package/dist/http/session-manager.js.map +1 -0
- package/dist/http/workspace-auth.d.ts +9 -0
- package/dist/http/workspace-auth.d.ts.map +1 -0
- package/dist/http/workspace-auth.js +29 -0
- package/dist/http/workspace-auth.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/mount.d.ts +11 -0
- package/dist/metrics/mount.d.ts.map +1 -0
- package/dist/metrics/mount.js +13 -0
- package/dist/metrics/mount.js.map +1 -0
- package/dist/metrics/recorder.d.ts +55 -0
- package/dist/metrics/recorder.d.ts.map +1 -0
- package/dist/metrics/recorder.js +97 -0
- package/dist/metrics/recorder.js.map +1 -0
- package/dist/revisions/hash.d.ts +7 -0
- package/dist/revisions/hash.d.ts.map +1 -0
- package/dist/revisions/hash.js +24 -0
- package/dist/revisions/hash.js.map +1 -0
- package/dist/revisions/index.d.ts +4 -0
- package/dist/revisions/index.d.ts.map +1 -0
- package/dist/revisions/index.js +4 -0
- package/dist/revisions/index.js.map +1 -0
- package/dist/revisions/store.d.ts +69 -0
- package/dist/revisions/store.d.ts.map +1 -0
- package/dist/revisions/store.js +196 -0
- package/dist/revisions/store.js.map +1 -0
- package/dist/revisions/types.d.ts +39 -0
- package/dist/revisions/types.d.ts.map +1 -0
- package/dist/revisions/types.js +2 -0
- package/dist/revisions/types.js.map +1 -0
- package/dist/server.d.ts +51 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +175 -0
- package/dist/server.js.map +1 -0
- package/dist/skill-tools.d.ts +3 -0
- package/dist/skill-tools.d.ts.map +1 -0
- package/dist/skill-tools.js +105 -0
- package/dist/skill-tools.js.map +1 -0
- package/dist/test/test/cli/dispatcher.test.d.ts +2 -0
- package/dist/test/test/cli/dispatcher.test.d.ts.map +1 -0
- package/dist/test/test/cli/dispatcher.test.js +47 -0
- package/dist/test/test/cli/dispatcher.test.js.map +1 -0
- package/dist/test/test/cross-ref.test.d.ts +2 -0
- package/dist/test/test/cross-ref.test.d.ts.map +1 -0
- package/dist/test/test/cross-ref.test.js +39 -0
- package/dist/test/test/cross-ref.test.js.map +1 -0
- package/dist/test/test/engine/session.test.d.ts +2 -0
- package/dist/test/test/engine/session.test.d.ts.map +1 -0
- package/dist/test/test/engine/session.test.js +144 -0
- package/dist/test/test/engine/session.test.js.map +1 -0
- package/dist/test/test/engine/uri-resolver.test.d.ts +2 -0
- package/dist/test/test/engine/uri-resolver.test.d.ts.map +1 -0
- package/dist/test/test/engine/uri-resolver.test.js +38 -0
- package/dist/test/test/engine/uri-resolver.test.js.map +1 -0
- package/dist/test/test/frontmatter.test.d.ts +2 -0
- package/dist/test/test/frontmatter.test.d.ts.map +1 -0
- package/dist/test/test/frontmatter.test.js +55 -0
- package/dist/test/test/frontmatter.test.js.map +1 -0
- package/dist/test/test/gateway/hosted-stub.test.d.ts +2 -0
- package/dist/test/test/gateway/hosted-stub.test.d.ts.map +1 -0
- package/dist/test/test/gateway/hosted-stub.test.js +11 -0
- package/dist/test/test/gateway/hosted-stub.test.js.map +1 -0
- package/dist/test/test/gateway/local.test.d.ts +2 -0
- package/dist/test/test/gateway/local.test.d.ts.map +1 -0
- package/dist/test/test/gateway/local.test.js +29 -0
- package/dist/test/test/gateway/local.test.js.map +1 -0
- package/dist/test/test/handbook-contract.test.d.ts +2 -0
- package/dist/test/test/handbook-contract.test.d.ts.map +1 -0
- package/dist/test/test/handbook-contract.test.js +71 -0
- package/dist/test/test/handbook-contract.test.js.map +1 -0
- package/dist/test/test/http/server.test.d.ts +2 -0
- package/dist/test/test/http/server.test.d.ts.map +1 -0
- package/dist/test/test/http/server.test.js +245 -0
- package/dist/test/test/http/server.test.js.map +1 -0
- package/dist/test/test/http/session-manager.test.d.ts +2 -0
- package/dist/test/test/http/session-manager.test.d.ts.map +1 -0
- package/dist/test/test/http/session-manager.test.js +83 -0
- package/dist/test/test/http/session-manager.test.js.map +1 -0
- package/dist/test/test/revisions/hash.test.d.ts +2 -0
- package/dist/test/test/revisions/hash.test.d.ts.map +1 -0
- package/dist/test/test/revisions/hash.test.js +33 -0
- package/dist/test/test/revisions/hash.test.js.map +1 -0
- package/dist/test/test/revisions/store.test.d.ts +2 -0
- package/dist/test/test/revisions/store.test.d.ts.map +1 -0
- package/dist/test/test/revisions/store.test.js +245 -0
- package/dist/test/test/revisions/store.test.js.map +1 -0
- package/dist/test/test/server.test.d.ts +2 -0
- package/dist/test/test/server.test.d.ts.map +1 -0
- package/dist/test/test/server.test.js +157 -0
- package/dist/test/test/server.test.js.map +1 -0
- package/dist/test/test/skill-tools.test.d.ts +2 -0
- package/dist/test/test/skill-tools.test.d.ts.map +1 -0
- package/dist/test/test/skill-tools.test.js +84 -0
- package/dist/test/test/skill-tools.test.js.map +1 -0
- package/dist/test/test/smoke.test.d.ts +2 -0
- package/dist/test/test/smoke.test.d.ts.map +1 -0
- package/dist/test/test/smoke.test.js +8 -0
- package/dist/test/test/smoke.test.js.map +1 -0
- package/dist/test/test/tools/asset-generate.test.d.ts +2 -0
- package/dist/test/test/tools/asset-generate.test.d.ts.map +1 -0
- package/dist/test/test/tools/asset-generate.test.js +66 -0
- package/dist/test/test/tools/asset-generate.test.js.map +1 -0
- package/dist/test/test/tools/edit.test.d.ts +2 -0
- package/dist/test/test/tools/edit.test.d.ts.map +1 -0
- package/dist/test/test/tools/edit.test.js +205 -0
- package/dist/test/test/tools/edit.test.js.map +1 -0
- package/dist/test/test/tools/export.test.d.ts +2 -0
- package/dist/test/test/tools/export.test.d.ts.map +1 -0
- package/dist/test/test/tools/export.test.js +144 -0
- package/dist/test/test/tools/export.test.js.map +1 -0
- package/dist/test/test/tools/history.test.d.ts +2 -0
- package/dist/test/test/tools/history.test.d.ts.map +1 -0
- package/dist/test/test/tools/history.test.js +29 -0
- package/dist/test/test/tools/history.test.js.map +1 -0
- package/dist/test/test/tools/inspect.test.d.ts +2 -0
- package/dist/test/test/tools/inspect.test.d.ts.map +1 -0
- package/dist/test/test/tools/inspect.test.js +62 -0
- package/dist/test/test/tools/inspect.test.js.map +1 -0
- package/dist/test/test/tools/list.test.d.ts +2 -0
- package/dist/test/test/tools/list.test.d.ts.map +1 -0
- package/dist/test/test/tools/list.test.js +23 -0
- package/dist/test/test/tools/list.test.js.map +1 -0
- package/dist/test/test/tools/open-editor.test.d.ts +2 -0
- package/dist/test/test/tools/open-editor.test.d.ts.map +1 -0
- package/dist/test/test/tools/open-editor.test.js +53 -0
- package/dist/test/test/tools/open-editor.test.js.map +1 -0
- package/dist/test/test/tools/preview.test.d.ts +2 -0
- package/dist/test/test/tools/preview.test.d.ts.map +1 -0
- package/dist/test/test/tools/preview.test.js +73 -0
- package/dist/test/test/tools/preview.test.js.map +1 -0
- package/dist/test/test/tools/rename.test.d.ts +2 -0
- package/dist/test/test/tools/rename.test.d.ts.map +1 -0
- package/dist/test/test/tools/rename.test.js +17 -0
- package/dist/test/test/tools/rename.test.js.map +1 -0
- package/dist/test/test/viewer/broadcaster.test.d.ts +2 -0
- package/dist/test/test/viewer/broadcaster.test.d.ts.map +1 -0
- package/dist/test/test/viewer/broadcaster.test.js +53 -0
- package/dist/test/test/viewer/broadcaster.test.js.map +1 -0
- package/dist/test/test/viewer/resource-route.test.d.ts +2 -0
- package/dist/test/test/viewer/resource-route.test.d.ts.map +1 -0
- package/dist/test/test/viewer/resource-route.test.js +70 -0
- package/dist/test/test/viewer/resource-route.test.js.map +1 -0
- package/dist/test/test/viewer/router.test.d.ts +2 -0
- package/dist/test/test/viewer/router.test.d.ts.map +1 -0
- package/dist/test/test/viewer/router.test.js +171 -0
- package/dist/test/test/viewer/router.test.js.map +1 -0
- package/dist/test/test/viewer/url-builder.test.d.ts +2 -0
- package/dist/test/test/viewer/url-builder.test.d.ts.map +1 -0
- package/dist/test/test/viewer/url-builder.test.js +31 -0
- package/dist/test/test/viewer/url-builder.test.js.map +1 -0
- package/dist/test/test/workspace/hosted-stub.test.d.ts +2 -0
- package/dist/test/test/workspace/hosted-stub.test.d.ts.map +1 -0
- package/dist/test/test/workspace/hosted-stub.test.js +30 -0
- package/dist/test/test/workspace/hosted-stub.test.js.map +1 -0
- package/dist/test/test/workspace/in-memory.test.d.ts +2 -0
- package/dist/test/test/workspace/in-memory.test.d.ts.map +1 -0
- package/dist/test/test/workspace/in-memory.test.js +4 -0
- package/dist/test/test/workspace/in-memory.test.js.map +1 -0
- package/dist/test/test/workspace/node-fs.test.d.ts +2 -0
- package/dist/test/test/workspace/node-fs.test.d.ts.map +1 -0
- package/dist/test/test/workspace/node-fs.test.js +20 -0
- package/dist/test/test/workspace/node-fs.test.js.map +1 -0
- package/dist/test/test/workspace/shared-contract.d.ts +3 -0
- package/dist/test/test/workspace/shared-contract.d.ts.map +1 -0
- package/dist/test/test/workspace/shared-contract.js +92 -0
- package/dist/test/test/workspace/shared-contract.js.map +1 -0
- package/dist/test/tsconfig.test.tsbuildinfo +1 -0
- package/dist/test/vitest.config.d.ts +3 -0
- package/dist/test/vitest.config.d.ts.map +1 -0
- package/dist/test/vitest.config.js +8 -0
- package/dist/test/vitest.config.js.map +1 -0
- package/dist/tools/asset-generate.d.ts +12 -0
- package/dist/tools/asset-generate.d.ts.map +1 -0
- package/dist/tools/asset-generate.js +112 -0
- package/dist/tools/asset-generate.js.map +1 -0
- package/dist/tools/asset-search.d.ts +10 -0
- package/dist/tools/asset-search.d.ts.map +1 -0
- package/dist/tools/asset-search.js +120 -0
- package/dist/tools/asset-search.js.map +1 -0
- package/dist/tools/content-types.d.ts +11 -0
- package/dist/tools/content-types.d.ts.map +1 -0
- package/dist/tools/content-types.js +2 -0
- package/dist/tools/content-types.js.map +1 -0
- package/dist/tools/edit.d.ts +29 -0
- package/dist/tools/edit.d.ts.map +1 -0
- package/dist/tools/edit.js +165 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/engine.d.ts +31 -0
- package/dist/tools/engine.d.ts.map +1 -0
- package/dist/tools/engine.js +59 -0
- package/dist/tools/engine.js.map +1 -0
- package/dist/tools/export.d.ts +19 -0
- package/dist/tools/export.d.ts.map +1 -0
- package/dist/tools/export.js +179 -0
- package/dist/tools/export.js.map +1 -0
- package/dist/tools/history.d.ts +7 -0
- package/dist/tools/history.d.ts.map +1 -0
- package/dist/tools/history.js +54 -0
- package/dist/tools/history.js.map +1 -0
- package/dist/tools/index.d.ts +35 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +72 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/inspect.d.ts +7 -0
- package/dist/tools/inspect.d.ts.map +1 -0
- package/dist/tools/inspect.js +80 -0
- package/dist/tools/inspect.js.map +1 -0
- package/dist/tools/list.d.ts +7 -0
- package/dist/tools/list.d.ts.map +1 -0
- package/dist/tools/list.js +18 -0
- package/dist/tools/list.js.map +1 -0
- package/dist/tools/metrics.d.ts +11 -0
- package/dist/tools/metrics.d.ts.map +1 -0
- package/dist/tools/metrics.js +28 -0
- package/dist/tools/metrics.js.map +1 -0
- package/dist/tools/open-editor.d.ts +10 -0
- package/dist/tools/open-editor.d.ts.map +1 -0
- package/dist/tools/open-editor.js +62 -0
- package/dist/tools/open-editor.js.map +1 -0
- package/dist/tools/preview.d.ts +12 -0
- package/dist/tools/preview.d.ts.map +1 -0
- package/dist/tools/preview.js +104 -0
- package/dist/tools/preview.js.map +1 -0
- package/dist/tools/rename.d.ts +7 -0
- package/dist/tools/rename.d.ts.map +1 -0
- package/dist/tools/rename.js +39 -0
- package/dist/tools/rename.js.map +1 -0
- package/dist/tools/result.d.ts +12 -0
- package/dist/tools/result.d.ts.map +1 -0
- package/dist/tools/result.js +55 -0
- package/dist/tools/result.js.map +1 -0
- package/dist/tools/save.d.ts +19 -0
- package/dist/tools/save.d.ts.map +1 -0
- package/dist/tools/save.js +117 -0
- package/dist/tools/save.js.map +1 -0
- package/dist/viewer/broadcaster.d.ts +13 -0
- package/dist/viewer/broadcaster.d.ts.map +1 -0
- package/dist/viewer/broadcaster.js +44 -0
- package/dist/viewer/broadcaster.js.map +1 -0
- package/dist/viewer/index.d.ts +7 -0
- package/dist/viewer/index.d.ts.map +1 -0
- package/dist/viewer/index.js +7 -0
- package/dist/viewer/index.js.map +1 -0
- package/dist/viewer/listener.d.ts +16 -0
- package/dist/viewer/listener.d.ts.map +1 -0
- package/dist/viewer/listener.js +30 -0
- package/dist/viewer/listener.js.map +1 -0
- package/dist/viewer/presigned-r2-url-builder.d.ts +30 -0
- package/dist/viewer/presigned-r2-url-builder.d.ts.map +1 -0
- package/dist/viewer/presigned-r2-url-builder.js +40 -0
- package/dist/viewer/presigned-r2-url-builder.js.map +1 -0
- package/dist/viewer/resource-route.d.ts +9 -0
- package/dist/viewer/resource-route.d.ts.map +1 -0
- package/dist/viewer/resource-route.js +59 -0
- package/dist/viewer/resource-route.js.map +1 -0
- package/dist/viewer/router.d.ts +20 -0
- package/dist/viewer/router.d.ts.map +1 -0
- package/dist/viewer/router.js +142 -0
- package/dist/viewer/router.js.map +1 -0
- package/dist/viewer/session-mount.d.ts +10 -0
- package/dist/viewer/session-mount.d.ts.map +1 -0
- package/dist/viewer/session-mount.js +24 -0
- package/dist/viewer/session-mount.js.map +1 -0
- package/dist/viewer/spa-assets.generated.d.ts +2 -0
- package/dist/viewer/spa-assets.generated.d.ts.map +1 -0
- package/dist/viewer/spa-assets.generated.js +989 -0
- package/dist/viewer/spa-assets.generated.js.map +1 -0
- package/dist/viewer/url-builder.d.ts +48 -0
- package/dist/viewer/url-builder.d.ts.map +1 -0
- package/dist/viewer/url-builder.js +38 -0
- package/dist/viewer/url-builder.js.map +1 -0
- package/dist/workspace/hosted-stub.d.ts +28 -0
- package/dist/workspace/hosted-stub.d.ts.map +1 -0
- package/dist/workspace/hosted-stub.js +44 -0
- package/dist/workspace/hosted-stub.js.map +1 -0
- package/dist/workspace/in-memory.d.ts +23 -0
- package/dist/workspace/in-memory.d.ts.map +1 -0
- package/dist/workspace/in-memory.js +161 -0
- package/dist/workspace/in-memory.js.map +1 -0
- package/dist/workspace/index.d.ts +6 -0
- package/dist/workspace/index.d.ts.map +1 -0
- package/dist/workspace/index.js +6 -0
- package/dist/workspace/index.js.map +1 -0
- package/dist/workspace/node-fs.d.ts +23 -0
- package/dist/workspace/node-fs.d.ts.map +1 -0
- package/dist/workspace/node-fs.js +90 -0
- package/dist/workspace/node-fs.js.map +1 -0
- package/dist/workspace/s3.d.ts +32 -0
- package/dist/workspace/s3.d.ts.map +1 -0
- package/dist/workspace/s3.js +191 -0
- package/dist/workspace/s3.js.map +1 -0
- package/dist/workspace/scoped.d.ts +32 -0
- package/dist/workspace/scoped.d.ts.map +1 -0
- package/dist/workspace/scoped.js +76 -0
- package/dist/workspace/scoped.js.map +1 -0
- package/dist/workspace/types.d.ts +75 -0
- package/dist/workspace/types.d.ts.map +1 -0
- package/dist/workspace/types.js +18 -0
- package/dist/workspace/types.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const DESCRIPTION = "Get a URL the human can open to view the design in CE.SDK. With `revision`, returns the design's " +
|
|
2
|
+
"stable URL — the viewer keeps it live, re-rendering as you `edit`, so print it ONCE and don't re-emit " +
|
|
3
|
+
"a fresh URL every turn. Add `pin: true` for a frozen permalink to that exact revision (for 'look at " +
|
|
4
|
+
"exactly this' or comparing revisions). Omit `revision` for the workspace landing page (mini-studio). " +
|
|
5
|
+
'The viewer is read-only — agent edits remain authoritative.';
|
|
6
|
+
export function createOpenEditorTool(opts) {
|
|
7
|
+
return {
|
|
8
|
+
name: 'open_editor',
|
|
9
|
+
description: DESCRIPTION,
|
|
10
|
+
inputSchema: {
|
|
11
|
+
type: 'object',
|
|
12
|
+
properties: {
|
|
13
|
+
revision: {
|
|
14
|
+
type: 'string',
|
|
15
|
+
description: 'Any revision in the design. Omit to get the workspace landing page.'
|
|
16
|
+
},
|
|
17
|
+
pin: {
|
|
18
|
+
type: 'boolean',
|
|
19
|
+
description: 'When true, return a frozen permalink to this exact revision instead of the live design URL.'
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
additionalProperties: false
|
|
23
|
+
},
|
|
24
|
+
call: async (rawArgs) => {
|
|
25
|
+
const args = (rawArgs ?? {});
|
|
26
|
+
try {
|
|
27
|
+
if (args.revision === undefined) {
|
|
28
|
+
return {
|
|
29
|
+
content: [
|
|
30
|
+
{
|
|
31
|
+
type: 'text',
|
|
32
|
+
text: JSON.stringify({ url: opts.urlBuilder.forStudio() })
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// historyOf returns the chain root-first; [0] is the design root.
|
|
38
|
+
const chain = await opts.store.historyOf(args.revision);
|
|
39
|
+
const root = chain[0].id;
|
|
40
|
+
const url = args.pin
|
|
41
|
+
? opts.urlBuilder.forPinnedRevision(root, args.revision)
|
|
42
|
+
: opts.urlBuilder.forDesign(root);
|
|
43
|
+
return {
|
|
44
|
+
content: [{ type: 'text', text: JSON.stringify({ url }) }]
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
const code = err.code;
|
|
49
|
+
const msg = code === 'ENOENT'
|
|
50
|
+
? `unknown revision ${args.revision}`
|
|
51
|
+
: err instanceof Error
|
|
52
|
+
? err.message
|
|
53
|
+
: String(err);
|
|
54
|
+
return {
|
|
55
|
+
isError: true,
|
|
56
|
+
content: [{ type: 'text', text: `open_editor: ${msg}` }]
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=open-editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-editor.js","sourceRoot":"","sources":["../../src/tools/open-editor.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,GACf,mGAAmG;IACnG,wGAAwG;IACxG,sGAAsG;IACtG,uGAAuG;IACvG,6DAA6D,CAAC;AAEhE,MAAM,UAAU,oBAAoB,CAClC,IAAiC;IAEjC,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,WAAW;QACxB,WAAW,EAAE;YACX,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAiB;oBACvB,WAAW,EACT,qEAAqE;iBACxE;gBACD,GAAG,EAAE;oBACH,IAAI,EAAE,SAAkB;oBACxB,WAAW,EACT,6FAA6F;iBAChG;aACF;YACD,oBAAoB,EAAE,KAAK;SAC5B;QACD,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACtB,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE,CAAyC,CAAC;YACrE,IAAI,CAAC;gBACH,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;oBAChC,OAAO;wBACL,OAAO,EAAE;4BACP;gCACE,IAAI,EAAE,MAAe;gCACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC;6BAC3D;yBACF;qBACF,CAAC;gBACJ,CAAC;gBACD,kEAAkE;gBAClE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACxD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG;oBAClB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC;oBACxD,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACpC,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;iBACpE,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,IAAI,GAAI,GAAyB,CAAC,IAAI,CAAC;gBAC7C,MAAM,GAAG,GACP,IAAI,KAAK,QAAQ;oBACf,CAAC,CAAC,oBAAoB,IAAI,CAAC,QAAQ,EAAE;oBACrC,CAAC,CAAC,GAAG,YAAY,KAAK;wBACpB,CAAC,CAAC,GAAG,CAAC,OAAO;wBACb,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACpB,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,gBAAgB,GAAG,EAAE,EAAE,CAAC;iBAClE,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { RevisionStore } from '../revisions/store.js';\nimport type { CodesignMcpToolRegistration } from '../server.js';\nimport type { ViewerUrlBuilder } from '../viewer/url-builder.js';\n\nexport interface CreateOpenEditorToolOptions {\n urlBuilder: ViewerUrlBuilder;\n /** Resolves a revision to its design root (the root revision id). */\n store: RevisionStore;\n}\n\nconst DESCRIPTION =\n \"Get a URL the human can open to view the design in CE.SDK. With `revision`, returns the design's \" +\n \"stable URL — the viewer keeps it live, re-rendering as you `edit`, so print it ONCE and don't re-emit \" +\n \"a fresh URL every turn. Add `pin: true` for a frozen permalink to that exact revision (for 'look at \" +\n \"exactly this' or comparing revisions). Omit `revision` for the workspace landing page (mini-studio). \" +\n 'The viewer is read-only — agent edits remain authoritative.';\n\nexport function createOpenEditorTool(\n opts: CreateOpenEditorToolOptions\n): CodesignMcpToolRegistration {\n return {\n name: 'open_editor',\n description: DESCRIPTION,\n inputSchema: {\n type: 'object' as const,\n properties: {\n revision: {\n type: 'string' as const,\n description:\n 'Any revision in the design. Omit to get the workspace landing page.'\n },\n pin: {\n type: 'boolean' as const,\n description:\n 'When true, return a frozen permalink to this exact revision instead of the live design URL.'\n }\n },\n additionalProperties: false\n },\n call: async (rawArgs) => {\n const args = (rawArgs ?? {}) as { revision?: string; pin?: boolean };\n try {\n if (args.revision === undefined) {\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify({ url: opts.urlBuilder.forStudio() })\n }\n ]\n };\n }\n // historyOf returns the chain root-first; [0] is the design root.\n const chain = await opts.store.historyOf(args.revision);\n const root = chain[0].id;\n const url = args.pin\n ? opts.urlBuilder.forPinnedRevision(root, args.revision)\n : opts.urlBuilder.forDesign(root);\n return {\n content: [{ type: 'text' as const, text: JSON.stringify({ url }) }]\n };\n } catch (err) {\n const code = (err as { code?: string }).code;\n const msg =\n code === 'ENOENT'\n ? `unknown revision ${args.revision}`\n : err instanceof Error\n ? err.message\n : String(err);\n return {\n isError: true,\n content: [{ type: 'text' as const, text: `open_editor: ${msg}` }]\n };\n }\n }\n };\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Mutex } from '../engine/mutex.js';
|
|
2
|
+
import type { EngineSession } from '../engine/session.js';
|
|
3
|
+
import type { RevisionStore } from '../revisions/store.js';
|
|
4
|
+
import type { CodesignMcpToolRegistration } from '../server.js';
|
|
5
|
+
export interface CreatePreviewToolOptions<E = unknown> {
|
|
6
|
+
store: RevisionStore;
|
|
7
|
+
session: EngineSession<E>;
|
|
8
|
+
/** Guards the shared engine — load-then-export must not interleave with another session's edit (see engine/mutex.ts). */
|
|
9
|
+
engineLock: Mutex;
|
|
10
|
+
}
|
|
11
|
+
export declare function createPreviewTool<E = unknown>(opts: CreatePreviewToolOptions<E>): CodesignMcpToolRegistration;
|
|
12
|
+
//# sourceMappingURL=preview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/tools/preview.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AA6ChE,MAAM,WAAW,wBAAwB,CAAC,CAAC,GAAG,OAAO;IACnD,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAC1B,yHAAyH;IACzH,UAAU,EAAE,KAAK,CAAC;CACnB;AAUD,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAC3C,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAChC,2BAA2B,CAgE7B"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// packages/codesign-mcp/src/tools/preview.ts
|
|
2
|
+
//
|
|
3
|
+
// `preview` — renders a block to an inline image. Adds an optional `revision`
|
|
4
|
+
// (spec §6.1): when supplied and the engine slot is at a different revision,
|
|
5
|
+
// the session loads that revision before exporting. Without `revision`, renders
|
|
6
|
+
// the engine's current state (uses `session.currentSlot()` — side-effect-free).
|
|
7
|
+
const MAX_DIMENSION_PX = 1800;
|
|
8
|
+
const DEFAULT_TARGET_WIDTH = 512;
|
|
9
|
+
const DESCRIPTION = [
|
|
10
|
+
'Render a block (almost always a page) to an inline image so you can see the result.',
|
|
11
|
+
'',
|
|
12
|
+
"`blockId` is REQUIRED — preview the page you're working on, not the scene root.",
|
|
13
|
+
'',
|
|
14
|
+
"Optional `revision`: if supplied, loads that revision into the engine before rendering. Without it, renders the engine's current state (almost always what you want directly after `edit`).",
|
|
15
|
+
'',
|
|
16
|
+
"Defaults: format='webp', width=512. Width/height clamped at 1800 px (Anthropic many-image limit)."
|
|
17
|
+
].join('\n');
|
|
18
|
+
const PREVIEW_INPUT_SCHEMA = {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
blockId: { type: 'integer' },
|
|
22
|
+
revision: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
description: "Revision id; defaults to the engine's current state."
|
|
25
|
+
},
|
|
26
|
+
format: { enum: ['webp', 'png', 'jpeg'] },
|
|
27
|
+
width: { type: 'integer', minimum: 1 },
|
|
28
|
+
height: { type: 'integer', minimum: 1 }
|
|
29
|
+
},
|
|
30
|
+
required: ['blockId'],
|
|
31
|
+
additionalProperties: false
|
|
32
|
+
};
|
|
33
|
+
function bytesToBase64(bytes) {
|
|
34
|
+
if (typeof Buffer !== 'undefined')
|
|
35
|
+
return Buffer.from(bytes).toString('base64');
|
|
36
|
+
let s = '';
|
|
37
|
+
for (let i = 0; i < bytes.length; i++)
|
|
38
|
+
s += String.fromCharCode(bytes[i]);
|
|
39
|
+
return btoa(s);
|
|
40
|
+
}
|
|
41
|
+
export function createPreviewTool(opts) {
|
|
42
|
+
const { store, session, engineLock } = opts;
|
|
43
|
+
return {
|
|
44
|
+
name: 'preview',
|
|
45
|
+
description: DESCRIPTION,
|
|
46
|
+
inputSchema: PREVIEW_INPUT_SCHEMA,
|
|
47
|
+
call: async (rawArgs) => {
|
|
48
|
+
const args = (rawArgs ?? {});
|
|
49
|
+
if (typeof args.blockId !== 'number') {
|
|
50
|
+
return {
|
|
51
|
+
isError: true,
|
|
52
|
+
content: [
|
|
53
|
+
{
|
|
54
|
+
type: 'text',
|
|
55
|
+
text: 'preview: `blockId` (integer) is required.'
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// Load (if a revision was given) and export read the shared engine across
|
|
61
|
+
// awaits — serialize against any concurrent engine-touching tool call.
|
|
62
|
+
return engineLock.runExclusive(async () => {
|
|
63
|
+
let slot;
|
|
64
|
+
if (args.revision !== undefined) {
|
|
65
|
+
const rev = await store.read(args.revision);
|
|
66
|
+
await session.populate(args.revision, rev.scene);
|
|
67
|
+
slot = await session.acquire(args.revision);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
// No revision: render the current engine state via the side-effect-free
|
|
71
|
+
// currentSlot accessor (does NOT reset). If no slot is warm, error.
|
|
72
|
+
const current = session.currentSlot();
|
|
73
|
+
if (!current) {
|
|
74
|
+
return {
|
|
75
|
+
isError: true,
|
|
76
|
+
content: [
|
|
77
|
+
{
|
|
78
|
+
type: 'text',
|
|
79
|
+
text: 'preview: no engine state to render. Run `edit` first, or pass `revision` to load a specific revision.'
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
slot = current;
|
|
85
|
+
}
|
|
86
|
+
const eng = slot.engine;
|
|
87
|
+
const format = args.format ?? 'webp';
|
|
88
|
+
const mimeType = `image/${format}`;
|
|
89
|
+
const targetWidth = Math.min(args.width ?? DEFAULT_TARGET_WIDTH, MAX_DIMENSION_PX);
|
|
90
|
+
const exportOpts = { targetWidth };
|
|
91
|
+
if (args.height !== undefined)
|
|
92
|
+
exportOpts.targetHeight = Math.min(args.height, MAX_DIMENSION_PX);
|
|
93
|
+
const blob = await eng.block.export(args.blockId, mimeType, exportOpts);
|
|
94
|
+
const bytes = new Uint8Array(await blob.arrayBuffer());
|
|
95
|
+
return {
|
|
96
|
+
content: [
|
|
97
|
+
{ type: 'image', data: bytesToBase64(bytes), mimeType }
|
|
98
|
+
]
|
|
99
|
+
};
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=preview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../../src/tools/preview.ts"],"names":[],"mappings":"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","sourcesContent":["// packages/codesign-mcp/src/tools/preview.ts\n//\n// `preview` — renders a block to an inline image. Adds an optional `revision`\n// (spec §6.1): when supplied and the engine slot is at a different revision,\n// the session loads that revision before exporting. Without `revision`, renders\n// the engine's current state (uses `session.currentSlot()` — side-effect-free).\n\nimport type { Mutex } from '../engine/mutex.js';\nimport type { EngineSession, EngineSlot } from '../engine/session.js';\nimport type { RevisionStore } from '../revisions/store.js';\nimport type { CodesignMcpToolRegistration } from '../server.js';\n\nconst MAX_DIMENSION_PX = 1800;\nconst DEFAULT_TARGET_WIDTH = 512;\n\ninterface MinimalEngine {\n block: {\n export(blockId: number, mimeType: string, options?: unknown): Promise<Blob>;\n };\n}\n\ninterface PreviewArgs {\n blockId: number;\n revision?: string;\n format?: 'webp' | 'png' | 'jpeg';\n width?: number;\n height?: number;\n}\n\nconst DESCRIPTION = [\n 'Render a block (almost always a page) to an inline image so you can see the result.',\n '',\n \"`blockId` is REQUIRED — preview the page you're working on, not the scene root.\",\n '',\n \"Optional `revision`: if supplied, loads that revision into the engine before rendering. Without it, renders the engine's current state (almost always what you want directly after `edit`).\",\n '',\n \"Defaults: format='webp', width=512. Width/height clamped at 1800 px (Anthropic many-image limit).\"\n].join('\\n');\n\nconst PREVIEW_INPUT_SCHEMA = {\n type: 'object' as const,\n properties: {\n blockId: { type: 'integer' as const },\n revision: {\n type: 'string' as const,\n description: \"Revision id; defaults to the engine's current state.\"\n },\n format: { enum: ['webp', 'png', 'jpeg'] },\n width: { type: 'integer' as const, minimum: 1 },\n height: { type: 'integer' as const, minimum: 1 }\n },\n required: ['blockId'],\n additionalProperties: false\n};\n\nexport interface CreatePreviewToolOptions<E = unknown> {\n store: RevisionStore;\n session: EngineSession<E>;\n /** Guards the shared engine — load-then-export must not interleave with another session's edit (see engine/mutex.ts). */\n engineLock: Mutex;\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n if (typeof Buffer !== 'undefined')\n return Buffer.from(bytes).toString('base64');\n let s = '';\n for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);\n return btoa(s);\n}\n\nexport function createPreviewTool<E = unknown>(\n opts: CreatePreviewToolOptions<E>\n): CodesignMcpToolRegistration {\n const { store, session, engineLock } = opts;\n return {\n name: 'preview',\n description: DESCRIPTION,\n inputSchema: PREVIEW_INPUT_SCHEMA,\n call: async (rawArgs) => {\n const args = (rawArgs ?? {}) as PreviewArgs;\n if (typeof args.blockId !== 'number') {\n return {\n isError: true,\n content: [\n {\n type: 'text' as const,\n text: 'preview: `blockId` (integer) is required.'\n }\n ]\n };\n }\n // Load (if a revision was given) and export read the shared engine across\n // awaits — serialize against any concurrent engine-touching tool call.\n return engineLock.runExclusive(async () => {\n let slot: EngineSlot<E>;\n if (args.revision !== undefined) {\n const rev = await store.read(args.revision);\n await session.populate(args.revision, rev.scene);\n slot = await session.acquire(args.revision);\n } else {\n // No revision: render the current engine state via the side-effect-free\n // currentSlot accessor (does NOT reset). If no slot is warm, error.\n const current = session.currentSlot();\n if (!current) {\n return {\n isError: true,\n content: [\n {\n type: 'text' as const,\n text: 'preview: no engine state to render. Run `edit` first, or pass `revision` to load a specific revision.'\n }\n ]\n };\n }\n slot = current;\n }\n const eng = slot.engine as MinimalEngine;\n const format = args.format ?? 'webp';\n const mimeType = `image/${format}`;\n const targetWidth = Math.min(\n args.width ?? DEFAULT_TARGET_WIDTH,\n MAX_DIMENSION_PX\n );\n const exportOpts: Record<string, unknown> = { targetWidth };\n if (args.height !== undefined)\n exportOpts.targetHeight = Math.min(args.height, MAX_DIMENSION_PX);\n const blob = await eng.block.export(args.blockId, mimeType, exportOpts);\n const bytes = new Uint8Array(await blob.arrayBuffer());\n return {\n content: [\n { type: 'image' as const, data: bytesToBase64(bytes), mimeType }\n ]\n };\n });\n }\n };\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { RevisionStore } from '../revisions/store.js';
|
|
2
|
+
import type { CodesignMcpToolRegistration } from '../server.js';
|
|
3
|
+
export interface CreateRenameToolOptions {
|
|
4
|
+
store: RevisionStore;
|
|
5
|
+
}
|
|
6
|
+
export declare function createRenameTool(opts: CreateRenameToolOptions): CodesignMcpToolRegistration;
|
|
7
|
+
//# sourceMappingURL=rename.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rename.d.ts","sourceRoot":"","sources":["../../src/tools/rename.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,aAAa,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,uBAAuB,GAC5B,2BAA2B,CAsC7B"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export function createRenameTool(opts) {
|
|
2
|
+
return {
|
|
3
|
+
name: 'rename',
|
|
4
|
+
description: "Rename a design. `revision` may be any revision in the lineage; the root's title is updated. Use this when the title set at design creation no longer fits.",
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: 'object',
|
|
7
|
+
properties: {
|
|
8
|
+
revision: { type: 'string' },
|
|
9
|
+
title: { type: 'string' }
|
|
10
|
+
},
|
|
11
|
+
required: ['revision', 'title'],
|
|
12
|
+
additionalProperties: false
|
|
13
|
+
},
|
|
14
|
+
call: async (rawArgs) => {
|
|
15
|
+
const args = (rawArgs ?? {});
|
|
16
|
+
if (typeof args.revision !== 'string' || typeof args.title !== 'string') {
|
|
17
|
+
return {
|
|
18
|
+
isError: true,
|
|
19
|
+
content: [
|
|
20
|
+
{
|
|
21
|
+
type: 'text',
|
|
22
|
+
text: 'rename: `revision` and `title` (strings) are required.'
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const result = await opts.store.renameRoot(args.revision, args.title);
|
|
28
|
+
return {
|
|
29
|
+
content: [
|
|
30
|
+
{
|
|
31
|
+
type: 'text',
|
|
32
|
+
text: JSON.stringify({ ok: true, ...result })
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=rename.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rename.js","sourceRoot":"","sources":["../../src/tools/rename.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,gBAAgB,CAC9B,IAA6B;IAE7B,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,WAAW,EACT,6JAA6J;QAC/J,WAAW,EAAE;YACX,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE;gBACrC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE;aACnC;YACD,QAAQ,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC;YAC/B,oBAAoB,EAAE,KAAK;SAC5B;QACD,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACtB,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE,CAA0C,CAAC;YACtE,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACxE,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,wDAAwD;yBAC/D;qBACF;iBACF,CAAC;YACJ,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACtE,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;qBAC9C;iBACF;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { RevisionStore } from '../revisions/store.js';\nimport type { CodesignMcpToolRegistration } from '../server.js';\n\nexport interface CreateRenameToolOptions {\n store: RevisionStore;\n}\n\nexport function createRenameTool(\n opts: CreateRenameToolOptions\n): CodesignMcpToolRegistration {\n return {\n name: 'rename',\n description:\n \"Rename a design. `revision` may be any revision in the lineage; the root's title is updated. Use this when the title set at design creation no longer fits.\",\n inputSchema: {\n type: 'object' as const,\n properties: {\n revision: { type: 'string' as const },\n title: { type: 'string' as const }\n },\n required: ['revision', 'title'],\n additionalProperties: false\n },\n call: async (rawArgs) => {\n const args = (rawArgs ?? {}) as { revision?: string; title?: string };\n if (typeof args.revision !== 'string' || typeof args.title !== 'string') {\n return {\n isError: true,\n content: [\n {\n type: 'text' as const,\n text: 'rename: `revision` and `title` (strings) are required.'\n }\n ]\n };\n }\n const result = await opts.store.renameRoot(args.revision, args.title);\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify({ ok: true, ...result })\n }\n ]\n };\n }\n };\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ImageContent, TextContent } from './content-types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The strict return contract for `design_exec`.
|
|
4
|
+
*
|
|
5
|
+
* The function body must return undefined, a single MessagePart, or an array
|
|
6
|
+
* of MessageParts. Anything else throws an educational error so the LLM
|
|
7
|
+
* learns the rule on first miss.
|
|
8
|
+
*/
|
|
9
|
+
export type MessagePart = TextContent | ImageContent;
|
|
10
|
+
export declare function validatePart(value: unknown): MessagePart;
|
|
11
|
+
export declare function normalizeResult(raw: unknown): MessagePart[];
|
|
12
|
+
//# sourceMappingURL=result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../../src/tools/result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEpE;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;AAErD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAcxD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,EAAE,CAI3D"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export function validatePart(value) {
|
|
2
|
+
if (!value || typeof value !== 'object')
|
|
3
|
+
throw badShape(value);
|
|
4
|
+
const v = value;
|
|
5
|
+
if (v.type === 'text' && typeof v.text === 'string') {
|
|
6
|
+
return { type: 'text', text: v.text };
|
|
7
|
+
}
|
|
8
|
+
if (v.type === 'image' &&
|
|
9
|
+
typeof v.data === 'string' &&
|
|
10
|
+
typeof v.mimeType === 'string') {
|
|
11
|
+
return { type: 'image', data: v.data, mimeType: v.mimeType };
|
|
12
|
+
}
|
|
13
|
+
throw badShape(value);
|
|
14
|
+
}
|
|
15
|
+
export function normalizeResult(raw) {
|
|
16
|
+
if (raw === undefined || raw === null)
|
|
17
|
+
return [];
|
|
18
|
+
if (Array.isArray(raw))
|
|
19
|
+
return raw.map(validatePart);
|
|
20
|
+
return [validatePart(raw)];
|
|
21
|
+
}
|
|
22
|
+
function inspect(value) {
|
|
23
|
+
if (value === undefined)
|
|
24
|
+
return 'undefined';
|
|
25
|
+
if (value === null)
|
|
26
|
+
return 'null';
|
|
27
|
+
if (typeof value === 'string')
|
|
28
|
+
return `string("${value.slice(0, 40)}${value.length > 40 ? '…' : ''}")`;
|
|
29
|
+
if (typeof value === 'number')
|
|
30
|
+
return `number(${value})`;
|
|
31
|
+
if (typeof value === 'boolean')
|
|
32
|
+
return `boolean(${value})`;
|
|
33
|
+
if (Array.isArray(value))
|
|
34
|
+
return `array(${value.length} items)`;
|
|
35
|
+
if (typeof Blob !== 'undefined' && value instanceof Blob)
|
|
36
|
+
return `Blob(${value.size}B, ${value.type || 'no mime'})`;
|
|
37
|
+
if (value instanceof Uint8Array)
|
|
38
|
+
return `Uint8Array(${value.byteLength}B)`;
|
|
39
|
+
if (value instanceof ArrayBuffer)
|
|
40
|
+
return `ArrayBuffer(${value.byteLength}B)`;
|
|
41
|
+
if (typeof value === 'object') {
|
|
42
|
+
const keys = Object.keys(value)
|
|
43
|
+
.slice(0, 5)
|
|
44
|
+
.join(',');
|
|
45
|
+
return `object({${keys}})`;
|
|
46
|
+
}
|
|
47
|
+
return typeof value;
|
|
48
|
+
}
|
|
49
|
+
function badShape(value) {
|
|
50
|
+
return new Error(`design_exec must return undefined, a MessagePart, or MessagePart[]. Got: ${inspect(value)}. ` +
|
|
51
|
+
`Wrap explicitly — e.g. return { type: "text", text: String(value) }, or return ` +
|
|
52
|
+
`{ type: "image", data: "<base64>", mimeType: "image/png" }. For visual verification, ` +
|
|
53
|
+
`prefer the design_capture tool — it renders + encodes for you.`);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=result.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/tools/result.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC/D,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACxC,CAAC;IACD,IACE,CAAC,CAAC,IAAI,KAAK,OAAO;QAClB,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;QAC1B,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,EAC9B,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC/D,CAAC;IACD,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IACjD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACrD,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,OAAO,CAAC,KAAc;IAC7B,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,WAAW,CAAC;IAC5C,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAC3B,OAAO,WAAW,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;IAC1E,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,UAAU,KAAK,GAAG,CAAC;IACzD,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,WAAW,KAAK,GAAG,CAAC;IAC3D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,KAAK,CAAC,MAAM,SAAS,CAAC;IAChE,IAAI,OAAO,IAAI,KAAK,WAAW,IAAI,KAAK,YAAY,IAAI;QACtD,OAAO,QAAQ,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,IAAI,IAAI,SAAS,GAAG,CAAC;IAC5D,IAAI,KAAK,YAAY,UAAU;QAAE,OAAO,cAAc,KAAK,CAAC,UAAU,IAAI,CAAC;IAC3E,IAAI,KAAK,YAAY,WAAW;QAAE,OAAO,eAAe,KAAK,CAAC,UAAU,IAAI,CAAC;IAC7E,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC;aACtC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,IAAI,CAAC,GAAG,CAAC,CAAC;QACb,OAAO,WAAW,IAAI,IAAI,CAAC;IAC7B,CAAC;IACD,OAAO,OAAO,KAAK,CAAC;AACtB,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,IAAI,KAAK,CACd,4EAA4E,OAAO,CAAC,KAAK,CAAC,IAAI;QAC5F,iFAAiF;QACjF,uFAAuF;QACvF,gEAAgE,CACnE,CAAC;AACJ,CAAC","sourcesContent":["import type { ImageContent, TextContent } from './content-types.js';\n\n/**\n * The strict return contract for `design_exec`.\n *\n * The function body must return undefined, a single MessagePart, or an array\n * of MessageParts. Anything else throws an educational error so the LLM\n * learns the rule on first miss.\n */\nexport type MessagePart = TextContent | ImageContent;\n\nexport function validatePart(value: unknown): MessagePart {\n if (!value || typeof value !== 'object') throw badShape(value);\n const v = value as Record<string, unknown>;\n if (v.type === 'text' && typeof v.text === 'string') {\n return { type: 'text', text: v.text };\n }\n if (\n v.type === 'image' &&\n typeof v.data === 'string' &&\n typeof v.mimeType === 'string'\n ) {\n return { type: 'image', data: v.data, mimeType: v.mimeType };\n }\n throw badShape(value);\n}\n\nexport function normalizeResult(raw: unknown): MessagePart[] {\n if (raw === undefined || raw === null) return [];\n if (Array.isArray(raw)) return raw.map(validatePart);\n return [validatePart(raw)];\n}\n\nfunction inspect(value: unknown): string {\n if (value === undefined) return 'undefined';\n if (value === null) return 'null';\n if (typeof value === 'string')\n return `string(\"${value.slice(0, 40)}${value.length > 40 ? '…' : ''}\")`;\n if (typeof value === 'number') return `number(${value})`;\n if (typeof value === 'boolean') return `boolean(${value})`;\n if (Array.isArray(value)) return `array(${value.length} items)`;\n if (typeof Blob !== 'undefined' && value instanceof Blob)\n return `Blob(${value.size}B, ${value.type || 'no mime'})`;\n if (value instanceof Uint8Array) return `Uint8Array(${value.byteLength}B)`;\n if (value instanceof ArrayBuffer) return `ArrayBuffer(${value.byteLength}B)`;\n if (typeof value === 'object') {\n const keys = Object.keys(value as object)\n .slice(0, 5)\n .join(',');\n return `object({${keys}})`;\n }\n return typeof value;\n}\n\nfunction badShape(value: unknown): Error {\n return new Error(\n `design_exec must return undefined, a MessagePart, or MessagePart[]. Got: ${inspect(value)}. ` +\n `Wrap explicitly — e.g. return { type: \"text\", text: String(value) }, or return ` +\n `{ type: \"image\", data: \"<base64>\", mimeType: \"image/png\" }. For visual verification, ` +\n `prefer the design_capture tool — it renders + encodes for you.`\n );\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Mutex } from '../engine/mutex.js';
|
|
2
|
+
import type { EngineSession } from '../engine/session.js';
|
|
3
|
+
import type { RevisionStore } from '../revisions/store.js';
|
|
4
|
+
import type { CodesignMcpToolRegistration } from '../server.js';
|
|
5
|
+
import type { ViewerUrlBuilder } from '../viewer/url-builder.js';
|
|
6
|
+
import type { WorkspaceFS } from '../workspace/types.js';
|
|
7
|
+
export interface CreateSaveToolOptions<E = unknown> {
|
|
8
|
+
fs: WorkspaceFS;
|
|
9
|
+
store: RevisionStore;
|
|
10
|
+
session: EngineSession<E>;
|
|
11
|
+
/** Builds the `httpUrl` for workspace-written artifacts (the `/r/` route). */
|
|
12
|
+
urlBuilder: ViewerUrlBuilder;
|
|
13
|
+
/** Whether to honour an `outPath` argument (Local: yes; Hosted/sandbox: no). */
|
|
14
|
+
allowOutPath?: boolean;
|
|
15
|
+
/** Guards the shared engine — load-then-archive must not interleave with another session's edit. */
|
|
16
|
+
engineLock: Mutex;
|
|
17
|
+
}
|
|
18
|
+
export declare function createSaveTool<E = unknown>(opts: CreateSaveToolOptions<E>): CodesignMcpToolRegistration;
|
|
19
|
+
//# sourceMappingURL=save.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../../src/tools/save.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AA+CzD,MAAM,WAAW,qBAAqB,CAAC,CAAC,GAAG,OAAO;IAChD,EAAE,EAAE,WAAW,CAAC;IAChB,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAC1B,8EAA8E;IAC9E,UAAU,EAAE,gBAAgB,CAAC;IAC7B,gFAAgF;IAChF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oGAAoG;IACpG,UAAU,EAAE,KAAK,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,CAAC,GAAG,OAAO,EACxC,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAC7B,2BAA2B,CAmF7B"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// packages/codesign-mcp/src/tools/save.ts
|
|
2
|
+
//
|
|
3
|
+
// `save` — emit a self-contained `.zip` archive of a revision (scene + all
|
|
4
|
+
// asset bytes), via CE.SDK `scene.saveToArchive()`. Unlike the removed
|
|
5
|
+
// `export target=scene`, this is an ENGINE operation: the scene is loaded into
|
|
6
|
+
// the shared engine so saveToArchive can resolve `workspace://` asset URIs and
|
|
7
|
+
// bundle the fetched bytes. Output lands at `exports/<shard>/<rev>/archive.zip`
|
|
8
|
+
// and returns the same envelope shape as `export`.
|
|
9
|
+
import { promises as nodeFs } from 'node:fs';
|
|
10
|
+
import { dirname } from 'node:path';
|
|
11
|
+
const DESCRIPTION = [
|
|
12
|
+
'Save a revision as a portable, self-contained `.zip` archive (scene + all asset bytes bundled). Written into the workspace at `exports/<shard>/<rev>/archive.zip`.',
|
|
13
|
+
'',
|
|
14
|
+
'You do NOT need this to persist your work — every `edit` auto-persists to the workspace. Use `save` only to take an editable copy of the design OUT (hand to a human, back it up, move it between servers).',
|
|
15
|
+
'',
|
|
16
|
+
'Returns JSON `{ uri, httpUrl?, path?, bytes, format, revision }`. `uri` (a `workspace://` URI) is the durable handle. `httpUrl` is a fetch link tied to this process. `path` (absolute disk path) is returned ONLY when you passed `outPath`.'
|
|
17
|
+
].join('\n');
|
|
18
|
+
// The schema is built per-backend: `outPath` is advertised ONLY when the
|
|
19
|
+
// backend honours it (Local). On Hosted the property is omitted entirely, so
|
|
20
|
+
// an agent never sees an affordance it can't use — it can't try a local path
|
|
21
|
+
// and hit a runtime rejection. The runtime guard in `call` stays as a backstop.
|
|
22
|
+
function buildSaveInputSchema(allowOutPath) {
|
|
23
|
+
const properties = {
|
|
24
|
+
revision: { type: 'string' }
|
|
25
|
+
};
|
|
26
|
+
if (allowOutPath) {
|
|
27
|
+
properties.outPath = {
|
|
28
|
+
type: 'string',
|
|
29
|
+
description: 'Local-only escape hatch; absolute path.'
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
type: 'object',
|
|
34
|
+
properties,
|
|
35
|
+
required: ['revision'],
|
|
36
|
+
additionalProperties: false
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function createSaveTool(opts) {
|
|
40
|
+
const { fs, store, session, urlBuilder, allowOutPath = false, engineLock } = opts;
|
|
41
|
+
return {
|
|
42
|
+
name: 'save',
|
|
43
|
+
description: DESCRIPTION,
|
|
44
|
+
inputSchema: buildSaveInputSchema(allowOutPath),
|
|
45
|
+
call: async (rawArgs) => {
|
|
46
|
+
const args = (rawArgs ?? {});
|
|
47
|
+
if (typeof args.revision !== 'string') {
|
|
48
|
+
return {
|
|
49
|
+
isError: true,
|
|
50
|
+
content: [
|
|
51
|
+
{ type: 'text', text: 'save: `revision` is required.' }
|
|
52
|
+
]
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (args.outPath !== undefined && !allowOutPath) {
|
|
56
|
+
return {
|
|
57
|
+
isError: true,
|
|
58
|
+
content: [
|
|
59
|
+
{
|
|
60
|
+
type: 'text',
|
|
61
|
+
text: 'save: `outPath` is not supported on this (hosted) backend. Omit it — the archive is written to the workspace and returned as `httpUrl`; fetch that URL to download the `.zip` to disk.'
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const rev = await store.read(args.revision);
|
|
67
|
+
const revision = args.revision;
|
|
68
|
+
const sceneBytes = rev.scene;
|
|
69
|
+
// load-into-engine then archive reads the shared engine across awaits —
|
|
70
|
+
// serialize against any concurrent engine-touching tool call.
|
|
71
|
+
const bytes = await engineLock.runExclusive(async () => {
|
|
72
|
+
await session.populate(revision, sceneBytes);
|
|
73
|
+
const slot = await session.acquire(revision);
|
|
74
|
+
const eng = slot.engine;
|
|
75
|
+
// saveToArchive bundles only assets "accessible when called" — force
|
|
76
|
+
// every page's resources to finish loading first, else in-flight
|
|
77
|
+
// assets are silently dropped from the zip (see the handbook's "Font-load barrier: forceLoadResources" section).
|
|
78
|
+
await eng.block.forceLoadResources(eng.scene.getPages());
|
|
79
|
+
const blob = await eng.scene.saveToArchive();
|
|
80
|
+
return new Uint8Array(await blob.arrayBuffer());
|
|
81
|
+
});
|
|
82
|
+
const shard = revision.slice(0, 2);
|
|
83
|
+
const rest = revision.slice(2);
|
|
84
|
+
const relPath = `exports/${shard}/${rest}/archive.zip`;
|
|
85
|
+
let absPath;
|
|
86
|
+
let httpUrl;
|
|
87
|
+
if (args.outPath !== undefined) {
|
|
88
|
+
// Local-only escape hatch: write through real disk fs, NOT the
|
|
89
|
+
// workspace abstraction. The caller chose this path, so echoing it
|
|
90
|
+
// back is a confirmation, not a workspace-path leak.
|
|
91
|
+
await nodeFs.mkdir(dirname(args.outPath), { recursive: true });
|
|
92
|
+
await nodeFs.writeFile(args.outPath, bytes);
|
|
93
|
+
absPath = args.outPath;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
await fs.writeFile(relPath, bytes);
|
|
97
|
+
httpUrl = await urlBuilder.forDownload(relPath);
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
content: [
|
|
101
|
+
{
|
|
102
|
+
type: 'text',
|
|
103
|
+
text: JSON.stringify({
|
|
104
|
+
uri: `workspace://${relPath}`,
|
|
105
|
+
...(httpUrl ? { httpUrl } : {}),
|
|
106
|
+
...(absPath ? { path: absPath } : {}),
|
|
107
|
+
bytes: bytes.byteLength,
|
|
108
|
+
format: 'archive',
|
|
109
|
+
revision
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=save.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save.js","sourceRoot":"","sources":["../../src/tools/save.ts"],"names":[],"mappings":"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","sourcesContent":["// packages/codesign-mcp/src/tools/save.ts\n//\n// `save` — emit a self-contained `.zip` archive of a revision (scene + all\n// asset bytes), via CE.SDK `scene.saveToArchive()`. Unlike the removed\n// `export target=scene`, this is an ENGINE operation: the scene is loaded into\n// the shared engine so saveToArchive can resolve `workspace://` asset URIs and\n// bundle the fetched bytes. Output lands at `exports/<shard>/<rev>/archive.zip`\n// and returns the same envelope shape as `export`.\nimport { promises as nodeFs } from 'node:fs';\nimport { dirname } from 'node:path';\nimport type { Mutex } from '../engine/mutex.js';\nimport type { EngineSession } from '../engine/session.js';\nimport type { RevisionStore } from '../revisions/store.js';\nimport type { CodesignMcpToolRegistration } from '../server.js';\nimport type { ViewerUrlBuilder } from '../viewer/url-builder.js';\nimport type { WorkspaceFS } from '../workspace/types.js';\n\ninterface MinimalArchiveEngine {\n scene: {\n getPages(): number[];\n saveToArchive(): Promise<Blob>;\n };\n block: {\n forceLoadResources(ids: number[]): Promise<void>;\n };\n}\n\ninterface SaveArgs {\n revision: string;\n outPath?: string;\n}\n\nconst DESCRIPTION = [\n 'Save a revision as a portable, self-contained `.zip` archive (scene + all asset bytes bundled). Written into the workspace at `exports/<shard>/<rev>/archive.zip`.',\n '',\n 'You do NOT need this to persist your work — every `edit` auto-persists to the workspace. Use `save` only to take an editable copy of the design OUT (hand to a human, back it up, move it between servers).',\n '',\n 'Returns JSON `{ uri, httpUrl?, path?, bytes, format, revision }`. `uri` (a `workspace://` URI) is the durable handle. `httpUrl` is a fetch link tied to this process. `path` (absolute disk path) is returned ONLY when you passed `outPath`.'\n].join('\\n');\n\n// The schema is built per-backend: `outPath` is advertised ONLY when the\n// backend honours it (Local). On Hosted the property is omitted entirely, so\n// an agent never sees an affordance it can't use — it can't try a local path\n// and hit a runtime rejection. The runtime guard in `call` stays as a backstop.\nfunction buildSaveInputSchema(allowOutPath: boolean) {\n const properties: Record<string, unknown> = {\n revision: { type: 'string' as const }\n };\n if (allowOutPath) {\n properties.outPath = {\n type: 'string' as const,\n description: 'Local-only escape hatch; absolute path.'\n };\n }\n return {\n type: 'object' as const,\n properties,\n required: ['revision'],\n additionalProperties: false\n };\n}\n\nexport interface CreateSaveToolOptions<E = unknown> {\n fs: WorkspaceFS;\n store: RevisionStore;\n session: EngineSession<E>;\n /** Builds the `httpUrl` for workspace-written artifacts (the `/r/` route). */\n urlBuilder: ViewerUrlBuilder;\n /** Whether to honour an `outPath` argument (Local: yes; Hosted/sandbox: no). */\n allowOutPath?: boolean;\n /** Guards the shared engine — load-then-archive must not interleave with another session's edit. */\n engineLock: Mutex;\n}\n\nexport function createSaveTool<E = unknown>(\n opts: CreateSaveToolOptions<E>\n): CodesignMcpToolRegistration {\n const {\n fs,\n store,\n session,\n urlBuilder,\n allowOutPath = false,\n engineLock\n } = opts;\n return {\n name: 'save',\n description: DESCRIPTION,\n inputSchema: buildSaveInputSchema(allowOutPath),\n call: async (rawArgs) => {\n const args = (rawArgs ?? {}) as Partial<SaveArgs>;\n if (typeof args.revision !== 'string') {\n return {\n isError: true,\n content: [\n { type: 'text' as const, text: 'save: `revision` is required.' }\n ]\n };\n }\n if (args.outPath !== undefined && !allowOutPath) {\n return {\n isError: true,\n content: [\n {\n type: 'text' as const,\n text: 'save: `outPath` is not supported on this (hosted) backend. Omit it — the archive is written to the workspace and returned as `httpUrl`; fetch that URL to download the `.zip` to disk.'\n }\n ]\n };\n }\n const rev = await store.read(args.revision);\n const revision = args.revision;\n const sceneBytes = rev.scene;\n // load-into-engine then archive reads the shared engine across awaits —\n // serialize against any concurrent engine-touching tool call.\n const bytes = await engineLock.runExclusive(async () => {\n await session.populate(revision, sceneBytes);\n const slot = await session.acquire(revision);\n const eng = slot.engine as MinimalArchiveEngine;\n // saveToArchive bundles only assets \"accessible when called\" — force\n // every page's resources to finish loading first, else in-flight\n // assets are silently dropped from the zip (see the handbook's \"Font-load barrier: forceLoadResources\" section).\n await eng.block.forceLoadResources(eng.scene.getPages());\n const blob = await eng.scene.saveToArchive();\n return new Uint8Array(await blob.arrayBuffer());\n });\n const shard = revision.slice(0, 2);\n const rest = revision.slice(2);\n const relPath = `exports/${shard}/${rest}/archive.zip`;\n let absPath: string | undefined;\n let httpUrl: string | undefined;\n if (args.outPath !== undefined) {\n // Local-only escape hatch: write through real disk fs, NOT the\n // workspace abstraction. The caller chose this path, so echoing it\n // back is a confirmation, not a workspace-path leak.\n await nodeFs.mkdir(dirname(args.outPath), { recursive: true });\n await nodeFs.writeFile(args.outPath, bytes);\n absPath = args.outPath;\n } else {\n await fs.writeFile(relPath, bytes);\n httpUrl = await urlBuilder.forDownload(relPath);\n }\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify({\n uri: `workspace://${relPath}`,\n ...(httpUrl ? { httpUrl } : {}),\n ...(absPath ? { path: absPath } : {}),\n bytes: bytes.byteLength,\n format: 'archive',\n revision\n })\n }\n ]\n };\n }\n };\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Response } from 'express';
|
|
2
|
+
export interface RevisionEvent {
|
|
3
|
+
revision: string;
|
|
4
|
+
rootRevision: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class SseBroadcaster {
|
|
7
|
+
private readonly subs;
|
|
8
|
+
subscribe(rootRevision: string, res: Response): void;
|
|
9
|
+
broadcast(event: RevisionEvent): void;
|
|
10
|
+
subscriberCount(rootRevision: string): number;
|
|
11
|
+
closeAll(): void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=broadcaster.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broadcaster.d.ts","sourceRoot":"","sources":["../../src/viewer/broadcaster.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoC;IAEzD,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI;IAoBpD,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAOrC,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAI7C,QAAQ,IAAI,IAAI;CAMjB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export class SseBroadcaster {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.subs = new Map();
|
|
4
|
+
}
|
|
5
|
+
subscribe(rootRevision, res) {
|
|
6
|
+
res.writeHead(200, {
|
|
7
|
+
'content-type': 'text/event-stream',
|
|
8
|
+
'cache-control': 'no-cache',
|
|
9
|
+
connection: 'keep-alive'
|
|
10
|
+
});
|
|
11
|
+
// Initial comment so the client knows the stream is open.
|
|
12
|
+
res.write(': codesign-mcp viewer\n\n');
|
|
13
|
+
let set = this.subs.get(rootRevision);
|
|
14
|
+
if (!set) {
|
|
15
|
+
set = new Set();
|
|
16
|
+
this.subs.set(rootRevision, set);
|
|
17
|
+
}
|
|
18
|
+
set.add(res);
|
|
19
|
+
res.on('close', () => {
|
|
20
|
+
set?.delete(res);
|
|
21
|
+
if (set && set.size === 0)
|
|
22
|
+
this.subs.delete(rootRevision);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
broadcast(event) {
|
|
26
|
+
const set = this.subs.get(event.rootRevision);
|
|
27
|
+
if (!set)
|
|
28
|
+
return;
|
|
29
|
+
const payload = `data: ${JSON.stringify(event)}\n\n`;
|
|
30
|
+
for (const res of set)
|
|
31
|
+
res.write(payload);
|
|
32
|
+
}
|
|
33
|
+
subscriberCount(rootRevision) {
|
|
34
|
+
return this.subs.get(rootRevision)?.size ?? 0;
|
|
35
|
+
}
|
|
36
|
+
closeAll() {
|
|
37
|
+
for (const set of this.subs.values()) {
|
|
38
|
+
for (const res of set)
|
|
39
|
+
res.end();
|
|
40
|
+
}
|
|
41
|
+
this.subs.clear();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=broadcaster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broadcaster.js","sourceRoot":"","sources":["../../src/viewer/broadcaster.ts"],"names":[],"mappings":"AAcA,MAAM,OAAO,cAAc;IAA3B;QACmB,SAAI,GAAG,IAAI,GAAG,EAAyB,CAAC;IAuC3D,CAAC;IArCC,SAAS,CAAC,YAAoB,EAAE,GAAa;QAC3C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,cAAc,EAAE,mBAAmB;YACnC,eAAe,EAAE,UAAU;YAC3B,UAAU,EAAE,YAAY;SACzB,CAAC,CAAC;QACH,0DAA0D;QAC1D,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;QACvC,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACtC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACnC,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACb,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACnB,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YACjB,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,CAAC,KAAoB;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,MAAM,OAAO,GAAG,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;QACrD,KAAK,MAAM,GAAG,IAAI,GAAG;YAAE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,eAAe,CAAC,YAAoB;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC;IAChD,CAAC;IAED,QAAQ;QACN,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YACrC,KAAK,MAAM,GAAG,IAAI,GAAG;gBAAE,GAAG,CAAC,GAAG,EAAE,CAAC;QACnC,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;CACF","sourcesContent":["//\n// Per-root SSE fan-out. Keeps `Map<rootRev, Set<Response>>`; broadcasts a\n// JSON-serialised event to every subscriber. Removes subscribers on connection\n// close.\n//\n// The `Response` shape used here is a structural subset of `express.Response`\n// (writeHead, write, end, on('close', cb)) so tests can pass a stub.\nimport type { Response } from 'express';\n\nexport interface RevisionEvent {\n revision: string;\n rootRevision: string;\n}\n\nexport class SseBroadcaster {\n private readonly subs = new Map<string, Set<Response>>();\n\n subscribe(rootRevision: string, res: Response): void {\n res.writeHead(200, {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-cache',\n connection: 'keep-alive'\n });\n // Initial comment so the client knows the stream is open.\n res.write(': codesign-mcp viewer\\n\\n');\n let set = this.subs.get(rootRevision);\n if (!set) {\n set = new Set();\n this.subs.set(rootRevision, set);\n }\n set.add(res);\n res.on('close', () => {\n set?.delete(res);\n if (set && set.size === 0) this.subs.delete(rootRevision);\n });\n }\n\n broadcast(event: RevisionEvent): void {\n const set = this.subs.get(event.rootRevision);\n if (!set) return;\n const payload = `data: ${JSON.stringify(event)}\\n\\n`;\n for (const res of set) res.write(payload);\n }\n\n subscriberCount(rootRevision: string): number {\n return this.subs.get(rootRevision)?.size ?? 0;\n }\n\n closeAll(): void {\n for (const set of this.subs.values()) {\n for (const res of set) res.end();\n }\n this.subs.clear();\n }\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { type RevisionEvent, SseBroadcaster } from './broadcaster.js';
|
|
2
|
+
export { type StartViewerListenerOptions, startViewerListener, type ViewerListener } from './listener.js';
|
|
3
|
+
export { type CreateViewerRouterOptions, createViewerRouter } from './router.js';
|
|
4
|
+
export { type MountSessionViewerOptions, mountSessionViewer } from './session-mount.js';
|
|
5
|
+
export { SPA_ASSETS } from './spa-assets.generated.js';
|
|
6
|
+
export { type LocalUrlBuilderOptions, LocalViewerUrlBuilder, viewerBaseFor, type ViewerBaseOptions, type ViewerUrlBuilder } from './url-builder.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/viewer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EACL,KAAK,0BAA0B,EAC/B,mBAAmB,EACnB,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,KAAK,yBAAyB,EAC9B,kBAAkB,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,yBAAyB,EAC9B,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EACL,KAAK,sBAAsB,EAC3B,qBAAqB,EACrB,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { SseBroadcaster } from './broadcaster.js';
|
|
2
|
+
export { startViewerListener } from './listener.js';
|
|
3
|
+
export { createViewerRouter } from './router.js';
|
|
4
|
+
export { mountSessionViewer } from './session-mount.js';
|
|
5
|
+
export { SPA_ASSETS } from './spa-assets.generated.js';
|
|
6
|
+
export { LocalViewerUrlBuilder, viewerBaseFor } from './url-builder.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/viewer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAEL,mBAAmB,EAEpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAEL,kBAAkB,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAEL,qBAAqB,EACrB,aAAa,EAGd,MAAM,kBAAkB,CAAC","sourcesContent":["export { type RevisionEvent, SseBroadcaster } from './broadcaster.js';\nexport {\n type StartViewerListenerOptions,\n startViewerListener,\n type ViewerListener\n} from './listener.js';\nexport {\n type CreateViewerRouterOptions,\n createViewerRouter\n} from './router.js';\nexport {\n type MountSessionViewerOptions,\n mountSessionViewer\n} from './session-mount.js';\nexport { SPA_ASSETS } from './spa-assets.generated.js';\nexport {\n type LocalUrlBuilderOptions,\n LocalViewerUrlBuilder,\n viewerBaseFor,\n type ViewerBaseOptions,\n type ViewerUrlBuilder\n} from './url-builder.js';\n"]}
|