kantban-cli 0.1.38 → 0.1.39

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.
@@ -12,7 +12,7 @@ import {
12
12
  generateMcpConfig,
13
13
  parseJsonFromLlmOutput,
14
14
  parseStuckDetectionResponse
15
- } from "./chunk-2CY5OPZN.js";
15
+ } from "./chunk-JGAOKTRU.js";
16
16
  import {
17
17
  LoopCheckpointSchema,
18
18
  VerdictSchema,
@@ -486,6 +486,8 @@ var PipelineOrchestrator = class {
486
486
  spawning = /* @__PURE__ */ new Set();
487
487
  /** Ticket IDs currently in onLoopComplete (prevents double-spawn during async advisor recovery) */
488
488
  completing = /* @__PURE__ */ new Set();
489
+ /** Ticket IDs aborted due to ticket:moved — suppresses onLoopComplete comment/advisor */
490
+ abortedForMove = /* @__PURE__ */ new Set();
489
491
  /** Per-column reservation count for in-flight spawns (prevents concurrency overshoot) */
490
492
  columnReservations = /* @__PURE__ */ new Map();
491
493
  /** Cached board scope for constraint evaluation — refreshed each scan cycle */
@@ -924,6 +926,26 @@ var PipelineOrchestrator = class {
924
926
  switch (event.type) {
925
927
  case "ticket:moved":
926
928
  case "ticket:created": {
929
+ if (event.type === "ticket:moved" && event.fromColumnId) {
930
+ const oldLoop = this.activeLoops.get(event.ticketId);
931
+ if (oldLoop) {
932
+ oldLoop.abort.abort();
933
+ this.activeLoops.delete(event.ticketId);
934
+ this.abortedForMove.add(event.ticketId);
935
+ }
936
+ this.knownTickets.delete(event.ticketId);
937
+ this.spawning.delete(event.ticketId);
938
+ this.deferredTickets.delete(event.ticketId);
939
+ const oldQueue = this.loopQueues.get(event.fromColumnId);
940
+ if (oldQueue) {
941
+ const idx = oldQueue.indexOf(event.ticketId);
942
+ if (idx !== -1) oldQueue.splice(idx, 1);
943
+ }
944
+ void this.drainQueue(event.fromColumnId).catch((err) => {
945
+ const msg = err instanceof Error ? err.message : String(err);
946
+ console.error(` [error] drainQueue failed for old column ${event.fromColumnId}: ${msg}`);
947
+ });
948
+ }
927
949
  if (event.columnId && this.pipelineColumns.has(event.columnId)) {
928
950
  if (this.isColumnBlocked(event.columnId)) {
929
951
  console.error(` [event] ${event.type} ${event.ticketId} \u2192 column ${event.columnId}: BLOCKED by firing constraints \u2014 deferred`);
@@ -1113,7 +1135,8 @@ var PipelineOrchestrator = class {
1113
1135
  lastError: err instanceof Error ? err.message : String(err)
1114
1136
  })
1115
1137
  );
1116
- this.activeLoops.set(ticketId, { columnId, promise });
1138
+ const abort = new AbortController();
1139
+ this.activeLoops.set(ticketId, { columnId, promise, abort });
1117
1140
  this.lastFiredAt.set(columnId, /* @__PURE__ */ new Date());
1118
1141
  void promise.then(
1119
1142
  (result) => this.onLoopComplete(ticketId, columnId, result).catch((err) => {
@@ -1138,7 +1161,8 @@ var PipelineOrchestrator = class {
1138
1161
  });
1139
1162
  placeholder.catch(() => {
1140
1163
  });
1141
- this.activeLoops.set(ticketId, { columnId, promise: placeholder });
1164
+ const abort = new AbortController();
1165
+ this.activeLoops.set(ticketId, { columnId, promise: placeholder, abort });
1142
1166
  this.lastFiredAt.set(columnId, /* @__PURE__ */ new Date());
1143
1167
  void readCheckpoint(
1144
1168
  {
@@ -1150,6 +1174,7 @@ var PipelineOrchestrator = class {
1150
1174
  columnId
1151
1175
  ).then((checkpoint) => {
1152
1176
  clearTimeout(timeoutId);
1177
+ if (!this.activeLoops.has(ticketId)) return;
1153
1178
  if (checkpoint) {
1154
1179
  console.error(` [checkpoint] Resuming ${ticketId} at iteration ${String(checkpoint.iteration + 1)} (model: ${checkpoint.model_tier})`);
1155
1180
  this.startLoopWithConfig(ticketId, columnId, config, checkpoint.iteration + 1, checkpoint.gutter_count, modelOverride ?? checkpoint.model_tier, checkpoint.last_fingerprint);
@@ -1158,6 +1183,7 @@ var PipelineOrchestrator = class {
1158
1183
  }
1159
1184
  }).catch((err) => {
1160
1185
  clearTimeout(timeoutId);
1186
+ if (!this.activeLoops.has(ticketId)) return;
1161
1187
  const msg = err instanceof Error ? err.message : String(err);
1162
1188
  console.error(` [warn] Checkpoint read failed for ${ticketId} (starting fresh): ${msg}`);
1163
1189
  this.startLoopWithConfig(ticketId, columnId, config, void 0, void 0, modelOverride);
@@ -1200,8 +1226,10 @@ var PipelineOrchestrator = class {
1200
1226
  if (toolRestrictions.tools !== void 0 || toolRestrictions.allowedTools || toolRestrictions.disallowedTools) {
1201
1227
  loopConfig.toolRestrictions = toolRestrictions;
1202
1228
  }
1229
+ const abort = new AbortController();
1230
+ loopConfig.abortSignal = abort.signal;
1203
1231
  const promise = this.deps.startLoop(ticketId, columnId, loopConfig);
1204
- this.activeLoops.set(ticketId, { columnId, promise });
1232
+ this.activeLoops.set(ticketId, { columnId, promise, abort });
1205
1233
  this.lastFiredAt.set(columnId, /* @__PURE__ */ new Date());
1206
1234
  void promise.then(
1207
1235
  (result) => this.onLoopComplete(ticketId, columnId, result).catch((err) => {
@@ -1661,6 +1689,11 @@ ${findingsText}`)
1661
1689
  async onLoopComplete(ticketId, columnId, result) {
1662
1690
  this.completing.add(ticketId);
1663
1691
  this.activeLoops.delete(ticketId);
1692
+ if (this.abortedForMove.has(ticketId)) {
1693
+ this.abortedForMove.delete(ticketId);
1694
+ this.completing.delete(ticketId);
1695
+ return;
1696
+ }
1664
1697
  try {
1665
1698
  const colScope = this.columnScopes.get(columnId);
1666
1699
  const ticket = colScope?.tickets.find((t) => t.id === ticketId);
@@ -3423,6 +3456,8 @@ var CodexProvider = class {
3423
3456
  for (const [name, server] of Object.entries(request.mcpConfig.servers)) {
3424
3457
  args.push("-c", `mcp_servers.${name}.command=${JSON.stringify(server.command)}`);
3425
3458
  args.push("-c", `mcp_servers.${name}.args=${JSON.stringify(server.args)}`);
3459
+ args.push("-c", `mcp_servers.${name}.tool_timeout_sec=1800`);
3460
+ args.push("-c", `mcp_servers.${name}.startup_timeout_sec=120`);
3426
3461
  if (Object.keys(server.env).length > 0) {
3427
3462
  for (const [key, value] of Object.entries(server.env)) {
3428
3463
  args.push("-c", `mcp_servers.${name}.env.${key}=${JSON.stringify(value)}`);
@@ -4740,6 +4775,7 @@ Received ${signal}. Shutting down gracefully...`);
4740
4775
  const ticket = payload["ticket"];
4741
4776
  const ticketId = (typeof payload["ticketId"] === "string" ? payload["ticketId"] : null) ?? (ticket && typeof ticket["id"] === "string" ? ticket["id"] : null);
4742
4777
  const columnId = (typeof payload["columnId"] === "string" ? payload["columnId"] : null) ?? (ticket && typeof ticket["column_id"] === "string" ? ticket["column_id"] : null);
4778
+ const fromColumnId = typeof payload["fromColumnId"] === "string" ? payload["fromColumnId"] : null;
4743
4779
  if (wsEvent.type === "firing_constraint:created" || wsEvent.type === "firing_constraint:updated" || wsEvent.type === "firing_constraint:deleted") {
4744
4780
  logger.orchestrator(`WS event: ${wsEvent.type} \u2014 refreshing constraint caches`);
4745
4781
  void orchestrator.refreshConstraints().catch((err) => {
@@ -4751,9 +4787,9 @@ Received ${signal}. Shutting down gracefully...`);
4751
4787
  if (!ticketId) return;
4752
4788
  const eventType = wsEvent.type;
4753
4789
  if (eventType === "ticket:created" || eventType === "ticket:moved" || eventType === "ticket:updated" || eventType === "ticket:archived" || eventType === "ticket:deleted") {
4754
- const pipelineEvent = { type: eventType, ticketId, columnId };
4790
+ const pipelineEvent = { type: eventType, ticketId, columnId, fromColumnId };
4755
4791
  eventQueue.push(pipelineEvent);
4756
- logger.orchestrator(`WS event: ${eventType} ticket=${ticketId} column=${columnId ?? "null"}`);
4792
+ logger.orchestrator(`WS event: ${eventType} ticket=${ticketId} column=${columnId ?? "null"} from=${fromColumnId ?? "null"}`);
4757
4793
  }
4758
4794
  },
4759
4795
  onConnect: () => {
@@ -4896,4 +4932,4 @@ export {
4896
4932
  runPipeline,
4897
4933
  stopPipeline
4898
4934
  };
4899
- //# sourceMappingURL=pipeline-IAKINX5A.js.map
4935
+ //# sourceMappingURL=pipeline-GF4H4IDN.js.map