返回 DeepSeek-Reasonix
inboxQueuePreview.ts
根目录 / desktop / frontend / src / lib / inboxQueuePreview.ts
1 import type { InboxQueueRequest, InboxQueueResult } from "./inboxQueueCommands";
2 import type { InboxTarget } from "./pendingFollowup";
3 import type { AppBindings } from "./bridge";
4
5 // Browser-only fixture using the production component and command contract.
6 // No live files, sessions, providers, or mutation endpoints are involved.
7 export function createInboxQueuePreview() {
8 let revision = 1, paused = false;
9 let rows = [
10 { id: "queue-layout", text: "检查页面布局和交互", version: "1" },
11 { id: "queue-save", text: "修复消息队列保存失败的问题。\n保留原消息的位置、附件和文件引用。\n完成后验证修改后的正文是否被正确执行。", version: "1" },
12 { id: "queue-tests", text: "补充验证并整理结果", version: "1" },
13 ];
14 const snapshot = (path = "") => ({ revision, paused, recovered: false, sessionPath: path, mutationsSupported: true,
15 items: rows.map((row, i) => ({ id: row.id, preview: row.text, state: "queued", intent: "followup", position: i + 1, byteSize: row.text.length })),
16 itemsCount: rows.length, bytes: 512, maxItems: 64, maxBytes: 64 * 1024 * 1024,
17 });
18 const receipts = new Map<string, { itemId: string; disposition: string; position: number; paused: boolean }>();
19 const enqueue = (text: string, key: string, steer = false) => {
20 const previous = receipts.get(key);
21 if (previous) return previous;
22 const id = `queue-${++revision}`;
23 if (!steer) rows.push({ id, text, version: String(revision) });
24 const receipt = { itemId: id, disposition: steer ? "steer_accepted" : "queued_followup", position: steer ? 0 : rows.length, paused };
25 receipts.set(key, receipt);
26 return receipt;
27 };
28 const command = async (target: InboxTarget, request: InboxQueueRequest): Promise<InboxQueueResult> => {
29 const row = rows.find(row => row.id === request.itemId);
30 const result = (outcome: InboxQueueResult["outcome"], reason?: string) => ({ outcome, reason, snapshot: snapshot(target.sessionPath) });
31 if (request.kind === "snapshot") return result("unchanged");
32 if (request.kind === "enqueue_steer") return { ...result("applied"), receipt: enqueue(request.text || "", request.idempotencyKey || "", true) };
33 if (request.kind === "pause") { paused = Boolean(request.paused); revision++; return result("applied"); }
34 if (!row) return result("unavailable", "item_missing");
35 if (request.kind === "read") return { ...result("unchanged"), edit: { id: row.id, text: row.text, contentVersion: row.version, references: row.id === "queue-save" ? ["问题截图.png", "Composer.tsx"] : [] } };
36 if (request.kind === "edit") {
37 if (row.version !== request.contentVersion) return result("conflict", "content_changed");
38 row.text = request.text || ""; row.version = String(++revision);
39 } else if (request.kind === "move") {
40 if (revision !== request.queueRevision) return result("conflict", "order_changed");
41 if (request.beforeItemId && !rows.some(row => row.id === request.beforeItemId)) return result("conflict", "anchor_missing");
42 rows = rows.filter(candidate => candidate !== row);
43 rows.splice(request.beforeItemId ? rows.findIndex(row => row.id === request.beforeItemId) : rows.length, 0, row); revision++;
44 } else if (request.kind === "delete" || request.kind === "steer") { rows = rows.filter(candidate => candidate !== row); revision++; }
45 return result("applied");
46 };
47 return { snapshot, command, enqueue, lookup: (key: string) => receipts.get(key) };
48 }
49
50 export function createInboxQueuePreviewBindings() {
51 const queue = createInboxQueuePreview();
52 const bindings: Pick<AppBindings, "CaptureInboxTarget" | "InboxQueueForTarget" | "EnqueueInboxFollowupForTarget" | "LookupInboxFollowupForTarget" | "InboxSnapshot"> = {
53 CaptureInboxTarget: async (tabId, sessionPath) => ({ tabId, sessionPath, generation: 1, selection: 0, remote: false }),
54 InboxQueueForTarget: queue.command,
55 EnqueueInboxFollowupForTarget: async (_target, display, submit, _invocations, key) => queue.enqueue(submit || display, key),
56 LookupInboxFollowupForTarget: async (_target, key) => {
57 const receipt = queue.lookup(key);
58 if (!receipt) throw new Error("Follow-up receipt unconfirmed");
59 return receipt;
60 },
61 InboxSnapshot: async () => queue.snapshot(),
62 };
63 return bindings;
64 }
65
65 lines TYPESCRIPT