@wrongstack/webui 0.282.0 → 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.
Files changed (25) hide show
  1. package/dist/assets/{AnalyticsDashboard-BrQc2ss-.js → AnalyticsDashboard-TCNC-sVb.js} +1 -1
  2. package/dist/assets/{AutoPhaseView-8NTdnZ0a.js → AutoPhaseView-BMUiT6aI.js} +1 -1
  3. package/dist/assets/{CodeEditor-C-pJLtUR.js → CodeEditor-C0si742k.js} +1 -1
  4. package/dist/assets/{DesignGalleryView-M6Hp7s9b.js → DesignGalleryView-BfZTw48N.js} +1 -1
  5. package/dist/assets/{KanbanView-nMv98m0N.js → KanbanView-C4T4y0b7.js} +1 -1
  6. package/dist/assets/{MailboxDetailView-g3IQx4DB.js → MailboxDetailView-DJtjP0NF.js} +1 -1
  7. package/dist/assets/{OfficeMapPanel-D3VE7UCd.js → OfficeMapPanel-CgvHvGQm.js} +1 -1
  8. package/dist/assets/{ProcessMonitor-CbfQYneY.js → ProcessMonitor-D53zn0h4.js} +1 -1
  9. package/dist/assets/{QueuePanel-eGK1SSKx.js → QueuePanel-DTO68vaB.js} +1 -1
  10. package/dist/assets/{SddBoardView-DvuH4f4e.js → SddBoardView-C8X4MiTy.js} +1 -1
  11. package/dist/assets/{SddWizard-G55Yw9Bb.js → SddWizard-t5Cly3CG.js} +1 -1
  12. package/dist/assets/{SkillDetailView-CX9zeWBG.js → SkillDetailView-Dq-fTqSp.js} +1 -1
  13. package/dist/assets/{SpecsView-BnUsqkrG.js → SpecsView-Cwd6PiYr.js} +1 -1
  14. package/dist/assets/{TerminalPanel-BCpddej2.js → TerminalPanel-Bzyhr2aC.js} +1 -1
  15. package/dist/assets/index-CWj2bI87.js +145 -0
  16. package/dist/index.html +1 -1
  17. package/dist/index.js +128 -58
  18. package/dist/index.js.map +1 -1
  19. package/dist/providers.json +2 -2
  20. package/dist/server/entry.js +300 -11
  21. package/dist/server/entry.js.map +1 -1
  22. package/dist/server/index.js +300 -11
  23. package/dist/server/index.js.map +1 -1
  24. package/package.json +6 -6
  25. package/dist/assets/index-BhO3caLf.js +0 -146
@@ -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 `<next_steps>` formatting"
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("[setup-events] Failed to write status.json:", err);
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("[setup-events] Failed to start status file watcher:", err);
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 = makeProviderFromConfig("anthropic", {
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
- ok(ws, type, { removed: await removeBoard(ctx.projectRoot, boardId) });
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: