@ash-cloud/ash-ui 0.0.5 → 0.0.7

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.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { NormalizedToolCall, NormalizedEntry, ToolDisplayConfig, WidgetRenderFunction, WidgetAction, LogEntry, ToolDisplayMode, TodoItem, ToolStatus, ActionType } from './types.js';
3
3
  export { AssistantMessageEntry, CommandRunAction, CommandRunResult, DEFAULT_DISPLAY_CONFIG, ErrorEntry, FileAttachment, FileEditAction, FileReadAction, FileWriteAction, GenericToolAction, GlobAction, LogCategory, LogLevel, McpToolAction, NormalizedEntryType, SearchAction, ThinkingEntry, TodoStatus, TodoWriteAction, ToolCallEntry, ToolExecutionGroup as ToolExecutionGroupType, ToolResult, UserMessageEntry, WebFetchAction, WebSearchAction, WidgetEntry, WidgetRenderProps, isCommandRunAction, isErrorEntry, isFileEditAction, isFileReadAction, isFileWriteAction, isGenericToolAction, isGlobAction, isMcpToolAction, isSearchAction, isTodoWriteAction, isToolCallEntry, isWebFetchAction, isWebSearchAction, isWidgetEntry } from './types.js';
4
- import { ReactNode, DragEvent, ChangeEvent } from 'react';
4
+ import { ReactNode, DragEvent, ChangeEvent, ClipboardEvent } from 'react';
5
5
  import { ParsedOption } from './utils.js';
6
6
  export { GroupedEntry, ParsedOptionsResult, ToolUseInput, cn, createToolCall, extractTextContent, extractToolCallsFromGroup, formatFileSize, formatTimestamp, formatToolName, generateToolSummary, getActionIcon, getActionLabel, groupEntriesForCompactMode, mapToolToActionType, normalizeToolResult, parseCommandResult, parseMcpToolName, parseOptionsFromContent, truncate, updateToolCallWithResult } from './utils.js';
7
7
  export { AlertCircleIcon, AlertTriangleIcon, BotIcon, BrainIcon, BugIcon, CheckCircleIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CircleIcon, ClipboardListIcon, CodeIcon, CopyIcon, EditIcon, ErrorIcon, FileIcon, FilePlusIcon, FolderSearchIcon, GlobeIcon, IconProps, InfoIcon, ListChecksIcon, LoaderIcon, MessageSquareIcon, MoonIcon, PaperclipIcon, PlugIcon, SearchIcon, SendIcon, SparklesIcon, SpinnerIcon, StopCircleIcon, SunIcon, TerminalIcon, ToolIcon, UserIcon, XCircleIcon, XIcon } from './icons.js';
@@ -64,6 +64,12 @@ interface MessageListProps {
64
64
  * Called when widgets dispatch actions via their onAction callback.
65
65
  */
66
66
  onWidgetAction?: (action: WidgetAction) => void;
67
+ /**
68
+ * Enable auto-scroll to bottom when new entries are added.
69
+ * Scrolls within the message list container (not the page).
70
+ * Default: true
71
+ */
72
+ autoScroll?: boolean;
67
73
  /** Additional class names */
68
74
  className?: string;
69
75
  }
@@ -87,7 +93,7 @@ interface MessageListProps {
87
93
  * <MessageList entries={entries} displayConfig={{ mode: 'compact' }} />
88
94
  * ```
89
95
  */
90
- declare function MessageList({ entries, loading, streamingContent, displayConfig: displayConfigProp, onOptionSelect, renderWidget, onWidgetAction, className, }: MessageListProps): react_jsx_runtime.JSX.Element;
96
+ declare function MessageList({ entries, loading, streamingContent, displayConfig: displayConfigProp, onOptionSelect, renderWidget, onWidgetAction, autoScroll, className, }: MessageListProps): react_jsx_runtime.JSX.Element;
91
97
 
92
98
  interface UserMessageProps {
93
99
  entry: NormalizedEntry;
@@ -202,14 +208,9 @@ interface ToolExecutionGroupProps {
202
208
  /**
203
209
  * ToolExecutionGroup - Displays multiple tool calls in a compact accordion format.
204
210
  *
205
- * In collapsed state, shows a single animated status line with the current/latest
206
- * tool call. When expanded, shows all tool calls as individual cards.
207
- *
208
- * Features:
209
- * - Animated status line that transitions between tool calls
210
- * - Expandable accordion to see all tool call details
211
- * - Count badge showing total tool calls
212
- * - Overall status indicator
211
+ * In collapsed state, shows a summary with tool count, action type icons,
212
+ * and file change badges. When expanded, shows compact tool rows that can
213
+ * be further expanded into full detail cards.
213
214
  *
214
215
  * @example
215
216
  * ```tsx
@@ -219,7 +220,7 @@ interface ToolExecutionGroupProps {
219
220
  * />
220
221
  * ```
221
222
  */
222
- declare function ToolExecutionGroup({ toolCalls, defaultExpanded, animationDuration, className, }: ToolExecutionGroupProps): react_jsx_runtime.JSX.Element | null;
223
+ declare function ToolExecutionGroup({ toolCalls, defaultExpanded, className, }: ToolExecutionGroupProps): react_jsx_runtime.JSX.Element | null;
223
224
 
224
225
  interface CompactToolStatusLineProps {
225
226
  /** The current tool call to display */
@@ -248,6 +249,48 @@ interface CompactToolStatusLineProps {
248
249
  */
249
250
  declare function CompactToolStatusLine({ toolCall, previousToolCall, animationDuration, className, }: CompactToolStatusLineProps): react_jsx_runtime.JSX.Element;
250
251
 
252
+ interface CompactToolRowProps {
253
+ toolCall: NormalizedToolCall;
254
+ /** Whether to show the full path or just filename */
255
+ showFullPath?: boolean;
256
+ className?: string;
257
+ }
258
+ /**
259
+ * CompactToolRow - A single-line compact display of a tool call
260
+ *
261
+ * Shows: Icon | Label | File Badge | Diff Stats | Description
262
+ *
263
+ * @example
264
+ * ```tsx
265
+ * <CompactToolRow toolCall={normalizedToolCall} />
266
+ * ```
267
+ */
268
+ declare function CompactToolRow({ toolCall, showFullPath, className }: CompactToolRowProps): react_jsx_runtime.JSX.Element;
269
+
270
+ interface FileBadgeProps {
271
+ /** Full file path or filename */
272
+ path: string;
273
+ /** Number of lines added */
274
+ linesAdded?: number;
275
+ /** Number of lines removed */
276
+ linesRemoved?: number;
277
+ /** Show only filename instead of full path */
278
+ showOnlyFilename?: boolean;
279
+ className?: string;
280
+ }
281
+ /**
282
+ * FileBadge - A compact pill showing filename with diff stats
283
+ *
284
+ * Used in the collapsed accordion view to show modified files.
285
+ *
286
+ * @example
287
+ * ```tsx
288
+ * <FileBadge path="src/utils.ts" linesAdded={5} linesRemoved={2} />
289
+ * <FileBadge path="SKILL.md" linesAdded={0} linesRemoved={22} />
290
+ * ```
291
+ */
292
+ declare function FileBadge({ path, linesAdded, linesRemoved, showOnlyFilename, className, }: FileBadgeProps): react_jsx_runtime.JSX.Element;
293
+
251
294
  /**
252
295
  * Context type for display mode configuration
253
296
  */
@@ -453,13 +496,12 @@ interface StepAccordionProps {
453
496
  className?: string;
454
497
  }
455
498
  /**
456
- * StepAccordion - Simpler accordion that shows tool calls as numbered steps
499
+ * StepAccordion - Compact accordion that shows tool calls with file badges
457
500
  *
458
501
  * Features:
459
- * - Collapsed header shows current running step or completion status
460
- * - Expanded view shows all steps as a numbered list
461
- * - Shows step duration for completed steps
462
- * - Compact design suitable for embedding in chat
502
+ * - Collapsed header shows tool count, action icons, and file change badges
503
+ * - Expanded view shows CompactToolRow for each tool call
504
+ * - Clean, minimal design matching the compact UI style
463
505
  *
464
506
  * @example
465
507
  * ```tsx
@@ -898,4 +940,275 @@ interface UseFileUploadReturn {
898
940
  declare function useFileUpload({ maxFileSize, // 100MB
899
941
  maxFiles, onValidationError, }?: UseFileUploadOptions): UseFileUploadReturn;
900
942
 
901
- export { ActionIcon, type ActionIconProps, ActionType, AssistantMessage, type AssistantMessageProps, type FileAttachment as ChatFileAttachment, CodeBlock, type CodeBlockProps, CompactToolStatusLine, type CompactToolStatusLineProps, type DisplayModeContextType, DisplayModeProvider, type DisplayModeProviderProps, DisplayModeToggle, type DisplayModeToggleProps, EnvVarsPanel, type EnvVarsPanelProps, ErrorMessage, type ErrorMessageProps, JsonDisplay, type JsonDisplayProps, LoadingIndicator, type LoadingIndicatorProps, LogEntry, LogsPanel, type LogsPanelProps, MessageEntry, type MessageEntryProps, MessageList, type MessageListProps, NormalizedEntry, NormalizedToolCall, OptionCards, type OptionCardsProps, ParsedOption, type QueuedMessage, StatusIndicator, type StatusIndicatorProps, StepAccordion, type StepAccordionProps, type StepStatus, StreamingText, type StreamingTextProps, type Theme, type ThemeContextType, ThemeProvider, type ThemeProviderProps, ThinkingMessage, type ThinkingMessageProps, TodoItem, TodoPanel, type TodoPanelProps, ToolCallCard, type ToolCallCardProps, ToolCallMessage, type ToolCallMessageProps, ToolDisplayConfig, ToolDisplayMode, ToolExecutionGroup, type ToolExecutionGroupProps, ToolStatus, TypewriterText, type TypewriterTextProps, type UseFileUploadOptions, type UseFileUploadReturn, type UseMessageQueueOptions, type UseMessageQueueReturn, type UseStopExecutionOptions, type UseStopExecutionReturn, UserMessage, type UserMessageProps, WidgetAction, WidgetRenderFunction, useDisplayConfig, useDisplayMode, useFileUpload, useMessageQueue, useStopExecution, useTheme };
943
+ /**
944
+ * useAgentChat - A React hook for streaming agent conversations
945
+ *
946
+ * This hook handles all the complexity of streaming agent responses:
947
+ * - Real-time text streaming via text_delta events
948
+ * - Tool call tracking and correlation
949
+ * - Proper deduplication (no duplicate messages)
950
+ * - Seamless transition from streaming to finalized state
951
+ *
952
+ * @example
953
+ * ```tsx
954
+ * import { useAgentChat } from '@ash-cloud/ash-ui';
955
+ * import { AgentCloudClient } from '@ash-cloud/client';
956
+ *
957
+ * const client = new AgentCloudClient({ apiKey: '...' });
958
+ *
959
+ * function Chat() {
960
+ * const {
961
+ * entries,
962
+ * isStreaming,
963
+ * error,
964
+ * sessionId,
965
+ * send,
966
+ * stop,
967
+ * } = useAgentChat({
968
+ * client,
969
+ * agentId: 'my-agent-id',
970
+ * });
971
+ *
972
+ * return (
973
+ * <div>
974
+ * <MessageList entries={entries} loading={isStreaming} />
975
+ * <input onSubmit={(e) => send(e.target.value)} />
976
+ * </div>
977
+ * );
978
+ * }
979
+ * ```
980
+ */
981
+
982
+ /**
983
+ * Stream event type - matches @ash-cloud/client StreamEvent
984
+ * We define it here to avoid a hard dependency on the client package
985
+ */
986
+ interface StreamEvent {
987
+ type: string;
988
+ sessionId?: string;
989
+ claudeSessionId?: string;
990
+ delta?: string;
991
+ text?: string;
992
+ toolId?: string;
993
+ toolName?: string;
994
+ input?: unknown;
995
+ toolResult?: unknown;
996
+ isError?: boolean;
997
+ error?: string;
998
+ code?: string;
999
+ status?: string;
1000
+ result?: string;
1001
+ totalCost?: number;
1002
+ totalTokens?: number;
1003
+ entry?: {
1004
+ timestamp: string;
1005
+ level: string;
1006
+ category: string;
1007
+ message: string;
1008
+ data?: Record<string, unknown>;
1009
+ };
1010
+ }
1011
+ /**
1012
+ * Async generator that yields StreamEvent objects
1013
+ */
1014
+ type StreamGenerator = AsyncGenerator<StreamEvent, void, unknown>;
1015
+ /**
1016
+ * Function that creates a stream of events
1017
+ * This matches the signature of client.agents.run() and client.sessions.send()
1018
+ */
1019
+ type CreateStreamFn = (prompt: string, sessionId?: string) => StreamGenerator;
1020
+ /**
1021
+ * Options for useAgentChat
1022
+ */
1023
+ interface UseAgentChatOptions {
1024
+ /**
1025
+ * Function to create a stream of events.
1026
+ * Can wrap client.agents.run() or client.sessions.send()
1027
+ *
1028
+ * @example
1029
+ * ```tsx
1030
+ * createStream: (prompt, sessionId) => {
1031
+ * if (sessionId) {
1032
+ * return client.sessions.send(sessionId, prompt);
1033
+ * }
1034
+ * return client.agents.run(agentId, prompt);
1035
+ * }
1036
+ * ```
1037
+ */
1038
+ createStream: CreateStreamFn;
1039
+ /**
1040
+ * Initial session ID (for resuming a conversation)
1041
+ */
1042
+ initialSessionId?: string;
1043
+ /**
1044
+ * Initial entries to display (e.g., from loading history)
1045
+ */
1046
+ initialEntries?: NormalizedEntry[];
1047
+ /**
1048
+ * Callback when session starts
1049
+ */
1050
+ onSessionStart?: (sessionId: string) => void;
1051
+ /**
1052
+ * Callback when session ends
1053
+ */
1054
+ onSessionEnd?: (sessionId: string, status: string) => void;
1055
+ /**
1056
+ * Callback when an error occurs
1057
+ */
1058
+ onError?: (error: string) => void;
1059
+ /**
1060
+ * Callback for sandbox log events
1061
+ */
1062
+ onSandboxLog?: (entry: NonNullable<StreamEvent['entry']>) => void;
1063
+ }
1064
+ /**
1065
+ * Return type for useAgentChat
1066
+ */
1067
+ interface UseAgentChatReturn {
1068
+ /**
1069
+ * All entries to display (history + streaming content)
1070
+ * This is the single source of truth for rendering
1071
+ */
1072
+ entries: NormalizedEntry[];
1073
+ /**
1074
+ * Whether a message is currently being streamed
1075
+ */
1076
+ isStreaming: boolean;
1077
+ /**
1078
+ * Current error message (if any)
1079
+ */
1080
+ error: string | null;
1081
+ /**
1082
+ * Current session ID
1083
+ */
1084
+ sessionId: string | null;
1085
+ /**
1086
+ * Send a message to the agent
1087
+ */
1088
+ send: (prompt: string) => Promise<void>;
1089
+ /**
1090
+ * Stop the current streaming request
1091
+ */
1092
+ stop: () => void;
1093
+ /**
1094
+ * Clear all entries and start fresh
1095
+ */
1096
+ clear: () => void;
1097
+ /**
1098
+ * Set entries from external source (e.g., loading from server)
1099
+ * This replaces all entries and clears streaming state
1100
+ */
1101
+ setEntries: (entries: NormalizedEntry[]) => void;
1102
+ }
1103
+ declare function useAgentChat(options: UseAgentChatOptions): UseAgentChatReturn;
1104
+
1105
+ /**
1106
+ * Configuration for long text auto-conversion
1107
+ */
1108
+ interface LongTextConversionOptions {
1109
+ /** Character threshold to trigger conversion (default: 5000) */
1110
+ threshold?: number;
1111
+ /** Filename template for converted attachments (default: 'pasted-text-{timestamp}.txt') */
1112
+ filenameTemplate?: string;
1113
+ /** Callback when text is converted to attachment */
1114
+ onConversion?: (info: ConversionInfo) => void;
1115
+ }
1116
+ /**
1117
+ * Information about a converted text attachment
1118
+ */
1119
+ interface ConversionInfo {
1120
+ /** Original text length */
1121
+ originalLength: number;
1122
+ /** Generated filename */
1123
+ filename: string;
1124
+ /** Truncated preview of the text (first 100 chars) */
1125
+ preview: string;
1126
+ /** Number of lines in the text */
1127
+ lineCount: number;
1128
+ }
1129
+ /**
1130
+ * Text attachment created from long pasted text
1131
+ */
1132
+ interface TextAttachment {
1133
+ /** Filename for the attachment */
1134
+ filename: string;
1135
+ /** Base64-encoded text content */
1136
+ content: string;
1137
+ /** MIME type (always 'text/plain') */
1138
+ mimeType: 'text/plain';
1139
+ /** Size in bytes */
1140
+ size: number;
1141
+ }
1142
+ /**
1143
+ * Result from the useLongTextConversion hook
1144
+ */
1145
+ interface UseLongTextConversionReturn {
1146
+ /**
1147
+ * Process text and convert to attachment if over threshold.
1148
+ * Returns the text if under threshold, or empty string if converted.
1149
+ */
1150
+ processText: (text: string) => {
1151
+ text: string;
1152
+ attachment?: TextAttachment;
1153
+ };
1154
+ /**
1155
+ * Paste event handler that auto-converts long pasted text.
1156
+ * Use this on input elements: onPaste={handlePaste}
1157
+ */
1158
+ handlePaste: (event: ClipboardEvent<HTMLTextAreaElement | HTMLInputElement>, currentValue: string, setValue: (value: string) => void, addAttachment: (attachment: TextAttachment) => void) => void;
1159
+ /**
1160
+ * Last conversion info (for showing notifications)
1161
+ */
1162
+ lastConversion: ConversionInfo | null;
1163
+ /**
1164
+ * Clear the last conversion info
1165
+ */
1166
+ clearLastConversion: () => void;
1167
+ /**
1168
+ * Current threshold value
1169
+ */
1170
+ threshold: number;
1171
+ }
1172
+ /**
1173
+ * Hook for automatically converting long pasted text into text file attachments.
1174
+ *
1175
+ * When users paste text over a certain threshold (default: 5000 characters),
1176
+ * the text is automatically converted to a .txt file attachment instead of
1177
+ * being inserted into the input field.
1178
+ *
1179
+ * @example
1180
+ * ```tsx
1181
+ * function ChatInput({ onSend }) {
1182
+ * const [value, setValue] = useState('');
1183
+ * const [files, setFiles] = useState<TextAttachment[]>([]);
1184
+ *
1185
+ * const { handlePaste, lastConversion, clearLastConversion } = useLongTextConversion({
1186
+ * threshold: 5000,
1187
+ * onConversion: (info) => {
1188
+ * console.log(`Converted ${info.originalLength} chars to ${info.filename}`);
1189
+ * }
1190
+ * });
1191
+ *
1192
+ * return (
1193
+ * <>
1194
+ * {lastConversion && (
1195
+ * <div className="notification">
1196
+ * Long text ({lastConversion.originalLength} chars) converted to attachment
1197
+ * <button onClick={clearLastConversion}>Dismiss</button>
1198
+ * </div>
1199
+ * )}
1200
+ * <textarea
1201
+ * value={value}
1202
+ * onChange={(e) => setValue(e.target.value)}
1203
+ * onPaste={(e) => handlePaste(e, value, setValue, (attachment) => {
1204
+ * setFiles(prev => [...prev, attachment]);
1205
+ * })}
1206
+ * />
1207
+ * </>
1208
+ * );
1209
+ * }
1210
+ * ```
1211
+ */
1212
+ declare function useLongTextConversion({ threshold, filenameTemplate, onConversion, }?: LongTextConversionOptions): UseLongTextConversionReturn;
1213
+
1214
+ export { ActionIcon, type ActionIconProps, ActionType, type StreamEvent as AgentStreamEvent, AssistantMessage, type AssistantMessageProps, type FileAttachment as ChatFileAttachment, CodeBlock, type CodeBlockProps, CompactToolRow, type CompactToolRowProps, CompactToolStatusLine, type CompactToolStatusLineProps, type ConversionInfo, type CreateStreamFn, type DisplayModeContextType, DisplayModeProvider, type DisplayModeProviderProps, DisplayModeToggle, type DisplayModeToggleProps, EnvVarsPanel, type EnvVarsPanelProps, ErrorMessage, type ErrorMessageProps, FileBadge, type FileBadgeProps, JsonDisplay, type JsonDisplayProps, LoadingIndicator, type LoadingIndicatorProps, LogEntry, LogsPanel, type LogsPanelProps, type LongTextConversionOptions, MessageEntry, type MessageEntryProps, MessageList, type MessageListProps, NormalizedEntry, NormalizedToolCall, OptionCards, type OptionCardsProps, ParsedOption, type QueuedMessage, StatusIndicator, type StatusIndicatorProps, StepAccordion, type StepAccordionProps, type StepStatus, type StreamGenerator, StreamingText, type StreamingTextProps, type TextAttachment, type Theme, type ThemeContextType, ThemeProvider, type ThemeProviderProps, ThinkingMessage, type ThinkingMessageProps, TodoItem, TodoPanel, type TodoPanelProps, ToolCallCard, type ToolCallCardProps, ToolCallMessage, type ToolCallMessageProps, ToolDisplayConfig, ToolDisplayMode, ToolExecutionGroup, type ToolExecutionGroupProps, ToolStatus, TypewriterText, type TypewriterTextProps, type UseAgentChatOptions, type UseAgentChatReturn, type UseFileUploadOptions, type UseFileUploadReturn, type UseLongTextConversionReturn, type UseMessageQueueOptions, type UseMessageQueueReturn, type UseStopExecutionOptions, type UseStopExecutionReturn, UserMessage, type UserMessageProps, WidgetAction, WidgetRenderFunction, useAgentChat, useDisplayConfig, useDisplayMode, useFileUpload, useLongTextConversion, useMessageQueue, useStopExecution, useTheme };