@wrongstack/webui 0.282.0 → 0.282.2
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-BrQc2ss-.js → AnalyticsDashboard-CPLSpHzV.js} +1 -1
- package/dist/assets/{AutoPhaseView-8NTdnZ0a.js → AutoPhaseView-HIzNPExo.js} +1 -1
- package/dist/assets/{CodeEditor-C-pJLtUR.js → CodeEditor-dOQDoCfn.js} +1 -1
- package/dist/assets/{DebugDashboard-BHpiEOcf.js → DebugDashboard-CQCI-B4W.js} +1 -1
- package/dist/assets/{DesignGalleryView-M6Hp7s9b.js → DesignGalleryView-BxTlrmrr.js} +1 -1
- package/dist/assets/{KanbanView-nMv98m0N.js → KanbanView-2uDRr6Qd.js} +1 -1
- package/dist/assets/{MailboxDetailView-g3IQx4DB.js → MailboxDetailView-B0DCs5lu.js} +1 -1
- package/dist/assets/OfficeMapPanel-lGSaptet.js +4 -0
- package/dist/assets/{ProcessMonitor-CbfQYneY.js → ProcessMonitor-eTb8_-ZW.js} +1 -1
- package/dist/assets/{QueuePanel-eGK1SSKx.js → QueuePanel-TbbkNAx_.js} +1 -1
- package/dist/assets/{RefreshDebugView-BXq2P3wo.js → RefreshDebugView-CX6x-xHs.js} +1 -1
- package/dist/assets/SddBoardView-BXQsH6fr.js +2 -0
- package/dist/assets/{SddFlowGraph-CtMpzU4S.js → SddFlowGraph-DTWV-DPB.js} +1 -1
- package/dist/assets/SddWizard-1ZhDgcgM.js +1 -0
- package/dist/assets/{SessionsDashboard-Dqsrp5CK.js → SessionsDashboard-CfNbqjeh.js} +1 -1
- package/dist/assets/SkillDetailView-UzixISza.js +2 -0
- package/dist/assets/{SpecsView-BnUsqkrG.js → SpecsView-BO8yG6ID.js} +1 -1
- package/dist/assets/{TerminalPanel-BCpddej2.js → TerminalPanel-Bjbu9ktV.js} +1 -1
- package/dist/assets/{chat-store-CIMOL6-x.js → chat-store-7ekEnPAf.js} +1 -1
- package/dist/assets/{i18n-CNo6A2vu.js → i18n-BCQuDmQo.js} +2 -2
- package/dist/assets/index-Cb-hw9qG.js +147 -0
- package/dist/assets/index-ZtF5f7wy.css +1 -0
- package/dist/assets/{session-store-DN1UYDL9.js → session-store-KCJiKVqL.js} +1 -1
- package/dist/assets/settings-wb322bGN.js +1 -0
- package/dist/assets/{ui-store-BdOsq6T-.js → ui-store-CcznRsiV.js} +1 -1
- package/dist/assets/utils-C3qJEm2b.js +1 -0
- package/dist/assets/{vendor-Ch4m_qLI.js → vendor-Cm3Womkr.js} +25 -25
- package/dist/assets/{ws-client-BAV7SLzK.js → ws-client-9j1mjm9I.js} +1 -1
- package/dist/assets/{xyflow-D5_yey7w.js → xyflow-Dy5Edi88.js} +3 -3
- package/dist/index.html +10 -10
- package/dist/index.js +4168 -3743
- package/dist/index.js.map +1 -1
- package/dist/providers.json +2 -2
- package/dist/server/entry.js +342 -16
- package/dist/server/entry.js.map +1 -1
- package/dist/server/index.js +342 -16
- package/dist/server/index.js.map +1 -1
- package/dist/types.d.ts +28 -0
- package/package.json +6 -6
- package/dist/assets/OfficeMapPanel-D3VE7UCd.js +0 -4
- package/dist/assets/SddBoardView-DvuH4f4e.js +0 -2
- package/dist/assets/SddWizard-G55Yw9Bb.js +0 -1
- package/dist/assets/SkillDetailView-CX9zeWBG.js +0 -2
- package/dist/assets/index-BhO3caLf.js +0 -146
- package/dist/assets/index-D7_FeyCA.css +0 -1
- package/dist/assets/settings-CGhOOFpI.js +0 -1
- package/dist/assets/utils-DBns3uMk.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, {
|
|
@@ -6073,7 +6073,14 @@ function setupEvents(deps2) {
|
|
|
6073
6073
|
await fs10.mkdir(dir, { recursive: true });
|
|
6074
6074
|
await fs10.writeFile(statusFile, JSON.stringify(e, null, 2), "utf-8");
|
|
6075
6075
|
} catch (err) {
|
|
6076
|
-
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
|
+
);
|
|
6077
6084
|
}
|
|
6078
6085
|
}
|
|
6079
6086
|
});
|
|
@@ -6163,7 +6170,14 @@ function setupEvents(deps2) {
|
|
|
6163
6170
|
console.log(`[setup-events] Watching ${projectsDir} for status.json changes (hash-filtered, debounced)`);
|
|
6164
6171
|
}
|
|
6165
6172
|
} catch (err) {
|
|
6166
|
-
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
|
+
);
|
|
6167
6181
|
}
|
|
6168
6182
|
};
|
|
6169
6183
|
events.on("client.status", (e) => {
|
|
@@ -6623,6 +6637,39 @@ import { toErrorMessage as toErrorMessage5 } from "@wrongstack/core/utils";
|
|
|
6623
6637
|
import { expectDefined as expectDefined2 } from "@wrongstack/core";
|
|
6624
6638
|
import { toErrorMessage as toErrorMessage4 } from "@wrongstack/core/utils";
|
|
6625
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
|
+
}
|
|
6626
6673
|
function logCreateFailure(event, err) {
|
|
6627
6674
|
console.error(
|
|
6628
6675
|
JSON.stringify({
|
|
@@ -6669,11 +6716,7 @@ function resolveSetupProvider(opts) {
|
|
|
6669
6716
|
}
|
|
6670
6717
|
}
|
|
6671
6718
|
console.log("[WebUI] No providers configured \u2014 showing setup screen");
|
|
6672
|
-
const provider =
|
|
6673
|
-
type: "anthropic",
|
|
6674
|
-
family: "anthropic",
|
|
6675
|
-
apiKey: "stub-key-replaced-on-setup"
|
|
6676
|
-
});
|
|
6719
|
+
const provider = makeUnconfiguredProvider();
|
|
6677
6720
|
return { provider, needsSetup: true };
|
|
6678
6721
|
}
|
|
6679
6722
|
|
|
@@ -9073,22 +9116,36 @@ async function handleWorklistMessage(ctx, ws, msg) {
|
|
|
9073
9116
|
// src/server/kanban-routes.ts
|
|
9074
9117
|
import {
|
|
9075
9118
|
addColumn,
|
|
9119
|
+
addGoalMetricToTask,
|
|
9076
9120
|
addTask,
|
|
9077
9121
|
assignTask,
|
|
9122
|
+
claimReadyTask,
|
|
9078
9123
|
copyTaskToBoard,
|
|
9079
9124
|
createBoard,
|
|
9125
|
+
deserializeTaskGraph,
|
|
9080
9126
|
duplicateBoard,
|
|
9127
|
+
exportBoardToTaskGraph,
|
|
9081
9128
|
generateBoardFromDescription,
|
|
9082
9129
|
getBoard,
|
|
9130
|
+
getKanbanOrchestrationSnapshot,
|
|
9083
9131
|
getTask,
|
|
9132
|
+
getTaskChain,
|
|
9133
|
+
listReadyTasks,
|
|
9084
9134
|
listBoards,
|
|
9135
|
+
mergeTasks,
|
|
9085
9136
|
moveTask,
|
|
9086
9137
|
parseLinesIntoTasks,
|
|
9087
9138
|
removeBoard,
|
|
9088
9139
|
removeColumn,
|
|
9089
9140
|
removeTask,
|
|
9141
|
+
releaseTaskClaim,
|
|
9142
|
+
serializeTaskGraph,
|
|
9143
|
+
setTaskChain,
|
|
9144
|
+
splitTask,
|
|
9145
|
+
syncBoardFromTaskGraph,
|
|
9090
9146
|
transferTaskToBoard,
|
|
9091
9147
|
updateBoard,
|
|
9148
|
+
updateGoalMetricOnTask,
|
|
9092
9149
|
updateTask
|
|
9093
9150
|
} from "@wrongstack/core";
|
|
9094
9151
|
function ok(ws, type, data) {
|
|
@@ -9170,7 +9227,11 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
9170
9227
|
fail(ws, type, "boardId required");
|
|
9171
9228
|
return true;
|
|
9172
9229
|
}
|
|
9173
|
-
|
|
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
|
+
});
|
|
9174
9235
|
return true;
|
|
9175
9236
|
}
|
|
9176
9237
|
case "kanban.generate": {
|
|
@@ -9196,6 +9257,86 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
9196
9257
|
ok(ws, type, await getBoard(ctx.projectRoot, board.id) ?? board);
|
|
9197
9258
|
return true;
|
|
9198
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
|
+
}
|
|
9199
9340
|
case "kanban.task.add": {
|
|
9200
9341
|
const boardId = payload?.boardId;
|
|
9201
9342
|
const title = payload?.title;
|
|
@@ -9214,6 +9355,51 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
9214
9355
|
result ? ok(ws, type, result.task) : fail(ws, type, `Board not found: ${boardId}`);
|
|
9215
9356
|
return true;
|
|
9216
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
|
+
}
|
|
9217
9403
|
case "kanban.task.update": {
|
|
9218
9404
|
const boardId = payload?.boardId;
|
|
9219
9405
|
const taskId = payload?.taskId;
|
|
@@ -9272,6 +9458,104 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
9272
9458
|
result ? ok(ws, type, result.targetBoard) : fail(ws, type, "Board or task not found");
|
|
9273
9459
|
return true;
|
|
9274
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
|
+
}
|
|
9275
9559
|
case "kanban.task.assign": {
|
|
9276
9560
|
const boardId = payload?.boardId;
|
|
9277
9561
|
const taskId = payload?.taskId;
|
|
@@ -9307,8 +9591,13 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
9307
9591
|
fail(ws, type, "boardId and taskId required");
|
|
9308
9592
|
return true;
|
|
9309
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
|
+
}
|
|
9310
9599
|
const board = await removeTask(ctx.projectRoot, boardId, taskId);
|
|
9311
|
-
board ? ok(ws, type, { removed: true }) : fail(ws, type, "Board or task not found");
|
|
9600
|
+
board ? ok(ws, type, { removed: true, boardId: board.id, taskId: task.id, board }) : fail(ws, type, "Board or task not found");
|
|
9312
9601
|
return true;
|
|
9313
9602
|
}
|
|
9314
9603
|
case "kanban.task.get": {
|
|
@@ -9343,7 +9632,7 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
9343
9632
|
const board = await removeColumn(ctx.projectRoot, boardId, columnId, {
|
|
9344
9633
|
moveTasksToColumnId: payload?.moveTasksToColumnId
|
|
9345
9634
|
});
|
|
9346
|
-
board ? ok(ws, type, { removed: true }) : fail(ws, type, `Column not found: ${columnId}`);
|
|
9635
|
+
board ? ok(ws, type, { removed: true, boardId: board.id, columnId, board }) : fail(ws, type, `Column not found: ${columnId}`);
|
|
9347
9636
|
return true;
|
|
9348
9637
|
}
|
|
9349
9638
|
default:
|
|
@@ -9943,18 +10232,55 @@ function createMessageDispatcher(opts) {
|
|
|
9943
10232
|
send(ws, { type: "pong", payload: {} });
|
|
9944
10233
|
break;
|
|
9945
10234
|
case "tools.list": {
|
|
9946
|
-
const
|
|
9947
|
-
|
|
10235
|
+
const entries = [...deps2.toolRegistry.listWithOwner(), ...deps2.toolRegistry.listDisabled()];
|
|
10236
|
+
const list = entries.map(({ tool, owner }) => {
|
|
10237
|
+
const schema = tool.inputSchema ?? {};
|
|
9948
10238
|
const params = schema.properties ? Object.keys(schema.properties) : [];
|
|
9949
10239
|
return {
|
|
9950
|
-
name:
|
|
9951
|
-
|
|
9952
|
-
|
|
10240
|
+
name: tool.name,
|
|
10241
|
+
owner,
|
|
10242
|
+
description: tool.description ?? "",
|
|
10243
|
+
params,
|
|
10244
|
+
disabled: deps2.toolRegistry.isDisabled(tool.name),
|
|
10245
|
+
mutating: tool.mutating,
|
|
10246
|
+
permission: tool.permission
|
|
9953
10247
|
};
|
|
9954
10248
|
});
|
|
9955
10249
|
send(ws, { type: "tools.list", payload: { tools: list } });
|
|
9956
10250
|
break;
|
|
9957
10251
|
}
|
|
10252
|
+
case "tool.disable": {
|
|
10253
|
+
const name2 = (msg.payload ?? {}).name;
|
|
10254
|
+
if (!name2) {
|
|
10255
|
+
send(ws, { type: "error", payload: { message: "tool.disable requires a name" } });
|
|
10256
|
+
break;
|
|
10257
|
+
}
|
|
10258
|
+
const ok2 = deps2.toolRegistry.disable(name2);
|
|
10259
|
+
const currentCfg = deps2.configStore.get().tools ?? {};
|
|
10260
|
+
const currentDisabled = currentCfg.disabledTools ?? [];
|
|
10261
|
+
if (ok2 && !currentDisabled.includes(name2)) {
|
|
10262
|
+
deps2.configStore.update({ tools: { ...currentCfg, disabledTools: [...currentDisabled, name2] } });
|
|
10263
|
+
}
|
|
10264
|
+
send(ws, { type: "tool.disabled", payload: { name: name2, ok: ok2 } });
|
|
10265
|
+
break;
|
|
10266
|
+
}
|
|
10267
|
+
case "tool.enable": {
|
|
10268
|
+
const name2 = (msg.payload ?? {}).name;
|
|
10269
|
+
if (!name2) {
|
|
10270
|
+
send(ws, { type: "error", payload: { message: "tool.enable requires a name" } });
|
|
10271
|
+
break;
|
|
10272
|
+
}
|
|
10273
|
+
const ok2 = deps2.toolRegistry.enable(name2);
|
|
10274
|
+
if (ok2) {
|
|
10275
|
+
const currentCfg = deps2.configStore.get().tools ?? {};
|
|
10276
|
+
const currentDisabled = currentCfg.disabledTools ?? [];
|
|
10277
|
+
deps2.configStore.update({
|
|
10278
|
+
tools: { ...currentCfg, disabledTools: currentDisabled.filter((n) => n !== name2) }
|
|
10279
|
+
});
|
|
10280
|
+
}
|
|
10281
|
+
send(ws, { type: "tool.enabled", payload: { name: name2, ok: ok2 } });
|
|
10282
|
+
break;
|
|
10283
|
+
}
|
|
9958
10284
|
// ── Memory operations — delegated to shared handlers (memory-handlers.ts) ──
|
|
9959
10285
|
case "memory.list":
|
|
9960
10286
|
return handleMemoryList(ws, deps2.memoryStore);
|