@kenkaiiii/gg-boss 4.3.146 → 4.3.148

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.
@@ -32167,8 +32167,11 @@ var require_jsx_runtime = __commonJS({
32167
32167
  }
32168
32168
  });
32169
32169
 
32170
- // src/worker.ts
32170
+ // src/logger.ts
32171
32171
  init_esm_shims();
32172
+ import fs26 from "fs";
32173
+ import path25 from "path";
32174
+ import { randomBytes as randomBytes3 } from "crypto";
32172
32175
 
32173
32176
  // ../ggcoder/dist/index.js
32174
32177
  init_esm_shims();
@@ -90714,6 +90717,73 @@ import { execFileSync as execFileSync2 } from "child_process";
90714
90717
  var ESC3 = String.fromCharCode(27);
90715
90718
  var oscResponsePattern = new RegExp(ESC3 + "\\]11;rgb:([0-9a-fA-F]+)/([0-9a-fA-F]+)/([0-9a-fA-F]+)");
90716
90719
 
90720
+ // src/logger.ts
90721
+ var MAX_BYTES3 = 10 * 1024 * 1024;
90722
+ var fd2 = null;
90723
+ var sessionId2 = "";
90724
+ function getLogPath() {
90725
+ return path25.join(getAppPaths().agentDir, "boss", "debug.log");
90726
+ }
90727
+ function rotateIfNeeded(filePath) {
90728
+ try {
90729
+ const st = fs26.statSync(filePath);
90730
+ if (st.size < MAX_BYTES3) return;
90731
+ const rotated = `${filePath}.1`;
90732
+ try {
90733
+ fs26.unlinkSync(rotated);
90734
+ } catch {
90735
+ }
90736
+ fs26.renameSync(filePath, rotated);
90737
+ } catch {
90738
+ }
90739
+ }
90740
+ function initLogger2(meta3) {
90741
+ if (fd2 !== null) return;
90742
+ const filePath = getLogPath();
90743
+ try {
90744
+ fs26.mkdirSync(path25.dirname(filePath), { recursive: true, mode: 448 });
90745
+ } catch {
90746
+ return;
90747
+ }
90748
+ rotateIfNeeded(filePath);
90749
+ try {
90750
+ fd2 = fs26.openSync(filePath, "a");
90751
+ } catch {
90752
+ return;
90753
+ }
90754
+ sessionId2 = randomBytes3(4).toString("hex");
90755
+ try {
90756
+ fs26.writeSync(fd2, "\n");
90757
+ } catch {
90758
+ }
90759
+ const parts = ["gg-boss"];
90760
+ if (meta3?.version) parts[0] += ` v${meta3.version}`;
90761
+ parts.push("started");
90762
+ if (meta3?.bossProvider) parts.push(`boss=${meta3.bossProvider}/${meta3.bossModel ?? "?"}`);
90763
+ if (meta3?.bossThinking) parts.push(`bossThinking=${meta3.bossThinking}`);
90764
+ if (meta3?.workerProvider) parts.push(`workers=${meta3.workerProvider}/${meta3.workerModel ?? "?"}`);
90765
+ if (meta3?.projectCount !== void 0) parts.push(`projects=${meta3.projectCount}`);
90766
+ parts.push(`pid=${process.pid}`);
90767
+ log2("INFO", "startup", parts.join(" "));
90768
+ }
90769
+ function log2(level, category, message, data) {
90770
+ if (fd2 === null) return;
90771
+ const ts = (/* @__PURE__ */ new Date()).toISOString();
90772
+ let line = `[${ts}] [sid=${sessionId2}] [${level}] [${category}] ${message}`;
90773
+ if (data) {
90774
+ const pairs = Object.entries(data).map(([k, v]) => `${k}=${typeof v === "string" ? v : JSON.stringify(v)}`).join(" ");
90775
+ if (pairs) line += ` ${pairs}`;
90776
+ }
90777
+ line += "\n";
90778
+ try {
90779
+ fs26.writeSync(fd2, line);
90780
+ } catch {
90781
+ }
90782
+ }
90783
+
90784
+ // src/worker.ts
90785
+ init_esm_shims();
90786
+
90717
90787
  // src/boss-store.ts
90718
90788
  init_esm_shims();
90719
90789
  var import_react75 = __toESM(require_react(), 1);
@@ -90832,6 +90902,19 @@ var bossStore = {
90832
90902
  };
90833
90903
  notify();
90834
90904
  },
90905
+ /**
90906
+ * Append the eye-catching update-available notice. Distinct kind so the
90907
+ * renderer can give it the rounded green-bordered "✨ ..." box treatment
90908
+ * that mirrors ggcoder's update notice — flat info text gets lost in
90909
+ * worker chatter, this stands out.
90910
+ */
90911
+ appendUpdateNotice(text) {
90912
+ state = {
90913
+ ...state,
90914
+ history: [...state.history, { kind: "update_notice", id: id(), text }]
90915
+ };
90916
+ notify();
90917
+ },
90835
90918
  /**
90836
90919
  * Queue an info message to be appended AFTER the boss's current turn ends.
90837
90920
  * Used by tools (like add_task's keybind hint) that fire mid-turn and would
@@ -91299,6 +91382,20 @@ var bossStore = {
91299
91382
  };
91300
91383
 
91301
91384
  // src/worker.ts
91385
+ function safeBusHandler(workerName, handlerName, fn, onError) {
91386
+ return (event) => {
91387
+ try {
91388
+ fn(event);
91389
+ } catch (err) {
91390
+ const message = err instanceof Error ? err.message : String(err);
91391
+ log2("ERROR", "worker", `bus handler "${handlerName}" threw`, {
91392
+ worker: workerName,
91393
+ message
91394
+ });
91395
+ onError(`Worker "${workerName}" event handler error: ${message}`);
91396
+ }
91397
+ };
91398
+ }
91302
91399
  var Worker = class {
91303
91400
  name;
91304
91401
  cwd;
@@ -91367,45 +91464,88 @@ var Worker = class {
91367
91464
  }
91368
91465
  wireEvents() {
91369
91466
  const bus = this.session.eventBus;
91370
- bus.on("text_delta", ({ text }) => {
91371
- this.currentText += text;
91372
- });
91373
- bus.on("tool_call_start", ({ toolCallId, name }) => {
91374
- this.activeTools.set(toolCallId, name);
91375
- });
91376
- bus.on("tool_call_end", ({ toolCallId, isError }) => {
91377
- const name = this.activeTools.get(toolCallId);
91378
- this.activeTools.delete(toolCallId);
91379
- if (name) this.currentTools.push({ name, ok: !isError });
91380
- });
91381
- bus.on("agent_done", () => {
91382
- this.turnCount += 1;
91383
- const summary = {
91384
- project: this.name,
91385
- cwd: this.cwd,
91386
- status: "idle",
91387
- finalText: this.currentText.trim(),
91388
- toolsUsed: [...this.currentTools],
91389
- turnIndex: this.turnCount,
91390
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
91391
- };
91392
- this.currentText = "";
91393
- this.currentTools = [];
91394
- this.status = "idle";
91395
- bossStore.appendWorkerEvent(summary);
91396
- this.queue.push({ kind: "worker_turn_complete", summary });
91397
- });
91398
- bus.on("error", ({ error: error51 }) => {
91399
- this.status = "error";
91467
+ const reportError2 = (message) => {
91400
91468
  const ts = (/* @__PURE__ */ new Date()).toISOString();
91401
- bossStore.appendWorkerError(this.name, error51.message, ts);
91469
+ this.status = "error";
91470
+ bossStore.appendWorkerError(this.name, message, ts);
91402
91471
  this.queue.push({
91403
91472
  kind: "worker_error",
91404
91473
  project: this.name,
91405
- message: error51.message,
91474
+ message,
91406
91475
  timestamp: ts
91407
91476
  });
91408
- });
91477
+ };
91478
+ bus.on(
91479
+ "text_delta",
91480
+ safeBusHandler(
91481
+ this.name,
91482
+ "text_delta",
91483
+ ({ text }) => {
91484
+ this.currentText += text;
91485
+ },
91486
+ reportError2
91487
+ )
91488
+ );
91489
+ bus.on(
91490
+ "tool_call_start",
91491
+ safeBusHandler(
91492
+ this.name,
91493
+ "tool_call_start",
91494
+ ({ toolCallId, name }) => {
91495
+ this.activeTools.set(toolCallId, name);
91496
+ },
91497
+ reportError2
91498
+ )
91499
+ );
91500
+ bus.on(
91501
+ "tool_call_end",
91502
+ safeBusHandler(
91503
+ this.name,
91504
+ "tool_call_end",
91505
+ ({ toolCallId, isError }) => {
91506
+ const name = this.activeTools.get(toolCallId);
91507
+ this.activeTools.delete(toolCallId);
91508
+ if (name) this.currentTools.push({ name, ok: !isError });
91509
+ },
91510
+ reportError2
91511
+ )
91512
+ );
91513
+ bus.on(
91514
+ "agent_done",
91515
+ safeBusHandler(
91516
+ this.name,
91517
+ "agent_done",
91518
+ () => {
91519
+ this.turnCount += 1;
91520
+ const summary = {
91521
+ project: this.name,
91522
+ cwd: this.cwd,
91523
+ status: "idle",
91524
+ finalText: this.currentText.trim(),
91525
+ toolsUsed: [...this.currentTools],
91526
+ turnIndex: this.turnCount,
91527
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
91528
+ };
91529
+ this.currentText = "";
91530
+ this.currentTools = [];
91531
+ this.status = "idle";
91532
+ bossStore.appendWorkerEvent(summary);
91533
+ this.queue.push({ kind: "worker_turn_complete", summary });
91534
+ },
91535
+ reportError2
91536
+ )
91537
+ );
91538
+ bus.on(
91539
+ "error",
91540
+ safeBusHandler(
91541
+ this.name,
91542
+ "error",
91543
+ ({ error: error51 }) => {
91544
+ reportError2(error51.message);
91545
+ },
91546
+ reportError2
91547
+ )
91548
+ );
91409
91549
  }
91410
91550
  };
91411
91551
 
@@ -91441,17 +91581,17 @@ var EventQueue = class {
91441
91581
 
91442
91582
  // src/settings.ts
91443
91583
  init_esm_shims();
91444
- import fs26 from "fs/promises";
91445
- import path25 from "path";
91584
+ import fs27 from "fs/promises";
91585
+ import path26 from "path";
91446
91586
  function settingsPath() {
91447
- return path25.join(getAppPaths().agentDir, "boss", "settings.json");
91587
+ return path26.join(getAppPaths().agentDir, "boss", "settings.json");
91448
91588
  }
91449
91589
  async function ensureDir() {
91450
- await fs26.mkdir(path25.dirname(settingsPath()), { recursive: true, mode: 448 });
91590
+ await fs27.mkdir(path26.dirname(settingsPath()), { recursive: true, mode: 448 });
91451
91591
  }
91452
91592
  async function loadSettings() {
91453
91593
  try {
91454
- const content = await fs26.readFile(settingsPath(), "utf-8");
91594
+ const content = await fs27.readFile(settingsPath(), "utf-8");
91455
91595
  const parsed = JSON.parse(content);
91456
91596
  return parsed && typeof parsed === "object" ? parsed : {};
91457
91597
  } catch {
@@ -91465,81 +91605,13 @@ async function saveSettings(patch) {
91465
91605
  const merged = { ...current, ...patch };
91466
91606
  await ensureDir();
91467
91607
  const tmp = `${settingsPath()}.${process.pid}.tmp`;
91468
- await fs26.writeFile(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
91469
- await fs26.rename(tmp, settingsPath());
91608
+ await fs27.writeFile(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
91609
+ await fs27.rename(tmp, settingsPath());
91470
91610
  });
91471
91611
  writeChain = next.catch(() => void 0);
91472
91612
  await next;
91473
91613
  }
91474
91614
 
91475
- // src/logger.ts
91476
- init_esm_shims();
91477
- import fs27 from "fs";
91478
- import path26 from "path";
91479
- import { randomBytes as randomBytes3 } from "crypto";
91480
- var MAX_BYTES3 = 10 * 1024 * 1024;
91481
- var fd2 = null;
91482
- var sessionId2 = "";
91483
- function getLogPath() {
91484
- return path26.join(getAppPaths().agentDir, "boss", "debug.log");
91485
- }
91486
- function rotateIfNeeded(filePath) {
91487
- try {
91488
- const st = fs27.statSync(filePath);
91489
- if (st.size < MAX_BYTES3) return;
91490
- const rotated = `${filePath}.1`;
91491
- try {
91492
- fs27.unlinkSync(rotated);
91493
- } catch {
91494
- }
91495
- fs27.renameSync(filePath, rotated);
91496
- } catch {
91497
- }
91498
- }
91499
- function initLogger2(meta3) {
91500
- if (fd2 !== null) return;
91501
- const filePath = getLogPath();
91502
- try {
91503
- fs27.mkdirSync(path26.dirname(filePath), { recursive: true, mode: 448 });
91504
- } catch {
91505
- return;
91506
- }
91507
- rotateIfNeeded(filePath);
91508
- try {
91509
- fd2 = fs27.openSync(filePath, "a");
91510
- } catch {
91511
- return;
91512
- }
91513
- sessionId2 = randomBytes3(4).toString("hex");
91514
- try {
91515
- fs27.writeSync(fd2, "\n");
91516
- } catch {
91517
- }
91518
- const parts = ["gg-boss"];
91519
- if (meta3?.version) parts[0] += ` v${meta3.version}`;
91520
- parts.push("started");
91521
- if (meta3?.bossProvider) parts.push(`boss=${meta3.bossProvider}/${meta3.bossModel ?? "?"}`);
91522
- if (meta3?.bossThinking) parts.push(`bossThinking=${meta3.bossThinking}`);
91523
- if (meta3?.workerProvider) parts.push(`workers=${meta3.workerProvider}/${meta3.workerModel ?? "?"}`);
91524
- if (meta3?.projectCount !== void 0) parts.push(`projects=${meta3.projectCount}`);
91525
- parts.push(`pid=${process.pid}`);
91526
- log2("INFO", "startup", parts.join(" "));
91527
- }
91528
- function log2(level, category, message, data) {
91529
- if (fd2 === null) return;
91530
- const ts = (/* @__PURE__ */ new Date()).toISOString();
91531
- let line = `[${ts}] [sid=${sessionId2}] [${level}] [${category}] ${message}`;
91532
- if (data) {
91533
- const pairs = Object.entries(data).map(([k, v]) => `${k}=${typeof v === "string" ? v : JSON.stringify(v)}`).join(" ");
91534
- if (pairs) line += ` ${pairs}`;
91535
- }
91536
- line += "\n";
91537
- try {
91538
- fs27.writeSync(fd2, line);
91539
- } catch {
91540
- }
91541
- }
91542
-
91543
91615
  // src/boss-system-prompt.ts
91544
91616
  init_esm_shims();
91545
91617
  function buildBossSystemPrompt(projects) {
@@ -92718,132 +92790,144 @@ var GGBoss = class {
92718
92790
  async run() {
92719
92791
  this.running = true;
92720
92792
  while (this.running) {
92721
- const event = await this.queue.next();
92722
- if (!this.running) break;
92723
- if (event.kind === "user_message") {
92724
- this.pendingUserMessages = Math.max(0, this.pendingUserMessages - 1);
92725
- bossStore.setPendingMessages(this.pendingUserMessages);
92726
- }
92727
- let finishedTaskId = null;
92728
- if (event.kind === "worker_turn_complete") {
92729
- void playDoneAudio();
92730
- this.hadWorkerActivitySinceReady = true;
92731
- this.lastSummaries.set(event.summary.project, event.summary);
92732
- log2("INFO", "worker_turn_complete", "worker finished", {
92733
- project: event.summary.project,
92734
- turn: event.summary.turnIndex,
92735
- tools: event.summary.toolsUsed.length,
92736
- failed: event.summary.toolsUsed.filter((t) => !t.ok).length
92737
- });
92738
- const taskId = this.inFlightTaskByProject.get(event.summary.project);
92739
- finishedTaskId = taskId ?? null;
92740
- if (taskId) {
92741
- this.inFlightTaskByProject.delete(event.summary.project);
92742
- const task = tasksStore.byId(taskId);
92743
- if (task && task.status === "in_progress") {
92744
- const reported = parseReportedStatus(event.summary.finalText);
92745
- const newStatus = reportedToTaskStatus(
92746
- reported,
92747
- event.summary.toolsUsed.some((t) => !t.ok)
92748
- );
92749
- await tasksStore.update(taskId, {
92750
- status: newStatus,
92751
- resultSummary: event.summary.finalText
92752
- });
92753
- }
92793
+ try {
92794
+ await this.runIteration();
92795
+ } catch (err) {
92796
+ const message = err instanceof Error ? err.message : String(err);
92797
+ log2("ERROR", "run_loop", "iteration threw", { message });
92798
+ try {
92799
+ bossStore.appendInfo(`Boss loop error (recovered): ${message}`, "error");
92800
+ } catch {
92754
92801
  }
92755
92802
  }
92756
- if (event.kind === "worker_error") {
92757
- this.hadWorkerActivitySinceReady = true;
92758
- log2("ERROR", "worker_error", event.message, { project: event.project });
92759
- const taskId = this.inFlightTaskByProject.get(event.project);
92760
- if (taskId) {
92761
- this.inFlightTaskByProject.delete(event.project);
92803
+ }
92804
+ }
92805
+ async runIteration() {
92806
+ const event = await this.queue.next();
92807
+ if (!this.running) return;
92808
+ if (event.kind === "user_message") {
92809
+ this.pendingUserMessages = Math.max(0, this.pendingUserMessages - 1);
92810
+ bossStore.setPendingMessages(this.pendingUserMessages);
92811
+ }
92812
+ let finishedTaskId = null;
92813
+ if (event.kind === "worker_turn_complete") {
92814
+ void playDoneAudio();
92815
+ this.hadWorkerActivitySinceReady = true;
92816
+ this.lastSummaries.set(event.summary.project, event.summary);
92817
+ log2("INFO", "worker_turn_complete", "worker finished", {
92818
+ project: event.summary.project,
92819
+ turn: event.summary.turnIndex,
92820
+ tools: event.summary.toolsUsed.length,
92821
+ failed: event.summary.toolsUsed.filter((t) => !t.ok).length
92822
+ });
92823
+ const taskId = this.inFlightTaskByProject.get(event.summary.project);
92824
+ finishedTaskId = taskId ?? null;
92825
+ if (taskId) {
92826
+ this.inFlightTaskByProject.delete(event.summary.project);
92827
+ const task = tasksStore.byId(taskId);
92828
+ if (task && task.status === "in_progress") {
92829
+ const reported = parseReportedStatus(event.summary.finalText);
92830
+ const newStatus = reportedToTaskStatus(
92831
+ reported,
92832
+ event.summary.toolsUsed.some((t) => !t.ok)
92833
+ );
92762
92834
  await tasksStore.update(taskId, {
92763
- status: "blocked",
92764
- notes: `Worker error: ${event.message}`
92835
+ status: newStatus,
92836
+ resultSummary: event.summary.finalText
92765
92837
  });
92766
92838
  }
92767
92839
  }
92768
- await this.runCompaction(false);
92769
- const workerSnapshot = [...this.workers.entries()].map(([name, w]) => ({
92770
- name,
92771
- status: w.getStatus()
92772
- }));
92773
- const notices = this.pendingAutoChainNotices.splice(0);
92774
- const text = formatEventForBoss(event, workerSnapshot, notices);
92775
- bossStore.startStreaming();
92776
- this.turnAc = new AbortController();
92777
- this.bossAgent.setSignal(this.turnAc.signal);
92778
- try {
92779
- const stream2 = this.bossAgent.prompt(text);
92780
- for await (const e of stream2) {
92781
- switch (e.type) {
92782
- case "text_delta":
92783
- bossStore.appendStreamText(e.text);
92784
- break;
92785
- case "thinking_delta":
92786
- bossStore.appendStreamThinking(e.text);
92787
- break;
92788
- case "tool_call_start":
92789
- bossStore.flushPendingText();
92790
- bossStore.startTool(e.toolCallId, e.name, e.args);
92791
- bossStore.setActivityPhase("tools");
92792
- break;
92793
- case "tool_call_end":
92794
- bossStore.endTool(e.toolCallId, e.isError, e.durationMs, e.result, e.details);
92795
- break;
92796
- case "turn_end":
92797
- if (e.usage) {
92798
- bossStore.setBossInputTokens(computeContextUsed(e.usage, this.opts.bossProvider));
92799
- }
92800
- bossStore.flushPendingText();
92801
- bossStore.flushEndOfTurnInfos();
92802
- break;
92803
- case "retry":
92804
- if (!e.silent) {
92805
- bossStore.setRetryInfo({
92806
- reason: e.reason,
92807
- attempt: e.attempt,
92808
- maxAttempts: e.maxAttempts,
92809
- delayMs: e.delayMs
92810
- });
92811
- }
92812
- break;
92813
- case "error":
92814
- bossStore.appendInfo(formatProviderError(e.error.message), "error");
92815
- break;
92816
- default:
92817
- break;
92818
- }
92840
+ }
92841
+ if (event.kind === "worker_error") {
92842
+ this.hadWorkerActivitySinceReady = true;
92843
+ log2("ERROR", "worker_error", event.message, { project: event.project });
92844
+ const taskId = this.inFlightTaskByProject.get(event.project);
92845
+ if (taskId) {
92846
+ this.inFlightTaskByProject.delete(event.project);
92847
+ await tasksStore.update(taskId, {
92848
+ status: "blocked",
92849
+ notes: `Worker error: ${event.message}`
92850
+ });
92851
+ }
92852
+ }
92853
+ await this.runCompaction(false);
92854
+ const workerSnapshot = [...this.workers.entries()].map(([name, w]) => ({
92855
+ name,
92856
+ status: w.getStatus()
92857
+ }));
92858
+ const notices = this.pendingAutoChainNotices.splice(0);
92859
+ const text = formatEventForBoss(event, workerSnapshot, notices);
92860
+ bossStore.startStreaming();
92861
+ this.turnAc = new AbortController();
92862
+ this.bossAgent.setSignal(this.turnAc.signal);
92863
+ try {
92864
+ const stream2 = this.bossAgent.prompt(text);
92865
+ for await (const e of stream2) {
92866
+ switch (e.type) {
92867
+ case "text_delta":
92868
+ bossStore.appendStreamText(e.text);
92869
+ break;
92870
+ case "thinking_delta":
92871
+ bossStore.appendStreamThinking(e.text);
92872
+ break;
92873
+ case "tool_call_start":
92874
+ bossStore.flushPendingText();
92875
+ bossStore.startTool(e.toolCallId, e.name, e.args);
92876
+ bossStore.setActivityPhase("tools");
92877
+ break;
92878
+ case "tool_call_end":
92879
+ bossStore.endTool(e.toolCallId, e.isError, e.durationMs, e.result, e.details);
92880
+ break;
92881
+ case "turn_end":
92882
+ if (e.usage) {
92883
+ bossStore.setBossInputTokens(computeContextUsed(e.usage, this.opts.bossProvider));
92884
+ }
92885
+ bossStore.flushPendingText();
92886
+ bossStore.flushEndOfTurnInfos();
92887
+ break;
92888
+ case "retry":
92889
+ if (!e.silent) {
92890
+ bossStore.setRetryInfo({
92891
+ reason: e.reason,
92892
+ attempt: e.attempt,
92893
+ maxAttempts: e.maxAttempts,
92894
+ delayMs: e.delayMs
92895
+ });
92896
+ }
92897
+ break;
92898
+ case "error":
92899
+ bossStore.appendInfo(formatProviderError(e.error.message), "error");
92900
+ break;
92901
+ default:
92902
+ break;
92819
92903
  }
92820
- } catch (err) {
92821
- if (isAbortError3(err)) {
92822
- bossStore.interruptStreaming();
92823
- if (!this.running) {
92824
- bossStore.finishStreaming();
92825
- return;
92826
- }
92827
- bossStore.appendInfo("Interrupted by user.", "warning");
92904
+ }
92905
+ } catch (err) {
92906
+ if (isAbortError3(err)) {
92907
+ bossStore.interruptStreaming();
92908
+ if (!this.running) {
92828
92909
  bossStore.finishStreaming();
92829
- await this.persistNewMessages();
92830
- continue;
92910
+ return;
92831
92911
  }
92832
- const message = err instanceof Error ? err.message : String(err);
92833
- log2("ERROR", "boss_turn", message);
92834
- bossStore.appendInfo(formatProviderError(message), "error");
92835
- }
92836
- bossStore.finishStreaming();
92837
- await this.persistNewMessages();
92838
- if (event.kind === "worker_turn_complete" && finishedTaskId) {
92839
- await this.maybeAutoChain(event.summary.project);
92840
- }
92841
- const allWorkersIdle = [...this.workers.values()].every((w) => w.getStatus() === "idle");
92842
- if (this.hadWorkerActivitySinceReady && allWorkersIdle && this.queue.size() === 0) {
92843
- this.hadWorkerActivitySinceReady = false;
92844
- log2("INFO", "all_clear", "all workers idle, queue empty");
92845
- void playReadyAudio();
92912
+ bossStore.appendInfo("Interrupted by user.", "warning");
92913
+ bossStore.finishStreaming();
92914
+ await this.persistNewMessages();
92915
+ return;
92846
92916
  }
92917
+ const message = err instanceof Error ? err.message : String(err);
92918
+ log2("ERROR", "boss_turn", message);
92919
+ bossStore.appendInfo(formatProviderError(message), "error");
92920
+ }
92921
+ bossStore.finishStreaming();
92922
+ await this.persistNewMessages();
92923
+ if (event.kind === "worker_turn_complete" && finishedTaskId) {
92924
+ await this.maybeAutoChain(event.summary.project);
92925
+ }
92926
+ const allWorkersIdle = [...this.workers.values()].every((w) => w.getStatus() === "idle");
92927
+ if (this.hadWorkerActivitySinceReady && allWorkersIdle && this.queue.size() === 0) {
92928
+ this.hadWorkerActivitySinceReady = false;
92929
+ log2("INFO", "all_clear", "all workers idle, queue empty");
92930
+ void playReadyAudio();
92847
92931
  }
92848
92932
  }
92849
92933
  async maybeAutoChain(project) {
@@ -92990,6 +93074,8 @@ export {
92990
93074
  ModelSelector,
92991
93075
  useBossState,
92992
93076
  bossStore,
93077
+ initLogger2 as initLogger,
93078
+ log2 as log,
92993
93079
  Worker,
92994
93080
  EventQueue,
92995
93081
  useTasksState,
@@ -92997,8 +93083,6 @@ export {
92997
93083
  loadSettings,
92998
93084
  getSplashAudioDurationMs,
92999
93085
  playSplashAudio,
93000
- initLogger2 as initLogger,
93001
- log2 as log,
93002
93086
  buildBossSystemPrompt,
93003
93087
  GGBoss
93004
93088
  };
@@ -93114,4 +93198,4 @@ react/cjs/react-jsx-runtime.development.js:
93114
93198
  * LICENSE file in the root directory of this source tree.
93115
93199
  *)
93116
93200
  */
93117
- //# sourceMappingURL=chunk-3EWLK53W.js.map
93201
+ //# sourceMappingURL=chunk-ZNVFGIDI.js.map