summaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-29 12:12:18 +0900
committerAdam Malczewski <[email protected]>2026-06-29 12:12:18 +0900
commit129bb3be45e1446ce4219d7f656ed0ed6f93a29f (patch)
tree5fe54f4bc10c90116a8b0dd5f140c5585b55120c /src/core
parent1cdb866fbb708a1f6c5e802a075789cece85800d (diff)
downloaddispatch-web-129bb3be45e1446ce4219d7f656ed0ed6f93a29f.tar.gz
dispatch-web-129bb3be45e1446ce4219d7f656ed0ed6f93a29f.zip
feat(chat): cancel a queued steering message from the UI
Implements the frontend for the cancel-queued-message backend feature (transport-contract 0.23.0 → 0.24.0, ADDITIVE). While a turn is generating and a user message is queued (awaiting steering delivery), the user can now cancel a single queued message by id so it never runs. - Consume the contract: regenerate the .dispatch/transport-contract.reference.md mirror to 0.24.0; add chat.queue.cancel to the exhaustive WsClientMessage guard (core/wire/conformance.ts) + its test. - ChatTransport port accepts ChatQueueCancelMessage; cancelQueuedMessage(id) on the chat store + app store sends chat.queue.cancel { conversationId, messageId } (fire-and-forget, idempotent — the server no-ops an already- drained/unknown id). - UI: a × cancel affordance per queued row in MessageQueueList.svelte, threaded through SurfaceView's onCancelQueuedMessage (dispatched on rendererId, never the surface id) and wired to store.cancelQueuedMessage. Optimistic removal (pure selectVisibleMessages/reconcileCancelledIds in logic/message-queue.ts) hides the row on click and reconciles from the message-queue surface's post-cancel snapshot. No new event handling — the existing surface subscription reflects the result. Tests: +12 (chat store cancel op ×3, optimistic-removal logic ×11 already existed pattern, MessageQueueList component cancel behavior ×9). Repo fix: package.json + bun.lock were still pinning file:../dispatch-backend/... (stale from the dispatch-backend → backend rename) — corrected to file:../backend/packages/...; bun install now resolves natively with no worktree symlink hack. typecheck 0/0, 1140 tests green (run twice), biome clean, build OK.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/wire/conformance.test.ts2
-rw-r--r--src/core/wire/conformance.ts2
2 files changed, 4 insertions, 0 deletions
diff --git a/src/core/wire/conformance.test.ts b/src/core/wire/conformance.test.ts
index 0d955d5..2b98ca6 100644
--- a/src/core/wire/conformance.test.ts
+++ b/src/core/wire/conformance.test.ts
@@ -212,6 +212,7 @@ describe("classifies every WsClientMessage type", () => {
{ type: "chat.subscribe" as const, conversationId: "c1" },
{ type: "chat.unsubscribe" as const, conversationId: "c1" },
{ type: "chat.queue" as const, conversationId: "c1", text: "steer" },
+ { type: "chat.queue.cancel" as const, conversationId: "c1", messageId: "m1" },
];
const labels = msgs.map(assertWsClientMessageExhaustive);
expect(labels).toEqual([
@@ -222,6 +223,7 @@ describe("classifies every WsClientMessage type", () => {
"chat.subscribe",
"chat.unsubscribe",
"chat.queue",
+ "chat.queue.cancel",
]);
});
});
diff --git a/src/core/wire/conformance.ts b/src/core/wire/conformance.ts
index bfa67dc..16558cd 100644
--- a/src/core/wire/conformance.ts
+++ b/src/core/wire/conformance.ts
@@ -116,6 +116,8 @@ export function assertWsClientMessageExhaustive(msg: WsClientMessage): string {
return "chat.unsubscribe";
case "chat.queue":
return "chat.queue";
+ case "chat.queue.cancel":
+ return "chat.queue.cancel";
default:
return msg satisfies never;
}