@myrialabs/clopen 0.1.3 → 0.1.5
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/CONTRIBUTING.md +40 -355
- package/README.md +46 -113
- package/backend/lib/chat/stream-manager.ts +8 -0
- package/backend/lib/database/migrations/022_add_snapshot_changes_column.ts +35 -0
- package/backend/lib/database/migrations/index.ts +7 -0
- package/backend/lib/database/queries/snapshot-queries.ts +7 -4
- package/backend/lib/files/file-watcher.ts +34 -0
- package/backend/lib/mcp/config.ts +7 -3
- package/backend/lib/mcp/servers/helper.ts +25 -14
- package/backend/lib/mcp/servers/index.ts +7 -2
- package/backend/lib/project/status-manager.ts +6 -4
- package/backend/lib/snapshot/snapshot-service.ts +471 -316
- package/backend/lib/terminal/pty-session-manager.ts +1 -32
- package/backend/ws/chat/stream.ts +45 -2
- package/backend/ws/snapshot/restore.ts +77 -67
- package/frontend/lib/components/chat/ChatInterface.svelte +21 -14
- package/frontend/lib/components/chat/input/ChatInput.svelte +2 -2
- package/frontend/lib/components/chat/input/components/ChatInputActions.svelte +1 -1
- package/frontend/lib/components/chat/input/components/EngineModelPicker.svelte +24 -12
- package/frontend/lib/components/chat/input/composables/use-textarea-resize.svelte.ts +12 -2
- package/frontend/lib/components/chat/tools/AskUserQuestionTool.svelte +3 -8
- package/frontend/lib/components/checkpoint/TimelineModal.svelte +222 -30
- package/frontend/lib/components/common/MonacoEditor.svelte +14 -0
- package/frontend/lib/components/common/xterm/XTerm.svelte +9 -0
- package/frontend/lib/components/common/xterm/xterm-service.ts +9 -0
- package/frontend/lib/components/git/DiffViewer.svelte +16 -2
- package/frontend/lib/components/history/HistoryModal.svelte +3 -4
- package/frontend/lib/components/settings/appearance/AppearanceSettings.svelte +59 -0
- package/frontend/lib/components/settings/engines/AIEnginesSettings.svelte +1 -1
- package/frontend/lib/components/terminal/Terminal.svelte +1 -7
- package/frontend/lib/components/workspace/DesktopNavigator.svelte +11 -19
- package/frontend/lib/components/workspace/MobileNavigator.svelte +4 -15
- package/frontend/lib/components/workspace/PanelHeader.svelte +623 -616
- package/frontend/lib/components/workspace/panels/ChatPanel.svelte +3 -2
- package/frontend/lib/components/workspace/panels/FilesPanel.svelte +3 -2
- package/frontend/lib/components/workspace/panels/GitPanel.svelte +3 -2
- package/frontend/lib/services/notification/global-stream-monitor.ts +56 -16
- package/frontend/lib/services/snapshot/snapshot.service.ts +71 -32
- package/frontend/lib/stores/core/presence.svelte.ts +63 -1
- package/frontend/lib/stores/features/settings.svelte.ts +9 -1
- package/frontend/lib/stores/features/terminal.svelte.ts +6 -0
- package/frontend/lib/stores/ui/workspace.svelte.ts +4 -3
- package/package.json +1 -1
- package/shared/types/database/schema.ts +18 -0
- package/shared/types/stores/settings.ts +2 -0
- package/scripts/pre-publish-check.sh +0 -142
- package/scripts/setup-hooks.sh +0 -134
- package/scripts/validate-branch-name.sh +0 -47
- package/scripts/validate-commit-msg.sh +0 -42
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
import { addNotification } from '$frontend/lib/stores/ui/notification.svelte';
|
|
8
8
|
import { openSettingsModal } from '$frontend/lib/stores/ui/settings-modal.svelte';
|
|
9
9
|
import { projectStatusService } from '$frontend/lib/services/project';
|
|
10
|
-
import { presenceState } from '$frontend/lib/stores/core/presence.svelte';
|
|
10
|
+
import { presenceState, getProjectStatusColor } from '$frontend/lib/stores/core/presence.svelte';
|
|
11
11
|
import type { Project } from '$shared/types/database/schema';
|
|
12
12
|
import { debug } from '$shared/utils/logger';
|
|
13
|
+
import { settings } from '$frontend/lib/stores/features/settings.svelte';
|
|
13
14
|
import FolderBrowser from '$frontend/lib/components/common/FolderBrowser.svelte';
|
|
14
15
|
import Dialog from '$frontend/lib/components/common/Dialog.svelte';
|
|
15
16
|
import ViewMenu from '$frontend/lib/components/workspace/ViewMenu.svelte';
|
|
@@ -30,7 +31,7 @@
|
|
|
30
31
|
const isCollapsed = $derived(workspaceState.navigatorCollapsed);
|
|
31
32
|
const currentProjectId = $derived(projectState.currentProject?.id);
|
|
32
33
|
const navigatorWidth = $derived(
|
|
33
|
-
workspaceState.navigatorCollapsed ? 48 : workspaceState.navigatorWidth
|
|
34
|
+
workspaceState.navigatorCollapsed ? 48 : Math.round(workspaceState.navigatorWidth * (settings.fontSize / 13))
|
|
34
35
|
);
|
|
35
36
|
|
|
36
37
|
const filteredProjects = $derived(() => {
|
|
@@ -110,18 +111,7 @@
|
|
|
110
111
|
}
|
|
111
112
|
}
|
|
112
113
|
|
|
113
|
-
//
|
|
114
|
-
// Shows real-time status for ALL projects, not just the active one.
|
|
115
|
-
// Uses backend-computed isWaitingInput so background sessions are accurate
|
|
116
|
-
// even when the frontend hasn't received their chat events.
|
|
117
|
-
function getStatusColor(projectId: string): string {
|
|
118
|
-
const status = presenceState.statuses.get(projectId);
|
|
119
|
-
if (!status?.streams) return 'bg-slate-500/30';
|
|
120
|
-
const activeStreams = status.streams.filter((s: any) => s.status === 'active');
|
|
121
|
-
if (activeStreams.length === 0) return 'bg-slate-500/30';
|
|
122
|
-
const hasWaitingInput = activeStreams.some((s: any) => s.isWaitingInput);
|
|
123
|
-
return hasWaitingInput ? 'bg-amber-500' : 'bg-emerald-500';
|
|
124
|
-
}
|
|
114
|
+
// Status color for project indicator — uses shared helper from presence store
|
|
125
115
|
|
|
126
116
|
// Close folder browser
|
|
127
117
|
function closeFolderBrowser() {
|
|
@@ -244,7 +234,7 @@
|
|
|
244
234
|
<div class="relative shrink-0">
|
|
245
235
|
<Icon name="lucide:folder" class="w-4 h-4" />
|
|
246
236
|
<span
|
|
247
|
-
class="absolute -bottom-0.5 -right-0.5 w-2.5 h-2.5 rounded-full border-2 border-slate-50 dark:border-slate-900/95 {
|
|
237
|
+
class="absolute -bottom-0.5 -right-0.5 w-2.5 h-2.5 rounded-full border-2 border-slate-50 dark:border-slate-900/95 {getProjectStatusColor(project.id ?? '')}"
|
|
248
238
|
></span>
|
|
249
239
|
</div>
|
|
250
240
|
|
|
@@ -301,7 +291,7 @@
|
|
|
301
291
|
</footer>
|
|
302
292
|
{:else}
|
|
303
293
|
<!-- Collapsed State: Icon Buttons -->
|
|
304
|
-
<div class="flex
|
|
294
|
+
<div class="flex flex-col items-center pt-4 px-2 shrink-0">
|
|
305
295
|
<button
|
|
306
296
|
type="button"
|
|
307
297
|
class="flex items-center justify-center w-9 h-9 bg-transparent border-none rounded-lg text-slate-500 cursor-pointer transition-all duration-150 relative hover:bg-violet-500/10 hover:text-slate-900 dark:hover:text-slate-100"
|
|
@@ -312,13 +302,15 @@
|
|
|
312
302
|
</button>
|
|
313
303
|
|
|
314
304
|
<div class="w-6 h-px bg-violet-500/10 my-1"></div>
|
|
305
|
+
</div>
|
|
315
306
|
|
|
316
|
-
|
|
307
|
+
<div class="flex-1 flex flex-col items-center gap-2 px-2 pb-4 min-h-0 overflow-y-auto">
|
|
308
|
+
{#each existingProjects as project (project.id)}
|
|
317
309
|
{@const projectStatus = presenceState.statuses.get(project.id ?? '')}
|
|
318
310
|
{@const activeUserCount = (projectStatus?.activeUsers || []).length}
|
|
319
311
|
<button
|
|
320
312
|
type="button"
|
|
321
|
-
class="flex items-center justify-center w-9 h-9 border-none rounded-lg cursor-pointer transition-all duration-150 relative font-semibold text-sm
|
|
313
|
+
class="flex items-center justify-center w-9 h-9 shrink-0 border-none rounded-lg cursor-pointer transition-all duration-150 relative font-semibold text-sm
|
|
322
314
|
{currentProjectId === project.id
|
|
323
315
|
? 'bg-violet-500/10 dark:bg-violet-500/20 text-violet-700 dark:text-violet-300'
|
|
324
316
|
: 'bg-slate-200/50 dark:bg-slate-800/50 text-slate-600 dark:text-slate-400 hover:bg-violet-500/10 hover:text-slate-900 dark:hover:text-slate-100'}"
|
|
@@ -327,7 +319,7 @@
|
|
|
327
319
|
>
|
|
328
320
|
<span>{getProjectInitials(project.name)}</span>
|
|
329
321
|
<span
|
|
330
|
-
class="absolute bottom-1 right-1 w-2.5 h-2.5 rounded-full border-2 border-slate-50 dark:border-slate-900/95 {
|
|
322
|
+
class="absolute bottom-1 right-1 w-2.5 h-2.5 rounded-full border-2 border-slate-50 dark:border-slate-900/95 {getProjectStatusColor(project.id ?? '')}"
|
|
331
323
|
></span>
|
|
332
324
|
{#if activeUserCount > 0}
|
|
333
325
|
<span
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
type PanelId
|
|
9
9
|
} from '$frontend/lib/stores/ui/workspace.svelte';
|
|
10
10
|
import { projectState, removeProject } from '$frontend/lib/stores/core/projects.svelte';
|
|
11
|
-
import { presenceState } from '$frontend/lib/stores/core/presence.svelte';
|
|
11
|
+
import { presenceState, getProjectStatusColor } from '$frontend/lib/stores/core/presence.svelte';
|
|
12
12
|
import { openSettingsModal } from '$frontend/lib/stores/ui/settings-modal.svelte';
|
|
13
13
|
import { addNotification } from '$frontend/lib/stores/ui/notification.svelte';
|
|
14
14
|
import type { IconName } from '$shared/types/ui/icons';
|
|
@@ -65,18 +65,7 @@
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
//
|
|
69
|
-
// Shows real-time status for ALL projects, not just the active one.
|
|
70
|
-
// Uses backend-computed isWaitingInput so background sessions are accurate
|
|
71
|
-
// even when the frontend hasn't received their chat events.
|
|
72
|
-
function getStatusColor(projectId: string): string {
|
|
73
|
-
const status = presenceState.statuses.get(projectId);
|
|
74
|
-
if (!status?.streams) return 'bg-slate-500/30';
|
|
75
|
-
const activeStreams = status.streams.filter((s: any) => s.status === 'active');
|
|
76
|
-
if (activeStreams.length === 0) return 'bg-slate-500/30';
|
|
77
|
-
const hasWaitingInput = activeStreams.some((s: any) => s.isWaitingInput);
|
|
78
|
-
return hasWaitingInput ? 'bg-amber-500' : 'bg-emerald-500';
|
|
79
|
-
}
|
|
68
|
+
// Status color for project indicator — uses shared helper from presence store
|
|
80
69
|
|
|
81
70
|
function openAddProject() {
|
|
82
71
|
showProjectMenu = false;
|
|
@@ -162,7 +151,7 @@
|
|
|
162
151
|
aria-expanded={showProjectMenu}
|
|
163
152
|
aria-haspopup="menu"
|
|
164
153
|
>
|
|
165
|
-
<div class="relative shrink-0"><Icon name="lucide:folder-open" class="w-4 h-4" /><span class="absolute -bottom-0.5 -right-0.5 w-2.5 h-2.5 rounded-full border-2 border-slate-100 dark:border-slate-800 {
|
|
154
|
+
<div class="relative shrink-0"><Icon name="lucide:folder-open" class="w-4 h-4" /><span class="absolute -bottom-0.5 -right-0.5 w-2.5 h-2.5 rounded-full border-2 border-slate-100 dark:border-slate-800 {getProjectStatusColor(projectState.currentProject?.id ?? '')}"></span></div>
|
|
166
155
|
<span class="flex-1 text-left overflow-hidden text-ellipsis whitespace-nowrap">
|
|
167
156
|
{projectState.currentProject?.name ?? 'No Project'}
|
|
168
157
|
</span>
|
|
@@ -315,7 +304,7 @@
|
|
|
315
304
|
>
|
|
316
305
|
<Icon name="lucide:folder" class="text-violet-600 dark:text-violet-400 w-4 h-4" />
|
|
317
306
|
<span
|
|
318
|
-
class="absolute -bottom-0.5 -right-0.5 w-2.5 h-2.5 rounded-full border-2 border-white dark:border-slate-900 {
|
|
307
|
+
class="absolute -bottom-0.5 -right-0.5 w-2.5 h-2.5 rounded-full border-2 border-white dark:border-slate-900 {getProjectStatusColor(project.id ?? '')}"
|
|
319
308
|
></span>
|
|
320
309
|
</div>
|
|
321
310
|
<div class="flex-1 min-w-0">
|