From ae5c61a17951406d17adc1f0c77b7fff642078cd Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 22 Apr 2026 11:08:25 -0400 Subject: [PATCH 1/8] feat(workspace): floating project chat widget Modeled on KnowledgeView's mini-chat. Three states (closed handle, collapsed input-only, expanded full panel). Takes over the project conversation lifecycle from WorkspaceView (resume-or-create on mount, delete-if-empty-and-new on unmount) and adds a restart action. Reuses ChatPanel for expanded view and ChatInputBar for collapsed. Co-Authored-By: Claude Opus 4.7 --- .../src/components/WorkspaceChatWidget.vue | 274 ++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 frontend/src/components/WorkspaceChatWidget.vue diff --git a/frontend/src/components/WorkspaceChatWidget.vue b/frontend/src/components/WorkspaceChatWidget.vue new file mode 100644 index 0000000..b2021e9 --- /dev/null +++ b/frontend/src/components/WorkspaceChatWidget.vue @@ -0,0 +1,274 @@ + + + + + From 6026c2445088aea44e5c874cf05a78d88162f777 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 22 Apr 2026 11:09:50 -0400 Subject: [PATCH 2/8] refactor(workspace): two-column grid; widget drives tool-call refresh WorkspaceView now renders tasks (1fr) on the left and notes (2fr) on the right with the floating WorkspaceChatWidget layered on top. The widget owns the SSE streamingToolCalls watcher and emits note-changed and task-changed events; the view listens and reloads the affected panel refs. Dropped from the view: - ChatPanel mount, empty-state quick chips, and Chat header toggle - The conversation lifecycle + SSE watcher (moved into the widget) Co-Authored-By: Claude Opus 4.7 --- .../src/components/WorkspaceChatWidget.vue | 43 +++- frontend/src/views/WorkspaceView.vue | 235 +++--------------- 2 files changed, 78 insertions(+), 200 deletions(-) diff --git a/frontend/src/components/WorkspaceChatWidget.vue b/frontend/src/components/WorkspaceChatWidget.vue index b2021e9..5443700 100644 --- a/frontend/src/components/WorkspaceChatWidget.vue +++ b/frontend/src/components/WorkspaceChatWidget.vue @@ -1,13 +1,54 @@ @@ -176,13 +94,6 @@ onUnmounted(async () => { > Tasks - - - - - - - - - - -
+
{
-
+ + + From 649c0f124b0f439f21c5e09bcbcb2f1b9264b9a8 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 22 Apr 2026 11:10:54 -0400 Subject: [PATCH 3/8] feat(workspace): history dropdown on project chat widget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clicking the β–Ύ button reveals conversations where rag_project_id === projectId, most-recent first. Selecting one repoints the widget (and the workspace_conv_{pid} storage key) to that conversation without deleting the previously active one. Co-Authored-By: Claude Opus 4.7 --- .../src/components/WorkspaceChatWidget.vue | 128 ++++++++++++++++-- 1 file changed, 118 insertions(+), 10 deletions(-) diff --git a/frontend/src/components/WorkspaceChatWidget.vue b/frontend/src/components/WorkspaceChatWidget.vue index 5443700..618ab2f 100644 --- a/frontend/src/components/WorkspaceChatWidget.vue +++ b/frontend/src/components/WorkspaceChatWidget.vue @@ -1,5 +1,5 @@ From 3b41a45757fd18b14e4ff5ad62faccb9d484c914 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 22 Apr 2026 14:35:45 -0400 Subject: [PATCH 6/8] style(workspace-notes): drop border between toolbar and body Co-Authored-By: Claude Opus 4.7 --- frontend/src/components/WorkspaceNoteEditor.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/components/WorkspaceNoteEditor.vue b/frontend/src/components/WorkspaceNoteEditor.vue index 2861001..4ef2614 100644 --- a/frontend/src/components/WorkspaceNoteEditor.vue +++ b/frontend/src/components/WorkspaceNoteEditor.vue @@ -871,6 +871,5 @@ defineExpose({ reload: loadProjectNotes }); flex: 1; overflow-y: auto; padding: 0.5rem 0.6rem; - border-top: 1px solid var(--color-border); } From 70ec060b7a5a8190b3d5b0e37430a160243ad4fd Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 22 Apr 2026 14:43:59 -0400 Subject: [PATCH 7/8] style(workspace-notes): move active-note indicator to right edge Anchors it to the editor side rather than the tasks-panel side. Co-Authored-By: Claude Opus 4.7 --- frontend/src/components/WorkspaceNoteEditor.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/WorkspaceNoteEditor.vue b/frontend/src/components/WorkspaceNoteEditor.vue index 4ef2614..2a8c613 100644 --- a/frontend/src/components/WorkspaceNoteEditor.vue +++ b/frontend/src/components/WorkspaceNoteEditor.vue @@ -551,13 +551,13 @@ defineExpose({ reload: loadProjectNotes }); border-bottom: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent); cursor: pointer; gap: 0.15rem; - border-left: 2px solid transparent; + border-right: 2px solid transparent; transition: background 0.12s; } .note-row:hover { background: color-mix(in srgb, var(--color-primary) 5%, var(--color-surface)); } .note-row.active { background: color-mix(in srgb, var(--color-primary) 8%, var(--color-surface)); - border-left-color: var(--color-primary); + border-right-color: var(--color-primary); } .note-row-main { From f422d4158c0f6e1d96009d45ce2251e2fc6b3759 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 22 Apr 2026 14:52:58 -0400 Subject: [PATCH 8/8] style(workspace-notes): larger, more spacious note title Title input bumps to 1.4rem with Fraunces serif (matches the design language's heading treatment) and gains 0.9/1.1rem padding on the title row for breathing room. Co-Authored-By: Claude Opus 4.7 --- frontend/src/components/WorkspaceNoteEditor.vue | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/WorkspaceNoteEditor.vue b/frontend/src/components/WorkspaceNoteEditor.vue index 2a8c613..d0185f2 100644 --- a/frontend/src/components/WorkspaceNoteEditor.vue +++ b/frontend/src/components/WorkspaceNoteEditor.vue @@ -741,7 +741,7 @@ defineExpose({ reload: loadProjectNotes }); .btn-save:disabled { opacity: 0.4; cursor: default; } .note-title-row { - padding: 0.5rem 0.75rem; + padding: 0.9rem 1.1rem 0.5rem; flex-shrink: 0; } @@ -749,12 +749,19 @@ defineExpose({ reload: loadProjectNotes }); width: 100%; background: transparent; border: none; - font-size: 1rem; + font-size: 1.4rem; font-weight: 600; + line-height: 1.25; color: var(--color-text); padding: 0; + font-family: 'Fraunces', serif; + letter-spacing: -0.01em; } .note-title-input:focus { outline: none; } +.note-title-input::placeholder { + color: var(--color-text-muted); + font-style: italic; +} .tag-row { display: flex;