@parallelworks/ui 0.19.0 → 0.20.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 (233) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunks/memoryStore-CC91S5LP.js → ai/adapter/memoryStore.js} +2 -2
  3. package/dist/ai/adapter/mock/index.js +2 -80
  4. package/dist/ai/adapter/mock/mockAdapter.js +81 -0
  5. package/dist/ai/adapter/openai/createOpenAIStream.js +33 -0
  6. package/dist/ai/adapter/openai/errors.js +37 -0
  7. package/dist/ai/adapter/openai/index.js +5 -333
  8. package/dist/ai/adapter/openai/openaiAdapter.js +54 -0
  9. package/dist/ai/adapter/openai/responses.js +108 -0
  10. package/dist/ai/adapter/openai/sse.js +112 -0
  11. package/dist/{chunks/types-Yy0NrerF.js → ai/adapter/types.js} +1 -1
  12. package/dist/ai/agent/classifier.js +12 -0
  13. package/dist/ai/agent/diff.js +223 -0
  14. package/dist/ai/agent/diffHighlight.js +101 -0
  15. package/dist/ai/agent/permissions.js +29 -0
  16. package/dist/ai/agent/toolfmt.js +383 -0
  17. package/dist/ai/agent/transcript.js +127 -0
  18. package/dist/ai/components/AllocationSelector.js +56 -0
  19. package/dist/ai/components/AttachmentManager.js +147 -0
  20. package/dist/ai/components/AttachmentUpload.js +179 -0
  21. package/dist/ai/components/BlockedGroupBanner.js +29 -0
  22. package/dist/ai/components/BranchNavigator.js +57 -0
  23. package/dist/ai/components/ChatEmptyState.js +171 -0
  24. package/dist/ai/components/ChatInput.js +265 -0
  25. package/dist/ai/components/ChatLayout.js +15 -0
  26. package/dist/ai/components/ChatMessage.js +341 -0
  27. package/dist/ai/components/ChatMessageList.js +301 -0
  28. package/dist/ai/components/ChatSidebar.js +345 -0
  29. package/dist/ai/components/ChatThread.js +198 -0
  30. package/dist/ai/components/ComposerChrome.js +50 -0
  31. package/dist/ai/components/ComposerFrame.js +33 -0
  32. package/dist/ai/components/DragOverlay.js +20 -0
  33. package/dist/ai/components/ModelSelector.js +343 -0
  34. package/dist/ai/components/ShareDialog.js +260 -0
  35. package/dist/ai/components/SlashMenu.js +91 -0
  36. package/dist/ai/components/agent/ActivityLine.js +151 -0
  37. package/dist/ai/components/agent/AgentMessageParts.js +721 -0
  38. package/dist/ai/components/agent/PermissionPicker.js +38 -0
  39. package/dist/ai/components/attachmentKeys.js +10 -0
  40. package/dist/ai/core/ChatProvider.js +848 -0
  41. package/dist/ai/core/KeyboardShortcutsProvider.js +9 -0
  42. package/dist/ai/core/chatReducer.js +223 -0
  43. package/dist/ai/core/config.js +46 -0
  44. package/dist/ai/core/events.js +4 -0
  45. package/dist/ai/core/exportConversation.js +42 -0
  46. package/dist/ai/core/greeting.js +38 -0
  47. package/dist/ai/core/parts.js +84 -0
  48. package/dist/ai/core/useDragDrop.js +36 -0
  49. package/dist/ai/core/useKeyboardShortcuts.js +77 -0
  50. package/dist/ai/core/useSSEStream.js +98 -0
  51. package/dist/ai/index.js +43 -6644
  52. package/dist/ai/strings.js +175 -0
  53. package/dist/ai/ui/Avatar.js +35 -0
  54. package/dist/ai/ui/Dropdown.js +110 -0
  55. package/dist/ai/ui/Markdown.js +79 -0
  56. package/dist/ai/ui/Notice.js +77 -0
  57. package/dist/ai/ui/codeBreaks.js +36 -0
  58. package/dist/ai/ui/prose.js +13 -0
  59. package/dist/ai/ui/sidebar.js +148 -0
  60. package/dist/ai/utils.js +23 -0
  61. package/dist/assets/editor.worker-DfmPPyOL.js +60 -0
  62. package/dist/assets/json.worker-Dqgjpq9F.js +92 -0
  63. package/dist/assets/yaml.worker-DLx0whrM.js +1441 -0
  64. package/dist/components/AddMenu.js +46 -0
  65. package/dist/components/Avatar.js +46 -0
  66. package/dist/{chunks/BareModal-BtRiQezg.js → components/BareModal.js} +1 -1
  67. package/dist/components/Breadcrumbs.js +83 -0
  68. package/dist/components/Button.js +83 -0
  69. package/dist/components/Callout.js +23 -0
  70. package/dist/components/Card.js +31 -0
  71. package/dist/components/CollapsiblePanel.js +77 -0
  72. package/dist/{chunks/ConfirmModal-aOR4O1QE.js → components/ConfirmModal.js} +4 -9
  73. package/dist/components/CopyToClipboard.js +81 -0
  74. package/dist/{chunks/Markdown-CM-FenNE.js → components/CreateModal.js} +9 -116
  75. package/dist/components/DescriptionList.js +42 -0
  76. package/dist/components/Dropdown.js +349 -0
  77. package/dist/components/EmptyState.js +27 -0
  78. package/dist/components/Filter.js +32 -0
  79. package/dist/components/FilterPill.js +13 -0
  80. package/dist/components/IconButton.js +34 -0
  81. package/dist/{chunks/Indicator-hBSIxOPK.js → components/Indicator.js} +1 -1
  82. package/dist/components/Input.js +88 -0
  83. package/dist/components/LetterBadge.js +13 -0
  84. package/dist/components/Listbox.js +123 -0
  85. package/dist/{chunks/Loader-BXoXTZGc.js → components/Loader.js} +1 -1
  86. package/dist/components/Markdown.js +15 -0
  87. package/dist/components/MultiSelect.js +171 -0
  88. package/dist/components/Overview.js +39 -0
  89. package/dist/components/PageHeader.js +194 -0
  90. package/dist/components/Pagination.js +35 -0
  91. package/dist/{chunks/Provider-CDYurraE.js → components/Provider.js} +13 -5
  92. package/dist/{chunks/RequiredMark-DfLdYbYZ.js → components/RequiredMark.js} +1 -1
  93. package/dist/components/SectionHeader.js +11 -0
  94. package/dist/components/SettingModeOption.js +30 -0
  95. package/dist/components/SettingRow.js +35 -0
  96. package/dist/components/SettingsCard.js +31 -0
  97. package/dist/components/SettingsGroup.js +17 -0
  98. package/dist/components/Sort.js +42 -0
  99. package/dist/components/StatusBadge.js +63 -0
  100. package/dist/components/SwitchToggle.js +59 -0
  101. package/dist/{chunks/SwitchToggleSmall-FcsaYSTs.js → components/SwitchToggleSmall.js} +1 -1
  102. package/dist/{chunks/Table-DU2MW8xz.js → components/Table.js} +3 -3
  103. package/dist/components/Toggle.js +20 -0
  104. package/dist/{chunks/Tooltip-K5HJr4_p.js → components/Tooltip.js} +2 -27
  105. package/dist/{chunks/StatusBadge-C1Blx_cW.js → components/dropdownUtils.js} +2 -63
  106. package/dist/{chunks/focus-D_iZJTW1.js → components/focus.js} +1 -1
  107. package/dist/components/ghostButton.js +7 -0
  108. package/dist/components/inputClasses.js +4 -0
  109. package/dist/components/keys.js +27 -0
  110. package/dist/components/relativeTime.js +32 -0
  111. package/dist/{chunks/useCssIsDark-DHr05dG2.js → components/useCssIsDark.js} +1 -1
  112. package/dist/{chunks/duration-BOv8Phl8.js → duration.js} +1 -1
  113. package/dist/editor/Editor.js +13 -0
  114. package/dist/editor/EditorField.js +53 -0
  115. package/dist/editor/FormCodePanel.js +173 -0
  116. package/dist/{chunks/Monaco-DJ8MW-Dq.js → editor/Monaco.js} +5 -26
  117. package/dist/editor/index.js +6 -1
  118. package/dist/editor/themes.js +91 -0
  119. package/dist/editor/workers.d.ts +5 -0
  120. package/dist/editor/workers.js +35 -0
  121. package/dist/editor/yaml.d.ts +9 -1
  122. package/dist/editor/yaml.js +15 -0
  123. package/dist/editor/yaml.worker.d.ts +1 -0
  124. package/dist/editor/yamlLanguage.d.ts +6 -0
  125. package/dist/editor/yamlLanguage.js +312 -0
  126. package/dist/file-explorer/FileExplorer.js +1405 -0
  127. package/dist/file-explorer/FileExplorerContext.js +370 -0
  128. package/dist/{chunks/CodePreviewEditor-YqQBz1YL.js → file-explorer/FilePreview/CodePreviewEditor.js} +3 -2
  129. package/dist/file-explorer/FilePreview/Inline.js +45 -0
  130. package/dist/file-explorer/FilePreview/StreamedBadge.js +16 -0
  131. package/dist/file-explorer/FilePreview/Viewer.js +526 -0
  132. package/dist/file-explorer/FilePreview/index.js +266 -0
  133. package/dist/file-explorer/FilePreview/parse.js +63 -0
  134. package/dist/file-explorer/FilePreview/previewCache.js +98 -0
  135. package/dist/file-explorer/FilePreview/previewType.js +151 -0
  136. package/dist/file-explorer/FilePreview/readCappedBytes.js +196 -0
  137. package/dist/file-explorer/FilePreview/useObjectBlobUrl.js +95 -0
  138. package/dist/file-explorer/FilePreview/useObjectText.js +109 -0
  139. package/dist/file-explorer/FilePreview/usePresignedUrl.js +73 -0
  140. package/dist/file-explorer/FileRow.js +165 -0
  141. package/dist/file-explorer/FileRowsWindow.js +92 -0
  142. package/dist/file-explorer/FileTable.js +172 -0
  143. package/dist/file-explorer/FileTableHeaders.js +49 -0
  144. package/dist/file-explorer/LoadMoreRow.js +46 -0
  145. package/dist/file-explorer/TreeView.js +376 -0
  146. package/dist/file-explorer/helpers.js +537 -0
  147. package/dist/file-explorer/index.js +7 -5671
  148. package/dist/file-explorer/lib/batch.js +39 -0
  149. package/dist/file-explorer/lib/errors.js +9 -0
  150. package/dist/file-explorer/lib/paging.js +124 -0
  151. package/dist/file-explorer/lib/utils.js +322 -0
  152. package/dist/file-explorer/toasts.js +400 -0
  153. package/dist/file-explorer/treeRows.js +73 -0
  154. package/dist/file-explorer/useNearEnd.js +27 -0
  155. package/dist/form/FieldWrapper.js +54 -0
  156. package/dist/form/Fields/BooleanField.js +51 -0
  157. package/dist/form/Fields/CheckboxGroupField.js +72 -0
  158. package/dist/form/Fields/ColorField.js +33 -0
  159. package/dist/form/Fields/DropdownField.js +49 -0
  160. package/dist/form/Fields/DurationField.js +130 -0
  161. package/dist/form/Fields/LabelField.js +19 -0
  162. package/dist/form/Fields/MultiDropdownField.js +40 -0
  163. package/dist/form/Fields/NumberField.js +51 -0
  164. package/dist/form/Fields/ObjectField.js +54 -0
  165. package/dist/form/Fields/RadioField.js +49 -0
  166. package/dist/form/Fields/RangeField.js +58 -0
  167. package/dist/form/Fields/ResourceOptionIcon.js +21 -0
  168. package/dist/form/Fields/StepField.js +6 -0
  169. package/dist/form/Fields/StringField.js +37 -0
  170. package/dist/form/Fields/TextAreaField.js +31 -0
  171. package/dist/form/Fields/durationValidity.js +11 -0
  172. package/dist/form/Form.js +643 -0
  173. package/dist/form/SpecialTypes/DropdownWrapper.js +30 -0
  174. package/dist/form/SpecialTypes/FormikCustomDropdown.js +122 -0
  175. package/dist/form/SpecialTypes/FormikCustomInput.js +111 -0
  176. package/dist/form/SpecialTypes/FormikMultiSelectDropdown.js +31 -0
  177. package/dist/form/SpecialTypes/FormikNumericInput.js +60 -0
  178. package/dist/form/Wizard/WizardContainer.js +138 -0
  179. package/dist/form/Wizard/WizardNavigation.js +92 -0
  180. package/dist/form/Wizard/WizardStepContent.js +35 -0
  181. package/dist/form/Wizard/WizardStepIndicator.js +108 -0
  182. package/dist/form/Wizard/useWizardState.js +118 -0
  183. package/dist/form/Wizard/utils.js +34 -0
  184. package/dist/form/fieldContext.js +26 -0
  185. package/dist/form/fieldRegistry.js +50 -0
  186. package/dist/form/index.js +17 -2321
  187. package/dist/{chunks/FieldWrapper-Cszwg-4B.js → form/lib.js} +2 -97
  188. package/dist/form/useParsedOpts.js +62 -0
  189. package/dist/form/usePrevious.js +11 -0
  190. package/dist/form/utils/checkShowIfObject.js +14 -0
  191. package/dist/form/utils/duration.js +69 -0
  192. package/dist/form/utils/getParentValue.js +23 -0
  193. package/dist/form/utils/getPlaceholder.js +9 -0
  194. package/dist/form/utils/getValueUsingPath.js +23 -0
  195. package/dist/form/utils/secondaryField.js +22 -0
  196. package/dist/graph/AnnotationBanner.js +141 -0
  197. package/dist/graph/Collapse.js +41 -0
  198. package/dist/graph/DependencyGraph.js +1398 -0
  199. package/dist/graph/JobSummary.js +104 -0
  200. package/dist/graph/MatrixGroup.js +107 -0
  201. package/dist/graph/Reveal.js +57 -0
  202. package/dist/graph/TreeView.js +711 -0
  203. package/dist/graph/index.js +1 -2519
  204. package/dist/graph/types.js +6 -0
  205. package/dist/icons.d.ts +4 -4
  206. package/dist/icons.js +5 -5
  207. package/dist/index.js +46 -599
  208. package/dist/list/ActionToolbar.js +184 -0
  209. package/dist/list/HoverCard.js +73 -0
  210. package/dist/list/ListPage.js +145 -0
  211. package/dist/list/ListPager.js +59 -0
  212. package/dist/list/ListTable.js +163 -0
  213. package/dist/list/ListViewControls.js +372 -0
  214. package/dist/list/RowContextMenu.js +351 -0
  215. package/dist/list/UserHoverCard.js +117 -0
  216. package/dist/list/index.js +11 -2
  217. package/dist/list/listSearch.js +137 -0
  218. package/dist/list/listView.js +210 -0
  219. package/dist/list/textEntry.js +10 -0
  220. package/dist/{chunks/logviewer-BTKuQWzw.js → logviewer/LogViewer.js} +4 -82
  221. package/dist/logviewer/index.js +2 -1
  222. package/dist/logviewer/segments.js +80 -0
  223. package/dist/safeUrl.d.ts +6 -0
  224. package/dist/safeUrl.js +22 -0
  225. package/package.json +7 -9
  226. package/dist/assets/editor.worker-BmHUIVG4.js +0 -14807
  227. package/dist/assets/json.worker-D8bJ92nw.js +0 -22207
  228. package/dist/assets/yaml.worker-C4gyGAko.js +0 -50201
  229. package/dist/chunks/PageHeader-0kG_iypP.js +0 -692
  230. package/dist/chunks/SwitchToggle-DShNdcao.js +0 -758
  231. package/dist/chunks/editor-Dk1rbV75.js +0 -361
  232. package/dist/chunks/list-CJm875m7.js +0 -1418
  233. /package/dist/{chunks/MarkdownImpl-CyeTVvSt.js → components/MarkdownImpl.js} +0 -0
@@ -0,0 +1,108 @@
1
+ //#region src/ai/adapter/openai/responses.ts
2
+ function contentString(content) {
3
+ return typeof content === "string" ? content : "";
4
+ }
5
+ function buildResponsesRequestBody(model, messages) {
6
+ const input = [];
7
+ let attachmentIds;
8
+ for (const m of messages) switch (m.role) {
9
+ case "system":
10
+ input.push({
11
+ type: "message",
12
+ role: "system",
13
+ content: contentString(m.content)
14
+ });
15
+ break;
16
+ case "user":
17
+ if (m.attachment_ids?.length) attachmentIds = m.attachment_ids;
18
+ input.push({
19
+ type: "message",
20
+ role: "user",
21
+ content: contentString(m.content)
22
+ });
23
+ break;
24
+ case "assistant": {
25
+ const replayed = Array.isArray(m.responses_output) ? replayableOutput(m.responses_output) : [];
26
+ if (replayed.length > 0) {
27
+ for (const item of replayed) input.push(item);
28
+ break;
29
+ }
30
+ const text = contentString(m.content);
31
+ const toolCalls = m.tool_calls ?? [];
32
+ if (text || toolCalls.length === 0) input.push({
33
+ type: "message",
34
+ role: "assistant",
35
+ content: text
36
+ });
37
+ for (const tc of toolCalls) input.push({
38
+ type: "function_call",
39
+ call_id: tc.id ?? "",
40
+ name: tc.function.name,
41
+ arguments: tc.function.arguments
42
+ });
43
+ break;
44
+ }
45
+ case "tool": input.push({
46
+ type: "function_call_output",
47
+ call_id: m.tool_call_id ?? "",
48
+ output: contentString(m.content)
49
+ });
50
+ }
51
+ const body = {
52
+ model,
53
+ input,
54
+ stream: true,
55
+ store: false,
56
+ include: ["reasoning.encrypted_content"]
57
+ };
58
+ if (attachmentIds?.length) body["attachment_ids"] = attachmentIds;
59
+ return body;
60
+ }
61
+ var REPLAYABLE_ITEM_TYPES = /* @__PURE__ */ new Set([
62
+ "reasoning",
63
+ "message",
64
+ "function_call"
65
+ ]);
66
+ function replayableOutput(output) {
67
+ if (!output?.length) return [];
68
+ return output.filter((item) => {
69
+ if (typeof item !== "object" || item === null) return false;
70
+ const itemType = item.type;
71
+ return typeof itemType === "string" && REPLAYABLE_ITEM_TYPES.has(itemType);
72
+ });
73
+ }
74
+ function parseResponsesSSELine(line) {
75
+ if (!line.startsWith("data: ")) return null;
76
+ const data = line.slice(6);
77
+ if (data === "[DONE]" || data === "\"[DONE]\"") return null;
78
+ let event;
79
+ try {
80
+ event = JSON.parse(data);
81
+ } catch {
82
+ return null;
83
+ }
84
+ if (event.error) return { error: event.error.message || "Unknown error" };
85
+ const model = event.response?.model;
86
+ switch (event.type) {
87
+ case "pw.message_id": return event.messageId ? { messageId: event.messageId } : null;
88
+ case "response.output_text.delta":
89
+ case "response.refusal.delta": return typeof event.delta === "string" ? { content: event.delta } : null;
90
+ case "response.reasoning_summary_text.delta": return typeof event.delta === "string" ? { reasoningContent: event.delta } : null;
91
+ case "response.created": return model ? { model } : null;
92
+ case "response.completed": return {
93
+ ...model && { model },
94
+ finishReason: "stop",
95
+ responsesOutput: replayableOutput(event.response?.output)
96
+ };
97
+ case "response.incomplete": return {
98
+ ...model && { model },
99
+ finishReason: "length",
100
+ responsesOutput: replayableOutput(event.response?.output)
101
+ };
102
+ case "response.failed": return { error: event.response?.error?.message || "Response failed" };
103
+ case "error": return { error: event.message || "Stream error" };
104
+ default: return null;
105
+ }
106
+ }
107
+ //#endregion
108
+ export { buildResponsesRequestBody, parseResponsesSSELine };
@@ -0,0 +1,112 @@
1
+ //#region src/ai/adapter/openai/sse.ts
2
+ function parseSSELine(line) {
3
+ if (!line.startsWith("data: ")) return null;
4
+ const data = line.slice(6);
5
+ if (data === "[DONE]" || data === "\"[DONE]\"") return null;
6
+ try {
7
+ const parsed = JSON.parse(data);
8
+ if (parsed.error) return { error: parsed.error.message || "Unknown error" };
9
+ const chunk = parsed;
10
+ const choice = chunk.choices?.[0];
11
+ return {
12
+ id: chunk.id,
13
+ messageId: chunk.messageId,
14
+ content: choice?.delta?.content,
15
+ reasoningContent: choice?.delta?.reasoning_content,
16
+ toolCalls: choice?.delta?.tool_calls ?? void 0,
17
+ finishReason: choice?.finish_reason,
18
+ model: chunk.model
19
+ };
20
+ } catch {
21
+ return null;
22
+ }
23
+ }
24
+ /** Process an SSE stream from a ReadableStream reader */
25
+ async function processSSEStream(reader, onContent, onToolCall, onError, onReasoning, onMessageId, parseLine = parseSSELine) {
26
+ const decoder = new TextDecoder();
27
+ let assistantContent = "";
28
+ let assistantReasoning = "";
29
+ let assistantMessageId = "";
30
+ let finishReason = null;
31
+ let resolvedModel = null;
32
+ let responsesOutput = [];
33
+ const toolCallsMap = /* @__PURE__ */ new Map();
34
+ let lineBuffer = "";
35
+ while (true) {
36
+ const result = await reader.read();
37
+ if (result.done) break;
38
+ const chunk = decoder.decode(result.value, { stream: true });
39
+ const lines = (lineBuffer + chunk).split("\n");
40
+ lineBuffer = lines.pop() || "";
41
+ for (const line of lines) {
42
+ const parsed = parseLine(line);
43
+ if (parsed) {
44
+ if (parsed.error) {
45
+ onError?.(parsed.error);
46
+ throw new Error(parsed.error);
47
+ }
48
+ if (parsed.messageId && !assistantMessageId) {
49
+ assistantMessageId = parsed.messageId;
50
+ onMessageId?.(parsed.messageId);
51
+ } else if (parsed.id && !assistantMessageId) assistantMessageId = parsed.id;
52
+ if (parsed.model && !resolvedModel) resolvedModel = parsed.model;
53
+ if (parsed.content) {
54
+ assistantContent += parsed.content;
55
+ onContent(parsed.content);
56
+ }
57
+ if (parsed.reasoningContent) {
58
+ assistantReasoning += parsed.reasoningContent;
59
+ onReasoning?.(parsed.reasoningContent);
60
+ }
61
+ if (parsed.finishReason) finishReason = parsed.finishReason;
62
+ if (parsed.responsesOutput?.length) responsesOutput = parsed.responsesOutput;
63
+ if (parsed.toolCalls) for (const tc of parsed.toolCalls) {
64
+ if (tc.index === void 0) continue;
65
+ const existing = toolCallsMap.get(tc.index);
66
+ if (existing) {
67
+ if (tc.function?.arguments) existing.arguments += tc.function.arguments;
68
+ } else toolCallsMap.set(tc.index, {
69
+ id: tc.id || "",
70
+ type: tc.type || "function",
71
+ name: tc.function?.name || "",
72
+ arguments: tc.function?.arguments || ""
73
+ });
74
+ }
75
+ }
76
+ }
77
+ }
78
+ if (lineBuffer.trim()) {
79
+ const parsed = parseLine(lineBuffer);
80
+ if (parsed) {
81
+ if (parsed.content) {
82
+ assistantContent += parsed.content;
83
+ onContent(parsed.content);
84
+ }
85
+ if (parsed.reasoningContent) {
86
+ assistantReasoning += parsed.reasoningContent;
87
+ onReasoning?.(parsed.reasoningContent);
88
+ }
89
+ if (parsed.finishReason) finishReason = parsed.finishReason;
90
+ }
91
+ }
92
+ const toolCalls = Array.from(toolCallsMap.values()).map((tc) => ({
93
+ id: tc.id,
94
+ type: tc.type,
95
+ function: {
96
+ name: tc.name,
97
+ arguments: tc.arguments
98
+ }
99
+ }));
100
+ if (toolCalls.length > 0 && onToolCall) onToolCall(toolCalls);
101
+ return {
102
+ content: assistantContent,
103
+ messageId: assistantMessageId,
104
+ toolCalls,
105
+ finishReason,
106
+ model: resolvedModel,
107
+ reasoning: assistantReasoning,
108
+ responsesOutput
109
+ };
110
+ }
111
+ //#endregion
112
+ export { parseSSELine, processSSEStream };
@@ -8,4 +8,4 @@ var ChatAdapterError = class extends Error {
8
8
  }
9
9
  };
10
10
  //#endregion
11
- export { ChatAdapterError as t };
11
+ export { ChatAdapterError };
@@ -0,0 +1,12 @@
1
+ //#region src/ai/agent/classifier.ts
2
+ var COMPACTION_MARKER = "[Conversation summary from automatic compaction]";
3
+ function classifyPseudoUserMessage(role, content) {
4
+ if (role !== "user" || !content) return null;
5
+ const t = content.trimStart();
6
+ if (t.startsWith("<command-input>")) return "command-input";
7
+ if (t.startsWith("<shell-input>")) return "shell-input";
8
+ if (t.startsWith(COMPACTION_MARKER)) return "compaction";
9
+ return null;
10
+ }
11
+ //#endregion
12
+ export { classifyPseudoUserMessage };
@@ -0,0 +1,223 @@
1
+ import { sanitizeLabel } from "./toolfmt.js";
2
+ //#region src/ai/agent/diff.ts
3
+ var MAX_EDIT_DIFF_LINES = 100;
4
+ var MAX_WRITE_DIFF_LINES = 50;
5
+ function isEditDiffTool(name) {
6
+ return name === "EditFile" || name === "WriteFile";
7
+ }
8
+ function parseEditArgs(argsJSON) {
9
+ try {
10
+ const a = JSON.parse(argsJSON);
11
+ return a && typeof a === "object" ? a : null;
12
+ } catch {
13
+ return null;
14
+ }
15
+ }
16
+ function splitLines(s) {
17
+ const trimmed = s.endsWith("\n") ? s.slice(0, -1) : s;
18
+ return trimmed === "" ? [] : trimmed.split("\n");
19
+ }
20
+ function getOpCodes(a, b) {
21
+ const n = a.length;
22
+ const m = b.length;
23
+ const lcs = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));
24
+ for (let i = n - 1; i >= 0; i--) {
25
+ const row = lcs[i];
26
+ const next = lcs[i + 1];
27
+ if (!row || !next) continue;
28
+ for (let j = m - 1; j >= 0; j--) row[j] = a[i] === b[j] ? (next[j + 1] ?? 0) + 1 : Math.max(next[j] ?? 0, row[j + 1] ?? 0);
29
+ }
30
+ const ops = [];
31
+ let i = 0;
32
+ let j = 0;
33
+ const push = (tag, i1, i2, j1, j2) => {
34
+ const last = ops[ops.length - 1];
35
+ if (last && last.tag === tag && last.i2 === i1 && last.j2 === j1) {
36
+ last.i2 = i2;
37
+ last.j2 = j2;
38
+ return;
39
+ }
40
+ ops.push({
41
+ tag,
42
+ i1,
43
+ i2,
44
+ j1,
45
+ j2
46
+ });
47
+ };
48
+ while (i < n && j < m) if (a[i] === b[j]) {
49
+ push("e", i, i + 1, j, j + 1);
50
+ i++;
51
+ j++;
52
+ } else if ((lcs[i + 1]?.[j] ?? 0) >= (lcs[i]?.[j + 1] ?? 0)) {
53
+ push("d", i, i + 1, j, j);
54
+ i++;
55
+ } else {
56
+ push("i", i, i, j, j + 1);
57
+ j++;
58
+ }
59
+ if (i < n) push("d", i, n, j, j);
60
+ if (j < m) push("i", i, i, j, m);
61
+ const merged = [];
62
+ for (const op of ops) {
63
+ const last = merged[merged.length - 1];
64
+ if (last && (last.tag === "d" && op.tag === "i" || last.tag === "i" && op.tag === "d")) {
65
+ merged[merged.length - 1] = {
66
+ tag: "r",
67
+ i1: Math.min(last.i1, op.i1),
68
+ i2: Math.max(last.i2, op.i2),
69
+ j1: Math.min(last.j1, op.j1),
70
+ j2: Math.max(last.j2, op.j2)
71
+ };
72
+ continue;
73
+ }
74
+ merged.push(op);
75
+ }
76
+ return merged;
77
+ }
78
+ function tokenizeWords(line) {
79
+ return line.match(/\w+|\s+|[^\w\s]+/g) ?? [];
80
+ }
81
+ function wordEmphasisRanges(oldLine, newLine) {
82
+ const a = tokenizeWords(oldLine);
83
+ const b = tokenizeWords(newLine);
84
+ if (a.length === 0 || b.length === 0) return null;
85
+ const ops = getOpCodes(a, b);
86
+ if (!ops.some((op) => op.tag === "e" && a.slice(op.i1, op.i2).some((t) => /\w/.test(t)))) return null;
87
+ const starts = [];
88
+ let pos = 0;
89
+ for (const t of b) {
90
+ starts.push(pos);
91
+ pos += t.length;
92
+ }
93
+ starts.push(pos);
94
+ const ranges = [];
95
+ for (const op of ops) {
96
+ if (op.tag !== "i" && op.tag !== "r") continue;
97
+ if (op.j1 >= op.j2) continue;
98
+ const start = starts[op.j1] ?? 0;
99
+ const end = starts[op.j2] ?? pos;
100
+ const last = ranges[ranges.length - 1];
101
+ if (last && last[1] === start) last[1] = end;
102
+ else ranges.push([start, end]);
103
+ }
104
+ return ranges.length > 0 ? ranges : null;
105
+ }
106
+ function lineDelta(oldLines, newLines) {
107
+ let added = 0;
108
+ let removed = 0;
109
+ for (const op of getOpCodes(oldLines, newLines)) {
110
+ if (op.tag === "d" || op.tag === "r") removed += op.i2 - op.i1;
111
+ if (op.tag === "i" || op.tag === "r") added += op.j2 - op.j1;
112
+ }
113
+ return [added, removed];
114
+ }
115
+ function computeEditDiff(oldString, newString, startLine = 0) {
116
+ const oldLines = splitLines(oldString);
117
+ const newLines = splitLines(newString);
118
+ const [added, removed] = lineDelta(oldLines, newLines);
119
+ const ops = getOpCodes(oldLines, newLines);
120
+ const numbered = startLine > 0;
121
+ const rows = [];
122
+ let truncated = false;
123
+ const push = (row) => {
124
+ if (rows.length >= 100) {
125
+ truncated = true;
126
+ return false;
127
+ }
128
+ rows.push(row);
129
+ return true;
130
+ };
131
+ outer: for (let k = 0; k < ops.length; k++) {
132
+ const op = ops[k];
133
+ if (!op) continue;
134
+ if (op.tag === "e") {
135
+ const len = op.i2 - op.i1;
136
+ const leading = k > 0 ? Math.min(3, len) : 0;
137
+ const trailing = k < ops.length - 1 ? Math.min(3, len) : 0;
138
+ const showAll = len <= leading + trailing;
139
+ const emit = (offset) => {
140
+ const oldNo = op.i1 + offset + 1;
141
+ const newNo = op.j1 + offset + 1;
142
+ return push({
143
+ kind: "ctx",
144
+ text: oldLines[op.i1 + offset] ?? "",
145
+ ...numbered ? {
146
+ oldNo: startLine + oldNo - 1,
147
+ newNo: startLine + newNo - 1
148
+ } : {}
149
+ });
150
+ };
151
+ if (showAll) {
152
+ for (let x = 0; x < len; x++) if (!emit(x)) break outer;
153
+ } else {
154
+ for (let x = 0; x < leading; x++) if (!emit(x)) break outer;
155
+ if (!push({
156
+ kind: "gap",
157
+ text: ""
158
+ })) break;
159
+ for (let x = len - trailing; x < len; x++) if (!emit(x)) break outer;
160
+ }
161
+ continue;
162
+ }
163
+ if (op.tag === "d" || op.tag === "r") {
164
+ for (let x = op.i1; x < op.i2; x++) if (!push({
165
+ kind: "del",
166
+ text: oldLines[x] ?? "",
167
+ ...numbered ? { oldNo: startLine + x } : {}
168
+ })) break outer;
169
+ }
170
+ if (op.tag === "i" || op.tag === "r") {
171
+ const paired = op.tag === "r" ? Math.min(op.i2 - op.i1, op.j2 - op.j1) : 0;
172
+ for (let x = op.j1; x < op.j2; x++) {
173
+ const k = x - op.j1;
174
+ const emphasis = k < paired ? wordEmphasisRanges(oldLines[op.i1 + k] ?? "", newLines[x] ?? "") : null;
175
+ if (!push({
176
+ kind: "add",
177
+ text: newLines[x] ?? "",
178
+ ...numbered ? { newNo: startLine + x } : {},
179
+ ...emphasis ? { emphasis } : {}
180
+ })) break outer;
181
+ }
182
+ }
183
+ }
184
+ return {
185
+ rows,
186
+ added,
187
+ removed,
188
+ truncated
189
+ };
190
+ }
191
+ function computeWriteRows(content) {
192
+ const lines = splitLines(content);
193
+ return {
194
+ rows: lines.slice(0, 50).map((text, i) => ({
195
+ kind: "ctx",
196
+ newNo: i + 1,
197
+ text
198
+ })),
199
+ total: lines.length,
200
+ truncated: lines.length > 50
201
+ };
202
+ }
203
+ function editSummary(toolName, argsJSON) {
204
+ const a = parseEditArgs(argsJSON);
205
+ if (!a) return "";
206
+ const count = (n) => `${n} ${n === 1 ? "line" : "lines"}`;
207
+ if (toolName === "EditFile") {
208
+ const [added, removed] = lineDelta(splitLines(a.old_string ?? ""), splitLines(a.new_string ?? ""));
209
+ if (added > 0 && removed > 0) return `Added ${count(added)}, removed ${count(removed)}`;
210
+ if (added > 0) return `Added ${count(added)}`;
211
+ if (removed > 0) return `Removed ${count(removed)}`;
212
+ return "";
213
+ }
214
+ if (toolName === "WriteFile") {
215
+ if (a.content === void 0) return "";
216
+ let s = `Wrote ${count(splitLines(a.content).length)}`;
217
+ if (a.path) s += ` to ${sanitizeLabel(a.path)}`;
218
+ return s;
219
+ }
220
+ return "";
221
+ }
222
+ //#endregion
223
+ export { MAX_EDIT_DIFF_LINES, MAX_WRITE_DIFF_LINES, computeEditDiff, computeWriteRows, editSummary, isEditDiffTool, lineDelta, parseEditArgs, wordEmphasisRanges };
@@ -0,0 +1,101 @@
1
+ //#region src/ai/agent/diffHighlight.ts
2
+ var EXT_LANG = {
3
+ ts: "typescript",
4
+ tsx: "tsx",
5
+ mts: "typescript",
6
+ cts: "typescript",
7
+ js: "javascript",
8
+ jsx: "jsx",
9
+ mjs: "javascript",
10
+ cjs: "javascript",
11
+ go: "go",
12
+ py: "python",
13
+ rb: "ruby",
14
+ rs: "rust",
15
+ java: "java",
16
+ c: "c",
17
+ h: "c",
18
+ cc: "cpp",
19
+ cpp: "cpp",
20
+ hpp: "cpp",
21
+ cs: "csharp",
22
+ php: "php",
23
+ swift: "swift",
24
+ kt: "kotlin",
25
+ scala: "scala",
26
+ sh: "shellscript",
27
+ bash: "shellscript",
28
+ zsh: "shellscript",
29
+ fish: "fish",
30
+ ps1: "powershell",
31
+ sql: "sql",
32
+ json: "json",
33
+ jsonc: "jsonc",
34
+ yaml: "yaml",
35
+ yml: "yaml",
36
+ toml: "toml",
37
+ xml: "xml",
38
+ html: "html",
39
+ css: "css",
40
+ scss: "scss",
41
+ less: "less",
42
+ md: "markdown",
43
+ mdx: "mdx",
44
+ vue: "vue",
45
+ svelte: "svelte",
46
+ tf: "terraform",
47
+ hcl: "hcl",
48
+ proto: "proto",
49
+ graphql: "graphql",
50
+ gql: "graphql",
51
+ dockerfile: "dockerfile",
52
+ lua: "lua",
53
+ r: "r",
54
+ pl: "perl",
55
+ ex: "elixir",
56
+ exs: "elixir",
57
+ zig: "zig"
58
+ };
59
+ function languageForPath(path) {
60
+ if (!path) return null;
61
+ const base = path.split("/").pop() ?? "";
62
+ if (base.toLowerCase() === "dockerfile") return "dockerfile";
63
+ const dot = base.lastIndexOf(".");
64
+ if (dot <= 0) return null;
65
+ return EXT_LANG[base.slice(dot + 1).toLowerCase()] ?? null;
66
+ }
67
+ var highlighters = /* @__PURE__ */ new Map();
68
+ function getHighlighter(lang) {
69
+ let p = highlighters.get(lang);
70
+ if (!p) {
71
+ p = (async () => {
72
+ const [{ createHighlighter }, { createJavaScriptRegexEngine }] = await Promise.all([import("shiki"), import("shiki/engine/javascript")]);
73
+ return await createHighlighter({
74
+ langs: [lang],
75
+ themes: ["github-light", "github-dark"],
76
+ engine: createJavaScriptRegexEngine({ forgiving: true })
77
+ });
78
+ })().catch(() => null);
79
+ highlighters.set(lang, p);
80
+ }
81
+ return p;
82
+ }
83
+ async function tokenizeDiffLines(lines, lang, isDark) {
84
+ const highlighter = await getHighlighter(lang);
85
+ if (!highlighter) return null;
86
+ try {
87
+ const tokens = highlighter.codeToTokensBase(lines.join("\n"), {
88
+ lang,
89
+ theme: isDark ? "github-dark" : "github-light"
90
+ });
91
+ if (tokens.length !== lines.length) return null;
92
+ return tokens.map((line) => line.map((t) => ({
93
+ content: t.content,
94
+ ...t.color ? { color: t.color } : {}
95
+ })));
96
+ } catch {
97
+ return null;
98
+ }
99
+ }
100
+ //#endregion
101
+ export { languageForPath, tokenizeDiffLines };
@@ -0,0 +1,29 @@
1
+ //#region src/ai/agent/permissions.ts
2
+ var REQUESTABLE_PERMISSION_MODES = [
3
+ "read-only",
4
+ "accept-edits",
5
+ "bypass-permissions"
6
+ ];
7
+ var NAMED_PERMISSION_MODES = [...REQUESTABLE_PERMISSION_MODES, "plan"];
8
+ var DEFAULT_PERMISSION_MODE = "accept-edits";
9
+ var PERMISSION_RANK = {
10
+ "read-only": 0,
11
+ plan: 1,
12
+ "accept-edits": 2,
13
+ "bypass-permissions": 3
14
+ };
15
+ function isNamedPermissionMode(mode) {
16
+ return NAMED_PERMISSION_MODES.some((m) => m === mode);
17
+ }
18
+ /** The daemon clamps a remote request to its owner's remoteMaxPermissionMode,
19
+ * so a menu offers only what that machine will honour. */
20
+ function permissionModesUpTo(ceiling) {
21
+ const max = isNamedPermissionMode(ceiling) ? PERMISSION_RANK[ceiling] : PERMISSION_RANK[DEFAULT_PERMISSION_MODE];
22
+ return REQUESTABLE_PERMISSION_MODES.filter((m) => PERMISSION_RANK[m] <= max);
23
+ }
24
+ function clampPermissionMode(mode, ceiling) {
25
+ const offered = permissionModesUpTo(ceiling);
26
+ return offered.includes(mode) ? mode : offered[offered.length - 1] ?? "read-only";
27
+ }
28
+ //#endregion
29
+ export { DEFAULT_PERMISSION_MODE, NAMED_PERMISSION_MODES, clampPermissionMode, isNamedPermissionMode, permissionModesUpTo };