@agent-native/core 0.107.2 → 0.109.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +24 -0
- package/corpus/core/docs/content/actions.mdx +48 -0
- package/corpus/core/docs/content/locales/ar-SA/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/de-DE/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/es-ES/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/fr-FR/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/hi-IN/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/ja-JP/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/ko-KR/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/pt-BR/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/zh-CN/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/zh-TW/actions.mdx +38 -0
- package/corpus/core/package.json +5 -1
- package/corpus/core/src/a2a/client.ts +140 -17
- package/corpus/core/src/a2a/handlers.ts +60 -0
- package/corpus/core/src/a2a/index.ts +6 -1
- package/corpus/core/src/a2a/invoke.ts +68 -1
- package/corpus/core/src/a2a/server.ts +13 -1
- package/corpus/core/src/a2a/types.ts +16 -0
- package/corpus/core/src/a2a-claims.ts +52 -0
- package/corpus/core/src/action.ts +7 -2
- package/corpus/core/src/agent/production-agent.ts +10 -4
- package/corpus/core/src/audit/record.ts +6 -0
- package/corpus/core/src/client/AssistantChat.tsx +648 -603
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +31 -4
- package/corpus/core/src/client/agent-chat-adapter.ts +23 -37
- package/corpus/core/src/client/agent-sidebar-state.ts +4 -0
- package/corpus/core/src/client/analytics.ts +84 -0
- package/corpus/core/src/client/chat/message-components.tsx +94 -22
- package/corpus/core/src/client/chat/tool-call-display.tsx +170 -47
- package/corpus/core/src/client/chat/use-agent-chat-lifecycle-tracking.ts +74 -0
- package/corpus/core/src/client/chat-thread-url.ts +11 -0
- package/corpus/core/src/client/error-capture.ts +12 -0
- package/corpus/core/src/client/extensions/ExtensionSlot.tsx +37 -1
- package/corpus/core/src/client/feature-flags/FeatureFlagsPanel.tsx +519 -0
- package/corpus/core/src/client/feature-flags/helpers.ts +77 -0
- package/corpus/core/src/client/feature-flags/index.ts +13 -0
- package/corpus/core/src/client/feature-flags/types.ts +29 -0
- package/corpus/core/src/client/feature-flags/use-feature-flag.ts +26 -0
- package/corpus/core/src/client/index.ts +13 -0
- package/corpus/core/src/client/route-chunk-recovery.ts +20 -8
- package/corpus/core/src/client/session-replay.ts +31 -0
- package/corpus/core/src/extensions/actions.ts +2 -14
- package/corpus/core/src/extensions/routes.ts +1 -1
- package/corpus/core/src/extensions/store.ts +1 -1
- package/corpus/core/src/feature-flags/a2a-action-route.ts +56 -0
- package/corpus/core/src/feature-flags/actions/get-feature-flags.ts +24 -0
- package/corpus/core/src/feature-flags/actions/list-feature-flags.ts +69 -0
- package/corpus/core/src/feature-flags/actions/set-feature-flag.ts +89 -0
- package/corpus/core/src/feature-flags/index.ts +21 -0
- package/corpus/core/src/feature-flags/permissions.ts +53 -0
- package/corpus/core/src/feature-flags/plugin.ts +44 -0
- package/corpus/core/src/feature-flags/registry.ts +96 -0
- package/corpus/core/src/feature-flags/store.ts +176 -0
- package/corpus/core/src/index.ts +15 -0
- package/corpus/core/src/localization/default-messages.ts +50 -0
- package/corpus/core/src/mcp/build-server.ts +2 -2
- package/corpus/core/src/progress/actions.ts +4 -2
- package/corpus/core/src/provider-api/index.ts +205 -105
- package/corpus/core/src/scripts/call-agent.ts +137 -17
- package/corpus/core/src/server/action-discovery.ts +12 -0
- package/corpus/core/src/server/action-routes.ts +47 -5
- package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +40 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +31 -0
- package/corpus/core/src/server/index.ts +1 -0
- package/corpus/core/src/settings/org-settings.ts +13 -0
- package/corpus/core/src/settings/store.ts +57 -0
- package/corpus/core/src/styles/agent-conversation.css +7 -0
- package/corpus/core/src/templates/default/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/core/src/templates/default/AGENTS.md +1 -0
- package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/de-DE.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/en-US.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/es-ES.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +19 -0
- package/corpus/core/src/templates/headless/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +28 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/corpus/core/src/templates/workspace-core/AGENTS.md +1 -1
- package/corpus/core/src/templates/workspace-root/AGENTS.md +1 -1
- package/corpus/core/src/vite/action-types-plugin.ts +12 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +29 -10
- package/corpus/templates/analytics/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +54 -23
- package/corpus/templates/analytics/.builder/skills/apollo/SKILL.md +19 -41
- package/corpus/templates/analytics/.builder/skills/commonroom/SKILL.md +20 -35
- package/corpus/templates/analytics/.builder/skills/github/SKILL.md +23 -67
- package/corpus/templates/analytics/.builder/skills/pylon/SKILL.md +25 -43
- package/corpus/templates/analytics/AGENTS.md +37 -16
- package/corpus/templates/analytics/actions/account-deep-dive.ts +1 -0
- package/corpus/templates/analytics/actions/configure-gong-native-insights.ts +29 -0
- package/corpus/templates/analytics/actions/content-calendar-schema.ts +8 -4
- package/corpus/templates/analytics/actions/content-calendar.ts +12 -4
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +2 -1
- package/corpus/templates/analytics/actions/gong-calls.ts +113 -22
- package/corpus/templates/analytics/actions/gong-native-insights.ts +166 -0
- package/corpus/templates/analytics/actions/hubspot-deals.ts +190 -46
- package/corpus/templates/analytics/actions/list-workspace-feature-flags.ts +15 -0
- package/corpus/templates/analytics/actions/navigate.ts +2 -2
- package/corpus/templates/analytics/actions/pylon-issues.ts +123 -0
- package/corpus/templates/analytics/actions/set-workspace-feature-flag.ts +45 -0
- package/corpus/templates/analytics/actions/slack-messages.ts +179 -27
- package/corpus/templates/analytics/actions/view-screen.ts +13 -0
- package/corpus/templates/analytics/app/components/agents/FeatureFlagsFleetPanel.tsx +243 -0
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +48 -152
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +11 -3
- package/corpus/templates/analytics/app/components/ui/chart.tsx +1 -1
- package/corpus/templates/analytics/app/hooks/use-chart-tooltip-flip.ts +21 -6
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +3 -1
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +30 -0
- package/corpus/templates/analytics/app/i18n-data.ts +385 -0
- package/corpus/templates/analytics/app/pages/Agents.tsx +22 -2
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +181 -30
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +6 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +4 -3
- package/corpus/templates/analytics/changelog/2026-07-17-dashboard-editors-can-add-shared-extensions-or-opt-into-per-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-dashboard-extensions-show-a-loading-skeleton.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-errors-now-group-repeat-failures-consistently-and-keep-priva.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-gong-transcript-reviews-now-batch-bounded-call-windows-for-f.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-hubspot-deal-filters-now-run-in-hubspot-before-paging-result.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-manage-feature-flag-rollouts-across-your-organization-s-apps.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-notion-content-calendars-now-discover-the-matching-database-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-pylon-dashboard-reads-now-use-the-paginated-issue-search-api.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-slack-reads-no-longer-join-channels-and-report-pagination-coverage.md +6 -0
- package/corpus/templates/analytics/server/handlers/notion.ts +14 -3
- package/corpus/templates/analytics/server/handlers/slack.ts +182 -29
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +2 -6
- package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +6 -2
- package/corpus/templates/analytics/server/lib/db-admin-connections.ts +13 -5
- package/corpus/templates/analytics/server/lib/error-capture.ts +75 -8
- package/corpus/templates/analytics/server/lib/gong-native-policy.ts +72 -0
- package/corpus/templates/analytics/server/lib/gong.ts +54 -66
- package/corpus/templates/analytics/server/lib/hubspot.ts +40 -3
- package/corpus/templates/analytics/server/lib/notion.ts +83 -8
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +4 -0
- package/corpus/templates/analytics/server/lib/slack.ts +242 -90
- package/corpus/templates/analytics/server/lib/workspace-feature-flags.ts +347 -0
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +3 -3
- package/corpus/templates/analytics/server/routes/api/pylon/accounts.get.ts +42 -1
- package/corpus/templates/analytics/server/routes/api/pylon/issues.get.ts +71 -1
- package/corpus/templates/analytics/server/routes/api/test-connection.post.ts +44 -4
- package/corpus/templates/assets/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/brain/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/calendar/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/chat/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/clips/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/clips/app/components/library/bulk-action-toolbar.tsx +19 -1
- package/corpus/templates/clips/app/components/library/create-folder-dialog.tsx +123 -0
- package/corpus/templates/clips/app/components/library/library-grid.tsx +42 -4
- package/corpus/templates/clips/app/components/library/recording-card.tsx +30 -0
- package/corpus/templates/clips/app/entry.client.tsx +6 -1
- package/corpus/templates/clips/app/i18n/ar-SA.ts +12 -1
- package/corpus/templates/clips/app/i18n/de-DE.ts +12 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +12 -1
- package/corpus/templates/clips/app/i18n/es-ES.ts +11 -1
- package/corpus/templates/clips/app/i18n/fr-FR.ts +11 -1
- package/corpus/templates/clips/app/i18n/hi-IN.ts +10 -1
- package/corpus/templates/clips/app/i18n/ja-JP.ts +12 -1
- package/corpus/templates/clips/app/i18n/ko-KR.ts +11 -1
- package/corpus/templates/clips/app/i18n/pt-BR.ts +11 -1
- package/corpus/templates/clips/app/i18n/zh-CN.ts +11 -1
- package/corpus/templates/clips/app/i18n/zh-TW.ts +11 -1
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +72 -1
- package/corpus/templates/clips/changelog/2026-07-17-choose-which-workspace-receives-new-clips-recordings-and-des.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-create-folders-directly-from-the-move-menu.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-failed-desktop-uploads-now-offer-a-direct-way-to-reopen-clip.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +1 -1
- package/corpus/templates/clips/server/plugins/feature-flags.ts +11 -0
- package/corpus/templates/clips/shared/feature-flags.ts +30 -37
- package/corpus/templates/content/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/content/app/entry.client.tsx +6 -1
- package/corpus/templates/design/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/design/AGENTS.md +5 -3
- package/corpus/templates/design/actions/add-fusion-screens.ts +4 -6
- package/corpus/templates/design/actions/apply-fusion-edits.ts +4 -6
- package/corpus/templates/design/actions/create-fusion-app.ts +5 -4
- package/corpus/templates/design/actions/deploy-fusion-app.ts +4 -3
- package/corpus/templates/design/actions/get-fusion-deploy-status.ts +4 -6
- package/corpus/templates/design/actions/list-fusion-edits.ts +4 -3
- package/corpus/templates/design/actions/push-fusion-app.ts +4 -6
- package/corpus/templates/design/actions/queue-fusion-edit.ts +4 -3
- package/corpus/templates/design/actions/send-fusion-message.ts +4 -6
- package/corpus/templates/design/actions/sync-fusion-app.ts +4 -3
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +1 -1
- package/corpus/templates/design/app/pages/Index.tsx +8 -6
- package/corpus/templates/design/server/plugins/feature-flags.ts +5 -0
- package/corpus/templates/design/shared/full-app.ts +10 -7
- package/corpus/templates/dispatch/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/dispatch/AGENTS.md +5 -0
- package/corpus/templates/dispatch/changelog/2026-07-17-apps-page-links-to-other-available-apps.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-17-curated-template-remixes.md +6 -0
- package/corpus/templates/forms/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/macros/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/mail/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/mail/app/entry.client.tsx +6 -1
- package/corpus/templates/plan/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/slides/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +11 -7
- package/corpus/templates/slides/.env.example +0 -1
- package/corpus/templates/slides/AGENTS.md +4 -0
- package/corpus/templates/slides/DEVELOPING.md +2 -2
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +1 -1
- package/corpus/templates/slides/actions/logo-config.ts +6 -7
- package/corpus/templates/slides/actions/search-images.ts +11 -39
- package/corpus/templates/slides/actions/search-logos.ts +5 -52
- package/corpus/templates/slides/app/components/editor/ImageSearchPanel.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/LogoSearchPanel.tsx +16 -26
- package/corpus/templates/slides/app/entry.client.tsx +6 -1
- package/corpus/templates/slides/server/lib/media-search-providers.ts +216 -0
- package/corpus/templates/slides/server/register-secrets.ts +30 -0
- package/corpus/templates/tasks/.agents/skills/feature-flags/SKILL.md +169 -0
- package/dist/a2a/client.d.ts +38 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +81 -12
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +47 -0
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/index.d.ts +4 -4
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +2 -2
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/invoke.d.ts +26 -2
- package/dist/a2a/invoke.d.ts.map +1 -1
- package/dist/a2a/invoke.js +30 -1
- package/dist/a2a/invoke.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +14 -1
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/types.d.ts +12 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/a2a-claims.d.ts +10 -0
- package/dist/a2a-claims.d.ts.map +1 -0
- package/dist/a2a-claims.js +41 -0
- package/dist/a2a-claims.js.map +1 -0
- package/dist/action.d.ts +7 -2
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +5 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +5 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/audit/record.d.ts +3 -0
- package/dist/audit/record.d.ts.map +1 -1
- package/dist/audit/record.js +3 -0
- package/dist/audit/record.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +14 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +158 -136
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +27 -4
- 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 +21 -39
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-sidebar-state.d.ts +1 -0
- package/dist/client/agent-sidebar-state.d.ts.map +1 -1
- package/dist/client/agent-sidebar-state.js +4 -0
- package/dist/client/agent-sidebar-state.js.map +1 -1
- package/dist/client/analytics.d.ts +14 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +67 -0
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +8 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +62 -19
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +6 -0
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +83 -14
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts +8 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts.map +1 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.js +51 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.js.map +1 -0
- package/dist/client/chat-thread-url.d.ts +2 -0
- package/dist/client/chat-thread-url.d.ts.map +1 -0
- package/dist/client/chat-thread-url.js +12 -0
- package/dist/client/chat-thread-url.js.map +1 -0
- package/dist/client/error-capture.d.ts.map +1 -1
- package/dist/client/error-capture.js +7 -0
- package/dist/client/error-capture.js.map +1 -1
- package/dist/client/extensions/ExtensionSlot.d.ts +3 -1
- package/dist/client/extensions/ExtensionSlot.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionSlot.js +28 -3
- package/dist/client/extensions/ExtensionSlot.js.map +1 -1
- package/dist/client/feature-flags/FeatureFlagsPanel.d.ts +10 -0
- package/dist/client/feature-flags/FeatureFlagsPanel.d.ts.map +1 -0
- package/dist/client/feature-flags/FeatureFlagsPanel.js +143 -0
- package/dist/client/feature-flags/FeatureFlagsPanel.js.map +1 -0
- package/dist/client/feature-flags/helpers.d.ts +16 -0
- package/dist/client/feature-flags/helpers.d.ts.map +1 -0
- package/dist/client/feature-flags/helpers.js +50 -0
- package/dist/client/feature-flags/helpers.js.map +1 -0
- package/dist/client/feature-flags/index.d.ts +5 -0
- package/dist/client/feature-flags/index.d.ts.map +1 -0
- package/dist/client/feature-flags/index.js +4 -0
- package/dist/client/feature-flags/index.js.map +1 -0
- package/dist/client/feature-flags/types.d.ts +27 -0
- package/dist/client/feature-flags/types.d.ts.map +1 -0
- package/dist/client/feature-flags/types.js +2 -0
- package/dist/client/feature-flags/types.js.map +1 -0
- package/dist/client/feature-flags/use-feature-flag.d.ts +8 -0
- package/dist/client/feature-flags/use-feature-flag.d.ts.map +1 -0
- package/dist/client/feature-flags/use-feature-flag.js +15 -0
- package/dist/client/feature-flags/use-feature-flag.js.map +1 -0
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/route-chunk-recovery.d.ts.map +1 -1
- package/dist/client/route-chunk-recovery.js +14 -9
- package/dist/client/route-chunk-recovery.js.map +1 -1
- package/dist/client/session-replay.d.ts +15 -0
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +20 -0
- package/dist/client/session-replay.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +2 -10
- package/dist/extensions/actions.js.map +1 -1
- package/dist/extensions/routes.d.ts.map +1 -1
- package/dist/extensions/routes.js +1 -1
- package/dist/extensions/routes.js.map +1 -1
- package/dist/extensions/store.js +1 -1
- package/dist/extensions/store.js.map +1 -1
- package/dist/feature-flags/a2a-action-route.d.ts +14 -0
- package/dist/feature-flags/a2a-action-route.d.ts.map +1 -0
- package/dist/feature-flags/a2a-action-route.js +50 -0
- package/dist/feature-flags/a2a-action-route.js.map +1 -0
- package/dist/feature-flags/actions/get-feature-flags.d.ts +3 -0
- package/dist/feature-flags/actions/get-feature-flags.d.ts.map +1 -0
- package/dist/feature-flags/actions/get-feature-flags.js +18 -0
- package/dist/feature-flags/actions/get-feature-flags.js.map +1 -0
- package/dist/feature-flags/actions/list-feature-flags.d.ts +28 -0
- package/dist/feature-flags/actions/list-feature-flags.d.ts.map +1 -0
- package/dist/feature-flags/actions/list-feature-flags.js +60 -0
- package/dist/feature-flags/actions/list-feature-flags.js.map +1 -0
- package/dist/feature-flags/actions/set-feature-flag.d.ts +26 -0
- package/dist/feature-flags/actions/set-feature-flag.d.ts.map +1 -0
- package/dist/feature-flags/actions/set-feature-flag.js +78 -0
- package/dist/feature-flags/actions/set-feature-flag.js.map +1 -0
- package/dist/feature-flags/index.d.ts +5 -0
- package/dist/feature-flags/index.d.ts.map +1 -0
- package/dist/feature-flags/index.js +5 -0
- package/dist/feature-flags/index.js.map +1 -0
- package/dist/feature-flags/permissions.d.ts +13 -0
- package/dist/feature-flags/permissions.d.ts.map +1 -0
- package/dist/feature-flags/permissions.js +37 -0
- package/dist/feature-flags/permissions.js.map +1 -0
- package/dist/feature-flags/plugin.d.ts +17 -0
- package/dist/feature-flags/plugin.d.ts.map +1 -0
- package/dist/feature-flags/plugin.js +29 -0
- package/dist/feature-flags/plugin.js.map +1 -0
- package/dist/feature-flags/registry.d.ts +23 -0
- package/dist/feature-flags/registry.d.ts.map +1 -0
- package/dist/feature-flags/registry.js +59 -0
- package/dist/feature-flags/registry.js.map +1 -0
- package/dist/feature-flags/store.d.ts +31 -0
- package/dist/feature-flags/store.d.ts.map +1 -0
- package/dist/feature-flags/store.js +124 -0
- package/dist/feature-flags/store.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/localization/default-messages.d.ts +45 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +45 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp/build-server.d.ts +2 -0
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +2 -2
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/progress/actions.d.ts.map +1 -1
- package/dist/progress/actions.js +3 -2
- package/dist/progress/actions.js.map +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +91 -8
- package/dist/provider-api/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +107 -16
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +12 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts +3 -0
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +45 -5
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.d.ts +6 -0
- package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +27 -0
- package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +27 -1
- 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/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/settings/org-settings.d.ts +2 -0
- package/dist/settings/org-settings.d.ts.map +1 -1
- package/dist/settings/org-settings.js +5 -1
- package/dist/settings/org-settings.js.map +1 -1
- package/dist/settings/store.d.ts +8 -0
- package/dist/settings/store.d.ts.map +1 -1
- package/dist/settings/store.js +48 -0
- package/dist/settings/store.js.map +1 -1
- package/dist/styles/agent-conversation.css +7 -0
- package/dist/templates/chat/.agents/skills/feature-flags/SKILL.md +169 -0
- package/dist/templates/default/.agents/skills/feature-flags/SKILL.md +169 -0
- package/dist/templates/default/AGENTS.md +1 -0
- package/dist/templates/default/app/i18n/ar-SA.ts +20 -0
- package/dist/templates/default/app/i18n/de-DE.ts +20 -0
- package/dist/templates/default/app/i18n/en-US.ts +20 -0
- package/dist/templates/default/app/i18n/es-ES.ts +20 -0
- package/dist/templates/default/app/i18n/fr-FR.ts +21 -0
- package/dist/templates/default/app/i18n/hi-IN.ts +19 -0
- package/dist/templates/default/app/i18n/ja-JP.ts +20 -0
- package/dist/templates/default/app/i18n/ko-KR.ts +19 -0
- package/dist/templates/default/app/i18n/pt-BR.ts +20 -0
- package/dist/templates/default/app/i18n/zh-CN.ts +19 -0
- package/dist/templates/default/app/i18n/zh-TW.ts +19 -0
- package/dist/templates/headless/.agents/skills/feature-flags/SKILL.md +169 -0
- package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +28 -0
- package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +169 -0
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/dist/templates/workspace-core/AGENTS.md +1 -1
- package/dist/templates/workspace-root/AGENTS.md +1 -1
- package/dist/vite/action-types-plugin.d.ts.map +1 -1
- package/dist/vite/action-types-plugin.js +12 -0
- package/dist/vite/action-types-plugin.js.map +1 -1
- package/docs/content/actions.mdx +48 -0
- package/docs/content/locales/ar-SA/actions.mdx +38 -0
- package/docs/content/locales/de-DE/actions.mdx +38 -0
- package/docs/content/locales/es-ES/actions.mdx +38 -0
- package/docs/content/locales/fr-FR/actions.mdx +38 -0
- package/docs/content/locales/hi-IN/actions.mdx +38 -0
- package/docs/content/locales/ja-JP/actions.mdx +38 -0
- package/docs/content/locales/ko-KR/actions.mdx +38 -0
- package/docs/content/locales/pt-BR/actions.mdx +38 -0
- package/docs/content/locales/zh-CN/actions.mdx +38 -0
- package/docs/content/locales/zh-TW/actions.mdx +38 -0
- package/package.json +5 -1
- package/src/templates/chat/.agents/skills/feature-flags/SKILL.md +169 -0
- package/src/templates/default/.agents/skills/feature-flags/SKILL.md +169 -0
- package/src/templates/default/AGENTS.md +1 -0
- package/src/templates/default/app/i18n/ar-SA.ts +20 -0
- package/src/templates/default/app/i18n/de-DE.ts +20 -0
- package/src/templates/default/app/i18n/en-US.ts +20 -0
- package/src/templates/default/app/i18n/es-ES.ts +20 -0
- package/src/templates/default/app/i18n/fr-FR.ts +21 -0
- package/src/templates/default/app/i18n/hi-IN.ts +19 -0
- package/src/templates/default/app/i18n/ja-JP.ts +20 -0
- package/src/templates/default/app/i18n/ko-KR.ts +19 -0
- package/src/templates/default/app/i18n/pt-BR.ts +20 -0
- package/src/templates/default/app/i18n/zh-CN.ts +19 -0
- package/src/templates/default/app/i18n/zh-TW.ts +19 -0
- package/src/templates/headless/.agents/skills/feature-flags/SKILL.md +169 -0
- package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +28 -0
- package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +169 -0
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/src/templates/workspace-core/AGENTS.md +1 -1
- package/src/templates/workspace-root/AGENTS.md +1 -1
- package/corpus/templates/analytics/server/handlers/github.ts +0 -200
- package/corpus/templates/analytics/server/handlers/pylon.ts +0 -43
- package/corpus/templates/analytics/server/lib/apollo.ts +0 -167
- package/corpus/templates/analytics/server/lib/commonroom.ts +0 -149
- package/corpus/templates/analytics/server/lib/github.ts +0 -660
- package/corpus/templates/analytics/server/lib/mixpanel.ts +0 -156
- package/corpus/templates/analytics/server/lib/posthog.ts +0 -194
- package/corpus/templates/analytics/server/lib/pylon.ts +0 -109
- package/corpus/templates/analytics/server/routes/api/github/graphql.post.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/issue.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/org-prs.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/pr.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/prs.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/search.get.ts +0 -1
- package/corpus/templates/clips/actions/get-feature-flags.ts +0 -30
- package/corpus/templates/slides/actions/fetch-logos.ts +0 -90
- package/corpus/templates/slides/actions/image-search.ts +0 -64
- package/corpus/templates/slides/actions/import-github.ts +0 -182
- package/corpus/templates/slides/actions/logo-lookup.ts +0 -113
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: feature-flags
|
|
3
|
+
description: >-
|
|
4
|
+
Declare, evaluate, manage, and remove framework feature flags. Use when
|
|
5
|
+
shipping a capability gradually, targeting users or organizations, or
|
|
6
|
+
replacing a compile-time rollout switch with a production-safe runtime flag.
|
|
7
|
+
scope: dev
|
|
8
|
+
metadata:
|
|
9
|
+
internal: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Feature Flags
|
|
13
|
+
|
|
14
|
+
A feature flag is a boolean declared in app code, evaluated locally by Core,
|
|
15
|
+
and managed from the Analytics fleet control plane. Code owns whether a flag
|
|
16
|
+
exists. Runtime settings own only its rollout state.
|
|
17
|
+
|
|
18
|
+
Flags let an app deploy dormant code and turn it on in the real environment
|
|
19
|
+
without another deployment. They are not experiments: do not add variants,
|
|
20
|
+
hypotheses, conversion metrics, exposure tracking, or lifecycle states.
|
|
21
|
+
|
|
22
|
+
## When to use one
|
|
23
|
+
|
|
24
|
+
Use a flag for a reversible rollout of a user-facing capability whose dormant
|
|
25
|
+
code is safe to deploy. Flags are useful for production dogfooding, exact-user
|
|
26
|
+
or organization pilots, and deterministic percentage rollouts.
|
|
27
|
+
|
|
28
|
+
Do not use a flag for authentication, authorization, secrets, audit enablement,
|
|
29
|
+
SSR cache behavior, or another security boundary. Client hiding is presentation
|
|
30
|
+
only; every guarded server action must evaluate the same registered flag.
|
|
31
|
+
|
|
32
|
+
## Agent workflow
|
|
33
|
+
|
|
34
|
+
### 1. Declare
|
|
35
|
+
|
|
36
|
+
Keep definitions in a shared TypeScript module so server and client code use the
|
|
37
|
+
same stable key. Flags are boolean and default-off.
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { defineFeatureFlag } from "@agent-native/core/feature-flags";
|
|
41
|
+
|
|
42
|
+
export const FULL_APP_BUILDING = defineFeatureFlag({
|
|
43
|
+
key: "full-app-building",
|
|
44
|
+
displayName: "Full app building",
|
|
45
|
+
description: "Create and edit Fusion-backed applications.",
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Keys are immutable, never reused, and contain only letters, numbers, dots,
|
|
50
|
+
underscores, or hyphens. Prefer a concise app-owned name. Do not create flag
|
|
51
|
+
definitions or rollout rows from Analytics.
|
|
52
|
+
|
|
53
|
+
### 2. Register
|
|
54
|
+
|
|
55
|
+
Register app definitions from a Nitro plugin before actions are discovered.
|
|
56
|
+
Do not add app-specific flags to a Core registry.
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { createFeatureFlagsPlugin } from "@agent-native/core/server";
|
|
60
|
+
|
|
61
|
+
import { FULL_APP_BUILDING } from "../../shared/feature-flags.js";
|
|
62
|
+
|
|
63
|
+
export default createFeatureFlagsPlugin({ flags: [FULL_APP_BUILDING] });
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 3. Guard server and client
|
|
67
|
+
|
|
68
|
+
The server action is the enforcement boundary:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
import { isFeatureFlagEnabled } from "@agent-native/core/feature-flags";
|
|
72
|
+
|
|
73
|
+
run: async (args, ctx) => {
|
|
74
|
+
if (!(await isFeatureFlagEnabled(FULL_APP_BUILDING, ctx))) {
|
|
75
|
+
throw new Error("Full app building is not enabled for this account.");
|
|
76
|
+
}
|
|
77
|
+
// guarded operation
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Use the client hook only to hide or reveal hydrated UI:
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import { useFeatureFlag } from "@agent-native/core/client";
|
|
85
|
+
|
|
86
|
+
const enabled = useFeatureFlag(FULL_APP_BUILDING.key);
|
|
87
|
+
return enabled ? <FullAppOption /> : null;
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The client hook intentionally returns false while loading or for an unknown
|
|
91
|
+
flag. Never replace that fail-closed behavior with app-local bucketing or a
|
|
92
|
+
compile-time fallback. Never evaluate personalized flags in the public SSR
|
|
93
|
+
shell; it is shared and cached for every visitor.
|
|
94
|
+
|
|
95
|
+
### 4. Verify and roll out
|
|
96
|
+
|
|
97
|
+
1. Verify the off path before changing rollout state.
|
|
98
|
+
2. Confirm the registered flag appears in **Analytics → Feature flags** for the
|
|
99
|
+
app and is Off by default.
|
|
100
|
+
3. Use **Enable for me** for initial production dogfood.
|
|
101
|
+
4. Expand to exact emails, organization IDs, or a percentage only from
|
|
102
|
+
Analytics.
|
|
103
|
+
5. Confirm the client presentation and authoritative server action agree.
|
|
104
|
+
|
|
105
|
+
## Management contract
|
|
106
|
+
|
|
107
|
+
Core mounts three actions in registered apps:
|
|
108
|
+
|
|
109
|
+
| Action | Purpose |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| `get-feature-flags` | Return the current caller's evaluated boolean values. |
|
|
112
|
+
| `list-feature-flags` | Return definitions and rollout metadata to an authorized operator. |
|
|
113
|
+
| `set-feature-flag` | Atomically turn a flag off, enable it for the operator, or replace targeting rules. |
|
|
114
|
+
|
|
115
|
+
Analytics calls the app-local operator actions through narrowly scoped A2A
|
|
116
|
+
delegation. Tokens require an exact audience, organization, scope, operator
|
|
117
|
+
role, and audit correlation id. Management is permission-checked and audited
|
|
118
|
+
by the target app. Never manage flags through generic settings routes, raw SQL,
|
|
119
|
+
or per-app toggle UIs.
|
|
120
|
+
|
|
121
|
+
## Rollout semantics
|
|
122
|
+
|
|
123
|
+
The operator modes are **Off**, **Targeted**, and **Everyone**. Core stores them
|
|
124
|
+
as `off`, `rules`, and `on`.
|
|
125
|
+
|
|
126
|
+
Targeted rules combine exact normalized emails, exact organization IDs, and a
|
|
127
|
+
percentage with OR semantics. Exact matches are checked first. Percentage
|
|
128
|
+
buckets use Core's stable hash of the flag key and authenticated user identity;
|
|
129
|
+
anonymous callers fail closed. Raising a percentage preserves the users already
|
|
130
|
+
included at a lower percentage. Do not implement bucketing in app code.
|
|
131
|
+
|
|
132
|
+
Unknown definitions, missing state, malformed state, storage errors, and
|
|
133
|
+
evaluation errors all return the code default (`false` in v1). Explicit Off
|
|
134
|
+
wins over every target; Everyone enables every authenticated caller.
|
|
135
|
+
|
|
136
|
+
## Remove a flag
|
|
137
|
+
|
|
138
|
+
After a rollout is permanent:
|
|
139
|
+
|
|
140
|
+
1. Replace guarded branches with the chosen behavior.
|
|
141
|
+
2. Delete the server and client gates.
|
|
142
|
+
3. Delete the definition and registration entry.
|
|
143
|
+
4. Verify the flag disappears from the Analytics fleet.
|
|
144
|
+
5. Remove stale tests and rollout instructions.
|
|
145
|
+
|
|
146
|
+
A permanent flag is just an if statement with a pension plan.
|
|
147
|
+
|
|
148
|
+
## Verification checklist
|
|
149
|
+
|
|
150
|
+
- Unknown and unregistered keys evaluate false.
|
|
151
|
+
- UI hiding and server enforcement use the same registered key.
|
|
152
|
+
- Exact-user, organization, deterministic percentage, Everyone, and Off paths
|
|
153
|
+
have focused tests.
|
|
154
|
+
- Increasing a percentage is monotonic; anonymous percentage evaluation is off.
|
|
155
|
+
- Unauthorized callers cannot list targeting details or mutate flags.
|
|
156
|
+
- Mutations are atomic, read back stored state, emit refresh, and appear in the
|
|
157
|
+
audit log with the flag key.
|
|
158
|
+
- Analytics represents ready, no-definition, unsupported, forbidden, legacy,
|
|
159
|
+
and unreachable directory apps honestly.
|
|
160
|
+
- Future agents can find this skill from root `AGENTS.md`, and
|
|
161
|
+
`pnpm guard:workspace-skills` passes after syncing generated copies.
|
|
162
|
+
|
|
163
|
+
## Related skills
|
|
164
|
+
|
|
165
|
+
- **adding-a-feature** — preserve UI/action/instruction/application-state parity
|
|
166
|
+
- **actions** — define and call guarded app operations
|
|
167
|
+
- **audit-log** — inspect automatic action mutation history
|
|
168
|
+
- **reliable-mutations** — make rollout changes atomic and provable
|
|
169
|
+
- **security** — keep security controls out of feature flags
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { useT } from "@agent-native/core/client";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
IconArchive,
|
|
4
|
+
IconFolder,
|
|
5
|
+
IconFolderPlus,
|
|
6
|
+
IconTrash,
|
|
7
|
+
IconX,
|
|
8
|
+
} from "@tabler/icons-react";
|
|
3
9
|
|
|
4
10
|
import { Button } from "@/components/ui/button";
|
|
5
11
|
import {
|
|
@@ -27,6 +33,7 @@ interface BulkActionToolbarProps {
|
|
|
27
33
|
onClear?: () => void;
|
|
28
34
|
moveTargets?: BulkMoveTarget[];
|
|
29
35
|
isPending?: boolean;
|
|
36
|
+
onCreateFolder?: () => void;
|
|
30
37
|
}
|
|
31
38
|
|
|
32
39
|
export function BulkActionToolbar({
|
|
@@ -37,6 +44,7 @@ export function BulkActionToolbar({
|
|
|
37
44
|
onClear,
|
|
38
45
|
moveTargets = [],
|
|
39
46
|
isPending = false,
|
|
47
|
+
onCreateFolder,
|
|
40
48
|
}: BulkActionToolbarProps) {
|
|
41
49
|
const t = useT();
|
|
42
50
|
if (count === 0) return null;
|
|
@@ -78,6 +86,16 @@ export function BulkActionToolbar({
|
|
|
78
86
|
{t("clipsFinalRaw.moveSelected", { count })}
|
|
79
87
|
</DropdownMenuLabel>
|
|
80
88
|
<DropdownMenuSeparator />
|
|
89
|
+
<DropdownMenuItem
|
|
90
|
+
disabled={isPending}
|
|
91
|
+
onSelect={() => {
|
|
92
|
+
setTimeout(() => onCreateFolder?.(), 0);
|
|
93
|
+
}}
|
|
94
|
+
>
|
|
95
|
+
<IconFolderPlus className="h-4 w-4 me-2" />
|
|
96
|
+
{t("navigation.newFolder")}
|
|
97
|
+
</DropdownMenuItem>
|
|
98
|
+
<DropdownMenuSeparator />
|
|
81
99
|
{moveTargets.map((target, index) => (
|
|
82
100
|
<DropdownMenuItem
|
|
83
101
|
key={target.id ?? `root-${index}`}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { useT } from "@agent-native/core/client";
|
|
2
|
+
import { IconLoader2 } from "@tabler/icons-react";
|
|
3
|
+
import { FormEvent, useState } from "react";
|
|
4
|
+
import { toast } from "sonner";
|
|
5
|
+
|
|
6
|
+
import { Button } from "@/components/ui/button";
|
|
7
|
+
import {
|
|
8
|
+
Dialog,
|
|
9
|
+
DialogContent,
|
|
10
|
+
DialogDescription,
|
|
11
|
+
DialogFooter,
|
|
12
|
+
DialogHeader,
|
|
13
|
+
DialogTitle,
|
|
14
|
+
} from "@/components/ui/dialog";
|
|
15
|
+
import { Input } from "@/components/ui/input";
|
|
16
|
+
import { Label } from "@/components/ui/label";
|
|
17
|
+
import { useCreateFolder } from "@/hooks/use-library";
|
|
18
|
+
|
|
19
|
+
interface CreatedFolder {
|
|
20
|
+
id: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface CreateFolderDialogProps {
|
|
24
|
+
open: boolean;
|
|
25
|
+
onOpenChange: (open: boolean) => void;
|
|
26
|
+
spaceId?: string | null;
|
|
27
|
+
parentId?: string | null;
|
|
28
|
+
onCreated?: (folder: CreatedFolder) => void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function CreateFolderDialog({
|
|
32
|
+
open,
|
|
33
|
+
onOpenChange,
|
|
34
|
+
spaceId,
|
|
35
|
+
parentId,
|
|
36
|
+
onCreated,
|
|
37
|
+
}: CreateFolderDialogProps) {
|
|
38
|
+
const t = useT();
|
|
39
|
+
const createFolder = useCreateFolder();
|
|
40
|
+
const [name, setName] = useState("");
|
|
41
|
+
|
|
42
|
+
function reset() {
|
|
43
|
+
setName("");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function handleSubmit(event: FormEvent<HTMLFormElement>) {
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
const trimmed = name.trim();
|
|
49
|
+
if (!trimmed || createFolder.isPending) return;
|
|
50
|
+
|
|
51
|
+
createFolder.mutate(
|
|
52
|
+
{
|
|
53
|
+
name: trimmed,
|
|
54
|
+
...(spaceId ? { spaceId } : {}),
|
|
55
|
+
...(parentId ? { parentId } : {}),
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
onSuccess: (folder) => {
|
|
59
|
+
toast.success(t("navigation.folderCreated"));
|
|
60
|
+
onCreated?.(folder);
|
|
61
|
+
reset();
|
|
62
|
+
onOpenChange(false);
|
|
63
|
+
},
|
|
64
|
+
onError: (err: any) => {
|
|
65
|
+
toast.error(err?.message ?? t("navigation.createFolderError"));
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<Dialog
|
|
73
|
+
open={open}
|
|
74
|
+
onOpenChange={(nextOpen) => {
|
|
75
|
+
onOpenChange(nextOpen);
|
|
76
|
+
if (!nextOpen) reset();
|
|
77
|
+
}}
|
|
78
|
+
>
|
|
79
|
+
<DialogContent className="sm:max-w-md">
|
|
80
|
+
<DialogHeader>
|
|
81
|
+
<DialogTitle>{t("navigation.newFolder")}</DialogTitle>
|
|
82
|
+
<DialogDescription className="sr-only">
|
|
83
|
+
{t("navigation.folderNamePlaceholder")}
|
|
84
|
+
</DialogDescription>
|
|
85
|
+
</DialogHeader>
|
|
86
|
+
<form onSubmit={handleSubmit} className="space-y-5">
|
|
87
|
+
<div className="space-y-1.5">
|
|
88
|
+
<Label htmlFor="new-folder-name">
|
|
89
|
+
{t("navigation.folderNamePlaceholder")}
|
|
90
|
+
</Label>
|
|
91
|
+
<Input
|
|
92
|
+
id="new-folder-name"
|
|
93
|
+
autoFocus
|
|
94
|
+
value={name}
|
|
95
|
+
onChange={(event) => setName(event.target.value)}
|
|
96
|
+
placeholder={t("navigation.folderNamePlaceholder")}
|
|
97
|
+
disabled={createFolder.isPending}
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
100
|
+
<DialogFooter>
|
|
101
|
+
<Button
|
|
102
|
+
type="button"
|
|
103
|
+
variant="outline"
|
|
104
|
+
onClick={() => onOpenChange(false)}
|
|
105
|
+
disabled={createFolder.isPending}
|
|
106
|
+
>
|
|
107
|
+
{t("common.cancel")}
|
|
108
|
+
</Button>
|
|
109
|
+
<Button
|
|
110
|
+
type="submit"
|
|
111
|
+
disabled={!name.trim() || createFolder.isPending}
|
|
112
|
+
>
|
|
113
|
+
{createFolder.isPending && (
|
|
114
|
+
<IconLoader2 className="h-4 w-4 animate-spin" />
|
|
115
|
+
)}
|
|
116
|
+
{t("common.create")}
|
|
117
|
+
</Button>
|
|
118
|
+
</DialogFooter>
|
|
119
|
+
</form>
|
|
120
|
+
</DialogContent>
|
|
121
|
+
</Dialog>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
@@ -7,6 +7,7 @@ import { IconAlertTriangle } from "@tabler/icons-react";
|
|
|
7
7
|
import { useEffect, useMemo, useState } from "react";
|
|
8
8
|
import { toast } from "sonner";
|
|
9
9
|
|
|
10
|
+
import { CreateFolderDialog } from "@/components/library/create-folder-dialog";
|
|
10
11
|
import { ShareRecordingDialog } from "@/components/player/share-dialog";
|
|
11
12
|
import { Button } from "@/components/ui/button";
|
|
12
13
|
import {
|
|
@@ -59,6 +60,10 @@ interface FolderTargetRow {
|
|
|
59
60
|
name: string;
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
type CreateFolderTarget =
|
|
64
|
+
| { kind: "single"; recording: RecordingSummary }
|
|
65
|
+
| { kind: "bulk"; recordingIds: string[] };
|
|
66
|
+
|
|
62
67
|
function buildMoveTargets(
|
|
63
68
|
folders: FolderTargetRow[],
|
|
64
69
|
currentFolderId: string | null,
|
|
@@ -102,6 +107,8 @@ export function LibraryGrid({
|
|
|
102
107
|
const [selected, setSelected] = useState<Set<string>>(new Set());
|
|
103
108
|
const selectionMode = selected.size > 0;
|
|
104
109
|
const [sharingRec, setSharingRec] = useState<RecordingSummary | null>(null);
|
|
110
|
+
const [createFolderTarget, setCreateFolderTarget] =
|
|
111
|
+
useState<CreateFolderTarget | null>(null);
|
|
105
112
|
const [isBulkPending, setIsBulkPending] = useState(false);
|
|
106
113
|
const selectionStateKey = useMemo(() => `selection:${getBrowserTabId()}`, []);
|
|
107
114
|
|
|
@@ -195,15 +202,18 @@ export function LibraryGrid({
|
|
|
195
202
|
setSelected(new Set());
|
|
196
203
|
};
|
|
197
204
|
|
|
198
|
-
const
|
|
199
|
-
|
|
205
|
+
const moveRecordings = async (
|
|
206
|
+
ids: string[],
|
|
207
|
+
targetFolderId: string | null,
|
|
208
|
+
) => {
|
|
209
|
+
if (ids.length === 0) return;
|
|
200
210
|
setIsBulkPending(true);
|
|
201
211
|
try {
|
|
202
212
|
await moveRecording.mutateAsync({
|
|
203
|
-
ids
|
|
213
|
+
ids,
|
|
204
214
|
folderId: targetFolderId,
|
|
205
215
|
});
|
|
206
|
-
toast.success(t("libraryGrid.clipsMoved", { count:
|
|
216
|
+
toast.success(t("libraryGrid.clipsMoved", { count: ids.length }));
|
|
207
217
|
clearSelection();
|
|
208
218
|
} catch (err: any) {
|
|
209
219
|
toast.error(err?.message ?? t("libraryGrid.moveFailed"));
|
|
@@ -212,6 +222,9 @@ export function LibraryGrid({
|
|
|
212
222
|
}
|
|
213
223
|
};
|
|
214
224
|
|
|
225
|
+
const moveSelected = (targetFolderId: string | null) =>
|
|
226
|
+
moveRecordings(selectedIds, targetFolderId);
|
|
227
|
+
|
|
215
228
|
const moveSingle = async (
|
|
216
229
|
rec: RecordingSummary,
|
|
217
230
|
targetFolderId: string | null,
|
|
@@ -265,6 +278,22 @@ export function LibraryGrid({
|
|
|
265
278
|
}}
|
|
266
279
|
/>
|
|
267
280
|
)}
|
|
281
|
+
<CreateFolderDialog
|
|
282
|
+
open={Boolean(createFolderTarget)}
|
|
283
|
+
onOpenChange={(open) => {
|
|
284
|
+
if (!open) setCreateFolderTarget(null);
|
|
285
|
+
}}
|
|
286
|
+
spaceId={view === "space" ? spaceId : null}
|
|
287
|
+
parentId={folderId}
|
|
288
|
+
onCreated={(folder) => {
|
|
289
|
+
if (!createFolderTarget) return;
|
|
290
|
+
if (createFolderTarget.kind === "single") {
|
|
291
|
+
void moveSingle(createFolderTarget.recording, folder.id);
|
|
292
|
+
} else {
|
|
293
|
+
void moveRecordings(createFolderTarget.recordingIds, folder.id);
|
|
294
|
+
}
|
|
295
|
+
}}
|
|
296
|
+
/>
|
|
268
297
|
|
|
269
298
|
{/* Page header — rendered into the top app bar */}
|
|
270
299
|
<PageHeader>
|
|
@@ -352,6 +381,9 @@ export function LibraryGrid({
|
|
|
352
381
|
moveTargets={moveTargets}
|
|
353
382
|
onMove={canMoveSelection ? moveSingle : undefined}
|
|
354
383
|
isMovePending={moveRecording.isPending}
|
|
384
|
+
onCreateFolder={() => {
|
|
385
|
+
setCreateFolderTarget({ kind: "single", recording: r });
|
|
386
|
+
}}
|
|
355
387
|
onTrash={
|
|
356
388
|
canManageRecordings
|
|
357
389
|
? (rec) => {
|
|
@@ -470,6 +502,12 @@ export function LibraryGrid({
|
|
|
470
502
|
}
|
|
471
503
|
}}
|
|
472
504
|
onMove={canMoveSelection ? moveSelected : undefined}
|
|
505
|
+
onCreateFolder={() => {
|
|
506
|
+
setCreateFolderTarget({
|
|
507
|
+
kind: "bulk",
|
|
508
|
+
recordingIds: selectedIds,
|
|
509
|
+
});
|
|
510
|
+
}}
|
|
473
511
|
onClear={clearSelection}
|
|
474
512
|
isPending={isBulkPending || moveRecording.isPending}
|
|
475
513
|
/>
|
|
@@ -7,10 +7,12 @@ import {
|
|
|
7
7
|
IconPlayerPlay,
|
|
8
8
|
IconShare,
|
|
9
9
|
IconFolder,
|
|
10
|
+
IconFolderPlus,
|
|
10
11
|
IconArchive,
|
|
11
12
|
IconTrash,
|
|
12
13
|
IconCheck,
|
|
13
14
|
IconAlertTriangle,
|
|
15
|
+
IconExternalLink,
|
|
14
16
|
} from "@tabler/icons-react";
|
|
15
17
|
import { useCallback, useMemo, useState } from "react";
|
|
16
18
|
import { Link } from "react-router";
|
|
@@ -31,6 +33,7 @@ import {
|
|
|
31
33
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
32
34
|
import { isDefaultTitle } from "@/hooks/use-auto-title";
|
|
33
35
|
import type { RecordingSummary } from "@/hooks/use-library";
|
|
36
|
+
import { attemptOpenDesktopApp } from "@/lib/capture-install-options";
|
|
34
37
|
import { isStaleRecordingUpload } from "@/lib/recording-status";
|
|
35
38
|
import { isStorageSetupFailureReason } from "@/lib/storage-failures";
|
|
36
39
|
import { cn } from "@/lib/utils";
|
|
@@ -67,6 +70,7 @@ interface RecordingCardProps {
|
|
|
67
70
|
onMove?: (rec: RecordingSummary, folderId: string | null) => void;
|
|
68
71
|
moveTargets?: BulkMoveTarget[];
|
|
69
72
|
isMovePending?: boolean;
|
|
73
|
+
onCreateFolder?: () => void;
|
|
70
74
|
onArchive?: (rec: RecordingSummary) => void;
|
|
71
75
|
onTrash?: (rec: RecordingSummary) => void;
|
|
72
76
|
readOnly?: boolean;
|
|
@@ -81,6 +85,7 @@ export function RecordingCard({
|
|
|
81
85
|
onMove,
|
|
82
86
|
moveTargets = [],
|
|
83
87
|
isMovePending = false,
|
|
88
|
+
onCreateFolder,
|
|
84
89
|
onArchive,
|
|
85
90
|
onTrash,
|
|
86
91
|
readOnly = false,
|
|
@@ -175,6 +180,11 @@ export function RecordingCard({
|
|
|
175
180
|
[onTrash, recording],
|
|
176
181
|
);
|
|
177
182
|
|
|
183
|
+
const handleOpenDesktopApp = useCallback((e: React.MouseEvent) => {
|
|
184
|
+
e.stopPropagation();
|
|
185
|
+
attemptOpenDesktopApp();
|
|
186
|
+
}, []);
|
|
187
|
+
|
|
178
188
|
return (
|
|
179
189
|
<div
|
|
180
190
|
role="article"
|
|
@@ -281,6 +291,16 @@ export function RecordingCard({
|
|
|
281
291
|
? t("clipsFinalRaw.retryFromClipsMenu")
|
|
282
292
|
: failureReason}
|
|
283
293
|
</div>
|
|
294
|
+
{nativeUploadPaused ? (
|
|
295
|
+
<button
|
|
296
|
+
type="button"
|
|
297
|
+
onClick={handleOpenDesktopApp}
|
|
298
|
+
className="pointer-events-auto mt-1.5 inline-flex items-center gap-1 rounded border border-border px-1.5 py-0.5 text-[10px] font-medium text-foreground hover:bg-accent"
|
|
299
|
+
>
|
|
300
|
+
<IconExternalLink className="h-3 w-3" />
|
|
301
|
+
{t("captureInstall.openDesktopApp")}
|
|
302
|
+
</button>
|
|
303
|
+
) : null}
|
|
284
304
|
</div>
|
|
285
305
|
{!waitingForStorage && onTrash && (
|
|
286
306
|
<button
|
|
@@ -365,6 +385,16 @@ export function RecordingCard({
|
|
|
365
385
|
{t("clipsFinalRaw.moveToFolder")}
|
|
366
386
|
</DropdownMenuSubTrigger>
|
|
367
387
|
<DropdownMenuSubContent className="w-64">
|
|
388
|
+
<DropdownMenuItem
|
|
389
|
+
disabled={isMovePending}
|
|
390
|
+
onSelect={() => {
|
|
391
|
+
setTimeout(() => onCreateFolder?.(), 0);
|
|
392
|
+
}}
|
|
393
|
+
>
|
|
394
|
+
<IconFolderPlus className="h-4 w-4 me-2" />
|
|
395
|
+
{t("navigation.newFolder")}
|
|
396
|
+
</DropdownMenuItem>
|
|
397
|
+
<DropdownMenuSeparator />
|
|
368
398
|
{moveTargets.map((target, index) => (
|
|
369
399
|
<DropdownMenuItem
|
|
370
400
|
key={target.id ?? `root-${index}`}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
appBasePath,
|
|
3
|
+
installRouteChunkRecovery,
|
|
4
|
+
} from "@agent-native/core/client";
|
|
2
5
|
import { hydrateRoot } from "react-dom/client";
|
|
3
6
|
import { HydratedRouter } from "react-router/dom";
|
|
4
7
|
|
|
8
|
+
installRouteChunkRecovery();
|
|
9
|
+
|
|
5
10
|
const basePath = appBasePath();
|
|
6
11
|
const pathname = window.location.pathname;
|
|
7
12
|
const routerBasePath =
|
|
@@ -623,6 +623,16 @@ const messages = {
|
|
|
623
623
|
languageDescription:
|
|
624
624
|
"اختر لغة الواجهة لهذا الحساب. سيتذكرها Clips عبر أجهزتك.",
|
|
625
625
|
languageLabel: "لغة الواجهة",
|
|
626
|
+
uploadWorkspaceTitle: "مساحة العمل النشطة",
|
|
627
|
+
uploadWorkspaceDescription:
|
|
628
|
+
"اختر مساحة العمل التي يستخدمها Clips للتسجيلات الجديدة، بما في ذلك تحميلات سطح المكتب.",
|
|
629
|
+
uploadWorkspaceLabel: "مساحة العمل الحالية",
|
|
630
|
+
uploadWorkspacePlaceholder: "اختر مساحة عمل",
|
|
631
|
+
uploadWorkspaceHint:
|
|
632
|
+
"يؤدي تغييرها أيضًا إلى تحديث عروض Clips المرتبطة بمساحة العمل.",
|
|
633
|
+
uploadWorkspaceSaving: "جارٍ حفظ مساحة العمل…",
|
|
634
|
+
uploadWorkspaceSaved: "تم تحديث مساحة العمل النشطة",
|
|
635
|
+
uploadWorkspaceSaveFailed: "تعذر تحديث مساحة العمل النشطة",
|
|
626
636
|
whatsNew: "ما الجديد",
|
|
627
637
|
changelogEmpty: "لا توجد تحديثات بعد.",
|
|
628
638
|
viewAllUpdates: "عرض كل التحديثات",
|
|
@@ -1368,7 +1378,8 @@ const messages = {
|
|
|
1368
1378
|
savedLocally: "حُفظ محليًا",
|
|
1369
1379
|
uploadFailed: "فشل الرفع",
|
|
1370
1380
|
connectStorageToFinish: "افتح للاتصال بالتخزين وإنهاء الحفظ.",
|
|
1371
|
-
retryFromClipsMenu:
|
|
1381
|
+
retryFromClipsMenu:
|
|
1382
|
+
"افتح Clips من شريط القائمة لإعادة محاولة هذا الرفع المحفوظ؛ لا حاجة لإعادة التسجيل.",
|
|
1372
1383
|
removeFailedClip: "إزالة هذا المقطع الفاشل.",
|
|
1373
1384
|
remove: "إزالة",
|
|
1374
1385
|
viewsCount: "{{count}} مشاهدة",
|
|
@@ -641,6 +641,17 @@ const messages = {
|
|
|
641
641
|
languageDescription:
|
|
642
642
|
"Wähle die Oberflächensprache für dieses Konto. Clips merkt sie sich geräteübergreifend.",
|
|
643
643
|
languageLabel: "Oberflächensprache",
|
|
644
|
+
uploadWorkspaceTitle: "Aktiver Arbeitsbereich",
|
|
645
|
+
uploadWorkspaceDescription:
|
|
646
|
+
"Wähle den Arbeitsbereich, den Clips für neue Aufnahmen einschließlich Desktop-Uploads verwendet.",
|
|
647
|
+
uploadWorkspaceLabel: "Aktueller Arbeitsbereich",
|
|
648
|
+
uploadWorkspacePlaceholder: "Arbeitsbereich auswählen",
|
|
649
|
+
uploadWorkspaceHint:
|
|
650
|
+
"Dadurch werden auch die arbeitsbereichsbezogenen Clips-Ansichten aktualisiert.",
|
|
651
|
+
uploadWorkspaceSaving: "Arbeitsbereich wird gespeichert…",
|
|
652
|
+
uploadWorkspaceSaved: "Aktiver Arbeitsbereich aktualisiert",
|
|
653
|
+
uploadWorkspaceSaveFailed:
|
|
654
|
+
"Aktiver Arbeitsbereich konnte nicht aktualisiert werden",
|
|
644
655
|
whatsNew: "Neuigkeiten",
|
|
645
656
|
changelogEmpty: "Noch keine Updates.",
|
|
646
657
|
viewAllUpdates: "Alle Updates anzeigen",
|
|
@@ -1397,7 +1408,7 @@ Alle sichtbaren Änderungen für Clips-Nutzer werden hier dokumentiert. Du kanns
|
|
|
1397
1408
|
connectStorageToFinish:
|
|
1398
1409
|
"Öffnen, um Speicher zu verbinden und das Speichern abzuschließen.",
|
|
1399
1410
|
retryFromClipsMenu:
|
|
1400
|
-
"
|
|
1411
|
+
"Öffne Clips über die Menüleiste, um diesen gespeicherten Upload erneut zu versuchen; keine neue Aufnahme nötig.",
|
|
1401
1412
|
removeFailedClip: "Diesen fehlgeschlagenen Clip entfernen.",
|
|
1402
1413
|
remove: "Entfernen",
|
|
1403
1414
|
viewsCount: "{{count}} Aufrufe",
|
|
@@ -619,6 +619,16 @@ const messages = {
|
|
|
619
619
|
languageDescription:
|
|
620
620
|
"Choose the interface language for this account. Clips remembers it across devices.",
|
|
621
621
|
languageLabel: "Interface language",
|
|
622
|
+
uploadWorkspaceTitle: "Active workspace",
|
|
623
|
+
uploadWorkspaceDescription:
|
|
624
|
+
"Choose the workspace Clips uses for new recordings, including desktop uploads.",
|
|
625
|
+
uploadWorkspaceLabel: "Current workspace",
|
|
626
|
+
uploadWorkspacePlaceholder: "Choose a workspace",
|
|
627
|
+
uploadWorkspaceHint:
|
|
628
|
+
"Switching this also updates workspace-scoped Clips views.",
|
|
629
|
+
uploadWorkspaceSaving: "Saving workspace…",
|
|
630
|
+
uploadWorkspaceSaved: "Active workspace updated",
|
|
631
|
+
uploadWorkspaceSaveFailed: "Could not update active workspace",
|
|
622
632
|
whatsNew: "What's new",
|
|
623
633
|
changelogEmpty: "No updates yet.",
|
|
624
634
|
viewAllUpdates: "View all updates",
|
|
@@ -1357,7 +1367,8 @@ All notable user-facing changes to Clips are documented here. Open it any time f
|
|
|
1357
1367
|
savedLocally: "Saved locally",
|
|
1358
1368
|
uploadFailed: "Upload failed",
|
|
1359
1369
|
connectStorageToFinish: "Open to connect storage and finish saving.",
|
|
1360
|
-
retryFromClipsMenu:
|
|
1370
|
+
retryFromClipsMenu:
|
|
1371
|
+
"Open Clips from the menu bar to retry this saved upload; no need to re-record.",
|
|
1361
1372
|
removeFailedClip: "Remove this failed clip.",
|
|
1362
1373
|
remove: "Remove",
|
|
1363
1374
|
viewsCount: "{{count}} views",
|
|
@@ -636,6 +636,16 @@ const messages = {
|
|
|
636
636
|
languageDescription:
|
|
637
637
|
"Elige el idioma de la interfaz para esta cuenta. Clips lo recordará en todos tus dispositivos.",
|
|
638
638
|
languageLabel: "Idioma de la interfaz",
|
|
639
|
+
uploadWorkspaceTitle: "Espacio activo",
|
|
640
|
+
uploadWorkspaceDescription:
|
|
641
|
+
"Elige el espacio que Clips usará para las nuevas grabaciones, incluidas las cargas desde el escritorio.",
|
|
642
|
+
uploadWorkspaceLabel: "Espacio actual",
|
|
643
|
+
uploadWorkspacePlaceholder: "Elige un espacio",
|
|
644
|
+
uploadWorkspaceHint:
|
|
645
|
+
"Al cambiarlo también se actualizan las vistas de Clips vinculadas al espacio.",
|
|
646
|
+
uploadWorkspaceSaving: "Guardando espacio…",
|
|
647
|
+
uploadWorkspaceSaved: "Espacio activo actualizado",
|
|
648
|
+
uploadWorkspaceSaveFailed: "No se pudo actualizar el espacio activo",
|
|
639
649
|
whatsNew: "Novedades",
|
|
640
650
|
changelogEmpty: "Aún no hay actualizaciones.",
|
|
641
651
|
viewAllUpdates: "Ver todas las actualizaciones",
|
|
@@ -1390,7 +1400,7 @@ Todos los cambios visibles para los usuarios de Clips se documentan aquí. Puede
|
|
|
1390
1400
|
connectStorageToFinish:
|
|
1391
1401
|
"Ábrelo para conectar almacenamiento y terminar de guardar.",
|
|
1392
1402
|
retryFromClipsMenu:
|
|
1393
|
-
"
|
|
1403
|
+
"Abre Clips desde la barra de menús para reintentar esta carga guardada; no hace falta grabar de nuevo.",
|
|
1394
1404
|
removeFailedClip: "Eliminar este clip fallido.",
|
|
1395
1405
|
remove: "Eliminar",
|
|
1396
1406
|
viewsCount: "{{count}} visualizaciones",
|
|
@@ -636,6 +636,16 @@ const messages = {
|
|
|
636
636
|
languageDescription:
|
|
637
637
|
"Choisissez la langue de l’interface pour ce compte. Clips s’en souviendra sur tous vos appareils.",
|
|
638
638
|
languageLabel: "Langue de l’interface",
|
|
639
|
+
uploadWorkspaceTitle: "Espace actif",
|
|
640
|
+
uploadWorkspaceDescription:
|
|
641
|
+
"Choisissez l’espace utilisé par Clips pour les nouveaux enregistrements, y compris ceux importés depuis le bureau.",
|
|
642
|
+
uploadWorkspaceLabel: "Espace actuel",
|
|
643
|
+
uploadWorkspacePlaceholder: "Choisir un espace",
|
|
644
|
+
uploadWorkspaceHint:
|
|
645
|
+
"Ce changement met également à jour les vues Clips liées à l’espace.",
|
|
646
|
+
uploadWorkspaceSaving: "Enregistrement de l’espace…",
|
|
647
|
+
uploadWorkspaceSaved: "Espace actif mis à jour",
|
|
648
|
+
uploadWorkspaceSaveFailed: "Impossible de mettre à jour l’espace actif",
|
|
639
649
|
whatsNew: "Nouveautés",
|
|
640
650
|
changelogEmpty: "Aucune mise à jour pour le moment.",
|
|
641
651
|
viewAllUpdates: "Voir toutes les mises à jour",
|
|
@@ -1391,7 +1401,7 @@ Tous les changements visibles par les utilisateurs de Clips sont documentés ici
|
|
|
1391
1401
|
connectStorageToFinish:
|
|
1392
1402
|
"Ouvrez pour connecter le stockage et terminer l’enregistrement.",
|
|
1393
1403
|
retryFromClipsMenu:
|
|
1394
|
-
"
|
|
1404
|
+
"Ouvrez Clips depuis la barre des menus pour réessayer cet envoi enregistré ; inutile de réenregistrer.",
|
|
1395
1405
|
removeFailedClip: "Supprimer ce clip en échec.",
|
|
1396
1406
|
remove: "Supprimer",
|
|
1397
1407
|
viewsCount: "{{count}} vues",
|