@agent-native/core 0.92.9 → 0.92.11
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +29 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/production-agent.ts +181 -15
- package/corpus/core/src/agent/run-manager.ts +31 -4
- package/corpus/core/src/agent/run-store.ts +80 -0
- package/corpus/core/src/cli/design-connect.ts +433 -151
- package/corpus/core/src/cli/skills.ts +14 -0
- package/corpus/core/src/client/AssistantChat.tsx +25 -0
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +40 -6
- package/corpus/core/src/client/agent-chat.ts +165 -1
- package/corpus/core/src/client/chat/index.ts +9 -1
- package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +38 -2
- package/corpus/core/src/client/index.ts +5 -0
- package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +18 -7
- package/corpus/core/src/collab/awareness-store.ts +23 -12
- package/corpus/core/src/collab/client.ts +16 -5
- package/corpus/core/src/collab/index.ts +4 -0
- package/corpus/core/src/collab/recent-edits.ts +65 -2
- package/corpus/core/src/deploy/build.ts +133 -5
- package/corpus/core/src/index.browser.ts +1 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +98 -11
- package/corpus/core/src/server/builder-design-systems.ts +30 -4
- package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +1 -1
- package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +12 -6
- package/corpus/templates/clips/AGENTS.md +4 -0
- package/corpus/templates/clips/actions/create-recording.ts +2 -0
- package/corpus/templates/clips/actions/lib/create-recording-schema.ts +5 -3
- package/corpus/templates/clips/actions/request-transcript.ts +102 -33
- package/corpus/templates/clips/app/components/library/library-grid.tsx +1 -0
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +59 -19
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +48 -4
- package/corpus/templates/clips/app/components/player/video-player.tsx +17 -12
- package/corpus/templates/clips/app/i18n/ar-SA.ts +1 -0
- package/corpus/templates/clips/app/i18n/de-DE.ts +1 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +1 -0
- package/corpus/templates/clips/app/i18n/es-ES.ts +1 -0
- package/corpus/templates/clips/app/i18n/fr-FR.ts +1 -0
- package/corpus/templates/clips/app/i18n/hi-IN.ts +1 -0
- package/corpus/templates/clips/app/i18n/ja-JP.ts +1 -0
- package/corpus/templates/clips/app/i18n/ko-KR.ts +1 -0
- package/corpus/templates/clips/app/i18n/pt-BR.ts +1 -0
- package/corpus/templates/clips/app/i18n/zh-CN.ts +1 -0
- package/corpus/templates/clips/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +70 -37
- package/corpus/templates/clips/app/routes/record.tsx +17 -4
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +2 -0
- package/corpus/templates/clips/changelog/2026-07-09-desktop-popover-sits-closer-to-the-menu-bar.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-desktop-recording-optimization-progress-stays-visible-until-the-clip-opens.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-fixed-large-video-file-uploads-failing-before-their-resumabl.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-fixed-new-video-uploads-defaulting-to-private.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-long-recordings-now-get-enough-time-to-download-their-media-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-meeting-notes-no-longer-lowers-your-microphone-volume-for-ot.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-on-mobile-tapping-a-playing-clip-reveals-playback-controls-w.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-regenerate-any-clip-transcript-from-its-saved-recording-or-r.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-slack-previews-now-show-the-clip-length-alongside-its-descri.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +12 -2
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +8 -1
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +8 -5
- package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +5 -5
- package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +3 -0
- package/corpus/templates/clips/desktop/src/styles.css +6 -3
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +29 -11
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +1 -1
- package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +103 -21
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +117 -39
- package/corpus/templates/clips/server/lib/slack-unfurls.ts +20 -1
- package/corpus/templates/clips/server/lib/streaming-upload-mode.ts +10 -4
- package/corpus/templates/clips/shared/recording-core.ts +12 -0
- package/corpus/templates/content/AGENTS.md +7 -6
- package/corpus/templates/content/actions/_document-flush.ts +132 -17
- package/corpus/templates/content/actions/_notion-action-utils.ts +15 -0
- package/corpus/templates/content/actions/create-and-link-notion-page.ts +2 -0
- package/corpus/templates/content/actions/link-notion-page.ts +2 -0
- package/corpus/templates/content/actions/pull-document.ts +5 -7
- package/corpus/templates/content/actions/pull-notion-page.ts +2 -0
- package/corpus/templates/content/actions/push-notion-page.ts +10 -0
- package/corpus/templates/content/actions/resolve-notion-sync-conflict.ts +2 -0
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +88 -23
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +32 -2
- package/corpus/templates/content/app/hooks/use-notion.ts +6 -6
- package/corpus/templates/content/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/content/app/i18n-data.ts +18 -0
- package/corpus/templates/content/changelog/2026-07-09-notion-conflict-choices-and-version-restores-preserve-docume.md +6 -0
- package/corpus/templates/content/server/lib/notion-sync.ts +80 -64
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +29 -2
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +86 -0
- package/corpus/templates/design/.agents/skills/export-handoff/SKILL.md +57 -0
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +11 -0
- package/corpus/templates/design/AGENTS.md +45 -10
- package/corpus/templates/design/actions/add-localhost-screens.ts +66 -13
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +45 -36
- package/corpus/templates/design/actions/apply-motion-edit.ts +25 -31
- package/corpus/templates/design/actions/apply-shader-fill.ts +29 -42
- package/corpus/templates/design/actions/detach-component-instance.ts +337 -0
- package/corpus/templates/design/actions/export-design-as-figma-svg.ts +219 -0
- package/corpus/templates/design/actions/generate-design.ts +79 -12
- package/corpus/templates/design/actions/generate-screens.ts +57 -12
- package/corpus/templates/design/actions/get-figma-styles.ts +115 -0
- package/corpus/templates/design/actions/go-to-main-component.ts +254 -0
- package/corpus/templates/design/actions/grant-localhost-write-consent.ts +4 -3
- package/corpus/templates/design/actions/import-design-source.ts +4 -31
- package/corpus/templates/design/actions/import-figma-clipboard.ts +134 -0
- package/corpus/templates/design/actions/import-figma-frame.ts +95 -0
- package/corpus/templates/design/actions/index-design-system-with-builder.ts +16 -1
- package/corpus/templates/design/actions/list-design-components.ts +104 -0
- package/corpus/templates/design/actions/list-figma-library-assets.ts +1 -24
- package/corpus/templates/design/actions/open-component-source.ts +2 -4
- package/corpus/templates/design/actions/present-design-variants.ts +412 -16
- package/corpus/templates/design/actions/preview-source-edit.ts +14 -1
- package/corpus/templates/design/actions/run-design-audit.ts +25 -3
- package/corpus/templates/design/actions/show-design-questions.ts +10 -0
- package/corpus/templates/design/actions/swap-component-instance.ts +544 -0
- package/corpus/templates/design/actions/take-design-screenshot.ts +45 -60
- package/corpus/templates/design/actions/write-local-file.ts +25 -1
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +152 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +1077 -58
- package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +5 -5
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +73 -21
- package/corpus/templates/design/app/components/design/EditPanel.tsx +16 -11
- package/corpus/templates/design/app/components/design/KeyboardShortcutsPanel.tsx +364 -0
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +180 -53
- package/corpus/templates/design/app/components/design/LocalhostWriteConsentDialog.tsx +0 -2
- package/corpus/templates/design/app/components/design/MotionDock.tsx +144 -21
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1152 -167
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +27 -5
- package/corpus/templates/design/app/components/design/ReviewPanel.tsx +23 -2
- package/corpus/templates/design/app/components/design/TokensPanel.tsx +63 -49
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1293 -54
- package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +7 -0
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +6 -1
- package/corpus/templates/design/app/components/design/bridge/motion-preview.bridge.ts +23 -6
- package/corpus/templates/design/app/components/design/bridge/sample.bridge.ts +7 -0
- package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +5 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +14 -2
- package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +37 -2
- package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open-guard.ts +25 -0
- package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open.ts +19 -1
- package/corpus/templates/design/app/components/design/code-workbench/model-registry.ts +43 -5
- package/corpus/templates/design/app/components/design/code-workbench/search/SearchView.tsx +27 -2
- package/corpus/templates/design/app/components/design/code-workbench/search/search-engine.ts +10 -1
- package/corpus/templates/design/app/components/design/code-workbench/store.tsx +19 -2
- package/corpus/templates/design/app/components/design/design-canvas/annotation-snapshot.ts +265 -0
- package/corpus/templates/design/app/components/design/design-canvas/annotation-submit.ts +16 -5
- package/corpus/templates/design/app/components/design/design-canvas/coordinate-transforms.ts +16 -2
- package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +7 -2
- package/corpus/templates/design/app/components/design/design-canvas/iframe-events.ts +3 -1
- package/corpus/templates/design/app/components/design/edit-panel/code-inspect-helpers.tsx +78 -8
- package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +451 -73
- package/corpus/templates/design/app/components/design/edit-panel/document-colors.ts +12 -4
- package/corpus/templates/design/app/components/design/edit-panel/effects-properties.tsx +398 -272
- package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +41 -7
- package/corpus/templates/design/app/components/design/edit-panel/element-identity.ts +16 -3
- package/corpus/templates/design/app/components/design/edit-panel/field-primitives.tsx +24 -4
- package/corpus/templates/design/app/components/design/edit-panel/fill-gradient-helpers.ts +222 -4
- package/corpus/templates/design/app/components/design/edit-panel/fill-properties.tsx +171 -78
- package/corpus/templates/design/app/components/design/edit-panel/inspector-controls.tsx +45 -5
- package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +299 -28
- package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +120 -150
- package/corpus/templates/design/app/components/design/edit-panel/position-helpers.ts +53 -1
- package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +284 -117
- package/corpus/templates/design/app/components/design/edit-panel/selection-helpers.ts +81 -0
- package/corpus/templates/design/app/components/design/edit-panel/stroke-properties.tsx +19 -14
- package/corpus/templates/design/app/components/design/edit-panel/style-options.ts +7 -0
- package/corpus/templates/design/app/components/design/edit-panel/typography-helpers.ts +155 -0
- package/corpus/templates/design/app/components/design/edit-panel/typography-properties.tsx +268 -46
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +350 -31
- package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +13 -4
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +233 -23
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +72 -2
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +51 -11
- package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +84 -11
- package/corpus/templates/design/app/components/design/inspector/index.ts +3 -0
- package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +552 -0
- package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +157 -0
- package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +53 -0
- package/corpus/templates/design/app/components/design/multi-screen/overview-layout.ts +184 -0
- package/corpus/templates/design/app/components/design/multi-screen/primitive-drop-target.ts +403 -26
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +20 -1
- package/corpus/templates/design/app/components/design/types.ts +33 -0
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +59 -7
- package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +119 -17
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +275 -63
- package/corpus/templates/design/app/hooks/use-question-flow.ts +14 -3
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +67 -10
- package/corpus/templates/design/app/i18n/zh-TW.ts +91 -1
- package/corpus/templates/design/app/i18n-data.ts +1217 -10
- package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +577 -0
- package/corpus/templates/design/app/lib/agent-chat.ts +23 -0
- package/corpus/templates/design/app/lib/design-import.ts +24 -0
- package/corpus/templates/design/app/lib/figma-clipboard.ts +157 -0
- package/corpus/templates/design/app/lib/figma-svg-copy.ts +221 -0
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +143 -30
- package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +15 -0
- package/corpus/templates/design/app/pages/design-editor/editor-session.ts +33 -0
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +38 -0
- package/corpus/templates/design/app/pages/design-editor/overview-annotation-context.ts +157 -0
- package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +62 -6
- package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +245 -0
- package/corpus/templates/design/app/pages/design-editor/react-semantic-handoff.ts +586 -0
- package/corpus/templates/design/app/pages/design-editor/screen-auto-layout.ts +169 -0
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +201 -1
- package/corpus/templates/design/changelog/2026-07-09-added-underline-strikethrough-and-text-case-uppercase-lowerc.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-annotate-now-draws-across-the-all-screens-canvas-without-swi.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-auto-layout-children-can-now-be-dragged-into-freeform-screen.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-board-shapes-now-stay-visible-and-nest-correctly-across-the-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-component-source-navigation-now-opens-reliably-from-the-insp.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-cross-screen-local-react-layer-moves-now-hand-off-exact-sour.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-cross-screen-moves-undo-and-redo-now-keep-both-screens-stabl.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-detach-a-component-instance-into-plain-editable-eleme.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-dragging-layers-into-auto-layout-now-respects-ignore-auto-la.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-drawing-annotations-sent-to-the-agent-now-include-a-rendered.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-editor-sidebars-now-use-figma-matched-default-widths-for-a-r.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-empty-frames-and-rectangles-now-expose-full-auto-layout-cont.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-export-any-design-screen-as-a-real-vector-svg-for-figma-with.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-grid-auto-layout-now-uses-true-responsive-rows-and-columns-w.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-hidden-and-locked-screens-now-behave-consistently-between-la.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-image-fills-now-preserve-valid-urls-and-layered-fit-settings.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-import-figma-frames-as-pixel-accurate-design-screens-via-a-s.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-inspect-code-now-hides-internal-styling-metadata-and-wraps-l.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-inspector-blur-and-shadow-effects-now-preserve-other-effects.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-jump-to-a-components-other-instances-from-the-inspecto.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-keyboard-shortcuts-are-now-discoverable-in-a-figma-style-bot.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-layer-selection-now-keeps-cmd-or-ctrl-toggles-and-shift-rang.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-layers-dropped-into-auto-layout-now-participate-correctly-in.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-live-edit-screens-now-enter-and-leave-full-view-withou.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-preview-urls-now-live-in-the-inspector-instead-of-taki.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-react-layers-can-now-be-hidden-and-locked-from-layers-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-react-layers-now-keep-exact-source-provenance-and-supp.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-react-visual-editing-now-loads-reliably-and-shows-live.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-paste-from-figma-cmd-v-now-imports-exact-editable-nodes-when.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-pressing-escape-after-selecting-a-screen-now-reveals-page-pr.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-right-click-overlapping-or-nested-objects-to-choose-the-exac.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-scale-edge-stretch-and-center-constraints-now-preserve-layer.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-screen-rows-can-now-be-reordered-in-layers-with-matching-can.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-screen-selection-stays-responsive-in-designs-with-hundreds-o.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-shift-a-now-enables-auto-layout-on-a-selected-screen-with-fl.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-swap-a-component-instance-for-another-from-the-libra.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-drawing-annotations-now-stay-available-to-retry-when-the.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +3 -6
- package/corpus/templates/design/e2e/helpers.ts +27 -6
- package/corpus/templates/design/server/lib/design-to-figma-svg.ts +1412 -0
- package/corpus/templates/design/server/lib/figma-clipboard-match.ts +196 -0
- package/corpus/templates/design/server/lib/figma-node-import.ts +311 -0
- package/corpus/templates/design/server/lib/figma-node-to-html.ts +1334 -0
- package/corpus/templates/design/server/lib/figma-paste-fallback.ts +64 -0
- package/corpus/templates/design/server/lib/playwright-runtime.ts +78 -0
- package/corpus/templates/design/server/plugins/db.ts +41 -0
- package/corpus/templates/design/server/source-workspace.ts +64 -0
- package/corpus/templates/design/shared/board-file.ts +13 -2
- package/corpus/templates/design/shared/canvas-math.ts +231 -33
- package/corpus/templates/design/shared/code-layer.ts +122 -8
- package/corpus/templates/design/shared/component-library.ts +161 -0
- package/corpus/templates/design/shared/db-conflict.ts +27 -0
- package/corpus/templates/design/shared/design-source-capabilities.ts +2 -1
- package/corpus/templates/design/shared/figma-url.ts +149 -0
- package/corpus/templates/design/shared/pen-path.ts +16 -7
- package/corpus/templates/design/shared/source-mode.ts +1 -0
- package/corpus/templates/plan/app/components/plan/CanvasArea.tsx +7 -19
- package/corpus/templates/plan/changelog/2026-07-09-canvas-panning-now-keeps-zoom-fixed-even-at-the-edges.md +6 -0
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +16 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +311 -70
- package/corpus/templates/slides/changelog/2026-07-09-fixed-the-slide-rail-going-permanently-stale-during-a-long-a.md +6 -0
- package/dist/agent/production-agent.d.ts +79 -6
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +161 -14
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +29 -5
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +46 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +61 -0
- package/dist/agent/run-store.js.map +1 -1
- package/dist/cli/design-connect.d.ts +6 -0
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +336 -139
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +14 -0
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +19 -3
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +38 -18
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat.d.ts +60 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +122 -1
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/chat/index.d.ts +1 -1
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js +1 -1
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.d.ts +12 -0
- package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.js +36 -2
- package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.js +18 -6
- package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
- package/dist/collab/awareness-store.d.ts +5 -0
- package/dist/collab/awareness-store.d.ts.map +1 -1
- package/dist/collab/awareness-store.js +19 -12
- package/dist/collab/awareness-store.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +13 -5
- package/dist/collab/client.js.map +1 -1
- package/dist/collab/index.d.ts +1 -0
- package/dist/collab/index.d.ts.map +1 -1
- package/dist/collab/index.js +1 -0
- package/dist/collab/index.js.map +1 -1
- package/dist/collab/recent-edits.d.ts +3 -1
- package/dist/collab/recent-edits.d.ts.map +1 -1
- package/dist/collab/recent-edits.js +57 -2
- package/dist/collab/recent-edits.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/deploy/build.d.ts +24 -0
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +102 -5
- package/dist/deploy/build.js.map +1 -1
- package/dist/index.browser.d.ts +1 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +87 -10
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/builder-design-systems.d.ts +15 -0
- package/dist/server/builder-design-systems.d.ts.map +1 -1
- package/dist/server/builder-design-systems.js +9 -4
- package/dist/server/builder-design-systems.js.map +1 -1
- package/package.json +1 -1
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
* Protocol (parent → iframe):
|
|
25
25
|
*
|
|
26
26
|
* { type: 'embedded-canvas-pan-mode', leftButtonEnabled }
|
|
27
|
+
* { type: 'embedded-canvas-gesture-mode', wheelEnabled,
|
|
28
|
+
* spaceKeyForwardingEnabled }
|
|
27
29
|
* { type: 'embedded-canvas-pan-cancel' }
|
|
28
30
|
*
|
|
29
31
|
* Rules:
|
|
@@ -244,6 +246,11 @@ declare var __EMBEDDED_SPACE_KEY_FORWARDING_ENABLED__: boolean;
|
|
|
244
246
|
}
|
|
245
247
|
if (e.data.type === "embedded-canvas-pan-mode") {
|
|
246
248
|
leftButtonEnabled = !!e.data.leftButtonEnabled;
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
if (e.data.type === "embedded-canvas-gesture-mode") {
|
|
252
|
+
wheelEnabled = !!e.data.wheelEnabled;
|
|
253
|
+
spaceKeyForwardingEnabled = !!e.data.spaceKeyForwardingEnabled;
|
|
247
254
|
}
|
|
248
255
|
}
|
|
249
256
|
|
|
@@ -251,7 +251,12 @@
|
|
|
251
251
|
el.getAttribute("data-agent-native-primitive") ||
|
|
252
252
|
""
|
|
253
253
|
).toLowerCase();
|
|
254
|
-
if (
|
|
254
|
+
if (
|
|
255
|
+
primitive !== "rectangle" &&
|
|
256
|
+
primitive !== "rect" &&
|
|
257
|
+
primitive !== "frame"
|
|
258
|
+
)
|
|
259
|
+
return false;
|
|
255
260
|
var cs = window.getComputedStyle(el);
|
|
256
261
|
return cs.position === "absolute" || cs.position === "fixed";
|
|
257
262
|
}
|
|
@@ -66,6 +66,26 @@
|
|
|
66
66
|
var touchedProps: Record<string, string[]> = {};
|
|
67
67
|
// Map of nodeId -> property -> original inline style value.
|
|
68
68
|
var originalInlineValues: Record<string, Record<string, string>> = {};
|
|
69
|
+
// Map of nodeId -> resolved element, so applyPreview's per-track lookup
|
|
70
|
+
// during scrub/playback (driven by the parent's own rAF loop — one
|
|
71
|
+
// "motion-preview" message per frame) does one attribute-selector
|
|
72
|
+
// querySelector per node ONCE instead of once per track on every single
|
|
73
|
+
// frame. Invalidated (falls through to a fresh querySelector) whenever the
|
|
74
|
+
// cached element is no longer in the document — e.g. a host-applied edit
|
|
75
|
+
// replaced the node — so a stale reference never silently no-ops a track.
|
|
76
|
+
// Reset alongside the other per-load state in clearPreview so a reload
|
|
77
|
+
// after the previewed screen's DOM changes always re-resolves.
|
|
78
|
+
var elementCache: Record<string, HTMLElement | null> = {};
|
|
79
|
+
|
|
80
|
+
function resolveTrackElement(nodeId: string): HTMLElement | null {
|
|
81
|
+
var cached = elementCache[nodeId];
|
|
82
|
+
if (cached && document.contains(cached)) return cached;
|
|
83
|
+
var el = document.querySelector(
|
|
84
|
+
'[data-agent-native-node-id="' + nodeId + '"]',
|
|
85
|
+
) as HTMLElement | null;
|
|
86
|
+
elementCache[nodeId] = el;
|
|
87
|
+
return el;
|
|
88
|
+
}
|
|
69
89
|
|
|
70
90
|
function camelizeProp(prop: string): string {
|
|
71
91
|
return String(prop).replace(/-([a-z])/g, function (_m: string, c: string) {
|
|
@@ -673,9 +693,7 @@
|
|
|
673
693
|
function applyPreview(t: number): void {
|
|
674
694
|
for (var i = 0; i < loadedTracks.length; i++) {
|
|
675
695
|
var track = loadedTracks[i];
|
|
676
|
-
var el =
|
|
677
|
-
'[data-agent-native-node-id="' + track.targetNodeId + '"]',
|
|
678
|
-
) as HTMLElement | null;
|
|
696
|
+
var el = resolveTrackElement(track.targetNodeId);
|
|
679
697
|
if (!el) continue;
|
|
680
698
|
var value = interpolate(track.keyframes, trackLocalT(track, t));
|
|
681
699
|
if (value === "") continue;
|
|
@@ -700,9 +718,7 @@
|
|
|
700
718
|
function clearPreview(): void {
|
|
701
719
|
var nodeIds = Object.keys(touchedProps);
|
|
702
720
|
for (var i = 0; i < nodeIds.length; i++) {
|
|
703
|
-
var el =
|
|
704
|
-
'[data-agent-native-node-id="' + nodeIds[i] + '"]',
|
|
705
|
-
) as HTMLElement | null;
|
|
721
|
+
var el = resolveTrackElement(nodeIds[i]);
|
|
706
722
|
if (!el) continue;
|
|
707
723
|
var props = touchedProps[nodeIds[i]];
|
|
708
724
|
for (var j = 0; j < props.length; j++) {
|
|
@@ -718,6 +734,7 @@
|
|
|
718
734
|
loadedTracks = [];
|
|
719
735
|
loadedDefaultEase = "ease";
|
|
720
736
|
loadedTimelineDurationMs = null;
|
|
737
|
+
elementCache = {};
|
|
721
738
|
}
|
|
722
739
|
|
|
723
740
|
// Last previewed playhead position, so reloading the track list (which
|
|
@@ -10,6 +10,13 @@
|
|
|
10
10
|
*/
|
|
11
11
|
(function () {
|
|
12
12
|
window.addEventListener("message", function (e: MessageEvent) {
|
|
13
|
+
// Every other *.bridge.ts listener validates the sender before trusting
|
|
14
|
+
// the payload (see editor-chrome.bridge.ts, hit-test.bridge.ts, etc. —
|
|
15
|
+
// all check `e.source !== window.parent`); this one didn't, even though
|
|
16
|
+
// it's just a compile-pipeline smoke-test fixture with no real iframe
|
|
17
|
+
// wiring today. Match the house rule so it stays a safe template to
|
|
18
|
+
// copy from if this file is ever pointed at a live surface.
|
|
19
|
+
if (e.source !== window.parent) return;
|
|
13
20
|
if (!e.data || e.data.type !== "agent-native:sample-ping") return;
|
|
14
21
|
var correlationId: string = e.data.correlationId ?? "";
|
|
15
22
|
try {
|
|
@@ -350,9 +350,14 @@ function CodeWorkbenchInner({
|
|
|
350
350
|
const onUp = () => {
|
|
351
351
|
target.removeEventListener("pointermove", onMove);
|
|
352
352
|
target.removeEventListener("pointerup", onUp);
|
|
353
|
+
target.removeEventListener("pointercancel", onUp);
|
|
353
354
|
};
|
|
354
355
|
target.addEventListener("pointermove", onMove);
|
|
355
356
|
target.addEventListener("pointerup", onUp);
|
|
357
|
+
// A cancelled pointer (e.g. a dialog stealing capture mid-drag) would
|
|
358
|
+
// otherwise never fire pointerup, leaking these listeners onto the
|
|
359
|
+
// resize handle until the next drag piles more on top of them.
|
|
360
|
+
target.addEventListener("pointercancel", onUp);
|
|
356
361
|
},
|
|
357
362
|
[api],
|
|
358
363
|
);
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from "../../code-workbench-theme";
|
|
10
10
|
import {
|
|
11
11
|
dispatchKeybinding,
|
|
12
|
+
runCommand,
|
|
12
13
|
type WorkbenchCommand,
|
|
13
14
|
type WorkbenchCommandContext,
|
|
14
15
|
} from "../commands";
|
|
@@ -93,11 +94,22 @@ export function MonacoHost({
|
|
|
93
94
|
// Safety net: Monaco's own Cmd+S binding (if any) is not guaranteed, and
|
|
94
95
|
// the root's capture-phase keydown handler already dispatches workbench
|
|
95
96
|
// commands before Monaco sees them — this addCommand is a belt-and-
|
|
96
|
-
// braces fallback for save specifically.
|
|
97
|
+
// braces fallback for save specifically. It goes through the same
|
|
98
|
+
// `workbench.save` command (via runCommand) as every other invocation
|
|
99
|
+
// path, not a bare `api.save()` call, so a failed save (stale version,
|
|
100
|
+
// missing local write consent, network error) still surfaces a toast /
|
|
101
|
+
// consent-retry here instead of failing silently.
|
|
97
102
|
editor.addCommand(
|
|
98
103
|
monacoModule.KeyMod.CtrlCmd | monacoModule.KeyCode.KeyS,
|
|
99
104
|
() => {
|
|
100
|
-
|
|
105
|
+
const saveCommand = commandsRef.current.find(
|
|
106
|
+
(command) => command.id === "workbench.save",
|
|
107
|
+
);
|
|
108
|
+
if (saveCommand) {
|
|
109
|
+
void runCommand(saveCommand, commandContextRef.current);
|
|
110
|
+
} else {
|
|
111
|
+
void commandContextRef.current.api.save();
|
|
112
|
+
}
|
|
101
113
|
},
|
|
102
114
|
);
|
|
103
115
|
|
|
@@ -93,6 +93,16 @@ export function FileTree({
|
|
|
93
93
|
text: "",
|
|
94
94
|
at: 0,
|
|
95
95
|
});
|
|
96
|
+
// When Enter/Escape ends a rename or new-file input via setRenamingPath /
|
|
97
|
+
// setPendingNewFile, React unmounts the focused input as part of that same
|
|
98
|
+
// update. Removing a focused DOM node makes the browser fire a native blur
|
|
99
|
+
// on it, which our onBlur handler would otherwise treat as an independent
|
|
100
|
+
// commit — double-submitting on Enter (rename/create called twice) and
|
|
101
|
+
// silently committing the draft on Escape instead of discarding it. These
|
|
102
|
+
// refs let the key handler mark "I already resolved this input" so the
|
|
103
|
+
// resulting blur is a no-op.
|
|
104
|
+
const renameHandledRef = useRef(false);
|
|
105
|
+
const newFileHandledRef = useRef(false);
|
|
96
106
|
|
|
97
107
|
const rows = flattenVisibleTree(nodes, expandedPaths);
|
|
98
108
|
|
|
@@ -121,6 +131,7 @@ export function FileTree({
|
|
|
121
131
|
);
|
|
122
132
|
|
|
123
133
|
const startRename = useCallback((node: TreeNode) => {
|
|
134
|
+
renameHandledRef.current = false;
|
|
124
135
|
setRenamingPath(node.path);
|
|
125
136
|
setRenameDraft(baseName(node.path));
|
|
126
137
|
}, []);
|
|
@@ -293,6 +304,7 @@ export function FileTree({
|
|
|
293
304
|
label="New File" /* i18n-ignore */
|
|
294
305
|
icon={IconPlus}
|
|
295
306
|
onClick={() => {
|
|
307
|
+
newFileHandledRef.current = false;
|
|
296
308
|
setPendingNewFile({ parentPath: "" });
|
|
297
309
|
setNewFileDraft("");
|
|
298
310
|
}}
|
|
@@ -390,14 +402,25 @@ export function FileTree({
|
|
|
390
402
|
value={renameDraft}
|
|
391
403
|
onClick={(event) => event.stopPropagation()}
|
|
392
404
|
onChange={(event) => setRenameDraft(event.target.value)}
|
|
393
|
-
onBlur={() =>
|
|
405
|
+
onBlur={() => {
|
|
406
|
+
// Enter/Escape already resolved this input; the blur
|
|
407
|
+
// firing right after is just the DOM node unmounting,
|
|
408
|
+
// not a real "user clicked away" commit request.
|
|
409
|
+
if (renameHandledRef.current) {
|
|
410
|
+
renameHandledRef.current = false;
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
void commitRename(row.node);
|
|
414
|
+
}}
|
|
394
415
|
onKeyDown={(event) => {
|
|
395
416
|
event.stopPropagation();
|
|
396
417
|
if (event.key === "Enter") {
|
|
397
418
|
event.preventDefault();
|
|
419
|
+
renameHandledRef.current = true;
|
|
398
420
|
void commitRename(row.node);
|
|
399
421
|
} else if (event.key === "Escape") {
|
|
400
422
|
event.preventDefault();
|
|
423
|
+
renameHandledRef.current = true;
|
|
401
424
|
setRenamingPath(null);
|
|
402
425
|
}
|
|
403
426
|
}}
|
|
@@ -418,6 +441,7 @@ export function FileTree({
|
|
|
418
441
|
<ContextMenuItem
|
|
419
442
|
className="text-[12px]"
|
|
420
443
|
onSelect={() => {
|
|
444
|
+
newFileHandledRef.current = false;
|
|
421
445
|
toggleFolder(row.path, true);
|
|
422
446
|
setPendingNewFile({ parentPath: row.path });
|
|
423
447
|
setNewFileDraft("");
|
|
@@ -481,14 +505,25 @@ export function FileTree({
|
|
|
481
505
|
value={newFileDraft}
|
|
482
506
|
placeholder="filename.ext" /* i18n-ignore */
|
|
483
507
|
onChange={(event) => setNewFileDraft(event.target.value)}
|
|
484
|
-
onBlur={() =>
|
|
508
|
+
onBlur={() => {
|
|
509
|
+
// Enter/Escape already resolved this input; the blur firing
|
|
510
|
+
// right after is just the DOM node unmounting, not a real
|
|
511
|
+
// "user clicked away" commit request.
|
|
512
|
+
if (newFileHandledRef.current) {
|
|
513
|
+
newFileHandledRef.current = false;
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
void commitNewFile();
|
|
517
|
+
}}
|
|
485
518
|
onKeyDown={(event) => {
|
|
486
519
|
event.stopPropagation();
|
|
487
520
|
if (event.key === "Enter") {
|
|
488
521
|
event.preventDefault();
|
|
522
|
+
newFileHandledRef.current = true;
|
|
489
523
|
void commitNewFile();
|
|
490
524
|
} else if (event.key === "Escape") {
|
|
491
525
|
event.preventDefault();
|
|
526
|
+
newFileHandledRef.current = true;
|
|
492
527
|
setPendingNewFile(null);
|
|
493
528
|
setNewFileDraft("");
|
|
494
529
|
}
|
package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open-guard.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure guard extracted from format-on-open.ts so it stays unit-testable
|
|
3
|
+
* without pulling in `../store` / `../model-registry` (and transitively
|
|
4
|
+
* `monaco-editor`, which requires a full browser environment and can't load
|
|
5
|
+
* under vitest's default node/jsdom setup) — same split used by
|
|
6
|
+
* status-bar-lang.ts for StatusBar.tsx.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Decide whether a completed background format result is still safe to
|
|
11
|
+
* apply. `snapshotContent` is the buffer content that was actually sent to
|
|
12
|
+
* Prettier; formatting runs asynchronously (dynamic plugin imports + async
|
|
13
|
+
* format), so by the time the result comes back the user may have already
|
|
14
|
+
* started editing the live model. Applying the formatted text in that case
|
|
15
|
+
* would silently discard their in-progress edits, so we bail unless the
|
|
16
|
+
* model's current value still matches the snapshot that was formatted.
|
|
17
|
+
*/
|
|
18
|
+
export function shouldApplyFormatResult(
|
|
19
|
+
currentModelValue: string,
|
|
20
|
+
snapshotContent: string,
|
|
21
|
+
formatted: string,
|
|
22
|
+
): boolean {
|
|
23
|
+
if (formatted === snapshotContent) return false;
|
|
24
|
+
return currentModelValue === snapshotContent;
|
|
25
|
+
}
|
package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open.ts
CHANGED
|
@@ -3,8 +3,11 @@ import { useEffect } from "react";
|
|
|
3
3
|
import { modelRegistry } from "../model-registry";
|
|
4
4
|
import { useWorkbench, type BufferLoadedEvent } from "../store";
|
|
5
5
|
import { providerKindFromKey } from "../workspace/types";
|
|
6
|
+
import { shouldApplyFormatResult } from "./format-on-open-guard";
|
|
6
7
|
import { formatWithPrettier, isFormattablePath } from "./prettier-format";
|
|
7
8
|
|
|
9
|
+
export { shouldApplyFormatResult } from "./format-on-open-guard";
|
|
10
|
+
|
|
8
11
|
/**
|
|
9
12
|
* Auto-format-on-first-open policy: the design's SQL-backed (inline) files
|
|
10
13
|
* are machine-generated, so the first time a formattable inline buffer is
|
|
@@ -42,10 +45,25 @@ export function useFormatOnFirstOpen({ enabled }: { enabled: boolean }): void {
|
|
|
42
45
|
void (async () => {
|
|
43
46
|
const result = await formatWithPrettier(event.read.content, event.path);
|
|
44
47
|
if ("error" in result) return;
|
|
45
|
-
if (result.formatted === event.read.content) return;
|
|
46
48
|
|
|
47
49
|
const entry = modelRegistry.get(event.uri);
|
|
48
50
|
if (!entry || entry.model.isDisposed()) return;
|
|
51
|
+
// Formatting is async (dynamic plugin imports + Prettier itself), so
|
|
52
|
+
// the user may have started typing in the buffer while we were
|
|
53
|
+
// awaiting the result. Applying `result.formatted` — derived from the
|
|
54
|
+
// pre-format snapshot — over the model unconditionally would silently
|
|
55
|
+
// clobber those in-progress edits. Bail out if the live model no
|
|
56
|
+
// longer matches the snapshot that was formatted; a later save or
|
|
57
|
+
// manual format can pick it up.
|
|
58
|
+
if (
|
|
59
|
+
!shouldApplyFormatResult(
|
|
60
|
+
entry.model.getValue(),
|
|
61
|
+
event.read.content,
|
|
62
|
+
result.formatted,
|
|
63
|
+
)
|
|
64
|
+
) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
49
67
|
// Push the formatted text without touching savedAltVersionId, so the
|
|
50
68
|
// buffer becomes dirty (matches the "formatted but unsaved" state a
|
|
51
69
|
// real edit would produce) — then save silently.
|
|
@@ -31,6 +31,16 @@ function monacoUriFor(uri: string): monaco.Uri {
|
|
|
31
31
|
|
|
32
32
|
class WorkbenchModelRegistry {
|
|
33
33
|
private entries = new Map<string, WorkbenchModelEntry>();
|
|
34
|
+
/**
|
|
35
|
+
* Uris currently inside an `applyExternalContent`/`reloadContent` call.
|
|
36
|
+
* Monaco fires `onDidChangeContent` synchronously from inside
|
|
37
|
+
* `pushEditOperations`, before this class can update `savedAltVersionId` to
|
|
38
|
+
* the post-edit version — so a dirty-tracking subscriber reading
|
|
39
|
+
* `isDirty()` from that callback would see a stale "dirty" result for an
|
|
40
|
+
* edit nobody typed. Callers (store.tsx's dirty-tracking subscription) use
|
|
41
|
+
* `isApplyingExternalContent` to skip acting on that spurious notification.
|
|
42
|
+
*/
|
|
43
|
+
private externalContentUris = new Set<string>();
|
|
34
44
|
|
|
35
45
|
get(uri: string): WorkbenchModelEntry | undefined {
|
|
36
46
|
return this.entries.get(uri);
|
|
@@ -75,6 +85,15 @@ class WorkbenchModelRegistry {
|
|
|
75
85
|
return entry.model.getAlternativeVersionId() !== entry.savedAltVersionId;
|
|
76
86
|
}
|
|
77
87
|
|
|
88
|
+
/**
|
|
89
|
+
* True while `uri`'s content is being replaced by `applyExternalContent`.
|
|
90
|
+
* Dirty-tracking subscribers must ignore `onDidChangeContent` notifications
|
|
91
|
+
* that fire while this is true — see the field comment above.
|
|
92
|
+
*/
|
|
93
|
+
isApplyingExternalContent(uri: string): boolean {
|
|
94
|
+
return this.externalContentUris.has(uri);
|
|
95
|
+
}
|
|
96
|
+
|
|
78
97
|
/**
|
|
79
98
|
* Replace buffer content from an external change (agent edit, canvas edit)
|
|
80
99
|
* while preserving the undo stack.
|
|
@@ -87,14 +106,33 @@ class WorkbenchModelRegistry {
|
|
|
87
106
|
entry.savedAltVersionId = model.getAlternativeVersionId();
|
|
88
107
|
return;
|
|
89
108
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
109
|
+
this.externalContentUris.add(uri);
|
|
110
|
+
try {
|
|
111
|
+
model.pushEditOperations(
|
|
112
|
+
null,
|
|
113
|
+
[{ range: model.getFullModelRange(), text: content }],
|
|
114
|
+
() => null,
|
|
115
|
+
);
|
|
116
|
+
} finally {
|
|
117
|
+
this.externalContentUris.delete(uri);
|
|
118
|
+
}
|
|
95
119
|
entry.savedAltVersionId = model.getAlternativeVersionId();
|
|
96
120
|
}
|
|
97
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Force an already-open buffer to match freshly read content + language,
|
|
124
|
+
* discarding any local edits. Used only for explicit user-initiated reload
|
|
125
|
+
* (e.g. the "File changed elsewhere — reload latest" conflict action) —
|
|
126
|
+
* the caller has already decided to discard unsaved edits, so unlike
|
|
127
|
+
* `applyExternalContent`'s callers this does not gate on dirty state.
|
|
128
|
+
*/
|
|
129
|
+
reloadContent(uri: string, content: string, language: string) {
|
|
130
|
+
const entry = this.entries.get(uri);
|
|
131
|
+
if (!entry || entry.model.isDisposed()) return;
|
|
132
|
+
monaco.editor.setModelLanguage(entry.model, language);
|
|
133
|
+
this.applyExternalContent(uri, content);
|
|
134
|
+
}
|
|
135
|
+
|
|
98
136
|
/** Mark the buffer clean as of the given alternative version id. */
|
|
99
137
|
markSaved(uri: string, altVersionId: number) {
|
|
100
138
|
const entry = this.entries.get(uri);
|
|
@@ -79,6 +79,21 @@ export function SearchView({ searchSeed }: SearchViewProps) {
|
|
|
79
79
|
const [replaceAllFailures, setReplaceAllFailures] = useState(0);
|
|
80
80
|
const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
81
81
|
const abortRef = useRef<AbortController | null>(null);
|
|
82
|
+
// `providers` is recreated with a new array/object identity on every
|
|
83
|
+
// unrelated design poll tick (it flows through the design's SWR-polled
|
|
84
|
+
// `files` query, which has no structural-sharing guard), even when the
|
|
85
|
+
// actual set of workspace sources hasn't changed. Depending on `providers`
|
|
86
|
+
// directly would re-run the search effect on every poll tick, silently
|
|
87
|
+
// resetting `dismissed` (bringing back results the user just dismissed)
|
|
88
|
+
// and `replaceAllFailures`. Keep the latest providers in a ref for the
|
|
89
|
+
// debounced search to read, and key the effect off a stable signature of
|
|
90
|
+
// provider identities instead so it only re-runs when the source set
|
|
91
|
+
// actually changes.
|
|
92
|
+
const providersRef = useRef(providers);
|
|
93
|
+
providersRef.current = providers;
|
|
94
|
+
const providersSignature = providers
|
|
95
|
+
.map((provider) => provider.key)
|
|
96
|
+
.join(",");
|
|
82
97
|
|
|
83
98
|
useEffect(() => {
|
|
84
99
|
if (searchSeed.token === 0) return;
|
|
@@ -102,7 +117,7 @@ export function SearchView({ searchSeed }: SearchViewProps) {
|
|
|
102
117
|
setDismissed({ files: new Set(), matches: new Set() });
|
|
103
118
|
setReplaceAllFailures(0);
|
|
104
119
|
searchWorkspace({
|
|
105
|
-
providers,
|
|
120
|
+
providers: providersRef.current,
|
|
106
121
|
query,
|
|
107
122
|
matchCase,
|
|
108
123
|
wholeWord,
|
|
@@ -121,7 +136,17 @@ export function SearchView({ searchSeed }: SearchViewProps) {
|
|
|
121
136
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
122
137
|
};
|
|
123
138
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
124
|
-
}, [query, matchCase, wholeWord, regex,
|
|
139
|
+
}, [query, matchCase, wholeWord, regex, providersSignature]);
|
|
140
|
+
|
|
141
|
+
// Safety net: abort any in-flight search when the view unmounts (it
|
|
142
|
+
// normally stays mounted-but-hidden per SideBar, but can genuinely unmount
|
|
143
|
+
// when the workbench itself closes) so a late `setResults` never fires
|
|
144
|
+
// against a torn-down component.
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
return () => {
|
|
147
|
+
abortRef.current?.abort();
|
|
148
|
+
};
|
|
149
|
+
}, []);
|
|
125
150
|
|
|
126
151
|
const visibleFiles = useMemo<FileSearchResult[]>(() => {
|
|
127
152
|
if (!results) return [];
|
package/corpus/templates/design/app/components/design/code-workbench/search/search-engine.ts
CHANGED
|
@@ -268,7 +268,16 @@ export function replaceMatchesInText(
|
|
|
268
268
|
count += 1;
|
|
269
269
|
if (options.regex) {
|
|
270
270
|
// Support $1, $2, ... backreferences the way String.replace does.
|
|
271
|
-
|
|
271
|
+
// The callback args are (match, ...captureGroups, offset, string[,
|
|
272
|
+
// namedGroups]) — `namedGroups` is only appended when the pattern has
|
|
273
|
+
// named capture groups, so it must be dropped before slicing off the
|
|
274
|
+
// trailing offset/string pair, or a `$N` beyond the real group count
|
|
275
|
+
// would silently resolve to the match offset instead of "".
|
|
276
|
+
let rest = matchArgs.slice(1);
|
|
277
|
+
if (typeof rest[rest.length - 1] === "object") {
|
|
278
|
+
rest = rest.slice(0, -1);
|
|
279
|
+
}
|
|
280
|
+
const groups = rest.slice(0, -2);
|
|
272
281
|
return replacement.replace(/\$(\d+)/g, (_all, index) => {
|
|
273
282
|
const groupIndex = Number(index) - 1;
|
|
274
283
|
return typeof groups[groupIndex] === "string" ? groups[groupIndex] : "";
|
|
@@ -341,6 +341,12 @@ export function WorkbenchProvider({
|
|
|
341
341
|
if (dirtySubscribedModelsRef.current.has(entry.model)) return;
|
|
342
342
|
dirtySubscribedModelsRef.current.add(entry.model);
|
|
343
343
|
entry.model.onDidChangeContent(() => {
|
|
344
|
+
// Programmatic content replacement (agent edit, external reload) fires
|
|
345
|
+
// this synchronously before the model registry updates its saved
|
|
346
|
+
// version marker; treating that as a real edit would incorrectly mark
|
|
347
|
+
// the buffer dirty (and pin a preview tab) for a change the user never
|
|
348
|
+
// made. See modelRegistry.isApplyingExternalContent.
|
|
349
|
+
if (modelRegistry.isApplyingExternalContent(uri)) return;
|
|
344
350
|
apiRef.current?.markDirty(uri, modelRegistry.isDirty(uri));
|
|
345
351
|
});
|
|
346
352
|
}, []);
|
|
@@ -369,7 +375,18 @@ export function WorkbenchProvider({
|
|
|
369
375
|
try {
|
|
370
376
|
const read = await provider.readFile(path);
|
|
371
377
|
const language = read.language ?? languageForPath(path);
|
|
372
|
-
|
|
378
|
+
// loadBuffer is also used by reloadBuffer to force an already-open
|
|
379
|
+
// buffer back to the latest server content (e.g. the "File changed
|
|
380
|
+
// elsewhere — reload latest" conflict action). `ensureModel` is
|
|
381
|
+
// intentionally a no-op on content when a model already exists (so
|
|
382
|
+
// the initial-open path here never clobbers a buffer someone is
|
|
383
|
+
// mid-edit on) — reloadContent is the explicit, caller-opted-in
|
|
384
|
+
// discard-local-edits path for that case.
|
|
385
|
+
if (modelRegistry.has(uri)) {
|
|
386
|
+
modelRegistry.reloadContent(uri, read.content, language);
|
|
387
|
+
} else {
|
|
388
|
+
modelRegistry.ensureModel(uri, read.content, language);
|
|
389
|
+
}
|
|
373
390
|
subscribeDirtyTracking(uri);
|
|
374
391
|
rememberVersionHash(uri, read.versionHash);
|
|
375
392
|
const firstLoad = !loadedOnceRef.current.has(uri);
|
|
@@ -382,7 +399,7 @@ export function WorkbenchProvider({
|
|
|
382
399
|
dirty: modelRegistry.isDirty(uri),
|
|
383
400
|
conflict: false,
|
|
384
401
|
saving: false,
|
|
385
|
-
readonly: read.readonly ?? false,
|
|
402
|
+
readonly: read.readonly ?? existingMeta?.readonly ?? false,
|
|
386
403
|
language,
|
|
387
404
|
fileId: read.fileId,
|
|
388
405
|
savedVersionHash: read.versionHash,
|