@wrongstack/tools 0.282.1 → 0.283.0

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/builtin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { spawn, execFileSync } from 'node:child_process';
2
2
  import * as Core from '@wrongstack/core';
3
- import { buildChildEnv, getDesignKitLoader, isDesignStack, loadActiveKit, applyTokenOverrides, setActiveKit, recordKitChoice, recordOverrides, setDesignOverrides, materializeTokens, runDesignVerify, ToolValidationError, detectNewlineStyle, normalizeToLf, toStyle, atomicWrite, unifiedDiff, ToolError, FetchError, isPrivateIPv4, isPrivateIPv6, assessCommitSafety, compileGlob, expectDefined, recordPackageAction, detectPackageEcosystem, deepMerge, addLinkToTask, addNoteToTask, updateCheckOnTask, addCheckToTask, updateGoalMetricOnTask, addGoalMetricToTask, addDependency, updateTaskAssignment, assignTask, releaseTaskClaim, claimReadyTask, getTaskChain, setTaskChain, removeTask, moveTask, updateTask, getTask, transferTaskToBoard, copyTaskToBoard, mergeTasks, splitTask, addTask, removeColumn, updateColumn, addColumn, getKanbanOrchestrationSnapshot, listReadyTasks, searchKanban, deserializeTaskGraph, syncBoardFromTaskGraph, exportBoardToTaskGraph, serializeTaskGraph, exportBoardAsMarkdown, generateBoardFromDescription, createBoard, parseLinesIntoTasks, getBoard, removeBoard, duplicateBoard, updateBoard, listBoards, mutatePlan, clearPlan, getPlanTemplate, addPlanItem, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, mutateTasks, formatTaskList, formatPlan, FsError, toErrorMessage as toErrorMessage$2, computeTaskItemProgress, loadPlan, savePlan, loadTasks, saveTasks, wstackGlobalRoot, resolveWstackPaths, truncate } from '@wrongstack/core';
3
+ import { buildChildEnv, getDesignKitLoader, isDesignStack, loadActiveKit, applyTokenOverrides, setActiveKit, recordKitChoice, recordOverrides, setDesignOverrides, materializeTokens, runDesignVerify, ToolValidationError, detectNewlineStyle, normalizeToLf, toStyle, atomicWrite, unifiedDiff, ToolError, FetchError, isPrivateIPv4, isPrivateIPv6, assessCommitSafety, compileGlob, expectDefined, recordPackageAction, detectPackageEcosystem, deepMerge, addLinkToTask, addNoteToTask, updateCheckOnTask, addCheckToTask, updateGoalMetricOnTask, addGoalMetricToTask, addDependency, getKanbanQueueHealth, listKanbanEvents, recoverStaleTaskAssignments, heartbeatTaskAssignment, updateTaskAssignment, assignTask, releaseTaskClaim, claimReadyTask, getTaskChain, setTaskChain, removeTask, moveTask, updateTask, getTask, transferTaskToBoard, copyTaskToBoard, mergeTasks, splitTask, addTask, removeColumn, updateColumn, addColumn, getKanbanOrchestrationSnapshot, listReadyTasks, searchKanban, deserializeTaskGraph, syncBoardFromTaskGraph, exportBoardToTaskGraph, serializeTaskGraph, exportBoardAsMarkdown, generateBoardFromDescription, createBoard, parseLinesIntoTasks, getBoard, removeBoard, duplicateBoard, updateBoard, listBoards, mutatePlan, clearPlan, getPlanTemplate, addPlanItem, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, mutateTasks, formatTaskList, formatPlan, FsError, toErrorMessage as toErrorMessage$2, computeTaskItemProgress, loadPlan, savePlan, loadTasks, saveTasks, wstackGlobalRoot, resolveWstackPaths, truncate } from '@wrongstack/core';
4
4
  import * as fs from 'node:fs';
5
5
  import { statSync, mkdirSync, createWriteStream } from 'node:fs';
6
6
  import * as fs2 from 'node:fs/promises';
@@ -9330,6 +9330,10 @@ var kanbanTool = {
9330
9330
  "release_task",
9331
9331
  "assign_task",
9332
9332
  "mark_assignment",
9333
+ "heartbeat_assignment",
9334
+ "recover_stale",
9335
+ "events",
9336
+ "queue_health",
9333
9337
  "add_dependency",
9334
9338
  "add_goal_metric",
9335
9339
  "update_goal_metric",
@@ -9376,6 +9380,12 @@ var kanbanTool = {
9376
9380
  fallbackModels: { type: "array", items: { type: "string" } },
9377
9381
  tools: { type: "array", items: { type: "string" } },
9378
9382
  allowedCapabilities: { type: "array", items: { type: "string" } },
9383
+ leaseId: { type: "string" },
9384
+ claimedAt: { type: "string" },
9385
+ heartbeatAt: { type: "string" },
9386
+ leaseExpiresAt: { type: "string" },
9387
+ attempt: { type: "number" },
9388
+ maxAttempts: { type: "number" },
9379
9389
  subagentId: { type: "string" },
9380
9390
  runTaskId: { type: "string" },
9381
9391
  lastResult: { type: "string" },
@@ -9387,6 +9397,8 @@ var kanbanTool = {
9387
9397
  releaseStatus: { type: "string", enum: ["pending", "ready", "blocked"] },
9388
9398
  releaseReason: { type: "string" },
9389
9399
  clearAssignee: { type: "boolean" },
9400
+ recoveryMode: { type: "string", enum: ["release", "retry", "fail"] },
9401
+ recoveryNow: { type: "string" },
9390
9402
  taskGraph: { type: "object" },
9391
9403
  graphId: { type: "string" },
9392
9404
  specId: { type: "string" },
@@ -9802,10 +9814,80 @@ var kanbanTool = {
9802
9814
  ...input.runTaskId !== void 0 ? { runTaskId: input.runTaskId } : {},
9803
9815
  ...input.lastResult !== void 0 ? { lastResult: input.lastResult } : {},
9804
9816
  ...input.error !== void 0 ? { error: input.error } : {},
9805
- ...input.agentId !== void 0 ? { agentId: input.agentId } : {}
9817
+ ...input.agentId !== void 0 ? { agentId: input.agentId } : {},
9818
+ ...input.leaseId !== void 0 ? { leaseId: input.leaseId } : {},
9819
+ ...input.claimedAt !== void 0 ? { claimedAt: input.claimedAt } : {},
9820
+ ...input.heartbeatAt !== void 0 ? { heartbeatAt: input.heartbeatAt } : {},
9821
+ ...input.leaseExpiresAt !== void 0 ? { leaseExpiresAt: input.leaseExpiresAt } : {},
9822
+ ...input.attempt !== void 0 ? { attempt: input.attempt } : {},
9823
+ ...input.maxAttempts !== void 0 ? { maxAttempts: input.maxAttempts } : {}
9806
9824
  });
9807
9825
  return board ? okBoard(board, "Assignment updated.") : fail("Task not found.");
9808
9826
  }
9827
+ case "heartbeat_assignment": {
9828
+ if (!input.boardId || !input.taskId) {
9829
+ return fail("heartbeat_assignment requires boardId and taskId.");
9830
+ }
9831
+ const board = await heartbeatTaskAssignment(projectRoot, input.boardId, input.taskId, {
9832
+ ...input.heartbeatAt !== void 0 ? { heartbeatAt: input.heartbeatAt } : {},
9833
+ ...input.leaseExpiresAt !== void 0 ? { leaseExpiresAt: input.leaseExpiresAt } : {}
9834
+ });
9835
+ return board ? okBoard(board, "Assignment heartbeat updated.") : fail("Task assignment not found.");
9836
+ }
9837
+ case "recover_stale": {
9838
+ if (!input.boardId) return fail("recover_stale requires boardId.");
9839
+ const policyFields = [
9840
+ input.recoveryPolicyFailOnCostCeiling !== void 0,
9841
+ input.recoveryPolicyReleaseOnFailureKinds !== void 0,
9842
+ input.recoveryPolicyReleaseOnHeartbeatDue !== void 0,
9843
+ input.recoveryPolicyRetryPolicyOverride !== void 0
9844
+ ].some(Boolean);
9845
+ const result = await recoverStaleTaskAssignments(projectRoot, input.boardId, {
9846
+ ...input.recoveryMode !== void 0 ? { mode: input.recoveryMode } : {},
9847
+ ...input.recoveryNow !== void 0 ? { now: input.recoveryNow } : {},
9848
+ ...input.releaseReason !== void 0 ? { reason: input.releaseReason } : {},
9849
+ ...input.clearAssignee !== void 0 ? { clearAssignee: input.clearAssignee } : {},
9850
+ ...policyFields ? {
9851
+ policy: {
9852
+ ...input.recoveryPolicyFailOnCostCeiling !== void 0 ? { failWhenCostCeilingSet: input.recoveryPolicyFailOnCostCeiling } : {},
9853
+ ...input.recoveryPolicyReleaseOnFailureKinds !== void 0 ? {
9854
+ releaseOnFailureKinds: input.recoveryPolicyReleaseOnFailureKinds
9855
+ } : {},
9856
+ ...input.recoveryPolicyReleaseOnHeartbeatDue !== void 0 ? {
9857
+ releaseOnHeartbeatDue: input.recoveryPolicyReleaseOnHeartbeatDue
9858
+ } : {},
9859
+ ...input.recoveryPolicyRetryPolicyOverride !== void 0 ? {
9860
+ retryPolicyOverride: input.recoveryPolicyRetryPolicyOverride
9861
+ } : {}
9862
+ }
9863
+ } : {}
9864
+ });
9865
+ return result ? {
9866
+ ok: true,
9867
+ message: `Recovered ${result.tasks.length} stale assignment(s).`,
9868
+ board: result.board,
9869
+ recoveredTasks: result.tasks
9870
+ } : { ok: true, message: "No stale assignment matched.", recoveredTasks: [] };
9871
+ }
9872
+ case "events": {
9873
+ if (!input.boardId) return fail("events requires boardId.");
9874
+ const eventList = await listKanbanEvents(projectRoot, input.boardId);
9875
+ return {
9876
+ ok: true,
9877
+ message: `${eventList.length} event(s).`,
9878
+ events: eventList
9879
+ };
9880
+ }
9881
+ case "queue_health": {
9882
+ const health = await getKanbanQueueHealth(projectRoot, {
9883
+ ...input.boardId !== void 0 ? { boardId: input.boardId } : {}
9884
+ });
9885
+ return {
9886
+ ok: true,
9887
+ message: `Counts: ready=${health.counts.ready}, running=${health.counts.running}, stale=${health.staleAssignments.count}.`,
9888
+ queueHealth: health
9889
+ };
9890
+ }
9809
9891
  case "add_dependency": {
9810
9892
  if (!input.boardId || !input.taskId || !input.dependencyTaskId) {
9811
9893
  return fail("add_dependency requires boardId, taskId, and dependencyTaskId.");
@@ -9957,11 +10039,20 @@ function assignmentInput(input) {
9957
10039
  fallbackModels: input.fallbackModels,
9958
10040
  tools: input.tools,
9959
10041
  allowedCapabilities: input.allowedCapabilities,
9960
- assignee: input.assignee
10042
+ assignee: input.assignee,
10043
+ leaseId: input.leaseId,
10044
+ claimedAt: input.claimedAt,
10045
+ heartbeatAt: input.heartbeatAt,
10046
+ leaseExpiresAt: input.leaseExpiresAt,
10047
+ attempt: input.attempt,
10048
+ maxAttempts: input.maxAttempts,
10049
+ costCeilingUsd: input.costCeilingUsd,
10050
+ retryPolicy: input.retryPolicy,
10051
+ lastFailureKind: input.lastFailureKind
9961
10052
  };
9962
10053
  }
9963
10054
  function hasAssignmentInput(input) {
9964
- return input.agentId !== void 0 || input.name !== void 0 || input.role !== void 0 || input.provider !== void 0 || input.model !== void 0 || input.fallbackProfile !== void 0 || input.fallbackModels !== void 0 || input.tools !== void 0 || input.allowedCapabilities !== void 0 || input.assignee !== void 0 || input.assignmentStatus !== void 0;
10055
+ return input.agentId !== void 0 || input.name !== void 0 || input.role !== void 0 || input.provider !== void 0 || input.model !== void 0 || input.fallbackProfile !== void 0 || input.fallbackModels !== void 0 || input.tools !== void 0 || input.allowedCapabilities !== void 0 || input.assignee !== void 0 || input.leaseId !== void 0 || input.claimedAt !== void 0 || input.heartbeatAt !== void 0 || input.leaseExpiresAt !== void 0 || input.attempt !== void 0 || input.maxAttempts !== void 0 || input.costCeilingUsd !== void 0 || input.retryPolicy !== void 0 || input.lastFailureKind !== void 0 || input.assignmentStatus !== void 0;
9965
10056
  }
9966
10057
  function assignmentForTaskCreate(input) {
9967
10058
  return {
@@ -9974,7 +10065,16 @@ function assignmentForTaskCreate(input) {
9974
10065
  ...input.fallbackProfile !== void 0 ? { fallbackProfile: input.fallbackProfile } : {},
9975
10066
  ...input.fallbackModels !== void 0 ? { fallbackModels: input.fallbackModels } : {},
9976
10067
  ...input.tools !== void 0 ? { tools: input.tools } : {},
9977
- ...input.allowedCapabilities !== void 0 ? { allowedCapabilities: input.allowedCapabilities } : {}
10068
+ ...input.allowedCapabilities !== void 0 ? { allowedCapabilities: input.allowedCapabilities } : {},
10069
+ ...input.leaseId !== void 0 ? { leaseId: input.leaseId } : {},
10070
+ ...input.claimedAt !== void 0 ? { claimedAt: input.claimedAt } : {},
10071
+ ...input.heartbeatAt !== void 0 ? { heartbeatAt: input.heartbeatAt } : {},
10072
+ ...input.leaseExpiresAt !== void 0 ? { leaseExpiresAt: input.leaseExpiresAt } : {},
10073
+ ...input.attempt !== void 0 ? { attempt: input.attempt } : {},
10074
+ ...input.maxAttempts !== void 0 ? { maxAttempts: input.maxAttempts } : {},
10075
+ ...input.costCeilingUsd !== void 0 ? { costCeilingUsd: input.costCeilingUsd } : {},
10076
+ ...input.retryPolicy !== void 0 ? { retryPolicy: input.retryPolicy } : {},
10077
+ ...input.lastFailureKind !== void 0 ? { lastFailureKind: input.lastFailureKind } : {}
9978
10078
  };
9979
10079
  }
9980
10080