@wrongstack/core 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.
Files changed (47) hide show
  1. package/dist/{agent-subagent-runner-DCczSoQj.d.ts → agent-subagent-runner-BsuWhB28.d.ts} +2 -2
  2. package/dist/coordination/index.d.ts +12 -12
  3. package/dist/coordination/index.js +315 -41
  4. package/dist/coordination/index.js.map +1 -1
  5. package/dist/defaults/index.d.ts +12 -12
  6. package/dist/defaults/index.js +316 -53
  7. package/dist/defaults/index.js.map +1 -1
  8. package/dist/{events-BOv8h6I1.d.ts → events-KmxSmvho.d.ts} +5 -0
  9. package/dist/execution/index.d.ts +7 -7
  10. package/dist/extension/index.d.ts +2 -2
  11. package/dist/{global-mailbox-MDDFhLYh.d.ts → global-mailbox-rWVt8YlO.d.ts} +70 -7
  12. package/dist/{goal-store-BEmDmSKF.d.ts → goal-store-8owBXJT2.d.ts} +1 -1
  13. package/dist/hq/index.d.ts +3 -3
  14. package/dist/hq/index.js +106 -32
  15. package/dist/hq/index.js.map +1 -1
  16. package/dist/{index-Dd-PJJ8A.d.ts → index-BhCteHAF.d.ts} +1 -1
  17. package/dist/index.d.ts +289 -19
  18. package/dist/index.js +919 -110
  19. package/dist/index.js.map +1 -1
  20. package/dist/infrastructure/index.d.ts +1 -1
  21. package/dist/kernel/index.d.ts +4 -4
  22. package/dist/kernel/index.js.map +1 -1
  23. package/dist/models/index.js +105 -42
  24. package/dist/models/index.js.map +1 -1
  25. package/dist/{multi-agent-coordinator-BRqtpn-a.d.ts → multi-agent-coordinator-CrjeTB9i.d.ts} +1 -1
  26. package/dist/{null-fleet-bus-BkptvIVo.d.ts → null-fleet-bus-D4e9R7Qc.d.ts} +9 -4
  27. package/dist/observability/index.d.ts +1 -1
  28. package/dist/{parallel-eternal-engine-BXECuOVG.d.ts → parallel-eternal-engine-iY2uxocj.d.ts} +4 -4
  29. package/dist/{provider-runner-CJtCs1Rw.d.ts → provider-runner-oQhDaZmH.d.ts} +1 -1
  30. package/dist/sdd/index.d.ts +4 -4
  31. package/dist/sdd/index.js.map +1 -1
  32. package/dist/storage/index.d.ts +5 -5
  33. package/dist/storage/index.js.map +1 -1
  34. package/dist/{todos-checkpoint-Bw83WMh9.d.ts → todos-checkpoint-BwCrj4Cb.d.ts} +1 -1
  35. package/dist/{tool-executor-4mWN2vHW.d.ts → tool-executor-kElSEgO0.d.ts} +4 -4
  36. package/dist/types/index.d.ts +8 -8
  37. package/dist/types/index.js +105 -45
  38. package/dist/types/index.js.map +1 -1
  39. package/dist/{worktree-manager-BrtjUFYk.d.ts → worktree-manager-BjyAW30D.d.ts} +1 -1
  40. package/instructions/modes/audit-lite.md +13 -0
  41. package/instructions/modes/debug-lite.md +13 -0
  42. package/instructions/modes/plan-lite.md +14 -0
  43. package/instructions/modes/refactor-lite.md +13 -0
  44. package/instructions/modes/research-lite.md +13 -0
  45. package/instructions/modes/review-lite.md +14 -0
  46. package/instructions/modes/test-lite.md +13 -0
  47. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3916,12 +3916,12 @@ var init_session_registry = __esm({
3916
3916
  const hasWaiting = agents.some((a) => a.status === "waiting_user");
3917
3917
  const hasError = agents.some((a) => a.status === "error");
3918
3918
  const status = hasRunning || hasWaiting || hasError ? "active" : "idle";
3919
- const nowIso2 = (/* @__PURE__ */ new Date()).toISOString();
3919
+ const nowIso3 = (/* @__PURE__ */ new Date()).toISOString();
3920
3920
  if (this.lastEntry) {
3921
3921
  this.lastEntry.agents = agents;
3922
3922
  this.lastEntry.agentCount = agents.length;
3923
3923
  this.lastEntry.status = status;
3924
- this.lastEntry.lastHeartbeatAt = nowIso2;
3924
+ this.lastEntry.lastHeartbeatAt = nowIso3;
3925
3925
  }
3926
3926
  await this.atomicUpdate((registry) => {
3927
3927
  let entry = registry[this.currentSessionId];
@@ -3933,7 +3933,7 @@ var init_session_registry = __esm({
3933
3933
  entry.agents = agents;
3934
3934
  entry.agentCount = agents.length;
3935
3935
  entry.status = status;
3936
- entry.lastHeartbeatAt = nowIso2;
3936
+ entry.lastHeartbeatAt = nowIso3;
3937
3937
  });
3938
3938
  }
3939
3939
  /**
@@ -4000,11 +4000,11 @@ var init_session_registry = __esm({
4000
4000
  if (!this.currentSessionId) return;
4001
4001
  try {
4002
4002
  const sessionId = this.currentSessionId;
4003
- const nowIso2 = (/* @__PURE__ */ new Date()).toISOString();
4003
+ const nowIso3 = (/* @__PURE__ */ new Date()).toISOString();
4004
4004
  await this.atomicUpdate((registry) => {
4005
4005
  const entry = registry[sessionId];
4006
4006
  if (entry) {
4007
- entry.lastHeartbeatAt = nowIso2;
4007
+ entry.lastHeartbeatAt = nowIso3;
4008
4008
  if (entry.status !== "closing") {
4009
4009
  const hasRunning = (entry.agents ?? []).some(
4010
4010
  (a) => a.status === "running" || a.status === "streaming"
@@ -4014,7 +4014,7 @@ var init_session_registry = __esm({
4014
4014
  return;
4015
4015
  }
4016
4016
  if (this.lastEntry) {
4017
- registry[sessionId] = { ...this.lastEntry, lastHeartbeatAt: nowIso2 };
4017
+ registry[sessionId] = { ...this.lastEntry, lastHeartbeatAt: nowIso3 };
4018
4018
  }
4019
4019
  });
4020
4020
  } catch {
@@ -13094,13 +13094,39 @@ var DEFAULT_PRIMARY_COOLDOWN_MAX_MS = 10 * 6e4;
13094
13094
  function sameTarget(a, b) {
13095
13095
  return !!a && a.providerId === b.providerId && a.model === b.model;
13096
13096
  }
13097
+ function fallbackCandidates(config, current) {
13098
+ const chain = effectiveFallbackChain(config);
13099
+ const configuredPrimary = primaryTarget(config);
13100
+ const manualTarget = sameTarget(configuredPrimary, current) ? [] : [formatModelRef({ provider: configuredPrimary.providerId, model: configuredPrimary.model })];
13101
+ const seen = /* @__PURE__ */ new Set();
13102
+ return [...manualTarget, ...chain].filter((ref) => {
13103
+ const normalized = normalizeModelRef(ref, config.provider);
13104
+ if (seen.has(normalized)) return false;
13105
+ seen.add(normalized);
13106
+ return true;
13107
+ });
13108
+ }
13109
+ var primaryTarget = (cfg) => ({ providerId: cfg.provider, model: cfg.model });
13110
+ function maxContextOf(provider) {
13111
+ const max = provider.capabilities.maxContext;
13112
+ return typeof max === "number" && Number.isFinite(max) ? max : 0;
13113
+ }
13114
+ function contextWindowWarning(currentProvider, nextProvider, currentTokens) {
13115
+ const fromMaxContext = maxContextOf(currentProvider);
13116
+ const toMaxContext = maxContextOf(nextProvider);
13117
+ if (fromMaxContext <= 0 || toMaxContext <= 0 || toMaxContext >= fromMaxContext) return void 0;
13118
+ return {
13119
+ fromMaxContext,
13120
+ toMaxContext,
13121
+ ...typeof currentTokens === "number" && currentTokens > 0 ? { currentTokens } : {}
13122
+ };
13123
+ }
13097
13124
  function createFallbackModelExtension(deps) {
13098
13125
  let dirty = false;
13099
13126
  let primaryFailureStreak = 0;
13100
13127
  let blockedPrimary;
13101
13128
  let primaryBlockedUntil = 0;
13102
13129
  const now = () => deps.now?.() ?? Date.now();
13103
- const primaryTarget = (cfg) => ({ providerId: cfg.provider, model: cfg.model });
13104
13130
  const cooldownBase = () => Math.max(0, deps.primaryCooldownMs ?? DEFAULT_PRIMARY_COOLDOWN_MS);
13105
13131
  const cooldownMax = () => Math.max(cooldownBase(), deps.primaryCooldownMaxMs ?? DEFAULT_PRIMARY_COOLDOWN_MAX_MS);
13106
13132
  const primaryInCooldown = (cfg) => sameTarget(blockedPrimary, primaryTarget(cfg)) && now() < primaryBlockedUntil;
@@ -13153,7 +13179,8 @@ function createFallbackModelExtension(deps) {
13153
13179
  } catch (firstErr) {
13154
13180
  let lastErr = firstErr;
13155
13181
  const cfg = deps.getConfig();
13156
- const chain = effectiveFallbackChain(cfg);
13182
+ const current = { providerId: ctx.provider.id, model: ctx.model };
13183
+ const chain = fallbackCandidates(cfg, current);
13157
13184
  if (shouldFallback(firstErr) !== null && ctx.provider.id === cfg.provider && ctx.model === cfg.model) {
13158
13185
  markPrimaryFailure(cfg);
13159
13186
  }
@@ -13178,6 +13205,7 @@ function createFallbackModelExtension(deps) {
13178
13205
  continue;
13179
13206
  }
13180
13207
  const providerSwitched = nextProvider.id !== from.providerId;
13208
+ const warning = contextWindowWarning(ctx.provider, nextProvider, ctx.lastRequestTokens);
13181
13209
  ctx.provider = nextProvider;
13182
13210
  ctx.model = parsed.model;
13183
13211
  request.model = parsed.model;
@@ -13188,7 +13216,8 @@ function createFallbackModelExtension(deps) {
13188
13216
  from,
13189
13217
  to: { providerId: nextProvider.id, model: parsed.model },
13190
13218
  status,
13191
- providerSwitched
13219
+ providerSwitched,
13220
+ ...warning ? { contextWindowWarning: warning } : {}
13192
13221
  });
13193
13222
  try {
13194
13223
  return await inner(ctx, request);
@@ -16074,9 +16103,6 @@ function isContextWindowModeId(id) {
16074
16103
  function resolveContextWindowPolicy(config = {}, overrideMode) {
16075
16104
  const requested = overrideMode ?? config.mode ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;
16076
16105
  const mode = getContextWindowMode(requested) ?? expectDefined(getContextWindowMode(DEFAULT_CONTEXT_WINDOW_MODE_ID));
16077
- if (mode.id !== DEFAULT_CONTEXT_WINDOW_MODE_ID) {
16078
- return mode;
16079
- }
16080
16106
  return {
16081
16107
  ...mode,
16082
16108
  thresholds: {
@@ -19257,6 +19283,16 @@ function getKanbanPath(projectRoot, boardId) {
19257
19283
  }
19258
19284
  return resolved;
19259
19285
  }
19286
+ function getKanbanEventsPath(projectRoot, boardId) {
19287
+ assertValidBoardId(boardId);
19288
+ const dir = path4.resolve(getKanbanDir(projectRoot));
19289
+ const resolved = path4.resolve(dir, `${boardId}.events.jsonl`);
19290
+ const rel = path4.relative(dir, resolved);
19291
+ if (rel.startsWith("..") || path4.isAbsolute(rel)) {
19292
+ throw invalidBoardId(boardId);
19293
+ }
19294
+ return resolved;
19295
+ }
19260
19296
  function isValidBoardId(boardId) {
19261
19297
  return BOARD_ID_RE.test(boardId) && !boardId.includes("..");
19262
19298
  }
@@ -19316,6 +19352,25 @@ async function writeBoard(projectRoot, board) {
19316
19352
  await writeBoardUnlocked(filePath, normalized);
19317
19353
  });
19318
19354
  }
19355
+ async function appendKanbanEvent(projectRoot, boardId, event) {
19356
+ const filePath = getKanbanEventsPath(projectRoot, boardId);
19357
+ await withFileLock(filePath, async () => {
19358
+ await fsp14.mkdir(path4.dirname(filePath), { recursive: true });
19359
+ await fsp14.appendFile(filePath, `${JSON.stringify(event)}
19360
+ `, "utf8");
19361
+ });
19362
+ }
19363
+ async function readKanbanEvents(projectRoot, boardRef) {
19364
+ const boardId = await resolveBoardRef(projectRoot, boardRef);
19365
+ if (!boardId) return [];
19366
+ try {
19367
+ const raw = await fsp14.readFile(getKanbanEventsPath(projectRoot, boardId), "utf8");
19368
+ return raw.split(/\r?\n/).filter(Boolean).map((line) => JSON.parse(line));
19369
+ } catch (err) {
19370
+ if (isEnoent(err)) return [];
19371
+ throw err;
19372
+ }
19373
+ }
19319
19374
  async function deleteBoard(projectRoot, boardRef) {
19320
19375
  const boardId = await resolveBoardRef(projectRoot, boardRef);
19321
19376
  if (!boardId) return false;
@@ -19323,6 +19378,11 @@ async function deleteBoard(projectRoot, boardRef) {
19323
19378
  return withFileLock(filePath, async () => {
19324
19379
  try {
19325
19380
  await fsp14.unlink(filePath);
19381
+ try {
19382
+ await fsp14.unlink(getKanbanEventsPath(projectRoot, boardId));
19383
+ } catch (eventsErr) {
19384
+ if (!isEnoent(eventsErr)) throw eventsErr;
19385
+ }
19326
19386
  return true;
19327
19387
  } catch (err) {
19328
19388
  if (isEnoent(err)) return false;
@@ -19726,18 +19786,31 @@ async function getTask(projectRoot, boardId, taskId) {
19726
19786
  const board = await readBoard(projectRoot, boardId);
19727
19787
  return board ? findTask(board, taskId) ?? null : null;
19728
19788
  }
19789
+ async function listKanbanEvents(projectRoot, boardId) {
19790
+ return readKanbanEvents(projectRoot, boardId);
19791
+ }
19729
19792
  async function assignTask(projectRoot, boardId, taskId, input) {
19730
- const assignment = buildAssignment(input);
19731
- return updateTask(projectRoot, boardId, taskId, {
19732
- assignedAgent: assignment.agentId ?? assignment.role ?? assignment.name,
19733
- assignee: input.assignee ?? assignment.name ?? assignment.agentId,
19734
- assignment
19735
- });
19793
+ return mutateBoard(projectRoot, boardId, (board) => {
19794
+ const task = findTask(board, taskId);
19795
+ if (!task) return null;
19796
+ const assignment = buildAssignment(input);
19797
+ task.assignment = assignment;
19798
+ task.assignedAgent = assignment.agentId ?? assignment.role ?? assignment.name;
19799
+ task.assignee = input.assignee ?? assignment.name ?? assignment.agentId;
19800
+ if (input.retryPolicy !== void 0) task.retryPolicy = input.retryPolicy;
19801
+ if (input.costCeilingUsd !== void 0) task.costCeilingUsd = input.costCeilingUsd;
19802
+ task.updatedAt = nowIso();
19803
+ board.updatedAt = task.updatedAt;
19804
+ return task;
19805
+ }).then((updated) => updated?.result ? updated.board : null);
19736
19806
  }
19737
19807
  async function updateTaskAssignment(projectRoot, boardId, taskId, patch) {
19808
+ let event;
19738
19809
  const updated = await mutateBoard(projectRoot, boardId, (board) => {
19739
19810
  const task = findTask(board, taskId);
19740
19811
  if (!task) return null;
19812
+ const previousColumnId = task.columnId;
19813
+ const beforeAssignment = task.assignment ? { ...task.assignment } : void 0;
19741
19814
  const nextAssignment = {
19742
19815
  ...task.assignment ?? { status: "assigned" }
19743
19816
  };
@@ -19775,12 +19848,166 @@ async function updateTaskAssignment(projectRoot, boardId, taskId, patch) {
19775
19848
  }
19776
19849
  delete task.completedAt;
19777
19850
  }
19851
+ syncTaskColumnForStatus(board, task, previousColumnId);
19778
19852
  task.updatedAt = nowIso();
19779
19853
  board.updatedAt = task.updatedAt;
19854
+ event = createKanbanEvent(board.id, task, assignmentEventType(task.assignment.status), {
19855
+ before: beforeAssignment,
19856
+ after: { ...task.assignment },
19857
+ note: patch.error ?? patch.lastResult
19858
+ });
19859
+ return task;
19860
+ });
19861
+ if (updated && event) await emitKanbanEvent(projectRoot, event);
19862
+ return updated?.result ? updated.board : null;
19863
+ }
19864
+ async function heartbeatTaskAssignment(projectRoot, boardId, taskId, input = {}) {
19865
+ let event;
19866
+ const updated = await mutateBoard(projectRoot, boardId, (board) => {
19867
+ const task = findTask(board, taskId);
19868
+ if (!task?.assignment) return null;
19869
+ const beforeAssignment = { ...task.assignment };
19870
+ const now = nowIso();
19871
+ task.assignment.heartbeatAt = input.heartbeatAt ?? now;
19872
+ if (input.leaseExpiresAt !== void 0) {
19873
+ task.assignment.leaseExpiresAt = input.leaseExpiresAt;
19874
+ }
19875
+ task.updatedAt = now;
19876
+ board.updatedAt = now;
19877
+ event = createKanbanEvent(board.id, task, "task.assignment.heartbeat", {
19878
+ before: beforeAssignment,
19879
+ after: { ...task.assignment }
19880
+ });
19780
19881
  return task;
19781
19882
  });
19883
+ if (updated && event) await emitKanbanEvent(projectRoot, event);
19782
19884
  return updated?.result ? updated.board : null;
19783
19885
  }
19886
+ function isAssignmentHeartbeatDue(assignment, checkedAt) {
19887
+ if (!assignment.heartbeatAt || !assignment.leaseExpiresAt) return false;
19888
+ const lastHeartbeat = new Date(assignment.heartbeatAt).getTime();
19889
+ const expiresAt = new Date(assignment.leaseExpiresAt).getTime();
19890
+ const now = new Date(checkedAt).getTime();
19891
+ const lease = expiresAt - lastHeartbeat;
19892
+ if (lease <= 0) return true;
19893
+ return now - lastHeartbeat >= lease / 2;
19894
+ }
19895
+ function selectRecoveryMode(args) {
19896
+ const { requested, task, isHeartbeatDue, policy } = args;
19897
+ if (requested !== "auto") return requested;
19898
+ const assignment = task.assignment;
19899
+ if (!assignment) return "retry";
19900
+ if (assignment.retryPolicy === "off") return "fail";
19901
+ const failureKind = assignment.lastFailureKind;
19902
+ if (policy?.releaseOnFailureKinds !== void 0 && failureKind !== void 0 && policy.releaseOnFailureKinds.includes(failureKind)) {
19903
+ return "release";
19904
+ }
19905
+ if (policy?.failWhenCostCeilingSet && assignment.costCeilingUsd !== void 0) {
19906
+ return "fail";
19907
+ }
19908
+ if (policy?.releaseOnHeartbeatDue && isHeartbeatDue) {
19909
+ return "release";
19910
+ }
19911
+ if (assignment.maxAttempts !== void 0 && (assignment.attempt ?? 0) + 1 > assignment.maxAttempts) {
19912
+ return "fail";
19913
+ }
19914
+ return "retry";
19915
+ }
19916
+ async function recoverStaleTaskAssignments(projectRoot, boardId, input = {}) {
19917
+ const recoveredTasks = [];
19918
+ const events = [];
19919
+ const requestedMode = input.mode ?? "retry";
19920
+ const checkedAt = input.now ?? nowIso();
19921
+ const updated = await mutateBoard(projectRoot, boardId, (board) => {
19922
+ for (const task of board.tasks) {
19923
+ const assignment = task.assignment;
19924
+ if (!assignment || assignment.status !== "queued" && assignment.status !== "running") {
19925
+ continue;
19926
+ }
19927
+ if (!assignment.leaseExpiresAt || assignment.leaseExpiresAt > checkedAt) continue;
19928
+ const previousColumnId = task.columnId;
19929
+ const beforeAssignment = { ...assignment };
19930
+ const isHeartbeatDueNow = isAssignmentHeartbeatDue(assignment, checkedAt);
19931
+ const mode = selectRecoveryMode({
19932
+ requested: requestedMode,
19933
+ task,
19934
+ isHeartbeatDue: isHeartbeatDueNow,
19935
+ policy: input.policy
19936
+ });
19937
+ const reason = input.reason ?? `Stale assignment recovered at ${checkedAt}`;
19938
+ const now = nowIso();
19939
+ task.notes = [
19940
+ ...task.notes ?? [],
19941
+ {
19942
+ id: randomUUID(),
19943
+ author: "system",
19944
+ content: `Stale assignment recovered (${mode}): ${reason}`,
19945
+ createdAt: now
19946
+ }
19947
+ ];
19948
+ if (mode === "fail") {
19949
+ assignment.status = "failed";
19950
+ assignment.error = reason;
19951
+ delete assignment.completedAt;
19952
+ task.status = "failed";
19953
+ delete task.completedAt;
19954
+ } else if (mode === "release") {
19955
+ delete task.assignment;
19956
+ if (input.clearAssignee !== false) {
19957
+ delete task.assignedAgent;
19958
+ delete task.assignee;
19959
+ }
19960
+ task.status = areDependenciesMet(board, task.id) ? "ready" : "blocked";
19961
+ delete task.completedAt;
19962
+ } else {
19963
+ const nextAttempt = (assignment.attempt ?? 0) + 1;
19964
+ if (assignment.maxAttempts !== void 0 && nextAttempt > assignment.maxAttempts) {
19965
+ assignment.status = "failed";
19966
+ assignment.error = `${reason}; max attempts exceeded (${assignment.maxAttempts})`;
19967
+ delete assignment.completedAt;
19968
+ task.status = "failed";
19969
+ delete task.completedAt;
19970
+ } else {
19971
+ task.assignment = {
19972
+ ...assignment,
19973
+ status: "assigned",
19974
+ attempt: nextAttempt
19975
+ };
19976
+ delete task.assignment.subagentId;
19977
+ delete task.assignment.runTaskId;
19978
+ delete task.assignment.completedAt;
19979
+ delete task.assignment.lastResult;
19980
+ delete task.assignment.error;
19981
+ delete task.assignment.leaseId;
19982
+ delete task.assignment.heartbeatAt;
19983
+ delete task.assignment.leaseExpiresAt;
19984
+ if (input.clearAssignee !== false) {
19985
+ delete task.assignedAgent;
19986
+ delete task.assignee;
19987
+ }
19988
+ task.status = areDependenciesMet(board, task.id) ? "ready" : "blocked";
19989
+ delete task.completedAt;
19990
+ }
19991
+ }
19992
+ syncTaskColumnForStatus(board, task, previousColumnId);
19993
+ task.updatedAt = now;
19994
+ board.updatedAt = now;
19995
+ recoveredTasks.push({ ...task, assignment: task.assignment ? { ...task.assignment } : void 0 });
19996
+ events.push(
19997
+ createKanbanEvent(board.id, task, "task.stale_recovered", {
19998
+ before: beforeAssignment,
19999
+ after: task.assignment ? { ...task.assignment } : void 0,
20000
+ note: reason
20001
+ })
20002
+ );
20003
+ }
20004
+ return recoveredTasks.length ? recoveredTasks : null;
20005
+ });
20006
+ if (updated) {
20007
+ for (const staleEvent of events) await emitKanbanEvent(projectRoot, staleEvent);
20008
+ }
20009
+ return updated?.result ? { board: updated.board, tasks: updated.result } : null;
20010
+ }
19784
20011
  async function claimReadyTask(projectRoot, input = {}) {
19785
20012
  if (input.boardId) return claimReadyTaskOnBoard(projectRoot, input.boardId, input);
19786
20013
  for (const board of await listBoards(projectRoot)) {
@@ -19790,9 +20017,12 @@ async function claimReadyTask(projectRoot, input = {}) {
19790
20017
  return null;
19791
20018
  }
19792
20019
  async function releaseTaskClaim(projectRoot, boardId, taskId, input = {}) {
20020
+ let event;
19793
20021
  const updated = await mutateBoard(projectRoot, boardId, (board) => {
19794
20022
  const task = findTask(board, taskId);
19795
20023
  if (!task) return null;
20024
+ const previousColumnId = task.columnId;
20025
+ const beforeAssignment = task.assignment ? { ...task.assignment } : void 0;
19796
20026
  delete task.assignment;
19797
20027
  if (input.clearAssignee !== false) {
19798
20028
  delete task.assignedAgent;
@@ -19812,10 +20042,17 @@ async function releaseTaskClaim(projectRoot, boardId, taskId, input = {}) {
19812
20042
  }
19813
20043
  ];
19814
20044
  }
20045
+ syncTaskColumnForStatus(board, task, previousColumnId);
19815
20046
  task.updatedAt = now;
19816
20047
  board.updatedAt = now;
20048
+ event = createKanbanEvent(board.id, task, "task.released", {
20049
+ before: beforeAssignment,
20050
+ after: void 0,
20051
+ note: input.reason
20052
+ });
19817
20053
  return task;
19818
20054
  });
20055
+ if (updated && event) await emitKanbanEvent(projectRoot, event);
19819
20056
  return updated?.result ? updated.board : null;
19820
20057
  }
19821
20058
  async function getKanbanOrchestrationSnapshot(projectRoot, input = {}) {
@@ -19858,6 +20095,101 @@ async function getKanbanOrchestrationSnapshot(projectRoot, input = {}) {
19858
20095
  }
19859
20096
  return snapshot;
19860
20097
  }
20098
+ async function getKanbanQueueHealth(projectRoot, input = {}) {
20099
+ const heartbeatIntervalMs = input.heartbeatIntervalMs ?? 6e4;
20100
+ const now = input.now ?? nowIso();
20101
+ const boards = await collectBoardsForHealth(projectRoot, input.boardId);
20102
+ const boardIds = boards.map((board) => board.id);
20103
+ const counts = {
20104
+ ready: 0,
20105
+ queued: 0,
20106
+ running: 0,
20107
+ review: 0,
20108
+ failed: 0,
20109
+ completed: 0,
20110
+ pending: 0,
20111
+ archived: 0,
20112
+ blocked: 0
20113
+ };
20114
+ const dependencyBlocked = [];
20115
+ const staleAssignments = [];
20116
+ const failedRetryable = [];
20117
+ const heartbeatDue = [];
20118
+ for (const board of boards) {
20119
+ const summary = summarizeBoard(board);
20120
+ for (const task of board.tasks) {
20121
+ const assignment = task.assignment;
20122
+ const dependencyUnmet = !areDependenciesMet(board, task.id);
20123
+ const isRunning = task.status === "in_progress" || assignment !== void 0 && assignment.status === "running";
20124
+ const isQueued = assignment !== void 0 && (assignment.status === "queued" || assignment.status === "assigned");
20125
+ if (task.status === "ready" && !isRunning) {
20126
+ counts.ready += 1;
20127
+ } else {
20128
+ counts[task.status] += 1;
20129
+ }
20130
+ if (isRunning) counts.running += 1;
20131
+ if (isQueued) counts.queued += 1;
20132
+ const readyButBlocked = task.status === "ready" && dependencyUnmet;
20133
+ const pendingButBlocked = task.status === "pending" && dependencyUnmet;
20134
+ if (readyButBlocked || pendingButBlocked) {
20135
+ dependencyBlocked.push({ board: summary, task });
20136
+ }
20137
+ const expiredLease = assignment !== void 0 && (assignment.status === "queued" || assignment.status === "running") && assignment.leaseExpiresAt !== void 0 && assignment.leaseExpiresAt <= now;
20138
+ if (expiredLease) {
20139
+ staleAssignments.push({ board: summary, task });
20140
+ }
20141
+ if (assignment && assignment.status === "running" && assignment.leaseExpiresAt !== void 0 && msUntilExpiry(assignment.leaseExpiresAt, now) <= heartbeatIntervalMs) {
20142
+ heartbeatDue.push({ board: summary, task });
20143
+ }
20144
+ if (task.status === "failed" && assignment && assignment.maxAttempts !== void 0 && (assignment.attempt ?? 0) < assignment.maxAttempts) {
20145
+ failedRetryable.push({ board: summary, task });
20146
+ }
20147
+ }
20148
+ }
20149
+ let lastDispatchedAt;
20150
+ let lastStaleRecoveredAt;
20151
+ for (const boardId of boardIds) {
20152
+ const events = await readKanbanEvents(projectRoot, boardId);
20153
+ for (const event of events) {
20154
+ if (event.type === "task.assignment.running") {
20155
+ lastDispatchedAt = later(lastDispatchedAt, event.ts);
20156
+ } else if (event.type === "task.stale_recovered") {
20157
+ lastStaleRecoveredAt = later(lastStaleRecoveredAt, event.ts);
20158
+ }
20159
+ }
20160
+ }
20161
+ return {
20162
+ generatedAt: now,
20163
+ boardIds,
20164
+ counts,
20165
+ dependencyBlocked: { count: dependencyBlocked.length, tasks: dependencyBlocked },
20166
+ staleAssignments: { count: staleAssignments.length, tasks: staleAssignments },
20167
+ failedRetryable: { count: failedRetryable.length, tasks: failedRetryable },
20168
+ heartbeatDue: { count: heartbeatDue.length, tasks: heartbeatDue },
20169
+ ...lastDispatchedAt !== void 0 ? { lastDispatchedAt } : {},
20170
+ ...lastStaleRecoveredAt !== void 0 ? { lastStaleRecoveredAt } : {}
20171
+ };
20172
+ }
20173
+ function msUntilExpiry(leaseExpiresAt, nowIso3) {
20174
+ return new Date(leaseExpiresAt).getTime() - new Date(nowIso3).getTime();
20175
+ }
20176
+ function later(a, b) {
20177
+ if (a === void 0) return b;
20178
+ return new Date(a).getTime() >= new Date(b).getTime() ? a : b;
20179
+ }
20180
+ async function collectBoardsForHealth(projectRoot, boardId) {
20181
+ if (boardId !== void 0) {
20182
+ const board = await getBoard(projectRoot, boardId);
20183
+ return board ? [board] : [];
20184
+ }
20185
+ const summaries = await listBoardSummaries(projectRoot);
20186
+ const out = [];
20187
+ for (const summary of summaries) {
20188
+ const board = await getBoard(projectRoot, summary.id);
20189
+ if (board) out.push(board);
20190
+ }
20191
+ return out;
20192
+ }
19861
20193
  async function addDependency(projectRoot, boardId, taskId, dependencyTaskId) {
19862
20194
  const updated = await mutateBoard(projectRoot, boardId, (board) => {
19863
20195
  const task = findTask(board, taskId);
@@ -20403,7 +20735,10 @@ function createTaskObject(board, input) {
20403
20735
  ...input.successCriteria !== void 0 ? { successCriteria: input.successCriteria } : {},
20404
20736
  ...input.goalMetrics !== void 0 ? { goalMetrics: input.goalMetrics } : {},
20405
20737
  ...input.links !== void 0 ? { links: input.links } : {},
20406
- ...input.notes !== void 0 ? { notes: input.notes } : {}
20738
+ ...input.notes !== void 0 ? { notes: input.notes } : {},
20739
+ // Sprint 3: mirror policy fields from assignment to durable task level.
20740
+ ...input.assignment?.retryPolicy !== void 0 ? { retryPolicy: input.assignment.retryPolicy } : {},
20741
+ ...input.assignment?.costCeilingUsd !== void 0 ? { costCeilingUsd: input.assignment.costCeilingUsd } : {}
20407
20742
  };
20408
20743
  applyCompletedAtForStatus(task, now);
20409
20744
  return task;
@@ -20536,14 +20871,25 @@ function buildAssignment(input) {
20536
20871
  ...input.fallbackProfile !== void 0 ? { fallbackProfile: input.fallbackProfile } : {},
20537
20872
  ...input.fallbackModels !== void 0 ? { fallbackModels: input.fallbackModels } : {},
20538
20873
  ...input.tools !== void 0 ? { tools: input.tools } : {},
20539
- ...input.allowedCapabilities !== void 0 ? { allowedCapabilities: input.allowedCapabilities } : {}
20874
+ ...input.allowedCapabilities !== void 0 ? { allowedCapabilities: input.allowedCapabilities } : {},
20875
+ ...input.leaseId !== void 0 ? { leaseId: input.leaseId } : {},
20876
+ ...input.claimedAt !== void 0 ? { claimedAt: input.claimedAt } : {},
20877
+ ...input.heartbeatAt !== void 0 ? { heartbeatAt: input.heartbeatAt } : {},
20878
+ ...input.leaseExpiresAt !== void 0 ? { leaseExpiresAt: input.leaseExpiresAt } : {},
20879
+ ...input.attempt !== void 0 ? { attempt: input.attempt } : {},
20880
+ ...input.maxAttempts !== void 0 ? { maxAttempts: input.maxAttempts } : {},
20881
+ ...input.costCeilingUsd !== void 0 ? { costCeilingUsd: input.costCeilingUsd } : {},
20882
+ ...input.retryPolicy !== void 0 ? { retryPolicy: input.retryPolicy } : {},
20883
+ ...input.lastFailureKind !== void 0 ? { lastFailureKind: input.lastFailureKind } : {}
20540
20884
  };
20541
20885
  }
20542
20886
  async function claimReadyTaskOnBoard(projectRoot, boardId, input) {
20887
+ let event;
20543
20888
  const updated = await mutateBoard(projectRoot, boardId, (board) => {
20544
20889
  const candidates = input.taskId ? [findTask(board, input.taskId)].filter((task2) => Boolean(task2)) : board.tasks.filter((task2) => isTaskReadyForWork(board, task2)).sort(compareTasksForWork);
20545
20890
  const task = candidates.find((candidate) => isTaskReadyForWork(board, candidate));
20546
20891
  if (!task) return null;
20892
+ const previousColumnId = task.columnId;
20547
20893
  const current = task.assignment;
20548
20894
  const assignment = buildAssignment({
20549
20895
  ...current?.agentId !== void 0 ? { agentId: current.agentId } : {},
@@ -20555,6 +20901,15 @@ async function claimReadyTaskOnBoard(projectRoot, boardId, input) {
20555
20901
  ...current?.fallbackModels !== void 0 ? { fallbackModels: current.fallbackModels } : {},
20556
20902
  ...current?.tools !== void 0 ? { tools: current.tools } : {},
20557
20903
  ...current?.allowedCapabilities !== void 0 ? { allowedCapabilities: current.allowedCapabilities } : {},
20904
+ ...current?.leaseId !== void 0 ? { leaseId: current.leaseId } : {},
20905
+ ...current?.claimedAt !== void 0 ? { claimedAt: current.claimedAt } : {},
20906
+ ...current?.heartbeatAt !== void 0 ? { heartbeatAt: current.heartbeatAt } : {},
20907
+ ...current?.leaseExpiresAt !== void 0 ? { leaseExpiresAt: current.leaseExpiresAt } : {},
20908
+ ...current?.attempt !== void 0 ? { attempt: current.attempt } : {},
20909
+ ...current?.maxAttempts !== void 0 ? { maxAttempts: current.maxAttempts } : {},
20910
+ ...current?.costCeilingUsd !== void 0 ? { costCeilingUsd: current.costCeilingUsd } : {},
20911
+ ...current?.retryPolicy !== void 0 ? { retryPolicy: current.retryPolicy } : {},
20912
+ ...current?.lastFailureKind !== void 0 ? { lastFailureKind: current.lastFailureKind } : {},
20558
20913
  ...input.agentId !== void 0 ? { agentId: input.agentId } : {},
20559
20914
  ...input.name !== void 0 ? { name: input.name } : {},
20560
20915
  ...input.role !== void 0 ? { role: input.role } : {},
@@ -20564,10 +20919,20 @@ async function claimReadyTaskOnBoard(projectRoot, boardId, input) {
20564
20919
  ...input.fallbackModels !== void 0 ? { fallbackModels: input.fallbackModels } : {},
20565
20920
  ...input.tools !== void 0 ? { tools: input.tools } : {},
20566
20921
  ...input.allowedCapabilities !== void 0 ? { allowedCapabilities: input.allowedCapabilities } : {},
20922
+ ...input.leaseId !== void 0 ? { leaseId: input.leaseId } : {},
20923
+ ...input.claimedAt !== void 0 ? { claimedAt: input.claimedAt } : {},
20924
+ ...input.heartbeatAt !== void 0 ? { heartbeatAt: input.heartbeatAt } : {},
20925
+ ...input.leaseExpiresAt !== void 0 ? { leaseExpiresAt: input.leaseExpiresAt } : {},
20926
+ ...input.attempt !== void 0 ? { attempt: input.attempt } : {},
20927
+ ...input.maxAttempts !== void 0 ? { maxAttempts: input.maxAttempts } : {},
20928
+ ...input.costCeilingUsd !== void 0 ? { costCeilingUsd: input.costCeilingUsd } : {},
20929
+ ...input.retryPolicy !== void 0 ? { retryPolicy: input.retryPolicy } : {},
20930
+ ...input.lastFailureKind !== void 0 ? { lastFailureKind: input.lastFailureKind } : {},
20567
20931
  ...input.assignee !== void 0 ? { assignee: input.assignee } : {},
20568
20932
  status: input.status ?? "queued"
20569
20933
  });
20570
- assignment.dispatchedAt = assignment.dispatchedAt ?? nowIso();
20934
+ assignment.claimedAt = assignment.claimedAt ?? nowIso();
20935
+ assignment.dispatchedAt = assignment.dispatchedAt ?? assignment.claimedAt;
20571
20936
  task.assignment = assignment;
20572
20937
  if (assignment.agentId ?? assignment.role ?? assignment.name) {
20573
20938
  task.assignedAgent = assignment.agentId ?? assignment.role ?? assignment.name;
@@ -20577,10 +20942,16 @@ async function claimReadyTaskOnBoard(projectRoot, boardId, input) {
20577
20942
  }
20578
20943
  task.status = assignment.status === "running" ? "in_progress" : "ready";
20579
20944
  delete task.completedAt;
20945
+ syncTaskColumnForStatus(board, task, previousColumnId);
20580
20946
  task.updatedAt = nowIso();
20581
20947
  board.updatedAt = task.updatedAt;
20948
+ event = createKanbanEvent(board.id, task, "task.claimed", {
20949
+ before: current ? { ...current } : void 0,
20950
+ after: { ...assignment }
20951
+ });
20582
20952
  return task;
20583
20953
  });
20954
+ if (updated && event) await emitKanbanEvent(projectRoot, event);
20584
20955
  return updated?.result ? { board: updated.board, task: updated.result } : null;
20585
20956
  }
20586
20957
  function compareTasksForWork(a, b) {
@@ -21047,11 +21418,48 @@ function reconcileTaskColumns(board, now) {
21047
21418
  function normalizeAllColumnTaskOrders(board) {
21048
21419
  for (const column of board.columns) normalizeColumnTaskOrders(board, column.id);
21049
21420
  }
21421
+ function createKanbanEvent(boardId, task, type, details = {}) {
21422
+ return {
21423
+ id: randomUUID(),
21424
+ boardId,
21425
+ taskId: task.id,
21426
+ type,
21427
+ ts: nowIso(),
21428
+ ...task.assignment?.agentId !== void 0 ? { actor: task.assignment.agentId } : {},
21429
+ ...task.assignment?.subagentId !== void 0 ? { subagentId: task.assignment.subagentId } : {},
21430
+ ...task.assignment?.runTaskId !== void 0 ? { runTaskId: task.assignment.runTaskId } : {},
21431
+ ...details
21432
+ };
21433
+ }
21434
+ async function emitKanbanEvent(projectRoot, event) {
21435
+ try {
21436
+ await appendKanbanEvent(projectRoot, event.boardId, event);
21437
+ } catch {
21438
+ }
21439
+ }
21440
+ function assignmentEventType(status) {
21441
+ return status === "completed" ? "task.assignment.completed" : status === "failed" ? "task.assignment.failed" : status === "running" ? "task.assignment.running" : status === "cancelled" ? "task.assignment.cancelled" : "task.assignment.updated";
21442
+ }
21443
+ function columnIdForKanbanStatus(board, status) {
21444
+ const preferred = status === "completed" ? ["done", "completed"] : status === "in_progress" ? ["in-progress", "progress", "doing"] : status === "review" || status === "failed" ? ["review"] : status === "blocked" ? ["blocked", "backlog"] : status === "ready" ? ["todo", "ready", "backlog"] : status === "archived" ? ["done", "archive", "backlog"] : ["todo", "backlog"];
21445
+ for (const columnRef of preferred) {
21446
+ const columnId = existingColumnId(board, columnRef);
21447
+ if (columnId) return columnId;
21448
+ }
21449
+ return board.columns[0]?.id;
21450
+ }
21050
21451
  function normalizeColumnTaskOrders(board, columnId) {
21051
21452
  board.tasks.filter((task) => task.columnId === columnId).sort((a, b) => a.order - b.order || a.createdAt.localeCompare(b.createdAt)).forEach((task, index) => {
21052
21453
  task.order = index;
21053
21454
  });
21054
21455
  }
21456
+ function syncTaskColumnForStatus(board, task, previousColumnId) {
21457
+ const nextColumnId = columnIdForKanbanStatus(board, task.status);
21458
+ if (!nextColumnId || nextColumnId === task.columnId) return;
21459
+ task.columnId = nextColumnId;
21460
+ normalizeColumnTaskOrders(board, previousColumnId);
21461
+ placeTaskInColumn(board, task, nextColumnId, void 0);
21462
+ }
21055
21463
  function placeTaskInColumn(board, task, columnId, targetOrder) {
21056
21464
  const tasks = board.tasks.filter((candidate) => candidate.columnId === columnId && candidate.id !== task.id).sort((a, b) => a.order - b.order || a.createdAt.localeCompare(b.createdAt));
21057
21465
  const index = clampOrder(targetOrder, tasks.length);
@@ -21324,6 +21732,9 @@ function makeLLMClassifier(complete) {
21324
21732
  }
21325
21733
 
21326
21734
  // src/coordination/director-tools.ts
21735
+ function nowIso2() {
21736
+ return (/* @__PURE__ */ new Date()).toISOString();
21737
+ }
21327
21738
  function makeSpawnTool(director, roster) {
21328
21739
  const inputSchema = {
21329
21740
  type: "object",
@@ -21881,8 +22292,8 @@ function makeAssignTool(director) {
21881
22292
  function makeKanbanQueueTool(director, roster) {
21882
22293
  return {
21883
22294
  name: "kanban_queue",
21884
- description: "Claim dependency-ready Kanban tasks and dispatch them into the Director fleet. Preserves per-task provider/model/role/tool routing metadata, assigns each claimed task to a spawned subagent, and can await results while writing completion back to Kanban.",
21885
- usageHint: 'Use action:"dispatch_ready" with optional boardId/taskId/maxTasks. Set awaitCompletion:true when you want this call to update Kanban to completed/failed before returning; otherwise use await_tasks and kanban mark_assignment later.',
22295
+ description: "Claim dependency-ready Kanban tasks and dispatch them into the Director fleet. Preserves per-task provider/model/role/tool routing metadata, seeds lease metadata (claimedAt, leaseExpiresAt, heartbeatAt), assigns each claimed task to a spawned subagent, instructs workers to call kanban heartbeat_assignment periodically, and can await results while writing completion back to Kanban.",
22296
+ usageHint: 'Use action:"dispatch_ready" with optional boardId/taskId/maxTasks. Set heartbeatIntervalMs (default 60s) and leaseTtlMs (default 5m) to size stale-recovery windows. Set awaitCompletion:true when you want this call to update Kanban to completed/failed before returning; otherwise use await_tasks and kanban mark_assignment later.',
21886
22297
  permission: "auto",
21887
22298
  mutating: true,
21888
22299
  capabilities: [ToolCapabilities.SUBAGENT_SPAWN, ToolCapabilities.FS_WRITE],
@@ -21913,6 +22324,16 @@ function makeKanbanQueueTool(director, roster) {
21913
22324
  minimum: 1,
21914
22325
  description: "Optional per-assigned-task tool-call cap."
21915
22326
  },
22327
+ heartbeatIntervalMs: {
22328
+ type: "number",
22329
+ minimum: 1e3,
22330
+ description: "Suggested heartbeat interval for the worker. Default 60000 (60s). Workers are instructed to call kanban heartbeat_assignment at this cadence."
22331
+ },
22332
+ leaseTtlMs: {
22333
+ type: "number",
22334
+ minimum: 1e3,
22335
+ description: "Lease time-to-live seeded on dispatch. Default 300000 (5m). Workers should refresh via heartbeat_assignment before expiry."
22336
+ },
21916
22337
  agentId: { type: "string" },
21917
22338
  name: { type: "string" },
21918
22339
  role: { type: "string" },
@@ -21935,6 +22356,14 @@ function makeKanbanQueueTool(director, roster) {
21935
22356
  const projectRoot = ctx.projectRoot;
21936
22357
  if (!projectRoot) return { error: "kanban_queue requires ctx.projectRoot." };
21937
22358
  const maxTasks = Math.max(1, Math.min(20, Math.floor(i.maxTasks ?? 1)));
22359
+ const leaseTtlMs = Math.max(1e3, Math.floor(i.leaseTtlMs ?? 5 * 60 * 1e3));
22360
+ const claimedAt = nowIso2();
22361
+ const leaseSeeding = {
22362
+ leaseId: randomUUID(),
22363
+ claimedAt,
22364
+ heartbeatAt: claimedAt,
22365
+ leaseExpiresAt: new Date(Date.now() + leaseTtlMs).toISOString()
22366
+ };
21938
22367
  const candidateTaskIds = i.taskId !== void 0 ? [i.taskId] : i.query ? (await listReadyTasks(projectRoot, {
21939
22368
  ...i.boardId !== void 0 ? { boardId: i.boardId } : {}
21940
22369
  })).filter((candidate) => matchesKanbanQueueQuery(candidate.task, i.query ?? "")).slice(0, maxTasks).map((candidate) => candidate.task.id) : void 0;
@@ -21955,6 +22384,7 @@ function makeKanbanQueueTool(director, roster) {
21955
22384
  ...i.fallbackModels !== void 0 ? { fallbackModels: i.fallbackModels } : {},
21956
22385
  ...i.tools !== void 0 ? { tools: i.tools } : {},
21957
22386
  ...i.allowedCapabilities !== void 0 ? { allowedCapabilities: i.allowedCapabilities } : {},
22387
+ ...leaseSeeding !== void 0 ? leaseSeeding : {},
21958
22388
  status: "queued"
21959
22389
  });
21960
22390
  if (!claim) {
@@ -21963,13 +22393,34 @@ function makeKanbanQueueTool(director, roster) {
21963
22393
  }
21964
22394
  let subagentId;
21965
22395
  let runTaskId;
22396
+ const costCeiling = claim.task.assignment?.costCeilingUsd;
22397
+ if (costCeiling !== void 0) {
22398
+ const remaining = director.getRemainingBudgetUsd();
22399
+ if (remaining !== void 0 && remaining < costCeiling) {
22400
+ await updateTaskAssignment(projectRoot, claim.board.id, claim.task.id, {
22401
+ status: "failed",
22402
+ error: `Cost ceiling ${costCeiling} exceeds remaining budget ${remaining.toFixed(4)}`,
22403
+ lastResult: "Skipped by kanban_queue cost gate (Sprint 3)"
22404
+ });
22405
+ errors.push({
22406
+ taskId: claim.task.id,
22407
+ error: `Cost ceiling ${costCeiling} exceeds remaining budget ${remaining.toFixed(4)}`
22408
+ });
22409
+ continue;
22410
+ }
22411
+ }
21966
22412
  try {
21967
22413
  const config = buildKanbanSubagentConfig(claim.task, i, roster);
21968
22414
  subagentId = await director.spawn(config);
21969
22415
  runTaskId = await director.assign({
21970
22416
  id: randomUUID(),
21971
22417
  subagentId,
21972
- description: buildKanbanFleetTaskPrompt(claim.board, claim.task),
22418
+ description: buildKanbanFleetTaskPrompt(claim.board, claim.task, {
22419
+ heartbeatIntervalMs: i.heartbeatIntervalMs ?? 6e4,
22420
+ leaseTtlMs,
22421
+ leaseId: leaseSeeding.leaseId,
22422
+ leaseExpiresAt: leaseSeeding.leaseExpiresAt
22423
+ }),
21973
22424
  ...i.maxToolCalls !== void 0 ? { maxToolCalls: i.maxToolCalls } : {},
21974
22425
  ...i.timeoutMs !== void 0 ? { timeoutMs: i.timeoutMs } : {},
21975
22426
  context: {
@@ -22067,7 +22518,9 @@ function normalizeKanbanQueueInput(input) {
22067
22518
  fallbackModels: stringArray(raw.fallbackModels),
22068
22519
  tools: stringArray(raw.tools),
22069
22520
  allowedCapabilities: stringArray(raw.allowedCapabilities),
22070
- worktree: normalizeWorktreeOverride(raw.worktree)
22521
+ worktree: normalizeWorktreeOverride(raw.worktree),
22522
+ heartbeatIntervalMs: typeof raw.heartbeatIntervalMs === "number" ? raw.heartbeatIntervalMs : void 0,
22523
+ leaseTtlMs: typeof raw.leaseTtlMs === "number" ? raw.leaseTtlMs : void 0
22071
22524
  };
22072
22525
  }
22073
22526
  function buildKanbanSubagentConfig(task, input, roster) {
@@ -22085,7 +22538,8 @@ function buildKanbanSubagentConfig(task, input, roster) {
22085
22538
  ...input.fallbackModels ?? assignment?.fallbackModels ? { fallbackModels: input.fallbackModels ?? assignment?.fallbackModels } : {},
22086
22539
  ...tools ? { tools: ensureKanbanTool(tools) } : {},
22087
22540
  ...input.allowedCapabilities ?? assignment?.allowedCapabilities ? { allowedCapabilities: input.allowedCapabilities ?? assignment?.allowedCapabilities } : {},
22088
- ...input.worktree !== void 0 ? { worktree: input.worktree } : {}
22541
+ ...input.worktree !== void 0 ? { worktree: input.worktree } : {},
22542
+ ...assignment?.costCeilingUsd !== void 0 ? { maxCostUsd: assignment.costCeilingUsd } : {}
22089
22543
  };
22090
22544
  }
22091
22545
  function ensureKanbanTool(tools) {
@@ -22105,7 +22559,7 @@ function matchesKanbanQueueQuery(task, query) {
22105
22559
  ...task.labels ?? []
22106
22560
  ].filter(Boolean).some((value) => String(value).toLowerCase().includes(normalized));
22107
22561
  }
22108
- function buildKanbanFleetTaskPrompt(board, task) {
22562
+ function buildKanbanFleetTaskPrompt(board, task, lease) {
22109
22563
  const dependencyLines = (task.dependsOn ?? []).map((depId) => board.tasks.find((candidate) => candidate.id === depId)).filter((dep) => Boolean(dep)).map((dep) => `- ${dep.title} [${dep.status}] (${dep.id})`);
22110
22564
  const checks = task.successCriteria?.map((check) => `- ${check.description}`).join("\n");
22111
22565
  const metrics = task.goalMetrics?.map(
@@ -22152,9 +22606,24 @@ ${checks}` : "",
22152
22606
  metrics ? `Goal metrics:
22153
22607
  ${metrics}` : "",
22154
22608
  task.labels?.length ? `Labels: ${task.labels.join(", ")}` : "",
22609
+ "Lease contract (Sprint 1):",
22610
+ `- leaseId: ${lease.leaseId}`,
22611
+ `- claimedAt: ${task.assignment?.claimedAt ?? "<unknown>"}`,
22612
+ `- leaseExpiresAt: ${lease.leaseExpiresAt}`,
22613
+ `- expected heartbeatIntervalMs: ${lease.heartbeatIntervalMs}`,
22614
+ `- expected leaseTtlMs: ${lease.leaseTtlMs}`,
22615
+ "",
22616
+ "Retry policy:",
22617
+ `- retryPolicy: ${task.assignment?.retryPolicy ?? task.retryPolicy ?? "<unset>"}`,
22618
+ `- maxAttempts: ${task.assignment?.maxAttempts ?? "<unset>"}`,
22619
+ `- costCeilingUsd: ${task.assignment?.costCeilingUsd ?? task.costCeilingUsd ?? "<unset>"}`,
22155
22620
  "",
22156
22621
  "Work this task end-to-end. If scope is too broad or too small, use the kanban tool to split_task or merge_tasks instead of losing traceability.",
22157
- `When you start or finish, call kanban with action "mark_assignment", boardId "${board.id}", taskId "${task.id}", and assignmentStatus "running", "completed", or "failed". Include lastResult or error when you finish.`,
22622
+ `When you start, call kanban with action "mark_assignment", boardId "${board.id}", taskId "${task.id}", and assignmentStatus "running". Include subagentId and runTaskId when you have them.`,
22623
+ `To stay alive in the queue, call kanban with action "heartbeat_assignment", boardId "${board.id}", taskId "${task.id}", and heartbeatAt set to the current time. Cadence must be <= heartbeatIntervalMs and well before leaseExpiresAt.`,
22624
+ `When you finish, call kanban with action "mark_assignment", boardId "${board.id}", taskId "${task.id}", and assignmentStatus "completed" or "failed". Include lastResult or error.`,
22625
+ `If you cannot finish in time, call kanban with action "heartbeat_assignment" to extend the lease, or with action "release_task" to release so another worker can claim. Do NOT silently abandon the assignment.`,
22626
+ 'On failure the host may call kanban with action "recover_stale" (mode: retry/release/fail); respect its decisions and do not duplicate work in parallel.',
22158
22627
  "When finished, report what changed, what you verified, and any remaining blockers."
22159
22628
  ].filter(Boolean).join("\n");
22160
22629
  }
@@ -23234,6 +23703,15 @@ var Director = class _Director {
23234
23703
  getLeaderContextPressure() {
23235
23704
  return this.leaderContextPressure;
23236
23705
  }
23706
+ /**
23707
+ * Remaining USD budget for the entire fleet (when a cap is configured).
23708
+ * Returns `undefined` when no cap was set (Infinity).
23709
+ */
23710
+ getRemainingBudgetUsd() {
23711
+ if (this.maxFleetCostUsd === Number.POSITIVE_INFINITY) return void 0;
23712
+ const totalCost = this.usage.snapshot().total?.cost ?? 0;
23713
+ return Math.max(0, this.maxFleetCostUsd - totalCost);
23714
+ }
23237
23715
  resolveMaxContext() {
23238
23716
  const resolved = typeof this.maxContext === "function" ? this.maxContext() : this.maxContext;
23239
23717
  return resolved && resolved > 0 ? resolved : 128e3;
@@ -26880,6 +27358,17 @@ var GlobalMailbox = class {
26880
27358
  _messageCacheMtime = -1;
26881
27359
  /** Size of the file when `_messageCache` was populated (extra guard). */
26882
27360
  _messageCacheSize = -1;
27361
+ /**
27362
+ * Serializes reads of the message file so overlapping concurrent
27363
+ * `_readMessagesCached()` calls don't both enter the incremental "file
27364
+ * only grew" branch against the same stale `_messageCacheSize` and
27365
+ * each push the same tail bytes onto the cache (duplicating every
27366
+ * appended message). The chain runs each read to completion before
27367
+ * the next starts, in issue order — readers are read-only and never
27368
+ * conflict with each other on content, only on the cache mutation
27369
+ * that follows the read. Pattern mirrors `DefaultMemoryStore.runSerialized`.
27370
+ */
27371
+ _readChain = Promise.resolve([]);
26883
27372
  /**
26884
27373
  * @param projectDir — `~/.wrongstack/projects/<slug>/`
26885
27374
  * @param events — optional EventBus for real-time TUI/WebUI notifications
@@ -26933,7 +27422,8 @@ var GlobalMailbox = class {
26933
27422
  await fsp14.mkdir(path4.dirname(this.messagePath), { recursive: true });
26934
27423
  await withFileLock(this.messagePath, async () => {
26935
27424
  await fsp14.appendFile(this.messagePath, line, "utf8");
26936
- this._pushToCache(msg);
27425
+ const { mtimeMs, size } = await this._statMessageFile();
27426
+ this._pushToCache(msg, mtimeMs, size);
26937
27427
  });
26938
27428
  this.publishHqMailboxEvent({
26939
27429
  mailboxId: this.hqMailboxId,
@@ -26977,7 +27467,6 @@ var GlobalMailbox = class {
26977
27467
  for (const a of input.acks) {
26978
27468
  byId.set(a.messageId, a);
26979
27469
  }
26980
- let cacheSnapshot = null;
26981
27470
  await withFileLock(this.messagePath, async () => {
26982
27471
  const all = await this._readMessagesFresh();
26983
27472
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -27005,9 +27494,9 @@ var GlobalMailbox = class {
27005
27494
  const serialized = all.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;
27006
27495
  await fsp14.writeFile(this.messagePath, serialized, "utf8");
27007
27496
  }
27008
- cacheSnapshot = all;
27497
+ const { mtimeMs, size } = await this._statMessageFile();
27498
+ this._setMessageCache(all, mtimeMs, size);
27009
27499
  });
27010
- if (cacheSnapshot) this._setMessageCache(cacheSnapshot);
27011
27500
  for (const message of updated) {
27012
27501
  this.publishHqMailboxEvent({
27013
27502
  mailboxId: this.hqMailboxId,
@@ -27031,7 +27520,6 @@ var GlobalMailbox = class {
27031
27520
  }
27032
27521
  async softDelete(mailId, by) {
27033
27522
  let updated = null;
27034
- let cacheSnapshot = null;
27035
27523
  await withFileLock(this.messagePath, async () => {
27036
27524
  const all = await this._readMessagesFresh();
27037
27525
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -27047,9 +27535,9 @@ var GlobalMailbox = class {
27047
27535
  }
27048
27536
  const serialized = all.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;
27049
27537
  await fsp14.writeFile(this.messagePath, serialized, "utf8");
27050
- cacheSnapshot = all;
27538
+ const { mtimeMs, size } = await this._statMessageFile();
27539
+ this._setMessageCache(all, mtimeMs, size);
27051
27540
  });
27052
- if (cacheSnapshot) this._setMessageCache(cacheSnapshot);
27053
27541
  if (updated !== null) {
27054
27542
  this.publishHqMailboxEvent({
27055
27543
  mailboxId: this.hqMailboxId,
@@ -27062,7 +27550,6 @@ var GlobalMailbox = class {
27062
27550
  }
27063
27551
  async restore(mailId) {
27064
27552
  let updated = null;
27065
- let cacheSnapshot = null;
27066
27553
  await withFileLock(this.messagePath, async () => {
27067
27554
  const all = await this._readMessagesFresh();
27068
27555
  for (const m of all) {
@@ -27073,9 +27560,9 @@ var GlobalMailbox = class {
27073
27560
  }
27074
27561
  const serialized = all.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;
27075
27562
  await fsp14.writeFile(this.messagePath, serialized, "utf8");
27076
- cacheSnapshot = all;
27563
+ const { mtimeMs, size } = await this._statMessageFile();
27564
+ this._setMessageCache(all, mtimeMs, size);
27077
27565
  });
27078
- if (cacheSnapshot) this._setMessageCache(cacheSnapshot);
27079
27566
  if (updated !== null) {
27080
27567
  this.publishHqMailboxEvent({
27081
27568
  mailboxId: this.hqMailboxId,
@@ -27320,8 +27807,9 @@ var GlobalMailbox = class {
27320
27807
  async clearAll() {
27321
27808
  await withFileLock(this.messagePath, async () => {
27322
27809
  await fsp14.writeFile(this.messagePath, "", "utf8");
27810
+ const { mtimeMs, size } = await this._statMessageFile();
27811
+ this._setMessageCache([], mtimeMs, size);
27323
27812
  });
27324
- this._setMessageCache([]);
27325
27813
  }
27326
27814
  async purgeStale(opts) {
27327
27815
  const COMPLETED_MAX_AGE_MS = opts?.completedMaxAgeMs ?? 864e5;
@@ -27353,7 +27841,8 @@ var GlobalMailbox = class {
27353
27841
  const content = kept.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;
27354
27842
  await fsp14.writeFile(this.messagePath, content, "utf8");
27355
27843
  }
27356
- this._setMessageCache(kept);
27844
+ const { mtimeMs, size } = await this._statMessageFile();
27845
+ this._setMessageCache(kept, mtimeMs, size);
27357
27846
  });
27358
27847
  return {
27359
27848
  completedPurged,
@@ -27440,14 +27929,43 @@ var GlobalMailbox = class {
27440
27929
  * from writers that just took the file lock — the read reflects the
27441
27930
  * authoritative post-lock state and should be served to subsequent
27442
27931
  * queries without re-reading.
27932
+ *
27933
+ * The mtime/size are captured from the stat at read time so the cache
27934
+ * trackers match exactly what was parsed. Writers that subsequently
27935
+ * rewrite the file MUST re-stat after the write and re-promote with the
27936
+ * post-write values (see ackMany / softDelete / restore / purgeStale /
27937
+ * clearAll) — otherwise a concurrent reader misclassifies the rewrite
27938
+ * as a "file only grew" append and corrupts the cache.
27443
27939
  */
27444
27940
  async _readMessagesFresh() {
27445
27941
  const all = await this._readMessages();
27446
- this._setMessageCache(all);
27942
+ const { mtimeMs, size } = await this._statMessageFile();
27943
+ this._setMessageCache(all, mtimeMs, size);
27447
27944
  return all;
27448
27945
  }
27449
27946
  /**
27450
- * Read messages, consulting the mtime-bounded in-memory cache first.
27947
+ * Stat the message file, returning its mtimeMs and size. Returns
27948
+ * `-1/-1` when the file does not yet exist (ENOENT) so callers can
27949
+ * still promote a cache snapshot — the next read will re-stat and
27950
+ * fall through to a full re-read. Call from inside the file lock so
27951
+ * the result reflects the post-write on-disk state, not a later
27952
+ * intermediate state from another process.
27953
+ */
27954
+ async _statMessageFile() {
27955
+ try {
27956
+ const st = await fsp14.stat(this.messagePath);
27957
+ return { mtimeMs: st.mtimeMs, size: st.size };
27958
+ } catch (err) {
27959
+ if (err.code === "ENOENT") {
27960
+ return { mtimeMs: -1, size: -1 };
27961
+ }
27962
+ throw err;
27963
+ }
27964
+ }
27965
+ /**
27966
+ * Read messages, consulting the mtime-bounded in-memory cache first,
27967
+ * serialized so concurrent callers don't both mutate the cache.
27968
+ *
27451
27969
  * The mailbox file is shared across processes; every `send`/`ack`/
27452
27970
  * `clearAll`/`purgeStale` takes the file lock, so writes are serialized
27453
27971
  * and a changed mtimeMs is a definitive freshness signal. When the
@@ -27458,8 +27976,28 @@ var GlobalMailbox = class {
27458
27976
  * When the file only grew (new messages appended by another process),
27459
27977
  * we read and parse just the tail bytes instead of the entire file.
27460
27978
  * This avoids re-parsing the full 10K-message history on every check.
27979
+ *
27980
+ * SERIALIZATION: the actual work is chained onto `_readChain` so two
27981
+ * overlapping calls can't both pass the `st.size > _messageCacheSize`
27982
+ * incremental check against the same stale tracker and each push the
27983
+ * same tail bytes onto the cache (duplicating every appended message).
27984
+ * Readers don't conflict on file content — only on the cache mutation
27985
+ * that follows the read — so we run them one at a time in issue order.
27986
+ * Errors in the chain are swallowed so a failed read never poisons
27987
+ * subsequent reads; each caller observes and re-throws its own error.
27988
+ */
27989
+ _readMessagesCached() {
27990
+ const run = this._readChain.catch(() => void 0).then(() => this._readMessagesCachedWork());
27991
+ this._readChain = run.catch(() => []);
27992
+ return run;
27993
+ }
27994
+ /**
27995
+ * The un-serialized body of {@link _readMessagesCached}. Reads the
27996
+ * message file with the mtime-bounded cache + incremental-tail
27997
+ * optimization. Must only be called from `_readMessagesCached` so the
27998
+ * cache mutations here don't race a sibling read.
27461
27999
  */
27462
- async _readMessagesCached() {
28000
+ async _readMessagesCachedWork() {
27463
28001
  try {
27464
28002
  const st = await fsp14.stat(this.messagePath);
27465
28003
  if (this._messageCache !== null && this._messageCacheMtime === st.mtimeMs && this._messageCacheSize === st.size) {
@@ -27488,9 +28026,19 @@ var GlobalMailbox = class {
27488
28026
  }
27489
28027
  }
27490
28028
  /**
27491
- * Replace the in-memory cache. Caller is responsible for guaranteeing
27492
- * that `messages` reflects the current on-disk state (e.g. they just
27493
- * read or wrote it under the file lock).
28029
+ * Replace the in-memory cache, setting the mtime/size trackers
28030
+ * synchronously in the same step. Callers MUST pass the stat of the
28031
+ * on-disk file state that produced `messages`.
28032
+ *
28033
+ * Why both are required (not fire-and-forget): `_readMessagesCached()`
28034
+ * validates the cache against a fresh stat using these two trackers.
28035
+ * If the cache array is updated but the trackers lag behind (e.g. via
28036
+ * a deferred `stat().then(...)`), a concurrent reader landing in that
28037
+ * window sees a mismatched mtime and falls into the incremental
28038
+ * "file only grew" branch — parsing rewritten bytes as an appended
28039
+ * tail and corrupting the cache with duplicates/garbage. So both
28040
+ * values are captured under the file lock and applied synchronously
28041
+ * here, matching the fix already shipped in DefaultMailbox.
27494
28042
  */
27495
28043
  _setMessageCache(messages, mtime, size) {
27496
28044
  if (messages.length > MESSAGE_CACHE_MAX_ENTRIES) {
@@ -27500,25 +28048,27 @@ var GlobalMailbox = class {
27500
28048
  return;
27501
28049
  }
27502
28050
  this._messageCache = messages;
27503
- if (mtime !== void 0 && size !== void 0) {
27504
- this._messageCacheMtime = mtime;
27505
- this._messageCacheSize = size;
27506
- } else {
27507
- void fsp14.stat(this.messagePath).then((st) => {
27508
- this._messageCacheMtime = st.mtimeMs;
27509
- this._messageCacheSize = st.size;
27510
- }).catch(() => {
27511
- });
27512
- }
28051
+ this._messageCacheMtime = mtime;
28052
+ this._messageCacheSize = size;
27513
28053
  }
27514
28054
  /**
27515
28055
  * Append a single just-sent message to the in-memory cache without
27516
28056
  * re-reading the file. The caller must hold the file lock (or have
27517
- * just released it after a successful append) so the cache stays
27518
- * consistent with on-disk state.
27519
- */
27520
- _pushToCache(msg) {
27521
- if (this._messageCache === null) return;
28057
+ * just released it after a successful append) and MUST pass the
28058
+ * post-append stat so the mtime/size trackers advance in lock-step
28059
+ * with the pushed content.
28060
+ *
28061
+ * Why the stat is required here: without it, `_messageCacheSize`
28062
+ * stays at the pre-append value. A concurrent `_readMessagesCached()`
28063
+ * then sees `st.size > _messageCacheSize` (the file did grow), takes
28064
+ * the incremental branch, and re-reads the just-appended tail —
28065
+ * pushing the same message onto the cache a second time. Setting the
28066
+ * trackers here closes that window for the local-process append path.
28067
+ */
28068
+ _pushToCache(msg, mtime, size) {
28069
+ if (this._messageCache === null) {
28070
+ return;
28071
+ }
27522
28072
  if (this._messageCache.length >= MESSAGE_CACHE_MAX_ENTRIES) {
27523
28073
  this._messageCache = null;
27524
28074
  this._messageCacheMtime = -1;
@@ -27526,6 +28076,8 @@ var GlobalMailbox = class {
27526
28076
  return;
27527
28077
  }
27528
28078
  this._messageCache.push(msg);
28079
+ this._messageCacheMtime = mtime;
28080
+ this._messageCacheSize = size;
27529
28081
  }
27530
28082
  async _ensureRegistry() {
27531
28083
  await fsp14.mkdir(path4.dirname(this.registryPath), { recursive: true });
@@ -35657,6 +36209,7 @@ function createMailboxChecker(opts) {
35657
36209
  for (const batch of batches) {
35658
36210
  for (const m of batch) {
35659
36211
  if (seen.has(m.id)) continue;
36212
+ if (opts.include && !opts.include(m)) continue;
35660
36213
  seen.add(m.id);
35661
36214
  messages.push(m);
35662
36215
  }
@@ -35667,7 +36220,7 @@ function createMailboxChecker(opts) {
35667
36220
  for (const m of fresh) {
35668
36221
  injectedIds.add(m.id);
35669
36222
  }
35670
- if (fresh.length > 0) {
36223
+ if (fresh.length > 0 && opts.ack !== false) {
35671
36224
  void mailbox.ackMany({
35672
36225
  acks: fresh.map((m) => ({
35673
36226
  messageId: m.id,
@@ -35696,6 +36249,27 @@ var TYPE_LABEL = {
35696
36249
  result: "\u2705 RESULT",
35697
36250
  review: "\u{1F50D} REVIEW"
35698
36251
  };
36252
+ function buildMailboxBtwAwarenessBlock(messages) {
36253
+ if (messages.length === 0) throw new Error("buildMailboxBtwAwarenessBlock called with empty messages");
36254
+ const parts = [];
36255
+ parts.push("[MAILBOX BTW] Mailbox awareness update:");
36256
+ parts.push("");
36257
+ parts.push(
36258
+ "Disclaimer: an agent just sent mail to everyone or to you. Do not stop your current work to look at it; this is only for awareness. This notification came from the WrongStack mailbox system."
36259
+ );
36260
+ parts.push("");
36261
+ for (const m of messages) {
36262
+ const typeLabel = TYPE_LABEL[m.type] ?? `\u{1F4E8} ${m.type.toUpperCase()}`;
36263
+ const scope = m.to === "*" ? "broadcast to everyone" : `addressed to ${m.to}`;
36264
+ parts.push(`--- ${typeLabel} from ${m.from} (${scope}) ---`);
36265
+ parts.push(`Subject: ${m.subject}`);
36266
+ parts.push("");
36267
+ parts.push(m.body);
36268
+ parts.push("");
36269
+ }
36270
+ parts.push("[END MAILBOX BTW]");
36271
+ return { type: "text", text: parts.join("\n") };
36272
+ }
35699
36273
  function buildMailboxBlock(messages) {
35700
36274
  if (messages.length === 0) throw new Error("buildMailboxBlock called with empty messages");
35701
36275
  const parts = [];
@@ -35890,14 +36464,46 @@ function attachMailboxCheckerInner(a, source) {
35890
36464
  mailbox.heartbeat({ agentId: id }).catch(() => {
35891
36465
  });
35892
36466
  }, HEARTBEAT_INTERVAL_MS2);
36467
+ heartbeatTimer.unref?.();
35893
36468
  a.ctx.registerAbortHook(() => {
35894
36469
  clearInterval(heartbeatTimer);
35895
36470
  });
35896
- return createMailboxChecker({
36471
+ const mailboxCheckerOptions = {
35897
36472
  mailbox,
35898
36473
  agentId: () => ensureRegistered(),
35899
36474
  aliases: [baseIdOf()]
36475
+ };
36476
+ const checkMailbox = createMailboxChecker(mailboxCheckerOptions);
36477
+ const checkMailboxAwareness = createMailboxChecker({
36478
+ ...mailboxCheckerOptions,
36479
+ include: (m) => m.type !== "control",
36480
+ ack: false
36481
+ });
36482
+ const MAILBOX_AWARENESS_INTERVAL_MS = 5e3;
36483
+ let pollInFlight = false;
36484
+ let awarenessDisposed = false;
36485
+ const pollMailboxAwareness = async () => {
36486
+ if (awarenessDisposed || pollInFlight) return;
36487
+ pollInFlight = true;
36488
+ try {
36489
+ const messages = await checkMailboxAwareness();
36490
+ if (!awarenessDisposed && messages.length > 0) {
36491
+ setBtwNote(a.ctx, buildMailboxBtwAwarenessBlock(messages).text);
36492
+ }
36493
+ } catch {
36494
+ } finally {
36495
+ pollInFlight = false;
36496
+ }
36497
+ };
36498
+ const awarenessTimer = setInterval(() => {
36499
+ void pollMailboxAwareness();
36500
+ }, MAILBOX_AWARENESS_INTERVAL_MS);
36501
+ awarenessTimer.unref?.();
36502
+ a.ctx.registerAbortHook(() => {
36503
+ awarenessDisposed = true;
36504
+ clearInterval(awarenessTimer);
35900
36505
  });
36506
+ return checkMailbox;
35901
36507
  }
35902
36508
  var PULSE_MIN_READ_INTERVAL_MS = 3e4;
35903
36509
  function attachFleetPulse(a, cfg) {
@@ -37637,6 +38243,146 @@ var Context = class {
37637
38243
  }
37638
38244
  };
37639
38245
 
38246
+ // src/core/continue-intent.ts
38247
+ init_todos_format();
38248
+ var CONTINUE_PHRASES = /* @__PURE__ */ new Set([
38249
+ // ── English ──
38250
+ "continue",
38251
+ "cont",
38252
+ "continue continue",
38253
+ "continue working",
38254
+ "keep going",
38255
+ "keep it going",
38256
+ "keep going on",
38257
+ "keep working",
38258
+ "keep on",
38259
+ "carry on",
38260
+ "go on",
38261
+ "goon",
38262
+ "go ahead",
38263
+ "proceed",
38264
+ "proceed further",
38265
+ "onward",
38266
+ "onwards",
38267
+ "next",
38268
+ "next step",
38269
+ "more",
38270
+ "resume",
38271
+ "and continue",
38272
+ "yes continue",
38273
+ "ok continue",
38274
+ // ── Turkish ──
38275
+ "devam",
38276
+ "devam et",
38277
+ "devam et bakalim",
38278
+ "devam edelim",
38279
+ "devam edin",
38280
+ "devam etsene",
38281
+ "devam etsenize",
38282
+ "devam ediyoruz",
38283
+ "devam et lutfen",
38284
+ "surdur",
38285
+ "devam etsen",
38286
+ "devam et hadi",
38287
+ "hadi devam",
38288
+ // ── Other Latin-script (light coverage) ──
38289
+ "weiter",
38290
+ // de
38291
+ "mach weiter",
38292
+ // de
38293
+ "continuar",
38294
+ // es/pt
38295
+ "continua",
38296
+ // es/it/pt
38297
+ "continuer",
38298
+ // fr
38299
+ "continue por favor"
38300
+ // pt/es
38301
+ ]);
38302
+ var POLITENESS_SUFFIXES = [
38303
+ "please",
38304
+ "pls",
38305
+ "plz",
38306
+ "lutfen",
38307
+ "thanks",
38308
+ "thank you",
38309
+ "thx",
38310
+ "ty"
38311
+ ];
38312
+ function foldDiacritics(s) {
38313
+ return s.replace(/ü/g, "u").replace(/ö/g, "o").replace(/ç/g, "c").replace(/ş/g, "s").replace(/ğ/g, "g").replace(/ı/g, "i").replace(/İ/g, "i").replace(/â/g, "a").replace(/î/g, "i").replace(/û/g, "u");
38314
+ }
38315
+ function normalizeContinueInput(raw) {
38316
+ let s = raw.trim().toLowerCase();
38317
+ s = foldDiacritics(s);
38318
+ s = s.replace(/^["'`]+/, "").replace(/["'`]+$/, "");
38319
+ s = s.replace(/^[\s.!?,;:…]+/, "").replace(/[\s.!?,;:…]+$/, "");
38320
+ s = s.replace(/\s+/g, " ").trim();
38321
+ for (const suffix of POLITENESS_SUFFIXES) {
38322
+ if (s === suffix) break;
38323
+ if (s.endsWith(` ${suffix}`)) {
38324
+ s = s.slice(0, s.length - suffix.length - 1).trim();
38325
+ break;
38326
+ }
38327
+ }
38328
+ return s;
38329
+ }
38330
+ var MAX_CONTINUE_WORDS = 4;
38331
+ function detectContinueIntent(raw) {
38332
+ if (!raw) return false;
38333
+ if (raw.length > 40) return false;
38334
+ const normalized = normalizeContinueInput(raw);
38335
+ if (!normalized) return false;
38336
+ if (normalized.split(" ").length > MAX_CONTINUE_WORDS) return false;
38337
+ return CONTINUE_PHRASES.has(normalized);
38338
+ }
38339
+ function ellipsize(s, max = 72) {
38340
+ const flat = s.replace(/\s+/g, " ").trim();
38341
+ return flat.length <= max ? flat : `${flat.slice(0, max - 1)}\u2026`;
38342
+ }
38343
+ function resolveContinuation(input) {
38344
+ const todos = Array.isArray(input.todos) ? input.todos : [];
38345
+ const suggestions = (Array.isArray(input.suggestions) ? input.suggestions : []).filter(
38346
+ (s) => typeof s === "string" && s.trim().length > 0
38347
+ );
38348
+ if (hasOpenTodos(todos)) {
38349
+ const inProgress = todos.find((t2) => t2.status === "in_progress");
38350
+ const next = inProgress ?? todos.find((t2) => t2.status === "pending");
38351
+ if (next) {
38352
+ const total = todos.length;
38353
+ const done = todos.filter((t2) => t2.status === "completed").length;
38354
+ const item = next.status === "in_progress" && next.activeForm ? next.activeForm : next.content;
38355
+ const text2 = [
38356
+ "Continue with the plan. Resume work on the next open todo:",
38357
+ "",
38358
+ ` ${item}`,
38359
+ "",
38360
+ `(${done}/${total} todos complete.) If this item is already done, mark it complete and move to the next open todo. When every todo is complete, stop and give a short summary \u2014 do not invent new work.`
38361
+ ].join("\n");
38362
+ return { source: "todo", text: text2, label: `\u25B6 Continue \u2192 todo: ${ellipsize(item)}` };
38363
+ }
38364
+ }
38365
+ const top = suggestions[0];
38366
+ if (top) {
38367
+ const text2 = [
38368
+ "Continue. Proceed with this next step:",
38369
+ "",
38370
+ ` ${top}`,
38371
+ "",
38372
+ "Carry it out now. When it is done, briefly report the result."
38373
+ ].join("\n");
38374
+ return { source: "suggestion", text: text2, label: `\u25B6 Continue \u2192 ${ellipsize(top)}` };
38375
+ }
38376
+ const text = [
38377
+ "Continue working.",
38378
+ "",
38379
+ "There is no explicit pending task queued, so decide the single most valuable next step yourself based on our conversation so far and the current state of the project, then carry it out.",
38380
+ "",
38381
+ "Prefer finishing, verifying, or hardening work already in progress over starting something unrelated. If the work is genuinely complete and nothing sensible remains, say so plainly in one or two sentences and propose a direction \u2014 do not fabricate busywork."
38382
+ ].join("\n");
38383
+ return { source: "open", text, label: "\u25B6 Continue \u2192 (no pending task \u2014 choosing next step)" };
38384
+ }
38385
+
37640
38386
  // src/core/input-builder.ts
37641
38387
  var InputBuilder = class {
37642
38388
  store;
@@ -45020,107 +45766,170 @@ var DEFAULT_MODES = [
45020
45766
  {
45021
45767
  id: "default",
45022
45768
  name: "Default",
45023
- description: "General-purpose coding assistant",
45769
+ description: "Balanced general-purpose mode; use when no special token/coverage trade-off is needed",
45024
45770
  prompt: "",
45025
- tags: ["general"]
45771
+ tags: ["general", "balanced"]
45772
+ },
45773
+ {
45774
+ id: "brief",
45775
+ name: "Brief",
45776
+ description: "Ultra-compact responses for low-context, high-speed work",
45777
+ prompt: modePrompt("brief"),
45778
+ tags: ["lite", "fast", "concise", "token-saving"],
45779
+ toolPreferences: ["read", "edit", "bash"],
45780
+ suggestedSkills: []
45781
+ },
45782
+ {
45783
+ id: "review-lite",
45784
+ name: "Review Lite",
45785
+ description: "Token-saving code review: changed files only, top correctness/security risks",
45786
+ prompt: modePrompt("review-lite"),
45787
+ tags: ["lite", "review", "quality", "token-saving"],
45788
+ toolPreferences: ["git", "diff", "read", "grep"],
45789
+ suggestedSkills: ["bug-hunter", "typescript-strict"]
45790
+ },
45791
+ {
45792
+ id: "audit-lite",
45793
+ name: "Audit Lite",
45794
+ description: "Token-saving security triage for a small diff or named file",
45795
+ prompt: modePrompt("audit-lite"),
45796
+ tags: ["lite", "security", "audit", "token-saving"],
45797
+ toolPreferences: ["grep", "read", "git"],
45798
+ suggestedSkills: ["security-scanner"]
45799
+ },
45800
+ {
45801
+ id: "plan-lite",
45802
+ name: "Plan Lite",
45803
+ description: "Token-saving planning: 3-6 actionable steps, minimal design debate",
45804
+ prompt: modePrompt("plan-lite"),
45805
+ tags: ["lite", "planning", "architecture", "token-saving"],
45806
+ toolPreferences: ["tree", "glob", "read", "grep"],
45807
+ suggestedSkills: ["refactor-planner"]
45808
+ },
45809
+ {
45810
+ id: "debug-lite",
45811
+ name: "Debug Lite",
45812
+ description: "Token-saving bug triage: one hypothesis, nearest evidence, narrow check",
45813
+ prompt: modePrompt("debug-lite"),
45814
+ tags: ["lite", "debug", "triage", "token-saving"],
45815
+ toolPreferences: ["read", "grep", "test", "logs"],
45816
+ suggestedSkills: ["bug-hunter"]
45817
+ },
45818
+ {
45819
+ id: "test-lite",
45820
+ name: "Test Lite",
45821
+ description: "Token-saving tests: one focused regression or narrow verification target",
45822
+ prompt: modePrompt("test-lite"),
45823
+ tags: ["lite", "testing", "qa", "token-saving"],
45824
+ toolPreferences: ["test", "read", "grep"],
45825
+ suggestedSkills: ["testing"]
45826
+ },
45827
+ {
45828
+ id: "refactor-lite",
45829
+ name: "Refactor Lite",
45830
+ description: "Token-saving cleanup: small scoped behavior-preserving changes",
45831
+ prompt: modePrompt("refactor-lite"),
45832
+ tags: ["lite", "refactor", "token-saving"],
45833
+ toolPreferences: ["read", "edit", "test"],
45834
+ suggestedSkills: ["typescript-strict"]
45835
+ },
45836
+ {
45837
+ id: "research-lite",
45838
+ name: "Research Lite",
45839
+ description: "Token-saving web research: one search, one authoritative fetch, short answer",
45840
+ prompt: modePrompt("research-lite"),
45841
+ tags: ["lite", "research", "web", "token-saving"],
45842
+ toolPreferences: ["search", "fetch"],
45843
+ suggestedSkills: ["research-web"]
45026
45844
  },
45027
45845
  {
45028
45846
  id: "code-reviewer",
45029
- name: "Code Reviewer",
45030
- description: "Focus on code quality, best practices, and potential bugs",
45847
+ name: "Review Deep",
45848
+ description: "Comprehensive code review across contracts, edge cases, lifecycle, errors, concurrency",
45031
45849
  prompt: modePrompt("code-reviewer"),
45032
- tags: ["review", "quality", "security"],
45850
+ tags: ["deep", "review", "quality", "security"],
45033
45851
  toolPreferences: ["read", "grep", "git", "diff", "test"],
45034
45852
  suggestedSkills: ["bug-hunter", "security-scanner", "typescript-strict", "testing"]
45035
45853
  },
45036
45854
  {
45037
45855
  id: "code-auditor",
45038
- name: "Code Auditor",
45039
- description: "Security-focused code analysis",
45856
+ name: "Audit Deep",
45857
+ description: "Comprehensive security audit with category coverage and exploitability notes",
45040
45858
  prompt: modePrompt("code-auditor"),
45041
- tags: ["security", "audit", "compliance"],
45859
+ tags: ["deep", "security", "audit", "compliance"],
45042
45860
  toolPreferences: ["grep", "read", "audit", "bash"],
45043
45861
  suggestedSkills: ["security-scanner", "bug-hunter", "audit-log"]
45044
45862
  },
45045
45863
  {
45046
45864
  id: "architect",
45047
- name: "Software Architect",
45048
- description: "Design patterns, scalability, and system design",
45865
+ name: "Architecture Deep",
45866
+ description: "Comprehensive architecture and cross-module contract analysis",
45049
45867
  prompt: modePrompt("architect"),
45050
- tags: ["architecture", "design", "scalability"],
45868
+ tags: ["deep", "architecture", "design", "scalability"],
45051
45869
  toolPreferences: ["read", "glob", "tree", "diff"],
45052
45870
  suggestedSkills: ["api-design", "refactor-planner", "node-modern", "docker-deploy"]
45053
45871
  },
45054
45872
  {
45055
45873
  id: "debugger",
45056
- name: "Debugger",
45057
- description: "Root cause analysis and error investigation",
45874
+ name: "Debug Deep",
45875
+ description: "Comprehensive root-cause analysis with traces, logs, assumptions, and verification",
45058
45876
  prompt: modePrompt("debugger"),
45059
- tags: ["debug", "investigation", "error-resolution"],
45877
+ tags: ["deep", "debug", "investigation", "error-resolution"],
45060
45878
  toolPreferences: ["read", "grep", "bash", "logs", "test"],
45061
45879
  suggestedSkills: ["bug-hunter", "audit-log", "observability"]
45062
45880
  },
45063
45881
  {
45064
45882
  id: "tester",
45065
- name: "QA Engineer",
45066
- description: "Test coverage, edge cases, and quality assurance",
45883
+ name: "Test Deep",
45884
+ description: "Comprehensive QA mode for coverage, boundaries, isolation, and integration gaps",
45067
45885
  prompt: modePrompt("tester"),
45068
- tags: ["testing", "qa", "quality"],
45886
+ tags: ["deep", "testing", "qa", "quality"],
45069
45887
  toolPreferences: ["read", "grep", "test", "bash"],
45070
45888
  suggestedSkills: ["testing", "bug-hunter", "typescript-strict"]
45071
45889
  },
45072
45890
  {
45073
45891
  id: "devops",
45074
- name: "DevOps Engineer",
45075
- description: "Infrastructure, deployment, and operations",
45892
+ name: "DevOps Deep",
45893
+ description: "Comprehensive infrastructure, deployment, observability, and operations review",
45076
45894
  prompt: modePrompt("devops"),
45077
- tags: ["devops", "infrastructure", "operations"],
45895
+ tags: ["deep", "devops", "infrastructure", "operations"],
45078
45896
  toolPreferences: ["read", "bash", "grep", "logs", "git"],
45079
45897
  suggestedSkills: ["docker-deploy", "observability", "security-scanner"]
45080
45898
  },
45081
45899
  {
45082
45900
  id: "refactorer",
45083
- name: "Refactorer",
45084
- description: "Code improvement and modernization",
45901
+ name: "Refactor Deep",
45902
+ description: "Comprehensive modernization/refactor mode with contracts and verification discipline",
45085
45903
  prompt: modePrompt("refactorer"),
45086
- tags: ["refactor", "modernization", "improvement"],
45904
+ tags: ["deep", "refactor", "modernization", "improvement"],
45087
45905
  toolPreferences: ["read", "edit", "test", "git", "grep"],
45088
45906
  suggestedSkills: ["refactor-planner", "typescript-strict", "node-modern", "testing"]
45089
45907
  },
45090
45908
  {
45091
45909
  id: "ui-design",
45092
- name: "UI Design",
45093
- description: "Design-first frontend & mobile UI work (Design Studio)",
45910
+ name: "UI Design Deep",
45911
+ description: "Comprehensive design-first frontend/mobile UI work with kit, tokens, and accessibility",
45094
45912
  prompt: modePrompt("ui-design"),
45095
- tags: ["ui", "frontend", "mobile", "design"],
45913
+ tags: ["deep", "ui", "frontend", "mobile", "design"],
45096
45914
  toolPreferences: ["design", "write", "edit", "read", "scaffold"],
45097
45915
  suggestedSkills: ["react-modern"]
45098
45916
  },
45099
- {
45100
- id: "brief",
45101
- name: "Brief",
45102
- description: "Fast, no-nonsense \u2014 get to the point",
45103
- prompt: modePrompt("brief"),
45104
- tags: ["fast", "concise", "direct"],
45105
- toolPreferences: ["read", "edit", "bash"],
45106
- suggestedSkills: []
45107
- },
45108
45917
  {
45109
45918
  id: "teach",
45110
- name: "Teach",
45111
- description: "Mentor mode \u2014 explains why, not just what",
45919
+ name: "Teach Deep",
45920
+ description: "Mentor mode with explanations, mental models, trade-offs, and takeaways",
45112
45921
  prompt: modePrompt("teach"),
45113
- tags: ["teaching", "mentor", "learning"],
45922
+ tags: ["deep", "teaching", "mentor", "learning"],
45114
45923
  toolPreferences: ["read", "edit", "explain"],
45115
45924
  suggestedSkills: ["prompt-engineering", "skill-creator", "node-modern", "typescript-strict"]
45116
45925
  },
45117
45926
  {
45118
45927
  id: "research-web",
45119
- name: "Research Web",
45120
- description: "Current-data research \u2014 search web, verify, inject findings into context",
45928
+ name: "Research Deep",
45929
+ description: "Comprehensive current-data research with cross-checking and reusable findings",
45121
45930
  prompt: modePrompt("research-web"),
45122
- tags: ["research", "web", "current-data", "up-to-date"],
45123
- toolPreferences: ["search/fetch", "search/fetch", "search", "fetch", "context_manager"],
45931
+ tags: ["deep", "research", "web", "current-data", "up-to-date"],
45932
+ toolPreferences: ["search", "fetch", "context_manager"],
45124
45933
  suggestedSkills: ["research-web", "tech-stack", "node-modern", "security-scanner", "react-modern"]
45125
45934
  }
45126
45935
  ];
@@ -48019,8 +48828,8 @@ ${body.trim()}`);
48019
48828
  if (!this.persistBackup || scope === "project-agents") return;
48020
48829
  try {
48021
48830
  const content = await this.backend.readAll(scope, this.files[scope]);
48022
- const { writeFile: writeFile21, mkdir: mkdir28 } = await import('fs/promises');
48023
- await mkdir28(this.backupDir, { recursive: true });
48831
+ const { writeFile: writeFile21, mkdir: mkdir29 } = await import('fs/promises');
48832
+ await mkdir29(this.backupDir, { recursive: true });
48024
48833
  await writeFile21(`${this.backupDir}/${scope}.md`, content, "utf8");
48025
48834
  } catch {
48026
48835
  }
@@ -57505,8 +58314,8 @@ var ReportGenerator = class {
57505
58314
  try {
57506
58315
  await stat(this.options.outputDir);
57507
58316
  } catch {
57508
- const { mkdir: mkdir28 } = await import('fs/promises');
57509
- await mkdir28(this.options.outputDir, { recursive: true });
58317
+ const { mkdir: mkdir29 } = await import('fs/promises');
58318
+ await mkdir29(this.options.outputDir, { recursive: true });
57510
58319
  }
57511
58320
  }
57512
58321
  generateMarkdown(result) {
@@ -61368,6 +62177,6 @@ init_utils();
61368
62177
  init_safe_json();
61369
62178
  init_term();
61370
62179
 
61371
- export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, TOOLS as AGENT_TOOL_PRESETS, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, ALL_SYNC_CATEGORIES, AUDIT_LOG_AGENT, AdaptiveConcurrencyController, Agent, AgentError, AgentMonitorService, AgentStatusTracker, AnnotationsStore, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhasePlanner, AutoPhaseRunner, AutonomousBrain, AutonomousCoordinator, AutonomousRunner, BUG_HUNTER_AGENT, BUILD_AGENTS, BUILTIN_PROMPT_CATEGORIES, BrainDecisionQueue, BrainMonitor, BudgetExceededError, BudgetThresholdSignal, CHIMERA_REVIEW_PROMPT, CODEX_MODELS, COMPLETED_WORK_LEDGER_MARKER, CONTEXT_WINDOW_MODES, CORE_RECONSTRUCT_EVENTS, CURRENT_KANBAN_VERSION, ChangeManager, CheckpointManager, CloudSync, CollabSession, CollaborationBus, ConfigError, ConfigMigrationError, ConsensusProtocol, Container, Context, ConversationState, DANGEROUS_FOR_SUBAGENTS, DECISION_TIMEOUT_MS, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_COLUMNS, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_HQ_REDACTION_POLICY, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_QUALITY_CHECKS, DEFAULT_SESSION_LOGGING_CONFIG, DEFAULT_SESSION_PRUNE_DAYS, DEFAULT_SKILLS_SH_URL, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DEFAULT_TOOL_DESCRIPTION_MODE, DEFAULT_TOOL_RESULT_RENDER_MODE, DEFAULT_TUI_THINKING_WORD, DELIVERY_AGENTS, DEPENDENCY_FILE_PATTERNS, DESIGN_STACKS, DISCOVERY_AGENTS, DOMAIN_AGENTS, DefaultAttachmentStore, DefaultBrainArbiter, DefaultConfigLoader, DefaultConfigStore, DefaultDesignKitLoader, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMailbox, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPermissionPolicy, DefaultPluginAPI, DefaultPromptLoader, DefaultPromptStore, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, Director, DirectorAlertLevel, DirectorStateCheckpoint, DoneConditionChecker, ENHANCER_SYSTEM_PROMPT, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FORBIDDEN_PROTO_KEYS, FOREIGN_SKILL_TOOLS, FetchError, FileMemoryBackend, FleetBus, FleetCostCapError, FleetManager, FleetNotifier, FleetSpawnBudgetError, FleetSupervisor, FleetUsageAggregator, FsError, GitignoreUpdater, GlobalMailbox, GraphMemoryBackend, HEAVY_BUDGET, HQ_AUTH_FILE_VERSION, HQ_COMMAND_TYPES, HQ_PROTOCOL_VERSION, HookRegistry, HookRunner, HqAlertEngine, HqCommandAuditLog, HqEventLog, HqPublisher, HqSnapshotStore, HqTimeseriesStore, HumanEscalatingBrainArbiter, HybridCompactor, INPUT_HISTORY_DEFAULT_MAX, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, InputHistoryStore, IntelligentCompactor, KERNEL_API_VERSION, KNOWLEDGE_AGENTS, KnowledgeGraph, LAYER_1_IDENTITY, LIGHT_BUDGET, LLMSelector, LargeAnswerStore, MAILBOX_BRIDGE_LOCK_FILENAME, MAILBOX_BRIDGE_TOKEN_FILENAME, MAILBOX_HEALTH_DEFAULT_FAILURE_THRESHOLD, MAILBOX_HEALTH_DEFAULT_FROM, MAILBOX_HEALTH_DEFAULT_INTERVAL_MS, MAILBOX_HEALTH_DEFAULT_TIMEOUT_MS, MALFORMED_ARG_MARKERS, MATRIX_PHASE_KEYS, MAX_JOURNAL_ENTRIES, MAX_PROGRESS_HISTORY, MAX_TUI_THINKING_WORD_LENGTH, MEDIUM_BUDGET, MEMORY_TYPE_LABELS, META_AGENTS, MailboxHealthWatchdog, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, ObservableBrainArbiter, PHASE_EVENT_NAMES, PLANNING_AGENTS, PROMETHEUS_CONTENT_TYPE, PROMPT_CATEGORY_LABELS, ParallelEternalEngine, ParseError, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, PromptInstaller, PromptManifestStore, PromptUsageStore, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, REVIEW_AGENTS, RecoveryLock, ReplayLogStore, ReplayProviderRunner, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SKILL_LIMITS, SPEC_TEMPLATES, STANDARD_AUDIT_EVENTS, ScopedEventBus, SddBoardProjector, SddBoardStore, SddError, SddInterviewDriver, SddParallelRun, SddRunRegistry, SddSupervisor, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SessionMemoryConsolidator, SessionRecovery, SessionRegistry, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, StreamHangError, SubagentBudget, TIMEOUT_PREEMPT_FRACTION, TOKENS, TaskAuctioneer, TaskDAG, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolAuditLog, ToolCapabilities, ToolError, ToolErrorCategory, ToolExecutor, ToolRegistry, ToolValidationError, VERIFY_AGENTS, WIDE_SUBAGENT_CAPABILITIES, WorktreeIntegrationError, WorktreeManager, WrongStackError, _resetDesignKitLoaderMemo, _resetDesignRulesCache, acquireOrJoin, actionToAckInput, activateDesign, addCheckToTask, addColumn, addDependency, addGoalMetricToTask, addLinkToTask, addNoteToTask, addPlanItem, addTask, allServers, analyzeCriticalPath, appendJournal, applyModelRuntime, applyRosterBudget, applySddLifecycle, applyTokenOverrides, applyToolDescriptionModeToTool, applyToolDescriptionModes, applyToolResultRenderModes, areDependenciesMet, assertNever, assertNotPrivateHost, assertSafePath, assertValidBoardId, assessCommitSafety, assignNickname, assignTask, atomicWrite, attachAutoExtend, attachDepWatcherBridge, attachMailboxChecker, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, boardMeta, bodyLineAdvisory, bootConfig, braveSearchServer, buildBoardSnapshot, buildBoardTasks, buildBtwBlock, buildChildEnv, buildContextEvidenceDigest, buildDownAlert, buildGoalPreamble, buildLosslessDigest, buildMailboxBlock, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildQueuedMessagesBlock, buildRecoveryAlert, buildSmartDigest, buildTaskGraphFromKanbanBoard, buildTranscriptFromEvents, claimReadyTask, classifyFamily, cleanupSddWorktrees, cleanupStaleSddWorktrees, clearActiveKit, clearPersistedActiveKit, clearPlan, codexModelMeta, collabInjectMiddleware, collabPauseMiddleware, color, colorToHex, compactLog, compactSchemaDescriptions, compactToolDefinitionForWire, compileGlob, compileUserRegex, completePartialObject, composeDirectorPrompt, composeSubagentPrompt, computeMessageTokens, computeTaskItemProgress, computeTaskProgress, consumeBtwNotes, consumeQueuedMessagesUpdate, context7Server, contextManagerTool, copyTaskToBoard, countShellHooks, createAgentMonitorService, createAutoExecutor, createAutoPhaseFromTaskGraph, createAutonomyBrain, createBoard, createBoardFromTaskGraph, createBoardObject, createBoardsFromPhaseGraph, createChimeraPlugin, createContextEvidenceState, createContextManagerTool, createDefaultPipelines, createDelegateTool, createFallbackModelExtension, createGitPlugin, createGlobalMailbox, createHqEventEnvelope, createHqPersistence, createHqPublisherFromEnv, createMailboxChecker, createMailboxEventPayload, createMailboxHooks, createMailboxSnapshotPayload, createMailboxSnapshotPayloadFromMailbox, createMcpControlTool, createMcpUseTool, createMessage, createObservabilityPlugin, createPlanPlugin, createPromptsPlugin, createSecurityPlugin, createSecuritySlashCommand, createSessionEventBridge, createSkillsPlugin, createSkillsShAdapter, createStrategyCompactor, createSyncPlugin, createTieredBrainArbiter, createToolOutputSerializer, decryptConfigSecrets, deepMerge, defaultGitignoreUpdater, defaultHqDataDir, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, definePlugin, deleteBoard, deriveTodosFromPlanItem, describeCatalogModel, deserializeTaskGraph, designProjectDir, destroySddProject, detectEcosystem, detectFrontendFile, detectFrontendIntent, detectNewlineStyle, detectEcosystem as detectPackageEcosystem, diffRegistry, discoverLocalHqEndpoint, dispatchAgent, downloadGitHubTarball, duplicateBoard, effectiveFallbackChain, eliseOldToolResults, emptyGoal, emptyHqAuthFile, emptyPlan, emptyTaskFile, encryptConfigSecrets, encryptedPrefixForVersion, enhanceUserPrompt, ensureDir, ensureHqFirstRunAuthFile, escapeGlobSubject, estimateMessageTokens, estimateMessages, estimateRequestTokens, estimateRequestTokensCalibrated, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, expandGlob, expandIPv6, expectDefined, exportBoardAsMarkdown, exportBoardToTaskGraph, extractRunEnv, extractSkillFromPrompt, extractText, extractVerificationCommand, fallbackProfileChain, filesystemServer, finalize, findBlockedTasks, findCriticalPath, findPreserveStart, flagsToConfigPatch, formatCompletedWorkLedger, formatContextWindowModeList, formatDecisionSummary, formatGoal, formatHumanPrompt, formatModelRef, formatPlan, formatPlanTemplates, formatTaskList, formatTaskProgress, formatTodosList, gatedEnhancerReasoning, generateBoardFromDescription, generateSessionId, generateSkillSkeleton, getAgentDefinition, getBoard, getCalibrationState, getContextWindowMode, getDangerousCapabilities, getDesignKitLoader, getDesignState, getFileHistory, getFilesByAgent, getFullLog, getFullPackageLog, getJsonPath, getKanbanDir, getKanbanOrchestrationSnapshot, getKanbanPath, getLastAuthor, getManifestPackages, getPackageAuthor, getPackagesByAgent, getPlanTemplate, getSessionRegistry, getTask, getTaskChain, getTemplate, getTermSize, getToolDescriptionMode, getToolResultRenderMode, githubDirectAdapter, githubServer, goalFilePath, googleMapsServer, hasCapability, hasConflictMarkers, hasDangerousCapabilityForSubagents, hasOpenTodos, hasSessionRegistry, hasTextContent, hashRequest, hookMatcherMatches, hqAuthFilePath, hqRuntimeFilePath, injectPendingMailboxMessages, installDesignStudioMiddleware, isAgentError, isBuiltinCategory, isColorToken, isConfigError, isContextWindowModeId, isDesignStack, isExplanatoryText, isFetchError, isFsError, isImageBlock, isInteractive, isJsonObject, isParseError, isPathSubjectKey, isPluginError, isPrimitiveArray, isPrivateIPv4, isPrivateIPv6, isSddError, isSessionError, isStdinTTY, isStdoutTTY, isTextBlock, isToolError, isToolResultBlock, isToolUseBlock, isToolValidationError, isUlid, isValidBoardId, isValidMatrixKey, isValidSkillNameFormat, isWrongStackError, jsonObjectFileExists, listBoardIds, listBoardSummaries, listBoards, listContextWindowModes, listPlanTemplates, listReadyTasks, listTemplates, loadActiveKit, loadCompletedWorkCheckpoint, loadDirectorState, loadGoal, loadInstructionBundle, loadPlan, loadPlugins, loadProjectDesignRules, loadProjectModes, loadTasks, loadTodosCheckpoint, loadUserModes, mailboxSessionTag, makeAgentSubagentRunner, makeAskResultTool, makeAskTool, makeAssignTool, makeAutonomyPromptContributor, makeAwaitTasksTool, makeCollabDebugTool, makeCommandVerifier, makeContinueToNextIterationTool, makeDependencyWatcherConfig, makeDesignDetectToolCallMiddleware, makeDesignDetectUserInputMiddleware, makeDesignStudioRequestMiddleware, makeDesignVerifyToolCallMiddleware, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetTool as makeFleetHealthTool, makeFleetTool as makeFleetSessionTool, makeFleetStatusTool, makeFleetTool, makeFleetTool as makeFleetUsageTool, makeKanbanQueueTool, makeLLMClassifier, makeLlmConflictResolver, makeLlmSubtaskGenerator, makeMailInboxTool, makeMailSendTool, makeMailboxTool, makePreferSideConflictResolver, makeQualityGateTool, makeRollUpTool, makeSpawnTool, makeTerminateAllTool, makeTerminateTool, makeWorkCompleteTool, mapMailboxAgentToHqSummary, mapMailboxMessageToHqSummary, mapSessionEventToEntries, markAssistantReferencedEvidence, matchAny, matchGlob, materializeTokens, matrixKeyKind, mergeCustomModelDefs, mergeInstructionBundle, mergeModelRuntime, mergeModelsPayload, mergeTasks, mergeToolResults, migratePlaintextSecrets, migratePromptEntry, miniMaxVisionServer, mintHqBrowserToken, mintHqToken, moveTask, mutateBoard, mutateHqAuthFile, mutatePlan, mutateTasks, nicknameKeyFromDisplay, noOpVault, normalizeModelRef, normalizePathSubject, normalizeRecipient, normalizeToLf, normalizeTokenSavingTier, normalizeToolDescriptionMode, normalizeToolResultRenderMode, normalizeTuiThinkingWord, normalizedEqual, oklchToHex, onResize, openInEditor, parseContinueDirective, parseEncryptedVersion, parseEntries, parseHqEventPayload, parseHqFrame, parseLinesIntoTasks, parseModelRef, parseOklch, parseProgressFromText, parseSkillFrontmatter, parseSkillRef, peekQueuedMessages, pendingBtwCount, phaseForRole, playwrightServer, projectHash, projectSlug, promptChecksum, readBoard, readBundledInstructionText, readHqAuthFile, readHqRuntimeFileSync, readJsonObjectFile, readLiveLock, recentTextTurns, recordActualUsage, recordCompletedWorkEvidence, recordFileAction, recordKitChoice, recordOverrides, recordPackageAction, recordProgress, recordToolOutputEvidence, recordUserIntentEvidence, redactHqEvent, redactHqValue, release, releaseTaskClaim, removeBoard, removeColumn, removeJsonPath, removeJsonPathInFile, removePlanItem, removeTask, renderInstructionTemplate, renderProgress, renderPrometheus, renderPrompt, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, repeatedReadPressure, resetCalibration, resolveAuditLevel, resolveBoardRef, resolveBundledDesignKitsDir, resolveCacheForRequest, resolveChimeraConfig, resolveConflictText, resolveContextWindowPolicy, resolveForeignToolIds, resolveForeignToolIdsWithWarnings, resolveHqConfig, resolveHqConfigFromEnv, resolveHqDataDir, resolveImplementationModelTarget, resolveMailboxIdentity, resolveModelMatrix, resolveModelMatrixResolution, resolveModelRuntime, resolveModelTargetFromEntry, resolveProjectDir, resolveProviderModelList, resolveReasoningForRequest, resolveSessionLoggingConfig, resolveSubagentModelTarget, resolveSubagentWorktreeDecision, resolveToolDescriptionMode, resolveToolResultRenderMode, resolveWstackPaths, rewriteConfigEncrypted, roleNeedsIndependentReviewModel, rollbackSddRunFromDisk, rosterSummaryFromConfigs, runConfigMigrations, runDesignVerify, runProviderWithRetry, runShellHook, safeParse, safeStringify, sameModelReference, sanitizeJsonString, sanitizeModel, sanitizeNodeOptions, saveCompletedWorkCheckpoint, saveGoal, savePlan, saveTasks, saveTodosCheckpoint, scoreAgents, scoreMessage, scrubAndTruncateHqPreview, searchKanban, securityScoreToTier, securitySlashCommand, sentinelServer, serializeTaskGraph, sessionScopedPath, setActiveKit, setBtwNote, setDesignOverrides, setJsonPath, setJsonPathInFile, setOutputLineGuard, setPlanItemStatus, setProgress, setQueuedMessagesSnapshot, setRawMode, setTaskChain, setToolDescriptionMode, setToolResultRenderMode, shellHooksEqual, shortIdMap, shouldEnhance, simplifyToolDescription, slackServer, sleep, slugify, smartDefaultFallbackChain, splitTask, sshManagerServer, stableStringify, startAgentMonitorEventBridge, startBrainTelemetryBridge, startCostTelemetryBridge, startFleetTelemetryBridge, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, startPackageOutdatedWatcher, startSddRun, startSessionTelemetryBridge, startTechStackConsumer, startToolTelemetryBridge, startWorktreeTelemetryBridge, stripAnsi, stripFrontmatter3 as stripFrontmatter, subagentNeedsWorktree, subjectForToolInput, summarizeBoard, summarizeHqToolArgs, summarizeUsage, syncBoardFromTaskGraph, syncCompletedWorkLedgerBlock, templateToMarkdown, toAlertMessage, toErrorMessage, toStyle, toWrongStackError, tokenHasCapability, topologicalSort, transferTaskToBoard, truncate, ulid, unifiedDiff, unloadPlugins, updateBoard, updateCheckOnTask, updateColumn, updateGoalMetricOnTask, updateJsonObjectFile, updatePackageOutdatedStatus, updateTask, updateTaskAssignment, validateAgainstSchema, validateHqCommand, validateRegistryManifest, validateSkillName, validateSkillNameAvailable, validateWatchdogOptions, verifyFiles, watchHqAuthFile, watchProviderConfig, wireMetricsToEvents, withDisabledToolFiltering, withFileLock, wrapAsState, wrapSubagentRunnerWithWorktrees, writeBoard, writeErr, writeHqAuthFile, writeHqRuntimeFile, writeJsonObjectFile, writeOut, writeSkeletonSkill, wstackGlobalRoot, zaiVisionServer };
62180
+ export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, TOOLS as AGENT_TOOL_PRESETS, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, ALL_SYNC_CATEGORIES, AUDIT_LOG_AGENT, AdaptiveConcurrencyController, Agent, AgentError, AgentMonitorService, AgentStatusTracker, AnnotationsStore, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhasePlanner, AutoPhaseRunner, AutonomousBrain, AutonomousCoordinator, AutonomousRunner, BUG_HUNTER_AGENT, BUILD_AGENTS, BUILTIN_PROMPT_CATEGORIES, BrainDecisionQueue, BrainMonitor, BudgetExceededError, BudgetThresholdSignal, CHIMERA_REVIEW_PROMPT, CODEX_MODELS, COMPLETED_WORK_LEDGER_MARKER, CONTEXT_WINDOW_MODES, CORE_RECONSTRUCT_EVENTS, CURRENT_KANBAN_VERSION, ChangeManager, CheckpointManager, CloudSync, CollabSession, CollaborationBus, ConfigError, ConfigMigrationError, ConsensusProtocol, Container, Context, ConversationState, DANGEROUS_FOR_SUBAGENTS, DECISION_TIMEOUT_MS, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_COLUMNS, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_HQ_REDACTION_POLICY, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_QUALITY_CHECKS, DEFAULT_SESSION_LOGGING_CONFIG, DEFAULT_SESSION_PRUNE_DAYS, DEFAULT_SKILLS_SH_URL, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DEFAULT_TOOL_DESCRIPTION_MODE, DEFAULT_TOOL_RESULT_RENDER_MODE, DEFAULT_TUI_THINKING_WORD, DELIVERY_AGENTS, DEPENDENCY_FILE_PATTERNS, DESIGN_STACKS, DISCOVERY_AGENTS, DOMAIN_AGENTS, DefaultAttachmentStore, DefaultBrainArbiter, DefaultConfigLoader, DefaultConfigStore, DefaultDesignKitLoader, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMailbox, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPermissionPolicy, DefaultPluginAPI, DefaultPromptLoader, DefaultPromptStore, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, Director, DirectorAlertLevel, DirectorStateCheckpoint, DoneConditionChecker, ENHANCER_SYSTEM_PROMPT, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FORBIDDEN_PROTO_KEYS, FOREIGN_SKILL_TOOLS, FetchError, FileMemoryBackend, FleetBus, FleetCostCapError, FleetManager, FleetNotifier, FleetSpawnBudgetError, FleetSupervisor, FleetUsageAggregator, FsError, GitignoreUpdater, GlobalMailbox, GraphMemoryBackend, HEAVY_BUDGET, HQ_AUTH_FILE_VERSION, HQ_COMMAND_TYPES, HQ_PROTOCOL_VERSION, HookRegistry, HookRunner, HqAlertEngine, HqCommandAuditLog, HqEventLog, HqPublisher, HqSnapshotStore, HqTimeseriesStore, HumanEscalatingBrainArbiter, HybridCompactor, INPUT_HISTORY_DEFAULT_MAX, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, InputHistoryStore, IntelligentCompactor, KERNEL_API_VERSION, KNOWLEDGE_AGENTS, KnowledgeGraph, LAYER_1_IDENTITY, LIGHT_BUDGET, LLMSelector, LargeAnswerStore, MAILBOX_BRIDGE_LOCK_FILENAME, MAILBOX_BRIDGE_TOKEN_FILENAME, MAILBOX_HEALTH_DEFAULT_FAILURE_THRESHOLD, MAILBOX_HEALTH_DEFAULT_FROM, MAILBOX_HEALTH_DEFAULT_INTERVAL_MS, MAILBOX_HEALTH_DEFAULT_TIMEOUT_MS, MALFORMED_ARG_MARKERS, MATRIX_PHASE_KEYS, MAX_JOURNAL_ENTRIES, MAX_PROGRESS_HISTORY, MAX_TUI_THINKING_WORD_LENGTH, MEDIUM_BUDGET, MEMORY_TYPE_LABELS, META_AGENTS, MailboxHealthWatchdog, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, ObservableBrainArbiter, PHASE_EVENT_NAMES, PLANNING_AGENTS, PROMETHEUS_CONTENT_TYPE, PROMPT_CATEGORY_LABELS, ParallelEternalEngine, ParseError, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, PromptInstaller, PromptManifestStore, PromptUsageStore, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, REVIEW_AGENTS, RecoveryLock, ReplayLogStore, ReplayProviderRunner, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SKILL_LIMITS, SPEC_TEMPLATES, STANDARD_AUDIT_EVENTS, ScopedEventBus, SddBoardProjector, SddBoardStore, SddError, SddInterviewDriver, SddParallelRun, SddRunRegistry, SddSupervisor, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SessionMemoryConsolidator, SessionRecovery, SessionRegistry, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, StreamHangError, SubagentBudget, TIMEOUT_PREEMPT_FRACTION, TOKENS, TaskAuctioneer, TaskDAG, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolAuditLog, ToolCapabilities, ToolError, ToolErrorCategory, ToolExecutor, ToolRegistry, ToolValidationError, VERIFY_AGENTS, WIDE_SUBAGENT_CAPABILITIES, WorktreeIntegrationError, WorktreeManager, WrongStackError, _resetDesignKitLoaderMemo, _resetDesignRulesCache, acquireOrJoin, actionToAckInput, activateDesign, addCheckToTask, addColumn, addDependency, addGoalMetricToTask, addLinkToTask, addNoteToTask, addPlanItem, addTask, allServers, analyzeCriticalPath, appendJournal, appendKanbanEvent, applyModelRuntime, applyRosterBudget, applySddLifecycle, applyTokenOverrides, applyToolDescriptionModeToTool, applyToolDescriptionModes, applyToolResultRenderModes, areDependenciesMet, assertNever, assertNotPrivateHost, assertSafePath, assertValidBoardId, assessCommitSafety, assignNickname, assignTask, atomicWrite, attachAutoExtend, attachDepWatcherBridge, attachMailboxChecker, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, boardMeta, bodyLineAdvisory, bootConfig, braveSearchServer, buildBoardSnapshot, buildBoardTasks, buildBtwBlock, buildChildEnv, buildContextEvidenceDigest, buildDownAlert, buildGoalPreamble, buildLosslessDigest, buildMailboxBlock, buildMailboxBtwAwarenessBlock, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildQueuedMessagesBlock, buildRecoveryAlert, buildSmartDigest, buildTaskGraphFromKanbanBoard, buildTranscriptFromEvents, claimReadyTask, classifyFamily, cleanupSddWorktrees, cleanupStaleSddWorktrees, clearActiveKit, clearPersistedActiveKit, clearPlan, codexModelMeta, collabInjectMiddleware, collabPauseMiddleware, color, colorToHex, compactLog, compactSchemaDescriptions, compactToolDefinitionForWire, compileGlob, compileUserRegex, completePartialObject, composeDirectorPrompt, composeSubagentPrompt, computeMessageTokens, computeTaskItemProgress, computeTaskProgress, consumeBtwNotes, consumeQueuedMessagesUpdate, context7Server, contextManagerTool, copyTaskToBoard, countShellHooks, createAgentMonitorService, createAutoExecutor, createAutoPhaseFromTaskGraph, createAutonomyBrain, createBoard, createBoardFromTaskGraph, createBoardObject, createBoardsFromPhaseGraph, createChimeraPlugin, createContextEvidenceState, createContextManagerTool, createDefaultPipelines, createDelegateTool, createFallbackModelExtension, createGitPlugin, createGlobalMailbox, createHqEventEnvelope, createHqPersistence, createHqPublisherFromEnv, createMailboxChecker, createMailboxEventPayload, createMailboxHooks, createMailboxSnapshotPayload, createMailboxSnapshotPayloadFromMailbox, createMcpControlTool, createMcpUseTool, createMessage, createObservabilityPlugin, createPlanPlugin, createPromptsPlugin, createSecurityPlugin, createSecuritySlashCommand, createSessionEventBridge, createSkillsPlugin, createSkillsShAdapter, createStrategyCompactor, createSyncPlugin, createTieredBrainArbiter, createToolOutputSerializer, decryptConfigSecrets, deepMerge, defaultGitignoreUpdater, defaultHqDataDir, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, definePlugin, deleteBoard, deriveTodosFromPlanItem, describeCatalogModel, deserializeTaskGraph, designProjectDir, destroySddProject, detectContinueIntent, detectEcosystem, detectFrontendFile, detectFrontendIntent, detectNewlineStyle, detectEcosystem as detectPackageEcosystem, diffRegistry, discoverLocalHqEndpoint, dispatchAgent, downloadGitHubTarball, duplicateBoard, effectiveFallbackChain, eliseOldToolResults, emptyGoal, emptyHqAuthFile, emptyPlan, emptyTaskFile, encryptConfigSecrets, encryptedPrefixForVersion, enhanceUserPrompt, ensureDir, ensureHqFirstRunAuthFile, escapeGlobSubject, estimateMessageTokens, estimateMessages, estimateRequestTokens, estimateRequestTokensCalibrated, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, expandGlob, expandIPv6, expectDefined, exportBoardAsMarkdown, exportBoardToTaskGraph, extractRunEnv, extractSkillFromPrompt, extractText, extractVerificationCommand, fallbackProfileChain, filesystemServer, finalize, findBlockedTasks, findCriticalPath, findPreserveStart, flagsToConfigPatch, formatCompletedWorkLedger, formatContextWindowModeList, formatDecisionSummary, formatGoal, formatHumanPrompt, formatModelRef, formatPlan, formatPlanTemplates, formatTaskList, formatTaskProgress, formatTodosList, gatedEnhancerReasoning, generateBoardFromDescription, generateSessionId, generateSkillSkeleton, getAgentDefinition, getBoard, getCalibrationState, getContextWindowMode, getDangerousCapabilities, getDesignKitLoader, getDesignState, getFileHistory, getFilesByAgent, getFullLog, getFullPackageLog, getJsonPath, getKanbanDir, getKanbanEventsPath, getKanbanOrchestrationSnapshot, getKanbanPath, getKanbanQueueHealth, getLastAuthor, getManifestPackages, getPackageAuthor, getPackagesByAgent, getPlanTemplate, getSessionRegistry, getTask, getTaskChain, getTemplate, getTermSize, getToolDescriptionMode, getToolResultRenderMode, githubDirectAdapter, githubServer, goalFilePath, googleMapsServer, hasCapability, hasConflictMarkers, hasDangerousCapabilityForSubagents, hasOpenTodos, hasSessionRegistry, hasTextContent, hashRequest, heartbeatTaskAssignment, hookMatcherMatches, hqAuthFilePath, hqRuntimeFilePath, injectPendingMailboxMessages, installDesignStudioMiddleware, isAgentError, isBuiltinCategory, isColorToken, isConfigError, isContextWindowModeId, isDesignStack, isExplanatoryText, isFetchError, isFsError, isImageBlock, isInteractive, isJsonObject, isParseError, isPathSubjectKey, isPluginError, isPrimitiveArray, isPrivateIPv4, isPrivateIPv6, isSddError, isSessionError, isStdinTTY, isStdoutTTY, isTextBlock, isToolError, isToolResultBlock, isToolUseBlock, isToolValidationError, isUlid, isValidBoardId, isValidMatrixKey, isValidSkillNameFormat, isWrongStackError, jsonObjectFileExists, listBoardIds, listBoardSummaries, listBoards, listContextWindowModes, listKanbanEvents, listPlanTemplates, listReadyTasks, listTemplates, loadActiveKit, loadCompletedWorkCheckpoint, loadDirectorState, loadGoal, loadInstructionBundle, loadPlan, loadPlugins, loadProjectDesignRules, loadProjectModes, loadTasks, loadTodosCheckpoint, loadUserModes, mailboxSessionTag, makeAgentSubagentRunner, makeAskResultTool, makeAskTool, makeAssignTool, makeAutonomyPromptContributor, makeAwaitTasksTool, makeCollabDebugTool, makeCommandVerifier, makeContinueToNextIterationTool, makeDependencyWatcherConfig, makeDesignDetectToolCallMiddleware, makeDesignDetectUserInputMiddleware, makeDesignStudioRequestMiddleware, makeDesignVerifyToolCallMiddleware, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetTool as makeFleetHealthTool, makeFleetTool as makeFleetSessionTool, makeFleetStatusTool, makeFleetTool, makeFleetTool as makeFleetUsageTool, makeKanbanQueueTool, makeLLMClassifier, makeLlmConflictResolver, makeLlmSubtaskGenerator, makeMailInboxTool, makeMailSendTool, makeMailboxTool, makePreferSideConflictResolver, makeQualityGateTool, makeRollUpTool, makeSpawnTool, makeTerminateAllTool, makeTerminateTool, makeWorkCompleteTool, mapMailboxAgentToHqSummary, mapMailboxMessageToHqSummary, mapSessionEventToEntries, markAssistantReferencedEvidence, matchAny, matchGlob, materializeTokens, matrixKeyKind, mergeCustomModelDefs, mergeInstructionBundle, mergeModelRuntime, mergeModelsPayload, mergeTasks, mergeToolResults, migratePlaintextSecrets, migratePromptEntry, miniMaxVisionServer, mintHqBrowserToken, mintHqToken, moveTask, mutateBoard, mutateHqAuthFile, mutatePlan, mutateTasks, nicknameKeyFromDisplay, noOpVault, normalizeModelRef, normalizePathSubject, normalizeRecipient, normalizeToLf, normalizeTokenSavingTier, normalizeToolDescriptionMode, normalizeToolResultRenderMode, normalizeTuiThinkingWord, normalizedEqual, oklchToHex, onResize, openInEditor, parseContinueDirective, parseEncryptedVersion, parseEntries, parseHqEventPayload, parseHqFrame, parseLinesIntoTasks, parseModelRef, parseOklch, parseProgressFromText, parseSkillFrontmatter, parseSkillRef, peekQueuedMessages, pendingBtwCount, phaseForRole, playwrightServer, projectHash, projectSlug, promptChecksum, readBoard, readBundledInstructionText, readHqAuthFile, readHqRuntimeFileSync, readJsonObjectFile, readKanbanEvents, readLiveLock, recentTextTurns, recordActualUsage, recordCompletedWorkEvidence, recordFileAction, recordKitChoice, recordOverrides, recordPackageAction, recordProgress, recordToolOutputEvidence, recordUserIntentEvidence, recoverStaleTaskAssignments, redactHqEvent, redactHqValue, release, releaseTaskClaim, removeBoard, removeColumn, removeJsonPath, removeJsonPathInFile, removePlanItem, removeTask, renderInstructionTemplate, renderProgress, renderPrometheus, renderPrompt, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, repeatedReadPressure, resetCalibration, resolveAuditLevel, resolveBoardRef, resolveBundledDesignKitsDir, resolveCacheForRequest, resolveChimeraConfig, resolveConflictText, resolveContextWindowPolicy, resolveContinuation, resolveForeignToolIds, resolveForeignToolIdsWithWarnings, resolveHqConfig, resolveHqConfigFromEnv, resolveHqDataDir, resolveImplementationModelTarget, resolveMailboxIdentity, resolveModelMatrix, resolveModelMatrixResolution, resolveModelRuntime, resolveModelTargetFromEntry, resolveProjectDir, resolveProviderModelList, resolveReasoningForRequest, resolveSessionLoggingConfig, resolveSubagentModelTarget, resolveSubagentWorktreeDecision, resolveToolDescriptionMode, resolveToolResultRenderMode, resolveWstackPaths, rewriteConfigEncrypted, roleNeedsIndependentReviewModel, rollbackSddRunFromDisk, rosterSummaryFromConfigs, runConfigMigrations, runDesignVerify, runProviderWithRetry, runShellHook, safeParse, safeStringify, sameModelReference, sanitizeJsonString, sanitizeModel, sanitizeNodeOptions, saveCompletedWorkCheckpoint, saveGoal, savePlan, saveTasks, saveTodosCheckpoint, scoreAgents, scoreMessage, scrubAndTruncateHqPreview, searchKanban, securityScoreToTier, securitySlashCommand, sentinelServer, serializeTaskGraph, sessionScopedPath, setActiveKit, setBtwNote, setDesignOverrides, setJsonPath, setJsonPathInFile, setOutputLineGuard, setPlanItemStatus, setProgress, setQueuedMessagesSnapshot, setRawMode, setTaskChain, setToolDescriptionMode, setToolResultRenderMode, shellHooksEqual, shortIdMap, shouldEnhance, simplifyToolDescription, slackServer, sleep, slugify, smartDefaultFallbackChain, splitTask, sshManagerServer, stableStringify, startAgentMonitorEventBridge, startBrainTelemetryBridge, startCostTelemetryBridge, startFleetTelemetryBridge, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, startPackageOutdatedWatcher, startSddRun, startSessionTelemetryBridge, startTechStackConsumer, startToolTelemetryBridge, startWorktreeTelemetryBridge, stripAnsi, stripFrontmatter3 as stripFrontmatter, subagentNeedsWorktree, subjectForToolInput, summarizeBoard, summarizeHqToolArgs, summarizeUsage, syncBoardFromTaskGraph, syncCompletedWorkLedgerBlock, templateToMarkdown, toAlertMessage, toErrorMessage, toStyle, toWrongStackError, tokenHasCapability, topologicalSort, transferTaskToBoard, truncate, ulid, unifiedDiff, unloadPlugins, updateBoard, updateCheckOnTask, updateColumn, updateGoalMetricOnTask, updateJsonObjectFile, updatePackageOutdatedStatus, updateTask, updateTaskAssignment, validateAgainstSchema, validateHqCommand, validateRegistryManifest, validateSkillName, validateSkillNameAvailable, validateWatchdogOptions, verifyFiles, watchHqAuthFile, watchProviderConfig, wireMetricsToEvents, withDisabledToolFiltering, withFileLock, wrapAsState, wrapSubagentRunnerWithWorktrees, writeBoard, writeErr, writeHqAuthFile, writeHqRuntimeFile, writeJsonObjectFile, writeOut, writeSkeletonSkill, wstackGlobalRoot, zaiVisionServer };
61372
62181
  //# sourceMappingURL=index.js.map
61373
62182
  //# sourceMappingURL=index.js.map