Skip to content

Commit 7735568

Browse files
committed
Message queue
1 parent bce5b13 commit 7735568

File tree

9 files changed

+351
-91
lines changed

9 files changed

+351
-91
lines changed

apps/desktop/src/components/codegen/CodegenInput.svelte

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
if (e.key === 'Enter' && !e.shiftKey) {
6767
e.preventDefault();
6868
69-
if (loading || value.trim().length === 0) return;
69+
if (value.trim().length === 0) return;
7070
7171
await handleSubmit();
7272
}
@@ -125,15 +125,14 @@
125125
<button
126126
class="send-button"
127127
type="button"
128-
disabled={loading || value.trim().length === 0}
128+
disabled={value.trim().length === 0}
129129
class:loading
130130
style="pop"
131131
onclick={handleSubmit}
132132
aria-label="Send"
133133
>
134134
<svg
135135
class="circle-icon"
136-
class:spinner={loading}
137136
viewBox="0 0 18 18"
138137
fill="none"
139138
xmlns="http://www.w3.org/2000/svg"
@@ -149,7 +148,6 @@
149148

150149
<svg
151150
class="arrow-icon"
152-
class:spinner={loading}
153151
viewBox="0 0 16 16"
154152
fill="none"
155153
xmlns="http://www.w3.org/2000/svg"

apps/desktop/src/components/codegen/CodegenPage.svelte

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import { useAvailabilityChecking } from '$lib/codegen/availabilityChecking.svelte';
3232
import { CLAUDE_CODE_SERVICE } from '$lib/codegen/claude';
3333
import { useSendMessage } from '$lib/codegen/messageQueue.svelte';
34+
import { messageQueueSelectors, messageQueueSlice } from '$lib/codegen/messageQueueSlice';
3435
import {
3536
currentStatus,
3637
formatMessages,
@@ -52,6 +53,7 @@
5253
import { SETTINGS } from '$lib/settings/userSettings';
5354
import { pushStatusToColor, pushStatusToIcon } from '$lib/stacks/stack';
5455
import { STACK_SERVICE } from '$lib/stacks/stackService.svelte';
56+
import { CLIENT_STATE } from '$lib/state/clientState.svelte';
5557
import { combineResults } from '$lib/state/helpers';
5658
import { UI_STATE } from '$lib/state/uiState.svelte';
5759
import { USER } from '$lib/user/user';
@@ -95,6 +97,7 @@
9597
const urlService = inject(URL_SERVICE);
9698
const userSettings = inject(SETTINGS);
9799
const settingsService = inject(SETTINGS_SERVICE);
100+
const clientState = inject(CLIENT_STATE);
98101
const claudeSettings = $derived($settingsService?.claude);
99102
100103
const stacks = $derived(stackService.stacks(projectId));
@@ -395,6 +398,17 @@
395398
cyclePermissionMode();
396399
}
397400
}
401+
402+
const queue = $derived(
403+
messageQueueSelectors
404+
.selectAll(clientState.messageQueue)
405+
.find(
406+
(q) =>
407+
q.head === selectedBranch?.head &&
408+
q.stackId === selectedBranch?.stackId &&
409+
q.projectId === projectId
410+
)
411+
);
398412
</script>
399413

400414
<svelte:window onkeydown={handleKeydown} />
@@ -694,8 +708,9 @@
694708

695709
{#snippet rightSidebar(events: ClaudeMessage[])}
696710
{@const addedDirs = laneState?.addedDirs.current || []}
711+
{@const queueLength = queue?.messages.length || 0}
697712
<div class="right-sidebar" bind:this={rightSidebarRef}>
698-
{#if !branchChanges || !selectedBranch || (branchChanges.response && branchChanges.response.changes.length === 0 && getTodos(events).length === 0 && addedDirs.length === 0)}
713+
{#if !branchChanges || !selectedBranch || (branchChanges.response && branchChanges.response.changes.length === 0 && getTodos(events).length === 0 && addedDirs.length === 0 && queueLength === 0)}
699714
<div class="right-sidebar__placeholder">
700715
<EmptyStatePlaceholder
701716
image={filesAndChecksSvg}
@@ -714,7 +729,7 @@
714729
<ReduxResult result={branchChanges.result} {projectId}>
715730
{#snippet children({ changes }, { projectId })}
716731
<Drawer
717-
bottomBorder={todos.length > 0 || addedDirs.length > 0}
732+
bottomBorder={todos.length > 0 || addedDirs.length > 0 || queueLength > 0}
718733
grow
719734
defaultCollapsed={todos.length > 0}
720735
notFoldable
@@ -752,7 +767,11 @@
752767
{/if}
753768

754769
{#if todos.length > 0}
755-
<Drawer defaultCollapsed={false} noshrink>
770+
<Drawer
771+
defaultCollapsed={false}
772+
noshrink
773+
bottomBorder={addedDirs.length > 0 || queueLength > 0}
774+
>
756775
{#snippet header()}
757776
<h4 class="text-14 text-semibold truncate">Todos</h4>
758777
<Badge>{todos.length}</Badge>
@@ -767,7 +786,7 @@
767786
{/if}
768787

769788
{#if addedDirs.length > 0}
770-
<Drawer defaultCollapsed={false} noshrink>
789+
<Drawer defaultCollapsed={false} noshrink bottomBorder={queueLength > 0}>
771790
{#snippet header()}
772791
<h4 class="text-14 text-semibold truncate">Added Directories</h4>
773792
<Badge>{addedDirs.length}</Badge>
@@ -794,6 +813,38 @@
794813
</div>
795814
</Drawer>
796815
{/if}
816+
817+
{#if queue && queue.messages.length > 0}
818+
<Drawer defaultCollapsed={false} noshrink>
819+
{#snippet header()}
820+
<h4 class="text-14 text-semibold truncate">Queued Message</h4>
821+
{/snippet}
822+
823+
<div class="right-sidebar-list right-sidebar-list--small-gap">
824+
{#each queue.messages as message}
825+
<div class="message-queue-item">
826+
<span class="text-13 grow-1 message-queue-item-text">{message.prompt}</span>
827+
<Button
828+
kind="ghost"
829+
icon="bin"
830+
shrinkable
831+
onclick={() => {
832+
if (selectedBranch) {
833+
clientState.dispatch(
834+
messageQueueSlice.actions.upsert({
835+
...queue,
836+
messages: queue.messages.filter((m) => m !== message)
837+
})
838+
);
839+
}
840+
}}
841+
tooltip="Remove prompt from queue"
842+
/>
843+
</div>
844+
{/each}
845+
</div>
846+
</Drawer>
847+
{/if}
797848
{/if}
798849

799850
<Resizer
@@ -867,7 +918,7 @@
867918
projectId,
868919
stackId
869920
})}
870-
{@const sidebarIsStackActive = claudeCodeService.isStackActive(projectId, stackId)}
921+
{@const isActive = claudeCodeService.isStackActive(projectId, stackId)}
871922
{@const rule = rulesService.aiRuleForStack({ projectId, stackId })}
872923

873924
<ReduxResult
@@ -876,7 +927,7 @@
876927
commits.result,
877928
branchDetails.result,
878929
events.result,
879-
sidebarIsStackActive.result,
930+
isActive.result,
880931
rule.result
881932
)}
882933
{projectId}
@@ -995,7 +1046,7 @@
9951046
<div class="not-available">
9961047
<DecorativeSplitView hideDetails img={vibecodingSvg}>
9971048
<div class="not-available__content">
998-
<h1 class="text-serif-42">Set up <i>Claude Code</i></h1>
1049+
<h1 class="text-serif-40">Set up <i>Claude Code</i></h1>
9991050
<ClaudeCheck
10001051
claudeExecutable={claudeExecutable.current}
10011052
recheckedAvailability={recheckedAvailability.current}
@@ -1234,6 +1285,18 @@
12341285
justify-content: space-between;
12351286
}
12361287
1288+
.message-queue-item {
1289+
display: flex;
1290+
align-items: center;
1291+
justify-content: space-between;
1292+
}
1293+
1294+
.message-queue-item-text {
1295+
overflow: hidden;
1296+
text-overflow: ellipsis;
1297+
white-space: nowrap;
1298+
}
1299+
12371300
.right-sidebar-list--small-gap {
12381301
gap: 4px;
12391302
}

apps/desktop/src/components/codegen/CodegenSidebarEntry.svelte

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,6 @@
153153
<div class="vibe-icon {status}">
154154
{#if status === 'running'}
155155
<Icon name="spinner" />
156-
{:else if status === 'completed'}
157-
<Icon name="success" />
158156
{/if}
159157
</div>
160158
{/snippet}
@@ -293,10 +291,6 @@
293291
294292
.vibe-icon {
295293
display: flex;
296-
297-
&.completed {
298-
color: var(--clr-theme-succ-element);
299-
}
300294
}
301295
302296
.active-indicator {

0 commit comments

Comments
 (0)