@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
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from "@agent-native/toolkit/ui/button";
|
|
3
|
+
import { Spinner } from "@agent-native/toolkit/ui/spinner";
|
|
4
|
+
import { Textarea } from "@agent-native/toolkit/ui/textarea";
|
|
5
|
+
import { IconMessageCircle, IconSend } from "@tabler/icons-react";
|
|
6
|
+
import { cn } from "../utils.js";
|
|
7
|
+
export function ReviewCommentComposer({ value, onChange, onSubmit, submittingTarget = null, disabled = false, showAgentAction = false, placeholder = "Add a comment...", commentLabel = "Comment", agentLabel = "Send to agent", autoFocus = false, submitOnEnter = false, onEscape, className, }) {
|
|
8
|
+
const canSubmit = Boolean(value.trim()) && !disabled;
|
|
9
|
+
const submit = (resolutionTarget) => {
|
|
10
|
+
if (!canSubmit)
|
|
11
|
+
return;
|
|
12
|
+
onSubmit(resolutionTarget);
|
|
13
|
+
};
|
|
14
|
+
return (_jsxs("form", { className: cn("@container/review", className), onSubmit: (event) => {
|
|
15
|
+
event.preventDefault();
|
|
16
|
+
submit("human");
|
|
17
|
+
}, children: [_jsx(Textarea, { autoFocus: autoFocus, value: value, disabled: disabled, onChange: (event) => onChange(event.currentTarget.value), placeholder: placeholder, className: "min-h-16 resize-none text-sm", onKeyDown: (event) => {
|
|
18
|
+
if (event.key === "Escape" && onEscape) {
|
|
19
|
+
event.stopPropagation();
|
|
20
|
+
event.preventDefault();
|
|
21
|
+
onEscape();
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (submitOnEnter && event.key === "Enter" && !event.shiftKey) {
|
|
25
|
+
event.preventDefault();
|
|
26
|
+
submit("human");
|
|
27
|
+
}
|
|
28
|
+
} }), _jsxs("div", { className: "mt-2 flex flex-col items-stretch justify-end gap-2 @2xs/review:flex-row @2xs/review:items-center", children: [_jsxs(Button, { type: "submit", size: "sm", disabled: !canSubmit, className: "h-8 w-full min-w-0 gap-1.5 @2xs/review:w-auto", children: [submittingTarget === "human" ? (_jsx(Spinner, { className: "size-3.5" })) : (_jsx(IconMessageCircle, { className: "size-3.5" })), _jsx("span", { className: "truncate", children: commentLabel })] }), showAgentAction ? (_jsxs(Button, { type: "button", size: "sm", variant: "outline", disabled: !canSubmit, className: "h-8 w-full min-w-0 gap-1.5 @2xs/review:w-auto", onClick: () => submit("agent"), children: [submittingTarget === "agent" ? (_jsx(Spinner, { className: "size-3.5" })) : (_jsx(IconSend, { className: "size-3.5" })), _jsx("span", { className: "truncate", children: agentLabel })] })) : null] })] }));
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=ReviewCommentComposer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReviewCommentComposer.js","sourceRoot":"","sources":["../../../src/client/review/ReviewCommentComposer.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Button } from \"@agent-native/toolkit/ui/button\";\nimport { Spinner } from \"@agent-native/toolkit/ui/spinner\";\nimport { Textarea } from \"@agent-native/toolkit/ui/textarea\";\nimport { IconMessageCircle, IconSend } from \"@tabler/icons-react\";\n\nimport type { ReviewResolutionTarget } from \"../../review/types.js\";\nimport { cn } from \"../utils.js\";\n\nexport interface ReviewCommentComposerProps {\n value: string;\n onChange: (value: string) => void;\n onSubmit: (resolutionTarget: ReviewResolutionTarget) => void;\n submittingTarget?: ReviewResolutionTarget | null;\n disabled?: boolean;\n showAgentAction?: boolean;\n placeholder?: string;\n commentLabel?: string;\n agentLabel?: string;\n autoFocus?: boolean;\n submitOnEnter?: boolean;\n onEscape?: () => void;\n className?: string;\n}\n\nexport function ReviewCommentComposer({\n value,\n onChange,\n onSubmit,\n submittingTarget = null,\n disabled = false,\n showAgentAction = false,\n placeholder = \"Add a comment...\",\n commentLabel = \"Comment\",\n agentLabel = \"Send to agent\",\n autoFocus = false,\n submitOnEnter = false,\n onEscape,\n className,\n}: ReviewCommentComposerProps) {\n const canSubmit = Boolean(value.trim()) && !disabled;\n const submit = (resolutionTarget: ReviewResolutionTarget) => {\n if (!canSubmit) return;\n onSubmit(resolutionTarget);\n };\n\n return (\n <form\n className={cn(\"@container/review\", className)}\n onSubmit={(event) => {\n event.preventDefault();\n submit(\"human\");\n }}\n >\n <Textarea\n autoFocus={autoFocus}\n value={value}\n disabled={disabled}\n onChange={(event) => onChange(event.currentTarget.value)}\n placeholder={placeholder}\n className=\"min-h-16 resize-none text-sm\"\n onKeyDown={(event) => {\n if (event.key === \"Escape\" && onEscape) {\n event.stopPropagation();\n event.preventDefault();\n onEscape();\n return;\n }\n if (submitOnEnter && event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n submit(\"human\");\n }\n }}\n />\n <div className=\"mt-2 flex flex-col items-stretch justify-end gap-2 @2xs/review:flex-row @2xs/review:items-center\">\n <Button\n type=\"submit\"\n size=\"sm\"\n disabled={!canSubmit}\n className=\"h-8 w-full min-w-0 gap-1.5 @2xs/review:w-auto\"\n >\n {submittingTarget === \"human\" ? (\n <Spinner className=\"size-3.5\" />\n ) : (\n <IconMessageCircle className=\"size-3.5\" />\n )}\n <span className=\"truncate\">{commentLabel}</span>\n </Button>\n {showAgentAction ? (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={!canSubmit}\n className=\"h-8 w-full min-w-0 gap-1.5 @2xs/review:w-auto\"\n onClick={() => submit(\"agent\")}\n >\n {submittingTarget === \"agent\" ? (\n <Spinner className=\"size-3.5\" />\n ) : (\n <IconSend className=\"size-3.5\" />\n )}\n <span className=\"truncate\">{agentLabel}</span>\n </Button>\n ) : null}\n </div>\n </form>\n );\n}\n"]}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
1
2
|
import type { ReviewComment } from "../../review/types.js";
|
|
2
3
|
export interface ReviewThread {
|
|
3
4
|
root: ReviewComment;
|
|
4
5
|
replies: ReviewComment[];
|
|
5
6
|
}
|
|
7
|
+
export type ReviewThreadCapability = boolean | ((thread: ReviewThread) => boolean);
|
|
8
|
+
export type ReviewCommentCapability = boolean | ((comment: ReviewComment, thread: ReviewThread) => boolean);
|
|
6
9
|
export interface ReviewThreadPanelProps {
|
|
7
10
|
resourceType: string;
|
|
8
11
|
resourceId: string;
|
|
@@ -11,10 +14,34 @@ export interface ReviewThreadPanelProps {
|
|
|
11
14
|
className?: string;
|
|
12
15
|
includeResolved?: boolean;
|
|
13
16
|
showComposer?: boolean;
|
|
17
|
+
showHeader?: boolean;
|
|
18
|
+
variant?: "card" | "plain";
|
|
14
19
|
placeholder?: string;
|
|
15
20
|
emptyState?: string;
|
|
21
|
+
loadingLabel?: string;
|
|
22
|
+
replyLabel?: string;
|
|
23
|
+
replyPlaceholder?: string;
|
|
24
|
+
cancelReplyLabel?: string;
|
|
25
|
+
resolveLabel?: string;
|
|
26
|
+
deleteLabel?: string;
|
|
27
|
+
moreActionsLabel?: string;
|
|
28
|
+
resolvedLabel?: string;
|
|
29
|
+
reviewerLabel?: string;
|
|
16
30
|
onSelectThread?: (thread: ReviewThread) => void;
|
|
31
|
+
onCommentCreated?: (comment: ReviewComment) => void;
|
|
32
|
+
/** Allow signed-in commenters to reply. Omitted capabilities fail closed. */
|
|
33
|
+
canReply?: ReviewThreadCapability;
|
|
34
|
+
/** Allow editors to resolve a thread. Omitted capabilities fail closed. */
|
|
35
|
+
canResolve?: ReviewThreadCapability;
|
|
36
|
+
/** Allow deletion only for comments the caller has authorized. */
|
|
37
|
+
canDeleteComment?: ReviewCommentCapability;
|
|
38
|
+
/** Extra per-thread controls rendered next to reply/resolve/delete. */
|
|
39
|
+
renderThreadActions?: (thread: ReviewThread) => ReactNode;
|
|
40
|
+
/** Show a separate agent-submit action when the host supports agent routing. */
|
|
41
|
+
showComposerTargetPicker?: boolean;
|
|
42
|
+
composerCommentLabel?: string;
|
|
43
|
+
composerAgentLabel?: string;
|
|
17
44
|
}
|
|
18
|
-
export declare function ReviewThreadPanel({ resourceType, resourceId, targetId, title, className, includeResolved, showComposer, placeholder, emptyState, onSelectThread, }: ReviewThreadPanelProps): import("react").JSX.Element;
|
|
45
|
+
export declare function ReviewThreadPanel({ resourceType, resourceId, targetId, title, className, includeResolved, showComposer, showHeader, variant, placeholder, emptyState, loadingLabel, replyLabel, replyPlaceholder, cancelReplyLabel, resolveLabel, deleteLabel, moreActionsLabel, resolvedLabel, reviewerLabel, onSelectThread, onCommentCreated, canReply, canResolve, canDeleteComment, renderThreadActions, showComposerTargetPicker, composerCommentLabel, composerAgentLabel, }: ReviewThreadPanelProps): import("react").JSX.Element;
|
|
19
46
|
export declare function buildReviewThreads(comments: ReviewComment[]): ReviewThread[];
|
|
20
47
|
//# sourceMappingURL=ReviewThreadPanel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReviewThreadPanel.d.ts","sourceRoot":"","sources":["../../../src/client/review/ReviewThreadPanel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ReviewThreadPanel.d.ts","sourceRoot":"","sources":["../../../src/client/review/ReviewThreadPanel.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1D,OAAO,KAAK,EACV,aAAa,EAEd,MAAM,uBAAuB,CAAC;AAa/B,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,MAAM,MAAM,sBAAsB,GAC9B,OAAO,GACP,CAAC,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC;AAExC,MAAM,MAAM,uBAAuB,GAC/B,OAAO,GACP,CAAC,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC;AAEhE,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IAChD,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;IACpD,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAClC,2EAA2E;IAC3E,UAAU,CAAC,EAAE,sBAAsB,CAAC;IACpC,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,uBAAuB,CAAC;IAC3C,uEAAuE;IACvE,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,SAAS,CAAC;IAC1D,gFAAgF;IAChF,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,iBAAiB,CAAC,EAChC,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,KAAgB,EAChB,SAAS,EACT,eAAsB,EACtB,YAAmB,EACnB,UAAiB,EACjB,OAAgB,EAChB,WAAgC,EAChC,UAAsC,EACtC,YAAiC,EACjC,UAAoB,EACpB,gBAA6B,EAC7B,gBAAiC,EACjC,YAAwB,EACxB,WAA8B,EAC9B,gBAAiC,EACjC,aAA0B,EAC1B,aAA0B,EAC1B,cAAc,EACd,gBAAgB,EAChB,QAAgB,EAChB,UAAkB,EAClB,gBAAwB,EACxB,mBAAmB,EACnB,wBAAgC,EAChC,oBAAgC,EAChC,kBAAoC,GACrC,EAAE,sBAAsB,+BAyTxB;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,YAAY,EAAE,CAkB5E"}
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { Avatar, AvatarFallback } from "@agent-native/toolkit/ui/avatar";
|
|
3
|
+
import { Button } from "@agent-native/toolkit/ui/button";
|
|
4
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@agent-native/toolkit/ui/dropdown-menu";
|
|
5
|
+
import { Input } from "@agent-native/toolkit/ui/input";
|
|
6
|
+
import { Skeleton } from "@agent-native/toolkit/ui/skeleton";
|
|
7
|
+
import { Spinner } from "@agent-native/toolkit/ui/spinner";
|
|
8
|
+
import { IconCircleCheck, IconDots, IconMessageCircle, IconSend, IconTrash, IconX, } from "@tabler/icons-react";
|
|
3
9
|
import { useMemo, useState } from "react";
|
|
10
|
+
import { useFormatters } from "../i18n.js";
|
|
4
11
|
import { cn } from "../utils.js";
|
|
12
|
+
import { ReviewCommentComposer } from "./ReviewCommentComposer.js";
|
|
5
13
|
import { ReviewStatusBadge } from "./ReviewStatusBadge.js";
|
|
6
14
|
import { useCreateReviewComment, useDeleteReviewComment, useReplyReviewComment, useResolveReviewThread, useReviewComments, } from "./use-review.js";
|
|
7
|
-
export function ReviewThreadPanel({ resourceType, resourceId, targetId, title = "Review", className, includeResolved = true, showComposer = true, placeholder = "Add a comment...", emptyState = "No review comments yet.", onSelectThread, }) {
|
|
15
|
+
export function ReviewThreadPanel({ resourceType, resourceId, targetId, title = "Review", className, includeResolved = true, showComposer = true, showHeader = true, variant = "card", placeholder = "Add a comment...", emptyState = "No review comments yet.", loadingLabel = "Loading comments", replyLabel = "Reply", replyPlaceholder = "Reply...", cancelReplyLabel = "Cancel reply", resolveLabel = "Resolve", deleteLabel = "Delete comment", moreActionsLabel = "More actions", resolvedLabel = "Resolved", reviewerLabel = "Reviewer", onSelectThread, onCommentCreated, canReply = false, canResolve = false, canDeleteComment = false, renderThreadActions, showComposerTargetPicker = false, composerCommentLabel = "Comment", composerAgentLabel = "Send to agent", }) {
|
|
8
16
|
const [draft, setDraft] = useState("");
|
|
17
|
+
const [submittingTarget, setSubmittingTarget] = useState(null);
|
|
18
|
+
const [replyingThreadId, setReplyingThreadId] = useState(null);
|
|
9
19
|
const [replyDrafts, setReplyDrafts] = useState({});
|
|
20
|
+
const { formatDate } = useFormatters();
|
|
10
21
|
const comments = useReviewComments({
|
|
11
22
|
resourceType,
|
|
12
23
|
resourceId,
|
|
@@ -18,41 +29,77 @@ export function ReviewThreadPanel({ resourceType, resourceId, targetId, title =
|
|
|
18
29
|
const resolveThread = useResolveReviewThread();
|
|
19
30
|
const deleteComment = useDeleteReviewComment();
|
|
20
31
|
const threads = useMemo(() => buildReviewThreads(comments.data?.comments ?? []), [comments.data?.comments]);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
32
|
+
const submitDraft = (resolutionTarget) => {
|
|
33
|
+
const body = draft.trim();
|
|
34
|
+
if (!body || createComment.isPending)
|
|
35
|
+
return;
|
|
36
|
+
setSubmittingTarget(resolutionTarget);
|
|
37
|
+
createComment.mutate({
|
|
38
|
+
resourceType,
|
|
39
|
+
resourceId,
|
|
40
|
+
targetId,
|
|
41
|
+
body,
|
|
42
|
+
...(showComposerTargetPicker ? { resolutionTarget } : {}),
|
|
43
|
+
}, {
|
|
44
|
+
onSuccess: (comment) => {
|
|
45
|
+
setDraft("");
|
|
46
|
+
onCommentCreated?.(comment);
|
|
47
|
+
},
|
|
48
|
+
onSettled: () => setSubmittingTarget(null),
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
return (_jsxs("section", { className: cn("@container/review overflow-hidden text-card-foreground", variant === "card"
|
|
52
|
+
? "rounded-lg border border-border bg-card"
|
|
53
|
+
: "bg-transparent", className), children: [showHeader ? (_jsxs("div", { className: "flex items-center justify-between gap-3 border-b border-border px-3 py-2.5", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(IconMessageCircle, { className: "size-4 shrink-0 text-muted-foreground" }), _jsx("h2", { className: "truncate text-sm font-medium", children: title })] }), _jsx(ReviewStatusBadge, { status: comments.data?.reviewStatus?.status, className: "shrink-0" })] })) : null, showComposer ? (_jsx(ReviewCommentComposer, { className: "border-b border-border px-3 py-3", value: draft, onChange: setDraft, onSubmit: submitDraft, submittingTarget: submittingTarget, disabled: createComment.isPending, showAgentAction: showComposerTargetPicker, placeholder: placeholder, commentLabel: composerCommentLabel, agentLabel: composerAgentLabel })) : null, _jsx("div", { className: "divide-y divide-border", children: comments.isLoading ? (_jsxs("div", { className: "flex flex-col gap-3 px-3 py-4", "aria-label": loadingLabel, children: [_jsxs("div", { className: "flex items-center gap-2.5", children: [_jsx(Skeleton, { className: "size-7 rounded-full" }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [_jsx(Skeleton, { className: "h-3 w-2/5" }), _jsx(Skeleton, { className: "h-3 w-4/5" })] })] }), _jsx(Skeleton, { className: "h-8 w-full" })] })) : threads.length ? (threads.map((thread) => {
|
|
54
|
+
const replyDraft = replyDrafts[thread.root.id] ?? "";
|
|
55
|
+
const replying = replyingThreadId === thread.root.threadId;
|
|
56
|
+
const threadIsOpen = thread.root.status === "open";
|
|
57
|
+
const replyAllowed = threadIsOpen && capabilityAllowsThread(canReply, thread);
|
|
58
|
+
const resolveAllowed = threadIsOpen && capabilityAllowsThread(canResolve, thread);
|
|
59
|
+
const deleteAllowed = capabilityAllowsComment(canDeleteComment, thread.root, thread);
|
|
60
|
+
const threadActions = renderThreadActions?.(thread);
|
|
61
|
+
const hasActions = replyAllowed ||
|
|
62
|
+
resolveAllowed ||
|
|
63
|
+
deleteAllowed ||
|
|
64
|
+
Boolean(threadActions);
|
|
65
|
+
return (_jsxs("article", { className: cn("group/thread px-3 py-3 transition-colors", onSelectThread && "cursor-pointer hover:bg-muted/30"), onClick: () => onSelectThread?.(thread), children: [_jsx(CommentBubble, { comment: thread.root, resolvedLabel: resolvedLabel, reviewerLabel: reviewerLabel, formatDate: formatDate }), thread.replies.length ? (_jsx("div", { className: "ms-3 mt-3 flex flex-col gap-3 border-s border-border ps-3", children: thread.replies.map((reply) => (_jsx(CommentBubble, { comment: reply, compact: true, resolvedLabel: resolvedLabel, reviewerLabel: reviewerLabel, formatDate: formatDate }, reply.id))) })) : null, replying && replyAllowed ? (_jsxs("form", { className: "mt-3 flex min-w-0 items-center gap-1.5", onClick: (event) => event.stopPropagation(), onSubmit: (event) => {
|
|
66
|
+
event.preventDefault();
|
|
67
|
+
const body = replyDraft.trim();
|
|
68
|
+
if (!body || replyComment.isPending)
|
|
69
|
+
return;
|
|
70
|
+
replyComment.mutate({
|
|
52
71
|
resourceType,
|
|
53
72
|
resourceId,
|
|
54
73
|
commentId: thread.root.id,
|
|
55
|
-
|
|
74
|
+
body,
|
|
75
|
+
}, {
|
|
76
|
+
onSuccess: () => {
|
|
77
|
+
setReplyDrafts((current) => ({
|
|
78
|
+
...current,
|
|
79
|
+
[thread.root.id]: "",
|
|
80
|
+
}));
|
|
81
|
+
setReplyingThreadId(null);
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
}, children: [_jsx(Input, { autoFocus: true, value: replyDraft, onChange: (event) => setReplyDrafts((current) => ({
|
|
85
|
+
...current,
|
|
86
|
+
[thread.root.id]: event.currentTarget.value,
|
|
87
|
+
})), onKeyDown: (event) => {
|
|
88
|
+
if (event.key === "Escape") {
|
|
89
|
+
event.preventDefault();
|
|
90
|
+
event.stopPropagation();
|
|
91
|
+
setReplyingThreadId(null);
|
|
92
|
+
}
|
|
93
|
+
}, placeholder: replyPlaceholder, className: "h-8 min-w-0 flex-1 text-sm" }), _jsx(Button, { type: "submit", size: "icon", variant: "outline", className: "size-8 shrink-0", disabled: !replyDraft.trim() || replyComment.isPending, "aria-label": replyLabel, children: replyComment.isPending ? (_jsx(Spinner, { className: "size-3.5" })) : (_jsx(IconSend, { className: "size-3.5" })) }), _jsx(Button, { type: "button", size: "icon", variant: "ghost", className: "size-8 shrink-0", "aria-label": cancelReplyLabel, onClick: () => setReplyingThreadId(null), children: _jsx(IconX, { className: "size-3.5" }) })] })) : hasActions ? (_jsxs("div", { className: "mt-2.5 flex min-w-0 items-center gap-0.5", onClick: (event) => event.stopPropagation(), children: [replyAllowed ? (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "h-7 min-w-0 gap-1.5 px-1.5 text-xs @xs/review:px-2", "aria-label": replyLabel, onClick: () => setReplyingThreadId(thread.root.threadId), children: [_jsx(IconMessageCircle, { className: "size-3.5" }), _jsx("span", { className: "hidden @2xs/review:inline", children: replyLabel })] })) : null, _jsxs("div", { className: "ms-auto flex min-w-0 items-center gap-0.5", children: [threadActions, resolveAllowed ? (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "h-7 min-w-0 gap-1.5 px-1.5 text-xs @xs/review:px-2", disabled: resolveThread.isPending, "aria-label": resolveLabel, onClick: () => resolveThread.mutate({
|
|
94
|
+
resourceType,
|
|
95
|
+
resourceId,
|
|
96
|
+
threadId: thread.root.threadId,
|
|
97
|
+
}), children: [resolveThread.isPending ? (_jsx(Spinner, { className: "size-3.5" })) : (_jsx(IconCircleCheck, { className: "size-3.5" })), _jsx("span", { className: "hidden @xs/review:inline", children: resolveLabel })] })) : null, deleteAllowed ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "size-7 shrink-0", "aria-label": moreActionsLabel, children: _jsx(IconDots, { className: "size-4" }) }) }), _jsx(DropdownMenuContent, { align: "end", className: "w-44", children: _jsxs(DropdownMenuItem, { disabled: deleteComment.isPending, className: "text-destructive focus:text-destructive", onSelect: () => deleteComment.mutate({
|
|
98
|
+
resourceType,
|
|
99
|
+
resourceId,
|
|
100
|
+
commentId: thread.root.id,
|
|
101
|
+
}), children: [_jsx(IconTrash, { className: "size-4" }), deleteLabel] }) })] })) : null] })] })) : null] }, thread.root.threadId));
|
|
102
|
+
})) : (_jsx("div", { className: "px-4 py-8 text-center text-sm text-muted-foreground", children: emptyState })) })] }));
|
|
56
103
|
}
|
|
57
104
|
export function buildReviewThreads(comments) {
|
|
58
105
|
const roots = [];
|
|
@@ -71,14 +118,79 @@ export function buildReviewThreads(comments) {
|
|
|
71
118
|
replies: replies.get(root.threadId) ?? [],
|
|
72
119
|
}));
|
|
73
120
|
}
|
|
74
|
-
function CommentBubble({ comment, compact = false, }) {
|
|
75
|
-
|
|
121
|
+
function CommentBubble({ comment, compact = false, resolvedLabel, reviewerLabel, formatDate, }) {
|
|
122
|
+
const author = comment.authorName ?? comment.authorEmail ?? reviewerLabel;
|
|
123
|
+
const resolutionNote = comment.status === "resolved" ? getReviewResolutionNote(comment) : null;
|
|
124
|
+
const bodyIsResolutionNote = resolutionNote !== null &&
|
|
125
|
+
resolutionNote === comment.body.trim() &&
|
|
126
|
+
isResolutionNoteMetadata(comment.metadata);
|
|
127
|
+
return (_jsxs("div", { className: "flex min-w-0 items-start gap-2.5", children: [_jsx(Avatar, { className: compact ? "size-5" : "size-7", children: _jsx(AvatarFallback, { className: "text-[10px] font-semibold text-muted-foreground", children: authorInitials(author) }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("span", { className: "truncate text-sm font-medium", children: author }), _jsx("time", { className: "shrink-0 text-[11px] text-muted-foreground", dateTime: comment.createdAt, children: formatCommentDate(comment.createdAt, formatDate) }), comment.status === "resolved" ? (_jsx("span", { className: "hidden shrink-0 rounded-full bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground @xs/review:inline-flex", children: resolvedLabel })) : null] }), !bodyIsResolutionNote ? (_jsx("p", { className: cn("mt-1 whitespace-pre-wrap break-words text-foreground", compact ? "text-xs leading-5" : "text-sm leading-5"), children: comment.body })) : null, resolutionNote ? (_jsxs("div", { className: "mt-1.5 flex min-w-0 items-start gap-1.5 rounded-md bg-muted/60 px-2 py-1.5 text-muted-foreground", "aria-label": resolvedLabel, children: [_jsx(IconCircleCheck, { className: "mt-0.5 size-3.5 shrink-0" }), _jsx("p", { className: "min-w-0 whitespace-pre-wrap break-words text-xs leading-4", children: resolutionNote })] })) : null] })] }));
|
|
128
|
+
}
|
|
129
|
+
function capabilityAllowsThread(capability, thread) {
|
|
130
|
+
return typeof capability === "function" ? capability(thread) : capability;
|
|
131
|
+
}
|
|
132
|
+
function capabilityAllowsComment(capability, comment, thread) {
|
|
133
|
+
return typeof capability === "function"
|
|
134
|
+
? capability(comment, thread)
|
|
135
|
+
: capability;
|
|
136
|
+
}
|
|
137
|
+
function getReviewResolutionNote(comment) {
|
|
138
|
+
const direct = comment.resolutionNote;
|
|
139
|
+
const metadata = comment.metadata;
|
|
140
|
+
const nestedResolution = metadata?.resolution;
|
|
141
|
+
const nestedNote = isRecord(nestedResolution) && typeof nestedResolution.note === "string"
|
|
142
|
+
? nestedResolution.note
|
|
143
|
+
: null;
|
|
144
|
+
const metadataNote = typeof metadata?.resolutionNote === "string"
|
|
145
|
+
? metadata.resolutionNote
|
|
146
|
+
: typeof metadata?.resolvedNote === "string"
|
|
147
|
+
? metadata.resolvedNote
|
|
148
|
+
: isResolutionNoteMetadata(metadata) &&
|
|
149
|
+
typeof metadata?.note === "string"
|
|
150
|
+
? metadata.note
|
|
151
|
+
: isResolutionNoteMetadata(metadata)
|
|
152
|
+
? comment.body
|
|
153
|
+
: null;
|
|
154
|
+
const candidate = typeof direct === "string" ? direct : (metadataNote ?? nestedNote);
|
|
155
|
+
const normalized = candidate?.trim();
|
|
156
|
+
return normalized || null;
|
|
76
157
|
}
|
|
77
|
-
function
|
|
158
|
+
function isResolutionNoteMetadata(metadata) {
|
|
159
|
+
const marker = metadata?.type ?? metadata?.kind;
|
|
160
|
+
return (marker === "resolution" ||
|
|
161
|
+
marker === "resolution_note" ||
|
|
162
|
+
marker === "resolution-note");
|
|
163
|
+
}
|
|
164
|
+
function isRecord(value) {
|
|
165
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
166
|
+
}
|
|
167
|
+
function authorInitials(value) {
|
|
168
|
+
const normalized = value.split("@")[0]?.trim() ?? "";
|
|
169
|
+
const parts = normalized.split(/[\s._+-]+/).filter(Boolean);
|
|
170
|
+
const initials = parts
|
|
171
|
+
.slice(0, 2)
|
|
172
|
+
.map((part) => part[0]?.toUpperCase())
|
|
173
|
+
.join("");
|
|
174
|
+
return initials || "R";
|
|
175
|
+
}
|
|
176
|
+
function formatCommentDate(value, formatDate) {
|
|
78
177
|
const date = new Date(value);
|
|
79
|
-
if (Number.isNaN(date.getTime()))
|
|
178
|
+
if (Number.isNaN(date.getTime()))
|
|
80
179
|
return value;
|
|
180
|
+
const now = new Date();
|
|
181
|
+
const sameDay = date.getFullYear() === now.getFullYear() &&
|
|
182
|
+
date.getMonth() === now.getMonth() &&
|
|
183
|
+
date.getDate() === now.getDate();
|
|
184
|
+
if (sameDay) {
|
|
185
|
+
return formatDate(date, { hour: "numeric", minute: "2-digit" });
|
|
81
186
|
}
|
|
82
|
-
|
|
187
|
+
if (date.getFullYear() === now.getFullYear()) {
|
|
188
|
+
return formatDate(date, { month: "short", day: "numeric" });
|
|
189
|
+
}
|
|
190
|
+
return formatDate(date, {
|
|
191
|
+
month: "short",
|
|
192
|
+
day: "numeric",
|
|
193
|
+
year: "numeric",
|
|
194
|
+
});
|
|
83
195
|
}
|
|
84
196
|
//# sourceMappingURL=ReviewThreadPanel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReviewThreadPanel.js","sourceRoot":"","sources":["../../../src/client/review/ReviewThreadPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n IconMessageCircle,\n IconPlus,\n IconSend,\n IconTrash,\n IconCircleCheck,\n} from \"@tabler/icons-react\";\nimport { useMemo, useState } from \"react\";\n\nimport type { ReviewComment } from \"../../review/types.js\";\nimport { cn } from \"../utils.js\";\nimport { ReviewStatusBadge } from \"./ReviewStatusBadge.js\";\nimport {\n useCreateReviewComment,\n useDeleteReviewComment,\n useReplyReviewComment,\n useResolveReviewThread,\n useReviewComments,\n} from \"./use-review.js\";\n\nexport interface ReviewThread {\n root: ReviewComment;\n replies: ReviewComment[];\n}\n\nexport interface ReviewThreadPanelProps {\n resourceType: string;\n resourceId: string;\n targetId?: string | null;\n title?: string;\n className?: string;\n includeResolved?: boolean;\n showComposer?: boolean;\n placeholder?: string;\n emptyState?: string;\n onSelectThread?: (thread: ReviewThread) => void;\n}\n\nexport function ReviewThreadPanel({\n resourceType,\n resourceId,\n targetId,\n title = \"Review\",\n className,\n includeResolved = true,\n showComposer = true,\n placeholder = \"Add a comment...\",\n emptyState = \"No review comments yet.\",\n onSelectThread,\n}: ReviewThreadPanelProps) {\n const [draft, setDraft] = useState(\"\");\n const [replyDrafts, setReplyDrafts] = useState<Record<string, string>>({});\n const comments = useReviewComments({\n resourceType,\n resourceId,\n targetId,\n includeResolved,\n });\n const createComment = useCreateReviewComment();\n const replyComment = useReplyReviewComment();\n const resolveThread = useResolveReviewThread();\n const deleteComment = useDeleteReviewComment();\n const threads = useMemo(\n () => buildReviewThreads(comments.data?.comments ?? []),\n [comments.data?.comments],\n );\n\n return (\n <section\n className={cn(\n \"rounded-lg border border-border bg-card text-card-foreground\",\n className,\n )}\n >\n <div className=\"flex items-center justify-between gap-3 border-b border-border px-4 py-3\">\n <div className=\"flex items-center gap-2\">\n <IconMessageCircle className=\"h-4 w-4 text-muted-foreground\" />\n <h2 className=\"text-sm font-medium\">{title}</h2>\n </div>\n <ReviewStatusBadge status={comments.data?.reviewStatus?.status} />\n </div>\n\n {showComposer ? (\n <form\n className=\"border-b border-border p-3\"\n onSubmit={(event) => {\n event.preventDefault();\n const body = draft.trim();\n if (!body) return;\n createComment.mutate(\n { resourceType, resourceId, targetId, body },\n { onSuccess: () => setDraft(\"\") },\n );\n }}\n >\n <textarea\n value={draft}\n onChange={(event) => setDraft(event.currentTarget.value)}\n placeholder={placeholder}\n className=\"min-h-20 w-full resize-y rounded-md border border-input bg-background px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-ring\"\n />\n <div className=\"mt-2 flex justify-end\">\n <button\n type=\"submit\"\n disabled={!draft.trim() || createComment.isPending}\n className=\"inline-flex h-8 items-center gap-1.5 rounded-md bg-primary px-3 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <IconPlus className=\"h-3.5 w-3.5\" />\n Comment\n </button>\n </div>\n </form>\n ) : null}\n\n <div className=\"divide-y divide-border\">\n {comments.isLoading ? (\n <div className=\"px-4 py-6 text-sm text-muted-foreground\">\n Loading comments...\n </div>\n ) : threads.length ? (\n threads.map((thread) => (\n <article\n key={thread.root.threadId}\n className=\"px-4 py-3\"\n onClick={() => onSelectThread?.(thread)}\n >\n <CommentBubble comment={thread.root} />\n {thread.replies.length ? (\n <div className=\"mt-3 space-y-3 border-l border-border pl-4\">\n {thread.replies.map((reply) => (\n <CommentBubble key={reply.id} comment={reply} compact />\n ))}\n </div>\n ) : null}\n <form\n className=\"mt-3 flex gap-2\"\n onSubmit={(event) => {\n event.preventDefault();\n const body = replyDrafts[thread.root.id]?.trim();\n if (!body) return;\n replyComment.mutate(\n {\n resourceType,\n resourceId,\n commentId: thread.root.id,\n body,\n },\n {\n onSuccess: () =>\n setReplyDrafts((current) => ({\n ...current,\n [thread.root.id]: \"\",\n })),\n },\n );\n }}\n >\n <input\n value={replyDrafts[thread.root.id] ?? \"\"}\n onChange={(event) =>\n setReplyDrafts((current) => ({\n ...current,\n [thread.root.id]: event.currentTarget.value,\n }))\n }\n placeholder=\"Reply...\"\n className=\"h-8 min-w-0 flex-1 rounded-md border border-input bg-background px-3 text-sm outline-none focus:ring-2 focus:ring-ring\"\n />\n <button\n type=\"submit\"\n disabled={\n !replyDrafts[thread.root.id]?.trim() ||\n replyComment.isPending\n }\n className=\"inline-flex h-8 w-8 items-center justify-center rounded-md border border-input hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label=\"Reply\"\n >\n <IconSend className=\"h-3.5 w-3.5\" />\n </button>\n {thread.root.status !== \"resolved\" ? (\n <button\n type=\"button\"\n className=\"inline-flex h-8 w-8 items-center justify-center rounded-md border border-input hover:bg-accent\"\n aria-label=\"Resolve thread\"\n onClick={() =>\n resolveThread.mutate({\n resourceType,\n resourceId,\n threadId: thread.root.threadId,\n })\n }\n >\n <IconCircleCheck className=\"h-3.5 w-3.5\" />\n </button>\n ) : null}\n <button\n type=\"button\"\n className=\"inline-flex h-8 w-8 items-center justify-center rounded-md border border-input text-muted-foreground hover:bg-accent\"\n aria-label=\"Delete comment\"\n onClick={() =>\n deleteComment.mutate({\n resourceType,\n resourceId,\n commentId: thread.root.id,\n })\n }\n >\n <IconTrash className=\"h-3.5 w-3.5\" />\n </button>\n </form>\n </article>\n ))\n ) : (\n <div className=\"px-4 py-6 text-sm text-muted-foreground\">\n {emptyState}\n </div>\n )}\n </div>\n </section>\n );\n}\n\nexport function buildReviewThreads(comments: ReviewComment[]): ReviewThread[] {\n const roots: ReviewComment[] = [];\n const replies = new Map<string, ReviewComment[]>();\n\n for (const comment of comments) {\n if (!comment.parentCommentId || comment.parentCommentId === comment.id) {\n roots.push(comment);\n continue;\n }\n const list = replies.get(comment.threadId) ?? [];\n list.push(comment);\n replies.set(comment.threadId, list);\n }\n\n return roots.map((root) => ({\n root,\n replies: replies.get(root.threadId) ?? [],\n }));\n}\n\nfunction CommentBubble({\n comment,\n compact = false,\n}: {\n comment: ReviewComment;\n compact?: boolean;\n}) {\n return (\n <div className={compact ? \"text-sm\" : \"\"}>\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-medium\">\n {comment.authorName ?? comment.authorEmail ?? \"Reviewer\"}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {formatCommentDate(comment.createdAt)}\n </span>\n {comment.status === \"resolved\" ? (\n <span className=\"rounded-full bg-emerald-50 px-2 py-0.5 text-xs text-emerald-700\">\n Resolved\n </span>\n ) : null}\n </div>\n <p className=\"mt-1 whitespace-pre-wrap text-sm text-foreground\">\n {comment.body}\n </p>\n </div>\n );\n}\n\nfunction formatCommentDate(value: string): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return value;\n }\n return date.toLocaleString();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ReviewThreadPanel.js","sourceRoot":"","sources":["../../../src/client/review/ReviewThreadPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Avatar, AvatarFallback } from \"@agent-native/toolkit/ui/avatar\";\nimport { Button } from \"@agent-native/toolkit/ui/button\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@agent-native/toolkit/ui/dropdown-menu\";\nimport { Input } from \"@agent-native/toolkit/ui/input\";\nimport { Skeleton } from \"@agent-native/toolkit/ui/skeleton\";\nimport { Spinner } from \"@agent-native/toolkit/ui/spinner\";\nimport {\n IconCircleCheck,\n IconDots,\n IconMessageCircle,\n IconSend,\n IconTrash,\n IconX,\n} from \"@tabler/icons-react\";\nimport { useMemo, useState, type ReactNode } from \"react\";\n\nimport type {\n ReviewComment,\n ReviewResolutionTarget,\n} from \"../../review/types.js\";\nimport { useFormatters } from \"../i18n.js\";\nimport { cn } from \"../utils.js\";\nimport { ReviewCommentComposer } from \"./ReviewCommentComposer.js\";\nimport { ReviewStatusBadge } from \"./ReviewStatusBadge.js\";\nimport {\n useCreateReviewComment,\n useDeleteReviewComment,\n useReplyReviewComment,\n useResolveReviewThread,\n useReviewComments,\n} from \"./use-review.js\";\n\nexport interface ReviewThread {\n root: ReviewComment;\n replies: ReviewComment[];\n}\n\nexport type ReviewThreadCapability =\n | boolean\n | ((thread: ReviewThread) => boolean);\n\nexport type ReviewCommentCapability =\n | boolean\n | ((comment: ReviewComment, thread: ReviewThread) => boolean);\n\nexport interface ReviewThreadPanelProps {\n resourceType: string;\n resourceId: string;\n targetId?: string | null;\n title?: string;\n className?: string;\n includeResolved?: boolean;\n showComposer?: boolean;\n showHeader?: boolean;\n variant?: \"card\" | \"plain\";\n placeholder?: string;\n emptyState?: string;\n loadingLabel?: string;\n replyLabel?: string;\n replyPlaceholder?: string;\n cancelReplyLabel?: string;\n resolveLabel?: string;\n deleteLabel?: string;\n moreActionsLabel?: string;\n resolvedLabel?: string;\n reviewerLabel?: string;\n onSelectThread?: (thread: ReviewThread) => void;\n onCommentCreated?: (comment: ReviewComment) => void;\n /** Allow signed-in commenters to reply. Omitted capabilities fail closed. */\n canReply?: ReviewThreadCapability;\n /** Allow editors to resolve a thread. Omitted capabilities fail closed. */\n canResolve?: ReviewThreadCapability;\n /** Allow deletion only for comments the caller has authorized. */\n canDeleteComment?: ReviewCommentCapability;\n /** Extra per-thread controls rendered next to reply/resolve/delete. */\n renderThreadActions?: (thread: ReviewThread) => ReactNode;\n /** Show a separate agent-submit action when the host supports agent routing. */\n showComposerTargetPicker?: boolean;\n composerCommentLabel?: string;\n composerAgentLabel?: string;\n}\n\nexport function ReviewThreadPanel({\n resourceType,\n resourceId,\n targetId,\n title = \"Review\",\n className,\n includeResolved = true,\n showComposer = true,\n showHeader = true,\n variant = \"card\",\n placeholder = \"Add a comment...\",\n emptyState = \"No review comments yet.\",\n loadingLabel = \"Loading comments\",\n replyLabel = \"Reply\",\n replyPlaceholder = \"Reply...\",\n cancelReplyLabel = \"Cancel reply\",\n resolveLabel = \"Resolve\",\n deleteLabel = \"Delete comment\",\n moreActionsLabel = \"More actions\",\n resolvedLabel = \"Resolved\",\n reviewerLabel = \"Reviewer\",\n onSelectThread,\n onCommentCreated,\n canReply = false,\n canResolve = false,\n canDeleteComment = false,\n renderThreadActions,\n showComposerTargetPicker = false,\n composerCommentLabel = \"Comment\",\n composerAgentLabel = \"Send to agent\",\n}: ReviewThreadPanelProps) {\n const [draft, setDraft] = useState(\"\");\n const [submittingTarget, setSubmittingTarget] =\n useState<ReviewResolutionTarget | null>(null);\n const [replyingThreadId, setReplyingThreadId] = useState<string | null>(null);\n const [replyDrafts, setReplyDrafts] = useState<Record<string, string>>({});\n const { formatDate } = useFormatters();\n const comments = useReviewComments({\n resourceType,\n resourceId,\n targetId,\n includeResolved,\n });\n const createComment = useCreateReviewComment();\n const replyComment = useReplyReviewComment();\n const resolveThread = useResolveReviewThread();\n const deleteComment = useDeleteReviewComment();\n const threads = useMemo(\n () => buildReviewThreads(comments.data?.comments ?? []),\n [comments.data?.comments],\n );\n\n const submitDraft = (resolutionTarget: ReviewResolutionTarget) => {\n const body = draft.trim();\n if (!body || createComment.isPending) return;\n setSubmittingTarget(resolutionTarget);\n createComment.mutate(\n {\n resourceType,\n resourceId,\n targetId,\n body,\n ...(showComposerTargetPicker ? { resolutionTarget } : {}),\n },\n {\n onSuccess: (comment) => {\n setDraft(\"\");\n onCommentCreated?.(comment);\n },\n onSettled: () => setSubmittingTarget(null),\n },\n );\n };\n\n return (\n <section\n className={cn(\n \"@container/review overflow-hidden text-card-foreground\",\n variant === \"card\"\n ? \"rounded-lg border border-border bg-card\"\n : \"bg-transparent\",\n className,\n )}\n >\n {showHeader ? (\n <div className=\"flex items-center justify-between gap-3 border-b border-border px-3 py-2.5\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconMessageCircle className=\"size-4 shrink-0 text-muted-foreground\" />\n <h2 className=\"truncate text-sm font-medium\">{title}</h2>\n </div>\n <ReviewStatusBadge\n status={comments.data?.reviewStatus?.status}\n className=\"shrink-0\"\n />\n </div>\n ) : null}\n\n {showComposer ? (\n <ReviewCommentComposer\n className=\"border-b border-border px-3 py-3\"\n value={draft}\n onChange={setDraft}\n onSubmit={submitDraft}\n submittingTarget={submittingTarget}\n disabled={createComment.isPending}\n showAgentAction={showComposerTargetPicker}\n placeholder={placeholder}\n commentLabel={composerCommentLabel}\n agentLabel={composerAgentLabel}\n />\n ) : null}\n\n <div className=\"divide-y divide-border\">\n {comments.isLoading ? (\n <div\n className=\"flex flex-col gap-3 px-3 py-4\"\n aria-label={loadingLabel}\n >\n <div className=\"flex items-center gap-2.5\">\n <Skeleton className=\"size-7 rounded-full\" />\n <div className=\"flex min-w-0 flex-1 flex-col gap-1.5\">\n <Skeleton className=\"h-3 w-2/5\" />\n <Skeleton className=\"h-3 w-4/5\" />\n </div>\n </div>\n <Skeleton className=\"h-8 w-full\" />\n </div>\n ) : threads.length ? (\n threads.map((thread) => {\n const replyDraft = replyDrafts[thread.root.id] ?? \"\";\n const replying = replyingThreadId === thread.root.threadId;\n const threadIsOpen = thread.root.status === \"open\";\n const replyAllowed =\n threadIsOpen && capabilityAllowsThread(canReply, thread);\n const resolveAllowed =\n threadIsOpen && capabilityAllowsThread(canResolve, thread);\n const deleteAllowed = capabilityAllowsComment(\n canDeleteComment,\n thread.root,\n thread,\n );\n const threadActions = renderThreadActions?.(thread);\n const hasActions =\n replyAllowed ||\n resolveAllowed ||\n deleteAllowed ||\n Boolean(threadActions);\n return (\n <article\n key={thread.root.threadId}\n className={cn(\n \"group/thread px-3 py-3 transition-colors\",\n onSelectThread && \"cursor-pointer hover:bg-muted/30\",\n )}\n onClick={() => onSelectThread?.(thread)}\n >\n <CommentBubble\n comment={thread.root}\n resolvedLabel={resolvedLabel}\n reviewerLabel={reviewerLabel}\n formatDate={formatDate}\n />\n {thread.replies.length ? (\n <div className=\"ms-3 mt-3 flex flex-col gap-3 border-s border-border ps-3\">\n {thread.replies.map((reply) => (\n <CommentBubble\n key={reply.id}\n comment={reply}\n compact\n resolvedLabel={resolvedLabel}\n reviewerLabel={reviewerLabel}\n formatDate={formatDate}\n />\n ))}\n </div>\n ) : null}\n\n {replying && replyAllowed ? (\n <form\n className=\"mt-3 flex min-w-0 items-center gap-1.5\"\n onClick={(event) => event.stopPropagation()}\n onSubmit={(event) => {\n event.preventDefault();\n const body = replyDraft.trim();\n if (!body || replyComment.isPending) return;\n replyComment.mutate(\n {\n resourceType,\n resourceId,\n commentId: thread.root.id,\n body,\n },\n {\n onSuccess: () => {\n setReplyDrafts((current) => ({\n ...current,\n [thread.root.id]: \"\",\n }));\n setReplyingThreadId(null);\n },\n },\n );\n }}\n >\n <Input\n autoFocus\n value={replyDraft}\n onChange={(event) =>\n setReplyDrafts((current) => ({\n ...current,\n [thread.root.id]: event.currentTarget.value,\n }))\n }\n onKeyDown={(event) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n setReplyingThreadId(null);\n }\n }}\n placeholder={replyPlaceholder}\n className=\"h-8 min-w-0 flex-1 text-sm\"\n />\n <Button\n type=\"submit\"\n size=\"icon\"\n variant=\"outline\"\n className=\"size-8 shrink-0\"\n disabled={!replyDraft.trim() || replyComment.isPending}\n aria-label={replyLabel}\n >\n {replyComment.isPending ? (\n <Spinner className=\"size-3.5\" />\n ) : (\n <IconSend className=\"size-3.5\" />\n )}\n </Button>\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"ghost\"\n className=\"size-8 shrink-0\"\n aria-label={cancelReplyLabel}\n onClick={() => setReplyingThreadId(null)}\n >\n <IconX className=\"size-3.5\" />\n </Button>\n </form>\n ) : hasActions ? (\n <div\n className=\"mt-2.5 flex min-w-0 items-center gap-0.5\"\n onClick={(event) => event.stopPropagation()}\n >\n {replyAllowed ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 min-w-0 gap-1.5 px-1.5 text-xs @xs/review:px-2\"\n aria-label={replyLabel}\n onClick={() =>\n setReplyingThreadId(thread.root.threadId)\n }\n >\n <IconMessageCircle className=\"size-3.5\" />\n <span className=\"hidden @2xs/review:inline\">\n {replyLabel}\n </span>\n </Button>\n ) : null}\n <div className=\"ms-auto flex min-w-0 items-center gap-0.5\">\n {threadActions}\n {resolveAllowed ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 min-w-0 gap-1.5 px-1.5 text-xs @xs/review:px-2\"\n disabled={resolveThread.isPending}\n aria-label={resolveLabel}\n onClick={() =>\n resolveThread.mutate({\n resourceType,\n resourceId,\n threadId: thread.root.threadId,\n })\n }\n >\n {resolveThread.isPending ? (\n <Spinner className=\"size-3.5\" />\n ) : (\n <IconCircleCheck className=\"size-3.5\" />\n )}\n <span className=\"hidden @xs/review:inline\">\n {resolveLabel}\n </span>\n </Button>\n ) : null}\n {deleteAllowed ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7 shrink-0\"\n aria-label={moreActionsLabel}\n >\n <IconDots className=\"size-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-44\">\n <DropdownMenuItem\n disabled={deleteComment.isPending}\n className=\"text-destructive focus:text-destructive\"\n onSelect={() =>\n deleteComment.mutate({\n resourceType,\n resourceId,\n commentId: thread.root.id,\n })\n }\n >\n <IconTrash className=\"size-4\" />\n {deleteLabel}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n </div>\n </div>\n ) : null}\n </article>\n );\n })\n ) : (\n <div className=\"px-4 py-8 text-center text-sm text-muted-foreground\">\n {emptyState}\n </div>\n )}\n </div>\n </section>\n );\n}\n\nexport function buildReviewThreads(comments: ReviewComment[]): ReviewThread[] {\n const roots: ReviewComment[] = [];\n const replies = new Map<string, ReviewComment[]>();\n\n for (const comment of comments) {\n if (!comment.parentCommentId || comment.parentCommentId === comment.id) {\n roots.push(comment);\n continue;\n }\n const list = replies.get(comment.threadId) ?? [];\n list.push(comment);\n replies.set(comment.threadId, list);\n }\n\n return roots.map((root) => ({\n root,\n replies: replies.get(root.threadId) ?? [],\n }));\n}\n\nfunction CommentBubble({\n comment,\n compact = false,\n resolvedLabel,\n reviewerLabel,\n formatDate,\n}: {\n comment: ReviewComment;\n compact?: boolean;\n resolvedLabel: string;\n reviewerLabel: string;\n formatDate: ReturnType<typeof useFormatters>[\"formatDate\"];\n}) {\n const author = comment.authorName ?? comment.authorEmail ?? reviewerLabel;\n const resolutionNote =\n comment.status === \"resolved\" ? getReviewResolutionNote(comment) : null;\n const bodyIsResolutionNote =\n resolutionNote !== null &&\n resolutionNote === comment.body.trim() &&\n isResolutionNoteMetadata(comment.metadata);\n return (\n <div className=\"flex min-w-0 items-start gap-2.5\">\n <Avatar className={compact ? \"size-5\" : \"size-7\"}>\n <AvatarFallback className=\"text-[10px] font-semibold text-muted-foreground\">\n {authorInitials(author)}\n </AvatarFallback>\n </Avatar>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"truncate text-sm font-medium\">{author}</span>\n <time\n className=\"shrink-0 text-[11px] text-muted-foreground\"\n dateTime={comment.createdAt}\n >\n {formatCommentDate(comment.createdAt, formatDate)}\n </time>\n {comment.status === \"resolved\" ? (\n <span className=\"hidden shrink-0 rounded-full bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground @xs/review:inline-flex\">\n {resolvedLabel}\n </span>\n ) : null}\n </div>\n {!bodyIsResolutionNote ? (\n <p\n className={cn(\n \"mt-1 whitespace-pre-wrap break-words text-foreground\",\n compact ? \"text-xs leading-5\" : \"text-sm leading-5\",\n )}\n >\n {comment.body}\n </p>\n ) : null}\n {resolutionNote ? (\n <div\n className=\"mt-1.5 flex min-w-0 items-start gap-1.5 rounded-md bg-muted/60 px-2 py-1.5 text-muted-foreground\"\n aria-label={resolvedLabel}\n >\n <IconCircleCheck className=\"mt-0.5 size-3.5 shrink-0\" />\n <p className=\"min-w-0 whitespace-pre-wrap break-words text-xs leading-4\">\n {resolutionNote}\n </p>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction capabilityAllowsThread(\n capability: ReviewThreadCapability,\n thread: ReviewThread,\n): boolean {\n return typeof capability === \"function\" ? capability(thread) : capability;\n}\n\nfunction capabilityAllowsComment(\n capability: ReviewCommentCapability,\n comment: ReviewComment,\n thread: ReviewThread,\n): boolean {\n return typeof capability === \"function\"\n ? capability(comment, thread)\n : capability;\n}\n\nfunction getReviewResolutionNote(comment: ReviewComment): string | null {\n const direct = comment.resolutionNote;\n const metadata = comment.metadata;\n const nestedResolution = metadata?.resolution;\n const nestedNote =\n isRecord(nestedResolution) && typeof nestedResolution.note === \"string\"\n ? nestedResolution.note\n : null;\n const metadataNote =\n typeof metadata?.resolutionNote === \"string\"\n ? metadata.resolutionNote\n : typeof metadata?.resolvedNote === \"string\"\n ? metadata.resolvedNote\n : isResolutionNoteMetadata(metadata) &&\n typeof metadata?.note === \"string\"\n ? metadata.note\n : isResolutionNoteMetadata(metadata)\n ? comment.body\n : null;\n const candidate =\n typeof direct === \"string\" ? direct : (metadataNote ?? nestedNote);\n const normalized = candidate?.trim();\n return normalized || null;\n}\n\nfunction isResolutionNoteMetadata(\n metadata: Record<string, unknown> | null,\n): boolean {\n const marker = metadata?.type ?? metadata?.kind;\n return (\n marker === \"resolution\" ||\n marker === \"resolution_note\" ||\n marker === \"resolution-note\"\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction authorInitials(value: string): string {\n const normalized = value.split(\"@\")[0]?.trim() ?? \"\";\n const parts = normalized.split(/[\\s._+-]+/).filter(Boolean);\n const initials = parts\n .slice(0, 2)\n .map((part) => part[0]?.toUpperCase())\n .join(\"\");\n return initials || \"R\";\n}\n\nfunction formatCommentDate(\n value: string,\n formatDate: ReturnType<typeof useFormatters>[\"formatDate\"],\n): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n const now = new Date();\n const sameDay =\n date.getFullYear() === now.getFullYear() &&\n date.getMonth() === now.getMonth() &&\n date.getDate() === now.getDate();\n if (sameDay) {\n return formatDate(date, { hour: \"numeric\", minute: \"2-digit\" });\n }\n if (date.getFullYear() === now.getFullYear()) {\n return formatDate(date, { month: \"short\", day: \"numeric\" });\n }\n return formatDate(date, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
export { ReviewCommentComposer, type ReviewCommentComposerProps, } from "./ReviewCommentComposer.js";
|
|
1
2
|
export { ReviewStatusBadge, type ReviewStatusBadgeProps, } from "./ReviewStatusBadge.js";
|
|
2
|
-
export { ReviewThreadPanel, buildReviewThreads, type ReviewThread, type ReviewThreadPanelProps, } from "./ReviewThreadPanel.js";
|
|
3
|
-
export { useConsumeReviewFeedback, useCreateReviewComment, useDeleteReviewComment, useReplyReviewComment, useResolveReviewThread, useReviewComments, useReviewFeedback, useSetReviewStatus, type ConsumeReviewFeedbackInput, type CreateReviewCommentInput, type DeleteReviewCommentInput, type GetReviewFeedbackParams, type GetReviewFeedbackResult, type ListReviewCommentsParams, type ListReviewCommentsResult, type ReplyReviewCommentInput, type ResolveReviewThreadInput, type SetReviewStatusInput, } from "./use-review.js";
|
|
3
|
+
export { ReviewThreadPanel, buildReviewThreads, type ReviewThread, type ReviewCommentCapability, type ReviewThreadCapability, type ReviewThreadPanelProps, } from "./ReviewThreadPanel.js";
|
|
4
|
+
export { useConsumeReviewFeedback, useCreateReviewComment, useDeleteReviewComment, useReplyReviewComment, useResolveReviewThread, useReviewComments, useReviewFeedback, useSetReviewStatus, useSendReviewThreadToAgent, type ConsumeReviewFeedbackInput, type CreateReviewCommentInput, type DeleteReviewCommentInput, type GetReviewFeedbackParams, type GetReviewFeedbackResult, type ListReviewCommentsParams, type ListReviewCommentsResult, type ReplyReviewCommentInput, type ResolveReviewThreadInput, type SetReviewStatusInput, type SendReviewThreadToAgentInput, } from "./use-review.js";
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/review/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,KAAK,sBAAsB,GAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,YAAY,EACjB,KAAK,sBAAsB,GAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/review/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,0BAA0B,GAChC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,iBAAiB,EACjB,KAAK,sBAAsB,GAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,GAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,EAC1B,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,GAClC,MAAM,iBAAiB,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
export { ReviewCommentComposer, } from "./ReviewCommentComposer.js";
|
|
1
2
|
export { ReviewStatusBadge, } from "./ReviewStatusBadge.js";
|
|
2
3
|
export { ReviewThreadPanel, buildReviewThreads, } from "./ReviewThreadPanel.js";
|
|
3
|
-
export { useConsumeReviewFeedback, useCreateReviewComment, useDeleteReviewComment, useReplyReviewComment, useResolveReviewThread, useReviewComments, useReviewFeedback, useSetReviewStatus, } from "./use-review.js";
|
|
4
|
+
export { useConsumeReviewFeedback, useCreateReviewComment, useDeleteReviewComment, useReplyReviewComment, useResolveReviewThread, useReviewComments, useReviewFeedback, useSetReviewStatus, useSendReviewThreadToAgent, } from "./use-review.js";
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/review/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/review/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,GAEtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,iBAAiB,GAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,GAKnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,GAY3B,MAAM,iBAAiB,CAAC","sourcesContent":["export {\n ReviewCommentComposer,\n type ReviewCommentComposerProps,\n} from \"./ReviewCommentComposer.js\";\nexport {\n ReviewStatusBadge,\n type ReviewStatusBadgeProps,\n} from \"./ReviewStatusBadge.js\";\nexport {\n ReviewThreadPanel,\n buildReviewThreads,\n type ReviewThread,\n type ReviewCommentCapability,\n type ReviewThreadCapability,\n type ReviewThreadPanelProps,\n} from \"./ReviewThreadPanel.js\";\nexport {\n useConsumeReviewFeedback,\n useCreateReviewComment,\n useDeleteReviewComment,\n useReplyReviewComment,\n useResolveReviewThread,\n useReviewComments,\n useReviewFeedback,\n useSetReviewStatus,\n useSendReviewThreadToAgent,\n type ConsumeReviewFeedbackInput,\n type CreateReviewCommentInput,\n type DeleteReviewCommentInput,\n type GetReviewFeedbackParams,\n type GetReviewFeedbackResult,\n type ListReviewCommentsParams,\n type ListReviewCommentsResult,\n type ReplyReviewCommentInput,\n type ResolveReviewThreadInput,\n type SetReviewStatusInput,\n type SendReviewThreadToAgentInput,\n} from \"./use-review.js\";\n"]}
|
|
@@ -10,6 +10,10 @@ export interface ListReviewCommentsParams {
|
|
|
10
10
|
export interface ListReviewCommentsResult {
|
|
11
11
|
comments: ReviewComment[];
|
|
12
12
|
reviewStatus: ReviewStatusEntry | null;
|
|
13
|
+
summary: {
|
|
14
|
+
openCount: number;
|
|
15
|
+
agentQueueCount: number;
|
|
16
|
+
};
|
|
13
17
|
}
|
|
14
18
|
export interface GetReviewFeedbackParams {
|
|
15
19
|
resourceType: string;
|
|
@@ -47,6 +51,7 @@ export interface ResolveReviewThreadInput {
|
|
|
47
51
|
resourceId: string;
|
|
48
52
|
threadId?: string;
|
|
49
53
|
commentId?: string;
|
|
54
|
+
resolutionNote?: string;
|
|
50
55
|
}
|
|
51
56
|
export interface DeleteReviewCommentInput {
|
|
52
57
|
resourceType: string;
|
|
@@ -58,6 +63,11 @@ export interface ConsumeReviewFeedbackInput {
|
|
|
58
63
|
resourceId: string;
|
|
59
64
|
commentIds: string[];
|
|
60
65
|
}
|
|
66
|
+
export interface SendReviewThreadToAgentInput {
|
|
67
|
+
resourceType: string;
|
|
68
|
+
resourceId: string;
|
|
69
|
+
threadId: string;
|
|
70
|
+
}
|
|
61
71
|
export interface SetReviewStatusInput {
|
|
62
72
|
resourceType: string;
|
|
63
73
|
resourceId: string;
|
|
@@ -77,6 +87,8 @@ export declare function useResolveReviewThread(): import("@tanstack/react-query"
|
|
|
77
87
|
threadId: string;
|
|
78
88
|
resolved: true;
|
|
79
89
|
updatedCount: number;
|
|
90
|
+
resolutionNote: string | null;
|
|
91
|
+
comment: ReviewComment;
|
|
80
92
|
}, Error, ResolveReviewThreadInput, unknown>;
|
|
81
93
|
export declare function useDeleteReviewComment(): import("@tanstack/react-query").UseMutationResult<{
|
|
82
94
|
commentId: string;
|
|
@@ -87,5 +99,16 @@ export declare function useConsumeReviewFeedback(): import("@tanstack/react-quer
|
|
|
87
99
|
consumedCommentIds: string[];
|
|
88
100
|
updatedCount: number;
|
|
89
101
|
}, Error, ConsumeReviewFeedbackInput, unknown>;
|
|
102
|
+
export declare function useSendReviewThreadToAgent(): import("@tanstack/react-query").UseMutationResult<{
|
|
103
|
+
resourceType: string;
|
|
104
|
+
resourceId: string;
|
|
105
|
+
threadId: string;
|
|
106
|
+
resolutionTarget: "agent";
|
|
107
|
+
consumedAt: null;
|
|
108
|
+
updatedCount: number;
|
|
109
|
+
ownerEmail: string | null;
|
|
110
|
+
orgId: string | null;
|
|
111
|
+
visibility: "private" | "org" | "public";
|
|
112
|
+
}, Error, SendReviewThreadToAgentInput, unknown>;
|
|
90
113
|
export declare function useSetReviewStatus(): import("@tanstack/react-query").UseMutationResult<ReviewStatusEntry, Error, SetReviewStatusInput, unknown>;
|
|
91
114
|
//# sourceMappingURL=use-review.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-review.d.ts","sourceRoot":"","sources":["../../../src/client/review/use-review.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,sBAAsB,EACtB,YAAY,EACZ,iBAAiB,EAClB,MAAM,uBAAuB,CAAC;AAG/B,MAAM,WAAW,wBAAwB;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,YAAY,EAAE,iBAAiB,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"use-review.d.ts","sourceRoot":"","sources":["../../../src/client/review/use-review.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,9 @@ export function useDeleteReviewComment() {
|
|
|
24
24
|
export function useConsumeReviewFeedback() {
|
|
25
25
|
return useActionMutation("consume-review-feedback");
|
|
26
26
|
}
|
|
27
|
+
export function useSendReviewThreadToAgent() {
|
|
28
|
+
return useActionMutation("send-review-thread-to-agent");
|
|
29
|
+
}
|
|
27
30
|
export function useSetReviewStatus() {
|
|
28
31
|
return useActionMutation("set-review-status");
|
|
29
32
|
}
|