@percena/weft-react 0.1.4 → 0.1.5-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -2943,6 +2943,48 @@ interface PermissionRequestCardProps {
2943
2943
  }
2944
2944
  declare function PermissionRequestCard({ requestId, toolName, scope, input, reason, isActive, previousResolution, onAllow, onDeny, className, }: PermissionRequestCardProps): react_jsx_runtime.JSX.Element;
2945
2945
 
2946
+ /**
2947
+ * Standard assistant-turn presentation: a TurnCard with local expand state that
2948
+ * stays open while the turn streams, the detailed display mode, and a click
2949
+ * handler that surfaces a step for inspection. Shared so the web app and the
2950
+ * embeddable chat panel render thinking steps identically.
2951
+ */
2952
+ declare function AssistantTurnCard({ sessionId, turn, isLast, onInspectActivity, }: {
2953
+ sessionId: string;
2954
+ turn: Extract<Turn, {
2955
+ type: 'assistant';
2956
+ }>;
2957
+ isLast: boolean;
2958
+ onInspectActivity: (activity: ActivityItem) => void;
2959
+ }): react_jsx_runtime.JSX.Element;
2960
+
2961
+ /**
2962
+ * Renders a single activity's input / output / error for inspection. Shared by
2963
+ * the web app's side panel and the embeddable chat panel's detail popup so the
2964
+ * step-detail view stays identical across hosts.
2965
+ */
2966
+ declare function ActivityInspector({ activity, onClose, }: {
2967
+ activity: ActivityItem | null;
2968
+ onClose?: () => void;
2969
+ }): react_jsx_runtime.JSX.Element;
2970
+
2971
+ /**
2972
+ * Modal popup wrapping ActivityInspector: centered, dismissable via backdrop
2973
+ * click or Escape. Open it from a TurnCard's onOpenActivityDetails callback.
2974
+ */
2975
+ declare function ActivityDetailsPanel({ activity, onClose, }: {
2976
+ activity: ActivityItem | null;
2977
+ onClose: () => void;
2978
+ }): react_jsx_runtime.JSX.Element | null;
2979
+
2980
+ declare function PermissionModeMenu({ value, onChange, onClose, isOpen, onToggle, }: {
2981
+ value: PermissionMode;
2982
+ onChange: (mode: PermissionMode) => void;
2983
+ onClose?: () => void;
2984
+ isOpen: boolean;
2985
+ onToggle: () => void;
2986
+ }): react_jsx_runtime.JSX.Element;
2987
+
2946
2988
  interface CodeBlockProps {
2947
2989
  code: string;
2948
2990
  language?: string;
@@ -3910,7 +3952,7 @@ interface UseEventProcessorResult {
3910
3952
  */
3911
3953
  declare function useEventProcessor(options: UseEventProcessorOptions): UseEventProcessorResult;
3912
3954
 
3913
- export { type ActivityItem, type ActivityStatus, AnnotationIslandMenu, type AnnotationIslandMenuProps, type AnnotationOverlayChip, type AnnotationOverlayGeometryResult, AnnotationOverlayLayer, type AnnotationOverlayLayerProps, type AnnotationOverlayRect, type AssistantTurn, type AuthRequestTurn, type ChatEvent, ChatTranscript, type ChatTranscriptProps, CodeBlock, CollapsibleMarkdownProvider, type Effect, type EventSource, type EventSourceCallback, type EventSourceCloseCallback, type EventSourceErrorCallback, InProcessEventSource, type InlineActivityItem, InlineCode, InlineExecution, type InlineExecutionProps, type InlineExecutionStatus, type IslandTransitionConfig, Markdown, type MarkdownProps, MemoizedMarkdown, PendingIndicator, type PendingIndicatorProps, PermissionRequestCard, type PermissionRequestCardProps, type PlatformActions, PlatformProvider, type PointerSnapshot, type ProcessResult, type RenderMode, ResponseCard, type ResponseCardProps, type ResponseContent, SIZE_CONFIG, SSEEventSource, type Session, type SessionState, SessionViewer, type SessionViewerMode, type SessionViewerProps, type StreamingState, SystemMessage, type SystemMessageProps, type SystemMessageType, type SystemTurn, type TextSegment, type TodoItem, type Turn, TurnCard, type TurnCardProps, UserMessageBubble, type UserMessageBubbleProps, type UserTurn, WebSocketEventSource, appendMessage, buildAnnotationChipEntryTransition, buildSelectionEntryTransition, collectTextSegments, computeAnnotationOverlayGeometry, createSelectionPreviewAnnotation, createTextSelectionAnnotation, findAssistantMessage, findStreamingMessage, findToolMessage, generateMessageId, getAssistantTurnUiKey, getCanonicalText, groupMessagesByTurn, hasExistingTextRangeAnnotation, mapCoreEventToProcessorEvent, mapTimelineEnvelopeToProcessorEvent, processEvent, resolveNodeOffset, shouldShowStreamingContent, updateMessageAt, useEventProcessor };
3955
+ export { ActivityDetailsPanel, ActivityInspector, type ActivityItem, type ActivityStatus, AnnotationIslandMenu, type AnnotationIslandMenuProps, type AnnotationOverlayChip, type AnnotationOverlayGeometryResult, AnnotationOverlayLayer, type AnnotationOverlayLayerProps, type AnnotationOverlayRect, type AssistantTurn, AssistantTurnCard, type AuthRequestTurn, type ChatEvent, ChatTranscript, type ChatTranscriptProps, CodeBlock, CollapsibleMarkdownProvider, type Effect, type EventSource, type EventSourceCallback, type EventSourceCloseCallback, type EventSourceErrorCallback, InProcessEventSource, type InlineActivityItem, InlineCode, InlineExecution, type InlineExecutionProps, type InlineExecutionStatus, type IslandTransitionConfig, Markdown, type MarkdownProps, MemoizedMarkdown, PendingIndicator, type PendingIndicatorProps, PermissionModeMenu, PermissionRequestCard, type PermissionRequestCardProps, type PlatformActions, PlatformProvider, type PointerSnapshot, type ProcessResult, type RenderMode, ResponseCard, type ResponseCardProps, type ResponseContent, SIZE_CONFIG, SSEEventSource, type Session, type SessionState, SessionViewer, type SessionViewerMode, type SessionViewerProps, type StreamingState, SystemMessage, type SystemMessageProps, type SystemMessageType, type SystemTurn, type TextSegment, type TodoItem, type Turn, TurnCard, type TurnCardProps, UserMessageBubble, type UserMessageBubbleProps, type UserTurn, WebSocketEventSource, appendMessage, buildAnnotationChipEntryTransition, buildSelectionEntryTransition, collectTextSegments, computeAnnotationOverlayGeometry, createSelectionPreviewAnnotation, createTextSelectionAnnotation, findAssistantMessage, findStreamingMessage, findToolMessage, generateMessageId, getAssistantTurnUiKey, getCanonicalText, groupMessagesByTurn, hasExistingTextRangeAnnotation, mapCoreEventToProcessorEvent, mapTimelineEnvelopeToProcessorEvent, processEvent, resolveNodeOffset, shouldShowStreamingContent, updateMessageAt, useEventProcessor };
3914
3956
 
3915
3957
  // -- @weft/ui/lib/en-fallback.d.ts --
3916
3958
  /**
package/dist/index.d.ts CHANGED
@@ -2943,6 +2943,48 @@ interface PermissionRequestCardProps {
2943
2943
  }
2944
2944
  declare function PermissionRequestCard({ requestId, toolName, scope, input, reason, isActive, previousResolution, onAllow, onDeny, className, }: PermissionRequestCardProps): react_jsx_runtime.JSX.Element;
2945
2945
 
2946
+ /**
2947
+ * Standard assistant-turn presentation: a TurnCard with local expand state that
2948
+ * stays open while the turn streams, the detailed display mode, and a click
2949
+ * handler that surfaces a step for inspection. Shared so the web app and the
2950
+ * embeddable chat panel render thinking steps identically.
2951
+ */
2952
+ declare function AssistantTurnCard({ sessionId, turn, isLast, onInspectActivity, }: {
2953
+ sessionId: string;
2954
+ turn: Extract<Turn, {
2955
+ type: 'assistant';
2956
+ }>;
2957
+ isLast: boolean;
2958
+ onInspectActivity: (activity: ActivityItem) => void;
2959
+ }): react_jsx_runtime.JSX.Element;
2960
+
2961
+ /**
2962
+ * Renders a single activity's input / output / error for inspection. Shared by
2963
+ * the web app's side panel and the embeddable chat panel's detail popup so the
2964
+ * step-detail view stays identical across hosts.
2965
+ */
2966
+ declare function ActivityInspector({ activity, onClose, }: {
2967
+ activity: ActivityItem | null;
2968
+ onClose?: () => void;
2969
+ }): react_jsx_runtime.JSX.Element;
2970
+
2971
+ /**
2972
+ * Modal popup wrapping ActivityInspector: centered, dismissable via backdrop
2973
+ * click or Escape. Open it from a TurnCard's onOpenActivityDetails callback.
2974
+ */
2975
+ declare function ActivityDetailsPanel({ activity, onClose, }: {
2976
+ activity: ActivityItem | null;
2977
+ onClose: () => void;
2978
+ }): react_jsx_runtime.JSX.Element | null;
2979
+
2980
+ declare function PermissionModeMenu({ value, onChange, onClose, isOpen, onToggle, }: {
2981
+ value: PermissionMode;
2982
+ onChange: (mode: PermissionMode) => void;
2983
+ onClose?: () => void;
2984
+ isOpen: boolean;
2985
+ onToggle: () => void;
2986
+ }): react_jsx_runtime.JSX.Element;
2987
+
2946
2988
  interface CodeBlockProps {
2947
2989
  code: string;
2948
2990
  language?: string;
@@ -3910,7 +3952,7 @@ interface UseEventProcessorResult {
3910
3952
  */
3911
3953
  declare function useEventProcessor(options: UseEventProcessorOptions): UseEventProcessorResult;
3912
3954
 
3913
- export { type ActivityItem, type ActivityStatus, AnnotationIslandMenu, type AnnotationIslandMenuProps, type AnnotationOverlayChip, type AnnotationOverlayGeometryResult, AnnotationOverlayLayer, type AnnotationOverlayLayerProps, type AnnotationOverlayRect, type AssistantTurn, type AuthRequestTurn, type ChatEvent, ChatTranscript, type ChatTranscriptProps, CodeBlock, CollapsibleMarkdownProvider, type Effect, type EventSource, type EventSourceCallback, type EventSourceCloseCallback, type EventSourceErrorCallback, InProcessEventSource, type InlineActivityItem, InlineCode, InlineExecution, type InlineExecutionProps, type InlineExecutionStatus, type IslandTransitionConfig, Markdown, type MarkdownProps, MemoizedMarkdown, PendingIndicator, type PendingIndicatorProps, PermissionRequestCard, type PermissionRequestCardProps, type PlatformActions, PlatformProvider, type PointerSnapshot, type ProcessResult, type RenderMode, ResponseCard, type ResponseCardProps, type ResponseContent, SIZE_CONFIG, SSEEventSource, type Session, type SessionState, SessionViewer, type SessionViewerMode, type SessionViewerProps, type StreamingState, SystemMessage, type SystemMessageProps, type SystemMessageType, type SystemTurn, type TextSegment, type TodoItem, type Turn, TurnCard, type TurnCardProps, UserMessageBubble, type UserMessageBubbleProps, type UserTurn, WebSocketEventSource, appendMessage, buildAnnotationChipEntryTransition, buildSelectionEntryTransition, collectTextSegments, computeAnnotationOverlayGeometry, createSelectionPreviewAnnotation, createTextSelectionAnnotation, findAssistantMessage, findStreamingMessage, findToolMessage, generateMessageId, getAssistantTurnUiKey, getCanonicalText, groupMessagesByTurn, hasExistingTextRangeAnnotation, mapCoreEventToProcessorEvent, mapTimelineEnvelopeToProcessorEvent, processEvent, resolveNodeOffset, shouldShowStreamingContent, updateMessageAt, useEventProcessor };
3955
+ export { ActivityDetailsPanel, ActivityInspector, type ActivityItem, type ActivityStatus, AnnotationIslandMenu, type AnnotationIslandMenuProps, type AnnotationOverlayChip, type AnnotationOverlayGeometryResult, AnnotationOverlayLayer, type AnnotationOverlayLayerProps, type AnnotationOverlayRect, type AssistantTurn, AssistantTurnCard, type AuthRequestTurn, type ChatEvent, ChatTranscript, type ChatTranscriptProps, CodeBlock, CollapsibleMarkdownProvider, type Effect, type EventSource, type EventSourceCallback, type EventSourceCloseCallback, type EventSourceErrorCallback, InProcessEventSource, type InlineActivityItem, InlineCode, InlineExecution, type InlineExecutionProps, type InlineExecutionStatus, type IslandTransitionConfig, Markdown, type MarkdownProps, MemoizedMarkdown, PendingIndicator, type PendingIndicatorProps, PermissionModeMenu, PermissionRequestCard, type PermissionRequestCardProps, type PlatformActions, PlatformProvider, type PointerSnapshot, type ProcessResult, type RenderMode, ResponseCard, type ResponseCardProps, type ResponseContent, SIZE_CONFIG, SSEEventSource, type Session, type SessionState, SessionViewer, type SessionViewerMode, type SessionViewerProps, type StreamingState, SystemMessage, type SystemMessageProps, type SystemMessageType, type SystemTurn, type TextSegment, type TodoItem, type Turn, TurnCard, type TurnCardProps, UserMessageBubble, type UserMessageBubbleProps, type UserTurn, WebSocketEventSource, appendMessage, buildAnnotationChipEntryTransition, buildSelectionEntryTransition, collectTextSegments, computeAnnotationOverlayGeometry, createSelectionPreviewAnnotation, createTextSelectionAnnotation, findAssistantMessage, findStreamingMessage, findToolMessage, generateMessageId, getAssistantTurnUiKey, getCanonicalText, groupMessagesByTurn, hasExistingTextRangeAnnotation, mapCoreEventToProcessorEvent, mapTimelineEnvelopeToProcessorEvent, processEvent, resolveNodeOffset, shouldShowStreamingContent, updateMessageAt, useEventProcessor };
3914
3956
 
3915
3957
  // -- @weft/ui/lib/en-fallback.d.ts --
3916
3958
  /**
package/dist/index.js CHANGED
@@ -166,7 +166,13 @@ import { createContext as createContext3, useContext as useContext3 } from "reac
166
166
  import { jsx as jsx32 } from "react/jsx-runtime";
167
167
  import { jsx as jsx33, jsxs as jsxs17 } from "react/jsx-runtime";
168
168
  import { jsx as jsx34, jsxs as jsxs18 } from "react/jsx-runtime";
169
- import { useCallback as useCallback8, useRef as useRef7, useState as useState10, useEffect as useEffect6 } from "react";
169
+ import { useState as useState10, useEffect as useEffect6 } from "react";
170
+ import { jsx as jsx35 } from "react/jsx-runtime";
171
+ import { jsx as jsx36, jsxs as jsxs19 } from "react/jsx-runtime";
172
+ import { useEffect as useEffect7 } from "react";
173
+ import { jsx as jsx37 } from "react/jsx-runtime";
174
+ import { jsx as jsx38, jsxs as jsxs20 } from "react/jsx-runtime";
175
+ import { useCallback as useCallback8, useRef as useRef7, useState as useState11, useEffect as useEffect8 } from "react";
170
176
  function getAssistantTurnUiKey(turn, index) {
171
177
  if (turn.response?.messageId) {
172
178
  return `assistant:msg:${turn.response.messageId}`;
@@ -5117,6 +5123,162 @@ function PendingIndicator({
5117
5123
  delay
5118
5124
  )) }) });
5119
5125
  }
5126
+ function AssistantTurnCard({
5127
+ sessionId,
5128
+ turn,
5129
+ isLast,
5130
+ onInspectActivity
5131
+ }) {
5132
+ const [isExpanded, setIsExpanded] = useState10(true);
5133
+ const [expandedActivityGroups, setExpandedActivityGroups] = useState10(/* @__PURE__ */ new Set());
5134
+ useEffect6(() => {
5135
+ if (turn.isStreaming) {
5136
+ setIsExpanded(true);
5137
+ }
5138
+ }, [turn.isStreaming]);
5139
+ return /* @__PURE__ */ jsx35(
5140
+ TurnCard,
5141
+ {
5142
+ sessionId,
5143
+ turnId: turn.turnId,
5144
+ activities: turn.activities,
5145
+ response: turn.response,
5146
+ intent: turn.intent,
5147
+ isStreaming: turn.isStreaming,
5148
+ isComplete: turn.isComplete,
5149
+ isExpanded,
5150
+ onExpandedChange: setIsExpanded,
5151
+ expandedActivityGroups,
5152
+ onExpandedActivityGroupsChange: setExpandedActivityGroups,
5153
+ onOpenActivityDetails: onInspectActivity,
5154
+ hasEditOrWriteActivities: turn.activities.some(
5155
+ (activity) => activity.toolName === "Edit" || activity.toolName === "Write"
5156
+ ),
5157
+ todos: turn.todos,
5158
+ isLastResponse: isLast,
5159
+ displayMode: "detailed",
5160
+ animateResponse: true,
5161
+ annotationInteractionMode: "tooltip-only"
5162
+ }
5163
+ );
5164
+ }
5165
+ function ActivityInspector({
5166
+ activity,
5167
+ onClose
5168
+ }) {
5169
+ if (!activity) {
5170
+ return /* @__PURE__ */ jsx36("div", { className: "rounded-[8px] bg-background shadow-minimal p-4 text-[13px] text-muted-foreground", children: "Select an activity from the turn card to inspect its input and output." });
5171
+ }
5172
+ return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col overflow-hidden", children: [
5173
+ /* @__PURE__ */ jsxs19("div", { className: "flex items-start justify-between gap-3 border-b border-border px-4 py-3", children: [
5174
+ /* @__PURE__ */ jsxs19("div", { className: "min-w-0", children: [
5175
+ /* @__PURE__ */ jsx36("div", { className: "truncate text-[13px] font-medium text-foreground", children: activity.displayName ?? activity.toolName ?? "Activity" }),
5176
+ /* @__PURE__ */ jsx36("div", { className: "mt-1 text-[12px] text-muted-foreground", children: activity.intent ?? activity.status ?? "unknown" })
5177
+ ] }),
5178
+ onClose && /* @__PURE__ */ jsx36(
5179
+ "button",
5180
+ {
5181
+ type: "button",
5182
+ onClick: onClose,
5183
+ className: "flex h-7 w-7 items-center justify-center rounded-[6px] text-[16px] leading-none text-muted-foreground transition hover:bg-foreground/[0.06] hover:text-foreground",
5184
+ "aria-label": "Close activity details",
5185
+ children: "\u2715"
5186
+ }
5187
+ )
5188
+ ] }),
5189
+ /* @__PURE__ */ jsxs19("div", { className: "overflow-y-auto space-y-4 p-4", children: [
5190
+ activity.toolInput && /* @__PURE__ */ jsxs19("div", { children: [
5191
+ /* @__PURE__ */ jsx36("div", { className: "mb-2 text-[12px] font-medium text-muted-foreground", children: "Input" }),
5192
+ /* @__PURE__ */ jsx36("pre", { className: "max-h-[280px] overflow-auto rounded-[6px] bg-foreground/[0.04] p-3 text-[12px] leading-relaxed text-foreground", children: JSON.stringify(activity.toolInput, null, 2) })
5193
+ ] }),
5194
+ activity.error && /* @__PURE__ */ jsxs19("div", { children: [
5195
+ /* @__PURE__ */ jsx36("div", { className: "mb-2 text-[12px] font-medium text-muted-foreground", children: "Error" }),
5196
+ /* @__PURE__ */ jsx36("pre", { className: "max-h-[320px] overflow-auto whitespace-pre-wrap rounded-[6px] bg-foreground/[0.04] p-3 text-[12px] leading-relaxed text-foreground", children: activity.error })
5197
+ ] }),
5198
+ activity.content && !activity.error && /* @__PURE__ */ jsxs19("div", { children: [
5199
+ /* @__PURE__ */ jsx36("div", { className: "mb-2 text-[12px] font-medium text-muted-foreground", children: "Output" }),
5200
+ /* @__PURE__ */ jsx36("div", { className: "max-h-[320px] overflow-y-auto rounded-[6px] bg-foreground/[0.04] px-3 py-2 text-[12px] text-foreground", children: /* @__PURE__ */ jsx36(Markdown, { mode: "minimal", className: "text-[12px] leading-relaxed", children: activity.content }) })
5201
+ ] })
5202
+ ] })
5203
+ ] });
5204
+ }
5205
+ function ActivityDetailsPanel({
5206
+ activity,
5207
+ onClose
5208
+ }) {
5209
+ useEffect7(() => {
5210
+ if (!activity) return;
5211
+ const handleKeyDown = (e) => {
5212
+ if (e.key === "Escape") onClose();
5213
+ };
5214
+ window.addEventListener("keydown", handleKeyDown);
5215
+ return () => window.removeEventListener("keydown", handleKeyDown);
5216
+ }, [activity, onClose]);
5217
+ if (!activity) return null;
5218
+ return /* @__PURE__ */ jsx37(
5219
+ "div",
5220
+ {
5221
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-background/60 backdrop-blur-sm",
5222
+ onClick: onClose,
5223
+ children: /* @__PURE__ */ jsx37(
5224
+ "div",
5225
+ {
5226
+ className: "relative w-full max-w-[640px] max-h-[80vh] overflow-hidden rounded-[12px] border border-border bg-background shadow-strong mx-4",
5227
+ onClick: (e) => e.stopPropagation(),
5228
+ children: /* @__PURE__ */ jsx37(ActivityInspector, { activity, onClose })
5229
+ }
5230
+ )
5231
+ }
5232
+ );
5233
+ }
5234
+ var PERMISSION_CONFIG = [
5235
+ { mode: "safe", label: "Explore", description: "Read-only planning and inspection.", icon: "\u25CE" },
5236
+ { mode: "ask", label: "Ask", description: "Review changes before execution.", icon: "\u24D8" },
5237
+ { mode: "allow-all", label: "Execute", description: "Allow edits and commands in this session.", icon: "\u21C4" }
5238
+ ];
5239
+ function PermissionModeMenu({
5240
+ value,
5241
+ onChange,
5242
+ onClose,
5243
+ isOpen,
5244
+ onToggle
5245
+ }) {
5246
+ const selected = PERMISSION_CONFIG.find((o) => o.mode === value) ?? PERMISSION_CONFIG[1];
5247
+ return /* @__PURE__ */ jsxs20("div", { className: "relative", children: [
5248
+ isOpen && /* @__PURE__ */ jsx38("div", { className: "absolute bottom-[calc(100%+6px)] left-0 z-20 w-[204px] rounded-[9px] border border-border bg-background p-1.5 shadow-modal-small", children: /* @__PURE__ */ jsx38("div", { className: "space-y-0.5", children: PERMISSION_CONFIG.map((option) => /* @__PURE__ */ jsxs20(
5249
+ "button",
5250
+ {
5251
+ type: "button",
5252
+ onClick: () => {
5253
+ onChange(option.mode);
5254
+ onClose?.();
5255
+ },
5256
+ className: `flex h-8 w-full items-center gap-2 rounded-[6px] px-2 text-left text-[12px] transition ${option.mode === value ? "bg-foreground/[0.08] text-foreground" : "text-muted-foreground hover:bg-foreground/[0.05] hover:text-foreground"}`,
5257
+ children: [
5258
+ /* @__PURE__ */ jsx38("span", { className: "w-4 text-center text-[12px]", children: option.icon }),
5259
+ /* @__PURE__ */ jsx38("span", { className: "flex-1", children: option.label }),
5260
+ option.mode === value && /* @__PURE__ */ jsx38("span", { "aria-hidden": "true", className: "text-[12px] text-foreground", children: "\u25CF" })
5261
+ ]
5262
+ },
5263
+ option.mode
5264
+ )) }) }),
5265
+ /* @__PURE__ */ jsxs20(
5266
+ "button",
5267
+ {
5268
+ type: "button",
5269
+ "aria-haspopup": "menu",
5270
+ "aria-expanded": isOpen,
5271
+ onClick: onToggle,
5272
+ className: "inline-flex h-8 items-center gap-1.5 rounded-[7px] border border-border bg-foreground/[0.035] px-2.5 text-[12px] text-foreground transition hover:bg-foreground/[0.06]",
5273
+ children: [
5274
+ /* @__PURE__ */ jsx38("span", { className: "text-muted-foreground", children: selected.icon }),
5275
+ /* @__PURE__ */ jsx38("span", { children: selected.label }),
5276
+ /* @__PURE__ */ jsx38("span", { className: "text-muted-foreground", children: "\u2304" })
5277
+ ]
5278
+ }
5279
+ )
5280
+ ] });
5281
+ }
5120
5282
  function generateMessageId2() {
5121
5283
  return generateMessageId();
5122
5284
  }
@@ -6518,6 +6680,10 @@ function normalizeTimelineToolName(name) {
6518
6680
  return name;
6519
6681
  }
6520
6682
  function optionalToolDisplayName(toolName, detail) {
6683
+ if (detail && typeof detail === "object") {
6684
+ const explicit = detail.displayName;
6685
+ if (typeof explicit === "string" && explicit) return { toolDisplayName: explicit };
6686
+ }
6521
6687
  if (toolName !== "commandExecution") return {};
6522
6688
  const displayName = commandDisplayName(detail);
6523
6689
  return displayName ? { toolDisplayName: displayName } : {};
@@ -6653,10 +6819,10 @@ function normalizeTokenUsage(usage) {
6653
6819
  }
6654
6820
  function useEventProcessor(options) {
6655
6821
  const { eventSource, sessionId, workspaceId, workspaceName, onEffect, onError, onClose } = options;
6656
- const [session, setSession] = useState10(null);
6822
+ const [session, setSession] = useState11(null);
6657
6823
  const sessionRef = useRef7(null);
6658
6824
  const streamingStates = useRef7(/* @__PURE__ */ new Map());
6659
- const [isConnected, setIsConnected] = useState10(false);
6825
+ const [isConnected, setIsConnected] = useState11(false);
6660
6826
  const processedCount = useRef7(0);
6661
6827
  const processAgentEvent = useCallback8((event) => {
6662
6828
  const processorEvent = mapCoreEventToProcessorEvent(event, sessionId);
@@ -6678,7 +6844,7 @@ function useEventProcessor(options) {
6678
6844
  effects: result.effects
6679
6845
  };
6680
6846
  }, [sessionId, workspaceId, workspaceName]);
6681
- useEffect6(() => {
6847
+ useEffect8(() => {
6682
6848
  eventSource.connect(
6683
6849
  (coreEvent) => {
6684
6850
  const result = processAgentEvent(coreEvent);
@@ -6837,7 +7003,7 @@ var InProcessEventSource = class {
6837
7003
 
6838
7004
  // ../local-chat/dist/index.js
6839
7005
  import { useState as useState22 } from "react";
6840
- import { useCallback as useCallback9, useEffect as useEffect7, useMemo as useMemo8, useRef as useRef8, useState as useState11 } from "react";
7006
+ import { useCallback as useCallback9, useEffect as useEffect9, useMemo as useMemo8, useRef as useRef8, useState as useState12 } from "react";
6841
7007
 
6842
7008
  // ../timeline/dist/index.js
6843
7009
  function createTimelineCursor(cursor) {
@@ -6885,7 +7051,7 @@ function timelineKey(item) {
6885
7051
  }
6886
7052
 
6887
7053
  // ../local-chat/dist/index.js
6888
- import { jsx as jsx35, jsxs as jsxs19 } from "react/jsx-runtime";
7054
+ import { jsx as jsx39, jsxs as jsxs21 } from "react/jsx-runtime";
6889
7055
  import { useCallback as useCallback22, useEffect as useEffect22, useMemo as useMemo22, useRef as useRef22, useState as useState32 } from "react";
6890
7056
  import { jsx as jsx210, jsxs as jsxs22 } from "react/jsx-runtime";
6891
7057
  function createAgentChatPanelModel(args) {
@@ -6974,8 +7140,8 @@ function createTimelineDetailItems(timeline) {
6974
7140
  }
6975
7141
  function useAgentChatSession(options) {
6976
7142
  const { runtime, workspaceId = "local-workspace", workspaceName = "Local Workspace" } = options;
6977
- const [auth, setAuth] = useState11(null);
6978
- const [error, setError] = useState11(null);
7143
+ const [auth, setAuth] = useState12(null);
7144
+ const [error, setError] = useState12(null);
6979
7145
  const processor = useEventProcessor({
6980
7146
  eventSource: runtime.events,
6981
7147
  sessionId: runtime.sessionId,
@@ -7022,13 +7188,13 @@ function useAgentChatSession(options) {
7022
7188
  }
7023
7189
  function useTimelineAgentChatSession(options) {
7024
7190
  const { runtime, workspaceId = "local-workspace", workspaceName = "Local Workspace" } = options;
7025
- const [timeline, setTimeline] = useState11([]);
7026
- const [capabilityReport, setCapabilityReport] = useState11(null);
7027
- const [error, setError] = useState11(null);
7028
- const [isReconnecting, setIsReconnecting] = useState11(false);
7029
- const [hasGap, setHasGap] = useState11(false);
7191
+ const [timeline, setTimeline] = useState12([]);
7192
+ const [capabilityReport, setCapabilityReport] = useState12(null);
7193
+ const [error, setError] = useState12(null);
7194
+ const [isReconnecting, setIsReconnecting] = useState12(false);
7195
+ const [hasGap, setHasGap] = useState12(false);
7030
7196
  const lastCursorRef = useRef8(null);
7031
- useEffect7(() => {
7197
+ useEffect9(() => {
7032
7198
  let catchupAbort = false;
7033
7199
  const onEvent = (envelope) => {
7034
7200
  lastCursorRef.current = { epoch: envelope.epoch, afterSeq: envelope.seq };
@@ -7334,8 +7500,8 @@ function AgentChatPanel({
7334
7500
  }
7335
7501
  }
7336
7502
  const storedSession = chat.session ? toStoredSession(chat.session, workspaceId) : createEmptyStoredSession(runtime.sessionId, workspaceId, workspaceName);
7337
- const footer = /* @__PURE__ */ jsxs19("form", { onSubmit: handleSubmit, className: "flex gap-2 p-3", children: [
7338
- /* @__PURE__ */ jsx35(
7503
+ const footer = /* @__PURE__ */ jsxs21("form", { onSubmit: handleSubmit, className: "flex gap-2 p-3", children: [
7504
+ /* @__PURE__ */ jsx39(
7339
7505
  "textarea",
7340
7506
  {
7341
7507
  value: draft,
@@ -7345,7 +7511,7 @@ function AgentChatPanel({
7345
7511
  className: "min-h-10 flex-1 resize-none rounded-md border px-3 py-2 text-sm"
7346
7512
  }
7347
7513
  ),
7348
- /* @__PURE__ */ jsx35(
7514
+ /* @__PURE__ */ jsx39(
7349
7515
  "button",
7350
7516
  {
7351
7517
  type: "submit",
@@ -7354,7 +7520,7 @@ function AgentChatPanel({
7354
7520
  children: "Send"
7355
7521
  }
7356
7522
  ),
7357
- chat.isRunning && /* @__PURE__ */ jsx35(
7523
+ chat.isRunning && /* @__PURE__ */ jsx39(
7358
7524
  "button",
7359
7525
  {
7360
7526
  type: "button",
@@ -7364,9 +7530,9 @@ function AgentChatPanel({
7364
7530
  }
7365
7531
  )
7366
7532
  ] });
7367
- return /* @__PURE__ */ jsxs19("div", { className, children: [
7368
- chat.error && /* @__PURE__ */ jsx35("div", { className: "border-b px-3 py-2 text-sm text-red-600", children: chat.error.message }),
7369
- /* @__PURE__ */ jsx35(
7533
+ return /* @__PURE__ */ jsxs21("div", { className, children: [
7534
+ chat.error && /* @__PURE__ */ jsx39("div", { className: "border-b px-3 py-2 text-sm text-red-600", children: chat.error.message }),
7535
+ /* @__PURE__ */ jsx39(
7370
7536
  SessionViewer,
7371
7537
  {
7372
7538
  session: storedSession,
@@ -7442,10 +7608,7 @@ function TimelineAgentChatPanel({
7442
7608
  const [selectedActivity, setSelectedActivity] = useState32(null);
7443
7609
  const [selectedDetail, setSelectedDetail] = useState32(null);
7444
7610
  const [permissionMode, setPermissionMode] = useState32("ask");
7445
- const [turnExpandOverride, setTurnExpandOverride] = useState32({});
7446
- const handleTurnExpandedChange = useCallback22((turnId, expanded) => {
7447
- setTurnExpandOverride((prev) => ({ ...prev, [turnId]: expanded }));
7448
- }, []);
7611
+ const [isPermMenuOpen, setIsPermMenuOpen] = useState32(false);
7449
7612
  const runtimeState = runtime.getState();
7450
7613
  const isWaitingPermission = runtimeState.status === "waiting_for_permission";
7451
7614
  const waitingRequestId = runtimeState.waitingPermissionRequestId;
@@ -7499,28 +7662,13 @@ function TimelineAgentChatPanel({
7499
7662
  return /* @__PURE__ */ jsx210("div", { className: "flex justify-end py-1", children: /* @__PURE__ */ jsx210(UserMessageBubble, { content: turn.message.content }) }, `user-${turn.message.id}`);
7500
7663
  }
7501
7664
  if (turn.type === "assistant") {
7502
- const isLast = index === chat.turns.length - 1;
7503
- const defaultExpanded = turn.isStreaming || isLast && chat.isRunning;
7504
- const isExpanded = turnExpandOverride[turn.turnId] ?? defaultExpanded;
7505
7665
  return /* @__PURE__ */ jsx210(
7506
- TurnCard,
7666
+ AssistantTurnCard,
7507
7667
  {
7508
7668
  sessionId: workspaceId,
7509
- turnId: turn.turnId,
7510
- activities: turn.activities,
7511
- response: turn.response,
7512
- intent: turn.intent,
7513
- isStreaming: turn.isStreaming,
7514
- isComplete: turn.isComplete,
7515
- isExpanded,
7516
- onExpandedChange: (expanded) => handleTurnExpandedChange(turn.turnId, expanded),
7517
- onOpenActivityDetails: setSelectedActivity,
7518
- hasEditOrWriteActivities: turn.activities.some(
7519
- (a) => a.toolName === "Edit" || a.toolName === "Write"
7520
- ),
7521
- todos: turn.todos,
7522
- isLastResponse: isLast,
7523
- displayMode: "detailed"
7669
+ turn,
7670
+ isLast: index === chat.turns.length - 1,
7671
+ onInspectActivity: setSelectedActivity
7524
7672
  },
7525
7673
  `assistant-${turn.turnId}`
7526
7674
  );
@@ -7610,24 +7758,19 @@ function TimelineAgentChatPanel({
7610
7758
  }
7611
7759
  )
7612
7760
  ] }),
7613
- /* @__PURE__ */ jsxs22("label", { className: "flex items-center gap-2 text-[12px] text-muted-foreground", children: [
7614
- /* @__PURE__ */ jsx210("span", { className: "shrink-0", children: "Tool permissions" }),
7615
- /* @__PURE__ */ jsxs22(
7616
- "select",
7617
- {
7618
- value: permissionMode,
7619
- onChange: (e) => setPermissionMode(e.currentTarget.value),
7620
- className: "rounded-[6px] border border-border bg-background px-2 py-1 text-[12px] text-foreground outline-none focus:ring-1 focus:ring-accent",
7621
- children: [
7622
- /* @__PURE__ */ jsx210("option", { value: "ask", children: "Ask before each tool" }),
7623
- /* @__PURE__ */ jsx210("option", { value: "allow-all", children: "Auto-run (no prompts)" })
7624
- ]
7625
- }
7626
- )
7627
- ] })
7761
+ /* @__PURE__ */ jsx210(
7762
+ PermissionModeMenu,
7763
+ {
7764
+ value: permissionMode,
7765
+ onChange: setPermissionMode,
7766
+ onClose: () => setIsPermMenuOpen(false),
7767
+ isOpen: isPermMenuOpen,
7768
+ onToggle: () => setIsPermMenuOpen((o) => !o)
7769
+ }
7770
+ )
7628
7771
  ] }) }),
7629
- selectedActivity && /* @__PURE__ */ jsx210(
7630
- ActivityDetailOverlay,
7772
+ /* @__PURE__ */ jsx210(
7773
+ ActivityDetailsPanel,
7631
7774
  {
7632
7775
  activity: selectedActivity,
7633
7776
  onClose: () => setSelectedActivity(null)
@@ -7635,74 +7778,6 @@ function TimelineAgentChatPanel({
7635
7778
  )
7636
7779
  ] });
7637
7780
  }
7638
- function formatActivityValue(value) {
7639
- if (value == null) return "";
7640
- if (typeof value === "string") return value;
7641
- try {
7642
- return JSON.stringify(value, null, 2);
7643
- } catch {
7644
- return String(value);
7645
- }
7646
- }
7647
- function ActivityDetailOverlay({
7648
- activity,
7649
- onClose
7650
- }) {
7651
- const title = activity.displayName || activity.toolName || activity.type;
7652
- const input = activity.toolInput && Object.keys(activity.toolInput).length > 0 ? formatActivityValue(activity.toolInput) : "";
7653
- const result = formatActivityValue(activity.content);
7654
- return /* @__PURE__ */ jsx210(
7655
- "div",
7656
- {
7657
- className: "fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",
7658
- onClick: onClose,
7659
- role: "presentation",
7660
- children: /* @__PURE__ */ jsxs22(
7661
- "div",
7662
- {
7663
- className: "flex max-h-[80vh] w-full max-w-[640px] flex-col overflow-hidden rounded-[10px] border border-border bg-background shadow-lg",
7664
- onClick: (e) => e.stopPropagation(),
7665
- role: "dialog",
7666
- "aria-modal": "true",
7667
- "aria-label": `${title} details`,
7668
- children: [
7669
- /* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between gap-2 border-b border-border px-4 py-3", children: [
7670
- /* @__PURE__ */ jsxs22("div", { className: "min-w-0", children: [
7671
- /* @__PURE__ */ jsx210("div", { className: "truncate text-[13px] font-medium text-foreground", children: title }),
7672
- /* @__PURE__ */ jsxs22("div", { className: "text-[11px] text-muted-foreground", children: [
7673
- activity.type,
7674
- " \xB7 ",
7675
- activity.status
7676
- ] })
7677
- ] }),
7678
- /* @__PURE__ */ jsx210(
7679
- "button",
7680
- {
7681
- type: "button",
7682
- onClick: onClose,
7683
- className: "shrink-0 rounded-[6px] px-2 py-1 text-[12px] text-muted-foreground transition hover:bg-foreground/[0.06] hover:text-foreground",
7684
- children: "Close"
7685
- }
7686
- )
7687
- ] }),
7688
- /* @__PURE__ */ jsxs22("div", { className: "flex-1 overflow-y-auto px-4 py-3 space-y-3", children: [
7689
- activity.error && /* @__PURE__ */ jsx210("div", { className: "rounded-[6px] bg-red-500/[0.08] px-3 py-2 text-[12px] text-red-600", children: activity.error }),
7690
- input && /* @__PURE__ */ jsxs22("div", { children: [
7691
- /* @__PURE__ */ jsx210("div", { className: "mb-1 text-[11px] font-medium uppercase text-muted-foreground", children: "Request" }),
7692
- /* @__PURE__ */ jsx210("pre", { className: "overflow-x-auto rounded-[6px] bg-foreground/[0.04] px-3 py-2 text-[12px] text-foreground whitespace-pre-wrap break-words", children: input })
7693
- ] }),
7694
- result && /* @__PURE__ */ jsxs22("div", { children: [
7695
- /* @__PURE__ */ jsx210("div", { className: "mb-1 text-[11px] font-medium uppercase text-muted-foreground", children: "Result" }),
7696
- /* @__PURE__ */ jsx210("pre", { className: "overflow-x-auto rounded-[6px] bg-foreground/[0.04] px-3 py-2 text-[12px] text-foreground whitespace-pre-wrap break-words", children: result })
7697
- ] }),
7698
- !input && !result && !activity.error && /* @__PURE__ */ jsx210("div", { className: "text-[12px] text-muted-foreground", children: "No additional detail for this step." })
7699
- ] })
7700
- ]
7701
- }
7702
- )
7703
- }
7704
- );
7705
- }
7706
7781
 
7707
7782
  // ../runtime-core/dist/index.js
7708
7783
  var RUNTIME_KINDS = ["native-sdk", "app-server", "compatible-sdk", "cli-fallback"];
@@ -8270,7 +8345,7 @@ var PushTimelineStream = class {
8270
8345
  };
8271
8346
 
8272
8347
  // src/use-agent-session.ts
8273
- import { useEffect as useEffect8, useMemo as useMemo9, useRef as useRef9 } from "react";
8348
+ import { useEffect as useEffect10, useMemo as useMemo9, useRef as useRef9 } from "react";
8274
8349
  function useAgentSession(options) {
8275
8350
  const onTokenExpiredRef = useRef9(options.onTokenExpired);
8276
8351
  onTokenExpiredRef.current = options.onTokenExpired;
@@ -8289,7 +8364,7 @@ function useAgentSession(options) {
8289
8364
  })
8290
8365
  });
8291
8366
  }, [options.server, options.sessionId]);
8292
- useEffect8(() => {
8367
+ useEffect10(() => {
8293
8368
  return () => {
8294
8369
  void runtime.disposeIfCreated();
8295
8370
  };
@@ -8373,9 +8448,12 @@ function createDeferredAgentRuntime(options) {
8373
8448
  };
8374
8449
  }
8375
8450
  export {
8451
+ ActivityDetailsPanel,
8452
+ ActivityInspector,
8376
8453
  AgentChatPanel,
8377
8454
  AnnotationIslandMenu,
8378
8455
  AnnotationOverlayLayer,
8456
+ AssistantTurnCard,
8379
8457
  ChatTranscript,
8380
8458
  CodeBlock,
8381
8459
  CollapsibleMarkdownProvider,
@@ -8386,6 +8464,7 @@ export {
8386
8464
  Markdown,
8387
8465
  MemoizedMarkdown,
8388
8466
  PendingIndicator,
8467
+ PermissionModeMenu,
8389
8468
  PermissionRequestCard,
8390
8469
  PlatformProvider,
8391
8470
  ResponseCard,