@i14ks/ccv 0.17.2 → 0.17.3

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 (2) hide show
  1. package/bundle/ccv.mjs +34 -6
  2. package/package.json +1 -1
package/bundle/ccv.mjs CHANGED
@@ -1234,9 +1234,10 @@ var ClaudeSession = class extends EventEmitter {
1234
1234
  * готово. Список нужен ровно для того, чтобы список сессий не называл
1235
1235
  * сессию «готова», пока где-то ещё крутится агент.
1236
1236
  *
1237
- * Очищается не отдельным событием (у уведомления нет надёжной привязки к
1238
- * конкретному toolUseId), а любым переходом обратно в `running` —
1239
- * `#setState` делает это сам, см. там же.
1237
+ * Запуск уходит из набора по `task_notification` с его toolUseId, по
1238
+ * ошибке в результате вызова (задача так и не стартовала) и — на случай,
1239
+ * если уведомление пришло без привязки, — любым переходом обратно в
1240
+ * `running`: `#setState` делает это сам, см. там же.
1240
1241
  */
1241
1242
  #backgroundWork = /* @__PURE__ */ new Set();
1242
1243
  /**
@@ -2576,7 +2577,7 @@ var ClaudeSession = class extends EventEmitter {
2576
2577
  const patch = message.patch ?? {};
2577
2578
  const status = patch.status;
2578
2579
  if (status === "completed" || status === "failed" || status === "killed") {
2579
- this.#tasks.delete(task.id);
2580
+ this.#finishTask(task.id, task.toolUseId);
2580
2581
  } else {
2581
2582
  if (typeof patch.is_backgrounded === "boolean")
2582
2583
  task.background = patch.is_backgrounded;
@@ -2586,11 +2587,15 @@ var ClaudeSession = class extends EventEmitter {
2586
2587
  this.emit("summary", this.summary());
2587
2588
  return true;
2588
2589
  }
2589
- case "task_notification":
2590
+ case "task_notification": {
2590
2591
  this.#lastActiveAt = Date.now();
2591
- if (taskId && this.#tasks.delete(taskId))
2592
+ if (!taskId)
2593
+ return false;
2594
+ const toolUseId = str(message.tool_use_id) ?? this.#tasks.get(taskId)?.toolUseId ?? null;
2595
+ if (this.#finishTask(taskId, toolUseId))
2592
2596
  this.emit("summary", this.summary());
2593
2597
  return false;
2598
+ }
2594
2599
  case "background_tasks_changed": {
2595
2600
  this.#lastActiveAt = Date.now();
2596
2601
  const live = Array.isArray(message.tasks) ? message.tasks.flatMap((t) => typeof t.task_id === "string" ? [t.task_id] : []) : [];
@@ -2608,6 +2613,23 @@ var ClaudeSession = class extends EventEmitter {
2608
2613
  return false;
2609
2614
  }
2610
2615
  }
2616
+ /**
2617
+ * Задача кончилась — убрать её отовсюду, где она числится живой. `true` —
2618
+ * что-то изменилось и сводку пора разослать.
2619
+ *
2620
+ * Уровень и набор запусков чистим здесь же, не дожидаясь их собственных
2621
+ * сигналов: следующий `background_tasks_changed` может не прийти вовсе, а
2622
+ * набор запусков иначе чистит только новый ход — и сессия, чья фоновая
2623
+ * команда тихо доработала, висела бы «в фоне» до следующего промпта.
2624
+ */
2625
+ #finishTask(taskId, toolUseId) {
2626
+ let changed = this.#tasks.delete(taskId);
2627
+ if (this.#backgroundLevel?.delete(taskId))
2628
+ changed = true;
2629
+ if (toolUseId !== null && this.#backgroundWork.delete(toolUseId))
2630
+ changed = true;
2631
+ return changed;
2632
+ }
2611
2633
  /** Сводка по прогрессу задач — не чаще раза в секунду. */
2612
2634
  #emitTasksSoon() {
2613
2635
  if (this.#taskSummaryTimer)
@@ -2686,6 +2708,7 @@ var ClaudeSession = class extends EventEmitter {
2686
2708
  const content = message.message.content;
2687
2709
  if (typeof content === "string")
2688
2710
  return;
2711
+ let backgroundChanged = false;
2689
2712
  for (const block of content) {
2690
2713
  if (block.type !== "tool_result")
2691
2714
  continue;
@@ -2695,7 +2718,12 @@ var ClaudeSession = class extends EventEmitter {
2695
2718
  content: contentToText2(block.content),
2696
2719
  isError: block.is_error === true
2697
2720
  });
2721
+ if (block.is_error === true && this.#backgroundWork.delete(block.tool_use_id)) {
2722
+ backgroundChanged = true;
2723
+ }
2698
2724
  }
2725
+ if (backgroundChanged)
2726
+ this.emit("summary", this.summary());
2699
2727
  }
2700
2728
  /** Индекс очередного блока сообщения — в той же нумерации, что у дельт. */
2701
2729
  #nextBlockIndex(messageId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@i14ks/ccv",
3
- "version": "0.17.2",
3
+ "version": "0.17.3",
4
4
  "license": "UNLICENSED",
5
5
  "description": "GUI для Claude Code: сессии агента в каталогах проектов, дерево файлов и редактор рядом с разговором.",
6
6
  "homepage": "https://claudevisual.com",