@parallelworks/ui 0.17.0 → 0.19.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.
Files changed (169) hide show
  1. package/README.md +86 -6
  2. package/dist/ai/adapter/memoryStore.d.ts +8 -0
  3. package/dist/ai/adapter/mock/index.d.ts +2 -0
  4. package/dist/ai/adapter/mock/index.js +81 -0
  5. package/dist/ai/adapter/mock/mockAdapter.d.ts +4 -0
  6. package/dist/ai/adapter/openai/createOpenAIStream.d.ts +9 -0
  7. package/dist/ai/adapter/openai/errors.d.ts +3 -0
  8. package/dist/ai/adapter/openai/index.d.ts +6 -0
  9. package/dist/ai/adapter/openai/index.js +334 -0
  10. package/dist/ai/adapter/openai/openaiAdapter.d.ts +9 -0
  11. package/dist/ai/adapter/openai/responses.d.ts +4 -0
  12. package/dist/ai/adapter/openai/sse.d.ts +24 -0
  13. package/dist/ai/adapter/openai/wire.d.ts +40 -0
  14. package/dist/ai/adapter/types.d.ts +131 -0
  15. package/dist/ai/agent/classifier.d.ts +2 -0
  16. package/dist/ai/agent/diff.d.ts +35 -0
  17. package/dist/ai/agent/diffHighlight.d.ts +6 -0
  18. package/dist/ai/agent/index.d.ts +6 -0
  19. package/dist/ai/agent/permissions.d.ts +11 -0
  20. package/dist/ai/agent/toolfmt.d.ts +18 -0
  21. package/dist/ai/agent/transcript.d.ts +38 -0
  22. package/dist/ai/ai.css +325 -0
  23. package/dist/ai/components/AllocationSelector.d.ts +4 -0
  24. package/dist/ai/components/AttachmentManager.d.ts +1 -0
  25. package/dist/ai/components/AttachmentUpload.d.ts +24 -0
  26. package/dist/ai/components/BlockedGroupBanner.d.ts +1 -0
  27. package/dist/ai/components/BranchNavigator.d.ts +8 -0
  28. package/dist/ai/components/ChatEmptyState.d.ts +3 -0
  29. package/dist/ai/components/ChatInput.d.ts +45 -0
  30. package/dist/ai/components/ChatLayout.d.ts +5 -0
  31. package/dist/ai/components/ChatMessage.d.ts +24 -0
  32. package/dist/ai/components/ChatMessageList.d.ts +35 -0
  33. package/dist/ai/components/ChatSidebar.d.ts +5 -0
  34. package/dist/ai/components/ChatThread.d.ts +3 -0
  35. package/dist/ai/components/ComposerChrome.d.ts +18 -0
  36. package/dist/ai/components/ComposerFrame.d.ts +16 -0
  37. package/dist/ai/components/DragOverlay.d.ts +5 -0
  38. package/dist/ai/components/ModelSelector.d.ts +6 -0
  39. package/dist/ai/components/ShareDialog.d.ts +11 -0
  40. package/dist/ai/components/SlashMenu.d.ts +28 -0
  41. package/dist/ai/components/agent/ActivityLine.d.ts +21 -0
  42. package/dist/ai/components/agent/AgentMessageParts.d.ts +54 -0
  43. package/dist/ai/components/agent/PermissionPicker.d.ts +11 -0
  44. package/dist/ai/components/attachmentKeys.d.ts +4 -0
  45. package/dist/ai/core/ChatProvider.d.ts +66 -0
  46. package/dist/ai/core/KeyboardShortcutsProvider.d.ts +5 -0
  47. package/dist/ai/core/chatReducer.d.ts +114 -0
  48. package/dist/ai/core/config.d.ts +47 -0
  49. package/dist/ai/core/events.d.ts +1 -0
  50. package/dist/ai/core/exportConversation.d.ts +4 -0
  51. package/dist/ai/core/greeting.d.ts +3 -0
  52. package/dist/ai/core/parts.d.ts +11 -0
  53. package/dist/ai/core/useDragDrop.d.ts +14 -0
  54. package/dist/ai/core/useKeyboardShortcuts.d.ts +12 -0
  55. package/dist/ai/core/useSSEStream.d.ts +34 -0
  56. package/dist/ai/index.d.ts +40 -0
  57. package/dist/ai/index.js +6645 -0
  58. package/dist/ai/strings.d.ts +167 -0
  59. package/dist/ai/types.d.ts +236 -0
  60. package/dist/ai/ui/Avatar.d.ts +8 -0
  61. package/dist/ai/ui/Dropdown.d.ts +31 -0
  62. package/dist/ai/ui/Markdown.d.ts +8 -0
  63. package/dist/ai/ui/Notice.d.ts +21 -0
  64. package/dist/ai/ui/buttons.d.ts +1 -0
  65. package/dist/ai/ui/codeBreaks.d.ts +16 -0
  66. package/dist/ai/ui/prose.d.ts +1 -0
  67. package/dist/ai/ui/sidebar.d.ts +81 -0
  68. package/dist/ai/utils.d.ts +4 -0
  69. package/dist/assets/{editor.worker-CuBRIwi-.js → editor.worker-BmHUIVG4.js} +194 -163
  70. package/dist/assets/{json.worker-8ytS02vz.js → json.worker-D8bJ92nw.js} +384 -338
  71. package/dist/assets/{yaml.worker-DJC-VUcv.js → yaml.worker-C4gyGAko.js} +15657 -13823
  72. package/dist/chunks/{CodePreviewEditor-UAtnpmOV.js → CodePreviewEditor-YqQBz1YL.js} +2 -2
  73. package/dist/chunks/ConfirmModal-aOR4O1QE.js +79 -0
  74. package/dist/chunks/{lib-CUTRDpa6.js → FieldWrapper-Cszwg-4B.js} +52 -55
  75. package/dist/chunks/{CreateModal-BbV5cTj7.js → Markdown-CM-FenNE.js} +25 -97
  76. package/dist/chunks/Monaco-DJ8MW-Dq.js +110 -0
  77. package/dist/chunks/{PageHeader-MxuOs9cH.js → PageHeader-0kG_iypP.js} +170 -105
  78. package/dist/chunks/{Provider-DHmZ3v9i.js → Provider-CDYurraE.js} +60 -24
  79. package/dist/chunks/{SwitchToggle-BRQoEwLZ.js → SwitchToggle-DShNdcao.js} +143 -140
  80. package/dist/chunks/{Table-C6JdFFiJ.js → Table-DU2MW8xz.js} +6 -4
  81. package/dist/chunks/{Tooltip-n9w7Tkt1.js → Tooltip-K5HJr4_p.js} +32 -5
  82. package/dist/chunks/duration-BOv8Phl8.js +17 -0
  83. package/dist/chunks/{editor-mNznodJN.js → editor-Dk1rbV75.js} +33 -19
  84. package/dist/chunks/focus-D_iZJTW1.js +7 -0
  85. package/dist/chunks/{list-7k0eaI5N.js → list-CJm875m7.js} +497 -379
  86. package/dist/chunks/logviewer-BTKuQWzw.js +828 -0
  87. package/dist/chunks/memoryStore-CC91S5LP.js +152 -0
  88. package/dist/chunks/types-Yy0NrerF.js +11 -0
  89. package/dist/components/AddMenu.d.ts +1 -0
  90. package/dist/components/Avatar.d.ts +13 -0
  91. package/dist/components/Breadcrumbs.d.ts +1 -1
  92. package/dist/components/Dropdown.d.ts +3 -1
  93. package/dist/components/EmptyState.d.ts +1 -1
  94. package/dist/components/Indicator.d.ts +2 -2
  95. package/dist/components/Input.d.ts +1 -1
  96. package/dist/components/LetterBadge.d.ts +1 -1
  97. package/dist/components/MarkdownImpl.d.ts +1 -1
  98. package/dist/components/Provider.d.ts +18 -65
  99. package/dist/components/SettingRow.d.ts +1 -1
  100. package/dist/components/SettingsGroup.d.ts +1 -1
  101. package/dist/components/focus.d.ts +2 -0
  102. package/dist/components/keys.d.ts +12 -0
  103. package/dist/duration.d.ts +3 -0
  104. package/dist/editor/Monaco.d.ts +1 -20
  105. package/dist/editor/index.d.ts +2 -1
  106. package/dist/editor/index.js +2 -2
  107. package/dist/editor/yaml.d.ts +5 -0
  108. package/dist/engine.d.ts +98 -0
  109. package/dist/file-explorer/FileExplorer.d.ts +11 -2
  110. package/dist/file-explorer/FileExplorerContext.d.ts +1 -1
  111. package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +1 -1
  112. package/dist/file-explorer/FilePreview/previewType.d.ts +1 -1
  113. package/dist/file-explorer/FileRow.d.ts +1 -1
  114. package/dist/file-explorer/helpers.d.ts +4 -4
  115. package/dist/file-explorer/index.d.ts +3 -3
  116. package/dist/file-explorer/index.js +632 -665
  117. package/dist/file-explorer/lib/types.d.ts +6 -1
  118. package/dist/file-explorer/lib/utils.d.ts +1 -3
  119. package/dist/file-explorer/useNearEnd.d.ts +1 -1
  120. package/dist/form/FieldWrapper.d.ts +2 -1
  121. package/dist/form/Fields/ResourceOptionIcon.d.ts +1 -1
  122. package/dist/form/Form.d.ts +7 -22
  123. package/dist/form/index.d.ts +11 -12
  124. package/dist/form/index.js +1333 -1454
  125. package/dist/form/lib.d.ts +6 -1
  126. package/dist/form/types/fieldComponentTypes.d.ts +4 -2
  127. package/dist/form/types/fieldTypes.d.ts +6 -20
  128. package/dist/form/useParsedOpts.d.ts +2 -2
  129. package/dist/form/utils/{slurmDuration.d.ts → duration.d.ts} +2 -2
  130. package/dist/{workflow → graph}/MatrixGroup.d.ts +2 -2
  131. package/dist/{workflow → graph}/index.d.ts +1 -1
  132. package/dist/{workflow → graph}/index.js +220 -185
  133. package/dist/{workflow → graph}/types.d.ts +3 -3
  134. package/dist/icons.d.ts +20 -21
  135. package/dist/icons.js +3 -3
  136. package/dist/index.d.ts +38 -39
  137. package/dist/index.js +355 -354
  138. package/dist/list/ListTable.d.ts +1 -1
  139. package/dist/list/ListViewControls.d.ts +2 -2
  140. package/dist/list/RowContextMenu.d.ts +9 -9
  141. package/dist/list/UserHoverCard.d.ts +45 -0
  142. package/dist/list/index.d.ts +9 -8
  143. package/dist/list/index.js +3 -3
  144. package/dist/logviewer/LogViewer.d.ts +1 -1
  145. package/dist/logviewer/index.d.ts +1 -0
  146. package/dist/logviewer/index.js +2 -742
  147. package/dist/logviewer/segments.d.ts +9 -0
  148. package/dist/styles/Geist-Variable.woff2 +0 -0
  149. package/dist/styles/GeistMono-Variable.woff2 +0 -0
  150. package/dist/styles/base.css +57 -0
  151. package/dist/styles/fonts.css +15 -0
  152. package/dist/styles/theme.css +9 -41
  153. package/dist/styles.css +1 -1
  154. package/dist/theme/index.js +2 -2
  155. package/package.json +45 -20
  156. package/LICENSE +0 -21
  157. package/dist/chunks/Monaco-DVyIpyv4.js +0 -1046
  158. package/dist/editor/usesGitlab.d.ts +0 -97
  159. package/dist/form/Fields/BucketReadOnlyField.d.ts +0 -7
  160. package/dist/form/types/workflow-schema.d.ts +0 -1145
  161. package/dist/form/utils/pwResolver.d.ts +0 -18
  162. package/dist/chunks/{BareModal-BqroLbZ5.js → BareModal-BtRiQezg.js} +1 -1
  163. package/dist/chunks/{MarkdownImpl-Bq4QhrtA.js → MarkdownImpl-CyeTVvSt.js} +1 -1
  164. /package/dist/{workflow → graph}/AnnotationBanner.d.ts +0 -0
  165. /package/dist/{workflow → graph}/Collapse.d.ts +0 -0
  166. /package/dist/{workflow → graph}/DependencyGraph.d.ts +0 -0
  167. /package/dist/{workflow → graph}/JobSummary.d.ts +0 -0
  168. /package/dist/{workflow → graph}/Reveal.d.ts +0 -0
  169. /package/dist/{workflow → graph}/TreeView.d.ts +0 -0
@@ -0,0 +1,131 @@
1
+ import type { Allocation, ApprovalPart, AttachmentRef, ChatModel, Conversation, ConversationSummary, ProviderInfo, ShareGroup, SharePermission, SharePermissionLevel, TodoItem, ToolCall, UnreachableSession } from '../types.js';
2
+ import type { CompletionMessage } from './openai/wire.js';
3
+ export declare class ChatAdapterError extends Error {
4
+ status?: number | undefined;
5
+ constructor(message: string, options?: {
6
+ status?: number;
7
+ cause?: unknown;
8
+ });
9
+ }
10
+ export interface ModelsList {
11
+ models: ChatModel[];
12
+ unreachableSessions: UnreachableSession[];
13
+ }
14
+ export interface StreamRequest {
15
+ model: string;
16
+ messages: CompletionMessage[];
17
+ conversationId: string;
18
+ parentMessageId?: string | null;
19
+ userMessageId: string;
20
+ allocation?: string | null;
21
+ useResponses?: boolean;
22
+ }
23
+ export interface StreamHandlers {
24
+ onContent: (content: string) => void;
25
+ onReasoning?: (reasoning: string) => void;
26
+ onMessageId?: (messageId: string) => void;
27
+ onPart?: (delta: PartDelta) => void;
28
+ }
29
+ export type PartDelta = {
30
+ type: 'tool_start';
31
+ id: string;
32
+ name: string;
33
+ args: string;
34
+ startLine?: number;
35
+ } | {
36
+ type: 'tool_update';
37
+ id: string;
38
+ args: string;
39
+ } | {
40
+ type: 'tool_end';
41
+ id: string;
42
+ result: string;
43
+ isError?: boolean;
44
+ } | {
45
+ type: 'subagent_start';
46
+ id: string;
47
+ agentType?: string;
48
+ color?: string;
49
+ background?: boolean;
50
+ description?: string;
51
+ } | {
52
+ type: 'subagent_action';
53
+ id: string;
54
+ action: string;
55
+ } | {
56
+ type: 'subagent_end';
57
+ id: string;
58
+ ok: boolean;
59
+ summary?: string;
60
+ report?: string;
61
+ } | {
62
+ type: 'approval_request';
63
+ approval: ApprovalPart;
64
+ } | {
65
+ type: 'approval_resolved';
66
+ id: string;
67
+ answer?: string;
68
+ } | {
69
+ type: 'notice' | 'warning';
70
+ text: string;
71
+ } | {
72
+ type: 'todo_snapshot';
73
+ todos: TodoItem[];
74
+ };
75
+ export interface StreamResult {
76
+ content: string;
77
+ messageId: string;
78
+ toolCalls: ToolCall[];
79
+ finishReason: string | null;
80
+ model: string | null;
81
+ reasoning: string;
82
+ responsesOutput: unknown[];
83
+ }
84
+ export type StreamCompletion = (req: StreamRequest, handlers: StreamHandlers, signal?: AbortSignal) => Promise<StreamResult>;
85
+ export interface ConversationsAdapter {
86
+ list(): Promise<ConversationSummary[]>;
87
+ get(id: string): Promise<Conversation>;
88
+ create(title?: string): Promise<ConversationSummary>;
89
+ rename(id: string, title: string): Promise<void>;
90
+ remove(id: string): Promise<void>;
91
+ }
92
+ export interface ProvidersAdapter {
93
+ list(): Promise<ProviderInfo[]>;
94
+ }
95
+ export interface AttachmentPage {
96
+ attachments: AttachmentRef[];
97
+ total: number;
98
+ nextCursor?: string;
99
+ hasMore: boolean;
100
+ }
101
+ export interface AttachmentsAdapter {
102
+ list(opts: {
103
+ limit: number;
104
+ cursor?: string;
105
+ }): Promise<AttachmentPage>;
106
+ upload(file: File, conversationId?: string): Promise<AttachmentRef>;
107
+ remove(id: string): Promise<void>;
108
+ downloadUrl(id: string): string;
109
+ onOpen?(attachment: AttachmentRef): void;
110
+ }
111
+ export interface SharingAdapter {
112
+ listPermissions(conversationId: string): Promise<SharePermission[]>;
113
+ listGroups(): Promise<ShareGroup[]>;
114
+ addPermission(conversationId: string, permission: Omit<SharePermission, 'id' | 'teamName'>): Promise<void>;
115
+ updatePermission(conversationId: string, permissionId: string, permission: SharePermissionLevel): Promise<void>;
116
+ removePermission(conversationId: string, permissionId: string): Promise<void>;
117
+ }
118
+ export interface AllocationsAdapter {
119
+ list(): Promise<Allocation[]>;
120
+ }
121
+ export interface ChatAdapter {
122
+ conversations: ConversationsAdapter;
123
+ models: {
124
+ list(): Promise<ModelsList>;
125
+ };
126
+ streamCompletion: StreamCompletion;
127
+ providers?: ProvidersAdapter;
128
+ attachments?: AttachmentsAdapter;
129
+ sharing?: SharingAdapter;
130
+ allocations?: AllocationsAdapter;
131
+ }
@@ -0,0 +1,2 @@
1
+ import type { PseudoUserKind } from '../types.js';
2
+ export declare function classifyPseudoUserMessage(role: string, content: string | null | undefined): PseudoUserKind | null;
@@ -0,0 +1,35 @@
1
+ export declare const MAX_EDIT_DIFF_LINES = 100;
2
+ export declare const MAX_WRITE_DIFF_LINES = 50;
3
+ export declare const DIFF_CONTEXT = 3;
4
+ export interface EditToolArgs {
5
+ path?: string;
6
+ old_string?: string;
7
+ new_string?: string;
8
+ content?: string;
9
+ replace_all?: boolean;
10
+ }
11
+ export declare function isEditDiffTool(name: string): boolean;
12
+ export declare function parseEditArgs(argsJSON: string): EditToolArgs | null;
13
+ export declare function wordEmphasisRanges(oldLine: string, newLine: string): Array<[number, number]> | null;
14
+ export declare function lineDelta(oldLines: string[], newLines: string[]): [number, number];
15
+ export interface DiffRow {
16
+ kind: 'add' | 'del' | 'ctx' | 'gap';
17
+ oldNo?: number;
18
+ newNo?: number;
19
+ text: string;
20
+ emphasis?: Array<[number, number]>;
21
+ }
22
+ export interface EditDiffModel {
23
+ rows: DiffRow[];
24
+ added: number;
25
+ removed: number;
26
+ truncated: boolean;
27
+ }
28
+ export declare function computeEditDiff(oldString: string, newString: string, startLine?: number): EditDiffModel;
29
+ export interface WriteModel {
30
+ rows: DiffRow[];
31
+ total: number;
32
+ truncated: boolean;
33
+ }
34
+ export declare function computeWriteRows(content: string): WriteModel;
35
+ export declare function editSummary(toolName: string, argsJSON: string): string;
@@ -0,0 +1,6 @@
1
+ export interface DiffToken {
2
+ content: string;
3
+ color?: string;
4
+ }
5
+ export declare function languageForPath(path: string | undefined): string | null;
6
+ export declare function tokenizeDiffLines(lines: string[], lang: string, isDark: boolean): Promise<DiffToken[][] | null>;
@@ -0,0 +1,6 @@
1
+ export { classifyPseudoUserMessage } from './classifier.js';
2
+ export { computeEditDiff, computeWriteRows, type DiffRow, type EditDiffModel, type EditToolArgs, editSummary, isEditDiffTool, lineDelta, MAX_EDIT_DIFF_LINES, MAX_WRITE_DIFF_LINES, parseEditArgs, type WriteModel, wordEmphasisRanges, } from './diff.js';
3
+ export { type DiffToken, languageForPath, tokenizeDiffLines, } from './diffHighlight.js';
4
+ export { clampPermissionMode, DEFAULT_PERMISSION_MODE, isNamedPermissionMode, NAMED_PERMISSION_MODES, type NamedPermissionMode, type PermissionMode, permissionModesUpTo, } from './permissions.js';
5
+ export { AGENT_COLOR_NAMES, agentColorHex, bashExitCode, clip, fullToolArgs, isGroupableTool, plural, resultFailed, rollupSentence, sanitizeLabel, sanitizePanelText, summarizeToolArgs, type ToolHeader, toolHeaderFor, toolSummary, } from './toolfmt.js';
6
+ export { agentTypeLabel, askQuestionFromArgs, firstNonEmptyLine, hiddenTranscriptTool, INTERRUPTED_NOTICE, interruptionNotice, parseSubagentNotice, planFromArgs, type SubagentNotice, subagentDeliveryLine, taskCallFromArgs, thinkingHeading, } from './transcript.js';
@@ -0,0 +1,11 @@
1
+ declare const REQUESTABLE_PERMISSION_MODES: readonly ['read-only', 'accept-edits', 'bypass-permissions'];
2
+ export declare const NAMED_PERMISSION_MODES: readonly ["read-only", "accept-edits", "bypass-permissions", "plan"];
3
+ export type PermissionMode = (typeof REQUESTABLE_PERMISSION_MODES)[number];
4
+ export type NamedPermissionMode = (typeof NAMED_PERMISSION_MODES)[number];
5
+ export declare const DEFAULT_PERMISSION_MODE: PermissionMode;
6
+ export declare function isNamedPermissionMode(mode: string | undefined): mode is NamedPermissionMode;
7
+ /** The daemon clamps a remote request to its owner's remoteMaxPermissionMode,
8
+ * so a menu offers only what that machine will honour. */
9
+ export declare function permissionModesUpTo(ceiling: string | undefined): PermissionMode[];
10
+ export declare function clampPermissionMode(mode: PermissionMode, ceiling: string | undefined): PermissionMode;
11
+ export {};
@@ -0,0 +1,18 @@
1
+ export interface ToolHeader {
2
+ label: string;
3
+ arg?: string;
4
+ }
5
+ export declare function toolHeaderFor(name: string): ToolHeader;
6
+ export declare function clip(s: string, max: number): string;
7
+ export declare function sanitizeLabel(s: string): string;
8
+ export declare function sanitizePanelText(s: string): string;
9
+ export declare function summarizeToolArgs(primary: string | undefined, argsJSON: string): string;
10
+ export declare function fullToolArgs(primary: string | undefined, argsJSON: string): string;
11
+ export declare function plural(n: number, noun: string): string;
12
+ export declare function resultFailed(name: string, result: string): boolean;
13
+ export declare function bashExitCode(body: string): [string, number, boolean];
14
+ export declare function toolSummary(name: string, args: string, result: string, isError: boolean, editSummaryFn?: (toolName: string, argsJSON: string) => string): string;
15
+ export declare function isGroupableTool(name: string): boolean;
16
+ export declare function rollupSentence(names: string[]): string;
17
+ export declare const AGENT_COLOR_NAMES: readonly ['blue', 'green', 'yellow', 'purple', 'cyan', 'orange', 'pink', 'red'];
18
+ export declare function agentColorHex(name: string | undefined): string | null;
@@ -0,0 +1,38 @@
1
+ export declare function hiddenTranscriptTool(name: string): boolean;
2
+ export declare function askQuestionFromArgs(argsJSON: string): string;
3
+ export declare function planFromArgs(argsJSON: string): string;
4
+ /** A Task call's display label the way the tool itself picks it: the
5
+ * description, else the clipped prompt, plus its custom agent type. */
6
+ export declare function taskCallFromArgs(argsJSON: string): {
7
+ description: string;
8
+ agentType: string;
9
+ };
10
+ /** The built-in "default" type is the same general-purpose agent an untyped
11
+ * Task spawns, so naming it would only add noise. */
12
+ export declare function agentTypeLabel(t: string): string;
13
+ /** The first line when the model wrote it as a heading ("# Title" or
14
+ * "**Title**"), the way reasoning summaries open, so a folded thought says
15
+ * what it was about. Prose gets no label of its own. */
16
+ export declare function thinkingHeading(raw: string): string;
17
+ /** How a turn cut short reads, whether replayed or watched live. */
18
+ export declare const INTERRUPTED_NOTICE: string;
19
+ /** The line the daemon files as the assistant's when a turn is cut short;
20
+ * it is a status, not something the model said. */
21
+ export declare function interruptionNotice(text: string): string | null;
22
+ export declare function firstNonEmptyLine(text: string, max: number): string;
23
+ export interface SubagentNotice {
24
+ id: string;
25
+ description: string;
26
+ preview: string;
27
+ /** The report itself, without the closing line addressed to the model. */
28
+ body: string;
29
+ interim: boolean;
30
+ /** The interrupted form is written for the model alone; the child's own
31
+ * block already reads interrupted, so no line is drawn for it. */
32
+ silent: boolean;
33
+ }
34
+ /** Reads a "[Background subagent <id> (<desc>) completed]" header; null for
35
+ * any other notice, which keeps its full text. */
36
+ export declare function parseSubagentNotice(text: string): SubagentNotice | null;
37
+ /** The line that marks a child's report entering the main conversation. */
38
+ export declare function subagentDeliveryLine(n: SubagentNotice): string;
package/dist/ai/ai.css ADDED
@@ -0,0 +1,325 @@
1
+ /* Chat-specific styles: markdown rendering (streamdown output) and the
2
+ * streaming/thinking animations. */
3
+
4
+ /* Answers are read at length, so their ink sits further from the page than
5
+ * the theme's UI text: pulled toward black on a light scheme and toward white
6
+ * on a dark one, from whatever ink the theme (or an org palette) supplies. */
7
+ .chat-ink {
8
+ --chat-ink: light-dark(
9
+ color-mix(in oklab, var(--theme-panel, #000) 60%, black),
10
+ color-mix(in oklab, var(--theme-panel, #fff) 75%, white)
11
+ );
12
+ color: var(--chat-ink);
13
+ --tw-prose-body: var(--chat-ink);
14
+ --tw-prose-headings: var(--chat-ink);
15
+ --tw-prose-bold: var(--chat-ink);
16
+ --tw-prose-code: var(--chat-ink);
17
+ }
18
+
19
+ /* Links */
20
+ .markdown a {
21
+ color: var(--theme-link, #428bca);
22
+ text-decoration: none;
23
+ }
24
+ .markdown a:hover {
25
+ text-decoration: underline;
26
+ }
27
+
28
+ /* Lists hang their markers in the gutter so a wrapped line lines up with the
29
+ * text above it, not with the number. Streamdown sets them inside. */
30
+ .markdown ol,
31
+ .markdown ul {
32
+ list-style-position: outside;
33
+ padding-left: 1.625em;
34
+ }
35
+ .markdown li {
36
+ padding-left: 0.25em;
37
+ }
38
+
39
+ /* Horizontal rules */
40
+ .markdown hr {
41
+ display: block;
42
+ height: 0;
43
+ border: 0;
44
+ border-top: 1px solid var(--theme-border, #e5e7eb);
45
+ margin: 1.5em 0;
46
+ padding: 0;
47
+ }
48
+
49
+ /* Inline code — code blocks are styled by Streamdown. A tint of the ink and
50
+ * no border: a hard outline turns every identifier into a keycap. */
51
+ .markdown code {
52
+ /* rem, not em: a table cell or list already sized down would size it twice. */
53
+ font-size: 0.875rem;
54
+ font-family: var(--font-mono, ui-monospace, monospace);
55
+ padding: 0.125em 0.375em;
56
+ background-color: color-mix(in oklab, var(--theme-panel, #000) 8%, transparent);
57
+ border-radius: 0.25rem;
58
+ /* Identifiers carry a colour of their own so they read as code at a glance
59
+ * without the weight the plugin gives them: the theme's link blue, which
60
+ * every palette already keeps legible on its surfaces. */
61
+ color: var(--theme-link, #2f6fa8);
62
+ font-weight: 400;
63
+ }
64
+ /* Reset inline code styles when inside a pre (code block) */
65
+ .markdown pre code {
66
+ padding: 0;
67
+ background-color: transparent;
68
+ border: none;
69
+ border-radius: 0;
70
+ font-size: inherit;
71
+ color: inherit;
72
+ }
73
+
74
+ /* KaTeX overrides */
75
+ .katex-display {
76
+ margin: 1em 0;
77
+ overflow-x: auto;
78
+ overflow-y: hidden;
79
+ }
80
+ .katex {
81
+ font-size: 1.1em;
82
+ }
83
+
84
+ /* Subscript and superscript */
85
+ .markdown sub,
86
+ .markdown sup {
87
+ font-size: 75%;
88
+ line-height: 0;
89
+ position: relative;
90
+ vertical-align: baseline;
91
+ }
92
+ .markdown sup {
93
+ top: -0.5em;
94
+ }
95
+ .markdown sub {
96
+ bottom: -0.25em;
97
+ }
98
+
99
+ /* Images */
100
+ .markdown img {
101
+ border: 0;
102
+ max-width: 100%;
103
+ height: auto;
104
+ vertical-align: middle;
105
+ border-radius: 0.5rem;
106
+ }
107
+
108
+ /* Streamdown tables: the body's own type,
109
+ * hairlines at a tenth of the ink, a header on a five-percent tint, and the
110
+ * copy/download controls only while the pointer is over the table. */
111
+ .markdown [data-streamdown="table-wrapper"] {
112
+ --table-line: color-mix(in oklab, var(--theme-panel, #000) 10%, transparent);
113
+ position: relative;
114
+ display: block;
115
+ background: transparent;
116
+ border: none;
117
+ padding: 0;
118
+ margin: 0.75rem 0;
119
+ }
120
+ .markdown [data-streamdown="table-wrapper"] > div:first-child {
121
+ position: absolute;
122
+ top: 0.375rem;
123
+ right: 0.375rem;
124
+ z-index: 1;
125
+ gap: 0.125rem;
126
+ padding: 0.125rem;
127
+ border-radius: 0.375rem;
128
+ background: var(--theme-panel-bg, #fff);
129
+ border: 1px solid var(--table-line);
130
+ opacity: 0;
131
+ transition: opacity 150ms ease-out;
132
+ }
133
+ .markdown [data-streamdown="table-wrapper"]:hover > div:first-child,
134
+ .markdown [data-streamdown="table-wrapper"]:focus-within > div:first-child {
135
+ opacity: 1;
136
+ }
137
+ .markdown [data-streamdown="table-wrapper"] > div:last-child {
138
+ padding: 0;
139
+ border: 1px solid var(--table-line);
140
+ border-radius: 0.5rem;
141
+ background: transparent;
142
+ }
143
+ .markdown [data-streamdown="table-wrapper"] table {
144
+ margin: 0;
145
+ font-size: 1rem;
146
+ line-height: 1.5;
147
+ }
148
+ .markdown [data-streamdown="table"] th {
149
+ padding: 0.4375rem 0.75rem;
150
+ font-size: 1rem;
151
+ font-weight: 500;
152
+ color: inherit;
153
+ background: color-mix(in oklab, var(--theme-panel, #000) 5%, transparent);
154
+ border-bottom: 1px solid var(--table-line);
155
+ }
156
+ .markdown [data-streamdown="table"] td {
157
+ padding: 0.4375rem 0.75rem;
158
+ /* Streamdown sizes cells down with its own class; the table is body type. */
159
+ font-size: 1rem;
160
+ line-height: 1.5;
161
+ vertical-align: top;
162
+ color: inherit;
163
+ /* A prose column keeps enough room to read; a wide table scrolls instead. */
164
+ min-width: 9rem;
165
+ }
166
+ .markdown [data-streamdown="table"] tbody tr {
167
+ border-bottom: 1px solid var(--table-line);
168
+ }
169
+ .markdown [data-streamdown="table"] tbody tr:last-child {
170
+ border-bottom: 0;
171
+ }
172
+ @media (prefers-reduced-motion: reduce) {
173
+ .markdown [data-streamdown="table-wrapper"] > div:first-child {
174
+ transition: none;
175
+ }
176
+ }
177
+
178
+ /* Streamdown code blocks — tighten spacing, remove inner double-border */
179
+ .markdown [data-streamdown="code-block"] {
180
+ padding: 0.375rem 0.5rem 0;
181
+ margin: 0.5em 0;
182
+ gap: 0;
183
+ }
184
+ .markdown [data-streamdown="code-block-header"] {
185
+ padding: 0.25rem 0.25rem;
186
+ }
187
+ .markdown [data-streamdown="code-block-body"] {
188
+ border: none;
189
+ border-radius: 0 0 0.5rem 0.5rem;
190
+ padding: 0;
191
+ }
192
+ /* Remove prose pre margin and code block body inner pre margin */
193
+ .markdown [data-streamdown="code-block-body"] pre {
194
+ margin: 0;
195
+ padding: 0.75rem 1rem;
196
+ overflow-x: auto;
197
+ /* Code reads looser than prose; Streamdown's text-sm line is too tight. */
198
+ line-height: 1.6;
199
+ }
200
+
201
+ /* Shiki dual-theme color overrides (standard Shiki approach).
202
+ Streamdown uses Tailwind dark: arbitrary-value classes for theme switching,
203
+ but Tailwind v4's source scanner can misparse them from minified JS —
204
+ generating broken selectors that apply dark bg unconditionally while
205
+ missing the text color classes entirely. Override both light and dark
206
+ explicitly to ensure correct colors in all modes.
207
+ See: https://shiki.style/guide/dual-themes#class-based-dark-mode */
208
+
209
+ /* Light mode: use the primary Shiki theme (--sdm-bg/--sdm-c) */
210
+ .markdown [data-streamdown="code-block-body"] pre {
211
+ background-color: var(--sdm-bg, inherit) !important;
212
+ color: var(--sdm-fg, inherit);
213
+ }
214
+ .markdown [data-streamdown="code-block-body"] pre code > span > span {
215
+ color: var(--sdm-c, inherit);
216
+ }
217
+
218
+ /* Dark mode: switch to --shiki-dark variants */
219
+ .dark .markdown [data-streamdown="code-block-body"] pre {
220
+ background-color: var(--shiki-dark-bg, var(--sdm-bg, inherit)) !important;
221
+ color: var(--shiki-dark, var(--sdm-fg, inherit));
222
+ }
223
+ .dark .markdown [data-streamdown="code-block-body"] pre code > span > span {
224
+ color: var(--shiki-dark, inherit);
225
+ font-style: var(--shiki-dark-font-style, inherit);
226
+ font-weight: var(--shiki-dark-font-weight, inherit);
227
+ text-decoration: var(--shiki-dark-text-decoration, inherit);
228
+ }
229
+ .dark .markdown [data-streamdown="code-block-body"] pre code > span > span[style*="--sdm-tbg"] {
230
+ background-color: var(--shiki-dark-bg, var(--sdm-tbg));
231
+ }
232
+
233
+ /* Remove prose backtick pseudo-elements on inline code */
234
+ .markdown code::before,
235
+ .markdown code::after {
236
+ content: none !important;
237
+ }
238
+
239
+ /* Task lists (checkboxes) */
240
+ .markdown input[type="checkbox"] {
241
+ margin-right: 0.5em;
242
+ vertical-align: middle;
243
+ }
244
+ .markdown li:has(> input[type="checkbox"]) {
245
+ list-style: none;
246
+ margin-left: -1.5em;
247
+ }
248
+
249
+ /* Touch device: always show chat actions */
250
+ @media (hover: none) {
251
+ .chat-actions,
252
+ .chat-meta {
253
+ opacity: 1 !important;
254
+ pointer-events: auto !important;
255
+ }
256
+ }
257
+
258
+ /* Long finished replies clamp with a bottom fade; mask keeps the fade
259
+ * background-agnostic across themes. */
260
+ .chat-message-clamp {
261
+ max-height: 600px;
262
+ overflow: hidden;
263
+ mask-image: linear-gradient(to bottom, black calc(100% - 96px), transparent);
264
+ -webkit-mask-image: linear-gradient(to bottom, black calc(100% - 96px), transparent);
265
+ }
266
+
267
+ /* Theme-aware input styling (matches the host app's .theme-input; defined
268
+ * here too so the edit textarea is styled in standalone use) */
269
+ .theme-input {
270
+ background-color: var(--theme-input-bg, #f9fafb);
271
+ border-color: var(--theme-border, #d1d5db);
272
+ color: var(--theme-app, #374151);
273
+ }
274
+
275
+ .theme-input:focus {
276
+ border-color: var(--theme-element, #3b82f6);
277
+ outline: none;
278
+ box-shadow: 0 0 0 1px var(--theme-element, #3b82f6);
279
+ }
280
+
281
+ @keyframes shimmer {
282
+ 0% {
283
+ background-position: 200% 0;
284
+ }
285
+ 100% {
286
+ background-position: -200% 0;
287
+ }
288
+ }
289
+
290
+ @utility animate-shimmer {
291
+ animation: shimmer 1.75s linear infinite;
292
+ background-size: 200% 100%;
293
+ }
294
+
295
+ @utility text-shimmer {
296
+ background-image: linear-gradient(
297
+ 90deg,
298
+ var(--theme-muted-text-color, #6a7282) 0%,
299
+ var(--theme-app, #d1d5db) 20%,
300
+ var(--theme-muted-text-color, #6a7282) 40%
301
+ );
302
+ -webkit-background-clip: text;
303
+ background-clip: text;
304
+ color: transparent;
305
+ }
306
+
307
+ /* Entrance animation for chat messages (CSS replacement for a JS motion lib).
308
+ * Only `from` is defined so elements settle at their natural styles (queued
309
+ * messages render at reduced opacity). */
310
+ @keyframes chat-fade-in-up {
311
+ from {
312
+ opacity: 0;
313
+ transform: translateY(8px);
314
+ }
315
+ }
316
+
317
+ @utility animate-chat-enter {
318
+ animation: chat-fade-in-up 0.25s ease-out;
319
+ }
320
+
321
+ @media (prefers-reduced-motion: reduce) {
322
+ .animate-chat-enter {
323
+ animation: none;
324
+ }
325
+ }
@@ -0,0 +1,4 @@
1
+ export default function AllocationSelector({ variant, }?: {
2
+ /** 'bare' drops the border, for a toolbar that reads as text. */
3
+ variant?: 'default' | 'bare';
4
+ }): import("react").JSX.Element | null;
@@ -0,0 +1 @@
1
+ export default function AttachmentManager(): import("react").JSX.Element | null;
@@ -0,0 +1,24 @@
1
+ export interface AttachmentUploadHandle {
2
+ addFiles: (files: FileList | File[]) => void;
3
+ }
4
+ export interface Attachment {
5
+ id?: string;
6
+ file?: File;
7
+ filename: string;
8
+ mimeType: string;
9
+ size: number;
10
+ uploading?: boolean;
11
+ uploaded?: boolean;
12
+ error?: string;
13
+ url?: string;
14
+ }
15
+ interface AttachmentUploadProps {
16
+ conversationId?: string | undefined;
17
+ attachments: Attachment[];
18
+ onAttachmentsChange: (attachments: Attachment[]) => void;
19
+ disabled?: boolean;
20
+ maxFiles?: number;
21
+ maxFileSize?: number;
22
+ }
23
+ declare const AttachmentUpload: import("react").ForwardRefExoticComponent<AttachmentUploadProps & import("react").RefAttributes<AttachmentUploadHandle>>;
24
+ export default AttachmentUpload;
@@ -0,0 +1 @@
1
+ export default function BlockedGroupBanner(): import("react").JSX.Element | null;
@@ -0,0 +1,8 @@
1
+ import type { ChatMessage as Message } from '../types.js';
2
+ interface BranchNavigatorProps {
3
+ messages: Message[];
4
+ currentMessageId: string;
5
+ onNavigate: (messageId: string) => void;
6
+ }
7
+ export default function BranchNavigator({ messages, currentMessageId, onNavigate, }: BranchNavigatorProps): import("react").JSX.Element | null;
8
+ export {};
@@ -0,0 +1,3 @@
1
+ export default function ChatEmptyState({ targetSession, }: {
2
+ targetSession?: string | null | undefined;
3
+ }): import("react").JSX.Element;
@@ -0,0 +1,45 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type SlashMenuConfig } from './SlashMenu.js';
3
+ interface ChatInputProps {
4
+ onSend: (content: string, attachmentIds?: string[], attachmentMeta?: Record<string, {
5
+ filename: string;
6
+ contentType: string;
7
+ size: number;
8
+ }>) => void;
9
+ disabled?: boolean;
10
+ placeholder?: string | undefined;
11
+ conversationId?: string;
12
+ onEditLastMessage?: () => void;
13
+ /** Only the box: no page padding, width cap, or settings row, for a host
14
+ * that lays out its own controls around it. */
15
+ flush?: boolean;
16
+ /** Send with nothing typed, for a surface where the text is optional. */
17
+ allowEmpty?: boolean;
18
+ /** Attach, paste, and drop files. Off for a target that takes text only. */
19
+ attachments?: boolean;
20
+ /** Hold sending until the provider's selected model is one it can serve.
21
+ * Off when the target picks its own model. */
22
+ requireModel?: boolean;
23
+ inputLabel?: string;
24
+ sendLabel?: string;
25
+ sendTestId?: string;
26
+ /** Offers the host's slash commands as the input starts with /. */
27
+ slash?: SlashMenuConfig | undefined;
28
+ /** Pills naming where the turn runs, rendered above the input. */
29
+ context?: ReactNode;
30
+ settingsLeft?: ReactNode;
31
+ settingsRight?: ReactNode;
32
+ /** A turn the chat provider does not run, such as an agent session's: it
33
+ * drives the Stop button in place of the provider's stream and queue. */
34
+ turn?: {
35
+ running: boolean;
36
+ onStop: () => void;
37
+ stopping?: boolean;
38
+ };
39
+ }
40
+ export interface ChatInputHandle {
41
+ addFiles: (files: FileList | File[]) => void;
42
+ focus: () => void;
43
+ }
44
+ declare const ChatInput: import("react").ForwardRefExoticComponent<ChatInputProps & import("react").RefAttributes<ChatInputHandle>>;
45
+ export default ChatInput;
@@ -0,0 +1,5 @@
1
+ import type { ReactNode } from 'react';
2
+ export default function ChatLayout({ children, sidebarActions, }: {
3
+ children: ReactNode;
4
+ sidebarActions?: boolean;
5
+ }): import("react").JSX.Element;