@agent-native/core 0.101.6 → 0.101.10

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.
Files changed (237) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +28 -0
  3. package/corpus/core/docs/content/deployment.mdx +9 -7
  4. package/corpus/core/docs/content/locales/ar-SA/deployment.mdx +9 -7
  5. package/corpus/core/docs/content/locales/de-DE/deployment.mdx +9 -7
  6. package/corpus/core/docs/content/locales/es-ES/deployment.mdx +9 -7
  7. package/corpus/core/docs/content/locales/fr-FR/deployment.mdx +9 -7
  8. package/corpus/core/docs/content/locales/hi-IN/deployment.mdx +9 -7
  9. package/corpus/core/docs/content/locales/ja-JP/deployment.mdx +9 -7
  10. package/corpus/core/docs/content/locales/ko-KR/deployment.mdx +9 -7
  11. package/corpus/core/docs/content/locales/pt-BR/deployment.mdx +9 -7
  12. package/corpus/core/docs/content/locales/zh-CN/deployment.mdx +9 -7
  13. package/corpus/core/docs/content/locales/zh-TW/deployment.mdx +9 -7
  14. package/corpus/core/package.json +1 -1
  15. package/corpus/core/src/a2a/artifact-response.ts +255 -12
  16. package/corpus/core/src/agent/thread-data-builder.ts +84 -11
  17. package/corpus/core/src/client/review/ReviewCommentComposer.tsx +9 -1
  18. package/corpus/core/src/client/review/ReviewThreadPanel.tsx +17 -2
  19. package/corpus/core/src/client/settings/SettingsPanel.tsx +41 -21
  20. package/corpus/core/src/client/settings/useBuilderStatus.ts +28 -9
  21. package/corpus/core/src/client/setup-connections/BuilderConnectCard.tsx +2 -7
  22. package/corpus/core/src/integrations/a2a-continuation-processor.ts +99 -7
  23. package/corpus/core/src/integrations/adapters/discord.ts +3 -1
  24. package/corpus/core/src/integrations/adapters/email.ts +4 -1
  25. package/corpus/core/src/integrations/adapters/google-docs.ts +4 -1
  26. package/corpus/core/src/integrations/adapters/microsoft-teams.ts +3 -1
  27. package/corpus/core/src/integrations/adapters/slack.ts +38 -9
  28. package/corpus/core/src/integrations/adapters/telegram.ts +32 -10
  29. package/corpus/core/src/integrations/adapters/whatsapp.ts +5 -1
  30. package/corpus/core/src/integrations/index.ts +1 -0
  31. package/corpus/core/src/integrations/types.ts +9 -2
  32. package/corpus/core/src/integrations/webhook-handler.ts +69 -45
  33. package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +1 -0
  34. package/corpus/core/src/server/auth.ts +25 -1
  35. package/corpus/core/src/server/builder-browser.ts +353 -1
  36. package/corpus/core/src/server/core-routes-plugin.ts +601 -223
  37. package/corpus/templates/calendar/app/components/calendar/DayView.tsx +80 -1
  38. package/corpus/templates/calendar/app/components/calendar/EventCard.tsx +28 -3
  39. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +5 -1
  40. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +30 -3
  41. package/corpus/templates/calendar/app/components/calendar/OutOfOfficeEvent.tsx +196 -0
  42. package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +115 -1
  43. package/corpus/templates/calendar/app/lib/out-of-office.ts +45 -0
  44. package/corpus/templates/calendar/changelog/2026-07-14-out-of-office-blocks-now-sit-behind-meetings-and-event-stack.md +6 -0
  45. package/corpus/templates/content/.agents/skills/content/SKILL.md +31 -0
  46. package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +35 -21
  47. package/corpus/templates/content/AGENTS.md +32 -9
  48. package/corpus/templates/content/actions/_builder-cms-intent-lookup.ts +87 -0
  49. package/corpus/templates/content/actions/_builder-cms-read-client.ts +173 -25
  50. package/corpus/templates/content/actions/_builder-cms-source-adapter.ts +1 -0
  51. package/corpus/templates/content/actions/_builder-cms-write-adapter.ts +427 -18
  52. package/corpus/templates/content/actions/_builder-cms-write-client.ts +17 -73
  53. package/corpus/templates/content/actions/_builder-cms-write-settings.ts +27 -7
  54. package/corpus/templates/content/actions/_builder-source-execution-claim.ts +124 -0
  55. package/corpus/templates/content/actions/_builder-source-execution-preservation.ts +21 -0
  56. package/corpus/templates/content/actions/_builder-source-timings.ts +57 -0
  57. package/corpus/templates/content/actions/_database-source-utils.ts +1071 -170
  58. package/corpus/templates/content/actions/_database-utils.ts +104 -13
  59. package/corpus/templates/content/actions/_local-file-documents.ts +53 -1
  60. package/corpus/templates/content/actions/_preview-document-draft.ts +31 -0
  61. package/corpus/templates/content/actions/_property-utils.ts +7 -1
  62. package/corpus/templates/content/actions/cancel-prepared-builder-source-update.ts +309 -0
  63. package/corpus/templates/content/actions/configure-document-property.ts +11 -0
  64. package/corpus/templates/content/actions/create-content-database.ts +11 -0
  65. package/corpus/templates/content/actions/create-document.ts +9 -0
  66. package/corpus/templates/content/actions/create-inline-content-database.ts +3 -0
  67. package/corpus/templates/content/actions/execute-builder-source-batch.ts +120 -49
  68. package/corpus/templates/content/actions/execute-builder-source-execution.ts +608 -264
  69. package/corpus/templates/content/actions/export-content-source.ts +1 -0
  70. package/corpus/templates/content/actions/get-content-database.ts +13 -1
  71. package/corpus/templates/content/actions/get-document.ts +12 -2
  72. package/corpus/templates/content/actions/get-preview-document-draft.ts +26 -0
  73. package/corpus/templates/content/actions/import-content-source.ts +6 -0
  74. package/corpus/templates/content/actions/list-documents.ts +3 -0
  75. package/corpus/templates/content/actions/materialize-builder-required-fields.ts +550 -0
  76. package/corpus/templates/content/actions/prepare-builder-source-execution.ts +112 -65
  77. package/corpus/templates/content/actions/prepare-builder-source-review.ts +463 -170
  78. package/corpus/templates/content/actions/preview-builder-source-review.ts +99 -0
  79. package/corpus/templates/content/actions/pull-document.ts +2 -0
  80. package/corpus/templates/content/actions/search-documents.ts +5 -1
  81. package/corpus/templates/content/actions/set-content-database-source-write-mode.ts +2 -2
  82. package/corpus/templates/content/actions/update-document.ts +16 -1
  83. package/corpus/templates/content/actions/update-preview-document-draft.ts +153 -0
  84. package/corpus/templates/content/actions/view-screen.ts +15 -2
  85. package/corpus/templates/content/app/components/editor/DescriptionField.tsx +121 -0
  86. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +14 -0
  87. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +250 -49
  88. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +57 -5
  89. package/corpus/templates/content/app/components/editor/body-hydration.ts +27 -0
  90. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +2414 -589
  91. package/corpus/templates/content/app/components/editor/database/settings.tsx +13 -10
  92. package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +358 -75
  93. package/corpus/templates/content/app/components/editor/previewDocumentSaveController.ts +124 -29
  94. package/corpus/templates/content/app/components/editor/previewDocumentSaveRegistry.ts +2 -0
  95. package/corpus/templates/content/app/global.css +18 -1
  96. package/corpus/templates/content/app/hooks/use-content-database.ts +68 -0
  97. package/corpus/templates/content/app/hooks/use-documents.ts +53 -4
  98. package/corpus/templates/content/app/i18n/zh-TW.ts +30 -0
  99. package/corpus/templates/content/app/i18n-data.ts +339 -0
  100. package/corpus/templates/content/changelog/2026-07-10-builder-backed-preview-edits-are-preserved-when-article-bodi.md +6 -0
  101. package/corpus/templates/content/changelog/2026-07-10-builder-cms-sources-can-now-be-enabled-for-guarded-staged-or.md +6 -0
  102. package/corpus/templates/content/changelog/2026-07-13-builder-connection-setup-is-now-available-directly-from-conn.md +6 -0
  103. package/corpus/templates/content/changelog/2026-07-13-builder-reviews-now-hide-already-applied-writes-detect-nativ.md +6 -0
  104. package/corpus/templates/content/changelog/2026-07-13-required-builder-publishing-fields-can-now-be-added-directly.md +6 -0
  105. package/corpus/templates/content/changelog/2026-07-13-you-can-now-cancel-a-prepared-builder-update-safely-before-i.md +6 -0
  106. package/corpus/templates/content/changelog/2026-07-14-builder-account-connection-now-remains-available-when-branch.md +6 -0
  107. package/corpus/templates/content/changelog/2026-07-14-builder-backed-articles-now-preserve-fifth-and-sixth-level-h.md +6 -0
  108. package/corpus/templates/content/changelog/2026-07-14-builder-sources-now-review-and-publish-rich-article-updates-.md +6 -0
  109. package/corpus/templates/content/changelog/2026-07-14-builder-writes-now-stop-retries-when-reconciliation-is-needed.md +6 -0
  110. package/corpus/templates/content/changelog/2026-07-14-file-and-media-links-now-validate-before-saving.md +6 -0
  111. package/corpus/templates/content/changelog/2026-07-14-pages-and-databases-can-describe-themselves-with-guidance-fo.md +6 -0
  112. package/corpus/templates/content/changelog/2026-07-14-slack-follow-ups-now-retain-created-content-identity-and-per.md +6 -0
  113. package/corpus/templates/content/parity/matrix.md +27 -25
  114. package/corpus/templates/content/parity/matrix.ts +50 -2
  115. package/corpus/templates/content/server/db/schema.ts +51 -0
  116. package/corpus/templates/content/server/lib/document-context.ts +76 -0
  117. package/corpus/templates/content/server/lib/public-documents.ts +3 -0
  118. package/corpus/templates/content/server/plugins/auth.ts +1 -0
  119. package/corpus/templates/content/server/plugins/db.ts +59 -0
  120. package/corpus/templates/content/server/routes/api/document-agent-context.json.get.ts +5 -0
  121. package/corpus/templates/content/shared/api.ts +87 -1
  122. package/corpus/templates/content/shared/builder-mdx.ts +705 -15
  123. package/corpus/templates/content/shared/content-source.ts +7 -0
  124. package/corpus/templates/content/shared/nfm.ts +3 -3
  125. package/corpus/templates/content/shared/properties.ts +2 -0
  126. package/corpus/templates/design/app/components/design/ReadOnlyDesignBanner.tsx +52 -7
  127. package/corpus/templates/design/app/components/design/ReviewCommentsPanel.tsx +36 -4
  128. package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +4 -1
  129. package/corpus/templates/design/app/i18n/ar-SA.ts +1 -0
  130. package/corpus/templates/design/app/i18n/de-DE.ts +1 -0
  131. package/corpus/templates/design/app/i18n/en-US.ts +1 -0
  132. package/corpus/templates/design/app/i18n/es-ES.ts +1 -0
  133. package/corpus/templates/design/app/i18n/fr-FR.ts +1 -0
  134. package/corpus/templates/design/app/i18n/hi-IN.ts +1 -0
  135. package/corpus/templates/design/app/i18n/ja-JP.ts +1 -0
  136. package/corpus/templates/design/app/i18n/ko-KR.ts +1 -0
  137. package/corpus/templates/design/app/i18n/pt-BR.ts +1 -0
  138. package/corpus/templates/design/app/i18n/zh-CN.ts +1 -0
  139. package/corpus/templates/design/app/i18n/zh-TW.ts +1 -0
  140. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +8 -0
  141. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +11 -0
  142. package/corpus/templates/design/changelog/2026-07-14-reviewers-can-now-pin-comments-from-the-canvas-toolbar-targe.md +6 -0
  143. package/corpus/templates/design/changelog/2026-07-15-viewer-comment-controls-now-sit-inside-the-read-only-notice-.md +6 -0
  144. package/corpus/templates/design/shared/review-anchor.ts +48 -0
  145. package/corpus/templates/plan/server/plan-mdx.ts +53 -7
  146. package/dist/a2a/artifact-response.d.ts +15 -0
  147. package/dist/a2a/artifact-response.d.ts.map +1 -1
  148. package/dist/a2a/artifact-response.js +204 -5
  149. package/dist/a2a/artifact-response.js.map +1 -1
  150. package/dist/agent/thread-data-builder.d.ts +6 -0
  151. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  152. package/dist/agent/thread-data-builder.js +71 -8
  153. package/dist/agent/thread-data-builder.js.map +1 -1
  154. package/dist/client/review/ReviewCommentComposer.d.ts +2 -1
  155. package/dist/client/review/ReviewCommentComposer.d.ts.map +1 -1
  156. package/dist/client/review/ReviewCommentComposer.js +3 -3
  157. package/dist/client/review/ReviewCommentComposer.js.map +1 -1
  158. package/dist/client/review/ReviewThreadPanel.d.ts +9 -1
  159. package/dist/client/review/ReviewThreadPanel.d.ts.map +1 -1
  160. package/dist/client/review/ReviewThreadPanel.js +6 -4
  161. package/dist/client/review/ReviewThreadPanel.js.map +1 -1
  162. package/dist/client/settings/SettingsPanel.d.ts +3 -0
  163. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  164. package/dist/client/settings/SettingsPanel.js +11 -4
  165. package/dist/client/settings/SettingsPanel.js.map +1 -1
  166. package/dist/client/settings/useBuilderStatus.d.ts +8 -4
  167. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  168. package/dist/client/settings/useBuilderStatus.js +19 -6
  169. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  170. package/dist/client/setup-connections/BuilderConnectCard.d.ts.map +1 -1
  171. package/dist/client/setup-connections/BuilderConnectCard.js +2 -5
  172. package/dist/client/setup-connections/BuilderConnectCard.js.map +1 -1
  173. package/dist/collab/awareness.d.ts +2 -2
  174. package/dist/collab/awareness.d.ts.map +1 -1
  175. package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -1
  176. package/dist/integrations/a2a-continuation-processor.js +72 -6
  177. package/dist/integrations/a2a-continuation-processor.js.map +1 -1
  178. package/dist/integrations/adapters/discord.d.ts.map +1 -1
  179. package/dist/integrations/adapters/discord.js +1 -0
  180. package/dist/integrations/adapters/discord.js.map +1 -1
  181. package/dist/integrations/adapters/email.d.ts.map +1 -1
  182. package/dist/integrations/adapters/email.js +2 -0
  183. package/dist/integrations/adapters/email.js.map +1 -1
  184. package/dist/integrations/adapters/google-docs.d.ts.map +1 -1
  185. package/dist/integrations/adapters/google-docs.js +2 -0
  186. package/dist/integrations/adapters/google-docs.js.map +1 -1
  187. package/dist/integrations/adapters/microsoft-teams.d.ts.map +1 -1
  188. package/dist/integrations/adapters/microsoft-teams.js +1 -0
  189. package/dist/integrations/adapters/microsoft-teams.js.map +1 -1
  190. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  191. package/dist/integrations/adapters/slack.js +21 -6
  192. package/dist/integrations/adapters/slack.js.map +1 -1
  193. package/dist/integrations/adapters/telegram.d.ts.map +1 -1
  194. package/dist/integrations/adapters/telegram.js +11 -2
  195. package/dist/integrations/adapters/telegram.js.map +1 -1
  196. package/dist/integrations/adapters/whatsapp.d.ts.map +1 -1
  197. package/dist/integrations/adapters/whatsapp.js +3 -0
  198. package/dist/integrations/adapters/whatsapp.js.map +1 -1
  199. package/dist/integrations/index.d.ts +1 -1
  200. package/dist/integrations/index.d.ts.map +1 -1
  201. package/dist/integrations/index.js.map +1 -1
  202. package/dist/integrations/types.d.ts +8 -2
  203. package/dist/integrations/types.d.ts.map +1 -1
  204. package/dist/integrations/types.js.map +1 -1
  205. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  206. package/dist/integrations/webhook-handler.js +40 -43
  207. package/dist/integrations/webhook-handler.js.map +1 -1
  208. package/dist/observability/routes.d.ts +5 -5
  209. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  210. package/dist/secrets/routes.d.ts +9 -9
  211. package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
  212. package/dist/server/agent-chat/action-filters-a2a.js +1 -0
  213. package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
  214. package/dist/server/auth.d.ts +1 -0
  215. package/dist/server/auth.d.ts.map +1 -1
  216. package/dist/server/auth.js +19 -2
  217. package/dist/server/auth.js.map +1 -1
  218. package/dist/server/builder-browser.d.ts +78 -0
  219. package/dist/server/builder-browser.d.ts.map +1 -1
  220. package/dist/server/builder-browser.js +246 -1
  221. package/dist/server/builder-browser.js.map +1 -1
  222. package/dist/server/core-routes-plugin.d.ts +41 -0
  223. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  224. package/dist/server/core-routes-plugin.js +260 -14
  225. package/dist/server/core-routes-plugin.js.map +1 -1
  226. package/docs/content/deployment.mdx +9 -7
  227. package/docs/content/locales/ar-SA/deployment.mdx +9 -7
  228. package/docs/content/locales/de-DE/deployment.mdx +9 -7
  229. package/docs/content/locales/es-ES/deployment.mdx +9 -7
  230. package/docs/content/locales/fr-FR/deployment.mdx +9 -7
  231. package/docs/content/locales/hi-IN/deployment.mdx +9 -7
  232. package/docs/content/locales/ja-JP/deployment.mdx +9 -7
  233. package/docs/content/locales/ko-KR/deployment.mdx +9 -7
  234. package/docs/content/locales/pt-BR/deployment.mdx +9 -7
  235. package/docs/content/locales/zh-CN/deployment.mdx +9 -7
  236. package/docs/content/locales/zh-TW/deployment.mdx +9 -7
  237. package/package.json +2 -2
@@ -12,7 +12,7 @@ import { cn } from "../utils.js";
12
12
  import { ReviewCommentComposer } from "./ReviewCommentComposer.js";
13
13
  import { ReviewStatusBadge } from "./ReviewStatusBadge.js";
14
14
  import { useCreateReviewComment, useDeleteReviewComment, useReplyReviewComment, useResolveReviewThread, useReviewComments, } from "./use-review.js";
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", }) {
15
+ export function ReviewThreadPanel({ resourceType, resourceId, targetId, composerTargetId, composerAnchor, composerMetadata, composerContextLabel, 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", }) {
16
16
  const [draft, setDraft] = useState("");
17
17
  const [submittingTarget, setSubmittingTarget] = useState(null);
18
18
  const [replyingThreadId, setReplyingThreadId] = useState(null);
@@ -37,9 +37,11 @@ export function ReviewThreadPanel({ resourceType, resourceId, targetId, title =
37
37
  createComment.mutate({
38
38
  resourceType,
39
39
  resourceId,
40
- targetId,
40
+ targetId: composerTargetId === undefined ? targetId : composerTargetId,
41
+ ...(composerAnchor !== undefined ? { anchor: composerAnchor } : {}),
42
+ ...(composerMetadata ? { metadata: composerMetadata } : {}),
41
43
  body,
42
- ...(showComposerTargetPicker ? { resolutionTarget } : {}),
44
+ resolutionTarget: showComposerTargetPicker ? resolutionTarget : "human",
43
45
  }, {
44
46
  onSuccess: (comment) => {
45
47
  setDraft("");
@@ -50,7 +52,7 @@ export function ReviewThreadPanel({ resourceType, resourceId, targetId, title =
50
52
  };
51
53
  return (_jsxs("section", { className: cn("@container/review overflow-hidden text-card-foreground", variant === "card"
52
54
  ? "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) => {
55
+ : "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, contextLabel: composerContextLabel })) : 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
56
  const replyDraft = replyDrafts[thread.root.id] ?? "";
55
57
  const replying = replyingThreadId === thread.root.threadId;
56
58
  const threadIsOpen = thread.root.status === "open";
@@ -1 +1 @@
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
+ {"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 /** Persist new comments against this target while targetId continues to filter the list. */\n composerTargetId?: string | null;\n /** Optional element/point anchor attached to new comments from the composer. */\n composerAnchor?: unknown | null;\n /** Host metadata attached to new comments from the composer. */\n composerMetadata?: Record<string, unknown>;\n /** Visible label describing the element currently targeted by the composer. */\n composerContextLabel?: string;\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 composerTargetId,\n composerAnchor,\n composerMetadata,\n composerContextLabel,\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: composerTargetId === undefined ? targetId : composerTargetId,\n ...(composerAnchor !== undefined ? { anchor: composerAnchor } : {}),\n ...(composerMetadata ? { metadata: composerMetadata } : {}),\n body,\n resolutionTarget: showComposerTargetPicker ? resolutionTarget : \"human\",\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 contextLabel={composerContextLabel}\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"]}
@@ -18,5 +18,8 @@ export interface SettingsPanelProps {
18
18
  sectionRequestKey?: number;
19
19
  }
20
20
  export declare function SettingsPanel(props: SettingsPanelProps): React.JSX.Element;
21
+ export declare function ConnectionsSettingsContent({ settingsPanelProps, }: {
22
+ settingsPanelProps: SettingsPanelProps;
23
+ }): React.JSX.Element;
21
24
  export declare function useAgentSettingsTabs(): SettingsTabItem[];
22
25
  //# sourceMappingURL=SettingsPanel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsPanel.d.ts","sourceRoot":"","sources":["../../../src/client/settings/SettingsPanel.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAQN,MAAM,OAAO,CAAC;AAoCf,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAwoB7D,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,MAAM,EACN,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,OAAO,GACR,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,qBAqDA;AAs+CD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AA8uBD,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,qBAEtD;AAED,wBAAgB,oBAAoB,IAAI,eAAe,EAAE,CAiFxD"}
1
+ {"version":3,"file":"SettingsPanel.d.ts","sourceRoot":"","sources":["../../../src/client/settings/SettingsPanel.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAQN,MAAM,OAAO,CAAC;AAqCf,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAwoB7D,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,MAAM,EACN,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,OAAO,GACR,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,qBAqDA;AAs+CD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAqvBD,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,qBAEtD;AAED,wBAAgB,0BAA0B,CAAC,EACzC,kBAAkB,GACnB,EAAE;IACD,kBAAkB,EAAE,kBAAkB,CAAC;CACxC,qBAcA;AAED,wBAAgB,oBAAoB,IAAI,eAAe,EAAE,CAyExD"}
@@ -8,6 +8,7 @@ import { agentNativePath } from "../api-path.js";
8
8
  import { BuilderBMark } from "../builder-mark.js";
9
9
  import { Tooltip, TooltipContent, TooltipTrigger, } from "../components/ui/tooltip.js";
10
10
  import { TeamPage } from "../org/TeamPage.js";
11
+ import { BuilderConnectCard } from "../setup-connections/BuilderConnectCard.js";
11
12
  import { callAction } from "../use-action.js";
12
13
  import { uploadAvatar, useAvatarUrl } from "../use-avatar.js";
13
14
  import { useDevMode } from "../use-dev-mode.js";
@@ -987,8 +988,10 @@ function AccountSectionInner({ open, onToggle, }) {
987
988
  };
988
989
  return (_jsx(SettingsSection, { id: settingsSectionDomId("account"), icon: _jsx(IconUserCircle, { size: 14 }), title: "Account", subtitle: "Your profile photo and signed-in identity.", open: open, onToggle: onToggle, children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: cn("flex shrink-0 items-center justify-center overflow-hidden rounded-full border border-border bg-accent font-semibold text-muted-foreground", isPage ? "h-14 w-14 text-[15px]" : "h-12 w-12 text-[13px]"), children: avatarUrl ? (_jsx("img", { src: avatarUrl, alt: "", className: "h-full w-full object-cover" })) : (initials) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: cn("truncate font-medium text-foreground", isPage ? "text-sm" : "text-[12px]"), children: isLoading ? "Loading..." : displayName }), email && (_jsx("p", { className: cn("truncate text-muted-foreground", subTextClass(isPage)), children: email })), status === "saved" && (_jsx("p", { className: cn("mt-1 text-green-600 dark:text-green-400", subTextClass(isPage)), children: "Photo updated" })), status === "error" && (_jsx("p", { className: cn("mt-1 text-destructive", subTextClass(isPage)), children: "Could not update photo" }))] }), _jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", className: "hidden", onChange: handleAvatarChange }), _jsx("button", { type: "button", disabled: !email || uploading, onClick: () => fileInputRef.current?.click(), className: cn(pillButtonClass(isPage, "outline"), "shrink-0 justify-center"), children: uploading ? "Uploading..." : "Change photo" })] }) }));
989
990
  }
990
- function SettingsPanelContent({ isDevMode, onToggleDevMode, showDevToggle, devAppUrl, initialSection, sectionRequestKey, sections = ALL_SETTINGS_SECTIONS, showCapabilityStrip = true, className, surface = "sidebar", }) {
991
- const { status: builder, loading: builderLoading } = useBuilderStatus();
991
+ function SettingsPanelContent({ isDevMode, onToggleDevMode, showDevToggle, devAppUrl, initialSection, sectionRequestKey, sections = ALL_SETTINGS_SECTIONS, showCapabilityStrip = true, className, surface = "sidebar", builderConnectionOwnedExternally = false, }) {
992
+ const { status: builder, loading: builderLoading } = useBuilderStatus({
993
+ enabled: !builderConnectionOwnedExternally,
994
+ });
992
995
  const connected = builder?.configured ?? false;
993
996
  const connectUrl = builder?.cliAuthUrl ?? builder?.connectUrl;
994
997
  const orgName = builder?.orgName;
@@ -996,6 +999,7 @@ function SettingsPanelContent({ isDevMode, onToggleDevMode, showDevToggle, devAp
996
999
  const credentialSource = builder?.credentialSource;
997
1000
  const builderBranchesAvailable = !!builder?.builderEnabled;
998
1001
  const builderFlow = useBuilderConnectFlow({
1002
+ enabled: !builderConnectionOwnedExternally,
999
1003
  popupUrl: connectUrl,
1000
1004
  trackingSource: "settings_panel_builder_card",
1001
1005
  });
@@ -1066,11 +1070,14 @@ function SettingsPanelContent({ isDevMode, onToggleDevMode, showDevToggle, devAp
1066
1070
  const nextIsDev = next === "development";
1067
1071
  if (nextIsDev !== isDevMode)
1068
1072
  onToggleDevMode();
1069
- } })) })), showCapabilityStrip && (_jsx(CapabilityStatusStrip, { isDevMode: isDevMode, builderConnected: connected, builderLoading: builderLoading, builderBranchesAvailable: builderBranchesAvailable, onOpenLlm: () => openSettingsSection("llm", true) })), shouldShowSection("account") && (_jsx(AccountSectionInner, { open: openSection === "account", onToggle: () => toggle("account") })), shouldShowSection("llm") && (_jsx(LLMSectionInner, { builderFlow: builderFlow, builderLoading: builderLoading, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, open: openSection === "llm", onToggle: () => toggle("llm") })), shouldShowSection("app-models") && (_jsx(AppModelDefaultsSectionInner, { open: openSection === "app-models", onToggle: () => toggle("app-models") })), shouldShowSection("limits") && (_jsx(AgentLimitsSectionInner, { open: openSection === "limits", onToggle: () => toggle("limits") })), shouldShowSection("voice") && (_jsx(SettingsSection, { id: settingsSectionDomId("voice"), icon: _jsx(IconMicrophone, { size: 14 }), title: "Voice Transcription", subtitle: "How the composer microphone turns your voice into text.", open: openSection === "voice", onToggle: () => toggle("voice"), children: _jsx(VoiceTranscriptionSection, {}) })), shouldShowSection("demo-mode") && (_jsx(SettingsSection, { id: settingsSectionDomId("demo-mode"), icon: _jsx(IconEyeOff, { size: 14 }), title: "Demo mode", subtitle: "Replace displayed emails with realistic fake data in this browser and reshape supported charts for presentations. Backend, MCP, and agent results stay real and access-scoped.", open: openSection === "demo-mode", onToggle: () => toggle("demo-mode"), children: _jsx(DemoModeSection, {}) })), shouldShowSection("automations") && (_jsx(SettingsSection, { id: settingsSectionDomId("automations"), icon: _jsx(IconBolt, { size: 14 }), title: "Automations", subtitle: "Event-triggered and scheduled automations.", open: openSection === "automations", onToggle: () => toggle("automations"), children: _jsx(AutomationsSection, {}) })), shouldShowSection("secrets") && (_jsx(SettingsSection, { id: settingsSectionDomId("secrets"), icon: _jsx(IconKey, { size: 14 }), title: "API Keys & Connections", subtitle: "Service credentials and automation keys.", open: openSection === "secrets", onToggle: () => toggle("secrets"), children: _jsx(SecretsSection, { focusKey: focusSecretKey }) })), shouldShowSection("hosting") && (_jsx(SettingsSection, { id: settingsSectionDomId("hosting"), icon: _jsx(IconCloud, { size: 14 }), title: "Hosting", subtitle: "Deploy your app to the cloud.", connected: connected, open: openSection === "hosting", onToggle: () => toggle("hosting"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "hosting_settings", trackingFlow: "hosting" }), _jsx(ManualSetupCard, { hint: "Deploy manually to Netlify, Vercel, Cloudflare, or any Nitro-supported target.", docsUrl: "https://www.builder.io/c/docs/agent-native-deployment", dim: connected })] }) })), shouldShowSection("database") && (_jsx(SettingsSection, { id: settingsSectionDomId("database"), icon: _jsx(IconDatabase, { size: 14 }), title: "Database", subtitle: "Connect a cloud database for persistent storage.", connected: connected, open: openSection === "database", onToggle: () => toggle("database"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "database_settings", trackingFlow: "database" }), _jsx(ManualSetupCard, { hint: "Set DATABASE_URL in your .env to connect Neon, Supabase, Turso, any Postgres/SQLite database, or local PGlite with pglite:./data/pglite.", docsUrl: "https://www.builder.io/c/docs/agent-native-database", dim: connected })] }) })), shouldShowSection("uploads") && (_jsx(SettingsSection, { id: settingsSectionDomId("uploads"), icon: _jsx(IconUpload, { size: 14 }), title: "File uploads", subtitle: "Where user-uploaded files (avatars, chat attachments) are stored.", connected: connected, open: openSection === "uploads", onToggle: () => toggle("uploads"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "file_upload_settings", trackingFlow: "file_upload" }), _jsx(ManualSetupCard, { hint: "Without a provider, files are stored as base64 in your database. Fine for dev, not recommended for production.", docsUrl: "https://www.builder.io/c/docs/agent-native-file-uploads", dim: connected })] }) })), shouldShowSection("auth") && (_jsx(SettingsSection, { id: settingsSectionDomId("auth"), icon: _jsx(IconShield, { size: 14 }), title: "Authentication", subtitle: "Set up user authentication and access control.", connected: connected, open: openSection === "auth", onToggle: () => toggle("auth"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "auth_settings", trackingFlow: "auth" }), _jsx(ManualSetupCard, { hint: "Configure Better Auth with BETTER_AUTH_SECRET and optional Google/GitHub OAuth providers.", docsUrl: "https://www.builder.io/c/docs/agent-native-authentication", dim: connected })] }) })), shouldShowSection("email") && (_jsx(EmailSectionInner, { open: openSection === "email", onToggle: () => toggle("email") })), shouldShowSection("browser") && (_jsx(SettingsSection, { id: settingsSectionDomId("browser"), icon: _jsx(IconBrowser, { size: 14 }), title: "Browser Automation", subtitle: "Let agents control a real browser for web tasks.", connected: connected, open: openSection === "browser", onToggle: () => toggle("browser"), children: _jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "browser_settings", trackingFlow: "browser_automation" }) })), builderBranchesAvailable && shouldShowSection("background") && (_jsx(SettingsSection, { id: settingsSectionDomId("background"), icon: _jsx(IconGitBranch, { size: 14 }), title: "Background Agent", subtitle: "Make code changes from production mode via Builder.", connected: connected, open: openSection === "background", onToggle: () => toggle("background"), children: _jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "background_agent_settings", trackingFlow: "background_agent" }) })), shouldShowSection("integrations") && (_jsx(SettingsSection, { id: settingsSectionDomId("integrations"), icon: _jsx(IconPlugConnected, { size: 14 }), title: "Integrations", subtitle: "Connect messaging platforms and external services.", open: openSection === "integrations", onToggle: () => toggle("integrations"), children: _jsx(Suspense, { fallback: null, children: _jsx(IntegrationsPanel, {}) }) })), shouldShowSection("usage") && (_jsx(SettingsSection, { id: settingsSectionDomId("usage"), icon: _jsx(IconCoin, { size: 14 }), title: "Usage", subtitle: "Track token consumption and estimated cost \u2014 broken down by chat, automations, and background jobs.", open: openSection === "usage", onToggle: () => toggle("usage"), children: _jsx(UsageSection, {}) })), shouldShowSection("a2a") && (_jsx(SettingsSection, { id: settingsSectionDomId("a2a"), icon: _jsx(IconTopologyRing2, { size: 14 }), title: "Connected Agents (A2A)", subtitle: "Manage remote agents connected via the A2A protocol.", open: openSection === "a2a", onToggle: () => toggle("a2a"), children: _jsx(AgentsSection, {}) }))] }) }));
1073
+ } })) })), showCapabilityStrip && (_jsx(CapabilityStatusStrip, { isDevMode: isDevMode, builderConnected: connected, builderLoading: builderLoading, builderBranchesAvailable: builderBranchesAvailable, onOpenLlm: () => openSettingsSection("llm", true) })), shouldShowSection("account") && (_jsx(AccountSectionInner, { open: openSection === "account", onToggle: () => toggle("account") })), shouldShowSection("llm") && (_jsx(LLMSectionInner, { builderFlow: builderFlow, builderLoading: builderLoading, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, open: openSection === "llm", onToggle: () => toggle("llm") })), shouldShowSection("app-models") && (_jsx(AppModelDefaultsSectionInner, { open: openSection === "app-models", onToggle: () => toggle("app-models") })), shouldShowSection("limits") && (_jsx(AgentLimitsSectionInner, { open: openSection === "limits", onToggle: () => toggle("limits") })), shouldShowSection("voice") && (_jsx(SettingsSection, { id: settingsSectionDomId("voice"), icon: _jsx(IconMicrophone, { size: 14 }), title: "Voice Transcription", subtitle: "How the composer microphone turns your voice into text.", open: openSection === "voice", onToggle: () => toggle("voice"), children: _jsx(VoiceTranscriptionSection, {}) })), shouldShowSection("demo-mode") && (_jsx(SettingsSection, { id: settingsSectionDomId("demo-mode"), icon: _jsx(IconEyeOff, { size: 14 }), title: "Demo mode", subtitle: "Replace displayed emails with realistic fake data in this browser and reshape supported charts for presentations. Backend, MCP, and agent results stay real and access-scoped.", open: openSection === "demo-mode", onToggle: () => toggle("demo-mode"), children: _jsx(DemoModeSection, {}) })), shouldShowSection("automations") && (_jsx(SettingsSection, { id: settingsSectionDomId("automations"), icon: _jsx(IconBolt, { size: 14 }), title: "Automations", subtitle: "Event-triggered and scheduled automations.", open: openSection === "automations", onToggle: () => toggle("automations"), children: _jsx(AutomationsSection, {}) })), shouldShowSection("secrets") && (_jsx(SettingsSection, { id: settingsSectionDomId("secrets"), icon: _jsx(IconKey, { size: 14 }), title: "API Keys & Connections", subtitle: "Service credentials and automation keys.", open: openSection === "secrets", onToggle: () => toggle("secrets"), children: _jsx(SecretsSection, { focusKey: focusSecretKey }) })), shouldShowSection("hosting") && (_jsx(SettingsSection, { id: settingsSectionDomId("hosting"), icon: _jsx(IconCloud, { size: 14 }), title: "Hosting", subtitle: "Deploy your app to the cloud.", connected: connected, open: openSection === "hosting", onToggle: () => toggle("hosting"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "hosting_settings", trackingFlow: "hosting" }), _jsx(ManualSetupCard, { hint: "Deploy manually to Netlify, Vercel, Cloudflare, or any Nitro-supported target.", docsUrl: "https://www.builder.io/c/docs/agent-native-deployment", dim: connected })] }) })), shouldShowSection("database") && (_jsx(SettingsSection, { id: settingsSectionDomId("database"), icon: _jsx(IconDatabase, { size: 14 }), title: "Database", subtitle: "Connect a cloud database for persistent storage.", connected: connected, open: openSection === "database", onToggle: () => toggle("database"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "database_settings", trackingFlow: "database" }), _jsx(ManualSetupCard, { hint: "Set DATABASE_URL in your .env to connect Neon, Supabase, Turso, any Postgres/SQLite database, or local PGlite with pglite:./data/pglite.", docsUrl: "https://www.builder.io/c/docs/agent-native-database", dim: connected })] }) })), shouldShowSection("uploads") && (_jsx(SettingsSection, { id: settingsSectionDomId("uploads"), icon: _jsx(IconUpload, { size: 14 }), title: "File uploads", subtitle: "Where user-uploaded files (avatars, chat attachments) are stored.", connected: connected, open: openSection === "uploads", onToggle: () => toggle("uploads"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "file_upload_settings", trackingFlow: "file_upload" }), _jsx(ManualSetupCard, { hint: "Without a provider, files are stored as base64 in your database. Fine for dev, not recommended for production.", docsUrl: "https://www.builder.io/c/docs/agent-native-file-uploads", dim: connected })] }) })), shouldShowSection("auth") && (_jsx(SettingsSection, { id: settingsSectionDomId("auth"), icon: _jsx(IconShield, { size: 14 }), title: "Authentication", subtitle: "Set up user authentication and access control.", connected: connected, open: openSection === "auth", onToggle: () => toggle("auth"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "auth_settings", trackingFlow: "auth" }), _jsx(ManualSetupCard, { hint: "Configure Better Auth with BETTER_AUTH_SECRET and optional Google/GitHub OAuth providers.", docsUrl: "https://www.builder.io/c/docs/agent-native-authentication", dim: connected })] }) })), shouldShowSection("email") && (_jsx(EmailSectionInner, { open: openSection === "email", onToggle: () => toggle("email") })), shouldShowSection("browser") && (_jsx(SettingsSection, { id: settingsSectionDomId("browser"), icon: _jsx(IconBrowser, { size: 14 }), title: "Browser Automation", subtitle: "Let agents control a real browser for web tasks.", connected: builderConnectionOwnedExternally ? undefined : connected, open: openSection === "browser", onToggle: () => toggle("browser"), children: !builderConnectionOwnedExternally ? (_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "browser_settings", trackingFlow: "browser_automation" })) : null })), builderBranchesAvailable && shouldShowSection("background") && (_jsx(SettingsSection, { id: settingsSectionDomId("background"), icon: _jsx(IconGitBranch, { size: 14 }), title: "Background Agent", subtitle: "Make code changes from production mode via Builder.", connected: connected, open: openSection === "background", onToggle: () => toggle("background"), children: _jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "background_agent_settings", trackingFlow: "background_agent" }) })), shouldShowSection("integrations") && (_jsx(SettingsSection, { id: settingsSectionDomId("integrations"), icon: _jsx(IconPlugConnected, { size: 14 }), title: "Integrations", subtitle: "Connect messaging platforms and external services.", open: openSection === "integrations", onToggle: () => toggle("integrations"), children: _jsx(Suspense, { fallback: null, children: _jsx(IntegrationsPanel, {}) }) })), shouldShowSection("usage") && (_jsx(SettingsSection, { id: settingsSectionDomId("usage"), icon: _jsx(IconCoin, { size: 14 }), title: "Usage", subtitle: "Track token consumption and estimated cost \u2014 broken down by chat, automations, and background jobs.", open: openSection === "usage", onToggle: () => toggle("usage"), children: _jsx(UsageSection, {}) })), shouldShowSection("a2a") && (_jsx(SettingsSection, { id: settingsSectionDomId("a2a"), icon: _jsx(IconTopologyRing2, { size: 14 }), title: "Connected Agents (A2A)", subtitle: "Manage remote agents connected via the A2A protocol.", open: openSection === "a2a", onToggle: () => toggle("a2a"), children: _jsx(AgentsSection, {}) }))] }) }));
1070
1074
  }
1071
1075
  export function SettingsPanel(props) {
1072
1076
  return _jsx(SettingsPanelContent, { ...props });
1073
1077
  }
1078
+ export function ConnectionsSettingsContent({ settingsPanelProps, }) {
1079
+ return (_jsxs("div", { className: "mx-auto w-full max-w-2xl space-y-4", children: [_jsx(BuilderConnectCard, { trackingSource: "settings_connections" }), _jsx(SettingsPanelContent, { ...settingsPanelProps, surface: "page", sections: CONNECTION_SETTINGS_SECTIONS, showCapabilityStrip: false, className: "w-full", builderConnectionOwnedExternally: true })] }));
1080
+ }
1074
1081
  export function useAgentSettingsTabs() {
1075
1082
  const { isDevMode, canToggle, setDevMode } = useDevMode();
1076
1083
  const baseProps = useMemo(() => ({
@@ -1103,7 +1110,7 @@ export function useAgentSettingsTabs() {
1103
1110
  ...connections,
1104
1111
  icon: IconPlugConnected,
1105
1112
  group: "agent",
1106
- content: (_jsx(SettingsPanelContent, { ...baseProps, surface: "page", sections: CONNECTION_SETTINGS_SECTIONS, showCapabilityStrip: false, className: "mx-auto w-full max-w-2xl" })),
1113
+ content: _jsx(ConnectionsSettingsContent, { settingsPanelProps: baseProps }),
1107
1114
  },
1108
1115
  {
1109
1116
  ...organization,