@agent-native/core 0.92.10 → 0.92.12
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 +214 -17
- package/corpus/core/src/agent/run-manager.ts +72 -14
- package/corpus/core/src/agent/run-store.ts +152 -27
- 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-adapter.ts +56 -12
- 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/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 +75 -9
- package/corpus/templates/clips/app/components/player/video-player.tsx +17 -12
- package/corpus/templates/clips/app/hooks/use-player-shortcuts.ts +1 -0
- 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/changelog/2026-07-10-fixed-copying-agent-responses-and-transcript-text-from-recor.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/_builder-cms-read-client.ts +82 -7
- package/corpus/templates/content/actions/_database-source-utils.ts +149 -30
- 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/add-content-database-source-field-property.ts +4 -7
- package/corpus/templates/content/actions/attach-content-database-source.ts +41 -17
- package/corpus/templates/content/actions/change-content-database-source-role.ts +46 -8
- 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/actions/suggest-source-join-key.ts +8 -1
- 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-builder-source-refreshes-now-keep-mapped-fields-such-as-topi.md +6 -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/content/shared/api.ts +1 -0
- 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 +82 -7
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +180 -17
- 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 +63 -14
- 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 +129 -22
- 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-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +48 -12
- package/dist/client/agent-chat-adapter.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/struct-routes.d.ts +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/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +3 -3
- 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
|
@@ -631,6 +631,20 @@ replace them with copied \`srcdoc\` HTML unless the user explicitly asks for a
|
|
|
631
631
|
frozen snapshot. To change a state, rerun \`add-localhost-screens\` with the new
|
|
632
632
|
path/query or duplicate the screen and update the copy's URL metadata.
|
|
633
633
|
|
|
634
|
+
## React Source Writeback
|
|
635
|
+
|
|
636
|
+
- Use compiler/debug provenance (project-relative file, line, column,
|
|
637
|
+
component, and runtime multiplicity) to locate React/TSX source. Treat it as
|
|
638
|
+
evidence, not as permission for a generic AST structural transform.
|
|
639
|
+
- Reparenting, grouping/ungrouping, wrappers, dynamic expressions, repeated
|
|
640
|
+
\`.map()\` instances, shared components, and cross-file changes go through the
|
|
641
|
+
coding agent with exact subject/target anchors and their runtime
|
|
642
|
+
relationship.
|
|
643
|
+
- Before each write, read the file and pass its exact \`versionHash\` to
|
|
644
|
+
\`write-local-file\` with \`requireExpectedVersionHash: true\`; on conflict,
|
|
645
|
+
re-read and re-plan. Keep the optimistic preview until HMR/runtime confirms
|
|
646
|
+
the result. Human write consent remains mandatory and agents cannot grant it.
|
|
647
|
+
|
|
634
648
|
## Verification
|
|
635
649
|
|
|
636
650
|
- \`list-localhost-connections\` returns the expected connection and routes.
|
|
@@ -55,9 +55,11 @@ import {
|
|
|
55
55
|
appendAgentChatContextToMessage,
|
|
56
56
|
formatAgentChatContextItemsForPrompt,
|
|
57
57
|
getAgentChatContextState,
|
|
58
|
+
isAgentChatSubmitCancelled,
|
|
58
59
|
normalizeAgentChatContextItem,
|
|
59
60
|
publishAgentChatContextItems,
|
|
60
61
|
refreshAgentChatContext,
|
|
62
|
+
reportAgentChatSubmitResult,
|
|
61
63
|
subscribeAgentChatContext,
|
|
62
64
|
type AgentChatContextItem,
|
|
63
65
|
} from "./agent-chat.js";
|
|
@@ -197,6 +199,8 @@ export type AgentRecoveryAction = "continue" | "retry";
|
|
|
197
199
|
export interface AssistantChatSendOptions {
|
|
198
200
|
trackInRunsTray?: boolean;
|
|
199
201
|
requestMode?: AgentRequestMode;
|
|
202
|
+
/** Correlates with `AGENT_CHAT_SUBMIT_RESULT_EVENT` — see agent-chat.ts. */
|
|
203
|
+
submitMessageId?: string;
|
|
200
204
|
}
|
|
201
205
|
|
|
202
206
|
function createUserMessageRunConfig(
|
|
@@ -3651,9 +3655,12 @@ const AssistantChatInner = forwardRef<
|
|
|
3651
3655
|
trackInRunsTray = false,
|
|
3652
3656
|
preserveReconnectAutoRecoveryBudget = false,
|
|
3653
3657
|
hideUserMessage = false,
|
|
3658
|
+
submitMessageId?: string,
|
|
3654
3659
|
) => {
|
|
3660
|
+
if (isAgentChatSubmitCancelled(submitMessageId)) return;
|
|
3655
3661
|
if (agentEngineConfigured.state === "missing") {
|
|
3656
3662
|
void ensureAgentEngineReadyForSubmit();
|
|
3663
|
+
reportAgentChatSubmitResult(submitMessageId, false, "missing-engine");
|
|
3657
3664
|
return;
|
|
3658
3665
|
}
|
|
3659
3666
|
if (!preserveReconnectAutoRecoveryBudget) {
|
|
@@ -3687,8 +3694,10 @@ const AssistantChatInner = forwardRef<
|
|
|
3687
3694
|
? err.message
|
|
3688
3695
|
: "Attachment could not be processed.";
|
|
3689
3696
|
setComposerError(msg);
|
|
3697
|
+
reportAgentChatSubmitResult(submitMessageId, false, "attachment-error");
|
|
3690
3698
|
return;
|
|
3691
3699
|
}
|
|
3700
|
+
if (isAgentChatSubmitCancelled(submitMessageId)) return;
|
|
3692
3701
|
const imageAttachments = createAgentImageAttachments(images);
|
|
3693
3702
|
const allAttachments = [
|
|
3694
3703
|
...(queuedAttachments ?? []),
|
|
@@ -3782,6 +3791,11 @@ const AssistantChatInner = forwardRef<
|
|
|
3782
3791
|
setComposerError(
|
|
3783
3792
|
`"${rejected.name}" makes the message too large to send (combined attachments must be under ${Math.round(MAX_ESTIMATED_BODY_BYTES / 1024 / 1024)} MB). Remove it or use a smaller image.`,
|
|
3784
3793
|
);
|
|
3794
|
+
reportAgentChatSubmitResult(
|
|
3795
|
+
submitMessageId,
|
|
3796
|
+
false,
|
|
3797
|
+
"attachment-too-large",
|
|
3798
|
+
);
|
|
3785
3799
|
return;
|
|
3786
3800
|
}
|
|
3787
3801
|
}
|
|
@@ -3789,6 +3803,7 @@ const AssistantChatInner = forwardRef<
|
|
|
3789
3803
|
}
|
|
3790
3804
|
}
|
|
3791
3805
|
// ── End body-size guard ──────────────────────────────────────────
|
|
3806
|
+
if (isAgentChatSubmitCancelled(submitMessageId)) return;
|
|
3792
3807
|
// Snapshot the exec mode at enqueue time when the caller didn't
|
|
3793
3808
|
// pass an explicit override. Without this, a plan-mode message that
|
|
3794
3809
|
// sits in the queue runs as 'act' if the user flips the global toggle
|
|
@@ -3863,9 +3878,16 @@ const AssistantChatInner = forwardRef<
|
|
|
3863
3878
|
} as Parameters<typeof threadRuntime.append>[0]);
|
|
3864
3879
|
} catch (error) {
|
|
3865
3880
|
setOptimisticRunning(false);
|
|
3881
|
+
reportAgentChatSubmitResult(submitMessageId, false, "append-failed");
|
|
3866
3882
|
throw error;
|
|
3867
3883
|
}
|
|
3868
3884
|
}
|
|
3885
|
+
// The turn is now either queued behind the active run or already a
|
|
3886
|
+
// visible message — either way it has reached the chat. This is
|
|
3887
|
+
// intentionally reported before the agent's response resolves: a
|
|
3888
|
+
// caller like sendToAgentChatAndConfirm only needs to know the submit
|
|
3889
|
+
// wasn't silently dropped, not whether the run itself later succeeds.
|
|
3890
|
+
reportAgentChatSubmitResult(submitMessageId, true);
|
|
3869
3891
|
if (submitted.includesContext) {
|
|
3870
3892
|
updateComposerContextItems(() => []);
|
|
3871
3893
|
}
|
|
@@ -3927,6 +3949,9 @@ const AssistantChatInner = forwardRef<
|
|
|
3927
3949
|
undefined,
|
|
3928
3950
|
false,
|
|
3929
3951
|
options?.trackInRunsTray === true,
|
|
3952
|
+
false,
|
|
3953
|
+
false,
|
|
3954
|
+
options?.submitMessageId,
|
|
3930
3955
|
);
|
|
3931
3956
|
},
|
|
3932
3957
|
prefillMessage(text: string) {
|
|
@@ -30,8 +30,10 @@ import {
|
|
|
30
30
|
claimAgentChatSubmit,
|
|
31
31
|
drainBufferedAgentChatOpenRequests,
|
|
32
32
|
drainBufferedAgentChatSubmits,
|
|
33
|
+
isAgentChatSubmitCancelled,
|
|
33
34
|
normalizeAgentChatContextItem,
|
|
34
35
|
parseSubmitChatMessage,
|
|
36
|
+
reportAgentChatSubmitResult,
|
|
35
37
|
type AgentChatContextItem,
|
|
36
38
|
} from "./agent-chat.js";
|
|
37
39
|
import { agentNativePath, appPath } from "./api-path.js";
|
|
@@ -79,6 +81,8 @@ interface PendingSend {
|
|
|
79
81
|
submit: boolean;
|
|
80
82
|
trackInRunsTray?: boolean;
|
|
81
83
|
requestMode?: "act" | "plan";
|
|
84
|
+
/** Correlates with `AGENT_CHAT_SUBMIT_RESULT_EVENT` — see agent-chat.ts. */
|
|
85
|
+
submitMessageId?: string;
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
/**
|
|
@@ -93,14 +97,18 @@ interface PendingDelivery {
|
|
|
93
97
|
|
|
94
98
|
/** The single path that hands a queued send to a mounted chat ref. */
|
|
95
99
|
function deliverPendingSend(ref: AssistantChatHandle, send: PendingSend): void {
|
|
100
|
+
if (isAgentChatSubmitCancelled(send.submitMessageId)) return;
|
|
96
101
|
if (!send.submit) {
|
|
97
102
|
ref.prefillMessage(send.message);
|
|
98
103
|
return;
|
|
99
104
|
}
|
|
100
|
-
if (send.trackInRunsTray || send.requestMode) {
|
|
105
|
+
if (send.trackInRunsTray || send.requestMode || send.submitMessageId) {
|
|
101
106
|
ref.sendMessage(send.message, send.images, {
|
|
102
107
|
...(send.trackInRunsTray ? { trackInRunsTray: true } : {}),
|
|
103
108
|
...(send.requestMode ? { requestMode: send.requestMode } : {}),
|
|
109
|
+
...(send.submitMessageId
|
|
110
|
+
? { submitMessageId: send.submitMessageId }
|
|
111
|
+
: {}),
|
|
104
112
|
});
|
|
105
113
|
} else {
|
|
106
114
|
ref.sendMessage(send.message, send.images);
|
|
@@ -1767,6 +1775,7 @@ export function MultiTabAssistantChat({
|
|
|
1767
1775
|
background,
|
|
1768
1776
|
submit,
|
|
1769
1777
|
images,
|
|
1778
|
+
submitMessageId,
|
|
1770
1779
|
} = parsed;
|
|
1771
1780
|
const requestedTabId = parsed.tabId;
|
|
1772
1781
|
const requestMode =
|
|
@@ -1777,7 +1786,14 @@ export function MultiTabAssistantChat({
|
|
|
1777
1786
|
if (openSidebar !== false && !background) {
|
|
1778
1787
|
window.dispatchEvent(new CustomEvent("agent-panel:open"));
|
|
1779
1788
|
}
|
|
1780
|
-
if (postMessageSubmissionsDisabled)
|
|
1789
|
+
if (postMessageSubmissionsDisabled) {
|
|
1790
|
+
reportAgentChatSubmitResult(
|
|
1791
|
+
submitMessageId,
|
|
1792
|
+
false,
|
|
1793
|
+
"composer-disabled",
|
|
1794
|
+
);
|
|
1795
|
+
return;
|
|
1796
|
+
}
|
|
1781
1797
|
|
|
1782
1798
|
// Plan mode is sent as request metadata by the chat adapter. Keep the
|
|
1783
1799
|
// user-visible message clean so mode instructions never enter history.
|
|
@@ -1791,9 +1807,11 @@ export function MultiTabAssistantChat({
|
|
|
1791
1807
|
submit,
|
|
1792
1808
|
...(background ? { trackInRunsTray: true } : {}),
|
|
1793
1809
|
...(requestMode ? { requestMode } : {}),
|
|
1810
|
+
...(submitMessageId ? { submitMessageId } : {}),
|
|
1794
1811
|
};
|
|
1795
1812
|
|
|
1796
1813
|
const sendToTab = (threadId: string) => {
|
|
1814
|
+
if (isAgentChatSubmitCancelled(submitMessageId)) return;
|
|
1797
1815
|
// If a model override was specified, apply it only if we recognize it
|
|
1798
1816
|
if (model) {
|
|
1799
1817
|
const matchedGroup = availableModels.find((g) =>
|
|
@@ -1826,8 +1844,17 @@ export function MultiTabAssistantChat({
|
|
|
1826
1844
|
|
|
1827
1845
|
if (newTab) {
|
|
1828
1846
|
const previousTabId = activeThreadIdRef.current;
|
|
1829
|
-
createThread(requestedTabId)
|
|
1830
|
-
|
|
1847
|
+
createThread(requestedTabId)
|
|
1848
|
+
.then((newId) => {
|
|
1849
|
+
if (isAgentChatSubmitCancelled(submitMessageId)) return;
|
|
1850
|
+
if (!newId) {
|
|
1851
|
+
reportAgentChatSubmitResult(
|
|
1852
|
+
submitMessageId,
|
|
1853
|
+
false,
|
|
1854
|
+
"thread-create-failed",
|
|
1855
|
+
);
|
|
1856
|
+
return;
|
|
1857
|
+
}
|
|
1831
1858
|
newThreadIds.current.add(newId);
|
|
1832
1859
|
if (background) {
|
|
1833
1860
|
mountedTabsRef.current.add(newId);
|
|
@@ -1842,8 +1869,14 @@ export function MultiTabAssistantChat({
|
|
|
1842
1869
|
if (background && previousTabId) {
|
|
1843
1870
|
switchThreadState(previousTabId);
|
|
1844
1871
|
}
|
|
1845
|
-
}
|
|
1846
|
-
|
|
1872
|
+
})
|
|
1873
|
+
.catch(() => {
|
|
1874
|
+
reportAgentChatSubmitResult(
|
|
1875
|
+
submitMessageId,
|
|
1876
|
+
false,
|
|
1877
|
+
"thread-create-failed",
|
|
1878
|
+
);
|
|
1879
|
+
});
|
|
1847
1880
|
} else {
|
|
1848
1881
|
const currentTabId = activeThreadIdRef.current;
|
|
1849
1882
|
if (currentTabId) {
|
|
@@ -1901,6 +1934,7 @@ export function MultiTabAssistantChat({
|
|
|
1901
1934
|
const active = activeThreadIdRef.current;
|
|
1902
1935
|
const remaining: PendingDelivery[] = [];
|
|
1903
1936
|
for (const delivery of pendingDeliveries.current) {
|
|
1937
|
+
if (isAgentChatSubmitCancelled(delivery.send.submitMessageId)) continue;
|
|
1904
1938
|
const threadId = delivery.threadId ?? active ?? null;
|
|
1905
1939
|
const ref = threadId ? chatRefs.current.get(threadId) : null;
|
|
1906
1940
|
if (threadId && ref) {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { ChatModelAdapter, ChatModelRunResult } from "@assistant-ui/react";
|
|
2
2
|
|
|
3
3
|
import { actionPreparationContinuationNote } from "../agent/action-continuation-guidance.js";
|
|
4
|
+
import {
|
|
5
|
+
LLM_MISSING_CREDENTIALS_ERROR_CODE,
|
|
6
|
+
LLM_MISSING_CREDENTIALS_MESSAGE,
|
|
7
|
+
} from "../agent/engine/credential-errors.js";
|
|
4
8
|
import type {
|
|
5
9
|
AgentChatStructuredContentPart,
|
|
6
10
|
AgentChatStructuredMessage,
|
|
@@ -157,7 +161,9 @@ const BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS = 150_000;
|
|
|
157
161
|
* (`agent_runs.terminal_reason`, surfaced by /runs/active). These runs died in
|
|
158
162
|
* server-side handoff machinery where no richer error event may exist, so the
|
|
159
163
|
* client owns the message. Keys are matched after stripping an optional
|
|
160
|
-
* `error:` prefix (`terminalReasonForEvent` records `error:<code>`).
|
|
164
|
+
* `error:` prefix (`terminalReasonForEvent` records `error:<code>`). Keep this
|
|
165
|
+
* map scoped to terminal failures, including reasons that must override a
|
|
166
|
+
* mistakenly completed row.
|
|
161
167
|
*/
|
|
162
168
|
const BACKGROUND_TERMINAL_REASON_MESSAGES: Record<string, string> = {
|
|
163
169
|
background_worker_never_started:
|
|
@@ -166,6 +172,8 @@ const BACKGROUND_TERMINAL_REASON_MESSAGES: Record<string, string> = {
|
|
|
166
172
|
"The agent's background worker could not hand off the next step of this run. Retry to continue from the preserved context.",
|
|
167
173
|
dispatch_payload_missing:
|
|
168
174
|
"The agent's background run lost its saved request data and could not continue. Retry to start a fresh run.",
|
|
175
|
+
missing_api_key: LLM_MISSING_CREDENTIALS_MESSAGE,
|
|
176
|
+
missing_credentials: LLM_MISSING_CREDENTIALS_MESSAGE,
|
|
169
177
|
turn_continuation_budget_exhausted:
|
|
170
178
|
"This request needed more automatic continuations than allowed and was stopped. Try breaking it into smaller steps.",
|
|
171
179
|
};
|
|
@@ -1761,6 +1769,11 @@ export function createAgentChatAdapter(
|
|
|
1761
1769
|
nextRunId: string,
|
|
1762
1770
|
previousRunId: string | null,
|
|
1763
1771
|
) => {
|
|
1772
|
+
if (previousRunId !== nextRunId) {
|
|
1773
|
+
lastAutoContinueReason = null;
|
|
1774
|
+
lastRecoverableRunError = null;
|
|
1775
|
+
lastActivityTrail = [];
|
|
1776
|
+
}
|
|
1764
1777
|
const rememberedSeq = seenRunSeqs.get(nextRunId);
|
|
1765
1778
|
if (rememberedSeq !== undefined) {
|
|
1766
1779
|
lastSeq = rememberedSeq;
|
|
@@ -2132,6 +2145,9 @@ export function createAgentChatAdapter(
|
|
|
2132
2145
|
...(runId ? { runId } : {}),
|
|
2133
2146
|
};
|
|
2134
2147
|
if (typeof window !== "undefined") {
|
|
2148
|
+
if (args.errorCode === LLM_MISSING_CREDENTIALS_ERROR_CODE) {
|
|
2149
|
+
dispatchMissingApiKey();
|
|
2150
|
+
}
|
|
2135
2151
|
window.dispatchEvent(
|
|
2136
2152
|
new CustomEvent("agent-chat:run-error", {
|
|
2137
2153
|
detail: { ...runError, tabId },
|
|
@@ -2169,7 +2185,46 @@ export function createAgentChatAdapter(
|
|
|
2169
2185
|
: "";
|
|
2170
2186
|
// terminal_reason is either a bare reason ("dispatch_payload_missing")
|
|
2171
2187
|
// or "error:<errorCode>" when derived from a terminal error event.
|
|
2188
|
+
const hasErrorTerminalReason = rawTerminalReason.startsWith("error:");
|
|
2172
2189
|
const terminalReason = rawTerminalReason.replace(/^error:/, "");
|
|
2190
|
+
const mappedMessage = terminalReason
|
|
2191
|
+
? BACKGROUND_TERMINAL_REASON_MESSAGES[terminalReason]
|
|
2192
|
+
: undefined;
|
|
2193
|
+
const mappedErrorCode =
|
|
2194
|
+
terminalReason === "missing_api_key" ||
|
|
2195
|
+
terminalReason === LLM_MISSING_CREDENTIALS_ERROR_CODE
|
|
2196
|
+
? LLM_MISSING_CREDENTIALS_ERROR_CODE
|
|
2197
|
+
: terminalReason;
|
|
2198
|
+
|
|
2199
|
+
if (mappedMessage) {
|
|
2200
|
+
yield* emitBackgroundTerminalError({
|
|
2201
|
+
message: mappedMessage,
|
|
2202
|
+
errorCode: mappedErrorCode,
|
|
2203
|
+
details: `terminal_reason: ${rawTerminalReason}`,
|
|
2204
|
+
});
|
|
2205
|
+
return;
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
if (hasErrorTerminalReason) {
|
|
2209
|
+
if (lastRecoverableRunError) {
|
|
2210
|
+
yield* emitBackgroundTerminalError({
|
|
2211
|
+
message: lastRecoverableRunError.message,
|
|
2212
|
+
errorCode:
|
|
2213
|
+
lastRecoverableRunError.errorCode ||
|
|
2214
|
+
mappedErrorCode ||
|
|
2215
|
+
"background_run_failed",
|
|
2216
|
+
details: lastRecoverableRunError.details,
|
|
2217
|
+
});
|
|
2218
|
+
return;
|
|
2219
|
+
}
|
|
2220
|
+
yield* emitBackgroundTerminalError({
|
|
2221
|
+
message:
|
|
2222
|
+
"The agent's background run failed before its final response could be recovered. You can retry from the preserved chat context.",
|
|
2223
|
+
errorCode: mappedErrorCode || "background_run_failed",
|
|
2224
|
+
details: `terminal_reason: ${rawTerminalReason}`,
|
|
2225
|
+
});
|
|
2226
|
+
return;
|
|
2227
|
+
}
|
|
2173
2228
|
|
|
2174
2229
|
if (status === "completed") {
|
|
2175
2230
|
// The turn finished server-side; the events we managed to fold are
|
|
@@ -2186,17 +2241,6 @@ export function createAgentChatAdapter(
|
|
|
2186
2241
|
return;
|
|
2187
2242
|
}
|
|
2188
2243
|
|
|
2189
|
-
const mappedMessage = terminalReason
|
|
2190
|
-
? BACKGROUND_TERMINAL_REASON_MESSAGES[terminalReason]
|
|
2191
|
-
: undefined;
|
|
2192
|
-
if (mappedMessage) {
|
|
2193
|
-
yield* emitBackgroundTerminalError({
|
|
2194
|
-
message: mappedMessage,
|
|
2195
|
-
errorCode: terminalReason,
|
|
2196
|
-
details: `terminal_reason: ${rawTerminalReason}`,
|
|
2197
|
-
});
|
|
2198
|
-
return;
|
|
2199
|
-
}
|
|
2200
2244
|
if (lastRecoverableRunError) {
|
|
2201
2245
|
// A replayed terminal error event already carried the real
|
|
2202
2246
|
// message (recoverable errors replay as auto-continue signals
|
|
@@ -96,6 +96,11 @@ export interface AgentChatMessage {
|
|
|
96
96
|
* focusing it or opening the sidebar. The message runs silently.
|
|
97
97
|
*/
|
|
98
98
|
background?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Stable id used to deduplicate a submit and correlate it with
|
|
101
|
+
* {@link AGENT_CHAT_SUBMIT_RESULT_EVENT}. Auto-generated if omitted.
|
|
102
|
+
*/
|
|
103
|
+
submitMessageId?: string;
|
|
99
104
|
}
|
|
100
105
|
|
|
101
106
|
export interface AgentChatContextItem {
|
|
@@ -210,6 +215,45 @@ export const AGENT_CHAT_INSERT_REFERENCE_EVENT =
|
|
|
210
215
|
"agentNative:insert-composer-reference";
|
|
211
216
|
const AGENT_PANEL_PREPARE_EVENT = "agent-panel:prepare";
|
|
212
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Fired once a submitted turn's fate is known: `delivered: true` once the
|
|
220
|
+
* receiving AssistantChat has actually committed the turn (added it to the
|
|
221
|
+
* visible thread, independent of whether the agent's response later
|
|
222
|
+
* succeeds), or `delivered: false` when it was rejected before ever
|
|
223
|
+
* appearing — e.g. no LLM/agent engine configured. Callers that must know
|
|
224
|
+
* whether their submit truly landed (rather than fire-and-forget) should use
|
|
225
|
+
* {@link sendToAgentChatAndConfirm} instead of listening for this directly.
|
|
226
|
+
*/
|
|
227
|
+
export const AGENT_CHAT_SUBMIT_RESULT_EVENT = "agentNative.chatSubmitResult";
|
|
228
|
+
|
|
229
|
+
export interface AgentChatSubmitResult {
|
|
230
|
+
submitMessageId: string;
|
|
231
|
+
delivered: boolean;
|
|
232
|
+
reason?: string;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** Report a submit's definitive outcome so `sendToAgentChatAndConfirm` (or any
|
|
236
|
+
* other correlated listener) can resolve. No-ops without a submitMessageId or
|
|
237
|
+
* a window (SSR). */
|
|
238
|
+
export function reportAgentChatSubmitResult(
|
|
239
|
+
submitMessageId: string | undefined,
|
|
240
|
+
delivered: boolean,
|
|
241
|
+
reason?: string,
|
|
242
|
+
): void {
|
|
243
|
+
if (
|
|
244
|
+
!submitMessageId ||
|
|
245
|
+
cancelledSubmitIds.has(submitMessageId) ||
|
|
246
|
+
typeof window === "undefined"
|
|
247
|
+
) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
window.dispatchEvent(
|
|
251
|
+
new CustomEvent<AgentChatSubmitResult>(AGENT_CHAT_SUBMIT_RESULT_EVENT, {
|
|
252
|
+
detail: { submitMessageId, delivered, reason },
|
|
253
|
+
}),
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
213
257
|
let agentChatContextState: AgentChatContextState = {
|
|
214
258
|
items: [],
|
|
215
259
|
updatedAt: 0,
|
|
@@ -262,6 +306,7 @@ interface BufferedSelfSubmit {
|
|
|
262
306
|
const SELF_SUBMIT_BUFFER_TTL_MS = 8000;
|
|
263
307
|
const bufferedSelfSubmits: BufferedSelfSubmit[] = [];
|
|
264
308
|
const claimedSubmitIds = new Set<string>();
|
|
309
|
+
const cancelledSubmitIds = new Set<string>();
|
|
265
310
|
|
|
266
311
|
interface BufferedOpenRequest extends BufferedAgentChatOpenRequest {
|
|
267
312
|
at: number;
|
|
@@ -289,6 +334,28 @@ function bufferSelfSubmit(data: Record<string, unknown>): void {
|
|
|
289
334
|
bufferedSelfSubmits.push({ id, data, at: now });
|
|
290
335
|
}
|
|
291
336
|
|
|
337
|
+
/**
|
|
338
|
+
* Permanently tombstone a submit for this page lifetime and remove its
|
|
339
|
+
* cold-start replay. A confirmation timeout must be terminal: callers may
|
|
340
|
+
* retry while preserving their own state, so the original submit cannot be
|
|
341
|
+
* allowed to appear later when a lazy panel or thread ref finally mounts.
|
|
342
|
+
*/
|
|
343
|
+
export function cancelAgentChatSubmit(id: string | undefined): void {
|
|
344
|
+
if (!id) return;
|
|
345
|
+
cancelledSubmitIds.add(id);
|
|
346
|
+
claimedSubmitIds.add(id);
|
|
347
|
+
for (let index = bufferedSelfSubmits.length - 1; index >= 0; index -= 1) {
|
|
348
|
+
if (bufferedSelfSubmits[index]?.id === id) {
|
|
349
|
+
bufferedSelfSubmits.splice(index, 1);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/** Whether a confirmed-submit timeout has made this delivery terminal. */
|
|
355
|
+
export function isAgentChatSubmitCancelled(id: string | undefined): boolean {
|
|
356
|
+
return Boolean(id && cancelledSubmitIds.has(id));
|
|
357
|
+
}
|
|
358
|
+
|
|
292
359
|
function pruneOpenRequestBuffer(now: number): void {
|
|
293
360
|
for (let i = bufferedOpenRequests.length - 1; i >= 0; i -= 1) {
|
|
294
361
|
if (now - bufferedOpenRequests[i].at > OPEN_REQUEST_BUFFER_TTL_MS) {
|
|
@@ -328,6 +395,7 @@ export function drainBufferedAgentChatSubmits(): Array<
|
|
|
328
395
|
/** Claim a submit; false if already handled. Idless submits always pass. */
|
|
329
396
|
export function claimAgentChatSubmit(id: string | undefined): boolean {
|
|
330
397
|
if (!id) return true;
|
|
398
|
+
if (cancelledSubmitIds.has(id)) return false;
|
|
331
399
|
if (claimedSubmitIds.has(id)) return false;
|
|
332
400
|
claimedSubmitIds.add(id);
|
|
333
401
|
return true;
|
|
@@ -353,6 +421,7 @@ export function claimAgentChatOpenRequest(id: unknown): boolean {
|
|
|
353
421
|
export function _resetAgentChatSubmitBufferForTests(): void {
|
|
354
422
|
bufferedSelfSubmits.length = 0;
|
|
355
423
|
claimedSubmitIds.clear();
|
|
424
|
+
cancelledSubmitIds.clear();
|
|
356
425
|
bufferedOpenRequests.length = 0;
|
|
357
426
|
claimedOpenRequestIds.clear();
|
|
358
427
|
}
|
|
@@ -896,7 +965,7 @@ export function sendToAgentChat(opts: AgentChatMessage): string {
|
|
|
896
965
|
return tabId;
|
|
897
966
|
}
|
|
898
967
|
|
|
899
|
-
const submitMessageId = generateSubmitMessageId();
|
|
968
|
+
const submitMessageId = opts.submitMessageId ?? generateSubmitMessageId();
|
|
900
969
|
const payload = {
|
|
901
970
|
type: AGENT_CHAT_MESSAGE_TYPE,
|
|
902
971
|
data: {
|
|
@@ -977,6 +1046,101 @@ export function sendToAgentChat(opts: AgentChatMessage): string {
|
|
|
977
1046
|
return tabId;
|
|
978
1047
|
}
|
|
979
1048
|
|
|
1049
|
+
// Must exceed SELF_SUBMIT_BUFFER_TTL_MS. Otherwise confirmation can time out
|
|
1050
|
+
// while its replay is still eligible to mount and deliver later.
|
|
1051
|
+
const DEFAULT_SUBMIT_CONFIRM_TIMEOUT_MS = SELF_SUBMIT_BUFFER_TTL_MS + 2000;
|
|
1052
|
+
|
|
1053
|
+
export interface SendToAgentChatAndConfirmResult {
|
|
1054
|
+
tabId: string;
|
|
1055
|
+
/** True once the message actually became a visible turn in the chat. */
|
|
1056
|
+
delivered: boolean;
|
|
1057
|
+
/** Set when `delivered` is false: "missing-engine", "timeout", etc. */
|
|
1058
|
+
reason?: string;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
/**
|
|
1062
|
+
* Like {@link sendToAgentChat}, but resolves once the submit's fate is known
|
|
1063
|
+
* instead of firing and forgetting. Use this whenever the caller must decide
|
|
1064
|
+
* whether to keep/restore its own state on failure (e.g. a draw/annotate
|
|
1065
|
+
* overlay that should not discard the user's work unless the message actually
|
|
1066
|
+
* reached the chat) — see the `AGENT_CHAT_SUBMIT_RESULT_EVENT` contract.
|
|
1067
|
+
* This acknowledgement is intentionally limited to submitted, non-code
|
|
1068
|
+
* messages with `chatTarget: "local"`; parent-frame and MCP host chats use
|
|
1069
|
+
* different delivery protocols and return `unsupported-target` here.
|
|
1070
|
+
*
|
|
1071
|
+
* Resolves `delivered: false` if the receiving chat explicitly rejects the
|
|
1072
|
+
* submit (e.g. no LLM/agent engine configured) OR if no result arrives within
|
|
1073
|
+
* `timeoutMs` — a silently-stuck submit (panel never mounts, thread never
|
|
1074
|
+
* gets a ref, message type not handled by this build) must fail the same way
|
|
1075
|
+
* an explicit rejection does, since the caller cannot otherwise tell the
|
|
1076
|
+
* difference between "still in flight" and "dropped."
|
|
1077
|
+
*/
|
|
1078
|
+
export function sendToAgentChatAndConfirm(
|
|
1079
|
+
opts: Omit<AgentChatMessage, "submitMessageId">,
|
|
1080
|
+
options?: { timeoutMs?: number },
|
|
1081
|
+
): Promise<SendToAgentChatAndConfirmResult> {
|
|
1082
|
+
const tabId = opts.tabId ?? generateTabId();
|
|
1083
|
+
if (typeof window === "undefined") {
|
|
1084
|
+
return Promise.resolve({ tabId, delivered: false, reason: "no-window" });
|
|
1085
|
+
}
|
|
1086
|
+
// Confirmation is deliberately a same-window/local-chat contract. Parent
|
|
1087
|
+
// frames, Builder code chat, and MCP host relays have independent protocols
|
|
1088
|
+
// and cannot answer this window-local CustomEvent acknowledgement.
|
|
1089
|
+
if (
|
|
1090
|
+
opts.chatTarget !== "local" ||
|
|
1091
|
+
opts.type === "code" ||
|
|
1092
|
+
opts.requiresCode === true ||
|
|
1093
|
+
opts.submit === false
|
|
1094
|
+
) {
|
|
1095
|
+
return Promise.resolve({
|
|
1096
|
+
tabId,
|
|
1097
|
+
delivered: false,
|
|
1098
|
+
reason: "unsupported-target",
|
|
1099
|
+
});
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
const submitMessageId = generateSubmitMessageId();
|
|
1103
|
+
const timeoutMs = Math.max(
|
|
1104
|
+
0,
|
|
1105
|
+
options?.timeoutMs ?? DEFAULT_SUBMIT_CONFIRM_TIMEOUT_MS,
|
|
1106
|
+
);
|
|
1107
|
+
|
|
1108
|
+
return new Promise<SendToAgentChatAndConfirmResult>((resolve) => {
|
|
1109
|
+
let settled = false;
|
|
1110
|
+
let timer: number | undefined;
|
|
1111
|
+
const cleanup = () => {
|
|
1112
|
+
window.removeEventListener(
|
|
1113
|
+
AGENT_CHAT_SUBMIT_RESULT_EVENT,
|
|
1114
|
+
onResult as EventListener,
|
|
1115
|
+
);
|
|
1116
|
+
if (timer !== undefined) window.clearTimeout(timer);
|
|
1117
|
+
};
|
|
1118
|
+
const finish = (delivered: boolean, reason?: string, cancel = false) => {
|
|
1119
|
+
if (settled) return;
|
|
1120
|
+
settled = true;
|
|
1121
|
+
if (cancel) cancelAgentChatSubmit(submitMessageId);
|
|
1122
|
+
cleanup();
|
|
1123
|
+
resolve({ tabId, delivered, reason });
|
|
1124
|
+
};
|
|
1125
|
+
const onResult = (event: Event) => {
|
|
1126
|
+
const detail = (event as CustomEvent<AgentChatSubmitResult>).detail;
|
|
1127
|
+
if (!detail || detail.submitMessageId !== submitMessageId) return;
|
|
1128
|
+
finish(detail.delivered, detail.reason);
|
|
1129
|
+
};
|
|
1130
|
+
|
|
1131
|
+
window.addEventListener(
|
|
1132
|
+
AGENT_CHAT_SUBMIT_RESULT_EVENT,
|
|
1133
|
+
onResult as EventListener,
|
|
1134
|
+
);
|
|
1135
|
+
timer = window.setTimeout(() => finish(false, "timeout", true), timeoutMs);
|
|
1136
|
+
try {
|
|
1137
|
+
sendToAgentChat({ ...opts, tabId, submitMessageId });
|
|
1138
|
+
} catch {
|
|
1139
|
+
finish(false, "send-failed", true);
|
|
1140
|
+
}
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
|
|
980
1144
|
/**
|
|
981
1145
|
* Add or replace a keyed context nugget in the active agent chat composer.
|
|
982
1146
|
* The context is not submitted until the user sends the prompt.
|
|
@@ -59,7 +59,15 @@ export {
|
|
|
59
59
|
} from "../code-agent-chat-adapter.js";
|
|
60
60
|
export * from "./connectors.js";
|
|
61
61
|
export * from "./runtime.js";
|
|
62
|
-
export {
|
|
62
|
+
export {
|
|
63
|
+
sendToAgentChat,
|
|
64
|
+
sendToAgentChatAndConfirm,
|
|
65
|
+
reportAgentChatSubmitResult,
|
|
66
|
+
AGENT_CHAT_SUBMIT_RESULT_EVENT,
|
|
67
|
+
type AgentChatMessage,
|
|
68
|
+
type AgentChatSubmitResult,
|
|
69
|
+
type SendToAgentChatAndConfirmResult,
|
|
70
|
+
} from "../agent-chat.js";
|
|
63
71
|
export { useAgentChatGenerating } from "../use-agent-chat.js";
|
|
64
72
|
export { useSendToAgentChat } from "../use-send-to-agent-chat.js";
|
|
65
73
|
export {
|
|
@@ -85,6 +85,31 @@ function serializeChatValue(value: unknown): string | undefined {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Slot contexts (e.g. Design's `DesignExtensionSlotContext`) commonly carry
|
|
90
|
+
* live callback functions alongside plain data — the host component uses
|
|
91
|
+
* those callbacks itself, but `window.postMessage` uses the structured clone
|
|
92
|
+
* algorithm, which throws a `DataCloneError` on any function-valued property
|
|
93
|
+
* (see MDN's postMessage docs). Round-tripping through JSON drops functions
|
|
94
|
+
* (and other non-cloneable values like symbols) the same way
|
|
95
|
+
* `JSON.stringify` already silently omits them, producing a payload that's
|
|
96
|
+
* safe to post. Exported so a test can verify functions never reach the
|
|
97
|
+
* iframe instead of only reading the code.
|
|
98
|
+
*/
|
|
99
|
+
export function sanitizeSlotContextForPostMessage(
|
|
100
|
+
context: Record<string, unknown> | null | undefined,
|
|
101
|
+
): Record<string, unknown> {
|
|
102
|
+
try {
|
|
103
|
+
return JSON.parse(JSON.stringify(context ?? {}));
|
|
104
|
+
} catch {
|
|
105
|
+
// Circular reference or other non-serializable shape — fail safe to an
|
|
106
|
+
// empty context rather than letting postMessage throw and skip every
|
|
107
|
+
// other message this handler sends in the same tick (theme update,
|
|
108
|
+
// ready signal).
|
|
109
|
+
return {};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
88
113
|
export interface EmbeddedExtensionProps {
|
|
89
114
|
extensionId: string;
|
|
90
115
|
/** Slot identifier passed via the iframe URL so the extension runtime knows it's
|
|
@@ -243,8 +268,16 @@ export function EmbeddedExtension({
|
|
|
243
268
|
useEffect(() => {
|
|
244
269
|
const win = iframeRef.current?.contentWindow;
|
|
245
270
|
if (!win) return;
|
|
271
|
+
// Post the JSON-round-tripped context, not the raw `context` object —
|
|
272
|
+
// slot contexts (e.g. Design's DesignExtensionSlotContext) carry live
|
|
273
|
+
// callback functions the host uses internally, and postMessage's
|
|
274
|
+
// structured clone throws a DataCloneError on any function-valued
|
|
275
|
+
// property. See sanitizeSlotContextForPostMessage's docblock.
|
|
246
276
|
win.postMessage(
|
|
247
|
-
{
|
|
277
|
+
{
|
|
278
|
+
type: "agent-native-slot-context",
|
|
279
|
+
context: sanitizeSlotContextForPostMessage(context),
|
|
280
|
+
},
|
|
248
281
|
"*",
|
|
249
282
|
);
|
|
250
283
|
}, [contextJson]);
|
|
@@ -400,7 +433,10 @@ export function EmbeddedExtension({
|
|
|
400
433
|
style={{ width: "100%", border: 0, height, display: "block" }}
|
|
401
434
|
onLoad={() => {
|
|
402
435
|
iframeRef.current?.contentWindow?.postMessage(
|
|
403
|
-
{
|
|
436
|
+
{
|
|
437
|
+
type: "agent-native-slot-context",
|
|
438
|
+
context: sanitizeSlotContextForPostMessage(context),
|
|
439
|
+
},
|
|
404
440
|
"*",
|
|
405
441
|
);
|
|
406
442
|
// Re-assert theme once the iframe document is live. The src bakes in
|
|
@@ -19,6 +19,9 @@ export {
|
|
|
19
19
|
requestAgentChatThreadOpen,
|
|
20
20
|
requestAgentTaskOpen,
|
|
21
21
|
sendToAgentChat,
|
|
22
|
+
sendToAgentChatAndConfirm,
|
|
23
|
+
reportAgentChatSubmitResult,
|
|
24
|
+
AGENT_CHAT_SUBMIT_RESULT_EVENT,
|
|
22
25
|
parseSubmitChatMessage,
|
|
23
26
|
setAgentChatContextItem,
|
|
24
27
|
setContextToAgentChat,
|
|
@@ -33,6 +36,8 @@ export {
|
|
|
33
36
|
type AgentChatContextSetOptions,
|
|
34
37
|
type AgentChatContextState,
|
|
35
38
|
type AgentChatMessage,
|
|
39
|
+
type AgentChatSubmitResult,
|
|
40
|
+
type SendToAgentChatAndConfirmResult,
|
|
36
41
|
type AgentComposerReference,
|
|
37
42
|
type AgentComposerReferenceInsertOptions,
|
|
38
43
|
type AgentComposerReferenceInsertPayload,
|