@agent-native/core 0.100.1 → 0.101.2
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 +73 -0
- package/corpus/core/docs/content/locales/ar-SA/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/ar-SA/template-plan.mdx +7 -0
- package/corpus/core/docs/content/locales/de-DE/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/de-DE/template-plan.mdx +7 -0
- package/corpus/core/docs/content/locales/es-ES/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/es-ES/template-plan.mdx +14 -0
- package/corpus/core/docs/content/locales/fr-FR/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/fr-FR/template-plan.mdx +7 -0
- package/corpus/core/docs/content/locales/hi-IN/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/hi-IN/template-plan.mdx +7 -0
- package/corpus/core/docs/content/locales/ja-JP/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/ja-JP/template-plan.mdx +7 -0
- package/corpus/core/docs/content/locales/ko-KR/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/ko-KR/template-plan.mdx +7 -0
- package/corpus/core/docs/content/locales/pt-BR/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/pt-BR/template-plan.mdx +14 -0
- package/corpus/core/docs/content/locales/zh-CN/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/zh-CN/template-plan.mdx +7 -0
- package/corpus/core/docs/content/locales/zh-TW/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/zh-TW/template-plan.mdx +7 -0
- package/corpus/core/docs/content/pr-visual-recap.mdx +50 -32
- package/corpus/core/docs/content/template-plan.mdx +14 -0
- package/corpus/core/docs/content/toolkit-comments-review.mdx +16 -2
- package/corpus/core/package.json +4 -1
- package/corpus/core/src/a2a/index.ts +2 -1
- package/corpus/core/src/a2a/server.ts +34 -9
- package/corpus/core/src/agent/production-agent.ts +56 -10
- package/corpus/core/src/cli/create.ts +47 -19
- package/corpus/core/src/cli/pr-visual-recap-workflow.ts +2 -3
- package/corpus/core/src/cli/recap.ts +3 -4932
- package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +6 -4
- package/corpus/core/src/cli/skills-content/visual-recap-skill.ts +7 -1
- package/corpus/core/src/client/AgentPanel.tsx +19 -17
- package/corpus/core/src/client/AssistantChat.tsx +4 -0
- package/corpus/core/src/client/analytics.ts +8 -1
- package/corpus/core/src/client/chat/markdown-renderer.tsx +54 -8
- package/corpus/core/src/client/chat/message-components.tsx +8 -2
- package/corpus/core/src/client/clipboard.ts +28 -1
- package/corpus/core/src/client/composer/PromptComposer.tsx +4 -0
- package/corpus/core/src/client/composer/TiptapComposer.tsx +30 -3
- package/corpus/core/src/client/guided-questions.tsx +4 -0
- package/corpus/core/src/client/i18n.tsx +2 -1
- package/corpus/core/src/client/index.ts +4 -0
- package/corpus/core/src/client/review/ReviewCommentComposer.tsx +108 -0
- package/corpus/core/src/client/review/ReviewThreadPanel.tsx +482 -150
- package/corpus/core/src/client/review/index.ts +8 -0
- package/corpus/core/src/client/review/use-review.ts +35 -1
- package/corpus/core/src/client/use-agent-chat-context.ts +3 -2
- package/corpus/core/src/integrations/webhook-handler.ts +4 -2
- package/corpus/core/src/review/actions/create-review-comment.ts +2 -1
- package/corpus/core/src/review/actions/get-review-feedback.ts +6 -11
- package/corpus/core/src/review/actions/list-review-comments.ts +38 -4
- package/corpus/core/src/review/actions/reply-review-comment.ts +33 -22
- package/corpus/core/src/review/actions/resolve-review-thread.ts +29 -2
- package/corpus/core/src/review/actions/send-review-thread-to-agent.ts +62 -0
- package/corpus/core/src/review/identity.ts +101 -0
- package/corpus/core/src/review/index.ts +14 -0
- package/corpus/core/src/review/store.ts +315 -8
- package/corpus/core/src/review/types.ts +4 -0
- package/corpus/core/src/secrets/crypto.ts +98 -47
- package/corpus/core/src/secrets/index.ts +2 -1
- package/corpus/core/src/secrets/schema.ts +3 -0
- package/corpus/core/src/secrets/storage.ts +164 -31
- package/corpus/core/src/server/action-discovery.ts +4 -0
- package/corpus/core/src/server/action-routes.ts +125 -4
- package/corpus/core/src/server/agent-chat/plugin-options.ts +16 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +1 -0
- package/corpus/core/src/server/index.ts +8 -0
- package/corpus/core/src/vite/action-types-plugin.ts +4 -0
- package/corpus/templates/analytics/changelog/2026-07-14-daily-dashboard-email-captures-authenticate-with-a-sessi.md +6 -0
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +156 -3
- package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +402 -142
- package/corpus/templates/assets/app/components/layout/Layout.tsx +4 -0
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +3 -1
- package/corpus/templates/assets/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/assets/app/i18n-data.ts +1 -0
- package/corpus/templates/assets/app/routes/library.tsx +187 -48
- package/corpus/templates/assets/changelog/2026-07-13-assets-keeps-the-right-chat-sidebar-closed-when-the-full-pag.md +6 -0
- package/corpus/templates/assets/changelog/2026-07-13-merged-the-candidates-panel-into-the-library-as-a-drafts-tab.md +6 -0
- package/corpus/templates/chat/app/lib/agent-page.tsx +40 -0
- package/corpus/templates/chat/app/routes/agent.tsx +5 -3
- package/corpus/templates/chat/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +6 -0
- package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +5 -0
- package/corpus/templates/clips/AGENTS.md +4 -0
- package/corpus/templates/clips/actions/get-feature-flags.ts +30 -0
- package/corpus/templates/clips/actions/lib/transcript-preview.ts +48 -0
- package/corpus/templates/clips/actions/request-transcript.ts +41 -1
- package/corpus/templates/clips/actions/view-screen.ts +5 -9
- package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
- package/corpus/templates/clips/app/components/player/video-player.tsx +39 -1
- package/corpus/templates/clips/app/hooks/use-desktop-promo.ts +6 -12
- package/corpus/templates/clips/app/hooks/use-mse-video-source.ts +146 -0
- package/corpus/templates/clips/app/lib/capture-install-options.ts +21 -0
- package/corpus/templates/clips/app/lib/fmp4.ts +271 -0
- package/corpus/templates/clips/app/lib/mse-video-loader.ts +585 -0
- package/corpus/templates/clips/app/routes/_app.dictate.tsx +0 -4
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +5 -13
- package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +2 -37
- package/corpus/templates/clips/app/routes/download.tsx +3 -2
- package/corpus/templates/clips/changelog/2026-07-10-shared-clips-now-start-playing-instantly-instead-of-showing-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-14-clips-now-distinguishes-transcript-previews-from-incomplete-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-14-desktop-app-prompts-stay-hidden-after-you-download-the-insta.md +6 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +5 -0
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +10 -0
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +2518 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +353 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +558 -67
- package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +11 -1
- package/corpus/templates/clips/desktop/src-tauri/src/remote_flags.rs +188 -0
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +1 -1
- package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +1 -0
- package/corpus/templates/clips/server/plugins/agent-chat.ts +5 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +5 -1
- package/corpus/templates/clips/shared/feature-flags.ts +41 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +3 -0
- package/corpus/templates/design/.agents/skills/design-review-feedback/SKILL.md +42 -0
- package/corpus/templates/design/AGENTS.md +6 -0
- package/corpus/templates/design/README.md +1 -0
- package/corpus/templates/design/actions/navigate.ts +4 -4
- package/corpus/templates/design/actions/view-screen.ts +116 -2
- package/corpus/templates/design/agent-native.app-skill.json +5 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +52 -59
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +13 -9
- package/corpus/templates/design/app/components/design/EditPanel.tsx +79 -11
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +78 -65
- package/corpus/templates/design/app/components/design/ReviewCommentsPanel.tsx +161 -0
- package/corpus/templates/design/app/components/design/ReviewStatusControl.tsx +96 -0
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +166 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +1 -0
- package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +1077 -0
- package/corpus/templates/design/app/components/visual-editor/index.ts +1 -0
- package/corpus/templates/design/app/components/visual-editor/review-canvas-state.ts +42 -0
- package/corpus/templates/design/app/hooks/use-design-systems.ts +2 -2
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +9 -6
- package/corpus/templates/design/app/hooks/use-question-flow.ts +7 -1
- package/corpus/templates/design/app/i18n/ar-SA.ts +56 -1
- package/corpus/templates/design/app/i18n/de-DE.ts +57 -1
- package/corpus/templates/design/app/i18n/en-US.ts +56 -1
- package/corpus/templates/design/app/i18n/es-ES.ts +56 -1
- package/corpus/templates/design/app/i18n/fr-FR.ts +57 -1
- package/corpus/templates/design/app/i18n/hi-IN.ts +56 -1
- package/corpus/templates/design/app/i18n/ja-JP.ts +56 -1
- package/corpus/templates/design/app/i18n/ko-KR.ts +56 -1
- package/corpus/templates/design/app/i18n/pt-BR.ts +57 -1
- package/corpus/templates/design/app/i18n/zh-CN.ts +56 -1
- package/corpus/templates/design/app/i18n/zh-TW.ts +51 -0
- package/corpus/templates/design/app/pages/Present.tsx +172 -14
- package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +23 -0
- package/corpus/templates/design/app/pages/design-editor/tool-state.ts +10 -0
- package/corpus/templates/design/app/pages/present-review-state.ts +18 -0
- package/corpus/templates/design/app/public-routes.ts +8 -0
- package/corpus/templates/design/app/root.tsx +7 -6
- package/corpus/templates/design/changelog/2026-07-13-dragged-design-assets-now-appear-at-the-visible-drop-locatio.md +6 -0
- package/corpus/templates/design/changelog/2026-07-13-reviewers-can-pin-comments-on-shared-designs-and-apply-verif.md +6 -0
- package/corpus/templates/design/server/plugins/agent-chat.ts +10 -0
- package/corpus/templates/design/server/plugins/auth.ts +7 -5
- package/corpus/templates/design/server/plugins/review.ts +9 -0
- package/corpus/templates/design/shared/review-anchor.ts +83 -0
- package/corpus/templates/design/shared/review-summary.ts +25 -0
- package/corpus/templates/forms/.agents/skills/form-publishing/SKILL.md +2 -0
- package/corpus/templates/forms/AGENTS.md +4 -0
- package/corpus/templates/forms/actions/create-form.ts +2 -1
- package/corpus/templates/forms/actions/update-form.ts +5 -2
- package/corpus/templates/forms/app/i18n/ar-SA.ts +3 -0
- package/corpus/templates/forms/app/i18n/de-DE.ts +3 -0
- package/corpus/templates/forms/app/i18n/en-US.ts +3 -0
- package/corpus/templates/forms/app/i18n/es-ES.ts +3 -0
- package/corpus/templates/forms/app/i18n/fr-FR.ts +3 -0
- package/corpus/templates/forms/app/i18n/hi-IN.ts +3 -0
- package/corpus/templates/forms/app/i18n/ja-JP.ts +3 -0
- package/corpus/templates/forms/app/i18n/ko-KR.ts +3 -0
- package/corpus/templates/forms/app/i18n/pt-BR.ts +3 -0
- package/corpus/templates/forms/app/i18n/zh-CN.ts +3 -0
- package/corpus/templates/forms/app/i18n/zh-TW.ts +3 -0
- package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +19 -0
- package/corpus/templates/forms/changelog/2026-07-14-fixed-the-ask-forms-loading-input-appearing-above-the-welcom.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-14-form-social-previews-now-show-the-form-title-description-and.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-14-forms-can-email-the-form-owner-when-new-responses-arrive.md +6 -0
- package/corpus/templates/forms/server/handlers/submissions.ts +17 -0
- package/corpus/templates/forms/server/lib/form-og-image.ts +64 -6
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +6 -2
- package/corpus/templates/forms/server/lib/response-email.ts +65 -0
- package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/forms/server/routes/api/forms/og/[...slug]/og.png.get.ts +184 -0
- package/corpus/templates/forms/shared/types.ts +2 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +6 -4
- package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +7 -1
- package/dist/a2a/index.d.ts +2 -1
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +1 -1
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/server.d.ts +25 -0
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +30 -6
- package/dist/a2a/server.js.map +1 -1
- package/dist/agent/production-agent.d.ts +2 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +37 -12
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/create.d.ts +5 -3
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +44 -19
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.d.ts +2 -2
- package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.js +2 -2
- package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
- package/dist/cli/recap.d.ts +3 -562
- package/dist/cli/recap.d.ts.map +1 -1
- package/dist/cli/recap.js +3 -3875
- package/dist/cli/recap.js.map +1 -1
- package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
- package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/visual-plan-skill.js +6 -4
- package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
- package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
- package/dist/cli/skills-content/visual-recap-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/visual-recap-skill.js +7 -1
- package/dist/cli/skills-content/visual-recap-skill.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +3 -3
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +2 -2
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/analytics.d.ts +5 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +3 -1
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/markdown-renderer.d.ts +1 -0
- package/dist/client/chat/markdown-renderer.d.ts.map +1 -1
- package/dist/client/chat/markdown-renderer.js +36 -1
- package/dist/client/chat/markdown-renderer.js.map +1 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +5 -2
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/clipboard.d.ts +3 -1
- package/dist/client/clipboard.d.ts.map +1 -1
- package/dist/client/clipboard.js +24 -1
- package/dist/client/clipboard.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts +2 -0
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +2 -2
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +3 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +20 -5
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/guided-questions.d.ts +3 -1
- package/dist/client/guided-questions.d.ts.map +1 -1
- package/dist/client/guided-questions.js +2 -1
- package/dist/client/guided-questions.js.map +1 -1
- package/dist/client/i18n.d.ts.map +1 -1
- package/dist/client/i18n.js +3 -1
- package/dist/client/i18n.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/review/ReviewCommentComposer.d.ts +18 -0
- package/dist/client/review/ReviewCommentComposer.d.ts.map +1 -0
- package/dist/client/review/ReviewCommentComposer.js +30 -0
- package/dist/client/review/ReviewCommentComposer.js.map +1 -0
- package/dist/client/review/ReviewThreadPanel.d.ts +28 -1
- package/dist/client/review/ReviewThreadPanel.d.ts.map +1 -1
- package/dist/client/review/ReviewThreadPanel.js +151 -39
- package/dist/client/review/ReviewThreadPanel.js.map +1 -1
- package/dist/client/review/index.d.ts +3 -2
- package/dist/client/review/index.d.ts.map +1 -1
- package/dist/client/review/index.js +2 -1
- package/dist/client/review/index.js.map +1 -1
- package/dist/client/review/use-review.d.ts +23 -0
- package/dist/client/review/use-review.d.ts.map +1 -1
- package/dist/client/review/use-review.js +3 -0
- package/dist/client/review/use-review.js.map +1 -1
- package/dist/client/use-agent-chat-context.d.ts +1 -1
- package/dist/client/use-agent-chat-context.d.ts.map +1 -1
- package/dist/client/use-agent-chat-context.js +4 -2
- package/dist/client/use-agent-chat-context.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +3 -2
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/review/actions/create-review-comment.js +2 -1
- package/dist/review/actions/create-review-comment.js.map +1 -1
- package/dist/review/actions/get-review-feedback.js +6 -11
- package/dist/review/actions/get-review-feedback.js.map +1 -1
- package/dist/review/actions/list-review-comments.d.ts +1 -0
- package/dist/review/actions/list-review-comments.js +25 -4
- package/dist/review/actions/list-review-comments.js.map +1 -1
- package/dist/review/actions/reply-review-comment.js +12 -5
- package/dist/review/actions/reply-review-comment.js.map +1 -1
- package/dist/review/actions/resolve-review-thread.d.ts +3 -0
- package/dist/review/actions/resolve-review-thread.js +20 -3
- package/dist/review/actions/resolve-review-thread.js.map +1 -1
- package/dist/review/actions/send-review-thread-to-agent.d.ts +17 -0
- package/dist/review/actions/send-review-thread-to-agent.d.ts.map +1 -0
- package/dist/review/actions/send-review-thread-to-agent.js +49 -0
- package/dist/review/actions/send-review-thread-to-agent.js.map +1 -0
- package/dist/review/identity.d.ts +6 -0
- package/dist/review/identity.d.ts.map +1 -0
- package/dist/review/identity.js +68 -0
- package/dist/review/identity.js.map +1 -0
- package/dist/review/index.d.ts +3 -1
- package/dist/review/index.d.ts.map +1 -1
- package/dist/review/index.js +2 -1
- package/dist/review/index.js.map +1 -1
- package/dist/review/store.d.ts +36 -0
- package/dist/review/store.d.ts.map +1 -1
- package/dist/review/store.js +223 -8
- package/dist/review/store.js.map +1 -1
- package/dist/review/types.d.ts +4 -0
- package/dist/review/types.d.ts.map +1 -1
- package/dist/review/types.js.map +1 -1
- package/dist/secrets/crypto.d.ts +35 -13
- package/dist/secrets/crypto.d.ts.map +1 -1
- package/dist/secrets/crypto.js +78 -41
- package/dist/secrets/crypto.js.map +1 -1
- package/dist/secrets/index.d.ts.map +1 -1
- package/dist/secrets/index.js +2 -1
- package/dist/secrets/index.js.map +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/secrets/schema.d.ts +20 -1
- package/dist/secrets/schema.d.ts.map +1 -1
- package/dist/secrets/schema.js +3 -0
- package/dist/secrets/schema.js.map +1 -1
- package/dist/secrets/storage.d.ts +7 -7
- package/dist/secrets/storage.d.ts.map +1 -1
- package/dist/secrets/storage.js +121 -30
- package/dist/secrets/storage.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +4 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts +45 -0
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +71 -5
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat/plugin-options.d.ts +16 -0
- package/dist/server/agent-chat/plugin-options.d.ts.map +1 -1
- package/dist/server/agent-chat/plugin-options.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +1 -0
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/index.d.ts +3 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -0
- package/dist/server/index.js.map +1 -1
- package/dist/vite/action-types-plugin.d.ts.map +1 -1
- package/dist/vite/action-types-plugin.js +4 -0
- package/dist/vite/action-types-plugin.js.map +1 -1
- package/docs/content/locales/ar-SA/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/ar-SA/template-plan.mdx +7 -0
- package/docs/content/locales/de-DE/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/de-DE/template-plan.mdx +7 -0
- package/docs/content/locales/es-ES/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/es-ES/template-plan.mdx +14 -0
- package/docs/content/locales/fr-FR/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/fr-FR/template-plan.mdx +7 -0
- package/docs/content/locales/hi-IN/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/hi-IN/template-plan.mdx +7 -0
- package/docs/content/locales/ja-JP/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/ja-JP/template-plan.mdx +7 -0
- package/docs/content/locales/ko-KR/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/ko-KR/template-plan.mdx +7 -0
- package/docs/content/locales/pt-BR/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/pt-BR/template-plan.mdx +14 -0
- package/docs/content/locales/zh-CN/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/zh-CN/template-plan.mdx +7 -0
- package/docs/content/locales/zh-TW/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/zh-TW/template-plan.mdx +7 -0
- package/docs/content/pr-visual-recap.mdx +50 -32
- package/docs/content/template-plan.mdx +14 -0
- package/docs/content/toolkit-comments-review.mdx +16 -2
- package/package.json +4 -1
- package/corpus/templates/forms/server/routes/api/forms/og/[slug]/og.png.get.ts +0 -45
|
@@ -49,6 +49,12 @@ const PILL_LABEL: &str = "recording-pill";
|
|
|
49
49
|
/// it through every command.
|
|
50
50
|
static PILL_DETACHED: AtomicBool = AtomicBool::new(false);
|
|
51
51
|
static PILL_RIGHT_SIDE: AtomicBool = AtomicBool::new(false);
|
|
52
|
+
/// Mirrors the renderer's `expanded` React state so a re-show of an already
|
|
53
|
+
/// open pill (e.g. after the tray icon toggles the popover) resizes the
|
|
54
|
+
/// native window to match what's actually rendered instead of snapping it
|
|
55
|
+
/// back to the collapsed size while the webview still renders the expanded
|
|
56
|
+
/// layout.
|
|
57
|
+
static PILL_EXPANDED: AtomicBool = AtomicBool::new(false);
|
|
52
58
|
|
|
53
59
|
/// Hover-tracking loop control. macOS only feeds mouse-moved / hover events to
|
|
54
60
|
/// the *key* window, so the background pill's CSS `:hover` never fires while
|
|
@@ -360,7 +366,8 @@ pub async fn recording_pill_show(
|
|
|
360
366
|
(Some(p), Some(s)) => Some((p.x, p.y, s.width, s.height)),
|
|
361
367
|
_ => None,
|
|
362
368
|
};
|
|
363
|
-
let
|
|
369
|
+
let expanded = PILL_EXPANDED.load(Ordering::Relaxed);
|
|
370
|
+
let (w, h, x, y) = anchored_rect(&app, expanded, previous);
|
|
364
371
|
let _ = existing.set_size(tauri::Size::Physical(PhysicalSize::new(w, h)));
|
|
365
372
|
let _ = existing.set_position(PhysicalPosition::new(x, y));
|
|
366
373
|
use tauri::Emitter;
|
|
@@ -377,6 +384,7 @@ pub async fn recording_pill_show(
|
|
|
377
384
|
return Ok(());
|
|
378
385
|
}
|
|
379
386
|
|
|
387
|
+
PILL_EXPANDED.store(false, Ordering::SeqCst);
|
|
380
388
|
let (w, h, x, y) = anchored_rect(&app, false, None);
|
|
381
389
|
|
|
382
390
|
let url = build_overlay_url("recording-pill");
|
|
@@ -465,6 +473,7 @@ fn stop_pill_hover_tracking() {
|
|
|
465
473
|
|
|
466
474
|
#[tauri::command]
|
|
467
475
|
pub async fn recording_pill_expand(app: AppHandle, expanded: bool) -> Result<(), String> {
|
|
476
|
+
PILL_EXPANDED.store(expanded, Ordering::SeqCst);
|
|
468
477
|
let Some(window) = app.get_webview_window(PILL_LABEL) else {
|
|
469
478
|
return Ok(());
|
|
470
479
|
};
|
|
@@ -534,6 +543,7 @@ pub async fn recording_pill_set_detached(app: AppHandle, detached: bool) -> Resu
|
|
|
534
543
|
// by the time we hit `anchored_rect` below, the new flag has
|
|
535
544
|
// already taken effect and we get the right size + position for
|
|
536
545
|
// the destination mode. (The atomic was flipped above.)
|
|
546
|
+
PILL_EXPANDED.store(false, Ordering::SeqCst);
|
|
537
547
|
let (w, h, x, y) = anchored_rect(&app, false, None);
|
|
538
548
|
let _ = window.set_size(tauri::Size::Physical(PhysicalSize::new(w, h)));
|
|
539
549
|
let _ = window.set_position(PhysicalPosition::new(x, y));
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
//! Server-controlled feature flags for the desktop capture pipeline
|
|
2
|
+
//! (`useCustomSCKPipeline`, `customSCKPipelineLiveUploadEnabled`) — flipping
|
|
3
|
+
//! either requires no desktop rebuild. This module fetches the flags from the
|
|
4
|
+
//! backend's `get-feature-flags` action and caches them in memory so
|
|
5
|
+
//! backend-selection stays a synchronous, zero-latency read.
|
|
6
|
+
//!
|
|
7
|
+
//! `spawn_watcher` runs its own periodic poll (independent of the meetings
|
|
8
|
+
//! watcher's tick, though it reuses the same session credentials via
|
|
9
|
+
//! `MeetingsWatcherState::session_snapshot()` rather than tracking its own);
|
|
10
|
+
//! recording start also kicks off a best-effort (non-blocking) refresh so the
|
|
11
|
+
//! cache stays warm without ever delaying a recording start. A fetch failure
|
|
12
|
+
//! (offline, no session yet, 401) just leaves the last-known-good value in
|
|
13
|
+
//! place — the cache never resets to defaults once a real value has been
|
|
14
|
+
//! fetched.
|
|
15
|
+
|
|
16
|
+
use std::sync::{Mutex, OnceLock};
|
|
17
|
+
use std::time::Duration;
|
|
18
|
+
|
|
19
|
+
use serde::Deserialize;
|
|
20
|
+
use tauri::{AppHandle, Manager};
|
|
21
|
+
|
|
22
|
+
use crate::meetings_watcher::MeetingsWatcherState;
|
|
23
|
+
|
|
24
|
+
/// How often the background watcher polls `get-feature-flags` once it has
|
|
25
|
+
/// fetched successfully at least once.
|
|
26
|
+
const REMOTE_FLAGS_POLL_SECS: u64 = 60;
|
|
27
|
+
/// How often it retries before the first successful fetch (e.g. while
|
|
28
|
+
/// waiting for the renderer to push session credentials after app launch).
|
|
29
|
+
const REMOTE_FLAGS_FAST_POLL_SECS: u64 = 5;
|
|
30
|
+
|
|
31
|
+
fn default_false() -> bool {
|
|
32
|
+
false
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Explicit `rename`s (not `rename_all = "camelCase"`) because serde's
|
|
36
|
+
// case conversion would turn `sck` into `Sck`, not `SCK` — these must match
|
|
37
|
+
// the JSON keys from the `get-feature-flags` action exactly.
|
|
38
|
+
#[derive(Debug, Clone, Copy, Deserialize)]
|
|
39
|
+
pub(crate) struct RemoteFeatureFlags {
|
|
40
|
+
#[serde(rename = "useCustomSCKPipeline", default = "default_false")]
|
|
41
|
+
pub(crate) use_custom_sck_pipeline: bool,
|
|
42
|
+
#[serde(
|
|
43
|
+
rename = "customSCKPipelineLiveUploadEnabled",
|
|
44
|
+
default = "default_false"
|
|
45
|
+
)]
|
|
46
|
+
pub(crate) custom_sck_pipeline_live_upload_enabled: bool,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
impl Default for RemoteFeatureFlags {
|
|
50
|
+
fn default() -> Self {
|
|
51
|
+
Self {
|
|
52
|
+
use_custom_sck_pipeline: false,
|
|
53
|
+
custom_sck_pipeline_live_upload_enabled: false,
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
fn cache() -> &'static Mutex<RemoteFeatureFlags> {
|
|
59
|
+
static CACHE: OnceLock<Mutex<RemoteFeatureFlags>> = OnceLock::new();
|
|
60
|
+
CACHE.get_or_init(|| Mutex::new(RemoteFeatureFlags::default()))
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/// Last-known-good flags. Synchronous — safe to call from the non-async
|
|
64
|
+
/// backend-selection code paths that choose the capture pipeline.
|
|
65
|
+
pub(crate) fn current() -> RemoteFeatureFlags {
|
|
66
|
+
*cache().lock().unwrap_or_else(|e| e.into_inner())
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/// Fetch `get-feature-flags` from the backend and update the in-memory cache
|
|
70
|
+
/// on success. Best-effort: any failure just leaves the cache untouched.
|
|
71
|
+
pub(crate) async fn refresh(
|
|
72
|
+
client: &reqwest::Client,
|
|
73
|
+
server_url: &str,
|
|
74
|
+
cookie: Option<&str>,
|
|
75
|
+
auth_token: Option<&str>,
|
|
76
|
+
) -> Result<(), String> {
|
|
77
|
+
let url = format!("{server_url}/_agent-native/actions/get-feature-flags");
|
|
78
|
+
let mut req = client.get(&url).header("X-Request-Source", "clips-desktop");
|
|
79
|
+
if let Some(c) = cookie {
|
|
80
|
+
req = req.header("Cookie", c);
|
|
81
|
+
}
|
|
82
|
+
if let Some(token) = auth_token {
|
|
83
|
+
req = req.bearer_auth(token);
|
|
84
|
+
}
|
|
85
|
+
let resp = req
|
|
86
|
+
.send()
|
|
87
|
+
.await
|
|
88
|
+
.map_err(|e| format!("fetch feature flags: {e}"))?;
|
|
89
|
+
if !resp.status().is_success() {
|
|
90
|
+
return Err(format!("fetch feature flags: HTTP {}", resp.status()));
|
|
91
|
+
}
|
|
92
|
+
let flags: RemoteFeatureFlags = resp
|
|
93
|
+
.json()
|
|
94
|
+
.await
|
|
95
|
+
.map_err(|e| format!("parse feature flags: {e}"))?;
|
|
96
|
+
*cache().lock().unwrap_or_else(|e| e.into_inner()) = flags;
|
|
97
|
+
Ok(())
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/// Fire a best-effort refresh in the background without blocking the caller
|
|
101
|
+
/// (e.g. recording start). No-ops silently without a server URL.
|
|
102
|
+
pub(crate) fn spawn_refresh(
|
|
103
|
+
server_url: Option<String>,
|
|
104
|
+
cookie: Option<String>,
|
|
105
|
+
auth_token: Option<String>,
|
|
106
|
+
) {
|
|
107
|
+
let Some(server_url) = server_url.filter(|s| !s.trim().is_empty()) else {
|
|
108
|
+
return;
|
|
109
|
+
};
|
|
110
|
+
tauri::async_runtime::spawn(async move {
|
|
111
|
+
let client = match reqwest::Client::builder()
|
|
112
|
+
.timeout(Duration::from_secs(5))
|
|
113
|
+
.build()
|
|
114
|
+
{
|
|
115
|
+
Ok(c) => c,
|
|
116
|
+
Err(err) => {
|
|
117
|
+
eprintln!("[feature-flags] reqwest build failed: {err}");
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
if let Err(err) = refresh(
|
|
122
|
+
&client,
|
|
123
|
+
&server_url,
|
|
124
|
+
cookie.as_deref(),
|
|
125
|
+
auth_token.as_deref(),
|
|
126
|
+
)
|
|
127
|
+
.await
|
|
128
|
+
{
|
|
129
|
+
eprintln!("[feature-flags] refresh failed: {err}");
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/// Spawn the long-running feature-flags poller. Idempotent — gated on a
|
|
135
|
+
/// static `OnceLock` so a double-call from setup is safe. Runs on its own
|
|
136
|
+
/// loop, entirely separate from the meetings watcher's tick; it only reads
|
|
137
|
+
/// that watcher's already-live session credentials (server URL / cookie /
|
|
138
|
+
/// auth token) via `session_snapshot()` instead of tracking a second copy.
|
|
139
|
+
///
|
|
140
|
+
/// Starts immediately (no initial delay) and retries every
|
|
141
|
+
/// `REMOTE_FLAGS_FAST_POLL_SECS` until the first successful fetch — session
|
|
142
|
+
/// credentials aren't pushed by the renderer until sign-in completes, so this
|
|
143
|
+
/// closes that gap without the app needing to notify this loop. Once a fetch
|
|
144
|
+
/// succeeds it settles into the slower `REMOTE_FLAGS_POLL_SECS` keep-warm
|
|
145
|
+
/// cadence.
|
|
146
|
+
pub(crate) fn spawn_watcher(app: AppHandle) {
|
|
147
|
+
static STARTED: OnceLock<()> = OnceLock::new();
|
|
148
|
+
if STARTED.set(()).is_err() {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
tauri::async_runtime::spawn(async move {
|
|
152
|
+
let client = match reqwest::Client::builder()
|
|
153
|
+
.timeout(Duration::from_secs(10))
|
|
154
|
+
.build()
|
|
155
|
+
{
|
|
156
|
+
Ok(c) => c,
|
|
157
|
+
Err(err) => {
|
|
158
|
+
eprintln!("[feature-flags] request build failed: {err}");
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
let mut fetched_once = false;
|
|
163
|
+
loop {
|
|
164
|
+
if let Some(state) = app.try_state::<MeetingsWatcherState>() {
|
|
165
|
+
let snapshot = state.session_snapshot();
|
|
166
|
+
if let Some(server_url) = snapshot.server_url {
|
|
167
|
+
match refresh(
|
|
168
|
+
&client,
|
|
169
|
+
&server_url,
|
|
170
|
+
snapshot.session_cookie.as_deref(),
|
|
171
|
+
snapshot.auth_token.as_deref(),
|
|
172
|
+
)
|
|
173
|
+
.await
|
|
174
|
+
{
|
|
175
|
+
Ok(()) => fetched_once = true,
|
|
176
|
+
Err(err) => eprintln!("[feature-flags] watcher refresh failed: {err}"),
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
let wait_secs = if fetched_once {
|
|
181
|
+
REMOTE_FLAGS_POLL_SECS
|
|
182
|
+
} else {
|
|
183
|
+
REMOTE_FLAGS_FAST_POLL_SECS
|
|
184
|
+
};
|
|
185
|
+
tokio::time::sleep(Duration::from_secs(wait_secs)).await;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
@@ -480,7 +480,7 @@ mod macos {
|
|
|
480
480
|
language: Option<&str>,
|
|
481
481
|
) -> Vec<(i64, i64, String)> {
|
|
482
482
|
let mut params = FullParams::new(SamplingStrategy::Greedy { best_of: 1 });
|
|
483
|
-
params.set_n_threads(
|
|
483
|
+
params.set_n_threads(2);
|
|
484
484
|
params.set_language(language);
|
|
485
485
|
params.set_translate(false);
|
|
486
486
|
params.set_no_context(true);
|
|
@@ -46,6 +46,7 @@ export async function dispatchPostFinalizeJob(args: {
|
|
|
46
46
|
kind: PostFinalizeJobKind;
|
|
47
47
|
delayMs?: number;
|
|
48
48
|
retryAttempt?: number;
|
|
49
|
+
regenerate?: boolean;
|
|
49
50
|
}): Promise<void> {
|
|
50
51
|
const token = signScopedAgentAccessToken({
|
|
51
52
|
resourceKind: POST_FINALIZE_JOB_TOKEN_KIND,
|
|
@@ -18,6 +18,7 @@ const INITIAL_TOOL_NAMES = [
|
|
|
18
18
|
"list-recordings",
|
|
19
19
|
"search-recordings",
|
|
20
20
|
"get-recording-player-data",
|
|
21
|
+
"request-transcript",
|
|
21
22
|
"create-recording",
|
|
22
23
|
"import-loom-recording",
|
|
23
24
|
"update-recording",
|
|
@@ -38,5 +39,9 @@ export default createAgentChatPlugin({
|
|
|
38
39
|
appId: "clips",
|
|
39
40
|
actions: loadActionsFromStaticRegistry(actionsRegistry),
|
|
40
41
|
initialToolNames: INITIAL_TOOL_NAMES,
|
|
42
|
+
extraContext: async () =>
|
|
43
|
+
`<clips-transcript-guidance>
|
|
44
|
+
The transcript in view-screen is a bounded preview. When previewTruncated is true, its text is expected to end mid-sentence and is never evidence that transcription stopped early. Call get-recording-player-data before judging transcript completeness or quoting the full transcript. For a failed or pending transcript, use request-transcript with force=true. For an explicit fresh retry of an existing ready transcript, also pass regenerate=true. Agent-triggered retries are queued for the durable worker and return pending while processing.
|
|
45
|
+
</clips-transcript-guidance>`,
|
|
41
46
|
resolveOrgId: async (event) => (await getOrgContext(event)).orgId,
|
|
42
47
|
});
|
|
@@ -26,6 +26,7 @@ const bodySchema = z.object({
|
|
|
26
26
|
token: z.string().min(1),
|
|
27
27
|
delayMs: z.number().int().min(0).max(30_000).optional(),
|
|
28
28
|
retryAttempt: z.number().int().min(1).max(10).optional(),
|
|
29
|
+
regenerate: z.boolean().optional(),
|
|
29
30
|
});
|
|
30
31
|
|
|
31
32
|
export default defineEventHandler(async (event: H3Event) => {
|
|
@@ -35,7 +36,8 @@ export default defineEventHandler(async (event: H3Event) => {
|
|
|
35
36
|
return { ok: false, error: "Invalid post-finalize job" };
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
const { recordingId, kind, token, delayMs, retryAttempt } =
|
|
39
|
+
const { recordingId, kind, token, delayMs, retryAttempt, regenerate } =
|
|
40
|
+
parsed.data;
|
|
39
41
|
const verified = verifyScopedAgentAccessToken(token, {
|
|
40
42
|
resourceKind: POST_FINALIZE_JOB_TOKEN_KIND,
|
|
41
43
|
resourceId: postFinalizeJobResourceId(recordingId, kind),
|
|
@@ -81,6 +83,7 @@ export default defineEventHandler(async (event: H3Event) => {
|
|
|
81
83
|
recordingId,
|
|
82
84
|
kind,
|
|
83
85
|
retryAttempt,
|
|
86
|
+
regenerate,
|
|
84
87
|
});
|
|
85
88
|
return {
|
|
86
89
|
ok: true,
|
|
@@ -102,6 +105,7 @@ export default defineEventHandler(async (event: H3Event) => {
|
|
|
102
105
|
recordingId,
|
|
103
106
|
force: true,
|
|
104
107
|
retryAttempt,
|
|
108
|
+
regenerate,
|
|
105
109
|
});
|
|
106
110
|
return { ok: true, kind, result };
|
|
107
111
|
},
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-controlled feature flags, readable from the action surface so
|
|
3
|
+
* behavior can change without a redeploy. Stored under one global `settings`
|
|
4
|
+
* key (not per-user/org) — these gate app-wide rollout decisions, not
|
|
5
|
+
* individual preferences.
|
|
6
|
+
*
|
|
7
|
+
* Add new flags here as they're needed; `get-feature-flags` stays generic
|
|
8
|
+
* and doesn't need to change.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export const FEATURE_FLAGS_KEY = "feature-flags";
|
|
12
|
+
|
|
13
|
+
export type FeatureFlags = {
|
|
14
|
+
/**
|
|
15
|
+
* Desktop app: use the custom ScreenCaptureKit (SCK) capture pipeline
|
|
16
|
+
* (fragmented MP4 writer + live audio mixer) instead of Apple's stock
|
|
17
|
+
* `SCRecordingOutput`. See `desktop/src-tauri/src/native_screen/custom_capture.rs`.
|
|
18
|
+
*/
|
|
19
|
+
useCustomSCKPipeline?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Desktop app: stream the recording to the server in chunks while it is
|
|
22
|
+
* being recorded, instead of uploading the whole file after Stop. Only
|
|
23
|
+
* effective when `useCustomSCKPipeline` is also on. See
|
|
24
|
+
* `desktop/src-tauri/src/native_screen/live_upload.rs`.
|
|
25
|
+
*/
|
|
26
|
+
customSCKPipelineLiveUploadEnabled?: boolean;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const FEATURE_FLAG_DEFAULTS: Required<FeatureFlags> = {
|
|
30
|
+
useCustomSCKPipeline: false,
|
|
31
|
+
customSCKPipelineLiveUploadEnabled: false,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export function withFeatureFlagDefaults(
|
|
35
|
+
flags: FeatureFlags | Record<string, unknown> | null | undefined,
|
|
36
|
+
): Required<FeatureFlags> {
|
|
37
|
+
return {
|
|
38
|
+
...FEATURE_FLAG_DEFAULTS,
|
|
39
|
+
...(flags as FeatureFlags | undefined),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -661,6 +661,9 @@ regeneration is slow, expensive, and regresses unrelated parts.
|
|
|
661
661
|
|
|
662
662
|
1. **Read before you edit.** Pull the current file with `get-design-snapshot`
|
|
663
663
|
(or `get-design`) so you edit the live content, not a stale memory of it.
|
|
664
|
+
If the design has persisted review comments, fetch the open queue with
|
|
665
|
+
`get-review-feedback` and use `.agents/skills/design-review-feedback` to
|
|
666
|
+
apply and verify one anchored thread at a time.
|
|
664
667
|
2. **Prefer `edit-design` for small changes.** It applies one or more
|
|
665
668
|
search/replace blocks to a file's HTML — surgical, cheap, and it preserves
|
|
666
669
|
everything you didn't touch (Alpine state, scroll, other screens):
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-review-feedback
|
|
3
|
+
description: >-
|
|
4
|
+
Work through persisted, element-anchored review comments on shared Design
|
|
5
|
+
prototypes and close the loop with verified edits.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Design Review Feedback
|
|
9
|
+
|
|
10
|
+
Use the shared review actions for design feedback:
|
|
11
|
+
|
|
12
|
+
1. Call `view-screen` first so the active design, screen, inspector tab, and
|
|
13
|
+
review queue are current.
|
|
14
|
+
2. Call `get-review-feedback` for the open queue and work on one root thread at
|
|
15
|
+
a time. Keep the thread id, target screen id, anchor node id, and nearby
|
|
16
|
+
context together while editing.
|
|
17
|
+
3. For element-anchored feedback, prefer the stable
|
|
18
|
+
`data-agent-native-node-id` from the anchor. Use the stored percentage point
|
|
19
|
+
only as a visual fallback when the node cannot be resolved.
|
|
20
|
+
4. Read the affected file with `get-design-snapshot`, make the smallest
|
|
21
|
+
persisted edit with `edit-design` or the appropriate design action, then
|
|
22
|
+
verify the saved result with `get-design-snapshot` and a screenshot or audit
|
|
23
|
+
when the change is visual.
|
|
24
|
+
5. Resolve the thread with `resolve-review-thread` only after the edit is
|
|
25
|
+
persisted and verified, and pass `resolutionNote` with a one-line description
|
|
26
|
+
of the persisted change. If the user needs to decide something, reply with
|
|
27
|
+
`reply-review-comment` and set `resolutionTarget: "human"`; do not silently
|
|
28
|
+
resolve it.
|
|
29
|
+
6. After applying a thread, call `consume-review-feedback` for the applied
|
|
30
|
+
agent-targeted root comment so the queue does not repeatedly resurface the
|
|
31
|
+
same work.
|
|
32
|
+
|
|
33
|
+
Reviewers can leave a human-only comment or choose **Send to agent** when
|
|
34
|
+
composing. Editors can selectively route an existing open thread with
|
|
35
|
+
`send-review-thread-to-agent`; that action only changes the selected thread.
|
|
36
|
+
When a thread is sent from the Design UI, the agent chat handoff includes its
|
|
37
|
+
thread id and instructs the agent not to apply other queued feedback.
|
|
38
|
+
|
|
39
|
+
Use `create-review-comment` for agent-authored follow-up notes when a durable
|
|
40
|
+
record is more useful than a chat-only explanation. Keep review comments
|
|
41
|
+
scoped to the design resource and the target screen; never copy large HTML,
|
|
42
|
+
screenshots, or provider payloads into a comment.
|
|
@@ -33,6 +33,12 @@ patterns live in `.agents/skills/`.
|
|
|
33
33
|
tool. The action schema is the source of truth for parameters.
|
|
34
34
|
- Call `view-screen` before editing a specific design if the current design or
|
|
35
35
|
selected file is not already clear from context.
|
|
36
|
+
- For shared prototype feedback, use the persisted review actions
|
|
37
|
+
(`list-review-comments`, `get-review-feedback`, `create-review-comment`,
|
|
38
|
+
`reply-review-comment`, `resolve-review-thread`, `consume-review-feedback`,
|
|
39
|
+
`send-review-thread-to-agent`, and `set-review-status`). Work one thread at a time, prefer its stable node
|
|
40
|
+
anchor, verify saved edits before resolving, and read
|
|
41
|
+
`.agents/skills/design-review-feedback/SKILL.md` for the full loop.
|
|
36
42
|
- Generated files must be complete, standalone HTML unless the user asks for a
|
|
37
43
|
different export format. They should render in the iframe without a build step.
|
|
38
44
|
- For design generation, ground the work in a concrete audience, primary job,
|
|
@@ -18,6 +18,7 @@ prompts and visual tweak controls.
|
|
|
18
18
|
- Save and reuse design-system preferences to stay on-brand.
|
|
19
19
|
- Import existing HTML or reference material as context.
|
|
20
20
|
- Export real files: HTML, ZIP, or PDF.
|
|
21
|
+
- Share prototypes with element-anchored review comments and apply verified feedback through the agent.
|
|
21
22
|
|
|
22
23
|
## Develop locally
|
|
23
24
|
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* --view View name (list, editor, design-systems, present, settings)
|
|
19
19
|
* --designId Design ID (for editor/present views)
|
|
20
20
|
* --editorView Editor mode for designs: single or overview
|
|
21
|
-
* --inspectorTab Inspector tab for designs: design or tweaks (extensions opens Tools for compatibility)
|
|
21
|
+
* --inspectorTab Inspector tab for designs: design, comments, or tweaks (extensions opens Tools for compatibility)
|
|
22
22
|
* --leftPanel Left editor panel: file, agent, assets, import, tools, tokens, or code
|
|
23
23
|
* --fileId Screen/file id to focus in the design editor
|
|
24
24
|
* --filename Screen filename to focus in the design editor
|
|
@@ -61,7 +61,7 @@ const designLeftPanelSchema = z.enum([
|
|
|
61
61
|
|
|
62
62
|
export default defineAction({
|
|
63
63
|
description:
|
|
64
|
-
"Navigate the UI to a specific view or path. Views: list, templates, editor, design-systems, present, settings. Use --templateId with templates, --designId with editor/present views, and --designSystemId with design-systems. For designs, use editorView=overview to show the infinite screens canvas, or editorView=single with fileId/filename/screen to focus a screen. Use leftPanel=file|agent|assets|import|tools|tokens|code to focus the left rail, including Import and the wide Code workspace. Legacy inspectorTab=extensions opens Tools. Use tool to activate a design editor tool.",
|
|
64
|
+
"Navigate the UI to a specific view or path. Views: list, templates, editor, design-systems, present, settings. Use --templateId with templates, --designId with editor/present views, and --designSystemId with design-systems. For designs, use editorView=overview to show the infinite screens canvas, or editorView=single with fileId/filename/screen to focus a screen. Use inspectorTab=design|comments|tweaks to focus the inspector, or leftPanel=file|agent|assets|import|tools|tokens|code to focus the left rail, including Import and the wide Code workspace. Legacy inspectorTab=extensions opens Tools. Use tool to activate a design editor tool.",
|
|
65
65
|
schema: z
|
|
66
66
|
.object({
|
|
67
67
|
view: z
|
|
@@ -87,11 +87,11 @@ export default defineAction({
|
|
|
87
87
|
.optional()
|
|
88
88
|
.describe("Alias for editorView"),
|
|
89
89
|
inspectorTab: z
|
|
90
|
-
.enum(["design", "tweaks", "extensions"])
|
|
90
|
+
.enum(["design", "comments", "tweaks", "extensions"])
|
|
91
91
|
.optional()
|
|
92
92
|
.describe("Design editor inspector tab to focus"),
|
|
93
93
|
inspector: z
|
|
94
|
-
.enum(["design", "tweaks", "extensions"])
|
|
94
|
+
.enum(["design", "comments", "tweaks", "extensions"])
|
|
95
95
|
.optional()
|
|
96
96
|
.describe("Alias for inspectorTab"),
|
|
97
97
|
leftPanel: designLeftPanelSchema
|
|
@@ -12,6 +12,16 @@ import {
|
|
|
12
12
|
readAppState,
|
|
13
13
|
readAppStateForCurrentTab,
|
|
14
14
|
} from "@agent-native/core/application-state";
|
|
15
|
+
import {
|
|
16
|
+
getReviewStatus,
|
|
17
|
+
queryReviewComments,
|
|
18
|
+
redactPublicReviewCommentIdentity,
|
|
19
|
+
redactPublicReviewStatusIdentity,
|
|
20
|
+
shouldRedactReviewIdentity,
|
|
21
|
+
type ReviewComment,
|
|
22
|
+
type ReviewResourceContext,
|
|
23
|
+
} from "@agent-native/core/review";
|
|
24
|
+
import * as reviewRuntime from "@agent-native/core/review";
|
|
15
25
|
import { resolveAccess } from "@agent-native/core/sharing";
|
|
16
26
|
import { eq } from "drizzle-orm";
|
|
17
27
|
import { z } from "zod";
|
|
@@ -21,6 +31,22 @@ import { parseCanvasFrameGeometryById } from "../shared/canvas-frames.js";
|
|
|
21
31
|
import { getDesignTemplatePreset } from "../shared/design-template-presets.js";
|
|
22
32
|
import { designGenerationSessionKey } from "../shared/generation-session.js";
|
|
23
33
|
|
|
34
|
+
interface ReviewThreadSummary {
|
|
35
|
+
openCount: number;
|
|
36
|
+
agentQueueCount: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const getReviewThreadSummary = (
|
|
40
|
+
reviewRuntime as unknown as {
|
|
41
|
+
getReviewThreadSummary?: (input: {
|
|
42
|
+
resourceType: string;
|
|
43
|
+
resourceId: string;
|
|
44
|
+
scope: { userEmail?: string | null; orgId?: string | null };
|
|
45
|
+
bypassScope?: boolean;
|
|
46
|
+
}) => Promise<ReviewThreadSummary>;
|
|
47
|
+
}
|
|
48
|
+
).getReviewThreadSummary;
|
|
49
|
+
|
|
24
50
|
function stringProp(value: unknown, key: string): string | undefined {
|
|
25
51
|
if (!value || typeof value !== "object") return undefined;
|
|
26
52
|
const candidate = (value as Record<string, unknown>)[key];
|
|
@@ -135,12 +161,57 @@ function resolveActiveCodeFile(
|
|
|
135
161
|
};
|
|
136
162
|
}
|
|
137
163
|
|
|
164
|
+
function reviewAnchorNodeId(anchor: unknown): string | null {
|
|
165
|
+
if (!anchor || typeof anchor !== "object") return null;
|
|
166
|
+
const nodeId = (anchor as Record<string, unknown>).nodeId;
|
|
167
|
+
return typeof nodeId === "string" && nodeId.trim() ? nodeId : null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function buildReviewSummary(
|
|
171
|
+
comments: ReviewComment[],
|
|
172
|
+
status: Awaited<ReturnType<typeof getReviewStatus>>,
|
|
173
|
+
activeScreenId: string | undefined,
|
|
174
|
+
summary?: ReviewThreadSummary,
|
|
175
|
+
) {
|
|
176
|
+
const openRoots = new Map<string, ReviewComment>();
|
|
177
|
+
for (const comment of comments) {
|
|
178
|
+
if (comment.status !== "open") continue;
|
|
179
|
+
if (!comment.parentCommentId && !openRoots.has(comment.threadId)) {
|
|
180
|
+
openRoots.set(comment.threadId, comment);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const agentQueueThreads = new Set(
|
|
184
|
+
Array.from(openRoots.values())
|
|
185
|
+
.filter(
|
|
186
|
+
(comment) =>
|
|
187
|
+
comment.resolutionTarget !== "human" && !comment.consumedAt,
|
|
188
|
+
)
|
|
189
|
+
.map((comment) => comment.threadId),
|
|
190
|
+
);
|
|
191
|
+
const activeScreenThreads = Array.from(openRoots.values())
|
|
192
|
+
.filter((comment) => comment.targetId === activeScreenId)
|
|
193
|
+
.map((comment) => ({
|
|
194
|
+
id: comment.id,
|
|
195
|
+
threadId: comment.threadId,
|
|
196
|
+
body: comment.body.slice(0, 180),
|
|
197
|
+
nodeId: reviewAnchorNodeId(comment.anchor),
|
|
198
|
+
author: comment.authorName ?? comment.authorEmail ?? comment.createdBy,
|
|
199
|
+
}));
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
status: status?.status ?? "draft",
|
|
203
|
+
openCount: summary?.openCount ?? openRoots.size,
|
|
204
|
+
agentQueueCount: summary?.agentQueueCount ?? agentQueueThreads.size,
|
|
205
|
+
activeScreenThreads,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
138
209
|
export default defineAction({
|
|
139
210
|
description:
|
|
140
|
-
"See what the user is currently looking at on screen. Returns the current navigation state including which design or template is open, which view they are on (list, templates, editor, design-systems, present, settings), active/focused design screen, selected element, active inspector tab (design or tweaks), active left rail panel (file, agent, assets, import, tools, tokens, or code), active code file metadata, overview canvas state, plus any pending question overlay. Always call this first before taking any action.",
|
|
211
|
+
"See what the user is currently looking at on screen. Returns the current navigation state including which design or template is open, which view they are on (list, templates, editor, design-systems, present, settings), active/focused design screen, selected element, active inspector tab (design, comments, or tweaks), active left rail panel (file, agent, assets, import, tools, tokens, or code), active code file metadata, overview canvas state, review status and feedback queue summary, plus any pending question overlay. Always call this first before taking any action.",
|
|
141
212
|
schema: z.object({}),
|
|
142
213
|
http: false,
|
|
143
|
-
run: async () => {
|
|
214
|
+
run: async (_, ctx) => {
|
|
144
215
|
const [navigation, designSelection] = await Promise.all([
|
|
145
216
|
readAppStateForCurrentTab("navigation"),
|
|
146
217
|
readAppStateForCurrentTab("design-selection"),
|
|
@@ -233,6 +304,49 @@ export default defineAction({
|
|
|
233
304
|
activeCodeFile: resolveActiveCodeFile(files, designSelection),
|
|
234
305
|
canvasFrames: parseCanvasFrameGeometryById(data.canvasFrames),
|
|
235
306
|
};
|
|
307
|
+
const reviewContext = ctx as ReviewResourceContext | undefined;
|
|
308
|
+
const reviewScope = {
|
|
309
|
+
userEmail: reviewContext?.userEmail ?? null,
|
|
310
|
+
orgId: reviewContext?.orgId ?? null,
|
|
311
|
+
};
|
|
312
|
+
const [reviewComments, reviewStatus, reviewSummary] = await Promise.all(
|
|
313
|
+
[
|
|
314
|
+
queryReviewComments({
|
|
315
|
+
resourceType: "design",
|
|
316
|
+
resourceId: designId,
|
|
317
|
+
scope: reviewScope,
|
|
318
|
+
bypassScope: true,
|
|
319
|
+
includeResolved: false,
|
|
320
|
+
includeDeleted: false,
|
|
321
|
+
limit: 500,
|
|
322
|
+
}),
|
|
323
|
+
getReviewStatus("design", designId, reviewScope, {
|
|
324
|
+
bypassScope: true,
|
|
325
|
+
}),
|
|
326
|
+
getReviewThreadSummary
|
|
327
|
+
? getReviewThreadSummary({
|
|
328
|
+
resourceType: "design",
|
|
329
|
+
resourceId: designId,
|
|
330
|
+
scope: reviewScope,
|
|
331
|
+
bypassScope: true,
|
|
332
|
+
})
|
|
333
|
+
: Promise.resolve(undefined),
|
|
334
|
+
],
|
|
335
|
+
);
|
|
336
|
+
const redactReviewIdentity = shouldRedactReviewIdentity(reviewContext, {
|
|
337
|
+
role: access.role,
|
|
338
|
+
visibility: access.resource.visibility,
|
|
339
|
+
});
|
|
340
|
+
(screen.design as Record<string, unknown>).review = buildReviewSummary(
|
|
341
|
+
redactReviewIdentity
|
|
342
|
+
? reviewComments.map(redactPublicReviewCommentIdentity)
|
|
343
|
+
: reviewComments,
|
|
344
|
+
redactReviewIdentity
|
|
345
|
+
? redactPublicReviewStatusIdentity(reviewStatus)
|
|
346
|
+
: reviewStatus,
|
|
347
|
+
resolveActiveScreen(files, navigation, designSelection)?.id,
|
|
348
|
+
reviewSummary,
|
|
349
|
+
);
|
|
236
350
|
}
|
|
237
351
|
}
|
|
238
352
|
if (showQuestions) {
|
|
@@ -46,6 +46,11 @@
|
|
|
46
46
|
"path": ".agents/skills/visual-edit",
|
|
47
47
|
"visibility": "both",
|
|
48
48
|
"exportAs": "visual-edit"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"path": ".agents/skills/design-review-feedback",
|
|
52
|
+
"visibility": "both",
|
|
53
|
+
"exportAs": "design-review-feedback"
|
|
49
54
|
}
|
|
50
55
|
],
|
|
51
56
|
"hostAdapters": [
|