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