@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 @@
|
|
|
1
|
+
{"version":3,"file":"spa-assets.generated.js","sourceRoot":"","sources":["../../src/viewer/spa-assets.generated.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,MAAM,CAAC,MAAM,UAAU,GAA2B;IACjD,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2Td;IACA,mBAAmB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwMrB;IACA,aAAa,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmIf;IACA,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoFb;IACA,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Pb;CACA,CAAC","sourcesContent":["// AUTO-GENERATED by scripts/generate-spa-assets.mjs. Do not edit by hand.\nexport const SPA_ASSETS: Record<string, string> = {\n\t\"index.html\": `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <title>codesign viewer</title>\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n <!-- Mount prefix injected by the viewer router (router.ts). \"\" on the stdio\n listener, \"/viewer\" on the HTTP transport. Read by viewer.js. -->\n <script>\n window.__VIEWER_BASE__ = '{{VIEWER_BASE}}';\n </script>\n <style>\n /* -------- reset & canvas -------- */\n html,\n body {\n margin: 0;\n padding: 0;\n height: 100%;\n width: 100%;\n background: #1d1d1f;\n color: #eee;\n font-family: -apple-system, system-ui, sans-serif;\n }\n #cesdk {\n position: fixed;\n inset: 0;\n }\n\n /* -------- pill base (spec §7) -------- */\n .pill {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 6px 11px;\n border-radius: 999px;\n font:\n 500 12px -apple-system,\n system-ui,\n sans-serif;\n color: #e8e8e8;\n background: rgba(20, 20, 22, 0.72);\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n border: 1px solid rgba(255, 255, 255, 0.08);\n box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);\n text-decoration: none;\n cursor: pointer;\n white-space: nowrap;\n }\n .pill.icon {\n padding: 6px 9px;\n }\n .pill:hover {\n background: rgba(30, 30, 33, 0.82);\n }\n\n /* -------- cluster anchors -------- */\n #bar-left,\n #bar-right {\n position: fixed;\n top: 14px;\n z-index: 10;\n display: flex;\n gap: 8px;\n }\n #bar-left {\n left: 14px;\n }\n #bar-right {\n right: 14px;\n }\n\n /* -------- title pill --------\n\t\t\t Non-interactive (no click handler) — override .pill's cursor + hover so\n\t\t\t the title visually matches its actual behavior. For a local MCP the URL\n\t\t\t isn't shareable, so there's nothing useful to copy. Revisit when a\n\t\t\t remote MCP ships — copy-share-URL is the natural fit there. */\n #title {\n font-weight: 600;\n max-width: 240px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: default;\n }\n #title:hover {\n background: rgba(20, 20, 22, 0.72);\n }\n\n /* -------- LIVE pill (read-only) -------- */\n .pill.live {\n color: #c8e6c9;\n cursor: default;\n }\n .pill.live:hover {\n background: rgba(20, 20, 22, 0.72);\n }\n .pill.live::before {\n content: '';\n width: 6px;\n height: 6px;\n border-radius: 999px;\n background: #34c759;\n box-shadow: 0 0 5px rgba(52, 199, 89, 0.55);\n }\n\n /* -------- hash chip -------- */\n .pill.hash {\n font-family: ui-monospace, monospace;\n font-size: 11px;\n color: #b8b8b8;\n }\n\n /* -------- Go Live pill + count badge -------- */\n .pill.golive {\n color: #9ec8ff;\n }\n .pill.golive .count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: 999px;\n background: #2b6cb0;\n color: #fff;\n font-size: 10px;\n font-weight: 600;\n margin-left: 4px;\n }\n\n /* -------- History pill -------- */\n .pill.history::before {\n content: '⎇';\n opacity: 0.8;\n }\n .pill.history.active,\n .pill.history.active:hover {\n background: rgba(43, 108, 176, 0.85);\n border-color: rgba(43, 108, 176, 0.95);\n color: #fff;\n }\n\n /* -------- floating history panel (spec §6) -------- */\n #revision-panel {\n position: fixed;\n top: 62px;\n right: 14px;\n bottom: 14px;\n width: 280px;\n background: rgba(20, 20, 22, 0.88);\n backdrop-filter: blur(16px);\n -webkit-backdrop-filter: blur(16px);\n border: 1px solid rgba(255, 255, 255, 0.08);\n border-radius: 12px;\n box-shadow: 0 14px 36px rgba(0, 0, 0, 0.42);\n box-sizing: border-box;\n overflow-y: auto;\n display: none;\n opacity: 0;\n transform: translateX(8px);\n z-index: 10;\n }\n body.panel-open #revision-panel {\n display: block;\n }\n @media (prefers-reduced-motion: no-preference) {\n #revision-panel {\n transition:\n opacity 160ms ease-out,\n transform 160ms ease-out;\n }\n body.panel-open #revision-panel {\n opacity: 1;\n transform: translateX(0);\n }\n }\n @media (prefers-reduced-motion: reduce) {\n body.panel-open #revision-panel {\n opacity: 1;\n transform: none;\n }\n }\n\n /* -------- panel internals (polish pass) -------- */\n .rp-header {\n padding: 12px 14px 10px;\n font-size: 10px;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: #888;\n border-bottom: 1px solid rgba(255, 255, 255, 0.06);\n }\n .rp-tree {\n padding: 8px 6px;\n }\n .rp-empty {\n padding: 16px 14px;\n font-size: 12px;\n color: #888;\n }\n\n .rp-node {\n display: block;\n text-decoration: none;\n color: inherit;\n padding: 6px 8px;\n border-radius: 6px;\n }\n .rp-node:hover {\n background: rgba(255, 255, 255, 0.04);\n }\n .rp-node.rp-current {\n background: rgba(30, 47, 68, 0.6);\n box-shadow: inset 2px 0 0 #4a9eff;\n }\n .rp-node-row {\n display: flex;\n gap: 8px;\n align-items: baseline;\n }\n .rp-elbow {\n color: #555;\n flex: none;\n }\n .rp-dot {\n flex: none;\n width: 12px;\n text-align: center;\n font-size: 10px;\n color: #888;\n }\n .rp-node.rp-head .rp-dot {\n color: #4a9eff;\n }\n .rp-node.rp-branch .rp-dot {\n color: #d6973f;\n }\n .rp-body {\n flex: 1;\n min-width: 0;\n }\n .rp-id {\n display: flex;\n align-items: center;\n gap: 6px;\n font-family: ui-monospace, monospace;\n font-size: 10px;\n color: #888;\n }\n .rp-tag {\n border: 1px solid rgba(255, 255, 255, 0.1);\n border-radius: 4px;\n padding: 0 4px;\n font-size: 9px;\n }\n .rp-tag.rp-tag-head {\n background: rgba(43, 108, 176, 0.85);\n border-color: rgba(43, 108, 176, 0.95);\n color: #fff;\n }\n .rp-tag.rp-tag-fork {\n color: #d6973f;\n border-color: rgba(214, 151, 63, 0.35);\n }\n .rp-note {\n font-size: 12px;\n color: #eee;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .rp-time {\n font-size: 10px;\n color: #777;\n }\n .rp-node.rp-current .rp-time::after {\n content: ' · on canvas';\n color: #4a9eff;\n }\n .rp-copy {\n font: inherit;\n font-size: 9px;\n color: #ccc;\n background: rgba(20, 20, 22, 0.72);\n border: 1px solid rgba(255, 255, 255, 0.08);\n border-radius: 999px;\n padding: 2px 7px;\n cursor: pointer;\n opacity: 0;\n margin-left: auto;\n transition:\n opacity 120ms ease-out,\n background 120ms ease-out;\n }\n .rp-node:hover .rp-copy {\n opacity: 1;\n }\n .rp-copy:hover {\n background: rgba(30, 30, 33, 0.82);\n }\n </style>\n </head>\n <body>\n <div id=\"cesdk\"></div>\n <div id=\"bar-left\">\n <a id=\"back\" class=\"pill icon\" href=\"{{VIEWER_BASE}}/\">←</a>\n <span id=\"title\" class=\"pill\">loading…</span>\n </div>\n <div id=\"bar-right\"></div>\n <aside id=\"revision-panel\"></aside>\n <script type=\"module\" src=\"{{VIEWER_BASE}}/static/viewer.js\"></script>\n </body>\n</html>\n`,\n\t\"revision-panel.js\": `// revision-panel.js — the in-viewer revision history panel. Fetches a design's\n// full revision tree from /api/design/<root>/revisions and renders it; clicking\n// a node asks the viewer to navigate there. The viewer drives setCurrent()\n// (highlight) and refresh() (re-fetch on SSE).\n//\n// All DOM is built with createElement + textContent: revision notes are\n// agent-authored text and must never reach innerHTML.\n\n// Mount prefix set by index.html (\"\" on stdio, \"/viewer\" on HTTP); node hrefs\n// and the revisions fetch are built relative to it. See router.ts.\nconst BASE = window.__VIEWER_BASE__ ?? '';\n\nexport function createRevisionPanel({ container, root, onNavigate, onCount }) {\n let currentRev = null;\n\n function relTime(ms) {\n const s = Math.max(0, Math.round((Date.now() - ms) / 1000));\n if (s < 60) return \\`\\${s}s ago\\`;\n const m = Math.round(s / 60);\n if (m < 60) return \\`\\${m}m ago\\`;\n const h = Math.round(m / 60);\n if (h < 24) return \\`\\${h}h ago\\`;\n return \\`\\${Math.round(h / 24)}d ago\\`;\n }\n\n // Depth-first walk. At each node the spine child (or, off-spine, the latest\n // child) continues at the same depth; other children are branches at\n // depth + 1, emitted before the continuation so the spine reads top-to-bottom.\n function order(nodes) {\n const byId = new Map(nodes.map((n) => [n.id, n]));\n const children = new Map();\n for (const n of nodes) {\n if (n.parent != null) {\n const sibs = children.get(n.parent) ?? [];\n sibs.push(n);\n children.set(n.parent, sibs);\n }\n }\n for (const sibs of children.values())\n sibs.sort((a, b) => a.createdAt - b.createdAt);\n const rootNode = nodes.find((n) => n.parent === null);\n const head = nodes.reduce((a, b) => (b.createdAt > a.createdAt ? b : a));\n const spine = new Set();\n for (let n = head; n; n = n.parent != null ? byId.get(n.parent) : null)\n spine.add(n.id);\n const out = [];\n function walk(node, depth) {\n out.push({\n node,\n depth,\n isHead: node.id === head.id,\n isRoot: node.parent === null\n });\n const kids = children.get(node.id) ?? [];\n if (kids.length === 0) return;\n const primary =\n kids.find((k) => spine.has(k.id)) ?? kids[kids.length - 1];\n for (const k of kids) if (k !== primary) walk(k, depth + 1);\n walk(primary, depth);\n }\n if (rootNode) walk(rootNode, 0);\n return out;\n }\n\n function tag(text, cls) {\n const el = document.createElement('span');\n el.className = cls ? \\`rp-tag \\${cls}\\` : 'rp-tag';\n el.textContent = text;\n return el;\n }\n\n function makeNode({ node, depth, isHead, isRoot }) {\n const a = document.createElement('a');\n a.className = \\`rp-node\\${depth > 0 ? ' rp-branch' : ''}\\${isHead ? ' rp-head' : ''}\\`;\n if (isRoot) a.dataset.root = '';\n a.dataset.rev = node.id;\n a.href = \\`\\${BASE}/d/\\${root}/\\${node.id}\\`;\n a.style.marginLeft = \\`\\${depth * 16}px\\`;\n if (node.id === currentRev) a.classList.add('rp-current');\n\n const row = document.createElement('div');\n row.className = 'rp-node-row';\n if (depth > 0) {\n const elbow = document.createElement('span');\n elbow.className = 'rp-elbow';\n elbow.textContent = '└';\n row.appendChild(elbow);\n }\n const dot = document.createElement('span');\n dot.className = 'rp-dot';\n dot.textContent = '●';\n row.appendChild(dot);\n\n const body = document.createElement('div');\n body.className = 'rp-body';\n\n const idLine = document.createElement('div');\n idLine.className = 'rp-id';\n const idText = document.createElement('span');\n idText.textContent = node.id.slice(0, 7);\n idLine.appendChild(idText);\n if (isRoot) idLine.appendChild(tag('root', ''));\n if (isHead) idLine.appendChild(tag('head', 'rp-tag-head'));\n if (depth > 0) idLine.appendChild(tag('⑂ fork', 'rp-tag-fork'));\n\n const copy = document.createElement('button');\n copy.type = 'button';\n copy.className = 'rp-copy';\n copy.textContent = '⧉ copy id';\n copy.addEventListener('click', async (e) => {\n e.preventDefault();\n e.stopPropagation();\n try {\n await navigator.clipboard?.writeText(node.id);\n copy.textContent = 'copied';\n setTimeout(() => {\n copy.textContent = '⧉ copy id';\n }, 1200);\n } catch {\n /* clipboard unavailable — fail quietly (spec §6) */\n }\n });\n idLine.appendChild(copy);\n body.appendChild(idLine);\n\n const note = document.createElement('div');\n note.className = 'rp-note';\n note.textContent = node.note || '(no note)';\n note.title = node.note || '';\n body.appendChild(note);\n\n const time = document.createElement('div');\n time.className = 'rp-time';\n time.textContent = relTime(node.createdAt);\n body.appendChild(time);\n\n row.appendChild(body);\n a.appendChild(row);\n\n a.addEventListener('click', (e) => {\n // Modified clicks (⌘/Ctrl/Shift/middle) fall through to the browser,\n // which opens the pinned /d/<root>/<rev> href in a new tab.\n if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey)\n return;\n e.preventDefault();\n onNavigate(node.id);\n });\n return a;\n }\n\n function paint(nodes) {\n container.replaceChildren();\n const header = document.createElement('div');\n header.className = 'rp-header';\n header.textContent = 'Revisions';\n container.appendChild(header);\n if (nodes.length === 0) {\n const empty = document.createElement('div');\n empty.className = 'rp-empty';\n empty.textContent = 'no revisions yet';\n container.appendChild(empty);\n return;\n }\n const tree = document.createElement('div');\n tree.className = 'rp-tree';\n for (const item of order(nodes)) tree.appendChild(makeNode(item));\n container.appendChild(tree);\n }\n\n function showError(message) {\n container.replaceChildren();\n const el = document.createElement('div');\n el.className = 'rp-empty';\n el.textContent = message;\n container.appendChild(el);\n }\n\n async function refresh() {\n try {\n const res = await fetch(\\`\\${BASE}/api/design/\\${root}/revisions\\`);\n if (!res.ok) throw new Error(String(res.status));\n const nodes = await res.json();\n paint(nodes);\n onCount(nodes.length);\n } catch {\n showError(\"couldn't load history\");\n onCount(0);\n }\n }\n\n function setCurrent(rev) {\n currentRev = rev;\n for (const el of container.querySelectorAll('.rp-node')) {\n el.classList.toggle('rp-current', el.dataset.rev === rev);\n }\n }\n\n refresh();\n return { setCurrent, refresh };\n}\n`,\n\t\"studio.html\": `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <title>IMG.LY CODESIGN MCP Workspace</title>\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n <!-- Mount prefix injected by the viewer router (router.ts). \"\" on the stdio\n listener, \"/viewer\" on the HTTP transport. Read by studio.js. -->\n <script>\n window.__VIEWER_BASE__ = '{{VIEWER_BASE}}';\n </script>\n <style>\n /* -------- reset --------\n\t\t\t Same palette + typography as the viewer SPA so the overview reads\n\t\t\t as part of the same product. See src/viewer/spa/index.html. */\n html,\n body {\n margin: 0;\n padding: 0;\n min-height: 100%;\n background: #1d1d1f;\n color: #eee;\n font-family: -apple-system, system-ui, sans-serif;\n }\n\n /* -------- sticky frosted strip --------\n\t\t\t Same frosted-glass material as the viewer pills + history panel:\n\t\t\t translucent dark + backdrop-blur + 1px hairline border. Sticky so\n\t\t\t the title stays visible while scrolling. */\n #bar {\n position: sticky;\n top: 0;\n z-index: 10;\n padding: 14px 24px;\n background: rgba(20, 20, 22, 0.72);\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n border-bottom: 1px solid rgba(255, 255, 255, 0.08);\n }\n #bar .title {\n font:\n 600 14px -apple-system,\n system-ui,\n sans-serif;\n letter-spacing: 0.02em;\n color: #e8e8e8;\n }\n\n /* -------- design grid -------- */\n .grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));\n gap: 16px;\n padding: 24px;\n }\n\n .empty {\n padding: 24px 4px;\n font-size: 13px;\n color: #888;\n }\n .empty code {\n font-family: ui-monospace, monospace;\n background: rgba(255, 255, 255, 0.05);\n border: 1px solid rgba(255, 255, 255, 0.08);\n border-radius: 4px;\n padding: 1px 6px;\n font-size: 12px;\n color: #cfcfcf;\n }\n\n /* -------- card --------\n\t\t\t Frosted-glass card, same materials as the history panel rows.\n\t\t\t Hover lifts the card and brightens the border + shadow to match the\n\t\t\t pill-hover pattern in the viewer chrome. */\n .card {\n display: block;\n text-decoration: none;\n color: inherit;\n background: rgba(20, 20, 22, 0.72);\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n border: 1px solid rgba(255, 255, 255, 0.08);\n border-radius: 12px;\n box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);\n overflow: hidden;\n transition:\n transform 120ms ease-out,\n border-color 120ms ease-out,\n box-shadow 120ms ease-out;\n }\n .card:hover {\n transform: translateY(-2px);\n border-color: rgba(255, 255, 255, 0.15);\n box-shadow: 0 8px 22px rgba(0, 0, 0, 0.35);\n }\n .card img {\n display: block;\n width: 100%;\n aspect-ratio: 4/3;\n object-fit: cover;\n background: #000;\n }\n .card .meta {\n padding: 12px 14px;\n }\n .card .title {\n font:\n 600 13px -apple-system,\n system-ui,\n sans-serif;\n color: #eee;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .card .updated {\n margin-top: 4px;\n font-size: 11px;\n color: #888;\n }\n </style>\n </head>\n <body>\n <header id=\"bar\">\n <span class=\"title\">IMG.LY CODESIGN MCP Workspace</span>\n </header>\n <div id=\"grid\" class=\"grid\"></div>\n <script type=\"module\" src=\"{{VIEWER_BASE}}/static/studio.js\"></script>\n </body>\n</html>\n`,\n\t\"studio.js\": `// Workspace overview landing page. Fetches /api/designs and renders one card\n// per design (keyed by root revision). Re-renders on tab focus and a 10s poll\n// so card links and thumbnails never go stale after the agent edits.\n//\n// DOM is built with createElement + textContent (never innerHTML for\n// design-supplied strings) so an author-controlled title can't escape into\n// HTML. Same pattern as viewer.js.\n\n// Mount prefix set by studio.html (\"\" on stdio, \"/viewer\" on HTTP); card\n// links, thumbnails, and the designs fetch are built relative to it. See\n// router.ts.\nconst BASE = window.__VIEWER_BASE__ ?? '';\n\nconst grid = document.getElementById('grid');\n\nfunction buildCard(d) {\n const card = document.createElement('a');\n card.className = 'card';\n card.href = \\`\\${BASE}/d/\\${d.rootRevision}\\`;\n\n const img = document.createElement('img');\n img.src = \\`\\${BASE}/snapshot/\\${d.latestLeaf}/thumbnail\\`;\n img.alt = '';\n img.addEventListener('error', () => {\n img.style.display = 'none';\n });\n card.appendChild(img);\n\n const meta = document.createElement('div');\n meta.className = 'meta';\n\n const title = document.createElement('div');\n title.className = 'title';\n title.textContent = d.title || 'Untitled';\n meta.appendChild(title);\n\n const updated = document.createElement('div');\n updated.className = 'updated';\n updated.textContent = \\`updated \\${new Date(d.updatedAt).toLocaleString()}\\`;\n meta.appendChild(updated);\n\n card.appendChild(meta);\n return card;\n}\n\nfunction renderEmptyText(text) {\n const div = document.createElement('div');\n div.className = 'empty';\n div.textContent = text;\n grid.replaceChildren(div);\n}\n\nfunction renderFirstRunEmpty() {\n const div = document.createElement('div');\n div.className = 'empty';\n div.appendChild(document.createTextNode('No designs yet — your first '));\n const code = document.createElement('code');\n code.textContent = 'edit({ parent: null, ... })';\n div.appendChild(code);\n div.appendChild(document.createTextNode(' will land here.'));\n grid.replaceChildren(div);\n}\n\nasync function render() {\n const res = await fetch(\\`\\${BASE}/api/designs\\`);\n if (!res.ok) {\n renderEmptyText(\\`failed to load designs: \\${res.status}\\`);\n return;\n }\n const designs = await res.json();\n if (designs.length === 0) {\n renderFirstRunEmpty();\n return;\n }\n grid.replaceChildren(...designs.map(buildCard));\n}\n\n// \\`render()\\` rejects on a network error; every caller logs it rather than\n// leaving an unhandled promise rejection.\nawait render().catch(console.error);\ndocument.addEventListener('visibilitychange', () => {\n if (!document.hidden) render().catch(console.error);\n});\nsetInterval(() => render().catch(console.error), 10000);\n`,\n\t\"viewer.js\": `// Read-only CE.SDK viewer with a revision-history side panel.\n// /d/<root> LIVE — opens at the design head, follows new revisions\n// /d/<root>/<rev> PINNED — opens frozen at <rev>\n//\n// Chrome is floating pill clusters in the corners; the history panel is a\n// detached card on the right.\n// See: docs/superpowers/specs/2026-05-24-viewer-ui-refresh-design.md\n//\n// Navigation is client-side: clicking a panel node (or the \"Go Live →\"\n// affordance) swaps the canvas and rewrites the URL via the History API — one\n// CE.SDK instance for the life of the tab. The SSE connection is held open\n// in BOTH modes so the panel's tree always stays fresh; it moves the canvas\n// only while \\`following\\`.\n\n// Mount prefix set by index.html (\"\" on stdio, \"/viewer\" on HTTP). Every\n// API/asset/history URL below is built relative to it so the SPA works under\n// any mount path. See router.ts.\nconst BASE = window.__VIEWER_BASE__ ?? '';\n\n// Path of the current page with the mount prefix stripped, so PATH_RE (which\n// is written relative to the SPA root) matches under \"/viewer\" too.\nconst relPath = () =>\n location.pathname.startsWith(BASE)\n ? location.pathname.slice(BASE.length)\n : location.pathname;\n\nconst { createRevisionPanel } = await import(\n \\`\\${BASE}/static/revision-panel.js\\`\n);\n\nconst PATH_RE = /^\\\\/d\\\\/([0-9a-f]{12})(?:\\\\/([0-9a-f]{12}))?$/;\nconst titleEl = document.getElementById('title');\nconst barRightEl = document.getElementById('bar-right');\nconst panelEl = document.getElementById('revision-panel');\n\nconst match = relPath().match(PATH_RE);\n\nif (!match) {\n titleEl.textContent = 'invalid URL';\n} else {\n const root = match[1];\n\n // Server-supplied license + resource base, fetched before bootstrapping\n // CE.SDK. CE.SDK validates the license regardless of role; \\`resourceBase\\`\n // is where workspace:// asset URIs resolve.\n const cfgRes = await fetch(\\`\\${BASE}/api/config\\`);\n if (!cfgRes.ok) throw new Error(\\`/api/config failed: \\${cfgRes.status}\\`);\n const { license, resourceBase } = await cfgRes.json();\n\n const cesdkMod =\n await import('https://cdn.img.ly/packages/imgly/cesdk-js/1.74.0/index.js');\n const CreativeEditorSDK = cesdkMod.default ?? cesdkMod.CreativeEditorSDK;\n const instance = await CreativeEditorSDK.create(\n document.getElementById('cesdk'),\n {\n license,\n role: 'Viewer',\n theme: 'dark',\n // The refresh moved all chrome out of CE.SDK and into our own floating\n // pills + history panel — back / title / LIVE / Go Live / hash / History.\n // CE.SDK's own nav + dock would render in the same physical space and,\n // because #cesdk has no stacking context, their internal z-indexes\n // outrank our z:10 pills, hiding them. \\`ui.hide: true\\` disables the\n // CE.SDK chrome entirely; users keep mousewheel zoom + drag-to-pan via\n // the engine, which is unaffected.\n ui: { hide: true }\n }\n );\n\n // Resolve workspace:// asset URIs to the /r/ HTTP route.\n const absResourceBase = location.origin + resourceBase;\n instance.engine.editor.setURIResolver((uri, defaultResolver) =>\n uri.startsWith('workspace://')\n ? absResourceBase + uri.slice('workspace://'.length)\n : defaultResolver(uri)\n );\n\n // --- runtime state ----------------------------------------------------\n let head = null; // the design's latest leaf\n let currentRev = null; // the revision currently on canvas\n let following = false; // true → the canvas tracks head as SSE arrives\n let newCount = 0; // revisions arrived since following stopped\n let panelOpen = false; // whether the history panel is visible\n\n async function loadRevision(rev) {\n const res = await fetch(\\`\\${BASE}/snapshot/\\${rev}\\`);\n if (!res.ok) throw new Error(\\`snapshot \\${rev} \\${res.status}\\`);\n const snap = await res.json();\n await instance.engine.scene.loadFromString(snap.scene);\n titleEl.textContent = snap.title ?? 'Untitled';\n }\n\n // Builds the right-side cluster from current state. Idempotent — called on\n // every mode flip, panel toggle, and newCount change. Uses createElement +\n // textContent everywhere (never innerHTML) so any author-supplied strings\n // can't escape into HTML.\n function renderRightCluster() {\n const nodes = [];\n\n if (following) {\n // LIVE — read-only green-dot pill.\n const live = document.createElement('span');\n live.className = 'pill live';\n live.textContent = 'LIVE';\n nodes.push(live);\n } else {\n // PINNED — hash chip (click-to-copy) + Go Live (+ count badge).\n const hash = document.createElement('button');\n hash.type = 'button';\n hash.className = 'pill hash';\n hash.title = 'copy revision id';\n hash.textContent = currentRev ? currentRev.slice(0, 7) : '';\n hash.addEventListener('click', async () => {\n if (!currentRev) return;\n try {\n await navigator.clipboard?.writeText(currentRev);\n } catch {\n /* clipboard unavailable — fail quietly (matches .rp-copy) */\n }\n });\n nodes.push(hash);\n\n const golive = document.createElement('button');\n golive.type = 'button';\n golive.className = 'pill golive';\n golive.appendChild(document.createTextNode('Go Live →'));\n if (newCount > 0) {\n const count = document.createElement('span');\n count.className = 'count';\n count.textContent = String(newCount);\n golive.appendChild(count);\n }\n golive.addEventListener('click', (e) => {\n if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey)\n return;\n e.preventDefault();\n if (head) show(head, { following: true, historyMode: 'push' });\n });\n nodes.push(golive);\n }\n\n const history = document.createElement('button');\n history.type = 'button';\n history.className = \\`pill history\\${panelOpen ? ' active' : ''}\\`;\n history.textContent = 'History';\n history.addEventListener('click', () => setPanelOpen(!panelOpen));\n nodes.push(history);\n\n barRightEl.replaceChildren(...nodes);\n }\n\n function setPanelOpen(open) {\n panelOpen = open;\n document.body.classList.toggle('panel-open', open);\n renderRightCluster();\n }\n\n // The single navigation primitive. Loads \\`rev\\` onto the canvas, sets the\n // LIVE/PINNED state, and writes the URL. \\`historyMode\\`: \"push\" adds a\n // history entry, \"replace\" rewrites in place, \"none\" leaves history alone\n // (used by popstate, where the browser already changed the URL).\n async function show(rev, { following: nextFollowing, historyMode }) {\n try {\n await loadRevision(rev);\n currentRev = rev;\n following = nextFollowing;\n if (following) newCount = 0;\n const url = following ? \\`\\${BASE}/d/\\${root}\\` : \\`\\${BASE}/d/\\${root}/\\${rev}\\`;\n if (historyMode === 'push') window.history.pushState({ rev }, '', url);\n else if (historyMode === 'replace')\n window.history.replaceState({ rev }, '', url);\n panel.setCurrent(rev);\n } catch {\n titleEl.textContent = 'unknown revision';\n }\n renderRightCluster();\n }\n\n // --- revision panel ---------------------------------------------------\n const panel = createRevisionPanel({\n container: panelEl,\n root,\n // Clicking a node pins it — unless it is the head, which is LIVE.\n onNavigate: (rev) =>\n show(rev, { following: rev === head, historyMode: 'push' }),\n onCount: () => {\n /* The History pill no longer carries the total count; the unseen-since-\n\t\t\t pin count lives on Go Live and is driven by \\`newCount\\` directly. */\n }\n });\n\n // --- keyboard ---------------------------------------------------------\n window.addEventListener('keydown', (e) => {\n if (e.key === 'Escape' && panelOpen) setPanelOpen(false);\n });\n\n // --- bootstrap --------------------------------------------------------\n let latestLeaf;\n try {\n const res = await fetch(\\`\\${BASE}/api/design/\\${root}\\`);\n if (!res.ok) throw new Error(String(res.status));\n latestLeaf = (await res.json()).latestLeaf;\n } catch {\n titleEl.textContent = 'unknown design';\n }\n\n if (latestLeaf !== undefined) {\n head = latestLeaf;\n const pinned = match[2]; // undefined → LIVE\n // Mode is the URL shape: a pinned URL stays pinned even if <rev> is head.\n await show(pinned ?? head, {\n following: pinned === undefined,\n historyMode: 'replace'\n });\n\n // SSE — held open for the life of the tab, in both modes. Every event\n // refreshes the panel's tree; it moves the canvas only while following.\n const es = new EventSource(\\`\\${BASE}/sse/\\${root}\\`);\n es.onmessage = (ev) => {\n let payload;\n try {\n payload = JSON.parse(ev.data);\n } catch (err) {\n console.error('sse parse failed', err);\n return;\n }\n if (!payload || typeof payload.revision !== 'string') return;\n head = payload.revision;\n panel.refresh();\n if (following) {\n show(head, { following: true, historyMode: 'replace' });\n } else {\n newCount += 1;\n renderRightCluster();\n }\n };\n }\n\n // Browser back/forward: re-resolve the URL shape and sync, without writing\n // history (the entry already changed).\n window.addEventListener('popstate', () => {\n const m = relPath().match(PATH_RE);\n if (!m || m[1] !== root) return;\n const pinned = m[2];\n show(pinned ?? head, {\n following: pinned === undefined,\n historyMode: 'none'\n });\n });\n}\n`,\n};\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export interface ViewerUrlBuilder {
|
|
2
|
+
/** Stable URL for a design, keyed by its root revision id. The viewer opens
|
|
3
|
+
* at the head and live-follows — the URL to print once and reuse. */
|
|
4
|
+
forDesign(root: string): string;
|
|
5
|
+
/** Permalink to one exact revision of a design. The viewer renders it
|
|
6
|
+
* frozen — no follow. */
|
|
7
|
+
forPinnedRevision(root: string, revision: string): string;
|
|
8
|
+
forStudio(): string;
|
|
9
|
+
/** Absolute URL for a workspace resource (assets/, exports/) served by the `/r/` route.
|
|
10
|
+
* MUST stay synchronous — the CE.SDK `workspace://` URI resolver callback is sync. */
|
|
11
|
+
forResource(relpath: string): string;
|
|
12
|
+
/** Download URL for a workspace artifact.
|
|
13
|
+
* Local: identical to `forResource` (the `/r/` route works locally).
|
|
14
|
+
* Hosted (S3/R2): a presigned GET URL so the client can download directly from storage. */
|
|
15
|
+
forDownload(relpath: string): Promise<string>;
|
|
16
|
+
}
|
|
17
|
+
export interface LocalUrlBuilderOptions {
|
|
18
|
+
/** Listener base URL, e.g. "http://127.0.0.1:8745". No trailing slash. */
|
|
19
|
+
base: string;
|
|
20
|
+
}
|
|
21
|
+
export declare class LocalViewerUrlBuilder implements ViewerUrlBuilder {
|
|
22
|
+
private readonly opts;
|
|
23
|
+
constructor(opts: LocalUrlBuilderOptions);
|
|
24
|
+
forDesign(root: string): string;
|
|
25
|
+
forPinnedRevision(root: string, revision: string): string;
|
|
26
|
+
forStudio(): string;
|
|
27
|
+
forResource(relpath: string): string;
|
|
28
|
+
forDownload(relpath: string): Promise<string>;
|
|
29
|
+
}
|
|
30
|
+
export interface ViewerBaseOptions {
|
|
31
|
+
/** Public origin (no trailing slash); undefined → loopback origin. */
|
|
32
|
+
publicBaseUrl: string | undefined;
|
|
33
|
+
/** Listener port — used only for the loopback origin. The loopback host is
|
|
34
|
+
* 127.0.0.1 (a connect address; the server binds 0.0.0.0 separately). */
|
|
35
|
+
port: number;
|
|
36
|
+
/** `session` uses the per-session `/v/<sid>` mount; `single`/`header` the
|
|
37
|
+
* fixed `/viewer` mount. */
|
|
38
|
+
mode: 'header' | 'session' | 'single';
|
|
39
|
+
sessionId: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Where a session's viewer lives. This is the single rule both `open_editor`
|
|
43
|
+
* URL construction (via the builders' `base`) and the docs rely on:
|
|
44
|
+
* session → <origin>/v/<sessionId> (multi-tenant mount, CF + local)
|
|
45
|
+
* other → <origin>/viewer (fixed-workspace mount)
|
|
46
|
+
*/
|
|
47
|
+
export declare function viewerBaseFor(opts: ViewerBaseOptions): string;
|
|
48
|
+
//# sourceMappingURL=url-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-builder.d.ts","sourceRoot":"","sources":["../../src/viewer/url-builder.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B;0EACsE;IACtE,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAChC;8BAC0B;IAC1B,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1D,SAAS,IAAI,MAAM,CAAC;IACpB;2FACuF;IACvF,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACrC;;gGAE4F;IAC5F,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,sBAAsB;IACrC,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,qBAAsB,YAAW,gBAAgB;IAChD,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,sBAAsB;IACzD,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAG/B,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAGzD,SAAS,IAAI,MAAM;IAGnB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAG9B,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAIpD;AAED,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC;8EAC0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb;iCAC6B;IAC7B,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAK7D"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Builds viewer URLs. Local: a single base + path concat. Hosted (Phase 2):
|
|
3
|
+
// signed-URL minting with account scope. Split out so the open_editor tool
|
|
4
|
+
// and the viewer router share construction logic.
|
|
5
|
+
export class LocalViewerUrlBuilder {
|
|
6
|
+
constructor(opts) {
|
|
7
|
+
this.opts = opts;
|
|
8
|
+
}
|
|
9
|
+
forDesign(root) {
|
|
10
|
+
return `${this.opts.base}/d/${root}`;
|
|
11
|
+
}
|
|
12
|
+
forPinnedRevision(root, revision) {
|
|
13
|
+
return `${this.opts.base}/d/${root}/${revision}`;
|
|
14
|
+
}
|
|
15
|
+
forStudio() {
|
|
16
|
+
return `${this.opts.base}/`;
|
|
17
|
+
}
|
|
18
|
+
forResource(relpath) {
|
|
19
|
+
return `${this.opts.base}/r/${relpath}`;
|
|
20
|
+
}
|
|
21
|
+
async forDownload(relpath) {
|
|
22
|
+
// Local: the /r/ route is reachable, so the resource URL doubles as the download URL.
|
|
23
|
+
return this.forResource(relpath);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Where a session's viewer lives. This is the single rule both `open_editor`
|
|
28
|
+
* URL construction (via the builders' `base`) and the docs rely on:
|
|
29
|
+
* session → <origin>/v/<sessionId> (multi-tenant mount, CF + local)
|
|
30
|
+
* other → <origin>/viewer (fixed-workspace mount)
|
|
31
|
+
*/
|
|
32
|
+
export function viewerBaseFor(opts) {
|
|
33
|
+
const origin = opts.publicBaseUrl ?? `http://127.0.0.1:${opts.port}`;
|
|
34
|
+
return opts.mode === 'session'
|
|
35
|
+
? `${origin}/v/${opts.sessionId}`
|
|
36
|
+
: `${origin}/viewer`;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=url-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-builder.js","sourceRoot":"","sources":["../../src/viewer/url-builder.ts"],"names":[],"mappings":"AAAA,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,kDAAkD;AAwBlD,MAAM,OAAO,qBAAqB;IAChC,YAA6B,IAA4B;QAA5B,SAAI,GAAJ,IAAI,CAAwB;IAAG,CAAC;IAC7D,SAAS,CAAC,IAAY;QACpB,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,IAAI,EAAE,CAAC;IACvC,CAAC;IACD,iBAAiB,CAAC,IAAY,EAAE,QAAgB;QAC9C,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;IACnD,CAAC;IACD,SAAS;QACP,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;IAC9B,CAAC;IACD,WAAW,CAAC,OAAe;QACzB,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,OAAO,EAAE,CAAC;IAC1C,CAAC;IACD,KAAK,CAAC,WAAW,CAAC,OAAe;QAC/B,sFAAsF;QACtF,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;CACF;AAcD;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAuB;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,IAAI,oBAAoB,IAAI,CAAC,IAAI,EAAE,CAAC;IACrE,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS;QAC5B,CAAC,CAAC,GAAG,MAAM,MAAM,IAAI,CAAC,SAAS,EAAE;QACjC,CAAC,CAAC,GAAG,MAAM,SAAS,CAAC;AACzB,CAAC","sourcesContent":["//\n// Builds viewer URLs. Local: a single base + path concat. Hosted (Phase 2):\n// signed-URL minting with account scope. Split out so the open_editor tool\n// and the viewer router share construction logic.\n\nexport interface ViewerUrlBuilder {\n /** Stable URL for a design, keyed by its root revision id. The viewer opens\n * at the head and live-follows — the URL to print once and reuse. */\n forDesign(root: string): string;\n /** Permalink to one exact revision of a design. The viewer renders it\n * frozen — no follow. */\n forPinnedRevision(root: string, revision: string): string;\n forStudio(): string;\n /** Absolute URL for a workspace resource (assets/, exports/) served by the `/r/` route.\n * MUST stay synchronous — the CE.SDK `workspace://` URI resolver callback is sync. */\n forResource(relpath: string): string;\n /** Download URL for a workspace artifact.\n * Local: identical to `forResource` (the `/r/` route works locally).\n * Hosted (S3/R2): a presigned GET URL so the client can download directly from storage. */\n forDownload(relpath: string): Promise<string>;\n}\n\nexport interface LocalUrlBuilderOptions {\n /** Listener base URL, e.g. \"http://127.0.0.1:8745\". No trailing slash. */\n base: string;\n}\n\nexport class LocalViewerUrlBuilder implements ViewerUrlBuilder {\n constructor(private readonly opts: LocalUrlBuilderOptions) {}\n forDesign(root: string): string {\n return `${this.opts.base}/d/${root}`;\n }\n forPinnedRevision(root: string, revision: string): string {\n return `${this.opts.base}/d/${root}/${revision}`;\n }\n forStudio(): string {\n return `${this.opts.base}/`;\n }\n forResource(relpath: string): string {\n return `${this.opts.base}/r/${relpath}`;\n }\n async forDownload(relpath: string): Promise<string> {\n // Local: the /r/ route is reachable, so the resource URL doubles as the download URL.\n return this.forResource(relpath);\n }\n}\n\nexport interface ViewerBaseOptions {\n /** Public origin (no trailing slash); undefined → loopback origin. */\n publicBaseUrl: string | undefined;\n /** Listener port — used only for the loopback origin. The loopback host is\n * 127.0.0.1 (a connect address; the server binds 0.0.0.0 separately). */\n port: number;\n /** `session` uses the per-session `/v/<sid>` mount; `single`/`header` the\n * fixed `/viewer` mount. */\n mode: 'header' | 'session' | 'single';\n sessionId: string;\n}\n\n/**\n * Where a session's viewer lives. This is the single rule both `open_editor`\n * URL construction (via the builders' `base`) and the docs rely on:\n * session → <origin>/v/<sessionId> (multi-tenant mount, CF + local)\n * other → <origin>/viewer (fixed-workspace mount)\n */\nexport function viewerBaseFor(opts: ViewerBaseOptions): string {\n const origin = opts.publicBaseUrl ?? `http://127.0.0.1:${opts.port}`;\n return opts.mode === 'session'\n ? `${origin}/v/${opts.sessionId}`\n : `${origin}/viewer`;\n}\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type Dirent, type FileHandleStats, type MkdirOptions, type ReadFileOptions, type WorkspaceFS } from './types.js';
|
|
2
|
+
export interface HostedStubOptions {
|
|
3
|
+
/** The IMG.LY account id this workspace belongs to. Phase 2 will key storage by this. */
|
|
4
|
+
account: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class HostedStubWorkspaceFS implements WorkspaceFS {
|
|
7
|
+
private readonly opts;
|
|
8
|
+
constructor(opts: HostedStubOptions);
|
|
9
|
+
get account(): string;
|
|
10
|
+
private nope;
|
|
11
|
+
readFile(path: string): Promise<Uint8Array>;
|
|
12
|
+
readFile(path: string, encoding: 'utf8' | 'utf-8'): Promise<string>;
|
|
13
|
+
readFile(path: string, options: ReadFileOptions): Promise<Uint8Array | string>;
|
|
14
|
+
writeFile(_path: string, _data: Uint8Array | string): Promise<void>;
|
|
15
|
+
stat(_path: string): Promise<FileHandleStats>;
|
|
16
|
+
exists(_path: string): Promise<boolean>;
|
|
17
|
+
readdir(path: string): Promise<string[]>;
|
|
18
|
+
readdir(path: string, options: {
|
|
19
|
+
withFileTypes: true;
|
|
20
|
+
}): Promise<Dirent[]>;
|
|
21
|
+
mkdir(_path: string, _options?: MkdirOptions): Promise<void>;
|
|
22
|
+
rm(_path: string, _options?: {
|
|
23
|
+
recursive?: boolean;
|
|
24
|
+
force?: boolean;
|
|
25
|
+
}): Promise<void>;
|
|
26
|
+
rename(_oldPath: string, _newPath: string): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=hosted-stub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-stub.d.ts","sourceRoot":"","sources":["../../src/workspace/hosted-stub.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,MAAM,EACX,KAAK,eAAe,EAEpB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,iBAAiB;IAChC,yFAAyF;IACzF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAsB,YAAW,WAAW;IAC3C,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,iBAAiB;IAEpD,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,OAAO,CAAC,IAAI;IAON,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IACnE,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,UAAU,GAAG,MAAM,CAAC;IAQzB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAI7C,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IACxC,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,aAAa,EAAE,IAAI,CAAA;KAAE,GAC/B,OAAO,CAAC,MAAM,EAAE,CAAC;IAQd,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5D,EAAE,CACN,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAClD,OAAO,CAAC,IAAI,CAAC;IAIV,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGhE"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// packages/codesign-mcp/src/workspace/hosted-stub.ts
|
|
2
|
+
//
|
|
3
|
+
// Phase 1 Hosted backend stub. Exists so the same `buildDesignToolRegistrations`
|
|
4
|
+
// can be wired against a Hosted workspace and the only thing that fails is the
|
|
5
|
+
// actual storage call (Phase 2 wires real S3/R2). Every method except `exists`
|
|
6
|
+
// throws ENOSYS — `exists` returns false so callers can short-circuit the
|
|
7
|
+
// "does this account have a workspace yet" check without a try/catch.
|
|
8
|
+
import { fsError } from './types.js';
|
|
9
|
+
export class HostedStubWorkspaceFS {
|
|
10
|
+
constructor(opts) {
|
|
11
|
+
this.opts = opts;
|
|
12
|
+
}
|
|
13
|
+
get account() {
|
|
14
|
+
return this.opts.account;
|
|
15
|
+
}
|
|
16
|
+
nope(method) {
|
|
17
|
+
throw fsError('ENOSYS', `HostedStubWorkspaceFS.${method}: Phase 2 wires real object-store backend (not implemented)`);
|
|
18
|
+
}
|
|
19
|
+
async readFile(_path, _options) {
|
|
20
|
+
this.nope('readFile');
|
|
21
|
+
}
|
|
22
|
+
async writeFile(_path, _data) {
|
|
23
|
+
this.nope('writeFile');
|
|
24
|
+
}
|
|
25
|
+
async stat(_path) {
|
|
26
|
+
this.nope('stat');
|
|
27
|
+
}
|
|
28
|
+
async exists(_path) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
async readdir(_path, _options) {
|
|
32
|
+
this.nope('readdir');
|
|
33
|
+
}
|
|
34
|
+
async mkdir(_path, _options) {
|
|
35
|
+
this.nope('mkdir');
|
|
36
|
+
}
|
|
37
|
+
async rm(_path, _options) {
|
|
38
|
+
this.nope('rm');
|
|
39
|
+
}
|
|
40
|
+
async rename(_oldPath, _newPath) {
|
|
41
|
+
this.nope('rename');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=hosted-stub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-stub.js","sourceRoot":"","sources":["../../src/workspace/hosted-stub.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,iFAAiF;AACjF,+EAA+E;AAC/E,+EAA+E;AAC/E,0EAA0E;AAC1E,sEAAsE;AACtE,OAAO,EAGL,OAAO,EAIR,MAAM,YAAY,CAAC;AAOpB,MAAM,OAAO,qBAAqB;IAChC,YAA6B,IAAuB;QAAvB,SAAI,GAAJ,IAAI,CAAmB;IAAG,CAAC;IAExD,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IAC3B,CAAC;IAEO,IAAI,CAAC,MAAc;QACzB,MAAM,OAAO,CACX,QAAQ,EACR,yBAAyB,MAAM,6DAA6D,CAC7F,CAAC;IACJ,CAAC;IAQD,KAAK,CAAC,QAAQ,CACZ,KAAa,EACb,QAA6C;QAE7C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAAa,EAAE,KAA0B;QACvD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa;QACtB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IAOD,KAAK,CAAC,OAAO,CACX,KAAa,EACb,QAAsC;QAEtC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAa,EAAE,QAAuB;QAChD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,EAAE,CACN,KAAa,EACb,QAAmD;QAEnD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,QAAgB;QAC7C,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtB,CAAC;CACF","sourcesContent":["// packages/codesign-mcp/src/workspace/hosted-stub.ts\n//\n// Phase 1 Hosted backend stub. Exists so the same `buildDesignToolRegistrations`\n// can be wired against a Hosted workspace and the only thing that fails is the\n// actual storage call (Phase 2 wires real S3/R2). Every method except `exists`\n// throws ENOSYS — `exists` returns false so callers can short-circuit the\n// \"does this account have a workspace yet\" check without a try/catch.\nimport {\n type Dirent,\n type FileHandleStats,\n fsError,\n type MkdirOptions,\n type ReadFileOptions,\n type WorkspaceFS\n} from './types.js';\n\nexport interface HostedStubOptions {\n /** The IMG.LY account id this workspace belongs to. Phase 2 will key storage by this. */\n account: string;\n}\n\nexport class HostedStubWorkspaceFS implements WorkspaceFS {\n constructor(private readonly opts: HostedStubOptions) {}\n\n get account(): string {\n return this.opts.account;\n }\n\n private nope(method: string): never {\n throw fsError(\n 'ENOSYS',\n `HostedStubWorkspaceFS.${method}: Phase 2 wires real object-store backend (not implemented)`\n );\n }\n\n async readFile(path: string): Promise<Uint8Array>;\n async readFile(path: string, encoding: 'utf8' | 'utf-8'): Promise<string>;\n async readFile(\n path: string,\n options: ReadFileOptions\n ): Promise<Uint8Array | string>;\n async readFile(\n _path: string,\n _options?: 'utf8' | 'utf-8' | ReadFileOptions\n ): Promise<Uint8Array | string> {\n this.nope('readFile');\n }\n\n async writeFile(_path: string, _data: Uint8Array | string): Promise<void> {\n this.nope('writeFile');\n }\n\n async stat(_path: string): Promise<FileHandleStats> {\n this.nope('stat');\n }\n\n async exists(_path: string): Promise<boolean> {\n return false;\n }\n\n async readdir(path: string): Promise<string[]>;\n async readdir(\n path: string,\n options: { withFileTypes: true }\n ): Promise<Dirent[]>;\n async readdir(\n _path: string,\n _options?: { withFileTypes?: boolean }\n ): Promise<string[] | Dirent[]> {\n this.nope('readdir');\n }\n\n async mkdir(_path: string, _options?: MkdirOptions): Promise<void> {\n this.nope('mkdir');\n }\n\n async rm(\n _path: string,\n _options?: { recursive?: boolean; force?: boolean }\n ): Promise<void> {\n this.nope('rm');\n }\n\n async rename(_oldPath: string, _newPath: string): Promise<void> {\n this.nope('rename');\n }\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type Dirent, type FileHandleStats, type MkdirOptions, type ReadFileOptions, type WorkspaceFS } from './types.js';
|
|
2
|
+
export declare class InMemoryWorkspaceFS implements WorkspaceFS {
|
|
3
|
+
private files;
|
|
4
|
+
private dirs;
|
|
5
|
+
private ensureParentDirs;
|
|
6
|
+
readFile(path: string): Promise<Uint8Array>;
|
|
7
|
+
readFile(path: string, encoding: 'utf8' | 'utf-8'): Promise<string>;
|
|
8
|
+
readFile(path: string, options: ReadFileOptions): Promise<Uint8Array | string>;
|
|
9
|
+
writeFile(path: string, data: Uint8Array | string): Promise<void>;
|
|
10
|
+
stat(path: string): Promise<FileHandleStats>;
|
|
11
|
+
exists(path: string): Promise<boolean>;
|
|
12
|
+
readdir(path: string): Promise<string[]>;
|
|
13
|
+
readdir(path: string, options: {
|
|
14
|
+
withFileTypes: true;
|
|
15
|
+
}): Promise<Dirent[]>;
|
|
16
|
+
mkdir(path: string, options?: MkdirOptions): Promise<void>;
|
|
17
|
+
rm(path: string, options?: {
|
|
18
|
+
recursive?: boolean;
|
|
19
|
+
force?: boolean;
|
|
20
|
+
}): Promise<void>;
|
|
21
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=in-memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory.d.ts","sourceRoot":"","sources":["../../src/workspace/in-memory.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,MAAM,EACX,KAAK,eAAe,EAEpB,KAAK,YAAY,EAEjB,KAAK,eAAe,EACpB,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AAYpB,qBAAa,mBAAoB,YAAW,WAAW;IACrD,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,IAAI,CAA8B;IAE1C,OAAO,CAAC,gBAAgB;IAQlB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IACnE,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,UAAU,GAAG,MAAM,CAAC;IAczB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjE,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAsB5C,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKtC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IACxC,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,aAAa,EAAE,IAAI,CAAA;KAAE,GAC/B,OAAO,CAAC,MAAM,EAAE,CAAC;IA8Cd,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB1D,EAAE,CACN,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GACjD,OAAO,CAAC,IAAI,CAAC;IAgBV,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAiB9D"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// packages/codesign-mcp/src/workspace/in-memory.ts
|
|
2
|
+
//
|
|
3
|
+
// Map-backed `WorkspaceFS`. Used by tests and by short-lived process flows
|
|
4
|
+
// (e.g. evals that don't need persistence). Two flat maps: one for files
|
|
5
|
+
// (path → bytes), one for directories (path → true). Directory existence is
|
|
6
|
+
// tracked so `stat("d")` works even when `d` has been created via `mkdir`
|
|
7
|
+
// without any files inside.
|
|
8
|
+
import { fsError } from './types.js';
|
|
9
|
+
function normalise(p) {
|
|
10
|
+
if (p.startsWith('/'))
|
|
11
|
+
return p.slice(1);
|
|
12
|
+
return p;
|
|
13
|
+
}
|
|
14
|
+
function parentOf(p) {
|
|
15
|
+
const i = p.lastIndexOf('/');
|
|
16
|
+
return i === -1 ? undefined : p.slice(0, i);
|
|
17
|
+
}
|
|
18
|
+
export class InMemoryWorkspaceFS {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.files = new Map();
|
|
21
|
+
this.dirs = new Set(['', '.']); // root always exists
|
|
22
|
+
}
|
|
23
|
+
ensureParentDirs(path) {
|
|
24
|
+
let dir = parentOf(path);
|
|
25
|
+
while (dir !== undefined && dir !== '' && !this.dirs.has(dir)) {
|
|
26
|
+
this.dirs.add(dir);
|
|
27
|
+
dir = parentOf(dir);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async readFile(path, options) {
|
|
31
|
+
const key = normalise(path);
|
|
32
|
+
const data = this.files.get(key);
|
|
33
|
+
if (data === undefined)
|
|
34
|
+
throw fsError('ENOENT', `no such file: ${path}`);
|
|
35
|
+
const encoding = typeof options === 'string' ? options : options?.encoding;
|
|
36
|
+
if (encoding === 'utf8' || encoding === 'utf-8')
|
|
37
|
+
return new TextDecoder('utf-8').decode(data);
|
|
38
|
+
return data;
|
|
39
|
+
}
|
|
40
|
+
async writeFile(path, data) {
|
|
41
|
+
const key = normalise(path);
|
|
42
|
+
const bytes = typeof data === 'string' ? new TextEncoder().encode(data) : data;
|
|
43
|
+
this.ensureParentDirs(key);
|
|
44
|
+
this.files.set(key, bytes);
|
|
45
|
+
}
|
|
46
|
+
async stat(path) {
|
|
47
|
+
const key = normalise(path);
|
|
48
|
+
const data = this.files.get(key);
|
|
49
|
+
if (data !== undefined) {
|
|
50
|
+
return {
|
|
51
|
+
size: data.byteLength,
|
|
52
|
+
mtimeMs: Date.now(),
|
|
53
|
+
isFile: () => true,
|
|
54
|
+
isDirectory: () => false
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
if (this.dirs.has(key)) {
|
|
58
|
+
return {
|
|
59
|
+
size: 0,
|
|
60
|
+
mtimeMs: Date.now(),
|
|
61
|
+
isFile: () => false,
|
|
62
|
+
isDirectory: () => true
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
throw fsError('ENOENT', `no such path: ${path}`);
|
|
66
|
+
}
|
|
67
|
+
async exists(path) {
|
|
68
|
+
const key = normalise(path);
|
|
69
|
+
return this.files.has(key) || this.dirs.has(key);
|
|
70
|
+
}
|
|
71
|
+
async readdir(path, options) {
|
|
72
|
+
const dir = normalise(path);
|
|
73
|
+
if (dir !== '' &&
|
|
74
|
+
!this.dirs.has(dir) &&
|
|
75
|
+
![...this.files.keys()].some((f) => f.startsWith(`${dir}/`))) {
|
|
76
|
+
throw fsError('ENOENT', `no such directory: ${path}`);
|
|
77
|
+
}
|
|
78
|
+
const prefix = dir === '' ? '' : `${dir}/`;
|
|
79
|
+
const seen = new Set();
|
|
80
|
+
const result = [];
|
|
81
|
+
for (const f of this.files.keys()) {
|
|
82
|
+
if (!f.startsWith(prefix))
|
|
83
|
+
continue;
|
|
84
|
+
const rest = f.slice(prefix.length);
|
|
85
|
+
const segment = rest.split('/')[0];
|
|
86
|
+
if (!seen.has(segment)) {
|
|
87
|
+
seen.add(segment);
|
|
88
|
+
result.push({ name: segment, isFile: rest === segment });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
for (const d of this.dirs) {
|
|
92
|
+
if (d === dir || !d.startsWith(prefix))
|
|
93
|
+
continue;
|
|
94
|
+
const rest = d.slice(prefix.length);
|
|
95
|
+
const segment = rest.split('/')[0];
|
|
96
|
+
if (segment && !seen.has(segment)) {
|
|
97
|
+
seen.add(segment);
|
|
98
|
+
result.push({ name: segment, isFile: false });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (options?.withFileTypes) {
|
|
102
|
+
return result.map((e) => ({
|
|
103
|
+
name: e.name,
|
|
104
|
+
isFile: () => e.isFile,
|
|
105
|
+
isDirectory: () => !e.isFile
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
return result.map((e) => e.name);
|
|
109
|
+
}
|
|
110
|
+
async mkdir(path, options) {
|
|
111
|
+
const key = normalise(path);
|
|
112
|
+
if (options?.recursive) {
|
|
113
|
+
this.ensureParentDirs(`${key}/x`); // trick: ensureParentDirs walks `key`
|
|
114
|
+
this.dirs.add(key);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const parent = parentOf(key);
|
|
118
|
+
if (parent !== undefined && parent !== '' && !this.dirs.has(parent)) {
|
|
119
|
+
throw fsError('ENOENT', `parent does not exist: ${parent}`);
|
|
120
|
+
}
|
|
121
|
+
if (this.dirs.has(key) || this.files.has(key)) {
|
|
122
|
+
throw fsError('EEXIST', `path already exists: ${path}`);
|
|
123
|
+
}
|
|
124
|
+
this.dirs.add(key);
|
|
125
|
+
}
|
|
126
|
+
async rm(path, options) {
|
|
127
|
+
const key = normalise(path);
|
|
128
|
+
const hadFile = this.files.delete(key);
|
|
129
|
+
const hadDir = this.dirs.delete(key);
|
|
130
|
+
if (options?.recursive) {
|
|
131
|
+
const prefix = `${key}/`;
|
|
132
|
+
for (const f of Array.from(this.files.keys()))
|
|
133
|
+
if (f.startsWith(prefix))
|
|
134
|
+
this.files.delete(f);
|
|
135
|
+
for (const d of Array.from(this.dirs))
|
|
136
|
+
if (d.startsWith(prefix))
|
|
137
|
+
this.dirs.delete(d);
|
|
138
|
+
}
|
|
139
|
+
if (!hadFile && !hadDir && !options?.force) {
|
|
140
|
+
throw fsError('ENOENT', `no such path: ${path}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async rename(oldPath, newPath) {
|
|
144
|
+
const oldKey = normalise(oldPath);
|
|
145
|
+
const newKey = normalise(newPath);
|
|
146
|
+
const data = this.files.get(oldKey);
|
|
147
|
+
if (data !== undefined) {
|
|
148
|
+
this.ensureParentDirs(newKey);
|
|
149
|
+
this.files.delete(oldKey);
|
|
150
|
+
this.files.set(newKey, data);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (this.dirs.has(oldKey)) {
|
|
154
|
+
this.dirs.delete(oldKey);
|
|
155
|
+
this.dirs.add(newKey);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
throw fsError('ENOENT', `no such path: ${oldPath}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=in-memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory.js","sourceRoot":"","sources":["../../src/workspace/in-memory.ts"],"names":[],"mappings":"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","sourcesContent":["// packages/codesign-mcp/src/workspace/in-memory.ts\n//\n// Map-backed `WorkspaceFS`. Used by tests and by short-lived process flows\n// (e.g. evals that don't need persistence). Two flat maps: one for files\n// (path → bytes), one for directories (path → true). Directory existence is\n// tracked so `stat(\"d\")` works even when `d` has been created via `mkdir`\n// without any files inside.\nimport {\n type Dirent,\n type FileHandleStats,\n fsError,\n type MkdirOptions,\n type ReaddirOptions,\n type ReadFileOptions,\n type WorkspaceFS\n} from './types.js';\n\nfunction normalise(p: string): string {\n if (p.startsWith('/')) return p.slice(1);\n return p;\n}\n\nfunction parentOf(p: string): string | undefined {\n const i = p.lastIndexOf('/');\n return i === -1 ? undefined : p.slice(0, i);\n}\n\nexport class InMemoryWorkspaceFS implements WorkspaceFS {\n private files = new Map<string, Uint8Array>();\n private dirs = new Set<string>(['', '.']); // root always exists\n\n private ensureParentDirs(path: string): void {\n let dir = parentOf(path);\n while (dir !== undefined && dir !== '' && !this.dirs.has(dir)) {\n this.dirs.add(dir);\n dir = parentOf(dir);\n }\n }\n\n async readFile(path: string): Promise<Uint8Array>;\n async readFile(path: string, encoding: 'utf8' | 'utf-8'): Promise<string>;\n async readFile(\n path: string,\n options: ReadFileOptions\n ): Promise<Uint8Array | string>;\n async readFile(\n path: string,\n options?: 'utf8' | 'utf-8' | ReadFileOptions\n ): Promise<Uint8Array | string> {\n const key = normalise(path);\n const data = this.files.get(key);\n if (data === undefined) throw fsError('ENOENT', `no such file: ${path}`);\n const encoding = typeof options === 'string' ? options : options?.encoding;\n if (encoding === 'utf8' || encoding === 'utf-8')\n return new TextDecoder('utf-8').decode(data);\n return data;\n }\n\n async writeFile(path: string, data: Uint8Array | string): Promise<void> {\n const key = normalise(path);\n const bytes =\n typeof data === 'string' ? new TextEncoder().encode(data) : data;\n this.ensureParentDirs(key);\n this.files.set(key, bytes);\n }\n\n async stat(path: string): Promise<FileHandleStats> {\n const key = normalise(path);\n const data = this.files.get(key);\n if (data !== undefined) {\n return {\n size: data.byteLength,\n mtimeMs: Date.now(),\n isFile: () => true,\n isDirectory: () => false\n };\n }\n if (this.dirs.has(key)) {\n return {\n size: 0,\n mtimeMs: Date.now(),\n isFile: () => false,\n isDirectory: () => true\n };\n }\n throw fsError('ENOENT', `no such path: ${path}`);\n }\n\n async exists(path: string): Promise<boolean> {\n const key = normalise(path);\n return this.files.has(key) || this.dirs.has(key);\n }\n\n async readdir(path: string): Promise<string[]>;\n async readdir(\n path: string,\n options: { withFileTypes: true }\n ): Promise<Dirent[]>;\n async readdir(\n path: string,\n options?: ReaddirOptions\n ): Promise<string[] | Dirent[]> {\n const dir = normalise(path);\n if (\n dir !== '' &&\n !this.dirs.has(dir) &&\n ![...this.files.keys()].some((f) => f.startsWith(`${dir}/`))\n ) {\n throw fsError('ENOENT', `no such directory: ${path}`);\n }\n const prefix = dir === '' ? '' : `${dir}/`;\n const seen = new Set<string>();\n const result: Array<{ name: string; isFile: boolean }> = [];\n for (const f of this.files.keys()) {\n if (!f.startsWith(prefix)) continue;\n const rest = f.slice(prefix.length);\n const segment = rest.split('/')[0];\n if (!seen.has(segment)) {\n seen.add(segment);\n result.push({ name: segment, isFile: rest === segment });\n }\n }\n for (const d of this.dirs) {\n if (d === dir || !d.startsWith(prefix)) continue;\n const rest = d.slice(prefix.length);\n const segment = rest.split('/')[0];\n if (segment && !seen.has(segment)) {\n seen.add(segment);\n result.push({ name: segment, isFile: false });\n }\n }\n if (options?.withFileTypes) {\n return result.map(\n (e): Dirent => ({\n name: e.name,\n isFile: () => e.isFile,\n isDirectory: () => !e.isFile\n })\n );\n }\n return result.map((e) => e.name);\n }\n\n async mkdir(path: string, options?: MkdirOptions): Promise<void> {\n const key = normalise(path);\n if (options?.recursive) {\n this.ensureParentDirs(`${key}/x`); // trick: ensureParentDirs walks `key`\n this.dirs.add(key);\n return;\n }\n const parent = parentOf(key);\n if (parent !== undefined && parent !== '' && !this.dirs.has(parent)) {\n throw fsError('ENOENT', `parent does not exist: ${parent}`);\n }\n if (this.dirs.has(key) || this.files.has(key)) {\n throw fsError('EEXIST', `path already exists: ${path}`);\n }\n this.dirs.add(key);\n }\n\n async rm(\n path: string,\n options?: { recursive?: boolean; force?: boolean }\n ): Promise<void> {\n const key = normalise(path);\n const hadFile = this.files.delete(key);\n const hadDir = this.dirs.delete(key);\n if (options?.recursive) {\n const prefix = `${key}/`;\n for (const f of Array.from(this.files.keys()))\n if (f.startsWith(prefix)) this.files.delete(f);\n for (const d of Array.from(this.dirs))\n if (d.startsWith(prefix)) this.dirs.delete(d);\n }\n if (!hadFile && !hadDir && !options?.force) {\n throw fsError('ENOENT', `no such path: ${path}`);\n }\n }\n\n async rename(oldPath: string, newPath: string): Promise<void> {\n const oldKey = normalise(oldPath);\n const newKey = normalise(newPath);\n const data = this.files.get(oldKey);\n if (data !== undefined) {\n this.ensureParentDirs(newKey);\n this.files.delete(oldKey);\n this.files.set(newKey, data);\n return;\n }\n if (this.dirs.has(oldKey)) {\n this.dirs.delete(oldKey);\n this.dirs.add(newKey);\n return;\n }\n throw fsError('ENOENT', `no such path: ${oldPath}`);\n }\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { HostedStubWorkspaceFS } from './hosted-stub.js';
|
|
2
|
+
export { InMemoryWorkspaceFS } from './in-memory.js';
|
|
3
|
+
export { NodeWorkspaceFS } from './node-fs.js';
|
|
4
|
+
export { sanitizeWorkspaceId, ScopedWorkspaceFS } from './scoped.js';
|
|
5
|
+
export * from './types.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrE,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { HostedStubWorkspaceFS } from './hosted-stub.js';
|
|
2
|
+
export { InMemoryWorkspaceFS } from './in-memory.js';
|
|
3
|
+
export { NodeWorkspaceFS } from './node-fs.js';
|
|
4
|
+
export { sanitizeWorkspaceId, ScopedWorkspaceFS } from './scoped.js';
|
|
5
|
+
export * from './types.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrE,cAAc,YAAY,CAAC","sourcesContent":["export { HostedStubWorkspaceFS } from './hosted-stub.js';\nexport { InMemoryWorkspaceFS } from './in-memory.js';\nexport { NodeWorkspaceFS } from './node-fs.js';\nexport { sanitizeWorkspaceId, ScopedWorkspaceFS } from './scoped.js';\nexport * from './types.js';\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Dirent, FileHandleStats, MkdirOptions, ReadFileOptions, WorkspaceFS } from './types.js';
|
|
2
|
+
export declare class NodeWorkspaceFS implements WorkspaceFS {
|
|
3
|
+
readonly root: string;
|
|
4
|
+
constructor(root: string);
|
|
5
|
+
private abs;
|
|
6
|
+
readFile(path: string): Promise<Uint8Array>;
|
|
7
|
+
readFile(path: string, encoding: 'utf8' | 'utf-8'): Promise<string>;
|
|
8
|
+
readFile(path: string, options: ReadFileOptions): Promise<Uint8Array | string>;
|
|
9
|
+
writeFile(path: string, data: Uint8Array | string): Promise<void>;
|
|
10
|
+
stat(path: string): Promise<FileHandleStats>;
|
|
11
|
+
exists(path: string): Promise<boolean>;
|
|
12
|
+
readdir(path: string): Promise<string[]>;
|
|
13
|
+
readdir(path: string, options: {
|
|
14
|
+
withFileTypes: true;
|
|
15
|
+
}): Promise<Dirent[]>;
|
|
16
|
+
mkdir(path: string, options?: MkdirOptions): Promise<void>;
|
|
17
|
+
rm(path: string, options?: {
|
|
18
|
+
recursive?: boolean;
|
|
19
|
+
force?: boolean;
|
|
20
|
+
}): Promise<void>;
|
|
21
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=node-fs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-fs.d.ts","sourceRoot":"","sources":["../../src/workspace/node-fs.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,MAAM,EACN,eAAe,EACf,YAAY,EAEZ,eAAe,EACf,WAAW,EACZ,MAAM,YAAY,CAAC;AAMpB,qBAAa,eAAgB,YAAW,WAAW;aACrB,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;IAExC,OAAO,CAAC,GAAG;IAmBL,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IACnE,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,UAAU,GAAG,MAAM,CAAC;IAczB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjE,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAU5C,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUtC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IACxC,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,aAAa,EAAE,IAAI,CAAA;KAAE,GAC/B,OAAO,CAAC,MAAM,EAAE,CAAC;IAmBd,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1D,EAAE,CACN,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GACjD,OAAO,CAAC,IAAI,CAAC;IAQV,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAK9D"}
|