@molecule/app-ide-react 1.0.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/LICENSE +115 -0
- package/dist/chatTimelineOrdering.d.ts +50 -0
- package/dist/chatTimelineOrdering.d.ts.map +1 -0
- package/dist/chatTimelineOrdering.js +46 -0
- package/dist/chatTimelineOrdering.js.map +1 -0
- package/dist/command-metadata.d.ts +78 -0
- package/dist/command-metadata.d.ts.map +1 -0
- package/dist/command-metadata.js +214 -0
- package/dist/command-metadata.js.map +1 -0
- package/dist/components/ActivityCard.d.ts +28 -0
- package/dist/components/ActivityCard.d.ts.map +1 -0
- package/dist/components/ActivityCard.js +62 -0
- package/dist/components/ActivityCard.js.map +1 -0
- package/dist/components/AutoCommitBadge.d.ts +58 -0
- package/dist/components/AutoCommitBadge.d.ts.map +1 -0
- package/dist/components/AutoCommitBadge.js +78 -0
- package/dist/components/AutoCommitBadge.js.map +1 -0
- package/dist/components/ChatPanel.d.ts +184 -0
- package/dist/components/ChatPanel.d.ts.map +1 -0
- package/dist/components/ChatPanel.js +6691 -0
- package/dist/components/ChatPanel.js.map +1 -0
- package/dist/components/CommandPalette.d.ts +18 -0
- package/dist/components/CommandPalette.d.ts.map +1 -0
- package/dist/components/CommandPalette.js +33 -0
- package/dist/components/CommandPalette.js.map +1 -0
- package/dist/components/DeviceFrameSelector.d.ts +60 -0
- package/dist/components/DeviceFrameSelector.d.ts.map +1 -0
- package/dist/components/DeviceFrameSelector.js +230 -0
- package/dist/components/DeviceFrameSelector.js.map +1 -0
- package/dist/components/EditorPanel.d.ts +17 -0
- package/dist/components/EditorPanel.d.ts.map +1 -0
- package/dist/components/EditorPanel.js +241 -0
- package/dist/components/EditorPanel.js.map +1 -0
- package/dist/components/FileExplorer.d.ts +64 -0
- package/dist/components/FileExplorer.d.ts.map +1 -0
- package/dist/components/FileExplorer.js +1111 -0
- package/dist/components/FileExplorer.js.map +1 -0
- package/dist/components/FileExplorerContextMenu.d.ts +37 -0
- package/dist/components/FileExplorerContextMenu.d.ts.map +1 -0
- package/dist/components/FileExplorerContextMenu.js +241 -0
- package/dist/components/FileExplorerContextMenu.js.map +1 -0
- package/dist/components/HelpCard.d.ts +34 -0
- package/dist/components/HelpCard.d.ts.map +1 -0
- package/dist/components/HelpCard.js +28 -0
- package/dist/components/HelpCard.js.map +1 -0
- package/dist/components/Icon.d.ts +50 -0
- package/dist/components/Icon.d.ts.map +1 -0
- package/dist/components/Icon.js +25 -0
- package/dist/components/Icon.js.map +1 -0
- package/dist/components/KeyboardShortcutsPanel.d.ts +19 -0
- package/dist/components/KeyboardShortcutsPanel.d.ts.map +1 -0
- package/dist/components/KeyboardShortcutsPanel.js +187 -0
- package/dist/components/KeyboardShortcutsPanel.js.map +1 -0
- package/dist/components/MarkdownContent.d.ts +52 -0
- package/dist/components/MarkdownContent.d.ts.map +1 -0
- package/dist/components/MarkdownContent.js +303 -0
- package/dist/components/MarkdownContent.js.map +1 -0
- package/dist/components/ModelsTable.d.ts +38 -0
- package/dist/components/ModelsTable.d.ts.map +1 -0
- package/dist/components/ModelsTable.js +96 -0
- package/dist/components/ModelsTable.js.map +1 -0
- package/dist/components/PreviewPanel.d.ts +66 -0
- package/dist/components/PreviewPanel.d.ts.map +1 -0
- package/dist/components/PreviewPanel.js +1752 -0
- package/dist/components/PreviewPanel.js.map +1 -0
- package/dist/components/QuickOpen.d.ts +20 -0
- package/dist/components/QuickOpen.d.ts.map +1 -0
- package/dist/components/QuickOpen.js +72 -0
- package/dist/components/QuickOpen.js.map +1 -0
- package/dist/components/QuickPicker.d.ts +21 -0
- package/dist/components/QuickPicker.d.ts.map +1 -0
- package/dist/components/QuickPicker.js +174 -0
- package/dist/components/QuickPicker.js.map +1 -0
- package/dist/components/RelevantSkillSuggestion.d.ts +41 -0
- package/dist/components/RelevantSkillSuggestion.d.ts.map +1 -0
- package/dist/components/RelevantSkillSuggestion.js +85 -0
- package/dist/components/RelevantSkillSuggestion.js.map +1 -0
- package/dist/components/ReportModal.d.ts +35 -0
- package/dist/components/ReportModal.d.ts.map +1 -0
- package/dist/components/ReportModal.js +112 -0
- package/dist/components/ReportModal.js.map +1 -0
- package/dist/components/ResizeHandle.d.ts +21 -0
- package/dist/components/ResizeHandle.d.ts.map +1 -0
- package/dist/components/ResizeHandle.js +109 -0
- package/dist/components/ResizeHandle.js.map +1 -0
- package/dist/components/ScriptsCard.d.ts +37 -0
- package/dist/components/ScriptsCard.d.ts.map +1 -0
- package/dist/components/ScriptsCard.js +177 -0
- package/dist/components/ScriptsCard.js.map +1 -0
- package/dist/components/SearchPanel.d.ts +18 -0
- package/dist/components/SearchPanel.d.ts.map +1 -0
- package/dist/components/SearchPanel.js +449 -0
- package/dist/components/SearchPanel.js.map +1 -0
- package/dist/components/SettingsCard.d.ts +49 -0
- package/dist/components/SettingsCard.d.ts.map +1 -0
- package/dist/components/SettingsCard.js +59 -0
- package/dist/components/SettingsCard.js.map +1 -0
- package/dist/components/ShareModal.d.ts +32 -0
- package/dist/components/ShareModal.d.ts.map +1 -0
- package/dist/components/ShareModal.js +126 -0
- package/dist/components/ShareModal.js.map +1 -0
- package/dist/components/SidebarTabs.d.ts +18 -0
- package/dist/components/SidebarTabs.d.ts.map +1 -0
- package/dist/components/SidebarTabs.js +20 -0
- package/dist/components/SidebarTabs.js.map +1 -0
- package/dist/components/SkillsCard.d.ts +86 -0
- package/dist/components/SkillsCard.d.ts.map +1 -0
- package/dist/components/SkillsCard.js +227 -0
- package/dist/components/SkillsCard.js.map +1 -0
- package/dist/components/StreamingIndicator.d.ts +50 -0
- package/dist/components/StreamingIndicator.d.ts.map +1 -0
- package/dist/components/StreamingIndicator.js +142 -0
- package/dist/components/StreamingIndicator.js.map +1 -0
- package/dist/components/TabBar.d.ts +37 -0
- package/dist/components/TabBar.d.ts.map +1 -0
- package/dist/components/TabBar.js +187 -0
- package/dist/components/TabBar.js.map +1 -0
- package/dist/components/TipCard.d.ts +22 -0
- package/dist/components/TipCard.d.ts.map +1 -0
- package/dist/components/TipCard.js +73 -0
- package/dist/components/TipCard.js.map +1 -0
- package/dist/components/ToolCallCard.d.ts +18 -0
- package/dist/components/ToolCallCard.d.ts.map +1 -0
- package/dist/components/ToolCallCard.js +716 -0
- package/dist/components/ToolCallCard.js.map +1 -0
- package/dist/components/UserAvatar.d.ts +45 -0
- package/dist/components/UserAvatar.d.ts.map +1 -0
- package/dist/components/UserAvatar.js +80 -0
- package/dist/components/UserAvatar.js.map +1 -0
- package/dist/components/WorkspaceLayout.d.ts +19 -0
- package/dist/components/WorkspaceLayout.d.ts.map +1 -0
- package/dist/components/WorkspaceLayout.js +56 -0
- package/dist/components/WorkspaceLayout.js.map +1 -0
- package/dist/components/activity-utilities.d.ts +107 -0
- package/dist/components/activity-utilities.d.ts.map +1 -0
- package/dist/components/activity-utilities.js +154 -0
- package/dist/components/activity-utilities.js.map +1 -0
- package/dist/components/chat-autocommit-utilities.d.ts +172 -0
- package/dist/components/chat-autocommit-utilities.d.ts.map +1 -0
- package/dist/components/chat-autocommit-utilities.js +185 -0
- package/dist/components/chat-autocommit-utilities.js.map +1 -0
- package/dist/components/chat-card-style.d.ts +64 -0
- package/dist/components/chat-card-style.d.ts.map +1 -0
- package/dist/components/chat-card-style.js +74 -0
- package/dist/components/chat-card-style.js.map +1 -0
- package/dist/components/chat-commands.d.ts +17 -0
- package/dist/components/chat-commands.d.ts.map +1 -0
- package/dist/components/chat-commands.js +17 -0
- package/dist/components/chat-commands.js.map +1 -0
- package/dist/components/chat-commit-utilities.d.ts +29 -0
- package/dist/components/chat-commit-utilities.d.ts.map +1 -0
- package/dist/components/chat-commit-utilities.js +31 -0
- package/dist/components/chat-commit-utilities.js.map +1 -0
- package/dist/components/chat-cost-utilities.d.ts +62 -0
- package/dist/components/chat-cost-utilities.d.ts.map +1 -0
- package/dist/components/chat-cost-utilities.js +66 -0
- package/dist/components/chat-cost-utilities.js.map +1 -0
- package/dist/components/chat-effort-utilities.d.ts +96 -0
- package/dist/components/chat-effort-utilities.d.ts.map +1 -0
- package/dist/components/chat-effort-utilities.js +97 -0
- package/dist/components/chat-effort-utilities.js.map +1 -0
- package/dist/components/chat-help-utilities.d.ts +89 -0
- package/dist/components/chat-help-utilities.d.ts.map +1 -0
- package/dist/components/chat-help-utilities.js +131 -0
- package/dist/components/chat-help-utilities.js.map +1 -0
- package/dist/components/chat-model-mode-utilities.d.ts +143 -0
- package/dist/components/chat-model-mode-utilities.d.ts.map +1 -0
- package/dist/components/chat-model-mode-utilities.js +191 -0
- package/dist/components/chat-model-mode-utilities.js.map +1 -0
- package/dist/components/chat-models-utilities.d.ts +98 -0
- package/dist/components/chat-models-utilities.d.ts.map +1 -0
- package/dist/components/chat-models-utilities.js +136 -0
- package/dist/components/chat-models-utilities.js.map +1 -0
- package/dist/components/chat-report-utilities.d.ts +149 -0
- package/dist/components/chat-report-utilities.d.ts.map +1 -0
- package/dist/components/chat-report-utilities.js +151 -0
- package/dist/components/chat-report-utilities.js.map +1 -0
- package/dist/components/chat-scripts-utilities.d.ts +140 -0
- package/dist/components/chat-scripts-utilities.d.ts.map +1 -0
- package/dist/components/chat-scripts-utilities.js +158 -0
- package/dist/components/chat-scripts-utilities.js.map +1 -0
- package/dist/components/chat-settings-utilities.d.ts +72 -0
- package/dist/components/chat-settings-utilities.d.ts.map +1 -0
- package/dist/components/chat-settings-utilities.js +56 -0
- package/dist/components/chat-settings-utilities.js.map +1 -0
- package/dist/components/chat-share-utilities.d.ts +104 -0
- package/dist/components/chat-share-utilities.d.ts.map +1 -0
- package/dist/components/chat-share-utilities.js +90 -0
- package/dist/components/chat-share-utilities.js.map +1 -0
- package/dist/components/chat-skills-utilities.d.ts +242 -0
- package/dist/components/chat-skills-utilities.d.ts.map +1 -0
- package/dist/components/chat-skills-utilities.js +433 -0
- package/dist/components/chat-skills-utilities.js.map +1 -0
- package/dist/components/chat-stream-utilities.d.ts +74 -0
- package/dist/components/chat-stream-utilities.d.ts.map +1 -0
- package/dist/components/chat-stream-utilities.js +103 -0
- package/dist/components/chat-stream-utilities.js.map +1 -0
- package/dist/components/chat-tips-utilities.d.ts +108 -0
- package/dist/components/chat-tips-utilities.d.ts.map +1 -0
- package/dist/components/chat-tips-utilities.js +137 -0
- package/dist/components/chat-tips-utilities.js.map +1 -0
- package/dist/components/device-cycle.d.ts +84 -0
- package/dist/components/device-cycle.d.ts.map +1 -0
- package/dist/components/device-cycle.js +77 -0
- package/dist/components/device-cycle.js.map +1 -0
- package/dist/components/index.d.ts +36 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +33 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/tool-call-utilities.d.ts +69 -0
- package/dist/components/tool-call-utilities.d.ts.map +1 -0
- package/dist/components/tool-call-utilities.js +368 -0
- package/dist/components/tool-call-utilities.js.map +1 -0
- package/dist/components/user-avatar-utilities.d.ts +41 -0
- package/dist/components/user-avatar-utilities.d.ts.map +1 -0
- package/dist/components/user-avatar-utilities.js +56 -0
- package/dist/components/user-avatar-utilities.js.map +1 -0
- package/dist/components/workspace-layout-utilities.d.ts +37 -0
- package/dist/components/workspace-layout-utilities.d.ts.map +1 -0
- package/dist/components/workspace-layout-utilities.js +58 -0
- package/dist/components/workspace-layout-utilities.js.map +1 -0
- package/dist/customEventCards.d.ts +117 -0
- package/dist/customEventCards.d.ts.map +1 -0
- package/dist/customEventCards.js +36 -0
- package/dist/customEventCards.js.map +1 -0
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useKeyboardShortcuts.d.ts +48 -0
- package/dist/hooks/useKeyboardShortcuts.d.ts.map +1 -0
- package/dist/hooks/useKeyboardShortcuts.js +112 -0
- package/dist/hooks/useKeyboardShortcuts.js.map +1 -0
- package/dist/hooks/useViewport.d.ts +42 -0
- package/dist/hooks/useViewport.d.ts.map +1 -0
- package/dist/hooks/useViewport.js +61 -0
- package/dist/hooks/useViewport.js.map +1 -0
- package/dist/index.d.ts +75 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/settings-metadata.d.ts +78 -0
- package/dist/settings-metadata.d.ts.map +1 -0
- package/dist/settings-metadata.js +131 -0
- package/dist/settings-metadata.js.map +1 -0
- package/dist/types.d.ts +751 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +25 -0
- package/dist/types.js.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure utility functions for tool call display.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from ToolCallCard for testability — these functions have no
|
|
5
|
+
* React dependencies and can be unit-tested directly.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import { t } from '@molecule/app-i18n';
|
|
10
|
+
/**
|
|
11
|
+
* Extracts the last path segment from a file path (e.g. "a/b/c.ts" → "c.ts").
|
|
12
|
+
* @param path - The file path to extract the basename from.
|
|
13
|
+
* @returns The basename string, or empty string if path is undefined.
|
|
14
|
+
*/
|
|
15
|
+
export function basename(path) {
|
|
16
|
+
if (!path)
|
|
17
|
+
return '';
|
|
18
|
+
return path.split('/').pop() ?? path;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Path of a `@molecule/*` package's MOLECULE.md inside the sandbox, where every
|
|
22
|
+
* package is pre-installed. Used by the find_package / read_molecule_doc cards
|
|
23
|
+
* so clicking a package opens its docs in the editor.
|
|
24
|
+
* @param packageName - The package name, with or without the `@molecule/` prefix.
|
|
25
|
+
* @returns The absolute sandbox path to the package's MOLECULE.md, or null for
|
|
26
|
+
* a name that isn't a plain molecule package slug.
|
|
27
|
+
*/
|
|
28
|
+
export function moleculeDocPath(packageName) {
|
|
29
|
+
if (!packageName)
|
|
30
|
+
return null;
|
|
31
|
+
const bare = packageName.trim().replace(/^@molecule\//, '');
|
|
32
|
+
if (!/^[a-z0-9-]+$/.test(bare))
|
|
33
|
+
return null;
|
|
34
|
+
return `/workspace/node_modules/@molecule/${bare}/MOLECULE.md`;
|
|
35
|
+
}
|
|
36
|
+
/** Truncate a string to `max` characters with a trailing ellipsis. */
|
|
37
|
+
function truncate(value, max = 60) {
|
|
38
|
+
return value.length > max ? `${value.slice(0, max)}…` : value;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Human-readable label for a tool call (e.g. "Edit `ChatPanel.tsx`").
|
|
42
|
+
* @param name - The tool name (e.g. "write_file", "exec_command").
|
|
43
|
+
* @param input - The raw tool input payload.
|
|
44
|
+
* @returns A formatted label string with backtick-wrapped filenames.
|
|
45
|
+
*/
|
|
46
|
+
export function toolLabel(name, input) {
|
|
47
|
+
const inp = (input ?? {});
|
|
48
|
+
const path = inp.path;
|
|
49
|
+
const cmd = inp.command;
|
|
50
|
+
const pattern = inp.pattern;
|
|
51
|
+
const url = inp.url;
|
|
52
|
+
// Wrap a value in a leading-space + backticks, or return '' when it's empty.
|
|
53
|
+
// While a tool call streams, its input arrives a beat after the block is
|
|
54
|
+
// created, so path/pattern/command are briefly undefined — emitting `Read ``
|
|
55
|
+
// (empty backticks) flashed before the real filename. Drop the backticks
|
|
56
|
+
// entirely until there's a value, so the label reads "Read" then "Read `x.ts`".
|
|
57
|
+
const code = (value) => (value ? ` \`${value}\`` : '');
|
|
58
|
+
switch (name) {
|
|
59
|
+
case 'list_files':
|
|
60
|
+
return `List${code(basename(path) || 'project')}`;
|
|
61
|
+
case 'read_file':
|
|
62
|
+
return `Read${code(basename(path))}`;
|
|
63
|
+
case 'write_file':
|
|
64
|
+
return `Write${code(basename(path))}`;
|
|
65
|
+
case 'edit_file':
|
|
66
|
+
return `Edit${code(basename(path))}`;
|
|
67
|
+
case 'search_files':
|
|
68
|
+
return `Search${code(pattern ?? '')}`;
|
|
69
|
+
case 'create_directory':
|
|
70
|
+
return `Create dir${code(basename(path))}`;
|
|
71
|
+
case 'rename_file':
|
|
72
|
+
return `Rename${code(basename(inp.old_path))}`;
|
|
73
|
+
case 'delete_file':
|
|
74
|
+
return `Delete${code(basename(path))}`;
|
|
75
|
+
case 'find_files':
|
|
76
|
+
return `Find${code(pattern ?? '')}`;
|
|
77
|
+
case 'load_skill':
|
|
78
|
+
return `Load skill${code(inp.name ?? '')}`;
|
|
79
|
+
case 'find_package': {
|
|
80
|
+
const query = inp.query ?? inp.category;
|
|
81
|
+
return `Find package${code(query ?? '')}`;
|
|
82
|
+
}
|
|
83
|
+
case 'read_molecule_doc': {
|
|
84
|
+
const pkg = inp.name?.trim().replace(/^@molecule\//, '');
|
|
85
|
+
return `Read docs${code(pkg ? `@molecule/${pkg}` : '')}`;
|
|
86
|
+
}
|
|
87
|
+
case 'web_fetch': {
|
|
88
|
+
try {
|
|
89
|
+
return `Fetch ${new URL(url ?? '').hostname}`;
|
|
90
|
+
}
|
|
91
|
+
catch (_error) {
|
|
92
|
+
// URL parsing failed (malformed/empty URL) — fall back to raw URL string, safe to ignore.
|
|
93
|
+
return `Fetch ${url ?? ''}`;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
case 'exec_command': {
|
|
97
|
+
return `Bash${code(truncate(cmd ?? ''))}`;
|
|
98
|
+
}
|
|
99
|
+
case 'sandbox_fetch': {
|
|
100
|
+
// The interesting part is WHICH endpoint (usually one the model just built) —
|
|
101
|
+
// show method + protocol-stripped URL, e.g. "GET `localhost:4000/api/todos`".
|
|
102
|
+
const method = (inp.method ?? 'GET').toUpperCase();
|
|
103
|
+
const compact = (url ?? '').replace(/^https?:\/\//, '').replace(/\/$/, '');
|
|
104
|
+
return `${method}${code(truncate(compact))}`;
|
|
105
|
+
}
|
|
106
|
+
case 'navigate_preview':
|
|
107
|
+
return `Go to${code(inp.path ?? '')}`;
|
|
108
|
+
case 'open_file':
|
|
109
|
+
return `Open${code(basename(path))}`;
|
|
110
|
+
case 'reload_preview':
|
|
111
|
+
return 'Reload preview';
|
|
112
|
+
case 'restart_preview':
|
|
113
|
+
return inp.restart === true ? 'Restart preview servers' : 'Start preview servers';
|
|
114
|
+
case 'read_preview_ui':
|
|
115
|
+
return 'Inspect preview';
|
|
116
|
+
case 'interact_preview': {
|
|
117
|
+
// Target priority mirrors the tool's own: molId is canonical, text is the
|
|
118
|
+
// visible name (usually the most readable), selector is the last resort.
|
|
119
|
+
// Deliberately NEVER show `value` — fill routinely types credentials.
|
|
120
|
+
const target = inp.text ??
|
|
121
|
+
inp.molId ??
|
|
122
|
+
inp.selector ??
|
|
123
|
+
'';
|
|
124
|
+
const verb = { click: 'Click', fill: 'Fill', select: 'Select', waitFor: 'Wait for' }[inp.action];
|
|
125
|
+
return verb ? `${verb}${code(truncate(target, 40))}` : `Interact${code(truncate(target, 40))}`;
|
|
126
|
+
}
|
|
127
|
+
case 'get_ide_state':
|
|
128
|
+
return 'Check IDE status';
|
|
129
|
+
case 'read_logs': {
|
|
130
|
+
const source = inp.source ?? '';
|
|
131
|
+
const filter = inp.filter ?? '';
|
|
132
|
+
const which = source && source !== 'all' ? `Read ${source} logs` : 'Read logs';
|
|
133
|
+
return `${which}${code(truncate(filter, 30))}`;
|
|
134
|
+
}
|
|
135
|
+
case 'find_example':
|
|
136
|
+
return `Find example${code(truncate(inp.query ?? '', 40))}`;
|
|
137
|
+
case 'save_script':
|
|
138
|
+
return `Save script${code(inp.name ?? '')}`;
|
|
139
|
+
case 'request_repo_import':
|
|
140
|
+
return 'Import repository';
|
|
141
|
+
case 'web_search':
|
|
142
|
+
return `Search web${code(truncate(inp.query ?? '', 40))}`;
|
|
143
|
+
case 'save_plan': {
|
|
144
|
+
const planName = inp.name ?? '';
|
|
145
|
+
return planName ? `Save plan \`${planName}\`` : 'Save plan';
|
|
146
|
+
}
|
|
147
|
+
case 'set_mode': {
|
|
148
|
+
const targetMode = inp.mode ?? '';
|
|
149
|
+
return targetMode ? `Switch to ${targetMode} mode` : 'Switch mode';
|
|
150
|
+
}
|
|
151
|
+
case 'ask_user':
|
|
152
|
+
return inp.question ?? 'Question';
|
|
153
|
+
default: {
|
|
154
|
+
const label = name.replace(/_/g, ' ');
|
|
155
|
+
// Salient-argument fallback for tools without an explicit case: nearly every
|
|
156
|
+
// tool has ONE short string input that carries its intent — show the first
|
|
157
|
+
// one present so a new tool never renders as a bare name. Never dump JSON.
|
|
158
|
+
const salient = [path, url, inp.query, inp.name, pattern, cmd, inp.source, inp.text].find((v) => typeof v === 'string' && v.trim() !== '');
|
|
159
|
+
return (label.charAt(0).toUpperCase() + label.slice(1) + code(salient ? truncate(salient, 40) : ''));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* One-line result summary shown beneath the label.
|
|
165
|
+
* @param name - The tool name.
|
|
166
|
+
* @param output - The raw tool output payload.
|
|
167
|
+
* @param status - The execution status (pending, running, done, error).
|
|
168
|
+
* @returns A brief summary string describing the result.
|
|
169
|
+
*/
|
|
170
|
+
export function toolSummary(name, output, status) {
|
|
171
|
+
if (status === 'pending')
|
|
172
|
+
return '';
|
|
173
|
+
if (status === 'running')
|
|
174
|
+
return t('ide.toolCall.statusRunning', undefined, { defaultValue: 'Running' });
|
|
175
|
+
const out = output;
|
|
176
|
+
const hasError = typeof out === 'object' && out !== null && 'error' in out;
|
|
177
|
+
if (hasError) {
|
|
178
|
+
const msg = (out.error ?? '').toLowerCase();
|
|
179
|
+
if (msg.includes('not found') || msg.includes('no such file'))
|
|
180
|
+
return t('ide.toolCall.statusNotFound', undefined, { defaultValue: 'Not found' });
|
|
181
|
+
if (msg.includes('permission') || msg.includes('access denied'))
|
|
182
|
+
return t('ide.toolCall.statusPermissionDenied', undefined, {
|
|
183
|
+
defaultValue: 'Permission denied',
|
|
184
|
+
});
|
|
185
|
+
return t('ide.toolCall.statusFailed', undefined, { defaultValue: 'Failed' });
|
|
186
|
+
}
|
|
187
|
+
switch (name) {
|
|
188
|
+
case 'write_file': {
|
|
189
|
+
const diff = out
|
|
190
|
+
?.diff;
|
|
191
|
+
if (!diff)
|
|
192
|
+
return '';
|
|
193
|
+
if (diff.type === 'unchanged')
|
|
194
|
+
return t('ide.toolCall.statusUnchanged', undefined, { defaultValue: 'Unchanged' });
|
|
195
|
+
return '';
|
|
196
|
+
}
|
|
197
|
+
case 'edit_file':
|
|
198
|
+
return '';
|
|
199
|
+
case 'list_files': {
|
|
200
|
+
const entries = out?.entries;
|
|
201
|
+
return entries != null
|
|
202
|
+
? t('ide.toolCall.entryCount', { count: entries.length }, {
|
|
203
|
+
defaultValue: '{{count}} entries',
|
|
204
|
+
})
|
|
205
|
+
: '';
|
|
206
|
+
}
|
|
207
|
+
case 'read_file':
|
|
208
|
+
return '';
|
|
209
|
+
case 'search_files': {
|
|
210
|
+
const matches = out?.matches;
|
|
211
|
+
return matches != null
|
|
212
|
+
? t('ide.toolCall.matchCount', { count: matches.length }, {
|
|
213
|
+
defaultValue: '{{count}} matches',
|
|
214
|
+
})
|
|
215
|
+
: '';
|
|
216
|
+
}
|
|
217
|
+
case 'find_files': {
|
|
218
|
+
const files = out?.files;
|
|
219
|
+
return files != null
|
|
220
|
+
? t('ide.toolCall.fileCount', { count: files.length }, {
|
|
221
|
+
defaultValue: '{{count}} files',
|
|
222
|
+
})
|
|
223
|
+
: '';
|
|
224
|
+
}
|
|
225
|
+
case 'create_directory':
|
|
226
|
+
return '';
|
|
227
|
+
case 'rename_file':
|
|
228
|
+
return '';
|
|
229
|
+
case 'delete_file':
|
|
230
|
+
return '';
|
|
231
|
+
case 'web_fetch':
|
|
232
|
+
case 'sandbox_fetch': {
|
|
233
|
+
const status_ = out?.status;
|
|
234
|
+
if (status_ == null)
|
|
235
|
+
return '';
|
|
236
|
+
if (status_ >= 200 && status_ < 300)
|
|
237
|
+
return '';
|
|
238
|
+
if (status_ === 404)
|
|
239
|
+
return t('ide.toolCall.statusNotFound', undefined, { defaultValue: 'Not found' });
|
|
240
|
+
if (status_ >= 400 && status_ < 500)
|
|
241
|
+
return t('ide.toolCall.statusFailed', undefined, { defaultValue: 'Failed' });
|
|
242
|
+
if (status_ >= 500)
|
|
243
|
+
return t('ide.toolCall.statusServerError', undefined, { defaultValue: 'Server error' });
|
|
244
|
+
return '';
|
|
245
|
+
}
|
|
246
|
+
case 'navigate_preview':
|
|
247
|
+
case 'interact_preview': {
|
|
248
|
+
// The snapshot's url is where the app actually landed — an auth-guard
|
|
249
|
+
// redirect is exactly what the user wants to see at a glance.
|
|
250
|
+
const landed = out?.url;
|
|
251
|
+
if (typeof landed !== 'string' || !landed)
|
|
252
|
+
return '';
|
|
253
|
+
try {
|
|
254
|
+
const u = new URL(landed);
|
|
255
|
+
return u.pathname + u.search;
|
|
256
|
+
}
|
|
257
|
+
catch (_error) {
|
|
258
|
+
// Not an absolute URL (already a path or malformed) — show it as-is.
|
|
259
|
+
return landed;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
case 'exec_command': {
|
|
263
|
+
const exitCode = out?.exitCode;
|
|
264
|
+
return exitCode != null && exitCode !== 0
|
|
265
|
+
? t('ide.toolCall.statusFailed', undefined, { defaultValue: 'Failed' })
|
|
266
|
+
: '';
|
|
267
|
+
}
|
|
268
|
+
case 'find_package': {
|
|
269
|
+
const found = out?.found;
|
|
270
|
+
if (found == null)
|
|
271
|
+
return '';
|
|
272
|
+
if (found === 0)
|
|
273
|
+
return t('ide.toolCall.noMatches', undefined, { defaultValue: 'No matches' });
|
|
274
|
+
return t('ide.toolCall.packageCount', { count: found }, { defaultValue: '{{count}} packages' });
|
|
275
|
+
}
|
|
276
|
+
case 'ask_user': {
|
|
277
|
+
if (typeof out === 'string')
|
|
278
|
+
return out;
|
|
279
|
+
const askOut = out;
|
|
280
|
+
if (askOut?.status === 'awaiting_response')
|
|
281
|
+
return '';
|
|
282
|
+
return '';
|
|
283
|
+
}
|
|
284
|
+
default:
|
|
285
|
+
return '';
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Count truly added/removed lines between two line arrays using LCS.
|
|
290
|
+
* @param oldLines - The original lines array.
|
|
291
|
+
* @param newLines - The modified lines array.
|
|
292
|
+
* @returns An object with the number of added and removed lines.
|
|
293
|
+
*/
|
|
294
|
+
export function diffLineCount(oldLines, newLines) {
|
|
295
|
+
const n = oldLines.length;
|
|
296
|
+
const m = newLines.length;
|
|
297
|
+
const dp = Array.from({ length: n + 1 }, () => Array(m + 1).fill(0));
|
|
298
|
+
for (let i = 1; i <= n; i++) {
|
|
299
|
+
for (let j = 1; j <= m; j++) {
|
|
300
|
+
dp[i][j] =
|
|
301
|
+
oldLines[i - 1] === newLines[j - 1]
|
|
302
|
+
? dp[i - 1][j - 1] + 1
|
|
303
|
+
: Math.max(dp[i - 1][j], dp[i][j - 1]);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
const common = dp[n][m];
|
|
307
|
+
return { added: m - common, removed: n - common };
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Compute lines added/removed from a file-changing tool call.
|
|
311
|
+
* @param name - The tool name (edit_file or write_file).
|
|
312
|
+
* @param input - The raw tool input payload.
|
|
313
|
+
* @param output - The raw tool output payload.
|
|
314
|
+
* @returns Diff stats with added and removed line counts, or null if not applicable.
|
|
315
|
+
*/
|
|
316
|
+
export function fileDiffStats(name, input, output) {
|
|
317
|
+
if (name === 'edit_file') {
|
|
318
|
+
const inp = (input ?? {});
|
|
319
|
+
const replacements = Array.isArray(inp.replacements)
|
|
320
|
+
? inp.replacements
|
|
321
|
+
: [];
|
|
322
|
+
if (replacements.length === 0)
|
|
323
|
+
return null;
|
|
324
|
+
let added = 0;
|
|
325
|
+
let removed = 0;
|
|
326
|
+
for (const r of replacements) {
|
|
327
|
+
if (typeof r.old_string !== 'string' || typeof r.new_string !== 'string')
|
|
328
|
+
continue;
|
|
329
|
+
const d = diffLineCount(r.old_string.split('\n'), r.new_string.split('\n'));
|
|
330
|
+
added += d.added;
|
|
331
|
+
removed += d.removed;
|
|
332
|
+
}
|
|
333
|
+
return { added, removed };
|
|
334
|
+
}
|
|
335
|
+
if (name === 'write_file') {
|
|
336
|
+
const diff = output?.diff;
|
|
337
|
+
if (!diff || diff.type === 'unchanged')
|
|
338
|
+
return null;
|
|
339
|
+
if (diff.type === 'new')
|
|
340
|
+
return { added: diff.linesAdded, removed: 0 };
|
|
341
|
+
return { added: diff.linesAdded, removed: diff.linesRemoved };
|
|
342
|
+
}
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Extracts the primary file path from a tool's input, if it operates on a single file.
|
|
347
|
+
* @param name - The tool name.
|
|
348
|
+
* @param input - The raw tool input payload.
|
|
349
|
+
* @returns The file path string, or null if the tool doesn't target a single file.
|
|
350
|
+
*/
|
|
351
|
+
export function extractFilePath(name, input) {
|
|
352
|
+
const inp = (input ?? {});
|
|
353
|
+
switch (name) {
|
|
354
|
+
case 'read_file':
|
|
355
|
+
case 'write_file':
|
|
356
|
+
case 'edit_file':
|
|
357
|
+
case 'open_file':
|
|
358
|
+
return inp.path || null;
|
|
359
|
+
case 'rename_file':
|
|
360
|
+
return inp.new_path || null;
|
|
361
|
+
case 'read_molecule_doc':
|
|
362
|
+
// Clicking the card opens the package's MOLECULE.md (pre-installed in the sandbox).
|
|
363
|
+
return moleculeDocPath(inp.name);
|
|
364
|
+
default:
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
//# sourceMappingURL=tool-call-utilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-call-utilities.js","sourceRoot":"","sources":["../../src/components/tool-call-utilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe resolution of a user's profile avatar for rendering in the chat timeline
|
|
3
|
+
* (SOC1).
|
|
4
|
+
*
|
|
5
|
+
* The IDE chat renders the signed-in user's real avatar — an inline
|
|
6
|
+
* `data:image/*` URI or a remote `http(s)` URL from the user's profile metadata
|
|
7
|
+
* — in place of a generic person glyph on their own messages. This module is the
|
|
8
|
+
* single, package-owned source of truth for deciding whether a stored avatar
|
|
9
|
+
* value is a SAFE, renderable `<img src>`.
|
|
10
|
+
*
|
|
11
|
+
* It lives in the package (not the host) on purpose: the package owns the render,
|
|
12
|
+
* so it must own the safety gate — a host that wires {@link ChatPanelProps.userAvatar}
|
|
13
|
+
* gets correct, attack-resistant behavior for free and does not need to ship its
|
|
14
|
+
* own copy. The host stays decoupled: it passes whatever string it has, and this
|
|
15
|
+
* helper — not the host — decides what reaches the DOM.
|
|
16
|
+
*
|
|
17
|
+
* Safety: only `data:image/*` URIs and `http(s)` URLs are accepted, so a
|
|
18
|
+
* `javascript:` (or other-scheme) value can never become an `<img src>`, and an
|
|
19
|
+
* oversized blob is rejected. Anything else resolves to `null`, which signals the
|
|
20
|
+
* caller to fall back to the generic icon.
|
|
21
|
+
*
|
|
22
|
+
* @module
|
|
23
|
+
*/
|
|
24
|
+
/** Maximum avatar source length we will render inline (~256 KB data-URI). */
|
|
25
|
+
export declare const MAX_AVATAR_SRC_LENGTH = 262144;
|
|
26
|
+
/**
|
|
27
|
+
* Resolve a stored avatar value to a safe `<img>` src, or `null` to fall back to
|
|
28
|
+
* the generic icon.
|
|
29
|
+
*
|
|
30
|
+
* @param avatar - The avatar value from user metadata (data-URI, URL, or absent).
|
|
31
|
+
* @returns A safe image src string, or `null` when there is no renderable avatar.
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveUserAvatar(avatar?: string | null): string | null;
|
|
34
|
+
/**
|
|
35
|
+
* Whether a stored avatar value is renderable (vs. needing the icon fallback).
|
|
36
|
+
*
|
|
37
|
+
* @param avatar - The avatar value from user metadata.
|
|
38
|
+
* @returns `true` when {@link resolveUserAvatar} would return a src.
|
|
39
|
+
*/
|
|
40
|
+
export declare function hasRenderableAvatar(avatar?: string | null): boolean;
|
|
41
|
+
//# sourceMappingURL=user-avatar-utilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-avatar-utilities.d.ts","sourceRoot":"","sources":["../../src/components/user-avatar-utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,SAAU,CAAA;AAQ5C;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAMvE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAEnE"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe resolution of a user's profile avatar for rendering in the chat timeline
|
|
3
|
+
* (SOC1).
|
|
4
|
+
*
|
|
5
|
+
* The IDE chat renders the signed-in user's real avatar — an inline
|
|
6
|
+
* `data:image/*` URI or a remote `http(s)` URL from the user's profile metadata
|
|
7
|
+
* — in place of a generic person glyph on their own messages. This module is the
|
|
8
|
+
* single, package-owned source of truth for deciding whether a stored avatar
|
|
9
|
+
* value is a SAFE, renderable `<img src>`.
|
|
10
|
+
*
|
|
11
|
+
* It lives in the package (not the host) on purpose: the package owns the render,
|
|
12
|
+
* so it must own the safety gate — a host that wires {@link ChatPanelProps.userAvatar}
|
|
13
|
+
* gets correct, attack-resistant behavior for free and does not need to ship its
|
|
14
|
+
* own copy. The host stays decoupled: it passes whatever string it has, and this
|
|
15
|
+
* helper — not the host — decides what reaches the DOM.
|
|
16
|
+
*
|
|
17
|
+
* Safety: only `data:image/*` URIs and `http(s)` URLs are accepted, so a
|
|
18
|
+
* `javascript:` (or other-scheme) value can never become an `<img src>`, and an
|
|
19
|
+
* oversized blob is rejected. Anything else resolves to `null`, which signals the
|
|
20
|
+
* caller to fall back to the generic icon.
|
|
21
|
+
*
|
|
22
|
+
* @module
|
|
23
|
+
*/
|
|
24
|
+
/** Maximum avatar source length we will render inline (~256 KB data-URI). */
|
|
25
|
+
export const MAX_AVATAR_SRC_LENGTH = 262_144;
|
|
26
|
+
/** Image data-URI MIME types we treat as renderable avatars. */
|
|
27
|
+
const DATA_IMAGE_RE = /^data:image\/(?:png|jpe?g|gif|webp|svg\+xml|avif);/i;
|
|
28
|
+
/** Remote URL schemes we treat as renderable avatars. */
|
|
29
|
+
const HTTP_URL_RE = /^https?:\/\//i;
|
|
30
|
+
/**
|
|
31
|
+
* Resolve a stored avatar value to a safe `<img>` src, or `null` to fall back to
|
|
32
|
+
* the generic icon.
|
|
33
|
+
*
|
|
34
|
+
* @param avatar - The avatar value from user metadata (data-URI, URL, or absent).
|
|
35
|
+
* @returns A safe image src string, or `null` when there is no renderable avatar.
|
|
36
|
+
*/
|
|
37
|
+
export function resolveUserAvatar(avatar) {
|
|
38
|
+
if (typeof avatar !== 'string')
|
|
39
|
+
return null;
|
|
40
|
+
const src = avatar.trim();
|
|
41
|
+
if (!src || src.length > MAX_AVATAR_SRC_LENGTH)
|
|
42
|
+
return null;
|
|
43
|
+
if (!DATA_IMAGE_RE.test(src) && !HTTP_URL_RE.test(src))
|
|
44
|
+
return null;
|
|
45
|
+
return src;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Whether a stored avatar value is renderable (vs. needing the icon fallback).
|
|
49
|
+
*
|
|
50
|
+
* @param avatar - The avatar value from user metadata.
|
|
51
|
+
* @returns `true` when {@link resolveUserAvatar} would return a src.
|
|
52
|
+
*/
|
|
53
|
+
export function hasRenderableAvatar(avatar) {
|
|
54
|
+
return resolveUserAvatar(avatar) !== null;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=user-avatar-utilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-avatar-utilities.js","sourceRoot":"","sources":["../../src/components/user-avatar-utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,6EAA6E;AAC7E,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAA;AAE5C,gEAAgE;AAChE,MAAM,aAAa,GAAG,qDAAqD,CAAA;AAE3E,yDAAyD;AACzD,MAAM,WAAW,GAAG,eAAe,CAAA;AAEnC;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAsB;IACtD,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IAC3C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,CAAA;IACzB,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,qBAAqB;QAAE,OAAO,IAAI,CAAA;IAC3D,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IACnE,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAsB;IACxD,OAAO,iBAAiB,CAAC,MAAM,CAAC,KAAK,IAAI,CAAA;AAC3C,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers for {@link WorkspaceLayout} panel sizing and resize clamping.
|
|
3
|
+
*
|
|
4
|
+
* Kept side-effect-free (no React, no DOM) so the resize math is unit-testable.
|
|
5
|
+
* The layout reads the LIVE size from `layout.sizes` — the same place
|
|
6
|
+
* `WorkspaceProvider.resizePanel` writes — so a drag is reflected and persisted
|
|
7
|
+
* (the previous code read `defaultSize`, which resize never updated, so drags
|
|
8
|
+
* silently did nothing).
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import type { PanelConfig, WorkspaceLayout } from '@molecule/app-ide';
|
|
13
|
+
/** Smallest a panel may shrink to, as a percentage of the container. */
|
|
14
|
+
export declare const MIN_PANEL_PERCENT = 10;
|
|
15
|
+
/** Largest a panel may grow to, as a percentage of the container. */
|
|
16
|
+
export declare const MAX_PANEL_PERCENT = 80;
|
|
17
|
+
/**
|
|
18
|
+
* Clamp a panel's new size after a pixel drag delta.
|
|
19
|
+
* @param currentSize - The panel's current size as a percentage.
|
|
20
|
+
* @param deltaPx - The drag delta in pixels (positive = grow the left panel).
|
|
21
|
+
* @param containerWidth - The layout container width in pixels.
|
|
22
|
+
* @param min - Minimum allowed percentage. Defaults to {@link MIN_PANEL_PERCENT}.
|
|
23
|
+
* @param max - Maximum allowed percentage. Defaults to {@link MAX_PANEL_PERCENT}.
|
|
24
|
+
* @returns The new size as a percentage, clamped to `[min, max]`.
|
|
25
|
+
*/
|
|
26
|
+
export declare function clampPanelSize(currentSize: number, deltaPx: number, containerWidth: number, min?: number, max?: number): number;
|
|
27
|
+
/**
|
|
28
|
+
* The live size (percentage) of the visible panel at `index`, read from
|
|
29
|
+
* `layout.sizes` keyed by the panel's position group (where `resizePanel`
|
|
30
|
+
* writes), falling back to the panel's `defaultSize`, then to an equal split.
|
|
31
|
+
* @param layout - The current workspace layout.
|
|
32
|
+
* @param panelConfigs - The visible panel configs, in render order.
|
|
33
|
+
* @param index - The index of the panel within `panelConfigs`.
|
|
34
|
+
* @returns The panel size as a percentage.
|
|
35
|
+
*/
|
|
36
|
+
export declare function livePanelSize(layout: WorkspaceLayout, panelConfigs: PanelConfig[], index: number): number;
|
|
37
|
+
//# sourceMappingURL=workspace-layout-utilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-layout-utilities.d.ts","sourceRoot":"","sources":["../../src/components/workspace-layout-utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAErE,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,KAAK,CAAA;AACnC,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,KAAK,CAAA;AAEnC;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,EACtB,GAAG,SAAoB,EACvB,GAAG,SAAoB,GACtB,MAAM,CAIR;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,eAAe,EACvB,YAAY,EAAE,WAAW,EAAE,EAC3B,KAAK,EAAE,MAAM,GACZ,MAAM,CAiBR"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers for {@link WorkspaceLayout} panel sizing and resize clamping.
|
|
3
|
+
*
|
|
4
|
+
* Kept side-effect-free (no React, no DOM) so the resize math is unit-testable.
|
|
5
|
+
* The layout reads the LIVE size from `layout.sizes` — the same place
|
|
6
|
+
* `WorkspaceProvider.resizePanel` writes — so a drag is reflected and persisted
|
|
7
|
+
* (the previous code read `defaultSize`, which resize never updated, so drags
|
|
8
|
+
* silently did nothing).
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
/** Smallest a panel may shrink to, as a percentage of the container. */
|
|
13
|
+
export const MIN_PANEL_PERCENT = 10;
|
|
14
|
+
/** Largest a panel may grow to, as a percentage of the container. */
|
|
15
|
+
export const MAX_PANEL_PERCENT = 80;
|
|
16
|
+
/**
|
|
17
|
+
* Clamp a panel's new size after a pixel drag delta.
|
|
18
|
+
* @param currentSize - The panel's current size as a percentage.
|
|
19
|
+
* @param deltaPx - The drag delta in pixels (positive = grow the left panel).
|
|
20
|
+
* @param containerWidth - The layout container width in pixels.
|
|
21
|
+
* @param min - Minimum allowed percentage. Defaults to {@link MIN_PANEL_PERCENT}.
|
|
22
|
+
* @param max - Maximum allowed percentage. Defaults to {@link MAX_PANEL_PERCENT}.
|
|
23
|
+
* @returns The new size as a percentage, clamped to `[min, max]`.
|
|
24
|
+
*/
|
|
25
|
+
export function clampPanelSize(currentSize, deltaPx, containerWidth, min = MIN_PANEL_PERCENT, max = MAX_PANEL_PERCENT) {
|
|
26
|
+
const width = containerWidth > 0 ? containerWidth : 1;
|
|
27
|
+
const percentDelta = (deltaPx / width) * 100;
|
|
28
|
+
return Math.max(min, Math.min(max, currentSize + percentDelta));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The live size (percentage) of the visible panel at `index`, read from
|
|
32
|
+
* `layout.sizes` keyed by the panel's position group (where `resizePanel`
|
|
33
|
+
* writes), falling back to the panel's `defaultSize`, then to an equal split.
|
|
34
|
+
* @param layout - The current workspace layout.
|
|
35
|
+
* @param panelConfigs - The visible panel configs, in render order.
|
|
36
|
+
* @param index - The index of the panel within `panelConfigs`.
|
|
37
|
+
* @returns The panel size as a percentage.
|
|
38
|
+
*/
|
|
39
|
+
export function livePanelSize(layout, panelConfigs, index) {
|
|
40
|
+
const equal = Math.floor(100 / Math.max(panelConfigs.length, 1));
|
|
41
|
+
const config = panelConfigs[index];
|
|
42
|
+
if (!config)
|
|
43
|
+
return equal;
|
|
44
|
+
const group = layout.sizes?.[config.position];
|
|
45
|
+
if (group) {
|
|
46
|
+
// Index within the position group = count of preceding configs sharing it.
|
|
47
|
+
let idxInGroup = 0;
|
|
48
|
+
for (let i = 0; i < index; i++) {
|
|
49
|
+
if (panelConfigs[i]?.position === config.position)
|
|
50
|
+
idxInGroup++;
|
|
51
|
+
}
|
|
52
|
+
const size = group[idxInGroup];
|
|
53
|
+
if (typeof size === 'number' && Number.isFinite(size))
|
|
54
|
+
return size;
|
|
55
|
+
}
|
|
56
|
+
return config.defaultSize ?? equal;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=workspace-layout-utilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-layout-utilities.js","sourceRoot":"","sources":["../../src/components/workspace-layout-utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,wEAAwE;AACxE,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAA;AACnC,qEAAqE;AACrE,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAEnC;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,WAAmB,EACnB,OAAe,EACf,cAAsB,EACtB,GAAG,GAAG,iBAAiB,EACvB,GAAG,GAAG,iBAAiB;IAEvB,MAAM,KAAK,GAAG,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA;IACrD,MAAM,YAAY,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,GAAG,CAAA;IAC5C,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,YAAY,CAAC,CAAC,CAAA;AACjE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAuB,EACvB,YAA2B,EAC3B,KAAa;IAEb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAA;IAChE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;IAClC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IAEzB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC7C,IAAI,KAAK,EAAE,CAAC;QACV,2EAA2E;QAC3E,IAAI,UAAU,GAAG,CAAC,CAAA;QAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,QAAQ,KAAK,MAAM,CAAC,QAAQ;gBAAE,UAAU,EAAE,CAAA;QACjE,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,CAAA;QAC9B,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;IACpE,CAAC;IAED,OAAO,MAAM,CAAC,WAAW,IAAI,KAAK,CAAA;AACpC,CAAC"}
|