@agent-native/core 0.100.2 → 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 +65 -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/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/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/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/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/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-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/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/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/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/routes.d.ts +9 -9
- 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
|
@@ -1,3 +1,58 @@
|
|
|
1
1
|
import { messagesByLocale } from "../i18n-data";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const messages = {
|
|
4
|
+
...messagesByLocale["zh-CN"],
|
|
5
|
+
review: {
|
|
6
|
+
comments: "评论",
|
|
7
|
+
commentsTab: "评论 · {{count}}",
|
|
8
|
+
commentsTitle: "审阅评论",
|
|
9
|
+
commentNumber: "审阅评论 {{count}}",
|
|
10
|
+
thisScreen: "当前画面",
|
|
11
|
+
allScreens: "所有画面",
|
|
12
|
+
signInToComment: "登录后评论",
|
|
13
|
+
panelTitle: "反馈",
|
|
14
|
+
placeholder: "留下反馈…",
|
|
15
|
+
emptyState: "暂无审阅评论。",
|
|
16
|
+
clickToPin: "点击任意位置固定反馈",
|
|
17
|
+
escToExit: "按 Esc 退出",
|
|
18
|
+
newComment: "新评论",
|
|
19
|
+
commentMode: "评论",
|
|
20
|
+
sendToAgent: "发送给智能体",
|
|
21
|
+
sendingToAgent: "正在发送给智能体…",
|
|
22
|
+
enterToPost: "按 Enter 发布 · 按 Shift+Enter 换行",
|
|
23
|
+
post: "发布",
|
|
24
|
+
posting: "正在发布…",
|
|
25
|
+
postFailed: "无法发布此评论",
|
|
26
|
+
loading: "正在加载评论",
|
|
27
|
+
replyPlaceholder: "回复此讨论…",
|
|
28
|
+
reply: "回复",
|
|
29
|
+
cancelReply: "取消回复",
|
|
30
|
+
replyFailed: "无法发布此回复",
|
|
31
|
+
resolve: "解决",
|
|
32
|
+
resolving: "正在解决…",
|
|
33
|
+
resolveFailed: "无法解决此讨论",
|
|
34
|
+
deleteComment: "删除评论",
|
|
35
|
+
moreActions: "更多操作",
|
|
36
|
+
resolved: "已解决",
|
|
37
|
+
reviewer: "审阅者",
|
|
38
|
+
applyFeedback: "应用反馈 ({{count}})",
|
|
39
|
+
applyingFeedback: "正在应用反馈…",
|
|
40
|
+
applyFeedbackFailed: "无法应用审阅反馈",
|
|
41
|
+
sendToAgentFailed: "无法将此讨论发送给智能体",
|
|
42
|
+
shareLinkDescription:
|
|
43
|
+
"任何获得此链接的人都可以查看设计。已登录的审阅者可以发表评论。",
|
|
44
|
+
presentComments: "评论",
|
|
45
|
+
presentCommentMode: "评论模式",
|
|
46
|
+
closeComments: "关闭评论",
|
|
47
|
+
status: {
|
|
48
|
+
draft: "草稿",
|
|
49
|
+
in_review: "审阅中",
|
|
50
|
+
approved: "已批准",
|
|
51
|
+
changes_requested: "已请求更改",
|
|
52
|
+
change: "更改审阅状态",
|
|
53
|
+
saveFailed: "无法更新审阅状态",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export default messages;
|
|
@@ -43,6 +43,57 @@ const messages = {
|
|
|
43
43
|
notFoundBackToDesigns: "返回設計",
|
|
44
44
|
teamCreateOrgDescription: "設定團隊,與同事共用設計。",
|
|
45
45
|
},
|
|
46
|
+
review: {
|
|
47
|
+
comments: "評論",
|
|
48
|
+
commentsTab: "評論 · {{count}}",
|
|
49
|
+
commentsTitle: "審閱評論",
|
|
50
|
+
commentNumber: "審閱評論 {{count}}",
|
|
51
|
+
thisScreen: "目前畫面",
|
|
52
|
+
allScreens: "所有畫面",
|
|
53
|
+
signInToComment: "登入後評論",
|
|
54
|
+
panelTitle: "意見回饋",
|
|
55
|
+
placeholder: "留下意見…",
|
|
56
|
+
emptyState: "目前沒有審閱評論。",
|
|
57
|
+
clickToPin: "點選任意位置以固定意見",
|
|
58
|
+
escToExit: "按 Esc 退出",
|
|
59
|
+
newComment: "新增評論",
|
|
60
|
+
commentMode: "評論",
|
|
61
|
+
sendToAgent: "傳送給代理",
|
|
62
|
+
sendingToAgent: "正在傳送給代理…",
|
|
63
|
+
enterToPost: "按 Enter 發布 · 按 Shift+Enter 換行",
|
|
64
|
+
post: "發布",
|
|
65
|
+
posting: "正在發布…",
|
|
66
|
+
postFailed: "無法發布這則評論",
|
|
67
|
+
loading: "正在載入評論",
|
|
68
|
+
replyPlaceholder: "回覆此討論串…",
|
|
69
|
+
reply: "回覆",
|
|
70
|
+
cancelReply: "取消回覆",
|
|
71
|
+
replyFailed: "無法發布這則回覆",
|
|
72
|
+
resolve: "解決",
|
|
73
|
+
resolving: "正在解決…",
|
|
74
|
+
resolveFailed: "無法解決此討論串",
|
|
75
|
+
deleteComment: "刪除評論",
|
|
76
|
+
moreActions: "更多操作",
|
|
77
|
+
resolved: "已解決",
|
|
78
|
+
reviewer: "審閱者",
|
|
79
|
+
applyFeedback: "套用意見 ({{count}})",
|
|
80
|
+
applyingFeedback: "正在套用意見…",
|
|
81
|
+
applyFeedbackFailed: "無法套用審閱意見",
|
|
82
|
+
sendToAgentFailed: "無法將此討論串傳送給代理",
|
|
83
|
+
shareLinkDescription:
|
|
84
|
+
"任何取得此連結的人都能檢視設計。已登入的審閱者可以評論。",
|
|
85
|
+
presentComments: "評論",
|
|
86
|
+
presentCommentMode: "評論模式",
|
|
87
|
+
closeComments: "關閉評論",
|
|
88
|
+
status: {
|
|
89
|
+
draft: "草稿",
|
|
90
|
+
in_review: "審閱中",
|
|
91
|
+
approved: "已核准",
|
|
92
|
+
changes_requested: "已要求變更",
|
|
93
|
+
change: "變更審閱狀態",
|
|
94
|
+
saveFailed: "無法更新審閱狀態",
|
|
95
|
+
},
|
|
96
|
+
},
|
|
46
97
|
chat: {
|
|
47
98
|
emptyState: "描述要建立的設計",
|
|
48
99
|
suggestionLandingPage: "為我的初創公司設計落地頁面",
|
|
@@ -1,14 +1,36 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ReviewStatusBadge,
|
|
3
|
+
agentNativePath,
|
|
2
4
|
injectSessionReplayIframeBootstrap,
|
|
3
5
|
SESSION_REPLAY_IFRAME_ATTRIBUTE,
|
|
4
6
|
useActionQuery,
|
|
7
|
+
useReviewComments,
|
|
8
|
+
useSession,
|
|
5
9
|
useT,
|
|
6
10
|
} from "@agent-native/core/client";
|
|
7
|
-
import {
|
|
11
|
+
import { readDesignReviewSummary } from "@shared/review-summary";
|
|
12
|
+
import { IconMessageCircle } from "@tabler/icons-react";
|
|
13
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
8
14
|
import { Link, useParams, useNavigate } from "react-router";
|
|
9
15
|
|
|
16
|
+
import { appendHitTestResponder } from "@/components/design/design-canvas/hit-test";
|
|
17
|
+
import { ReviewCommentsPanel } from "@/components/design/ReviewCommentsPanel";
|
|
10
18
|
import { QueryErrorState } from "@/components/QueryErrorState";
|
|
19
|
+
import { Button } from "@/components/ui/button";
|
|
20
|
+
import {
|
|
21
|
+
Sheet,
|
|
22
|
+
SheetContent,
|
|
23
|
+
SheetDescription,
|
|
24
|
+
SheetHeader,
|
|
25
|
+
SheetTitle,
|
|
26
|
+
} from "@/components/ui/sheet";
|
|
11
27
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
28
|
+
import { ReviewCanvasPins } from "@/components/visual-editor/ReviewCanvasPins";
|
|
29
|
+
|
|
30
|
+
import {
|
|
31
|
+
resolvePresentEscapeAction,
|
|
32
|
+
shouldBlockPresentPageNavigation,
|
|
33
|
+
} from "./present-review-state";
|
|
12
34
|
|
|
13
35
|
interface DesignFile {
|
|
14
36
|
id: string;
|
|
@@ -21,13 +43,17 @@ interface DesignData {
|
|
|
21
43
|
id: string;
|
|
22
44
|
title: string;
|
|
23
45
|
files: DesignFile[];
|
|
46
|
+
accessRole?: "viewer" | "editor" | "admin" | "owner";
|
|
24
47
|
}
|
|
25
48
|
|
|
26
49
|
export default function Present() {
|
|
27
50
|
const t = useT();
|
|
28
51
|
const { id } = useParams<{ id: string }>();
|
|
29
52
|
const navigate = useNavigate();
|
|
53
|
+
const { session } = useSession();
|
|
30
54
|
const [currentPage, setCurrentPage] = useState(0);
|
|
55
|
+
const [commentMode, setCommentMode] = useState(false);
|
|
56
|
+
const [commentsOpen, setCommentsOpen] = useState(false);
|
|
31
57
|
|
|
32
58
|
const {
|
|
33
59
|
data: design,
|
|
@@ -38,14 +64,67 @@ export default function Present() {
|
|
|
38
64
|
} = useActionQuery<DesignData>("get-design", { id: id! });
|
|
39
65
|
|
|
40
66
|
const files: DesignFile[] = design?.files ?? [];
|
|
67
|
+
const activeFile = files[currentPage] ?? files[0];
|
|
68
|
+
const reviewQuery = useReviewComments(
|
|
69
|
+
{
|
|
70
|
+
resourceType: "design",
|
|
71
|
+
resourceId: id ?? "",
|
|
72
|
+
targetId: activeFile?.id ?? undefined,
|
|
73
|
+
includeResolved: false,
|
|
74
|
+
limit: 500,
|
|
75
|
+
},
|
|
76
|
+
{ enabled: Boolean(id) },
|
|
77
|
+
);
|
|
78
|
+
const canPost = Boolean(session?.email);
|
|
79
|
+
const canResolve = Boolean(
|
|
80
|
+
design?.accessRole === "owner" ||
|
|
81
|
+
design?.accessRole === "admin" ||
|
|
82
|
+
design?.accessRole === "editor",
|
|
83
|
+
);
|
|
84
|
+
const reviewableContent = useMemo(
|
|
85
|
+
() =>
|
|
86
|
+
injectSessionReplayIframeBootstrap(
|
|
87
|
+
appendHitTestResponder(activeFile?.content ?? ""),
|
|
88
|
+
),
|
|
89
|
+
[activeFile?.content],
|
|
90
|
+
);
|
|
91
|
+
const reviewCommentCount =
|
|
92
|
+
readDesignReviewSummary(reviewQuery.data)?.openCount ??
|
|
93
|
+
new Set(
|
|
94
|
+
(reviewQuery.data?.comments ?? [])
|
|
95
|
+
.filter(
|
|
96
|
+
(comment) =>
|
|
97
|
+
comment.status === "open" && comment.parentCommentId === null,
|
|
98
|
+
)
|
|
99
|
+
.map((comment) => comment.threadId),
|
|
100
|
+
).size;
|
|
101
|
+
const signInHref = (() => {
|
|
102
|
+
const base = agentNativePath("/_agent-native/sign-in");
|
|
103
|
+
if (typeof window === "undefined") return base;
|
|
104
|
+
const returnUrl = new URL(window.location.href);
|
|
105
|
+
returnUrl.search = "";
|
|
106
|
+
returnUrl.hash = "";
|
|
107
|
+
return `${base}?return=${encodeURIComponent(returnUrl.pathname)}`;
|
|
108
|
+
})();
|
|
41
109
|
|
|
42
110
|
// Keyboard navigation
|
|
43
111
|
const handleKeyDown = useCallback(
|
|
44
112
|
(e: KeyboardEvent) => {
|
|
45
113
|
if (e.key === "Escape") {
|
|
46
|
-
|
|
114
|
+
const action = resolvePresentEscapeAction({
|
|
115
|
+
commentsOpen,
|
|
116
|
+
commentMode,
|
|
117
|
+
});
|
|
118
|
+
if (action === "close-comments") setCommentsOpen(false);
|
|
119
|
+
if (action === "exit-presentation") navigate(`/design/${id}`);
|
|
120
|
+
// ReviewCanvasPins owns "defer-to-comment-mode" so it can dismiss an
|
|
121
|
+
// active draft before it exits the tool.
|
|
47
122
|
return;
|
|
48
123
|
}
|
|
124
|
+
// Freeze slide navigation while review UI is active so typing a space
|
|
125
|
+
// or using arrow keys in the sheet cannot change the anchored screen.
|
|
126
|
+
if (shouldBlockPresentPageNavigation({ commentsOpen, commentMode }))
|
|
127
|
+
return;
|
|
49
128
|
if (files.length <= 1) return;
|
|
50
129
|
if (e.key === "ArrowRight" || e.key === "ArrowDown" || e.key === " ") {
|
|
51
130
|
e.preventDefault();
|
|
@@ -56,7 +135,7 @@ export default function Present() {
|
|
|
56
135
|
setCurrentPage((p) => Math.max(p - 1, 0));
|
|
57
136
|
}
|
|
58
137
|
},
|
|
59
|
-
[
|
|
138
|
+
[commentMode, commentsOpen, files.length, id, navigate],
|
|
60
139
|
);
|
|
61
140
|
|
|
62
141
|
useEffect(() => {
|
|
@@ -99,17 +178,96 @@ export default function Present() {
|
|
|
99
178
|
);
|
|
100
179
|
}
|
|
101
180
|
|
|
102
|
-
const activeFile = files[currentPage] ?? files[0];
|
|
103
|
-
|
|
104
181
|
return (
|
|
105
|
-
<div className="h-screen w-screen bg-black
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
182
|
+
<div className="relative h-screen w-screen overflow-hidden bg-black">
|
|
183
|
+
<div className="present-review-canvas h-full w-full">
|
|
184
|
+
<iframe
|
|
185
|
+
{...{ [SESSION_REPLAY_IFRAME_ATTRIBUTE]: "" }}
|
|
186
|
+
srcDoc={reviewableContent}
|
|
187
|
+
sandbox="allow-scripts"
|
|
188
|
+
data-design-preview-iframe
|
|
189
|
+
className="h-full w-full border-0"
|
|
190
|
+
title={`${design.title} — ${activeFile.filename}`}
|
|
191
|
+
/>
|
|
192
|
+
<ReviewCanvasPins
|
|
193
|
+
active={commentMode}
|
|
194
|
+
onClose={() => setCommentMode(false)}
|
|
195
|
+
canvasSelector=".present-review-canvas"
|
|
196
|
+
resourceType="design"
|
|
197
|
+
resourceId={id}
|
|
198
|
+
targetId={activeFile.id}
|
|
199
|
+
canPost={canPost}
|
|
200
|
+
canResolve={canResolve}
|
|
201
|
+
/>
|
|
202
|
+
</div>
|
|
203
|
+
|
|
204
|
+
<div className="fixed right-4 top-4 z-[70] flex items-center gap-2">
|
|
205
|
+
<ReviewStatusBadge
|
|
206
|
+
status={reviewQuery.data?.reviewStatus?.status ?? "draft"}
|
|
207
|
+
/>
|
|
208
|
+
<Button
|
|
209
|
+
type="button"
|
|
210
|
+
variant="secondary"
|
|
211
|
+
size="sm"
|
|
212
|
+
className="gap-1.5 rounded-full bg-black/75 text-white shadow-lg hover:bg-black"
|
|
213
|
+
onClick={() => {
|
|
214
|
+
setCommentMode(false);
|
|
215
|
+
setCommentsOpen(true);
|
|
216
|
+
}}
|
|
217
|
+
>
|
|
218
|
+
<IconMessageCircle className="size-4" />
|
|
219
|
+
{t("review.presentComments")}
|
|
220
|
+
{reviewCommentCount > 0 ? ` · ${reviewCommentCount}` : ""}
|
|
221
|
+
</Button>
|
|
222
|
+
</div>
|
|
223
|
+
|
|
224
|
+
<Sheet open={commentsOpen} onOpenChange={setCommentsOpen}>
|
|
225
|
+
<SheetContent
|
|
226
|
+
side="right"
|
|
227
|
+
className="flex w-[min(92vw,380px)] flex-col overflow-hidden p-0"
|
|
228
|
+
>
|
|
229
|
+
<SheetHeader className="border-b border-border px-4 py-3">
|
|
230
|
+
<SheetTitle className="flex items-center gap-2 text-sm">
|
|
231
|
+
<IconMessageCircle className="size-4" />
|
|
232
|
+
{t("review.presentComments")}
|
|
233
|
+
</SheetTitle>
|
|
234
|
+
<SheetDescription className="sr-only">
|
|
235
|
+
{t("review.commentsTitle")}
|
|
236
|
+
</SheetDescription>
|
|
237
|
+
</SheetHeader>
|
|
238
|
+
<ReviewCommentsPanel
|
|
239
|
+
designId={id}
|
|
240
|
+
activeFileId={activeFile.id}
|
|
241
|
+
canComment={canPost}
|
|
242
|
+
canResolve={canResolve}
|
|
243
|
+
canDeleteComment={(comment) =>
|
|
244
|
+
canResolve ||
|
|
245
|
+
("canDelete" in comment && comment.canDelete === true) ||
|
|
246
|
+
comment.authorEmail === session?.email
|
|
247
|
+
}
|
|
248
|
+
showComposer={false}
|
|
249
|
+
signInHref={signInHref}
|
|
250
|
+
className="min-h-0 flex-1"
|
|
251
|
+
/>
|
|
252
|
+
{canPost ? (
|
|
253
|
+
<div className="shrink-0 border-t border-border p-3">
|
|
254
|
+
<Button
|
|
255
|
+
type="button"
|
|
256
|
+
variant="outline"
|
|
257
|
+
size="sm"
|
|
258
|
+
className="w-full gap-1.5"
|
|
259
|
+
onClick={() => {
|
|
260
|
+
setCommentsOpen(false);
|
|
261
|
+
setCommentMode(true);
|
|
262
|
+
}}
|
|
263
|
+
>
|
|
264
|
+
<IconMessageCircle className="size-3.5" />
|
|
265
|
+
{t("review.presentCommentMode")}
|
|
266
|
+
</Button>
|
|
267
|
+
</div>
|
|
268
|
+
) : null}
|
|
269
|
+
</SheetContent>
|
|
270
|
+
</Sheet>
|
|
113
271
|
|
|
114
272
|
{/* Page indicator */}
|
|
115
273
|
{files.length > 1 && (
|
|
@@ -127,7 +285,7 @@ export default function Present() {
|
|
|
127
285
|
)}
|
|
128
286
|
|
|
129
287
|
{/* Exit hint */}
|
|
130
|
-
<div className="fixed
|
|
288
|
+
<div className="fixed left-4 top-4 text-xs text-white/20">
|
|
131
289
|
{t("pages.presentExitHint")}
|
|
132
290
|
</div>
|
|
133
291
|
</div>
|
|
@@ -509,6 +509,29 @@ export function computeIframeLocalCanvasPoint(args: {
|
|
|
509
509
|
};
|
|
510
510
|
}
|
|
511
511
|
|
|
512
|
+
export function resolveScreenDropPoint(args: {
|
|
513
|
+
clientX: number;
|
|
514
|
+
clientY: number;
|
|
515
|
+
screenId: string | null | undefined;
|
|
516
|
+
iframeRect:
|
|
517
|
+
| { left: number; top: number; right: number; bottom: number }
|
|
518
|
+
| null
|
|
519
|
+
| undefined;
|
|
520
|
+
zoomPercent: number;
|
|
521
|
+
}): { screenId: string; x: number; y: number } | null {
|
|
522
|
+
if (!args.screenId || !args.iframeRect) return null;
|
|
523
|
+
if (
|
|
524
|
+
args.clientX < args.iframeRect.left ||
|
|
525
|
+
args.iframeRect.right < args.clientX ||
|
|
526
|
+
args.clientY < args.iframeRect.top ||
|
|
527
|
+
args.iframeRect.bottom < args.clientY
|
|
528
|
+
) {
|
|
529
|
+
return null;
|
|
530
|
+
}
|
|
531
|
+
const point = computeIframeLocalCanvasPoint(args);
|
|
532
|
+
return point ? { screenId: args.screenId, ...point } : null;
|
|
533
|
+
}
|
|
534
|
+
|
|
512
535
|
/**
|
|
513
536
|
* Reads MultiScreenCanvas's live imperative zoom from the exact inline
|
|
514
537
|
* transform written by `applyViewToDom` while a wheel/pinch gesture is still
|
|
@@ -92,6 +92,16 @@ export function getDesignToolActivationState(tool: DesignTool): {
|
|
|
92
92
|
return { mode: "edit", drawMode: false, pinMode: false };
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
export function shouldAutoEnableDrawOverlay(args: {
|
|
96
|
+
mode: EditorMode;
|
|
97
|
+
activeTool: DesignTool;
|
|
98
|
+
pinMode: boolean;
|
|
99
|
+
}): boolean {
|
|
100
|
+
return (
|
|
101
|
+
args.mode === "annotate" && args.activeTool === "draw" && !args.pinMode
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
95
105
|
export function getSingleScreenCreationTool(args: {
|
|
96
106
|
activeTool: DesignTool;
|
|
97
107
|
viewMode: "single" | "overview";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface PresentReviewState {
|
|
2
|
+
commentsOpen: boolean;
|
|
3
|
+
commentMode: boolean;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export function resolvePresentEscapeAction(
|
|
7
|
+
state: PresentReviewState,
|
|
8
|
+
): "close-comments" | "defer-to-comment-mode" | "exit-presentation" {
|
|
9
|
+
if (state.commentsOpen) return "close-comments";
|
|
10
|
+
if (state.commentMode) return "defer-to-comment-mode";
|
|
11
|
+
return "exit-presentation";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function shouldBlockPresentPageNavigation(
|
|
15
|
+
state: PresentReviewState,
|
|
16
|
+
): boolean {
|
|
17
|
+
return state.commentsOpen || state.commentMode;
|
|
18
|
+
}
|
|
@@ -33,10 +33,14 @@ import { AppToolkitProvider } from "@/components/ui/toolkit-provider";
|
|
|
33
33
|
|
|
34
34
|
import changelog from "../CHANGELOG.md?raw";
|
|
35
35
|
import { i18nCatalog } from "./i18n";
|
|
36
|
+
import { isPublicDesignAppPath } from "./public-routes";
|
|
36
37
|
|
|
37
38
|
import stylesheet from "./global.css?url";
|
|
38
39
|
|
|
39
40
|
configureTracking({
|
|
41
|
+
llmConnectionStatus:
|
|
42
|
+
typeof window === "undefined" ||
|
|
43
|
+
!isPublicDesignAppPath(window.location.pathname),
|
|
40
44
|
getDefaultProps: (_name, properties) => ({
|
|
41
45
|
...properties,
|
|
42
46
|
app: "design",
|
|
@@ -182,16 +186,13 @@ function RootContent() {
|
|
|
182
186
|
export default function Root() {
|
|
183
187
|
const [queryClient] = useState(() => createAgentNativeQueryClient());
|
|
184
188
|
const location = useLocation();
|
|
185
|
-
const
|
|
186
|
-
location.pathname === "/visual-edit" ||
|
|
187
|
-
location.pathname === "/design" ||
|
|
188
|
-
location.pathname.startsWith("/design/");
|
|
189
|
+
const isPublicPath = isPublicDesignAppPath(location.pathname);
|
|
189
190
|
return (
|
|
190
191
|
<AppToolkitProvider>
|
|
191
192
|
<AppProviders
|
|
192
193
|
queryClient={queryClient}
|
|
193
|
-
|
|
194
|
-
i18n={{ catalog: i18nCatalog }}
|
|
194
|
+
isPublicPath={isPublicPath}
|
|
195
|
+
i18n={{ catalog: i18nCatalog, persistPreference: !isPublicPath }}
|
|
195
196
|
>
|
|
196
197
|
<RootContent />
|
|
197
198
|
</AppProviders>
|
|
@@ -12,6 +12,14 @@ const DESIGN_BACKGROUND_RUN_NO_PROGRESS_TIMEOUT_MS = 12 * 60_000;
|
|
|
12
12
|
|
|
13
13
|
const INITIAL_TOOL_NAMES = [
|
|
14
14
|
"view-screen",
|
|
15
|
+
"list-review-comments",
|
|
16
|
+
"get-review-feedback",
|
|
17
|
+
"create-review-comment",
|
|
18
|
+
"reply-review-comment",
|
|
19
|
+
"send-review-thread-to-agent",
|
|
20
|
+
"resolve-review-thread",
|
|
21
|
+
"consume-review-feedback",
|
|
22
|
+
"set-review-status",
|
|
15
23
|
"list-designs",
|
|
16
24
|
"list-design-templates",
|
|
17
25
|
"get-design",
|
|
@@ -60,6 +68,8 @@ When the user asks to start from a template, call list-design-templates and then
|
|
|
60
68
|
|
|
61
69
|
When the user asks you to refine an existing design, call view-screen if the open design is unclear, then read the live current file with get-design-snapshot before editing. For small localized changes, call edit-design with exact search/replace edits. For broad copy-only changes such as translating all visible text, call edit-design in replace-file mode with the complete updated file content from the snapshot so the HTML structure, scripts, styles, and tweaks are preserved without dozens of fragile search blocks. Do not claim the design is updated until the mutating action succeeds.
|
|
62
70
|
|
|
71
|
+
When open review feedback exists, call get-review-feedback and work one anchored thread at a time. Prefer the stable node anchor, verify each persisted edit before resolving its thread, pass resolutionNote with a one-line description of the persisted change, and call consume-review-feedback after applying agent-targeted feedback. If a reviewer selectively sends one thread to the agent, use that thread id as the scope and do not apply other open feedback. If a thread needs a human decision, reply with resolutionTarget "human" instead of resolving it; follow the design-review-feedback skill for the complete loop.
|
|
72
|
+
|
|
63
73
|
When the user picks one direction from a set of presented variants, delete each unchosen variant screen at most once, then call get-design-snapshot exactly once for the kept screen's fileId and call edit-design on that same fileId. Use edit-design replace-file when expanding the placeholder into a complete but compact product UI in the chosen direction. Prioritize the primary workflow and render secondary details as visible controls, states, or affordances if the feature list is too large for one reliable edit. Do not call generate-design after a variant pick unless the user explicitly asks to create a separate new screen.
|
|
64
74
|
|
|
65
75
|
When the user asks to visually inspect or edit a running local app, use open-visual-edit. It registers the localhost bridge, creates or reuses the Design project, places URL-backed iframe screens, stores the active visual-edit context, and navigates to overview mode in one authenticated step. For follow-ups like adding a mobile viewport or another route state, reuse the current designId and connectionId and call open-visual-edit or add-localhost-screens with explicit routes/paths and viewport sizes.
|
|
@@ -2,10 +2,10 @@ import { createAuthPlugin } from "@agent-native/core/server";
|
|
|
2
2
|
|
|
3
3
|
export default createAuthPlugin({
|
|
4
4
|
workspaceAppAudience: "internal",
|
|
5
|
-
//
|
|
6
|
-
// a session. Creating, mutating, generating, and sharing designs
|
|
7
|
-
// through authenticated actions.
|
|
8
|
-
workspaceAppPublicPaths: ["/visual-edit", "/design"],
|
|
5
|
+
// Visual-edit, public design editor links, and presentation links can load
|
|
6
|
+
// without a session. Creating, mutating, generating, and sharing designs
|
|
7
|
+
// still go through authenticated actions.
|
|
8
|
+
workspaceAppPublicPaths: ["/visual-edit", "/design", "/present"],
|
|
9
9
|
marketing: {
|
|
10
10
|
appName: "Agent-Native Design",
|
|
11
11
|
tagline:
|
|
@@ -23,11 +23,13 @@ export default createAuthPlugin({
|
|
|
23
23
|
// server/routes/api/design-handoff/[id].get.ts — verifyShortLivedToken).
|
|
24
24
|
// publicPaths uses prefix matching, so this covers
|
|
25
25
|
// /api/design-handoff/<id>?token=... while keeping every other /api/* and
|
|
26
|
-
// /_agent-native/* route behind auth.
|
|
26
|
+
// /_agent-native/* route behind auth. The listed action routes are read-only;
|
|
27
|
+
// review comment mutations remain protected by action auth and resource ACLs.
|
|
27
28
|
publicPaths: [
|
|
28
29
|
"/api/design-handoff",
|
|
29
30
|
"/__manifest",
|
|
30
31
|
"/_agent-native/actions/get-design",
|
|
31
32
|
"/_agent-native/actions/list-design-native-assets",
|
|
33
|
+
"/_agent-native/actions/list-review-comments",
|
|
32
34
|
],
|
|
33
35
|
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { registerReviewableResource } from "@agent-native/core/review";
|
|
2
|
+
import { defineNitroPlugin } from "@agent-native/core/server";
|
|
3
|
+
|
|
4
|
+
export default defineNitroPlugin(() => {
|
|
5
|
+
registerReviewableResource({
|
|
6
|
+
type: "design",
|
|
7
|
+
displayName: "Design",
|
|
8
|
+
});
|
|
9
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export interface ReviewAnchorPoint {
|
|
2
|
+
xPct: number;
|
|
3
|
+
yPct: number;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface DesignReviewAnchor {
|
|
7
|
+
nodeId?: string;
|
|
8
|
+
point: ReviewAnchorPoint;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ResolvedReviewAnchor {
|
|
12
|
+
anchor: DesignReviewAnchor;
|
|
13
|
+
point: ReviewAnchorPoint;
|
|
14
|
+
source: "node" | "point";
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function finitePercentage(value: unknown): number | null {
|
|
18
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return null;
|
|
19
|
+
return Math.min(100, Math.max(0, value));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function inBoundsPercentage(value: unknown): number | null {
|
|
23
|
+
if (
|
|
24
|
+
typeof value !== "number" ||
|
|
25
|
+
!Number.isFinite(value) ||
|
|
26
|
+
value < 0 ||
|
|
27
|
+
value > 100
|
|
28
|
+
) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Parse the persisted anchor contract used by Design review comments.
|
|
36
|
+
* Malformed anchors intentionally return null so a thread remains visible in
|
|
37
|
+
* the panel without creating a misleading canvas pin.
|
|
38
|
+
*/
|
|
39
|
+
export function parseReviewAnchor(value: unknown): DesignReviewAnchor | null {
|
|
40
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const record = value as Record<string, unknown>;
|
|
44
|
+
const point =
|
|
45
|
+
record.point &&
|
|
46
|
+
typeof record.point === "object" &&
|
|
47
|
+
!Array.isArray(record.point)
|
|
48
|
+
? (record.point as Record<string, unknown>)
|
|
49
|
+
: null;
|
|
50
|
+
const xPct = finitePercentage(point?.xPct);
|
|
51
|
+
const yPct = finitePercentage(point?.yPct);
|
|
52
|
+
if (xPct === null || yPct === null) return null;
|
|
53
|
+
|
|
54
|
+
const nodeId = typeof record.nodeId === "string" ? record.nodeId.trim() : "";
|
|
55
|
+
return {
|
|
56
|
+
...(nodeId ? { nodeId } : {}),
|
|
57
|
+
point: { xPct, yPct },
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Resolve a node-id position first, then degrade to the stored click point. */
|
|
62
|
+
export function resolveReviewAnchor(
|
|
63
|
+
value: unknown,
|
|
64
|
+
resolveNodePoint: (nodeId: string) => ReviewAnchorPoint | null,
|
|
65
|
+
): ResolvedReviewAnchor | null {
|
|
66
|
+
const anchor = parseReviewAnchor(value);
|
|
67
|
+
if (!anchor) return null;
|
|
68
|
+
if (anchor.nodeId) {
|
|
69
|
+
const nodePoint = resolveNodePoint(anchor.nodeId);
|
|
70
|
+
if (nodePoint) {
|
|
71
|
+
const xPct = inBoundsPercentage(nodePoint.xPct);
|
|
72
|
+
const yPct = inBoundsPercentage(nodePoint.yPct);
|
|
73
|
+
if (xPct !== null && yPct !== null) {
|
|
74
|
+
return {
|
|
75
|
+
anchor,
|
|
76
|
+
point: { xPct, yPct },
|
|
77
|
+
source: "node",
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return { anchor, point: anchor.point, source: "point" };
|
|
83
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface DesignReviewSummary {
|
|
2
|
+
openCount: number;
|
|
3
|
+
agentQueueCount: number;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export function readDesignReviewSummary(
|
|
7
|
+
result: unknown,
|
|
8
|
+
): DesignReviewSummary | null {
|
|
9
|
+
if (!result || typeof result !== "object") return null;
|
|
10
|
+
const summary = (result as { summary?: unknown }).summary;
|
|
11
|
+
if (!summary || typeof summary !== "object") return null;
|
|
12
|
+
const openCount = Number((summary as { openCount?: unknown }).openCount);
|
|
13
|
+
const agentQueueCount = Number(
|
|
14
|
+
(summary as { agentQueueCount?: unknown }).agentQueueCount,
|
|
15
|
+
);
|
|
16
|
+
if (
|
|
17
|
+
!Number.isInteger(openCount) ||
|
|
18
|
+
openCount < 0 ||
|
|
19
|
+
!Number.isInteger(agentQueueCount) ||
|
|
20
|
+
agentQueueCount < 0
|
|
21
|
+
) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
return { openCount, agentQueueCount };
|
|
25
|
+
}
|