@agent-native/core-corpus 0.219.0 → 0.220.0-nightly-20261023183804
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/templates/analytics/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/analytics/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/assets/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/assets/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/brain/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/brain/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/calendar/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/calendar/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/chat/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/clips/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/clips/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +146 -14
- package/corpus/templates/clips/app/routes/record.tsx +11 -0
- package/corpus/templates/clips/desktop/src/app.tsx +74 -16
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +12 -4
- package/corpus/templates/clips/desktop/src/lib/recording-request.ts +54 -0
- package/corpus/templates/clips/desktop/src/lib/url.ts +7 -1
- package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +50 -2
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +1 -0
- package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +95 -0
- package/corpus/templates/community/qr/package.json +1 -1
- package/corpus/templates/content/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/content/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/content/actions/_content-save-outcomes.ts +1 -0
- package/corpus/templates/content/actions/_database-utils.ts +49 -1
- package/corpus/templates/content/actions/_document-edit-mutation.ts +273 -0
- package/corpus/templates/content/actions/_document-flush.ts +13 -0
- package/corpus/templates/content/actions/_github-source.ts +664 -267
- package/corpus/templates/content/actions/_move-page-to-space.ts +5 -0
- package/corpus/templates/content/actions/_property-utils.ts +4 -2
- package/corpus/templates/content/actions/add-comment.ts +56 -29
- package/corpus/templates/content/actions/attach-content-database-source.ts +29 -14
- package/corpus/templates/content/actions/bind-content-database-source-field.ts +18 -5
- package/corpus/templates/content/actions/cancel-prepared-builder-source-update.ts +12 -5
- package/corpus/templates/content/actions/change-content-database-source-role.ts +13 -7
- package/corpus/templates/content/actions/create-content-database.ts +11 -4
- package/corpus/templates/content/actions/delete-document.ts +8 -0
- package/corpus/templates/content/actions/disconnect-content-database-source.ts +18 -5
- package/corpus/templates/content/actions/duplicate-database-item.ts +13 -7
- package/corpus/templates/content/actions/duplicate-database-items.ts +28 -22
- package/corpus/templates/content/actions/edit-document.ts +86 -2
- package/corpus/templates/content/actions/execute-builder-source-execution.ts +13 -5
- package/corpus/templates/content/actions/get-content-database.ts +30 -13
- package/corpus/templates/content/actions/materialize-builder-required-fields.ts +9 -3
- package/corpus/templates/content/actions/move-database-item.ts +12 -6
- package/corpus/templates/content/actions/prepare-builder-source-execution.ts +8 -4
- package/corpus/templates/content/actions/preview-content-database-source-attach.ts +6 -3
- package/corpus/templates/content/actions/query-content-database-items.ts +24 -5
- package/corpus/templates/content/actions/remove-database-items.ts +19 -10
- package/corpus/templates/content/actions/restore-document-version.ts +302 -63
- package/corpus/templates/content/actions/review-content-database-source-change-set.ts +11 -4
- package/corpus/templates/content/actions/set-content-database-source-write-mode.ts +11 -4
- package/corpus/templates/content/actions/set-image-alt-text.ts +10 -2
- package/corpus/templates/content/actions/set-live-body-switch.ts +4 -1
- package/corpus/templates/content/actions/stage-builder-revision.ts +10 -4
- package/corpus/templates/content/actions/suggest-document-edit.ts +256 -15
- package/corpus/templates/content/actions/transcribe-media.ts +16 -2
- package/corpus/templates/content/actions/update-content-database-view.ts +8 -2
- package/corpus/templates/content/actions/update-document.ts +1 -1
- package/corpus/templates/content/actions/validate-builder-source-execution.ts +11 -4
- package/corpus/templates/content/app/components/editor/CommentComposer.tsx +142 -2
- package/corpus/templates/content/app/components/editor/CommentEntry.tsx +30 -5
- package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +707 -283
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +38 -40
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +2 -2
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +27 -4
- package/corpus/templates/content/app/components/editor/SuggestionReviewCard.tsx +264 -0
- package/corpus/templates/content/app/components/editor/SuggestionReviewCardSkeleton.tsx +13 -0
- package/corpus/templates/content/app/components/editor/ThreadSuggestion.tsx +3 -2
- package/corpus/templates/content/app/components/editor/block-field-comment-threads.ts +3 -2
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +16 -18
- package/corpus/templates/content/app/components/editor/database/GitHubSourceStatusLine.tsx +128 -0
- package/corpus/templates/content/app/components/editor/database/navigation-state.ts +10 -3
- package/corpus/templates/content/app/components/editor/database/settings.tsx +8 -8
- package/corpus/templates/content/app/components/editor/discussion-panel.tsx +504 -0
- package/corpus/templates/content/app/components/layout/ContentStartupShell.tsx +12 -0
- package/corpus/templates/content/app/discussion-messages.ts +270 -0
- package/corpus/templates/content/app/hooks/use-comments.ts +6 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +114 -110
- package/corpus/templates/content/app/hooks/use-github-folder.ts +15 -5
- package/corpus/templates/content/app/i18n-data.ts +17 -0
- package/corpus/templates/content/app/lib/content-database-query-cache.ts +60 -0
- package/corpus/templates/content/app/root.tsx +23 -8
- package/corpus/templates/content/app/routes/suggestions.$documentId.tsx +79 -0
- package/corpus/templates/content/changelog/2026-10-21-agents-suggested-edits-show-inline-in-mcp-apps-hosts-like-cl.md +6 -0
- package/corpus/templates/content/changelog/2026-10-21-comments-panel-is-now-discussion.md +6 -0
- package/corpus/templates/content/changelog/2026-10-22-a-big-github-folder-fills-its-collection-much-faster-and-kee.md +6 -0
- package/corpus/templates/content/changelog/2026-10-22-collections-with-large-select-properties-open-faster-and-use.md +6 -0
- package/corpus/templates/content/changelog/2026-10-22-pressing-escape-while-writing-a-comment-reply-or-edit-cancel.md +6 -0
- package/corpus/templates/content/docs/product/capabilities/content.comment.page-owned.md +7 -7
- package/corpus/templates/content/docs/product/capabilities/content.discussion.page.md +43 -28
- package/corpus/templates/content/docs/product/encyclopedia.md +7 -7
- package/corpus/templates/content/e2e/helpers.ts +1 -1
- package/corpus/templates/content/server/db/schema.ts +25 -0
- package/corpus/templates/content/server/lib/comment-ai.ts +13 -17
- package/corpus/templates/content/server/lib/comment-anchor-follow.ts +107 -0
- package/corpus/templates/content/server/lib/comment-notifications.ts +3 -3
- package/corpus/templates/content/server/lib/document-body-steps.ts +182 -0
- package/corpus/templates/content/server/lib/document-history.ts +44 -0
- package/corpus/templates/content/server/lib/document-title-propagation.ts +16 -3
- package/corpus/templates/content/server/lib/github-source-client.ts +100 -12
- package/corpus/templates/content/server/lib/live-body-writer.ts +38 -11
- package/corpus/templates/content/server/lib/private-icon-references.ts +4 -2
- package/corpus/templates/content/server/lib/suggested-edits.ts +361 -355
- package/corpus/templates/content/server/lib/suggestion-live-accept.ts +284 -0
- package/corpus/templates/content/server/lib/suggestion-rebaseline.ts +237 -0
- package/corpus/templates/content/server/live-copy/anchor-text.ts +48 -0
- package/corpus/templates/content/server/live-copy/apply-suggestion-edit.ts +528 -0
- package/corpus/templates/content/server/live-copy/binding.ts +3 -0
- package/corpus/templates/content/server/live-copy/persist.ts +94 -30
- package/corpus/templates/content/server/live-copy/rebase.ts +330 -0
- package/corpus/templates/content/server/live-copy/switch.ts +5 -1
- package/corpus/templates/content/server/live-copy/task-names.ts +1 -0
- package/corpus/templates/content/server/live-copy/tasks.ts +160 -6
- package/corpus/templates/content/server/live-copy/write-cause.ts +9 -0
- package/corpus/templates/content/server/live-copy/write.ts +146 -3
- package/corpus/templates/content/server/plugins/db.ts +16 -0
- package/corpus/templates/content/shared/api.ts +59 -4
- package/corpus/templates/content/shared/comment-ai.ts +9 -0
- package/corpus/templates/content/shared/comment-reanchor.ts +148 -2
- package/corpus/templates/content/shared/database-row-properties.ts +172 -0
- package/corpus/templates/content/shared/suggestion-apply.ts +314 -0
- package/corpus/templates/content/shared/suggestion-link.ts +11 -0
- package/corpus/templates/content/shared/suggestion-rebase.ts +1 -1
- package/corpus/templates/content/shared/suggestion-rebaseline.ts +256 -0
- package/corpus/templates/content/vite.config.ts +1 -1
- package/corpus/templates/crm/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/crm/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +46 -8
- package/corpus/templates/design/.agents/skills/export-handoff/SKILL.md +12 -1
- package/corpus/templates/design/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/design/.agents/skills/hubspot-email/SKILL.md +146 -0
- package/corpus/templates/design/.agents/skills/hubspot-email-review/SKILL.md +84 -0
- package/corpus/templates/design/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/design/.generated/bridge/native-builtin-metadata.generated.ts +326 -0
- package/corpus/templates/design/.generated/bridge/native-worker-source.generated.ts +6 -0
- package/corpus/templates/design/AGENTS.md +22 -23
- package/corpus/templates/design/actions/create-file.ts +40 -4
- package/corpus/templates/design/actions/edit-design.ts +1 -1
- package/corpus/templates/design/actions/export-hubspot-html.ts +110 -0
- package/corpus/templates/design/actions/export-png.ts +42 -3
- package/corpus/templates/design/actions/generate-design.ts +84 -28
- package/corpus/templates/design/actions/get-design-snapshot.ts +5 -1
- package/corpus/templates/design/actions/get-design-surface-index.ts +1 -0
- package/corpus/templates/design/actions/take-design-screenshot.ts +217 -116
- package/corpus/templates/design/actions/update-file.ts +9 -0
- package/corpus/templates/design/actions/view-screen.ts +16 -1
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +8 -1
- package/corpus/templates/design/app/components/design/EditPanel.tsx +1 -5
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +3 -3
- package/corpus/templates/design/app/components/design/design-canvas/content-size-report.ts +13 -3
- package/corpus/templates/design/app/components/design/design-canvas/interact-document.ts +10 -3
- package/corpus/templates/design/app/i18n/en-US.ts +13 -0
- package/corpus/templates/design/app/pages/design-editor/commands/download-hubspot-html.ts +86 -0
- package/corpus/templates/design/app/pages/design-editor/design-editor-view.tsx +1 -0
- package/corpus/templates/design/app/pages/design-editor/domains/use-editor-canvas-and-screens.ts +2 -1
- package/corpus/templates/design/app/pages/design-editor/domains/use-editor-export-and-handoff.ts +18 -0
- package/corpus/templates/design/app/pages/design-editor/domains/use-editor-screen-rendering.tsx +1 -0
- package/corpus/templates/design/app/pages/design-editor/domains/use-hubspot-html-export.ts +124 -0
- package/corpus/templates/design/app/pages/design-editor/effects/publish-agent-selection-context.ts +15 -0
- package/corpus/templates/design/app/pages/design-editor/png-export-render.ts +12 -1
- package/corpus/templates/design/app/pages/design-editor/view/editor-dialogs.tsx +10 -0
- package/corpus/templates/design/app/pages/design-editor/view/export-submenu-content.tsx +11 -0
- package/corpus/templates/design/app/pages/design-editor/view/hubspot-email-conversion-dialog.tsx +54 -0
- package/corpus/templates/design/changelog/2026-10-22-create-hubspot-email-frames-rebuild-existing-frames-for-emai.md +6 -0
- package/corpus/templates/design/changelog/2026-10-22-hubspot-conversion-exports-can-verify-that-original-link-des.md +6 -0
- package/corpus/templates/design/changelog/2026-10-22-hubspot-emails-receive-an-independent-content-and-mobile-lay.md +6 -0
- package/corpus/templates/design/changelog/2026-10-22-hug-frames-expand-to-show-their-full-content-in-the-canvas-a.md +6 -0
- package/corpus/templates/design/changelog/2026-10-22-preview-hubspot-emails-with-sample-recipient-names-and-butto.md +6 -0
- package/corpus/templates/design/changelog/2026-10-22-screenshot-previews-use-local-chromium-when-available-for-fa.md +6 -0
- package/corpus/templates/design/changelog/2026-10-22-verification-and-export-requests-finish-without-requiring-un.md +6 -0
- package/corpus/templates/design/changelog/2026-10-23-external-stylesheet-image-export.md +6 -0
- package/corpus/templates/design/changelog/2026-10-23-html-motion-edits-preserve-interactive-alpine-visibility-sta.md +6 -0
- package/corpus/templates/design/changelog/2026-10-23-motion-editing-works-again-on-designs-that-load-tailwind-and.md +6 -0
- package/corpus/templates/design/changelog/2026-10-23-promo-artwork-uses-delivery-size-typography.md +6 -0
- package/corpus/templates/design/server/lib/design-response-guard.ts +29 -1
- package/corpus/templates/design/server/lib/email-css-properties.ts +128 -0
- package/corpus/templates/design/server/lib/email-css-values.ts +36 -0
- package/corpus/templates/design/server/lib/email-css-visibility.ts +72 -0
- package/corpus/templates/design/server/lib/email-image-bytes.ts +87 -0
- package/corpus/templates/design/server/lib/email-text-color.ts +85 -0
- package/corpus/templates/design/server/lib/hubl-interpolation.ts +63 -0
- package/corpus/templates/design/server/lib/hubspot-email-export.ts +1005 -0
- package/corpus/templates/design/server/lib/hubspot-email-preview.ts +153 -0
- package/corpus/templates/design/server/lib/playwright-runtime.ts +6 -6
- package/corpus/templates/design/server/lib/protect-hubl-tokens.ts +31 -0
- package/corpus/templates/design/server/lib/screenshot-readiness.ts +176 -0
- package/corpus/templates/design/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/design/server/source-workspace.ts +22 -0
- package/corpus/templates/design/shared/hubl-tokens.ts +55 -0
- package/corpus/templates/design/shared/hubspot-email-authoring.ts +35 -0
- package/corpus/templates/design/shared/hubspot-email.ts +100 -0
- package/corpus/templates/design/shared/motion-html-source.ts +547 -16
- package/corpus/templates/dispatch/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/dispatch/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/factory/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/forms/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/forms/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/mail/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/mail/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/plan/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/plan/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/slides/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/slides/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/slides/scripts/edit-fidelity/run-options.ts +26 -0
- package/corpus/templates/slides/scripts/edit-fidelity/run.ts +25 -4
- package/corpus/templates/slides-2/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/corpus/templates/slides-2/.deploy-tmp/agent-native-provided-plugins.mjs +10 -0
- package/corpus/templates/tasks/.agents/skills/external-agents/references/mcp-apps-embedding.md +12 -5
- package/package.json +1 -1
package/corpus/README.md
CHANGED
package/corpus/templates/analytics/.agents/skills/external-agents/references/mcp-apps-embedding.md
CHANGED
|
@@ -162,8 +162,15 @@ actions for Forms, Content, Clips, Slides, and Design. The action should return
|
|
|
162
162
|
concise structured content plus the link; it should not dump large catalogs or
|
|
163
163
|
HTML.
|
|
164
164
|
|
|
165
|
-
Compatibility target: build to the standard once, not per-client shims.
|
|
166
|
-
Apps
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
165
|
+
Compatibility target: build to the standard once, not per-client shims.
|
|
166
|
+
Hosts that render MCP Apps inline today include Claude chat on web, desktop, and
|
|
167
|
+
mobile, plus the Claude Desktop Code tab; ChatGPT; VS Code GitHub Copilot (1.109+);
|
|
168
|
+
Microsoft 365 Copilot; Cursor (2.6+); Goose; Postman; MCPJam; Codex Desktop (26.616+);
|
|
169
|
+
and T3 Code (in Codex threads). Desktop Code rendering is observed in
|
|
170
|
+
[widget bug reports](https://github.com/anthropics/claude-code/issues/103809).
|
|
171
|
+
Treat the Claude Code terminal, Cowork, and Code on claude.ai web as link-out hosts.
|
|
172
|
+
[Cowork doesn't declare MCP Apps yet](https://github.com/anthropics/claude-code/issues/103924),
|
|
173
|
+
and using it on the same connector can make inline apps disappear in Chat until
|
|
174
|
+
you reconnect the connector. Host support varies by plan, release channel, and client version,
|
|
175
|
+
so keep the deep link fallback. See the community-maintained
|
|
176
|
+
[MCP client matrix](https://modelcontextprotocol.io/extensions/client-matrix).
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// AUTO-GENERATED by @agent-native/core deploy build
|
|
2
|
+
import { markDefaultPluginProvided } from "@agent-native/core/server/edge";
|
|
3
|
+
|
|
4
|
+
const pluginStems = ["agent-chat","analytics-alert-jobs","analytics-rollup-backfill-jobs","auth","collab","config","content-metrics-collection-jobs","core-routes","creative-context","dashboard-report-jobs","db","feature-flags","labs","onboarding","otel","session-replay-retention-jobs","transactional-emails","uptime-monitor-jobs"];
|
|
5
|
+
|
|
6
|
+
export default function markBuildDiscoveredPlugins(nitroApp) {
|
|
7
|
+
for (const stem of pluginStems) {
|
|
8
|
+
markDefaultPluginProvided(nitroApp, stem);
|
|
9
|
+
}
|
|
10
|
+
}
|
package/corpus/templates/assets/.agents/skills/external-agents/references/mcp-apps-embedding.md
CHANGED
|
@@ -162,8 +162,15 @@ actions for Forms, Content, Clips, Slides, and Design. The action should return
|
|
|
162
162
|
concise structured content plus the link; it should not dump large catalogs or
|
|
163
163
|
HTML.
|
|
164
164
|
|
|
165
|
-
Compatibility target: build to the standard once, not per-client shims.
|
|
166
|
-
Apps
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
165
|
+
Compatibility target: build to the standard once, not per-client shims.
|
|
166
|
+
Hosts that render MCP Apps inline today include Claude chat on web, desktop, and
|
|
167
|
+
mobile, plus the Claude Desktop Code tab; ChatGPT; VS Code GitHub Copilot (1.109+);
|
|
168
|
+
Microsoft 365 Copilot; Cursor (2.6+); Goose; Postman; MCPJam; Codex Desktop (26.616+);
|
|
169
|
+
and T3 Code (in Codex threads). Desktop Code rendering is observed in
|
|
170
|
+
[widget bug reports](https://github.com/anthropics/claude-code/issues/103809).
|
|
171
|
+
Treat the Claude Code terminal, Cowork, and Code on claude.ai web as link-out hosts.
|
|
172
|
+
[Cowork doesn't declare MCP Apps yet](https://github.com/anthropics/claude-code/issues/103924),
|
|
173
|
+
and using it on the same connector can make inline apps disappear in Chat until
|
|
174
|
+
you reconnect the connector. Host support varies by plan, release channel, and client version,
|
|
175
|
+
so keep the deep link fallback. See the community-maintained
|
|
176
|
+
[MCP client matrix](https://modelcontextprotocol.io/extensions/client-matrix).
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// AUTO-GENERATED by @agent-native/core deploy build
|
|
2
|
+
import { markDefaultPluginProvided } from "@agent-native/core/server/edge";
|
|
3
|
+
|
|
4
|
+
const pluginStems = ["agent-chat","auth","creative-context","db","labs","onboarding","otel"];
|
|
5
|
+
|
|
6
|
+
export default function markBuildDiscoveredPlugins(nitroApp) {
|
|
7
|
+
for (const stem of pluginStems) {
|
|
8
|
+
markDefaultPluginProvided(nitroApp, stem);
|
|
9
|
+
}
|
|
10
|
+
}
|
package/corpus/templates/brain/.agents/skills/external-agents/references/mcp-apps-embedding.md
CHANGED
|
@@ -162,8 +162,15 @@ actions for Forms, Content, Clips, Slides, and Design. The action should return
|
|
|
162
162
|
concise structured content plus the link; it should not dump large catalogs or
|
|
163
163
|
HTML.
|
|
164
164
|
|
|
165
|
-
Compatibility target: build to the standard once, not per-client shims.
|
|
166
|
-
Apps
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
165
|
+
Compatibility target: build to the standard once, not per-client shims.
|
|
166
|
+
Hosts that render MCP Apps inline today include Claude chat on web, desktop, and
|
|
167
|
+
mobile, plus the Claude Desktop Code tab; ChatGPT; VS Code GitHub Copilot (1.109+);
|
|
168
|
+
Microsoft 365 Copilot; Cursor (2.6+); Goose; Postman; MCPJam; Codex Desktop (26.616+);
|
|
169
|
+
and T3 Code (in Codex threads). Desktop Code rendering is observed in
|
|
170
|
+
[widget bug reports](https://github.com/anthropics/claude-code/issues/103809).
|
|
171
|
+
Treat the Claude Code terminal, Cowork, and Code on claude.ai web as link-out hosts.
|
|
172
|
+
[Cowork doesn't declare MCP Apps yet](https://github.com/anthropics/claude-code/issues/103924),
|
|
173
|
+
and using it on the same connector can make inline apps disappear in Chat until
|
|
174
|
+
you reconnect the connector. Host support varies by plan, release channel, and client version,
|
|
175
|
+
so keep the deep link fallback. See the community-maintained
|
|
176
|
+
[MCP client matrix](https://modelcontextprotocol.io/extensions/client-matrix).
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// AUTO-GENERATED by @agent-native/core deploy build
|
|
2
|
+
import { markDefaultPluginProvided } from "@agent-native/core/server/edge";
|
|
3
|
+
|
|
4
|
+
const pluginStems = ["agent-chat","auth","brain-jobs","core-routes","db","otel"];
|
|
5
|
+
|
|
6
|
+
export default function markBuildDiscoveredPlugins(nitroApp) {
|
|
7
|
+
for (const stem of pluginStems) {
|
|
8
|
+
markDefaultPluginProvided(nitroApp, stem);
|
|
9
|
+
}
|
|
10
|
+
}
|
package/corpus/templates/calendar/.agents/skills/external-agents/references/mcp-apps-embedding.md
CHANGED
|
@@ -162,8 +162,15 @@ actions for Forms, Content, Clips, Slides, and Design. The action should return
|
|
|
162
162
|
concise structured content plus the link; it should not dump large catalogs or
|
|
163
163
|
HTML.
|
|
164
164
|
|
|
165
|
-
Compatibility target: build to the standard once, not per-client shims.
|
|
166
|
-
Apps
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
165
|
+
Compatibility target: build to the standard once, not per-client shims.
|
|
166
|
+
Hosts that render MCP Apps inline today include Claude chat on web, desktop, and
|
|
167
|
+
mobile, plus the Claude Desktop Code tab; ChatGPT; VS Code GitHub Copilot (1.109+);
|
|
168
|
+
Microsoft 365 Copilot; Cursor (2.6+); Goose; Postman; MCPJam; Codex Desktop (26.616+);
|
|
169
|
+
and T3 Code (in Codex threads). Desktop Code rendering is observed in
|
|
170
|
+
[widget bug reports](https://github.com/anthropics/claude-code/issues/103809).
|
|
171
|
+
Treat the Claude Code terminal, Cowork, and Code on claude.ai web as link-out hosts.
|
|
172
|
+
[Cowork doesn't declare MCP Apps yet](https://github.com/anthropics/claude-code/issues/103924),
|
|
173
|
+
and using it on the same connector can make inline apps disappear in Chat until
|
|
174
|
+
you reconnect the connector. Host support varies by plan, release channel, and client version,
|
|
175
|
+
so keep the deep link fallback. See the community-maintained
|
|
176
|
+
[MCP client matrix](https://modelcontextprotocol.io/extensions/client-matrix).
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// AUTO-GENERATED by @agent-native/core deploy build
|
|
2
|
+
import { markDefaultPluginProvided } from "@agent-native/core/server/edge";
|
|
3
|
+
|
|
4
|
+
const pluginStems = ["agent-chat","auth","core-routes","db","event-rules","oauth-refresh","otel","transactional-emails"];
|
|
5
|
+
|
|
6
|
+
export default function markBuildDiscoveredPlugins(nitroApp) {
|
|
7
|
+
for (const stem of pluginStems) {
|
|
8
|
+
markDefaultPluginProvided(nitroApp, stem);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// AUTO-GENERATED by @agent-native/core deploy build
|
|
2
|
+
import { markDefaultPluginProvided } from "@agent-native/core/server/edge";
|
|
3
|
+
|
|
4
|
+
const pluginStems = ["agent-chat","auth","otel"];
|
|
5
|
+
|
|
6
|
+
export default function markBuildDiscoveredPlugins(nitroApp) {
|
|
7
|
+
for (const stem of pluginStems) {
|
|
8
|
+
markDefaultPluginProvided(nitroApp, stem);
|
|
9
|
+
}
|
|
10
|
+
}
|
package/corpus/templates/clips/.agents/skills/external-agents/references/mcp-apps-embedding.md
CHANGED
|
@@ -162,8 +162,15 @@ actions for Forms, Content, Clips, Slides, and Design. The action should return
|
|
|
162
162
|
concise structured content plus the link; it should not dump large catalogs or
|
|
163
163
|
HTML.
|
|
164
164
|
|
|
165
|
-
Compatibility target: build to the standard once, not per-client shims.
|
|
166
|
-
Apps
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
165
|
+
Compatibility target: build to the standard once, not per-client shims.
|
|
166
|
+
Hosts that render MCP Apps inline today include Claude chat on web, desktop, and
|
|
167
|
+
mobile, plus the Claude Desktop Code tab; ChatGPT; VS Code GitHub Copilot (1.109+);
|
|
168
|
+
Microsoft 365 Copilot; Cursor (2.6+); Goose; Postman; MCPJam; Codex Desktop (26.616+);
|
|
169
|
+
and T3 Code (in Codex threads). Desktop Code rendering is observed in
|
|
170
|
+
[widget bug reports](https://github.com/anthropics/claude-code/issues/103809).
|
|
171
|
+
Treat the Claude Code terminal, Cowork, and Code on claude.ai web as link-out hosts.
|
|
172
|
+
[Cowork doesn't declare MCP Apps yet](https://github.com/anthropics/claude-code/issues/103924),
|
|
173
|
+
and using it on the same connector can make inline apps disappear in Chat until
|
|
174
|
+
you reconnect the connector. Host support varies by plan, release channel, and client version,
|
|
175
|
+
so keep the deep link fallback. See the community-maintained
|
|
176
|
+
[MCP client matrix](https://modelcontextprotocol.io/extensions/client-matrix).
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// AUTO-GENERATED by @agent-native/core deploy build
|
|
2
|
+
import { markDefaultPluginProvided } from "@agent-native/core/server/edge";
|
|
3
|
+
|
|
4
|
+
const pluginStems = ["agent-chat","auth","calendar-jobs","config","core-routes","db","feature-flags","labs","onboarding","onboarding-calendar","otel","transactional-email-catalog"];
|
|
5
|
+
|
|
6
|
+
export default function markBuildDiscoveredPlugins(nitroApp) {
|
|
7
|
+
for (const stem of pluginStems) {
|
|
8
|
+
markDefaultPluginProvided(nitroApp, stem);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -31,10 +31,11 @@ import {
|
|
|
31
31
|
// success should finish this card's setup; a connection made long after the
|
|
32
32
|
// cancel belongs to something else.
|
|
33
33
|
const CANCELLED_SETUP_RECOVERY_MS = 60_000;
|
|
34
|
+
// The custom-keys form finishes in another tab with no signal back, so a
|
|
35
|
+
// status read on leaving or returning credits it only this long after it was
|
|
36
|
+
// opened; storage set up later belongs to something else.
|
|
37
|
+
const CUSTOM_KEYS_CREDIT_WINDOW_MS = 15 * 60_000;
|
|
34
38
|
|
|
35
|
-
// The S3 path finishes in settings, outside this card, so only the choice is
|
|
36
|
-
// recorded here; a later `recording_started.storage_connected` shows whether
|
|
37
|
-
// it landed.
|
|
38
39
|
function trackStorageStep(
|
|
39
40
|
name:
|
|
40
41
|
| "onboarding_step_viewed"
|
|
@@ -66,6 +67,8 @@ export interface StorageSetupCardProps {
|
|
|
66
67
|
*/
|
|
67
68
|
recordingAttemptId?: string;
|
|
68
69
|
outputId?: string;
|
|
70
|
+
/** Why the host is showing the card, recorded on every step event. */
|
|
71
|
+
setupReason?: string;
|
|
69
72
|
}
|
|
70
73
|
|
|
71
74
|
export function StorageSetupCard({
|
|
@@ -79,6 +82,7 @@ export function StorageSetupCard({
|
|
|
79
82
|
connectFlow = "file_upload",
|
|
80
83
|
recordingAttemptId,
|
|
81
84
|
outputId,
|
|
85
|
+
setupReason,
|
|
82
86
|
}: StorageSetupCardProps) {
|
|
83
87
|
const t = useT();
|
|
84
88
|
const storageSetupHref = useStorageSetupHref();
|
|
@@ -100,6 +104,9 @@ export function StorageSetupCard({
|
|
|
100
104
|
const connectRequestedRef = useRef(false);
|
|
101
105
|
const connectIntentExpiresAtRef = useRef<number | null>(null);
|
|
102
106
|
const [stepViewId] = useState(createOnboardingCorrelationId);
|
|
107
|
+
// Fixed for the showing: the host's status can change while the card is up,
|
|
108
|
+
// and every event under one step_view_id must agree on why it showed.
|
|
109
|
+
const [viewSetupReason] = useState(setupReason);
|
|
103
110
|
const stepProperties = useMemo(
|
|
104
111
|
() => ({
|
|
105
112
|
flow: connectSource,
|
|
@@ -108,8 +115,69 @@ export function StorageSetupCard({
|
|
|
108
115
|
? { recording_attempt_id: recordingAttemptId }
|
|
109
116
|
: {}),
|
|
110
117
|
...(outputId ? { output_id: outputId } : {}),
|
|
118
|
+
...(viewSetupReason ? { setup_reason: viewSetupReason } : {}),
|
|
111
119
|
}),
|
|
112
|
-
[connectSource, stepViewId, recordingAttemptId, outputId],
|
|
120
|
+
[connectSource, stepViewId, recordingAttemptId, outputId, viewSetupReason],
|
|
121
|
+
);
|
|
122
|
+
const stepPropertiesRef = useRef(stepProperties);
|
|
123
|
+
stepPropertiesRef.current = stepProperties;
|
|
124
|
+
const builderHandedOffRef = useRef(false);
|
|
125
|
+
const skippedRef = useRef(false);
|
|
126
|
+
const customKeysOpenedAtRef = useRef<number | null>(null);
|
|
127
|
+
const customKeysOpenedRecently = useCallback(() => {
|
|
128
|
+
const openedAt = customKeysOpenedAtRef.current;
|
|
129
|
+
return (
|
|
130
|
+
openedAt !== null && Date.now() - openedAt <= CUSTOM_KEYS_CREDIT_WINDOW_MS
|
|
131
|
+
);
|
|
132
|
+
}, []);
|
|
133
|
+
const completionTrackedRef = useRef(false);
|
|
134
|
+
const returnReadInFlightRef = useRef(false);
|
|
135
|
+
const storageBeforeSetupRef = useRef<Promise<
|
|
136
|
+
{ status: VideoStorageStatus } | { error: unknown }
|
|
137
|
+
> | null>(null);
|
|
138
|
+
const readStorageBeforeSetup = useCallback(() => {
|
|
139
|
+
storageBeforeSetupRef.current ??= fetchVideoStorageStatus({
|
|
140
|
+
timeoutMs: 10_000,
|
|
141
|
+
}).then(
|
|
142
|
+
(status) => ({ status }),
|
|
143
|
+
(error: unknown) => ({ error }),
|
|
144
|
+
);
|
|
145
|
+
}, []);
|
|
146
|
+
|
|
147
|
+
// The route hosting this card can unmount it the moment the shared storage
|
|
148
|
+
// status reads configured, before this card's poll sees it, so the unmount
|
|
149
|
+
// path below reads the status once more and records through this too.
|
|
150
|
+
// Only a change to the workspace's own storage completes this step: free
|
|
151
|
+
// hosted clips also read as configured, and own storage that was already
|
|
152
|
+
// there at the showing's first setup click was not set up by this card.
|
|
153
|
+
// The read of storage before setup must start before any setup request
|
|
154
|
+
// can, since one-request account activation can finish before a read sent
|
|
155
|
+
// with it.
|
|
156
|
+
const trackCompletedIfConfigured = useCallback(
|
|
157
|
+
(status: VideoStorageStatus) => {
|
|
158
|
+
const before = storageBeforeSetupRef.current;
|
|
159
|
+
if (status.mode !== "own" || !before || completionTrackedRef.current) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// Claimed before the wait, so reads landing together record once.
|
|
163
|
+
completionTrackedRef.current = true;
|
|
164
|
+
void before.then((read) => {
|
|
165
|
+
if ("error" in read) {
|
|
166
|
+
console.warn(
|
|
167
|
+
"[storage-setup] storage before setup could not be read:",
|
|
168
|
+
read.error,
|
|
169
|
+
);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (read.status.mode === "own" || skippedRef.current) return;
|
|
173
|
+
const methodId = status.activeProvider?.id;
|
|
174
|
+
trackStorageStep("onboarding_step_completed", {
|
|
175
|
+
...stepPropertiesRef.current,
|
|
176
|
+
...(methodId ? { method_id: methodId } : {}),
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
},
|
|
180
|
+
[],
|
|
113
181
|
);
|
|
114
182
|
|
|
115
183
|
const clearConfiguredTimeout = useCallback(() => {
|
|
@@ -177,10 +245,7 @@ export function StorageSetupCard({
|
|
|
177
245
|
stop();
|
|
178
246
|
setConnecting(false);
|
|
179
247
|
setConnected(true);
|
|
180
|
-
|
|
181
|
-
...stepProperties,
|
|
182
|
-
method_id: "builder",
|
|
183
|
-
});
|
|
248
|
+
trackCompletedIfConfigured(status);
|
|
184
249
|
clearConfiguredTimeout();
|
|
185
250
|
configuredTimeoutRef.current = setTimeout(() => {
|
|
186
251
|
configuredTimeoutRef.current = null;
|
|
@@ -211,9 +276,9 @@ export function StorageSetupCard({
|
|
|
211
276
|
}, [
|
|
212
277
|
clearConfiguredTimeout,
|
|
213
278
|
onConfigured,
|
|
214
|
-
stepProperties,
|
|
215
279
|
stopVisibilityHandler,
|
|
216
280
|
t,
|
|
281
|
+
trackCompletedIfConfigured,
|
|
217
282
|
]);
|
|
218
283
|
|
|
219
284
|
const handleBuilderConnected = useCallback(() => {
|
|
@@ -222,6 +287,7 @@ export function StorageSetupCard({
|
|
|
222
287
|
connectRequestedRef.current = false;
|
|
223
288
|
connectIntentExpiresAtRef.current = null;
|
|
224
289
|
if (expiresAt !== null && Date.now() > expiresAt) return;
|
|
290
|
+
builderHandedOffRef.current = true;
|
|
225
291
|
startFileUploadPoll();
|
|
226
292
|
}, [startFileUploadPoll]);
|
|
227
293
|
|
|
@@ -269,6 +335,7 @@ export function StorageSetupCard({
|
|
|
269
335
|
setStatusIssue("connect-not-allowed");
|
|
270
336
|
return;
|
|
271
337
|
}
|
|
338
|
+
readStorageBeforeSetup();
|
|
272
339
|
connectRequestedRef.current = true;
|
|
273
340
|
connectIntentExpiresAtRef.current = null;
|
|
274
341
|
setStatusIssue(null);
|
|
@@ -281,7 +348,12 @@ export function StorageSetupCard({
|
|
|
281
348
|
scope: builderConnectionScope,
|
|
282
349
|
});
|
|
283
350
|
},
|
|
284
|
-
[
|
|
351
|
+
[
|
|
352
|
+
builderConnectionScope,
|
|
353
|
+
builderConnect.start,
|
|
354
|
+
readStorageBeforeSetup,
|
|
355
|
+
stepProperties,
|
|
356
|
+
],
|
|
285
357
|
);
|
|
286
358
|
const handleBuilderCancel = useCallback(() => {
|
|
287
359
|
connectIntentExpiresAtRef.current =
|
|
@@ -290,6 +362,7 @@ export function StorageSetupCard({
|
|
|
290
362
|
}, [builderConnect.cancel]);
|
|
291
363
|
const handleSkip = useCallback(() => {
|
|
292
364
|
clearConfiguredTimeout();
|
|
365
|
+
skippedRef.current = true;
|
|
293
366
|
trackStorageStep("onboarding_step_skipped", {
|
|
294
367
|
...stepProperties,
|
|
295
368
|
});
|
|
@@ -307,8 +380,41 @@ export function StorageSetupCard({
|
|
|
307
380
|
)
|
|
308
381
|
: null;
|
|
309
382
|
const builderConnecting = builderConnect.connecting;
|
|
383
|
+
const builderConnectingRef = useRef(builderConnecting);
|
|
384
|
+
builderConnectingRef.current = builderConnecting;
|
|
310
385
|
const actionConnecting = connecting || builderConnecting;
|
|
311
386
|
|
|
387
|
+
// The custom-keys form opens in another tab, and some routes keep this card
|
|
388
|
+
// mounted after it saves, so a return to this tab reads the status too.
|
|
389
|
+
useEffect(() => {
|
|
390
|
+
const readOnReturn = () => {
|
|
391
|
+
if (
|
|
392
|
+
document.hidden ||
|
|
393
|
+
!customKeysOpenedRecently() ||
|
|
394
|
+
completionTrackedRef.current ||
|
|
395
|
+
skippedRef.current ||
|
|
396
|
+
returnReadInFlightRef.current
|
|
397
|
+
) {
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
returnReadInFlightRef.current = true;
|
|
401
|
+
void fetchVideoStorageStatus({ timeoutMs: 10_000 })
|
|
402
|
+
.then(trackCompletedIfConfigured)
|
|
403
|
+
.catch((err) => {
|
|
404
|
+
console.warn("[storage-setup] completion check failed:", err);
|
|
405
|
+
})
|
|
406
|
+
.finally(() => {
|
|
407
|
+
returnReadInFlightRef.current = false;
|
|
408
|
+
});
|
|
409
|
+
};
|
|
410
|
+
window.addEventListener("focus", readOnReturn);
|
|
411
|
+
document.addEventListener("visibilitychange", readOnReturn);
|
|
412
|
+
return () => {
|
|
413
|
+
window.removeEventListener("focus", readOnReturn);
|
|
414
|
+
document.removeEventListener("visibilitychange", readOnReturn);
|
|
415
|
+
};
|
|
416
|
+
}, [customKeysOpenedRecently, trackCompletedIfConfigured]);
|
|
417
|
+
|
|
312
418
|
useEffect(() => {
|
|
313
419
|
trackStorageStep("onboarding_step_viewed", {
|
|
314
420
|
...stepProperties,
|
|
@@ -319,6 +425,24 @@ export function StorageSetupCard({
|
|
|
319
425
|
mountedRef.current = true;
|
|
320
426
|
return () => {
|
|
321
427
|
mountedRef.current = false;
|
|
428
|
+
// The route can unmount this card mid-setup: while the connect flow is
|
|
429
|
+
// still connecting, or after this card accepted the connect but before
|
|
430
|
+
// its storage poll saw it. After a cancel the flow keeps connecting
|
|
431
|
+
// through its popup-closed grace, so crediting then relies on that grace
|
|
432
|
+
// staying shorter than CANCELLED_SETUP_RECOVERY_MS.
|
|
433
|
+
const setupPending =
|
|
434
|
+
!completionTrackedRef.current &&
|
|
435
|
+
!skippedRef.current &&
|
|
436
|
+
(builderHandedOffRef.current ||
|
|
437
|
+
builderConnectingRef.current ||
|
|
438
|
+
customKeysOpenedRecently());
|
|
439
|
+
if (setupPending) {
|
|
440
|
+
void fetchVideoStorageStatus({ timeoutMs: 10_000 })
|
|
441
|
+
.then(trackCompletedIfConfigured)
|
|
442
|
+
.catch((err) => {
|
|
443
|
+
console.warn("[storage-setup] completion check failed:", err);
|
|
444
|
+
});
|
|
445
|
+
}
|
|
322
446
|
clearConfiguredTimeout();
|
|
323
447
|
if (pollRef.current) {
|
|
324
448
|
clearInterval(pollRef.current);
|
|
@@ -326,7 +450,12 @@ export function StorageSetupCard({
|
|
|
326
450
|
}
|
|
327
451
|
stopVisibilityHandler();
|
|
328
452
|
};
|
|
329
|
-
}, [
|
|
453
|
+
}, [
|
|
454
|
+
clearConfiguredTimeout,
|
|
455
|
+
customKeysOpenedRecently,
|
|
456
|
+
stopVisibilityHandler,
|
|
457
|
+
trackCompletedIfConfigured,
|
|
458
|
+
]);
|
|
330
459
|
|
|
331
460
|
return (
|
|
332
461
|
<div className="mx-auto flex w-full max-w-md flex-col gap-5 rounded-2xl border border-border bg-card p-6 shadow-lg">
|
|
@@ -357,6 +486,7 @@ export function StorageSetupCard({
|
|
|
357
486
|
cancel: undefined,
|
|
358
487
|
}}
|
|
359
488
|
onConnect={handleBuilderConnect}
|
|
489
|
+
onTriggerClick={readStorageBeforeSetup}
|
|
360
490
|
>
|
|
361
491
|
<Button
|
|
362
492
|
type="button"
|
|
@@ -379,12 +509,14 @@ export function StorageSetupCard({
|
|
|
379
509
|
href={storageSetupHref}
|
|
380
510
|
target="_blank"
|
|
381
511
|
rel="noopener noreferrer"
|
|
382
|
-
onClick={() =>
|
|
512
|
+
onClick={() => {
|
|
513
|
+
readStorageBeforeSetup();
|
|
514
|
+
customKeysOpenedAtRef.current = Date.now();
|
|
383
515
|
trackStorageStep("onboarding_method_clicked", {
|
|
384
516
|
...stepProperties,
|
|
385
517
|
method_id: "s3",
|
|
386
|
-
})
|
|
387
|
-
}
|
|
518
|
+
});
|
|
519
|
+
}}
|
|
388
520
|
>
|
|
389
521
|
{t("storageSetup.customKeys")}
|
|
390
522
|
</a>
|
|
@@ -1279,6 +1279,16 @@ export function shouldRedirectToStorageSetupHome({
|
|
|
1279
1279
|
);
|
|
1280
1280
|
}
|
|
1281
1281
|
|
|
1282
|
+
export function storageSetupReason(
|
|
1283
|
+
status: Pick<VideoStorageStatus, "denyReason"> | undefined,
|
|
1284
|
+
): string {
|
|
1285
|
+
if (!status) return "status_unavailable";
|
|
1286
|
+
// "disabled" means free hosted clips are off, not that a hosted clip was denied.
|
|
1287
|
+
return status.denyReason && status.denyReason !== "disabled"
|
|
1288
|
+
? `hosted_${status.denyReason}`
|
|
1289
|
+
: "storage_required";
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1282
1292
|
export function shouldShowFirstRunStorageSetup({
|
|
1283
1293
|
storageConfigured,
|
|
1284
1294
|
storageStatusUnavailable,
|
|
@@ -4187,6 +4197,7 @@ export default function RecordRoute() {
|
|
|
4187
4197
|
showBuilderStorageOffer={!hostedAllowanceExhausted}
|
|
4188
4198
|
connectSource="clips_record_storage_setup_card"
|
|
4189
4199
|
connectFlow="record"
|
|
4200
|
+
setupReason={storageSetupReason(storageQuery.data)}
|
|
4190
4201
|
/>
|
|
4191
4202
|
</div>
|
|
4192
4203
|
) : showStorageStatusUnavailable ? (
|
|
@@ -230,7 +230,9 @@ import {
|
|
|
230
230
|
import {
|
|
231
231
|
RECORDING_SERVER_UNAVAILABLE,
|
|
232
232
|
RECORDING_SESSION_EXPIRED,
|
|
233
|
+
buildVideoStorageSetupUrl,
|
|
233
234
|
isStorageSetupFailureMessage,
|
|
235
|
+
onStorageSetupRequired,
|
|
234
236
|
} from "./lib/recording-request";
|
|
235
237
|
import {
|
|
236
238
|
listenForRecordingShortcutStopAcks,
|
|
@@ -1392,6 +1394,8 @@ export function App({
|
|
|
1392
1394
|
);
|
|
1393
1395
|
}, [videoStorageIdentity, serverUrl, signedInAs]);
|
|
1394
1396
|
|
|
1397
|
+
const videoStorageProbeSeqRef = useRef(0);
|
|
1398
|
+
|
|
1395
1399
|
const refreshVideoStorageStatus = useCallback(async () => {
|
|
1396
1400
|
if (authStatus !== "authed") {
|
|
1397
1401
|
hostedClipLimitMsRef.current = null;
|
|
@@ -1400,11 +1404,15 @@ export function App({
|
|
|
1400
1404
|
}
|
|
1401
1405
|
|
|
1402
1406
|
const probedIdentity = videoStorageIdentity;
|
|
1407
|
+
// Probes are slow enough to overlap; only the newest result may land, or a
|
|
1408
|
+
// pre-connect "missing" overwrites the "configured" that came after it.
|
|
1409
|
+
const probeSeq = ++videoStorageProbeSeqRef.current;
|
|
1403
1410
|
const { probe, maxClipDurationMs } = await hasConfiguredVideoStorage(
|
|
1404
1411
|
serverUrl,
|
|
1405
1412
|
signedInAs,
|
|
1406
1413
|
);
|
|
1407
1414
|
if (videoStorageIdentityRef.current !== probedIdentity) return false;
|
|
1415
|
+
if (videoStorageProbeSeqRef.current !== probeSeq) return false;
|
|
1408
1416
|
if (probe === "unavailable") {
|
|
1409
1417
|
setVideoStorageStatus("unavailable");
|
|
1410
1418
|
return false;
|
|
@@ -1433,8 +1441,10 @@ export function App({
|
|
|
1433
1441
|
});
|
|
1434
1442
|
};
|
|
1435
1443
|
const interval = window.setInterval(tick, 5000);
|
|
1444
|
+
// Showing the popover always re-probes, even past an in-flight probe: the
|
|
1445
|
+
// newest probe wins.
|
|
1436
1446
|
const onVisibilityChange = () => {
|
|
1437
|
-
if (!document.hidden)
|
|
1447
|
+
if (!document.hidden) void refreshVideoStorageStatus();
|
|
1438
1448
|
};
|
|
1439
1449
|
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
1440
1450
|
return () => {
|
|
@@ -3855,6 +3865,7 @@ export function App({
|
|
|
3855
3865
|
) => {
|
|
3856
3866
|
if (recordFirstUploading || !recordFirstKey || !signedInAs) return;
|
|
3857
3867
|
if (videoStorageStatus !== "configured") {
|
|
3868
|
+
setRecError(STORAGE_SETUP_HELP_TEXT);
|
|
3858
3869
|
openVideoStorageSetup();
|
|
3859
3870
|
return;
|
|
3860
3871
|
}
|
|
@@ -4147,19 +4158,62 @@ export function App({
|
|
|
4147
4158
|
const openVideoStorageSetup = useCallback(
|
|
4148
4159
|
(targetServerUrl?: string) => {
|
|
4149
4160
|
const base = (targetServerUrl?.trim() || serverUrl).replace(/\/+$/, "");
|
|
4150
|
-
|
|
4151
|
-
void openExternal(`${base}/record?connectStorage=1`).catch((err) => {
|
|
4161
|
+
void openExternal(buildVideoStorageSetupUrl(base)).catch((err) => {
|
|
4152
4162
|
setRecError(
|
|
4153
4163
|
err instanceof Error
|
|
4154
4164
|
? err.message
|
|
4155
4165
|
: "Could not open Clips storage setup.",
|
|
4156
4166
|
);
|
|
4157
4167
|
});
|
|
4158
|
-
void refreshVideoStorageStatus();
|
|
4159
4168
|
},
|
|
4160
|
-
[
|
|
4169
|
+
[serverUrl],
|
|
4170
|
+
);
|
|
4171
|
+
|
|
4172
|
+
// Drops the "missing" banner until the next probe. A probe already in flight
|
|
4173
|
+
// would land after this and restore it, so it is invalidated too.
|
|
4174
|
+
const forgetMissingVideoStorage = useCallback(() => {
|
|
4175
|
+
videoStorageProbeSeqRef.current += 1;
|
|
4176
|
+
setRecError((message) =>
|
|
4177
|
+
isStorageSetupFailureMessage(message) ? null : message,
|
|
4178
|
+
);
|
|
4179
|
+
setVideoStorageStatus((status) =>
|
|
4180
|
+
status === "missing" ? "checking" : status,
|
|
4181
|
+
);
|
|
4182
|
+
}, []);
|
|
4183
|
+
|
|
4184
|
+
// The banner goes away on click; reopening the popover re-probes, and the
|
|
4185
|
+
// banner returns only if storage is still missing.
|
|
4186
|
+
const connectVideoStorage = useCallback(() => {
|
|
4187
|
+
forgetMissingVideoStorage();
|
|
4188
|
+
openVideoStorageSetup();
|
|
4189
|
+
}, [forgetMissingVideoStorage, openVideoStorageSetup]);
|
|
4190
|
+
|
|
4191
|
+
useEffect(
|
|
4192
|
+
() =>
|
|
4193
|
+
onStorageSetupRequired(() => {
|
|
4194
|
+
setRecError(STORAGE_SETUP_HELP_TEXT);
|
|
4195
|
+
invoke("show_popover").catch(() => {});
|
|
4196
|
+
void refreshVideoStorageStatus();
|
|
4197
|
+
}),
|
|
4198
|
+
[refreshVideoStorageStatus],
|
|
4161
4199
|
);
|
|
4162
4200
|
|
|
4201
|
+
useEffect(() => {
|
|
4202
|
+
if (videoStorageStatus !== "configured") return;
|
|
4203
|
+
setRecError((message) =>
|
|
4204
|
+
isStorageSetupFailureMessage(message) ? null : message,
|
|
4205
|
+
);
|
|
4206
|
+
}, [videoStorageStatus]);
|
|
4207
|
+
|
|
4208
|
+
useEffect(() => {
|
|
4209
|
+
const onVisibilityChange = () => {
|
|
4210
|
+
if (document.hidden) forgetMissingVideoStorage();
|
|
4211
|
+
};
|
|
4212
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
4213
|
+
return () =>
|
|
4214
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
4215
|
+
}, [forgetMissingVideoStorage]);
|
|
4216
|
+
|
|
4163
4217
|
async function handleStartRecording(options?: {
|
|
4164
4218
|
resumeCapture?: RestartHandoff;
|
|
4165
4219
|
}): Promise<RecorderHandle | null> {
|
|
@@ -4877,14 +4931,14 @@ export function App({
|
|
|
4877
4931
|
delete next[key];
|
|
4878
4932
|
return next;
|
|
4879
4933
|
});
|
|
4880
|
-
void openExternal(
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
}
|
|
4887
|
-
|
|
4934
|
+
void openExternal(buildVideoStorageSetupUrl(targetServerUrl)).catch(
|
|
4935
|
+
(error) => {
|
|
4936
|
+
setRecoveryActionErrors((errors) => ({
|
|
4937
|
+
...errors,
|
|
4938
|
+
[key]: error instanceof Error ? error.message : String(error),
|
|
4939
|
+
}));
|
|
4940
|
+
},
|
|
4941
|
+
);
|
|
4888
4942
|
},
|
|
4889
4943
|
};
|
|
4890
4944
|
const pendingUploadBanner = shouldShowRecordingRecoveryBanner(
|
|
@@ -5475,9 +5529,7 @@ export function App({
|
|
|
5475
5529
|
onRetry={() => beginRecording()}
|
|
5476
5530
|
/>
|
|
5477
5531
|
) : isStorageSetupFailureMessage(recError) ? (
|
|
5478
|
-
<StorageConnectionBanner
|
|
5479
|
-
onConnect={() => openVideoStorageSetup()}
|
|
5480
|
-
/>
|
|
5532
|
+
<StorageConnectionBanner onConnect={connectVideoStorage} />
|
|
5481
5533
|
) : recError === RECORDING_SESSION_EXPIRED ? (
|
|
5482
5534
|
<SessionExpiredBanner onReconnect={() => void reconnectSession()} />
|
|
5483
5535
|
) : recError === RECORDING_SERVER_UNAVAILABLE ? (
|
|
@@ -5486,6 +5538,12 @@ export function App({
|
|
|
5486
5538
|
<div className="error-banner">{recError}</div>
|
|
5487
5539
|
)
|
|
5488
5540
|
) : null}
|
|
5541
|
+
{!recError &&
|
|
5542
|
+
localRecordingMode === "off" &&
|
|
5543
|
+
authStatus === "authed" &&
|
|
5544
|
+
videoStorageStatus === "missing" ? (
|
|
5545
|
+
<StorageConnectionBanner onConnect={connectVideoStorage} />
|
|
5546
|
+
) : null}
|
|
5489
5547
|
{cameraError && !recError ? (
|
|
5490
5548
|
cameraError === MACOS_CAPTURE_PERMISSION_MESSAGE ||
|
|
5491
5549
|
cameraError === DESKTOP_CAPTURE_PERMISSION_MESSAGE ? (
|