@burtson-labs/agent-ui 1.0.11

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 (144) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +45 -0
  3. package/dist/components/AgentConsole.d.ts +11 -0
  4. package/dist/components/AgentConsole.d.ts.map +1 -0
  5. package/dist/components/AgentConsole.js +139 -0
  6. package/dist/components/AgentConsole.js.map +1 -0
  7. package/dist/components/AgentSummaryCard.d.ts +9 -0
  8. package/dist/components/AgentSummaryCard.d.ts.map +1 -0
  9. package/dist/components/AgentSummaryCard.js +96 -0
  10. package/dist/components/AgentSummaryCard.js.map +1 -0
  11. package/dist/components/ChatComposer.d.ts +134 -0
  12. package/dist/components/ChatComposer.d.ts.map +1 -0
  13. package/dist/components/ChatComposer.js +411 -0
  14. package/dist/components/ChatComposer.js.map +1 -0
  15. package/dist/components/ChatConversation.d.ts +28 -0
  16. package/dist/components/ChatConversation.d.ts.map +1 -0
  17. package/dist/components/ChatConversation.js +82 -0
  18. package/dist/components/ChatConversation.js.map +1 -0
  19. package/dist/components/ChatMessage.d.ts +38 -0
  20. package/dist/components/ChatMessage.d.ts.map +1 -0
  21. package/dist/components/ChatMessage.js +208 -0
  22. package/dist/components/ChatMessage.js.map +1 -0
  23. package/dist/components/DiffBlock.d.ts +7 -0
  24. package/dist/components/DiffBlock.d.ts.map +1 -0
  25. package/dist/components/DiffBlock.js +58 -0
  26. package/dist/components/DiffBlock.js.map +1 -0
  27. package/dist/components/DiffReview/DiffBlock.d.ts +7 -0
  28. package/dist/components/DiffReview/DiffBlock.d.ts.map +1 -0
  29. package/dist/components/DiffReview/DiffBlock.js +13 -0
  30. package/dist/components/DiffReview/DiffBlock.js.map +1 -0
  31. package/dist/components/DiffReview/DiffFileGroup.d.ts +14 -0
  32. package/dist/components/DiffReview/DiffFileGroup.d.ts.map +1 -0
  33. package/dist/components/DiffReview/DiffFileGroup.js +44 -0
  34. package/dist/components/DiffReview/DiffFileGroup.js.map +1 -0
  35. package/dist/components/DiffReview/DiffReviewPanel.d.ts +16 -0
  36. package/dist/components/DiffReview/DiffReviewPanel.d.ts.map +1 -0
  37. package/dist/components/DiffReview/DiffReviewPanel.js +25 -0
  38. package/dist/components/DiffReview/DiffReviewPanel.js.map +1 -0
  39. package/dist/components/DiffReview/index.d.ts +3 -0
  40. package/dist/components/DiffReview/index.d.ts.map +1 -0
  41. package/dist/components/DiffReview/index.js +19 -0
  42. package/dist/components/DiffReview/index.js.map +1 -0
  43. package/dist/components/DiffReviewCard.d.ts +10 -0
  44. package/dist/components/DiffReviewCard.d.ts.map +1 -0
  45. package/dist/components/DiffReviewCard.js +36 -0
  46. package/dist/components/DiffReviewCard.js.map +1 -0
  47. package/dist/components/DiffStream.d.ts +12 -0
  48. package/dist/components/DiffStream.d.ts.map +1 -0
  49. package/dist/components/DiffStream.js +43 -0
  50. package/dist/components/DiffStream.js.map +1 -0
  51. package/dist/components/MarkdownMessage.d.ts +17 -0
  52. package/dist/components/MarkdownMessage.d.ts.map +1 -0
  53. package/dist/components/MarkdownMessage.js +158 -0
  54. package/dist/components/MarkdownMessage.js.map +1 -0
  55. package/dist/components/PermissionCard.d.ts +64 -0
  56. package/dist/components/PermissionCard.d.ts.map +1 -0
  57. package/dist/components/PermissionCard.js +156 -0
  58. package/dist/components/PermissionCard.js.map +1 -0
  59. package/dist/components/PlanActivity.d.ts +20 -0
  60. package/dist/components/PlanActivity.d.ts.map +1 -0
  61. package/dist/components/PlanActivity.js +186 -0
  62. package/dist/components/PlanActivity.js.map +1 -0
  63. package/dist/components/PlanTree.d.ts +13 -0
  64. package/dist/components/PlanTree.d.ts.map +1 -0
  65. package/dist/components/PlanTree.js +70 -0
  66. package/dist/components/PlanTree.js.map +1 -0
  67. package/dist/components/TaskList.d.ts +9 -0
  68. package/dist/components/TaskList.d.ts.map +1 -0
  69. package/dist/components/TaskList.js +26 -0
  70. package/dist/components/TaskList.js.map +1 -0
  71. package/dist/components/TelemetryPanel.d.ts +9 -0
  72. package/dist/components/TelemetryPanel.d.ts.map +1 -0
  73. package/dist/components/TelemetryPanel.js +54 -0
  74. package/dist/components/TelemetryPanel.js.map +1 -0
  75. package/dist/components/index.d.ts +15 -0
  76. package/dist/components/index.d.ts.map +1 -0
  77. package/dist/components/index.js +31 -0
  78. package/dist/components/index.js.map +1 -0
  79. package/dist/context/BanditContext.d.ts +14 -0
  80. package/dist/context/BanditContext.d.ts.map +1 -0
  81. package/dist/context/BanditContext.js +18 -0
  82. package/dist/context/BanditContext.js.map +1 -0
  83. package/dist/context/index.d.ts +2 -0
  84. package/dist/context/index.d.ts.map +1 -0
  85. package/dist/context/index.js +18 -0
  86. package/dist/context/index.js.map +1 -0
  87. package/dist/hooks/index.d.ts +3 -0
  88. package/dist/hooks/index.d.ts.map +1 -0
  89. package/dist/hooks/index.js +19 -0
  90. package/dist/hooks/index.js.map +1 -0
  91. package/dist/hooks/useAgentEvents.d.ts +13 -0
  92. package/dist/hooks/useAgentEvents.d.ts.map +1 -0
  93. package/dist/hooks/useAgentEvents.js +54 -0
  94. package/dist/hooks/useAgentEvents.js.map +1 -0
  95. package/dist/hooks/useTelemetry.d.ts +4 -0
  96. package/dist/hooks/useTelemetry.d.ts.map +1 -0
  97. package/dist/hooks/useTelemetry.js +198 -0
  98. package/dist/hooks/useTelemetry.js.map +1 -0
  99. package/dist/index.d.ts +12 -0
  100. package/dist/index.d.ts.map +1 -0
  101. package/dist/index.js +29 -0
  102. package/dist/index.js.map +1 -0
  103. package/dist/theme/BanditThemeProvider.d.ts +26 -0
  104. package/dist/theme/BanditThemeProvider.d.ts.map +1 -0
  105. package/dist/theme/BanditThemeProvider.js +138 -0
  106. package/dist/theme/BanditThemeProvider.js.map +1 -0
  107. package/dist/theme/catppuccin-mocha.json +23 -0
  108. package/dist/theme/charcoal.json +23 -0
  109. package/dist/theme/dark.json +23 -0
  110. package/dist/theme/dracula.json +23 -0
  111. package/dist/theme/index.d.ts +5 -0
  112. package/dist/theme/index.d.ts.map +1 -0
  113. package/dist/theme/index.js +21 -0
  114. package/dist/theme/index.js.map +1 -0
  115. package/dist/theme/light.json +23 -0
  116. package/dist/theme/midnight.json +23 -0
  117. package/dist/theme/nord.json +23 -0
  118. package/dist/theme/onyx.json +23 -0
  119. package/dist/theme/sepia.json +23 -0
  120. package/dist/theme/solarized-dark.json +23 -0
  121. package/dist/theme/solarized-light.json +23 -0
  122. package/dist/theme/theme-base.d.ts +37 -0
  123. package/dist/theme/theme-base.d.ts.map +1 -0
  124. package/dist/theme/theme-base.js +141 -0
  125. package/dist/theme/theme-base.js.map +1 -0
  126. package/dist/theme/theme-registry.d.ts +22 -0
  127. package/dist/theme/theme-registry.d.ts.map +1 -0
  128. package/dist/theme/theme-registry.js +52 -0
  129. package/dist/theme/theme-registry.js.map +1 -0
  130. package/dist/theme/tokyo-night.json +23 -0
  131. package/dist/theme/vscode-theme.d.ts +3 -0
  132. package/dist/theme/vscode-theme.d.ts.map +1 -0
  133. package/dist/theme/vscode-theme.js +128 -0
  134. package/dist/theme/vscode-theme.js.map +1 -0
  135. package/dist/types/ui-schema.d.ts +114 -0
  136. package/dist/types/ui-schema.d.ts.map +1 -0
  137. package/dist/types/ui-schema.js +3 -0
  138. package/dist/types/ui-schema.js.map +1 -0
  139. package/dist/utils/classNames.d.ts +2 -0
  140. package/dist/utils/classNames.d.ts.map +1 -0
  141. package/dist/utils/classNames.js +8 -0
  142. package/dist/utils/classNames.js.map +1 -0
  143. package/package.json +55 -0
  144. package/styles/agent-ui.css +3844 -0
@@ -0,0 +1,28 @@
1
+ import { type JSX } from "react";
2
+ import type { ChatMessage, ChatMessageContextFile } from "../types/ui-schema";
3
+ import { type MarkdownRenderOptions } from "./MarkdownMessage";
4
+ export interface ChatConversationProps extends MarkdownRenderOptions {
5
+ messages: ChatMessage[];
6
+ renderMarkdown?: (content: string) => string;
7
+ onFeedback?: (messageId: string, rating: "up" | "down") => void;
8
+ onDismissFeedback?: (messageId: string) => void;
9
+ onContextFileClick?: (file: ChatMessageContextFile) => void;
10
+ onFileReferenceClick?: (reference: string) => void;
11
+ onPermissionChoice?: (id: string, choice: "once" | "session" | "save" | "deny", notes?: string) => void;
12
+ /** When present, each assistant message renders a speaker pill that
13
+ * invokes this callback with the message id, speakable text, and a
14
+ * control action ("start" | "pause" | "resume" | "stop"). Host handles
15
+ * TTS (fetch audio, play, pause, resume, stop). Currently active
16
+ * message id is passed via `speakingMessageId`; pause vs play state via
17
+ * `speakPaused`. Leave undefined to hide voice affordances entirely. */
18
+ onSpeak?: (messageId: string, text: string, action?: "start" | "pause" | "resume" | "stop") => void;
19
+ speakingMessageId?: string | null;
20
+ /** True when speakingMessageId's audio is paused (vs playing). */
21
+ speakPaused?: boolean;
22
+ /** Id of the assistant message currently being streamed. While set,
23
+ * the speaker pill on that message is hidden — listening to a
24
+ * half-baked response is jarring. */
25
+ streamingMessageId?: string | null;
26
+ }
27
+ export declare const ChatConversation: ({ messages, renderMarkdown, onFeedback, onDismissFeedback, onContextFileClick, resolveFileHref, onFileReferenceClick, onPermissionChoice, onSpeak, speakingMessageId, speakPaused, streamingMessageId }: ChatConversationProps) => JSX.Element;
28
+ //# sourceMappingURL=ChatConversation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatConversation.d.ts","sourceRoot":"","sources":["../../src/components/ChatConversation.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE9E,OAAO,EAAwB,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAoDrF,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB;IAClE,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC;IAChE,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAC5D,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACxG;;;;;6EAKyE;IACzE,OAAO,CAAC,EAAE,CACR,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,KAC3C,IAAI,CAAC;IACV,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,kEAAkE;IAClE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;0CAEsC;IACtC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,eAAO,MAAM,gBAAgB,GAAI,yMAa9B,qBAAqB,KAAG,GAAG,CAAC,OA2E9B,CAAC"}
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChatConversation = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const ChatMessage_1 = require("./ChatMessage");
7
+ const MarkdownMessage_1 = require("./MarkdownMessage");
8
+ const GROUP_TIME_GAP_MS = 5 * 60 * 1000;
9
+ const ROLE_LABELS = {
10
+ user: "You",
11
+ assistant: "Bandit",
12
+ system: "System",
13
+ tool: "Tool"
14
+ };
15
+ const normalizeTimestamp = (value) => {
16
+ if (typeof value === "number" && Number.isFinite(value)) {
17
+ return value < 1e12 ? value * 1000 : value;
18
+ }
19
+ if (typeof value === "string") {
20
+ const trimmed = value.trim();
21
+ if (!trimmed) {
22
+ return null;
23
+ }
24
+ if (/^\d+$/.test(trimmed)) {
25
+ const numeric = Number(trimmed);
26
+ if (Number.isFinite(numeric)) {
27
+ return numeric < 1e12 ? numeric * 1000 : numeric;
28
+ }
29
+ }
30
+ const parsed = Date.parse(trimmed);
31
+ if (!Number.isNaN(parsed)) {
32
+ return parsed;
33
+ }
34
+ }
35
+ return null;
36
+ };
37
+ const getMessageTimestamp = (message) => {
38
+ const raw = message.createdAt ??
39
+ message.timestamp;
40
+ return normalizeTimestamp(raw);
41
+ };
42
+ const formatTimestampLabel = (timestampMs) => new Date(timestampMs).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
43
+ const ChatConversation = ({ messages, renderMarkdown, onFeedback, onDismissFeedback, onContextFileClick, resolveFileHref, onFileReferenceClick, onPermissionChoice, onSpeak, speakingMessageId, speakPaused, streamingMessageId }) => {
44
+ const renderContent = renderMarkdown ?? MarkdownMessage_1.renderMarkdownToHtml;
45
+ const groupedMessages = (0, react_1.useMemo)(() => {
46
+ const groups = [];
47
+ messages.forEach((message, index) => {
48
+ const role = message.role;
49
+ const timestampMs = getMessageTimestamp(message);
50
+ const lastGroup = groups[groups.length - 1];
51
+ const isSameRole = lastGroup?.role === role;
52
+ const timeGapExceeded = isSameRole &&
53
+ typeof timestampMs === "number" &&
54
+ typeof lastGroup?.lastTimestampMs === "number" &&
55
+ timestampMs - lastGroup.lastTimestampMs > GROUP_TIME_GAP_MS;
56
+ if (!lastGroup || !isSameRole || timeGapExceeded) {
57
+ groups.push({
58
+ id: message.id ?? `group-${index}`,
59
+ role,
60
+ label: ROLE_LABELS[role] ?? role,
61
+ messages: [message],
62
+ timestampMs: timestampMs ?? undefined,
63
+ lastTimestampMs: timestampMs ?? undefined
64
+ });
65
+ return;
66
+ }
67
+ lastGroup.messages.push(message);
68
+ if (typeof timestampMs === "number") {
69
+ lastGroup.timestampMs = timestampMs;
70
+ lastGroup.lastTimestampMs = timestampMs;
71
+ }
72
+ });
73
+ return groups;
74
+ }, [messages]);
75
+ return ((0, jsx_runtime_1.jsx)("div", { className: "chat-conversation", children: groupedMessages.map((group) => {
76
+ const timestampLabel = typeof group.timestampMs === "number" ? formatTimestampLabel(group.timestampMs) : undefined;
77
+ const showHeader = group.messages.length > 1 || !!timestampLabel;
78
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "chat-message-group", "data-role": group.role, children: [showHeader ? ((0, jsx_runtime_1.jsxs)("div", { className: "chat-message-group__header", children: [(0, jsx_runtime_1.jsx)("span", { className: "chat-message-group__label", children: group.label }), timestampLabel ? ((0, jsx_runtime_1.jsx)("span", { className: "chat-message-group__timestamp", children: timestampLabel })) : null] })) : null, (0, jsx_runtime_1.jsx)("div", { className: "chat-message-group__messages", children: group.messages.map((message, index) => ((0, jsx_runtime_1.jsx)(ChatMessage_1.ChatMessageBubble, { message: message, renderMarkdown: renderContent, onFeedback: onFeedback, onDismissFeedback: onDismissFeedback, onContextFileClick: onContextFileClick, resolveFileHref: resolveFileHref, onFileReferenceClick: onFileReferenceClick, showTimestamp: !timestampLabel, onPermissionChoice: onPermissionChoice, onSpeak: onSpeak, speakingMessageId: speakingMessageId, speakPaused: speakPaused, streamingMessageId: streamingMessageId }, message.id ?? `${group.id}-message-${index}`))) })] }, group.id));
79
+ }) }));
80
+ };
81
+ exports.ChatConversation = ChatConversation;
82
+ //# sourceMappingURL=ChatConversation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatConversation.js","sourceRoot":"","sources":["../../src/components/ChatConversation.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { type JSX } from "react";
2
+ import type { ChatMessage, ChatMessageContextFile } from "../types/ui-schema";
3
+ import { type MarkdownRenderOptions } from "./MarkdownMessage";
4
+ import { type PermissionChoice } from "./PermissionCard";
5
+ export interface ChatMessageProps extends MarkdownRenderOptions {
6
+ message: ChatMessage;
7
+ renderMarkdown?: (content: string) => string;
8
+ onFeedback?: (messageId: string, rating: "up" | "down") => void;
9
+ onDismissFeedback?: (messageId: string) => void;
10
+ onContextFileClick?: (file: ChatMessageContextFile) => void;
11
+ onFileReferenceClick?: (reference: string) => void;
12
+ showTimestamp?: boolean;
13
+ /** Show the thumbs up/down feedback buttons on assistant messages. Default: false. */
14
+ showFeedbackButtons?: boolean;
15
+ /** Show the "Copy" button on assistant messages. Default: false. */
16
+ showCopyButton?: boolean;
17
+ /** Called when the user clicks a button on an inline permission card.
18
+ * The host is expected to post the choice back to the extension. */
19
+ onPermissionChoice?: (id: string, choice: PermissionChoice, notes?: string) => void;
20
+ /** Called when the user clicks a speaker control on an assistant
21
+ * message. Host fetches TTS audio and plays/pauses/resumes/stops it.
22
+ * Action defaults to "start" for backward compatibility. When the
23
+ * prop is undefined, no speaker affordance renders. */
24
+ onSpeak?: (messageId: string, text: string, action?: "start" | "pause" | "resume" | "stop") => void;
25
+ /** Id of the message whose audio is currently active (playing or
26
+ * paused). Used to render the multi-button speaker pill. */
27
+ speakingMessageId?: string | null;
28
+ /** True when speakingMessageId's audio is paused (vs playing). Drives
29
+ * the Pause vs Play icon swap inside the active pill. */
30
+ speakPaused?: boolean;
31
+ /** Id of the assistant message currently being streamed in. While set,
32
+ * we hide the speaker pill on that message — listening to a half-baked
33
+ * response is jarring, and the button reappears as soon as the stream
34
+ * closes. */
35
+ streamingMessageId?: string | null;
36
+ }
37
+ export declare const ChatMessageBubble: ({ message, renderMarkdown, onFeedback, onContextFileClick, resolveFileHref, onFileReferenceClick, showTimestamp, showFeedbackButtons, showCopyButton, onPermissionChoice, onSpeak, speakingMessageId, speakPaused, streamingMessageId }: ChatMessageProps) => JSX.Element;
38
+ //# sourceMappingURL=ChatMessage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatMessage.d.ts","sourceRoot":"","sources":["../../src/components/ChatMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAY9D,OAAO,KAAK,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAyC,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AACtG,OAAO,EAAgD,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEvG,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB;IAC7D,OAAO,EAAE,WAAW,CAAC;IACrB,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC;IAChE,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAC5D,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,sFAAsF;IACtF,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oEAAoE;IACpE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;wEACoE;IACpE,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpF;;;4DAGwD;IACxD,OAAO,CAAC,EAAE,CACR,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,KAC3C,IAAI,CAAC;IACV;iEAC6D;IAC7D,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC;8DAC0D;IAC1D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;kBAGc;IACd,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAuCD,eAAO,MAAM,iBAAiB,GAAI,yOAe/B,gBAAgB,KAAG,GAAG,CAAC,OAkZzB,CAAC"}
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ChatMessageBubble = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = require("react");
9
+ const outline_1 = require("@heroicons/react/24/outline");
10
+ const clsx_1 = __importDefault(require("clsx"));
11
+ const MarkdownMessage_1 = require("./MarkdownMessage");
12
+ const PermissionCard_1 = require("./PermissionCard");
13
+ // Matches the fenced markdown block the extension injects for permission
14
+ // prompts: ```bandit-permission\n{...json...}\n```
15
+ const PERMISSION_BLOCK_RE = /```bandit-permission\n([\s\S]*?)\n```/g;
16
+ /** Split content into an ordered list of markdown-text and permission-card
17
+ * segments so we can render each in-line in the correct position. */
18
+ function splitPermissionSegments(content) {
19
+ const segments = [];
20
+ let cursor = 0;
21
+ PERMISSION_BLOCK_RE.lastIndex = 0;
22
+ let m;
23
+ while ((m = PERMISSION_BLOCK_RE.exec(content)) !== null) {
24
+ if (m.index > cursor) {
25
+ segments.push({ kind: "text", text: content.slice(cursor, m.index) });
26
+ }
27
+ try {
28
+ const payload = JSON.parse(m[1]);
29
+ if (payload && payload.type === "bandit:permission" && typeof payload.id === "string") {
30
+ segments.push({ kind: "permission", payload });
31
+ }
32
+ else {
33
+ segments.push({ kind: "text", text: m[0] });
34
+ }
35
+ }
36
+ catch {
37
+ segments.push({ kind: "text", text: m[0] });
38
+ }
39
+ cursor = m.index + m[0].length;
40
+ }
41
+ if (cursor < content.length) {
42
+ segments.push({ kind: "text", text: content.slice(cursor) });
43
+ }
44
+ return segments.length ? segments : [{ kind: "text", text: content }];
45
+ }
46
+ const ChatMessageBubble = ({ message, renderMarkdown, onFeedback, onContextFileClick, resolveFileHref, onFileReferenceClick, showTimestamp = true, showFeedbackButtons = false, showCopyButton = false, onPermissionChoice, onSpeak, speakingMessageId, speakPaused = false, streamingMessageId = null }) => {
47
+ const payload = tryParseJson(message.content);
48
+ const payloadType = typeof payload?.type === "string" ? payload.type : undefined;
49
+ const contentSegments = splitPermissionSegments(message.content);
50
+ const hasPermissionCard = contentSegments.some(s => s.kind === "permission");
51
+ const metadataModel = message.metadata?.model ||
52
+ message.metadata?.modelId ||
53
+ message.metadata?.provider;
54
+ const timestamp = typeof message.createdAt === "string"
55
+ ? message.createdAt
56
+ : undefined;
57
+ const timestampLabel = showTimestamp && timestamp
58
+ ? new Date(timestamp).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })
59
+ : undefined;
60
+ const fileReferences = Array.isArray(message.metadata?.fileReferences)
61
+ ? message.metadata?.fileReferences ?? []
62
+ : [];
63
+ const showFeedback = showFeedbackButtons && message.role === "assistant" && message.id;
64
+ const submitted = message.feedback?.submitted ?? false;
65
+ const rating = message.feedback?.rating;
66
+ const hasContextFiles = Array.isArray(message.contextFiles) && message.contextFiles.length > 0;
67
+ const contextSource = message.contextFiles?.[0]?.source;
68
+ const contextLabel = contextSource === "auto" ? "Auto context" : "Attached context";
69
+ const imageAttachments = Array.isArray(message.images)
70
+ ? message.images
71
+ .map((src) => (typeof src === "string" ? src.trim() : ""))
72
+ .filter((src) => src.length > 0)
73
+ : [];
74
+ const canCopyResponse = showCopyButton &&
75
+ message.role === "assistant" &&
76
+ message.content.trim().length > 0 &&
77
+ payloadType !== "agent-summary";
78
+ const [responseCopied, setResponseCopied] = (0, react_1.useState)(false);
79
+ const [expandedImage, setExpandedImage] = (0, react_1.useState)(null);
80
+ const responseCopyTimer = (0, react_1.useRef)(null);
81
+ (0, react_1.useEffect)(() => {
82
+ return () => {
83
+ if (responseCopyTimer.current !== null) {
84
+ window.clearTimeout(responseCopyTimer.current);
85
+ }
86
+ };
87
+ }, []);
88
+ (0, react_1.useEffect)(() => {
89
+ setResponseCopied(false);
90
+ }, [message.content]);
91
+ (0, react_1.useEffect)(() => {
92
+ if (!expandedImage) {
93
+ return;
94
+ }
95
+ const handleKeyDown = (event) => {
96
+ if (event.key === "Escape") {
97
+ setExpandedImage(null);
98
+ }
99
+ };
100
+ window.addEventListener("keydown", handleKeyDown);
101
+ return () => window.removeEventListener("keydown", handleKeyDown);
102
+ }, [expandedImage]);
103
+ const handleFeedback = (nextRating) => {
104
+ if (!message.id || submitted) {
105
+ return;
106
+ }
107
+ onFeedback?.(message.id, nextRating);
108
+ };
109
+ const handleContextFileClick = (file) => {
110
+ if (!file?.path) {
111
+ return;
112
+ }
113
+ onContextFileClick?.(file);
114
+ };
115
+ const handleFileReferenceClick = (path) => {
116
+ if (!path)
117
+ return;
118
+ onFileReferenceClick?.(path);
119
+ };
120
+ const handleCopyResponse = () => {
121
+ const text = message.content.trim();
122
+ if (!text) {
123
+ return;
124
+ }
125
+ void writeTextToClipboard(text).then(() => {
126
+ setResponseCopied(true);
127
+ if (responseCopyTimer.current !== null) {
128
+ window.clearTimeout(responseCopyTimer.current);
129
+ }
130
+ responseCopyTimer.current = window.setTimeout(() => {
131
+ setResponseCopied(false);
132
+ responseCopyTimer.current = null;
133
+ }, 1500);
134
+ });
135
+ };
136
+ const handleOpenImagePreview = (src, alt) => {
137
+ setExpandedImage({ src, alt });
138
+ };
139
+ const handleCloseImagePreview = () => {
140
+ setExpandedImage(null);
141
+ };
142
+ return ((0, jsx_runtime_1.jsx)("article", { className: (0, clsx_1.default)("message", message.role), children: (0, jsx_runtime_1.jsxs)("div", { className: (0, clsx_1.default)("message-body", message.role), children: [payload?.type === "agent-summary" && payload.__html ? ((0, jsx_runtime_1.jsx)("div", { className: "message-content", dangerouslySetInnerHTML: { __html: payload.__html } })) : hasPermissionCard ? (
143
+ // Permission requests render as a compact placeholder IN the
144
+ // transcript — the interactive card lives in the approval
145
+ // queue above the composer (one-at-a-time, fixed position).
146
+ // This keeps the chat history from getting flooded with
147
+ // cards on multi-edit turns, and kills the screen jitter
148
+ // when cards resolve and vanish from the middle of the
149
+ // scrollback. `onPermissionChoice` is still wired so older
150
+ // snapshots of a conversation that were rendered before the
151
+ // queue existed remain interactive as a fallback.
152
+ (0, jsx_runtime_1.jsx)("div", { className: "message-content", children: contentSegments.map((seg, i) => seg.kind === "permission" ? ((0, jsx_runtime_1.jsxs)("div", { className: "permission-placeholder", role: "status", children: [(0, jsx_runtime_1.jsxs)("svg", { className: "permission-placeholder__icon", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [(0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "12", r: "9" }), (0, jsx_runtime_1.jsx)("polyline", { points: "12 7 12 12 15 14" })] }), (0, jsx_runtime_1.jsxs)("span", { className: "permission-placeholder__label", children: ["Awaiting approval: ", (0, jsx_runtime_1.jsx)("code", { children: seg.payload.tool }), seg.payload.primary ? (0, jsx_runtime_1.jsxs)("span", { className: "permission-placeholder__primary", children: [" \u00B7 ", seg.payload.primary] }) : null] }), (0, jsx_runtime_1.jsx)("span", { className: "permission-placeholder__hint", children: "see approval card above composer" }), onPermissionChoice && (
153
+ // Fallback: clicking the placeholder surfaces the old
154
+ // inline card. Only used when the queue isn't active
155
+ // (e.g. viewing a conversation history in isolation).
156
+ (0, jsx_runtime_1.jsxs)("details", { className: "permission-placeholder__fallback", children: [(0, jsx_runtime_1.jsx)("summary", { children: "Resolve here instead" }), (0, jsx_runtime_1.jsx)(PermissionCard_1.PermissionCard, { payload: seg.payload, onChoice: (id, choice, notes) => onPermissionChoice?.(id, choice, notes) })] }))] }, `perm-${seg.payload.id}-${i}`)) : ((0, jsx_runtime_1.jsx)(MarkdownMessage_1.MarkdownMessage, { content: seg.text, renderHtml: renderMarkdown ?? MarkdownMessage_1.renderMarkdownToHtml, resolveFileHref: resolveFileHref, onFileReferenceClick: onFileReferenceClick ? (reference) => onFileReferenceClick(reference) : undefined }, `md-${i}`))) })) : ((0, jsx_runtime_1.jsx)(MarkdownMessage_1.MarkdownMessage, { className: "message-content", content: message.content, renderHtml: renderMarkdown ?? MarkdownMessage_1.renderMarkdownToHtml, resolveFileHref: resolveFileHref, onFileReferenceClick: onFileReferenceClick ? (reference) => onFileReferenceClick(reference) : undefined })), (metadataModel || timestampLabel || fileReferences.length > 0) && ((0, jsx_runtime_1.jsxs)("div", { className: "message-meta", children: [(0, jsx_runtime_1.jsxs)("div", { className: "message-meta__pills", role: "list", children: [metadataModel && ((0, jsx_runtime_1.jsx)("span", { className: "message-meta__pill", role: "listitem", children: metadataModel })), timestampLabel && ((0, jsx_runtime_1.jsx)("span", { className: "message-meta__pill", role: "listitem", children: timestampLabel }))] }), fileReferences.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "message-meta__files", role: "list", "aria-label": "Message file references", children: fileReferences.map((ref) => ((0, jsx_runtime_1.jsxs)("button", { type: "button", className: "message-meta__file", onClick: () => handleFileReferenceClick(ref.path), children: [(0, jsx_runtime_1.jsx)(outline_1.DocumentTextIcon, { "aria-hidden": "true" }), (0, jsx_runtime_1.jsx)("span", { className: "message-meta__file-text", children: ref.path })] }, ref.path))) }))] })), imageAttachments.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "message-attachments", role: "list", "aria-label": "Image attachments", children: imageAttachments.map((src, index) => ((0, jsx_runtime_1.jsx)("figure", { className: "message-attachment", role: "listitem", children: (0, jsx_runtime_1.jsx)("button", { type: "button", className: "message-attachment__button", onClick: () => handleOpenImagePreview(src, `Image attachment ${index + 1}`), "aria-label": `Open image attachment ${index + 1}`, children: (0, jsx_runtime_1.jsx)("img", { src: src, alt: `Image attachment ${index + 1}`, loading: "lazy", decoding: "async" }) }) }, `${message.id ?? "message"}-image-${index}`))) })), hasContextFiles && ((0, jsx_runtime_1.jsxs)("div", { className: "message-context", children: [(0, jsx_runtime_1.jsx)("span", { className: "message-context__label", children: contextLabel }), (0, jsx_runtime_1.jsx)("div", { className: "message-context__chips", children: message.contextFiles?.map((file) => ((0, jsx_runtime_1.jsxs)("button", { type: "button", className: "message-context__chip", onClick: () => handleContextFileClick(file), "aria-label": `Open ${file.path}`, children: [(0, jsx_runtime_1.jsx)(outline_1.DocumentTextIcon, { "aria-hidden": "true", className: "message-context__chip-icon" }), (0, jsx_runtime_1.jsx)("span", { className: "message-context__chip-text", children: file.path })] }, file.path))) })] })), showFeedback && ((0, jsx_runtime_1.jsx)("div", { className: (0, clsx_1.default)("message-feedback", "message-feedback--compact"), "data-status": submitted ? "submitted" : undefined, "data-rating": submitted && rating ? rating : undefined, children: [
157
+ { rating: "up", Icon: outline_1.HandThumbUpIcon, label: "Helpful" },
158
+ { rating: "down", Icon: outline_1.HandThumbDownIcon, label: "Needs work" }
159
+ ].map(({ rating: optionRating, Icon, label }) => ((0, jsx_runtime_1.jsx)("button", { type: "button", className: (0, clsx_1.default)("feedback-icon-button", optionRating, submitted && rating === optionRating && "active"), onClick: () => handleFeedback(optionRating), disabled: submitted, "aria-label": label, title: label, children: (0, jsx_runtime_1.jsx)(Icon, { "aria-hidden": "true" }) }, optionRating))) })), (() => {
160
+ const isStreamingThisMessage = !!streamingMessageId && message.id === streamingMessageId;
161
+ const speakerEligible = !!onSpeak &&
162
+ !!message.id &&
163
+ message.role === "assistant" &&
164
+ !isStreamingThisMessage;
165
+ const isActive = speakerEligible && speakingMessageId === message.id;
166
+ if (!canCopyResponse && !speakerEligible) {
167
+ return null;
168
+ }
169
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "message-response-actions", children: [canCopyResponse && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: (0, clsx_1.default)("message-response-copy", responseCopied && "is-copied"), onClick: handleCopyResponse, "aria-label": "Copy response", children: responseCopied ? "Copied" : "Copy" })), speakerEligible && !isActive && ((0, jsx_runtime_1.jsxs)("button", { type: "button", className: "message-response-speak", onClick: () => onSpeak(message.id, message.content, "start"), "aria-label": "Read aloud", title: "Read aloud (Brian voice, cloud only)", children: [(0, jsx_runtime_1.jsx)(outline_1.SpeakerWaveIcon, { "aria-hidden": "true" }), (0, jsx_runtime_1.jsx)("span", { className: "message-response-speak__label", children: "Listen" })] })), speakerEligible && isActive && ((0, jsx_runtime_1.jsxs)("div", { className: (0, clsx_1.default)("message-response-speak-pill", speakPaused ? "is-paused" : "is-playing"), role: "group", "aria-label": speakPaused ? "Audio paused" : "Audio playing", children: [(0, jsx_runtime_1.jsxs)("span", { className: "message-response-speak-pill__status", "aria-hidden": "true", children: [(0, jsx_runtime_1.jsx)(outline_1.SpeakerWaveIcon, {}), (0, jsx_runtime_1.jsx)("span", { className: "message-response-speak-pill__label", children: speakPaused ? "Paused" : "Speaking" })] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "message-response-speak-pill__btn", onClick: () => onSpeak(message.id, message.content, speakPaused ? "resume" : "pause"), "aria-label": speakPaused ? "Resume playback" : "Pause playback", title: speakPaused ? "Resume" : "Pause", children: speakPaused ? (0, jsx_runtime_1.jsx)(outline_1.PlayIcon, { "aria-hidden": "true" }) : (0, jsx_runtime_1.jsx)(outline_1.PauseIcon, { "aria-hidden": "true" }) }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "message-response-speak-pill__btn message-response-speak-pill__btn--stop", onClick: () => onSpeak(message.id, message.content, "stop"), "aria-label": "Stop playback", title: "Stop", children: (0, jsx_runtime_1.jsx)(outline_1.StopIcon, { "aria-hidden": "true" }) })] }))] }));
170
+ })(), expandedImage && ((0, jsx_runtime_1.jsx)("div", { className: "agent-image-lightbox", role: "dialog", "aria-modal": "true", "aria-label": "Image preview", onClick: handleCloseImagePreview, children: (0, jsx_runtime_1.jsxs)("div", { className: "agent-image-lightbox__frame", onClick: (event) => event.stopPropagation(), children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: "agent-image-lightbox__close", onClick: handleCloseImagePreview, "aria-label": "Close image preview", children: (0, jsx_runtime_1.jsx)(outline_1.XMarkIcon, { "aria-hidden": "true" }) }), (0, jsx_runtime_1.jsx)("img", { className: "agent-image-lightbox__img", src: expandedImage.src, alt: expandedImage.alt, loading: "eager", decoding: "sync" })] }) }))] }) }));
171
+ };
172
+ exports.ChatMessageBubble = ChatMessageBubble;
173
+ const tryParseJson = (raw) => {
174
+ try {
175
+ return JSON.parse(raw);
176
+ }
177
+ catch {
178
+ return null;
179
+ }
180
+ };
181
+ const writeTextToClipboard = async (text) => {
182
+ if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) {
183
+ try {
184
+ await navigator.clipboard.writeText(text);
185
+ return;
186
+ }
187
+ catch {
188
+ // Fall back to execCommand below.
189
+ }
190
+ }
191
+ if (typeof document === "undefined") {
192
+ return;
193
+ }
194
+ const textarea = document.createElement("textarea");
195
+ textarea.value = text;
196
+ textarea.style.position = "fixed";
197
+ textarea.style.opacity = "0";
198
+ document.body.appendChild(textarea);
199
+ textarea.focus();
200
+ textarea.select();
201
+ try {
202
+ document.execCommand("copy");
203
+ }
204
+ finally {
205
+ document.body.removeChild(textarea);
206
+ }
207
+ };
208
+ //# sourceMappingURL=ChatMessage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatMessage.js","sourceRoot":"","sources":["../../src/components/ChatMessage.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { JSX } from "react";
2
+ export interface DiffBlockProps {
3
+ source?: string | null;
4
+ className?: string;
5
+ }
6
+ export declare const DiffBlock: ({ source, className }: DiffBlockProps) => JSX.Element | null;
7
+ //# sourceMappingURL=DiffBlock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DiffBlock.d.ts","sourceRoot":"","sources":["../../src/components/DiffBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAiBjC,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,SAAS,GAAI,uBAAuB,cAAc,KAAG,GAAG,CAAC,OAAO,GAAG,IA+D/E,CAAC"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DiffBlock = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const classNames_1 = require("../utils/classNames");
6
+ const DIFF_META_PATTERN = /^(diff --git|index|--- |\+\+\+|rename |similarity |new file|deleted file|\\ No newline)/;
7
+ const HUNK_HEADER_PATTERN = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/;
8
+ const getLineClassName = (line) => {
9
+ return (0, classNames_1.classNames)("diff-line", line.startsWith("@@") && "diff-hunk", line.startsWith("+") && "diff-add", line.startsWith("-") && "diff-del", DIFF_META_PATTERN.test(line) && "diff-meta");
10
+ };
11
+ const DiffBlock = ({ source, className }) => {
12
+ if (!source || !source.trim()) {
13
+ return null;
14
+ }
15
+ const normalizedLines = source.replace(/\r\n/g, "\n").split("\n");
16
+ let oldLine = 0;
17
+ let newLine = 0;
18
+ const getLineNumbers = (line) => {
19
+ if (line.startsWith("@@")) {
20
+ const match = line.match(HUNK_HEADER_PATTERN);
21
+ if (match) {
22
+ oldLine = Number.parseInt(match[1], 10);
23
+ newLine = Number.parseInt(match[2], 10);
24
+ }
25
+ return { oldNumber: null, newNumber: null };
26
+ }
27
+ if (DIFF_META_PATTERN.test(line)) {
28
+ return { oldNumber: null, newNumber: null };
29
+ }
30
+ if (line.startsWith("+")) {
31
+ const current = newLine;
32
+ newLine += 1;
33
+ return { oldNumber: null, newNumber: current };
34
+ }
35
+ if (line.startsWith("-")) {
36
+ const current = oldLine;
37
+ oldLine += 1;
38
+ return { oldNumber: current, newNumber: null };
39
+ }
40
+ if (line.startsWith(" ")) {
41
+ const currentOld = oldLine;
42
+ const currentNew = newLine;
43
+ oldLine += 1;
44
+ newLine += 1;
45
+ return { oldNumber: currentOld, newNumber: currentNew };
46
+ }
47
+ return { oldNumber: null, newNumber: null };
48
+ };
49
+ const formatNumber = (value) => {
50
+ return typeof value === "number" ? value.toString() : "";
51
+ };
52
+ return ((0, jsx_runtime_1.jsx)("pre", { className: (0, classNames_1.classNames)("diff-block", className), children: (0, jsx_runtime_1.jsx)("code", { className: "language-diff", children: normalizedLines.map((line, index) => {
53
+ const { oldNumber, newNumber } = getLineNumbers(line);
54
+ return ((0, jsx_runtime_1.jsxs)("span", { className: getLineClassName(line), children: [(0, jsx_runtime_1.jsxs)("span", { className: "diff-line__numbers", "aria-hidden": "true", children: [(0, jsx_runtime_1.jsx)("span", { children: formatNumber(oldNumber) }), (0, jsx_runtime_1.jsx)("span", { children: formatNumber(newNumber) })] }), (0, jsx_runtime_1.jsx)("span", { className: "diff-line__content", children: line.length ? line : "\u00a0" })] }, `diff-line-${index}`));
55
+ }) }) }));
56
+ };
57
+ exports.DiffBlock = DiffBlock;
58
+ //# sourceMappingURL=DiffBlock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DiffBlock.js","sourceRoot":"","sources":["../../src/components/DiffBlock.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { JSX } from "react";
2
+ export interface DiffReviewBlockProps {
3
+ diffText?: string | null;
4
+ className?: string;
5
+ }
6
+ export declare const DiffBlock: ({ diffText, className }: DiffReviewBlockProps) => JSX.Element | null;
7
+ //# sourceMappingURL=DiffBlock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DiffBlock.d.ts","sourceRoot":"","sources":["../../../src/components/DiffReview/DiffBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAGjC,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,SAAS,GAAI,yBAAyB,oBAAoB,KAAG,GAAG,CAAC,OAAO,GAAG,IAKvF,CAAC"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DiffBlock = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const DiffBlock_1 = require("../DiffBlock");
6
+ const DiffBlock = ({ diffText, className }) => {
7
+ if (!diffText || !diffText.trim()) {
8
+ return null;
9
+ }
10
+ return (0, jsx_runtime_1.jsx)(DiffBlock_1.DiffBlock, { source: diffText, className: className ?? "diff-review-block" });
11
+ };
12
+ exports.DiffBlock = DiffBlock;
13
+ //# sourceMappingURL=DiffBlock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DiffBlock.js","sourceRoot":"","sources":["../../../src/components/DiffReview/DiffBlock.tsx"],"names":[],"mappings":";;;;AACA,4CAA0D;AAOnD,MAAM,SAAS,GAAG,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAwB,EAAsB,EAAE;IAC7F,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,uBAAC,qBAAa,IAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,IAAI,mBAAmB,GAAI,CAAC;AAC1F,CAAC,CAAC;AALW,QAAA,SAAS,aAKpB"}
@@ -0,0 +1,14 @@
1
+ import type { JSX } from "react";
2
+ export interface DiffFileGroupProps {
3
+ filePath: string;
4
+ diffText: string;
5
+ added?: number;
6
+ removed?: number;
7
+ confidence?: number;
8
+ review?: string | null;
9
+ defaultOpen?: boolean;
10
+ onCopyDiff?: (filePath: string, diffText: string) => void;
11
+ onOpenFile?: (filePath: string) => void;
12
+ }
13
+ export declare const DiffFileGroup: ({ filePath, diffText, added, removed, confidence, review, defaultOpen, onCopyDiff, onOpenFile }: DiffFileGroupProps) => JSX.Element;
14
+ //# sourceMappingURL=DiffFileGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DiffFileGroup.d.ts","sourceRoot":"","sources":["../../../src/components/DiffReview/DiffFileGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAkB,MAAM,OAAO,CAAC;AAIjD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAkBD,eAAO,MAAM,aAAa,GAAI,iGAU3B,kBAAkB,KAAG,GAAG,CAAC,OAwD3B,CAAC"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DiffFileGroup = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const DiffBlock_1 = require("./DiffBlock");
7
+ const formatSummary = (added, removed) => {
8
+ if (typeof added !== "number" && typeof removed !== "number") {
9
+ return null;
10
+ }
11
+ const addedLabel = typeof added === "number" ? `+${added}` : "+0";
12
+ const removedLabel = typeof removed === "number" ? `-${removed}` : "-0";
13
+ return `${addedLabel} / ${removedLabel}`;
14
+ };
15
+ const formatConfidence = (confidence) => {
16
+ if (typeof confidence !== "number" || Number.isNaN(confidence)) {
17
+ return null;
18
+ }
19
+ return `${Math.round(confidence * 100)}% conf.`;
20
+ };
21
+ const DiffFileGroup = ({ filePath, diffText, added, removed, confidence, review, defaultOpen = false, onCopyDiff, onOpenFile }) => {
22
+ const [isOpen, setIsOpen] = (0, react_1.useState)(defaultOpen);
23
+ const summary = formatSummary(added, removed);
24
+ const confidenceLabel = formatConfidence(confidence);
25
+ const handleCopy = () => {
26
+ if (onCopyDiff) {
27
+ onCopyDiff(filePath, diffText);
28
+ return;
29
+ }
30
+ if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) {
31
+ void navigator.clipboard.writeText(diffText);
32
+ }
33
+ };
34
+ const handleOpenFile = () => {
35
+ onOpenFile?.(filePath);
36
+ };
37
+ const fileLabel = typeof onOpenFile === "function" ? ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "link-button diff-review-file-link", onClick: handleOpenFile, children: filePath })) : ((0, jsx_runtime_1.jsx)("span", { className: "diff-review-file-label", children: filePath }));
38
+ const handleToggle = (event) => {
39
+ setIsOpen(event.currentTarget.open);
40
+ };
41
+ return ((0, jsx_runtime_1.jsxs)("details", { className: "diff-review-file", open: isOpen, onToggle: handleToggle, children: [(0, jsx_runtime_1.jsxs)("summary", { className: "diff-review-file-summary", children: [(0, jsx_runtime_1.jsxs)("div", { className: "diff-review-file-meta", children: [fileLabel, summary && (0, jsx_runtime_1.jsx)("span", { className: "diff-review-chip", children: summary }), confidenceLabel && (0, jsx_runtime_1.jsx)("span", { className: "diff-review-chip", children: confidenceLabel })] }), (0, jsx_runtime_1.jsx)("div", { className: "diff-review-file-actions", children: (0, jsx_runtime_1.jsx)("button", { type: "button", className: "link-button", onClick: handleCopy, children: "Copy diff" }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "diff-review-file-body", children: [(0, jsx_runtime_1.jsx)(DiffBlock_1.DiffBlock, { diffText: diffText, className: "diff-review-diff" }), review?.trim() && ((0, jsx_runtime_1.jsx)("div", { className: "diff-review-note", children: (0, jsx_runtime_1.jsx)("p", { children: review.trim() }) }))] })] }));
42
+ };
43
+ exports.DiffFileGroup = DiffFileGroup;
44
+ //# sourceMappingURL=DiffFileGroup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DiffFileGroup.js","sourceRoot":"","sources":["../../../src/components/DiffReview/DiffFileGroup.tsx"],"names":[],"mappings":"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"}