@wrongstack/webui 0.281.3 → 0.282.1
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/dist/assets/{AnalyticsDashboard-Cb08RPms.js → AnalyticsDashboard-TCNC-sVb.js} +1 -1
- package/dist/assets/AutoPhaseView-BMUiT6aI.js +1 -0
- package/dist/assets/{CodeEditor-CSTcX3Za.js → CodeEditor-C0si742k.js} +1 -1
- package/dist/assets/{DebugDashboard-D6-znhBO.js → DebugDashboard-BHpiEOcf.js} +1 -1
- package/dist/assets/{DesignGalleryView-yKa55dpM.js → DesignGalleryView-BfZTw48N.js} +1 -1
- package/dist/assets/KanbanView-C4T4y0b7.js +1 -0
- package/dist/assets/{MailboxDetailView-DbX_cNcu.js → MailboxDetailView-DJtjP0NF.js} +1 -1
- package/dist/assets/OfficeMapPanel-CgvHvGQm.js +4 -0
- package/dist/assets/{ProcessMonitor-DvPiHdzj.js → ProcessMonitor-D53zn0h4.js} +1 -1
- package/dist/assets/{QueuePanel-BVvnJXHh.js → QueuePanel-DTO68vaB.js} +1 -1
- package/dist/assets/{RefreshDebugView-pmMPOier.js → RefreshDebugView-BXq2P3wo.js} +1 -1
- package/dist/assets/{SddBoardView-CGJbbRrh.js → SddBoardView-C8X4MiTy.js} +2 -2
- package/dist/assets/{SddFlowGraph-WW0qCx0t.js → SddFlowGraph-CtMpzU4S.js} +1 -1
- package/dist/assets/SddWizard-t5Cly3CG.js +1 -0
- package/dist/assets/{SessionsDashboard-VwXvmSxS.js → SessionsDashboard-Dqsrp5CK.js} +1 -1
- package/dist/assets/SkillDetailView-Dq-fTqSp.js +2 -0
- package/dist/assets/{SpecsView-BRdxB6rh.js → SpecsView-Cwd6PiYr.js} +1 -1
- package/dist/assets/{TerminalPanel-CAcbPNO_.js → TerminalPanel-Bzyhr2aC.js} +1 -1
- package/dist/assets/{chat-store-YPRVJGbn.js → chat-store-CIMOL6-x.js} +1 -1
- package/dist/assets/{i18n-BJCOtLro.js → i18n-CNo6A2vu.js} +1 -1
- package/dist/assets/index-CWj2bI87.js +145 -0
- package/dist/assets/index-D7_FeyCA.css +1 -0
- package/dist/assets/{session-store-Do0MGnXu.js → session-store-DN1UYDL9.js} +1 -1
- package/dist/assets/ui-store-BdOsq6T-.js +1 -0
- package/dist/assets/utils-DBns3uMk.js +1 -0
- package/dist/assets/{vendor-Bhf0nZ3B.js → vendor-Ch4m_qLI.js} +25 -25
- package/dist/assets/{ws-client-D9IQ9580.js → ws-client-BAV7SLzK.js} +1 -1
- package/dist/assets/{xyflow-Bp8EMwkC.js → xyflow-D5_yey7w.js} +3 -3
- package/dist/index.html +9 -9
- package/dist/index.js +6253 -5282
- package/dist/index.js.map +1 -1
- package/dist/providers.json +2 -2
- package/dist/server/entry.js +642 -21
- package/dist/server/entry.js.map +1 -1
- package/dist/server/index.js +642 -21
- package/dist/server/index.js.map +1 -1
- package/dist/types.d.ts +18 -3
- package/package.json +6 -6
- package/dist/assets/AutoPhaseView--Ec4Mom8.js +0 -1
- package/dist/assets/OfficeMapPanel-BMxzEv_S.js +0 -4
- package/dist/assets/SddWizard-Cen90k6M.js +0 -1
- package/dist/assets/SkillDetailView-CjUeZv6V.js +0 -2
- package/dist/assets/index-BSuiEQIC.js +0 -145
- package/dist/assets/index-CMiinLaB.css +0 -1
- package/dist/assets/ui-store-D3gGpJWY.js +0 -1
- package/dist/assets/utils-sFCTikqz.js +0 -1
package/dist/server/entry.js
CHANGED
|
@@ -4864,7 +4864,7 @@ ${trigger}
|
|
|
4864
4864
|
` : "",
|
|
4865
4865
|
"## Skills in scope",
|
|
4866
4866
|
"- `bug-hunter` \u2014 for systematic bug detection patterns",
|
|
4867
|
-
"- `output-standards` \u2014 for standardized `<
|
|
4867
|
+
"- `output-standards` \u2014 for standardized `<nextsteps>` formatting"
|
|
4868
4868
|
].join("\n");
|
|
4869
4869
|
await atomicWrite5(path11.join(targetDir, "SKILL.md"), skillContent);
|
|
4870
4870
|
send(ws, {
|
|
@@ -5720,7 +5720,16 @@ function setupEvents(deps2) {
|
|
|
5720
5720
|
});
|
|
5721
5721
|
});
|
|
5722
5722
|
events.on("provider.response", (e) => {
|
|
5723
|
-
broadcast2(clients, {
|
|
5723
|
+
broadcast2(clients, {
|
|
5724
|
+
type: "provider.response",
|
|
5725
|
+
payload: sessionPayload2({
|
|
5726
|
+
sessionId: e.sessionId,
|
|
5727
|
+
content: e.content,
|
|
5728
|
+
usage: e.usage,
|
|
5729
|
+
stopReason: e.stopReason,
|
|
5730
|
+
messageId: "current"
|
|
5731
|
+
})
|
|
5732
|
+
});
|
|
5724
5733
|
});
|
|
5725
5734
|
events.on("ctx.pct", (e) => {
|
|
5726
5735
|
broadcast2(clients, {
|
|
@@ -6060,7 +6069,14 @@ function setupEvents(deps2) {
|
|
|
6060
6069
|
await fs10.mkdir(dir, { recursive: true });
|
|
6061
6070
|
await fs10.writeFile(statusFile, JSON.stringify(e, null, 2), "utf-8");
|
|
6062
6071
|
} catch (err) {
|
|
6063
|
-
console.error(
|
|
6072
|
+
console.error(
|
|
6073
|
+
JSON.stringify({
|
|
6074
|
+
level: "error",
|
|
6075
|
+
event: "setup_events.status_write_failed",
|
|
6076
|
+
message: err instanceof Error ? err.message : String(err),
|
|
6077
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
6078
|
+
})
|
|
6079
|
+
);
|
|
6064
6080
|
}
|
|
6065
6081
|
}
|
|
6066
6082
|
});
|
|
@@ -6150,7 +6166,14 @@ function setupEvents(deps2) {
|
|
|
6150
6166
|
console.log(`[setup-events] Watching ${projectsDir} for status.json changes (hash-filtered, debounced)`);
|
|
6151
6167
|
}
|
|
6152
6168
|
} catch (err) {
|
|
6153
|
-
console.error(
|
|
6169
|
+
console.error(
|
|
6170
|
+
JSON.stringify({
|
|
6171
|
+
level: "error",
|
|
6172
|
+
event: "setup_events.status_watcher_start_failed",
|
|
6173
|
+
message: err instanceof Error ? err.message : String(err),
|
|
6174
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
6175
|
+
})
|
|
6176
|
+
);
|
|
6154
6177
|
}
|
|
6155
6178
|
};
|
|
6156
6179
|
events.on("client.status", (e) => {
|
|
@@ -6610,6 +6633,39 @@ import { toErrorMessage as toErrorMessage5 } from "@wrongstack/core/utils";
|
|
|
6610
6633
|
import { expectDefined as expectDefined2 } from "@wrongstack/core";
|
|
6611
6634
|
import { toErrorMessage as toErrorMessage4 } from "@wrongstack/core/utils";
|
|
6612
6635
|
import { makeProviderFromConfig } from "@wrongstack/providers";
|
|
6636
|
+
var UNCONFIGURED_CAPABILITIES = {
|
|
6637
|
+
tools: false,
|
|
6638
|
+
parallelTools: false,
|
|
6639
|
+
vision: false,
|
|
6640
|
+
streaming: false,
|
|
6641
|
+
promptCache: false,
|
|
6642
|
+
systemPrompt: false,
|
|
6643
|
+
jsonMode: false,
|
|
6644
|
+
reasoning: false,
|
|
6645
|
+
maxContext: 0,
|
|
6646
|
+
cacheControl: "none",
|
|
6647
|
+
topK: false,
|
|
6648
|
+
frequencyPenalty: false,
|
|
6649
|
+
presencePenalty: false,
|
|
6650
|
+
seed: false,
|
|
6651
|
+
structuredOutput: false,
|
|
6652
|
+
logprobs: false,
|
|
6653
|
+
audio: false,
|
|
6654
|
+
multipleCompletions: false
|
|
6655
|
+
};
|
|
6656
|
+
function makeUnconfiguredProvider() {
|
|
6657
|
+
const message = "No provider configured. Complete setup before starting an agent run.";
|
|
6658
|
+
return {
|
|
6659
|
+
id: "unconfigured",
|
|
6660
|
+
capabilities: UNCONFIGURED_CAPABILITIES,
|
|
6661
|
+
async *stream() {
|
|
6662
|
+
throw new Error(message);
|
|
6663
|
+
},
|
|
6664
|
+
async complete() {
|
|
6665
|
+
throw new Error(message);
|
|
6666
|
+
}
|
|
6667
|
+
};
|
|
6668
|
+
}
|
|
6613
6669
|
function logCreateFailure(event, err) {
|
|
6614
6670
|
console.error(
|
|
6615
6671
|
JSON.stringify({
|
|
@@ -6656,11 +6712,7 @@ function resolveSetupProvider(opts) {
|
|
|
6656
6712
|
}
|
|
6657
6713
|
}
|
|
6658
6714
|
console.log("[WebUI] No providers configured \u2014 showing setup screen");
|
|
6659
|
-
const provider =
|
|
6660
|
-
type: "anthropic",
|
|
6661
|
-
family: "anthropic",
|
|
6662
|
-
apiKey: "stub-key-replaced-on-setup"
|
|
6663
|
-
});
|
|
6715
|
+
const provider = makeUnconfiguredProvider();
|
|
6664
6716
|
return { provider, needsSetup: true };
|
|
6665
6717
|
}
|
|
6666
6718
|
|
|
@@ -8702,12 +8754,13 @@ function createConnectionHandler(opts) {
|
|
|
8702
8754
|
void opts.sessionStartPayload().then(async (payload) => {
|
|
8703
8755
|
const enriched = { ...payload };
|
|
8704
8756
|
try {
|
|
8705
|
-
const
|
|
8757
|
+
const replay = await opts.loadReplay?.();
|
|
8758
|
+
const live = replay?.messages ?? opts.context.messages ?? [];
|
|
8706
8759
|
const slice = live.length > REPLAY_MESSAGE_CAP ? live.slice(-REPLAY_MESSAGE_CAP) : live;
|
|
8707
8760
|
if (slice.length > 0) {
|
|
8708
8761
|
enriched.replayMessages = slice;
|
|
8709
8762
|
}
|
|
8710
|
-
const total = opts.tokenCounter.total();
|
|
8763
|
+
const total = replay?.usage ?? opts.tokenCounter.total();
|
|
8711
8764
|
if (total.input + total.output + (total.cacheRead ?? 0) + (total.cacheWrite ?? 0) > 0) {
|
|
8712
8765
|
enriched.replayUsage = {
|
|
8713
8766
|
input: total.input,
|
|
@@ -8834,8 +8887,8 @@ async function handleGoalGet(projectRoot, broadcast2) {
|
|
|
8834
8887
|
}
|
|
8835
8888
|
|
|
8836
8889
|
// src/server/handlers/worklist-handlers.ts
|
|
8837
|
-
function sendResult2(ws, ctx,
|
|
8838
|
-
ctx.send(ws, { type:
|
|
8890
|
+
function sendResult2(ws, ctx, ok2, message) {
|
|
8891
|
+
ctx.send(ws, { type: ok2 ? "ok" : "error", message });
|
|
8839
8892
|
}
|
|
8840
8893
|
function sessionPayload(ctx, payload) {
|
|
8841
8894
|
const provided = payload["sessionId"];
|
|
@@ -9056,6 +9109,541 @@ async function handleWorklistMessage(ctx, ws, msg) {
|
|
|
9056
9109
|
}
|
|
9057
9110
|
}
|
|
9058
9111
|
|
|
9112
|
+
// src/server/kanban-routes.ts
|
|
9113
|
+
import {
|
|
9114
|
+
addColumn,
|
|
9115
|
+
addGoalMetricToTask,
|
|
9116
|
+
addTask,
|
|
9117
|
+
assignTask,
|
|
9118
|
+
claimReadyTask,
|
|
9119
|
+
copyTaskToBoard,
|
|
9120
|
+
createBoard,
|
|
9121
|
+
deserializeTaskGraph,
|
|
9122
|
+
duplicateBoard,
|
|
9123
|
+
exportBoardToTaskGraph,
|
|
9124
|
+
generateBoardFromDescription,
|
|
9125
|
+
getBoard,
|
|
9126
|
+
getKanbanOrchestrationSnapshot,
|
|
9127
|
+
getTask,
|
|
9128
|
+
getTaskChain,
|
|
9129
|
+
listReadyTasks,
|
|
9130
|
+
listBoards,
|
|
9131
|
+
mergeTasks,
|
|
9132
|
+
moveTask,
|
|
9133
|
+
parseLinesIntoTasks,
|
|
9134
|
+
removeBoard,
|
|
9135
|
+
removeColumn,
|
|
9136
|
+
removeTask,
|
|
9137
|
+
releaseTaskClaim,
|
|
9138
|
+
serializeTaskGraph,
|
|
9139
|
+
setTaskChain,
|
|
9140
|
+
splitTask,
|
|
9141
|
+
syncBoardFromTaskGraph,
|
|
9142
|
+
transferTaskToBoard,
|
|
9143
|
+
updateBoard,
|
|
9144
|
+
updateGoalMetricOnTask,
|
|
9145
|
+
updateTask
|
|
9146
|
+
} from "@wrongstack/core";
|
|
9147
|
+
function ok(ws, type, data) {
|
|
9148
|
+
send(ws, { type, payload: { success: true, data: data ?? null } });
|
|
9149
|
+
}
|
|
9150
|
+
function fail(ws, type, message) {
|
|
9151
|
+
send(ws, { type, payload: { success: false, error: message } });
|
|
9152
|
+
}
|
|
9153
|
+
async function handleKanbanRoute(ws, msg, ctx) {
|
|
9154
|
+
if (!msg.type.startsWith("kanban.")) return false;
|
|
9155
|
+
const payload = msg.payload;
|
|
9156
|
+
const type = msg.type;
|
|
9157
|
+
try {
|
|
9158
|
+
switch (type) {
|
|
9159
|
+
case "kanban.list":
|
|
9160
|
+
ok(ws, type, await listBoards(ctx.projectRoot));
|
|
9161
|
+
return true;
|
|
9162
|
+
case "kanban.get": {
|
|
9163
|
+
const boardId = payload?.boardId;
|
|
9164
|
+
if (!boardId) {
|
|
9165
|
+
fail(ws, type, "boardId required");
|
|
9166
|
+
return true;
|
|
9167
|
+
}
|
|
9168
|
+
const board = await getBoard(ctx.projectRoot, boardId);
|
|
9169
|
+
board ? ok(ws, type, board) : fail(ws, type, `Board not found: ${boardId}`);
|
|
9170
|
+
return true;
|
|
9171
|
+
}
|
|
9172
|
+
case "kanban.create": {
|
|
9173
|
+
const title = payload?.title;
|
|
9174
|
+
if (!title) {
|
|
9175
|
+
fail(ws, type, "title required");
|
|
9176
|
+
return true;
|
|
9177
|
+
}
|
|
9178
|
+
ok(
|
|
9179
|
+
ws,
|
|
9180
|
+
type,
|
|
9181
|
+
await createBoard(ctx.projectRoot, {
|
|
9182
|
+
title,
|
|
9183
|
+
...payload?.description ? { description: payload.description } : {},
|
|
9184
|
+
...payload?.tags ? { tags: payload.tags } : {},
|
|
9185
|
+
...payload?.columns ? { columns: payload.columns } : {}
|
|
9186
|
+
})
|
|
9187
|
+
);
|
|
9188
|
+
return true;
|
|
9189
|
+
}
|
|
9190
|
+
case "kanban.update": {
|
|
9191
|
+
const boardId = payload?.boardId;
|
|
9192
|
+
if (!boardId) {
|
|
9193
|
+
fail(ws, type, "boardId required");
|
|
9194
|
+
return true;
|
|
9195
|
+
}
|
|
9196
|
+
const board = await updateBoard(ctx.projectRoot, boardId, {
|
|
9197
|
+
...payload?.title ? { title: payload.title } : {},
|
|
9198
|
+
...payload?.description ? { description: payload.description } : {},
|
|
9199
|
+
...payload?.tags ? { tags: payload.tags } : {},
|
|
9200
|
+
...payload?.columns ? { columns: payload.columns } : {}
|
|
9201
|
+
});
|
|
9202
|
+
board ? ok(ws, type, board) : fail(ws, type, `Board not found: ${boardId}`);
|
|
9203
|
+
return true;
|
|
9204
|
+
}
|
|
9205
|
+
case "kanban.duplicate": {
|
|
9206
|
+
const boardId = payload?.boardId;
|
|
9207
|
+
if (!boardId) {
|
|
9208
|
+
fail(ws, type, "boardId required");
|
|
9209
|
+
return true;
|
|
9210
|
+
}
|
|
9211
|
+
const board = await duplicateBoard(ctx.projectRoot, boardId, {
|
|
9212
|
+
...payload?.title ? { title: payload.title } : {},
|
|
9213
|
+
...typeof payload?.includeTasks === "boolean" ? { includeTasks: payload.includeTasks } : {},
|
|
9214
|
+
...typeof payload?.includeCompletedTasks === "boolean" ? { includeCompletedTasks: payload.includeCompletedTasks } : {},
|
|
9215
|
+
...typeof payload?.preserveAssignment === "boolean" ? { preserveAssignment: payload.preserveAssignment } : {}
|
|
9216
|
+
});
|
|
9217
|
+
board ? ok(ws, type, board) : fail(ws, type, `Board not found: ${boardId}`);
|
|
9218
|
+
return true;
|
|
9219
|
+
}
|
|
9220
|
+
case "kanban.delete": {
|
|
9221
|
+
const boardId = payload?.boardId;
|
|
9222
|
+
if (!boardId) {
|
|
9223
|
+
fail(ws, type, "boardId required");
|
|
9224
|
+
return true;
|
|
9225
|
+
}
|
|
9226
|
+
const board = await getBoard(ctx.projectRoot, boardId);
|
|
9227
|
+
ok(ws, type, {
|
|
9228
|
+
removed: board ? await removeBoard(ctx.projectRoot, board.id) : false,
|
|
9229
|
+
boardId: board?.id ?? boardId
|
|
9230
|
+
});
|
|
9231
|
+
return true;
|
|
9232
|
+
}
|
|
9233
|
+
case "kanban.generate": {
|
|
9234
|
+
const description = payload?.description;
|
|
9235
|
+
if (!description) {
|
|
9236
|
+
fail(ws, type, "description required");
|
|
9237
|
+
return true;
|
|
9238
|
+
}
|
|
9239
|
+
const board = await createBoard(
|
|
9240
|
+
ctx.projectRoot,
|
|
9241
|
+
generateBoardFromDescription({
|
|
9242
|
+
description,
|
|
9243
|
+
...payload?.title ? { title: payload.title } : {},
|
|
9244
|
+
...payload?.context ? { context: payload.context } : {}
|
|
9245
|
+
})
|
|
9246
|
+
);
|
|
9247
|
+
for (const taskInput of parseLinesIntoTasks(
|
|
9248
|
+
description,
|
|
9249
|
+
board.columns[0]?.id ?? "backlog"
|
|
9250
|
+
)) {
|
|
9251
|
+
await addTask(ctx.projectRoot, board.id, taskInput);
|
|
9252
|
+
}
|
|
9253
|
+
ok(ws, type, await getBoard(ctx.projectRoot, board.id) ?? board);
|
|
9254
|
+
return true;
|
|
9255
|
+
}
|
|
9256
|
+
case "kanban.task.ready": {
|
|
9257
|
+
ok(
|
|
9258
|
+
ws,
|
|
9259
|
+
type,
|
|
9260
|
+
await listReadyTasks(ctx.projectRoot, {
|
|
9261
|
+
...payload?.boardId ? { boardId: payload.boardId } : {},
|
|
9262
|
+
...payload?.query ? { query: payload.query } : {},
|
|
9263
|
+
...payload?.assignedAgent ? { assignedAgent: payload.assignedAgent } : {},
|
|
9264
|
+
...payload?.priority ? { priority: payload.priority } : {},
|
|
9265
|
+
...payload?.label ? { label: payload.label } : {},
|
|
9266
|
+
...payload?.chainId ? { chainId: payload.chainId } : {},
|
|
9267
|
+
...typeof payload?.limit === "number" ? { limit: payload.limit } : {}
|
|
9268
|
+
})
|
|
9269
|
+
);
|
|
9270
|
+
return true;
|
|
9271
|
+
}
|
|
9272
|
+
case "kanban.snapshot": {
|
|
9273
|
+
ok(
|
|
9274
|
+
ws,
|
|
9275
|
+
type,
|
|
9276
|
+
await getKanbanOrchestrationSnapshot(ctx.projectRoot, {
|
|
9277
|
+
...payload?.boardId ? { boardId: payload.boardId } : {},
|
|
9278
|
+
...payload?.query ? { query: payload.query } : {},
|
|
9279
|
+
...payload?.assignedAgent ? { assignedAgent: payload.assignedAgent } : {},
|
|
9280
|
+
...payload?.priority ? { priority: payload.priority } : {},
|
|
9281
|
+
...payload?.status ? { status: payload.status } : {},
|
|
9282
|
+
...payload?.label ? { label: payload.label } : {},
|
|
9283
|
+
...payload?.chainId ? { chainId: payload.chainId } : {}
|
|
9284
|
+
})
|
|
9285
|
+
);
|
|
9286
|
+
return true;
|
|
9287
|
+
}
|
|
9288
|
+
case "kanban.taskgraph.export": {
|
|
9289
|
+
const boardId = payload?.boardId;
|
|
9290
|
+
if (!boardId) {
|
|
9291
|
+
fail(ws, type, "boardId required");
|
|
9292
|
+
return true;
|
|
9293
|
+
}
|
|
9294
|
+
const exported = await exportBoardToTaskGraph(ctx.projectRoot, boardId, {
|
|
9295
|
+
...payload?.graphId ? { graphId: payload.graphId } : {},
|
|
9296
|
+
...payload?.specId ? { specId: payload.specId } : {},
|
|
9297
|
+
...payload?.title ? { title: payload.title } : {},
|
|
9298
|
+
...typeof payload?.preserveOriginTaskIds === "boolean" ? { preserveOriginTaskIds: payload.preserveOriginTaskIds } : {},
|
|
9299
|
+
...typeof payload?.includeArchived === "boolean" ? { includeArchived: payload.includeArchived } : {}
|
|
9300
|
+
});
|
|
9301
|
+
exported ? ok(ws, type, { board: exported.board, taskGraph: serializeTaskGraph(exported.graph) }) : fail(ws, type, `Board not found: ${boardId}`);
|
|
9302
|
+
return true;
|
|
9303
|
+
}
|
|
9304
|
+
case "kanban.taskgraph.sync": {
|
|
9305
|
+
const boardId = payload?.boardId;
|
|
9306
|
+
const taskGraph = payload?.taskGraph;
|
|
9307
|
+
if (!boardId || !taskGraph) {
|
|
9308
|
+
fail(ws, type, "boardId and taskGraph required");
|
|
9309
|
+
return true;
|
|
9310
|
+
}
|
|
9311
|
+
const result = await syncBoardFromTaskGraph(
|
|
9312
|
+
ctx.projectRoot,
|
|
9313
|
+
boardId,
|
|
9314
|
+
deserializeTaskGraph(taskGraph),
|
|
9315
|
+
{
|
|
9316
|
+
...payload?.title ? { title: payload.title } : {},
|
|
9317
|
+
...payload?.description ? { description: payload.description } : {},
|
|
9318
|
+
...payload?.tags ? { tags: payload.tags } : {},
|
|
9319
|
+
...payload?.generatedBy ? { generatedBy: payload.generatedBy } : {},
|
|
9320
|
+
...payload?.sourceSystem ? { sourceSystem: payload.sourceSystem } : {},
|
|
9321
|
+
...payload?.phaseId ? { phaseId: payload.phaseId } : {},
|
|
9322
|
+
...typeof payload?.includeCompletedTasks === "boolean" ? { includeCompletedTasks: payload.includeCompletedTasks } : {},
|
|
9323
|
+
...typeof payload?.archiveMissingTasks === "boolean" ? { archiveMissingTasks: payload.archiveMissingTasks } : {},
|
|
9324
|
+
...typeof payload?.preserveManualDependencies === "boolean" ? { preserveManualDependencies: payload.preserveManualDependencies } : {}
|
|
9325
|
+
}
|
|
9326
|
+
);
|
|
9327
|
+
result ? ok(ws, type, {
|
|
9328
|
+
board: result.board,
|
|
9329
|
+
taskIdMap: Object.fromEntries(result.taskIdMap),
|
|
9330
|
+
createdTaskIds: result.createdTaskIds,
|
|
9331
|
+
updatedTaskIds: result.updatedTaskIds,
|
|
9332
|
+
archivedTaskIds: result.archivedTaskIds
|
|
9333
|
+
}) : fail(ws, type, `Board not found: ${boardId}`);
|
|
9334
|
+
return true;
|
|
9335
|
+
}
|
|
9336
|
+
case "kanban.task.add": {
|
|
9337
|
+
const boardId = payload?.boardId;
|
|
9338
|
+
const title = payload?.title;
|
|
9339
|
+
if (!boardId || !title) {
|
|
9340
|
+
fail(ws, type, "boardId and title required");
|
|
9341
|
+
return true;
|
|
9342
|
+
}
|
|
9343
|
+
const result = await addTask(ctx.projectRoot, boardId, {
|
|
9344
|
+
title,
|
|
9345
|
+
columnId: payload?.columnId ?? "backlog",
|
|
9346
|
+
...payload?.description ? { description: payload.description } : {},
|
|
9347
|
+
...payload?.priority ? { priority: payload.priority } : {},
|
|
9348
|
+
...payload?.assignedAgent ? { assignedAgent: payload.assignedAgent } : {},
|
|
9349
|
+
...payload?.labels ? { labels: payload.labels } : {}
|
|
9350
|
+
});
|
|
9351
|
+
result ? ok(ws, type, result.task) : fail(ws, type, `Board not found: ${boardId}`);
|
|
9352
|
+
return true;
|
|
9353
|
+
}
|
|
9354
|
+
case "kanban.task.split": {
|
|
9355
|
+
const boardId = payload?.boardId;
|
|
9356
|
+
const taskId = payload?.taskId;
|
|
9357
|
+
const childTitles = payload?.childTitles;
|
|
9358
|
+
if (!boardId || !taskId || !childTitles?.length) {
|
|
9359
|
+
fail(ws, type, "boardId, taskId, and childTitles required");
|
|
9360
|
+
return true;
|
|
9361
|
+
}
|
|
9362
|
+
const result = await splitTask(ctx.projectRoot, boardId, taskId, {
|
|
9363
|
+
titles: childTitles,
|
|
9364
|
+
...payload?.targetColumnId ? { columnId: payload.targetColumnId } : {},
|
|
9365
|
+
...typeof payload?.inheritAssignment === "boolean" ? { inheritAssignment: payload.inheritAssignment } : {},
|
|
9366
|
+
...typeof payload?.inheritLabels === "boolean" ? { inheritLabels: payload.inheritLabels } : {},
|
|
9367
|
+
...typeof payload?.inheritSuccessCriteria === "boolean" ? { inheritSuccessCriteria: payload.inheritSuccessCriteria } : {},
|
|
9368
|
+
...typeof payload?.inheritGoalMetrics === "boolean" ? { inheritGoalMetrics: payload.inheritGoalMetrics } : {},
|
|
9369
|
+
...typeof payload?.inheritDependencies === "boolean" ? { inheritDependencies: payload.inheritDependencies } : {},
|
|
9370
|
+
...typeof payload?.chainChildren === "boolean" ? { chainChildren: payload.chainChildren } : {},
|
|
9371
|
+
...typeof payload?.rewireDependents === "boolean" ? { rewireDependents: payload.rewireDependents } : {}
|
|
9372
|
+
});
|
|
9373
|
+
result ? ok(ws, type, { board: result.board, parent: result.parent, children: result.children }) : fail(ws, type, "Board or task not found");
|
|
9374
|
+
return true;
|
|
9375
|
+
}
|
|
9376
|
+
case "kanban.task.merge": {
|
|
9377
|
+
const boardId = payload?.boardId;
|
|
9378
|
+
const taskIds = payload?.taskIds;
|
|
9379
|
+
const title = payload?.title;
|
|
9380
|
+
if (!boardId || !taskIds?.length || !title) {
|
|
9381
|
+
fail(ws, type, "boardId, taskIds, and title required");
|
|
9382
|
+
return true;
|
|
9383
|
+
}
|
|
9384
|
+
const result = await mergeTasks(ctx.projectRoot, boardId, {
|
|
9385
|
+
taskIds,
|
|
9386
|
+
title,
|
|
9387
|
+
...payload?.description ? { description: payload.description } : {},
|
|
9388
|
+
...payload?.targetColumnId ? { targetColumnId: payload.targetColumnId } : {},
|
|
9389
|
+
...typeof payload?.preserveAssignment === "boolean" ? { preserveAssignment: payload.preserveAssignment } : {},
|
|
9390
|
+
...typeof payload?.closeSourceTasks === "boolean" ? { closeSourceTasks: payload.closeSourceTasks } : {}
|
|
9391
|
+
});
|
|
9392
|
+
result ? ok(ws, type, {
|
|
9393
|
+
board: result.board,
|
|
9394
|
+
task: result.task,
|
|
9395
|
+
sourceTasks: result.sourceTasks
|
|
9396
|
+
}) : fail(ws, type, "Board or task not found");
|
|
9397
|
+
return true;
|
|
9398
|
+
}
|
|
9399
|
+
case "kanban.task.update": {
|
|
9400
|
+
const boardId = payload?.boardId;
|
|
9401
|
+
const taskId = payload?.taskId;
|
|
9402
|
+
if (!boardId || !taskId) {
|
|
9403
|
+
fail(ws, type, "boardId and taskId required");
|
|
9404
|
+
return true;
|
|
9405
|
+
}
|
|
9406
|
+
const board = await updateTask(ctx.projectRoot, boardId, taskId, {
|
|
9407
|
+
...payload?.title ? { title: payload.title } : {},
|
|
9408
|
+
...payload?.description ? { description: payload.description } : {},
|
|
9409
|
+
...payload?.columnId ? { columnId: payload.columnId } : {},
|
|
9410
|
+
...payload?.priority ? { priority: payload.priority } : {},
|
|
9411
|
+
...payload?.status ? { status: payload.status } : {},
|
|
9412
|
+
...payload?.assignedAgent ? { assignedAgent: payload.assignedAgent } : {},
|
|
9413
|
+
...payload?.labels ? { labels: payload.labels } : {}
|
|
9414
|
+
});
|
|
9415
|
+
board ? ok(ws, type, findTask(board.tasks, taskId)) : fail(ws, type, "Board or task not found");
|
|
9416
|
+
return true;
|
|
9417
|
+
}
|
|
9418
|
+
case "kanban.task.move": {
|
|
9419
|
+
const boardId = payload?.boardId;
|
|
9420
|
+
const taskId = payload?.taskId;
|
|
9421
|
+
const columnId = payload?.columnId;
|
|
9422
|
+
if (!boardId || !taskId || !columnId) {
|
|
9423
|
+
fail(ws, type, "boardId, taskId, columnId required");
|
|
9424
|
+
return true;
|
|
9425
|
+
}
|
|
9426
|
+
const board = await moveTask(
|
|
9427
|
+
ctx.projectRoot,
|
|
9428
|
+
boardId,
|
|
9429
|
+
taskId,
|
|
9430
|
+
columnId,
|
|
9431
|
+
payload?.order
|
|
9432
|
+
);
|
|
9433
|
+
board ? ok(ws, type, findTask(board.tasks, taskId)) : fail(ws, type, "Move failed");
|
|
9434
|
+
return true;
|
|
9435
|
+
}
|
|
9436
|
+
case "kanban.task.copy":
|
|
9437
|
+
case "kanban.task.transfer": {
|
|
9438
|
+
const boardId = payload?.boardId;
|
|
9439
|
+
const taskId = payload?.taskId;
|
|
9440
|
+
const targetBoardId = payload?.targetBoardId;
|
|
9441
|
+
if (!boardId || !taskId || !targetBoardId) {
|
|
9442
|
+
fail(ws, type, "boardId, taskId, targetBoardId required");
|
|
9443
|
+
return true;
|
|
9444
|
+
}
|
|
9445
|
+
const result = type === "kanban.task.copy" ? await copyTaskToBoard(ctx.projectRoot, boardId, taskId, targetBoardId, {
|
|
9446
|
+
...payload?.targetColumnId ? { targetColumnId: payload.targetColumnId } : {},
|
|
9447
|
+
...typeof payload?.preserveAssignment === "boolean" ? { preserveAssignment: payload.preserveAssignment } : {},
|
|
9448
|
+
...typeof payload?.preserveDependencies === "boolean" ? { preserveDependencies: payload.preserveDependencies } : {}
|
|
9449
|
+
}) : await transferTaskToBoard(ctx.projectRoot, boardId, taskId, targetBoardId, {
|
|
9450
|
+
...payload?.targetColumnId ? { targetColumnId: payload.targetColumnId } : {},
|
|
9451
|
+
...typeof payload?.preserveAssignment === "boolean" ? { preserveAssignment: payload.preserveAssignment } : {},
|
|
9452
|
+
...typeof payload?.preserveDependencies === "boolean" ? { preserveDependencies: payload.preserveDependencies } : {}
|
|
9453
|
+
});
|
|
9454
|
+
result ? ok(ws, type, result.targetBoard) : fail(ws, type, "Board or task not found");
|
|
9455
|
+
return true;
|
|
9456
|
+
}
|
|
9457
|
+
case "kanban.task.chain": {
|
|
9458
|
+
const boardId = payload?.boardId;
|
|
9459
|
+
const taskIds = payload?.taskIds;
|
|
9460
|
+
if (!boardId || !taskIds?.length) {
|
|
9461
|
+
fail(ws, type, "boardId and taskIds required");
|
|
9462
|
+
return true;
|
|
9463
|
+
}
|
|
9464
|
+
const result = await setTaskChain(ctx.projectRoot, boardId, {
|
|
9465
|
+
taskIds,
|
|
9466
|
+
...payload?.chainId ? { chainId: payload.chainId } : {},
|
|
9467
|
+
...typeof payload?.enforceDependencies === "boolean" ? { enforceDependencies: payload.enforceDependencies } : {}
|
|
9468
|
+
});
|
|
9469
|
+
result ? ok(ws, type, { board: result.board, chainId: result.chainId, tasks: result.tasks }) : fail(ws, type, "Board or task not found");
|
|
9470
|
+
return true;
|
|
9471
|
+
}
|
|
9472
|
+
case "kanban.task.chain.get": {
|
|
9473
|
+
const boardId = payload?.boardId;
|
|
9474
|
+
const taskOrChainId = payload?.taskId ?? payload?.chainId;
|
|
9475
|
+
if (!boardId || !taskOrChainId) {
|
|
9476
|
+
fail(ws, type, "boardId and taskId or chainId required");
|
|
9477
|
+
return true;
|
|
9478
|
+
}
|
|
9479
|
+
const result = await getTaskChain(ctx.projectRoot, boardId, taskOrChainId);
|
|
9480
|
+
result ? ok(ws, type, { board: result.board, chainId: result.chainId, tasks: result.tasks }) : fail(ws, type, "Chain not found");
|
|
9481
|
+
return true;
|
|
9482
|
+
}
|
|
9483
|
+
case "kanban.task.claim": {
|
|
9484
|
+
const result = await claimReadyTask(ctx.projectRoot, {
|
|
9485
|
+
...payload?.boardId ? { boardId: payload.boardId } : {},
|
|
9486
|
+
...payload?.taskId ? { taskId: payload.taskId } : {},
|
|
9487
|
+
...payload?.agentId ? { agentId: payload.agentId } : {},
|
|
9488
|
+
...payload?.name ? { name: payload.name } : {},
|
|
9489
|
+
...payload?.role ? { role: payload.role } : {},
|
|
9490
|
+
...payload?.provider ? { provider: payload.provider } : {},
|
|
9491
|
+
...payload?.model ? { model: payload.model } : {},
|
|
9492
|
+
...payload?.fallbackProfile ? { fallbackProfile: payload.fallbackProfile } : {},
|
|
9493
|
+
...payload?.fallbackModels ? { fallbackModels: payload.fallbackModels } : {},
|
|
9494
|
+
...payload?.tools ? { tools: payload.tools } : {},
|
|
9495
|
+
...payload?.allowedCapabilities ? { allowedCapabilities: payload.allowedCapabilities } : {},
|
|
9496
|
+
...payload?.assignee ? { assignee: payload.assignee } : {},
|
|
9497
|
+
status: payload?.assignmentStatus ?? "queued"
|
|
9498
|
+
});
|
|
9499
|
+
result ? ok(ws, type, { board: result.board, task: result.task }) : fail(ws, type, "No ready kanban task matched the claim");
|
|
9500
|
+
return true;
|
|
9501
|
+
}
|
|
9502
|
+
case "kanban.task.release": {
|
|
9503
|
+
const boardId = payload?.boardId;
|
|
9504
|
+
const taskId = payload?.taskId;
|
|
9505
|
+
if (!boardId || !taskId) {
|
|
9506
|
+
fail(ws, type, "boardId and taskId required");
|
|
9507
|
+
return true;
|
|
9508
|
+
}
|
|
9509
|
+
const board = await releaseTaskClaim(ctx.projectRoot, boardId, taskId, {
|
|
9510
|
+
...payload?.status ? { status: payload.status } : {},
|
|
9511
|
+
...payload?.reason ? { reason: payload.reason } : {},
|
|
9512
|
+
...typeof payload?.clearAssignee === "boolean" ? { clearAssignee: payload.clearAssignee } : {}
|
|
9513
|
+
});
|
|
9514
|
+
board ? ok(ws, type, board) : fail(ws, type, "Board or task not found");
|
|
9515
|
+
return true;
|
|
9516
|
+
}
|
|
9517
|
+
case "kanban.task.metric.add": {
|
|
9518
|
+
const boardId = payload?.boardId;
|
|
9519
|
+
const taskId = payload?.taskId;
|
|
9520
|
+
const name2 = payload?.name;
|
|
9521
|
+
if (!boardId || !taskId || !name2) {
|
|
9522
|
+
fail(ws, type, "boardId, taskId, and name required");
|
|
9523
|
+
return true;
|
|
9524
|
+
}
|
|
9525
|
+
const board = await addGoalMetricToTask(ctx.projectRoot, boardId, taskId, {
|
|
9526
|
+
name: name2,
|
|
9527
|
+
...payload?.status ? { status: payload.status } : {},
|
|
9528
|
+
...payload?.target !== void 0 ? { target: payload.target } : {},
|
|
9529
|
+
...payload?.current !== void 0 ? { current: payload.current } : {},
|
|
9530
|
+
...payload?.unit ? { unit: payload.unit } : {},
|
|
9531
|
+
...payload?.notes ? { notes: payload.notes } : {}
|
|
9532
|
+
});
|
|
9533
|
+
board ? ok(ws, type, board) : fail(ws, type, "Board or task not found");
|
|
9534
|
+
return true;
|
|
9535
|
+
}
|
|
9536
|
+
case "kanban.task.metric.update": {
|
|
9537
|
+
const boardId = payload?.boardId;
|
|
9538
|
+
const taskId = payload?.taskId;
|
|
9539
|
+
const metricId = payload?.metricId;
|
|
9540
|
+
if (!boardId || !taskId || !metricId) {
|
|
9541
|
+
fail(ws, type, "boardId, taskId, and metricId required");
|
|
9542
|
+
return true;
|
|
9543
|
+
}
|
|
9544
|
+
const board = await updateGoalMetricOnTask(ctx.projectRoot, boardId, taskId, metricId, {
|
|
9545
|
+
...payload?.name ? { name: payload.name } : {},
|
|
9546
|
+
...payload?.status ? { status: payload.status } : {},
|
|
9547
|
+
...payload?.target !== void 0 ? { target: payload.target } : {},
|
|
9548
|
+
...payload?.current !== void 0 ? { current: payload.current } : {},
|
|
9549
|
+
...payload?.unit ? { unit: payload.unit } : {},
|
|
9550
|
+
...payload?.notes ? { notes: payload.notes } : {}
|
|
9551
|
+
});
|
|
9552
|
+
board ? ok(ws, type, board) : fail(ws, type, "Metric not found");
|
|
9553
|
+
return true;
|
|
9554
|
+
}
|
|
9555
|
+
case "kanban.task.assign": {
|
|
9556
|
+
const boardId = payload?.boardId;
|
|
9557
|
+
const taskId = payload?.taskId;
|
|
9558
|
+
if (!boardId || !taskId) {
|
|
9559
|
+
fail(ws, type, "boardId and taskId required");
|
|
9560
|
+
return true;
|
|
9561
|
+
}
|
|
9562
|
+
const board = await assignTask(ctx.projectRoot, boardId, taskId, {
|
|
9563
|
+
...payload?.agentId ? { agentId: payload.agentId } : {},
|
|
9564
|
+
...payload?.name ? { name: payload.name } : {},
|
|
9565
|
+
...payload?.role ? { role: payload.role } : {},
|
|
9566
|
+
...payload?.provider ? { provider: payload.provider } : {},
|
|
9567
|
+
...payload?.model ? { model: payload.model } : {},
|
|
9568
|
+
...payload?.fallbackProfile ? { fallbackProfile: payload.fallbackProfile } : {},
|
|
9569
|
+
...payload?.fallbackModels ? { fallbackModels: payload.fallbackModels } : {},
|
|
9570
|
+
...payload?.tools ? { tools: payload.tools } : {},
|
|
9571
|
+
...payload?.allowedCapabilities ? { allowedCapabilities: payload.allowedCapabilities } : {}
|
|
9572
|
+
});
|
|
9573
|
+
board ? ok(ws, type, findTask(board.tasks, taskId)) : fail(ws, type, "Board or task not found");
|
|
9574
|
+
return true;
|
|
9575
|
+
}
|
|
9576
|
+
case "kanban.task.dispatch":
|
|
9577
|
+
fail(
|
|
9578
|
+
ws,
|
|
9579
|
+
type,
|
|
9580
|
+
"Kanban agent dispatch is only available from the CLI-hosted WebUI runtime."
|
|
9581
|
+
);
|
|
9582
|
+
return true;
|
|
9583
|
+
case "kanban.task.remove": {
|
|
9584
|
+
const boardId = payload?.boardId;
|
|
9585
|
+
const taskId = payload?.taskId;
|
|
9586
|
+
if (!boardId || !taskId) {
|
|
9587
|
+
fail(ws, type, "boardId and taskId required");
|
|
9588
|
+
return true;
|
|
9589
|
+
}
|
|
9590
|
+
const task = await getTask(ctx.projectRoot, boardId, taskId);
|
|
9591
|
+
if (!task) {
|
|
9592
|
+
fail(ws, type, "Board or task not found");
|
|
9593
|
+
return true;
|
|
9594
|
+
}
|
|
9595
|
+
const board = await removeTask(ctx.projectRoot, boardId, taskId);
|
|
9596
|
+
board ? ok(ws, type, { removed: true, boardId: board.id, taskId: task.id, board }) : fail(ws, type, "Board or task not found");
|
|
9597
|
+
return true;
|
|
9598
|
+
}
|
|
9599
|
+
case "kanban.task.get": {
|
|
9600
|
+
const boardId = payload?.boardId;
|
|
9601
|
+
const taskId = payload?.taskId;
|
|
9602
|
+
if (!boardId || !taskId) {
|
|
9603
|
+
fail(ws, type, "boardId and taskId required");
|
|
9604
|
+
return true;
|
|
9605
|
+
}
|
|
9606
|
+
const task = await getTask(ctx.projectRoot, boardId, taskId);
|
|
9607
|
+
task ? ok(ws, type, task) : fail(ws, type, "Task not found");
|
|
9608
|
+
return true;
|
|
9609
|
+
}
|
|
9610
|
+
case "kanban.column.add": {
|
|
9611
|
+
const boardId = payload?.boardId;
|
|
9612
|
+
const title = payload?.title;
|
|
9613
|
+
if (!boardId || !title) {
|
|
9614
|
+
fail(ws, type, "boardId and title required");
|
|
9615
|
+
return true;
|
|
9616
|
+
}
|
|
9617
|
+
const result = await addColumn(ctx.projectRoot, boardId, { title });
|
|
9618
|
+
result ? ok(ws, type, result.board.columns) : fail(ws, type, `Board not found: ${boardId}`);
|
|
9619
|
+
return true;
|
|
9620
|
+
}
|
|
9621
|
+
case "kanban.column.remove": {
|
|
9622
|
+
const boardId = payload?.boardId;
|
|
9623
|
+
const columnId = payload?.columnId;
|
|
9624
|
+
if (!boardId || !columnId) {
|
|
9625
|
+
fail(ws, type, "boardId and columnId required");
|
|
9626
|
+
return true;
|
|
9627
|
+
}
|
|
9628
|
+
const board = await removeColumn(ctx.projectRoot, boardId, columnId, {
|
|
9629
|
+
moveTasksToColumnId: payload?.moveTasksToColumnId
|
|
9630
|
+
});
|
|
9631
|
+
board ? ok(ws, type, { removed: true, boardId: board.id, columnId, board }) : fail(ws, type, `Column not found: ${columnId}`);
|
|
9632
|
+
return true;
|
|
9633
|
+
}
|
|
9634
|
+
default:
|
|
9635
|
+
fail(ws, type, `Unknown kanban message type: ${type}`);
|
|
9636
|
+
return true;
|
|
9637
|
+
}
|
|
9638
|
+
} catch (err) {
|
|
9639
|
+
fail(ws, type, err instanceof Error ? err.message : String(err));
|
|
9640
|
+
return true;
|
|
9641
|
+
}
|
|
9642
|
+
}
|
|
9643
|
+
function findTask(tasks, taskId) {
|
|
9644
|
+
return tasks.find((task) => task.id === taskId || task.id.startsWith(taskId));
|
|
9645
|
+
}
|
|
9646
|
+
|
|
9059
9647
|
// src/server/mailbox-routes.ts
|
|
9060
9648
|
async function handleMailboxRoute(ws, msg, handlers) {
|
|
9061
9649
|
switch (msg.type) {
|
|
@@ -9540,6 +10128,7 @@ function createMessageDispatcher(opts) {
|
|
|
9540
10128
|
if (await handleSpecsRoute(ws, msg, routes.specsRoutes)) return;
|
|
9541
10129
|
if (await handleSddBoardRoute(ws, msg, routes.sddBoardRoutes)) return;
|
|
9542
10130
|
if (await handleSddWizardRoute(ws, msg, routes.sddWizardRoutes)) return;
|
|
10131
|
+
if (await handleKanbanRoute(ws, msg, { projectRoot: state.getProjectRoot() })) return;
|
|
9543
10132
|
if (msg.type.startsWith("worktree.") && await deps2.worktreeHandler.handleMessage(
|
|
9544
10133
|
msg
|
|
9545
10134
|
))
|
|
@@ -9554,7 +10143,10 @@ function createMessageDispatcher(opts) {
|
|
|
9554
10143
|
case "collab.resume":
|
|
9555
10144
|
case "collab.grant_control":
|
|
9556
10145
|
case "collab.inject_tool": {
|
|
9557
|
-
deps2.collabHandler.handleMessage(
|
|
10146
|
+
deps2.collabHandler.handleMessage(
|
|
10147
|
+
ws,
|
|
10148
|
+
msg
|
|
10149
|
+
);
|
|
9558
10150
|
return;
|
|
9559
10151
|
}
|
|
9560
10152
|
// Integrated terminal — interactive pty transport, bypasses the agent loop.
|
|
@@ -9582,7 +10174,10 @@ function createMessageDispatcher(opts) {
|
|
|
9582
10174
|
runLock.set(thisRun);
|
|
9583
10175
|
try {
|
|
9584
10176
|
const maxIt = typeof deps2.context.meta["maxIterations"] === "number" ? deps2.context.meta["maxIterations"] : void 0;
|
|
9585
|
-
const result = await deps2.agent.run(content, {
|
|
10177
|
+
const result = await deps2.agent.run(content, {
|
|
10178
|
+
signal: thisRun.signal,
|
|
10179
|
+
maxIterations: maxIt
|
|
10180
|
+
});
|
|
9586
10181
|
send(ws, {
|
|
9587
10182
|
type: "run.result",
|
|
9588
10183
|
payload: sessionPayload2({
|
|
@@ -9722,22 +10317,43 @@ function createMessageDispatcher(opts) {
|
|
|
9722
10317
|
break;
|
|
9723
10318
|
// Design Studio — shared handlers (design-handlers.ts).
|
|
9724
10319
|
case "design.list":
|
|
9725
|
-
await handleDesignList(ws, {
|
|
10320
|
+
await handleDesignList(ws, {
|
|
10321
|
+
projectRoot: state.getProjectRoot(),
|
|
10322
|
+
agentMeta: deps2.context
|
|
10323
|
+
});
|
|
9726
10324
|
break;
|
|
9727
10325
|
case "design.use":
|
|
9728
|
-
await handleDesignUse(
|
|
10326
|
+
await handleDesignUse(
|
|
10327
|
+
ws,
|
|
10328
|
+
{ projectRoot: state.getProjectRoot(), agentMeta: deps2.context },
|
|
10329
|
+
msg
|
|
10330
|
+
);
|
|
9729
10331
|
break;
|
|
9730
10332
|
case "design.state":
|
|
9731
|
-
await handleDesignState(ws, {
|
|
10333
|
+
await handleDesignState(ws, {
|
|
10334
|
+
projectRoot: state.getProjectRoot(),
|
|
10335
|
+
agentMeta: deps2.context
|
|
10336
|
+
});
|
|
9732
10337
|
break;
|
|
9733
10338
|
case "design.set":
|
|
9734
|
-
await handleDesignSet(
|
|
10339
|
+
await handleDesignSet(
|
|
10340
|
+
ws,
|
|
10341
|
+
{ projectRoot: state.getProjectRoot(), agentMeta: deps2.context },
|
|
10342
|
+
msg
|
|
10343
|
+
);
|
|
9735
10344
|
break;
|
|
9736
10345
|
case "design.materialize":
|
|
9737
|
-
await handleDesignMaterialize(
|
|
10346
|
+
await handleDesignMaterialize(
|
|
10347
|
+
ws,
|
|
10348
|
+
{ projectRoot: state.getProjectRoot(), agentMeta: deps2.context },
|
|
10349
|
+
msg
|
|
10350
|
+
);
|
|
9738
10351
|
break;
|
|
9739
10352
|
case "design.verify":
|
|
9740
|
-
await handleDesignVerify(ws, {
|
|
10353
|
+
await handleDesignVerify(ws, {
|
|
10354
|
+
projectRoot: state.getProjectRoot(),
|
|
10355
|
+
agentMeta: deps2.context
|
|
10356
|
+
});
|
|
9741
10357
|
break;
|
|
9742
10358
|
case "diag.get": {
|
|
9743
10359
|
if (!ensureCurrentSession(ws, msg, "diag.get")) return;
|
|
@@ -11930,6 +12546,11 @@ async function startWebUI(opts = {}) {
|
|
|
11930
12546
|
sessionStartPayload,
|
|
11931
12547
|
tokenCounter,
|
|
11932
12548
|
context,
|
|
12549
|
+
loadReplay: async () => {
|
|
12550
|
+
await session.flush().catch(() => void 0);
|
|
12551
|
+
const data = await sessionStore.load(session.id);
|
|
12552
|
+
return { messages: data.messages, usage: data.usage };
|
|
12553
|
+
},
|
|
11933
12554
|
clients,
|
|
11934
12555
|
pendingConfirms,
|
|
11935
12556
|
autoPhaseHandler,
|