chatroom-cli 1.49.1 → 1.49.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -30140,6 +30140,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
30140
30140
  } catch (err) {
30141
30141
  console.warn(`[opencode-sdk] session.abort for pid=${pid} sessionId=${meta.sessionId} failed (continuing with SIGTERM):`, err instanceof Error ? err.message : err);
30142
30142
  }
30143
+ this.sessionStore.remove(meta.sessionId);
30143
30144
  }
30144
30145
  await super.stop(pid);
30145
30146
  }
@@ -83327,6 +83328,16 @@ var init_crash_loop_tracker = __esm(() => {
83327
83328
  ];
83328
83329
  });
83329
83330
 
83331
+ // src/infrastructure/deps/process.ts
83332
+ function isProcessAlive(kill, pid) {
83333
+ try {
83334
+ kill(pid, 0);
83335
+ return true;
83336
+ } catch {
83337
+ return false;
83338
+ }
83339
+ }
83340
+
83330
83341
  // src/infrastructure/machine/stop-reason.ts
83331
83342
  function resolveStopReason(code2, signal) {
83332
83343
  if (signal !== null)
@@ -83449,16 +83460,24 @@ class AgentProcessManager {
83449
83460
  async ensureRunning(opts) {
83450
83461
  const key = agentKey2(opts.chatroomId, opts.role);
83451
83462
  const slot = this.getOrCreateSlot(key);
83452
- if (slot.state === "running") {
83453
- return { success: true, pid: slot.pid };
83454
- }
83455
- if (slot.state === "spawning" && slot.pendingOperation) {
83456
- return slot.pendingOperation;
83463
+ if (slot.state === "running" && slot.pid && !isProcessAlive(this.deps.processes.kill, slot.pid)) {
83464
+ slot.state = "idle";
83465
+ slot.pid = undefined;
83466
+ slot.harness = undefined;
83467
+ slot.harnessSessionId = undefined;
83468
+ slot.model = undefined;
83469
+ slot.workingDir = undefined;
83470
+ slot.startedAt = undefined;
83471
+ slot.pendingOperation = undefined;
83457
83472
  }
83458
- if (slot.state === "stopping" && slot.pendingOperation) {
83459
- await slot.pendingOperation;
83473
+ if (slot.pendingOperation) {
83474
+ if (slot.state === "stopping") {
83475
+ await slot.pendingOperation;
83476
+ } else {
83477
+ return slot.pendingOperation;
83478
+ }
83460
83479
  }
83461
- const operation = this.doEnsureRunning(key, slot, opts);
83480
+ const operation = this.executeEnsureRunning(key, slot, opts);
83462
83481
  slot.pendingOperation = operation;
83463
83482
  return operation;
83464
83483
  }
@@ -83621,31 +83640,38 @@ class AgentProcessManager {
83621
83640
  } catch (err) {
83622
83641
  console.warn(`[AgentProcessManager] ⚠️ Failed to load persisted agent entries: ${err.message}`);
83623
83642
  }
83624
- let recovered = 0;
83643
+ let killed = 0;
83625
83644
  let cleaned = 0;
83626
83645
  for (const { chatroomId, role, entry } of entries2) {
83627
- const key = agentKey2(chatroomId, role);
83628
- let alive = false;
83629
- try {
83630
- this.deps.processes.kill(entry.pid, 0);
83631
- alive = true;
83632
- } catch {
83633
- alive = false;
83634
- }
83635
- if (alive) {
83636
- this.slots.set(key, {
83637
- state: "running",
83646
+ if (isProcessAlive(this.deps.processes.kill, entry.pid)) {
83647
+ await this.stopPersistedProcess(entry.pid, entry.harness);
83648
+ const exitArgs = {
83649
+ sessionId: this.deps.sessionId,
83650
+ machineId: this.deps.machineId,
83651
+ chatroomId,
83652
+ role,
83638
83653
  pid: entry.pid,
83639
- harness: entry.harness,
83640
- wantResume: true
83654
+ stopReason: "daemon.shutdown",
83655
+ exitCode: undefined,
83656
+ signal: undefined,
83657
+ agentHarness: entry.harness
83658
+ };
83659
+ this.deps.backend.mutation(api.machines.recordAgentExited, exitArgs).catch((err) => {
83660
+ console.log(` ⚠️ Failed to record agent exit on recovery: ${err.message}`);
83661
+ this.queueExitRetry({ role, args: exitArgs });
83641
83662
  });
83642
- recovered++;
83663
+ try {
83664
+ await this.deps.persistence.clearAgentPid(this.deps.machineId, chatroomId, role);
83665
+ } catch {}
83666
+ killed++;
83643
83667
  } else {
83644
- this.deps.persistence.clearAgentPid(this.deps.machineId, chatroomId, role);
83668
+ try {
83669
+ await this.deps.persistence.clearAgentPid(this.deps.machineId, chatroomId, role);
83670
+ } catch {}
83645
83671
  cleaned++;
83646
83672
  }
83647
83673
  }
83648
- console.log(`[AgentProcessManager] Recovery: ${recovered} alive, ${cleaned} cleaned up`);
83674
+ console.log(`[AgentProcessManager] Recovery: ${killed} killed, ${cleaned} cleaned up`);
83649
83675
  }
83650
83676
  getOrCreateSlot(key) {
83651
83677
  let slot = this.slots.get(key);
@@ -83655,6 +83681,82 @@ class AgentProcessManager {
83655
83681
  }
83656
83682
  return slot;
83657
83683
  }
83684
+ async stopPersistedProcess(pid, harness) {
83685
+ const service = this.deps.agentServices.get(harness);
83686
+ if (service) {
83687
+ try {
83688
+ await service.stop(pid);
83689
+ service.untrack(pid);
83690
+ } catch {}
83691
+ } else {
83692
+ try {
83693
+ this.deps.processes.kill(-pid, "SIGTERM");
83694
+ } catch {}
83695
+ for (const svc of this.deps.agentServices.values()) {
83696
+ svc.untrack(pid);
83697
+ }
83698
+ }
83699
+ untrackChildPid(pid);
83700
+ }
83701
+ async killExistingBeforeSpawn(chatroomId, role) {
83702
+ const key = agentKey2(chatroomId, role);
83703
+ const slot = this.slots.get(key);
83704
+ if (slot?.pid && isProcessAlive(this.deps.processes.kill, slot.pid) && (slot.state === "running" || slot.state === "spawning")) {
83705
+ const pid2 = slot.pid;
83706
+ slot.state = "stopping";
83707
+ await this.doStop(key, slot, pid2, { chatroomId, role, reason: "daemon.respawn" });
83708
+ }
83709
+ let entries2 = [];
83710
+ try {
83711
+ entries2 = await this.deps.persistence.listAgentEntries(this.deps.machineId);
83712
+ } catch {
83713
+ return;
83714
+ }
83715
+ const persisted = entries2.find((e) => e.chatroomId === chatroomId && e.role.toLowerCase() === role.toLowerCase());
83716
+ if (!persisted) {
83717
+ return;
83718
+ }
83719
+ const { pid, harness } = persisted.entry;
83720
+ if (!isProcessAlive(this.deps.processes.kill, pid)) {
83721
+ try {
83722
+ await this.deps.persistence.clearAgentPid(this.deps.machineId, chatroomId, role);
83723
+ } catch {}
83724
+ return;
83725
+ }
83726
+ const currentSlot = this.slots.get(key);
83727
+ if (currentSlot?.pid === pid && currentSlot.state !== "idle") {
83728
+ return;
83729
+ }
83730
+ await this.stopPersistedProcess(pid, harness);
83731
+ const exitArgs = {
83732
+ sessionId: this.deps.sessionId,
83733
+ machineId: this.deps.machineId,
83734
+ chatroomId,
83735
+ role,
83736
+ pid,
83737
+ stopReason: "daemon.respawn",
83738
+ exitCode: undefined,
83739
+ signal: undefined,
83740
+ agentHarness: harness
83741
+ };
83742
+ this.deps.backend.mutation(api.machines.recordAgentExited, exitArgs).catch((err) => {
83743
+ console.log(` ⚠️ Failed to record agent exit before respawn: ${err.message}`);
83744
+ this.queueExitRetry({ role, args: exitArgs });
83745
+ });
83746
+ try {
83747
+ await this.deps.persistence.clearAgentPid(this.deps.machineId, chatroomId, role);
83748
+ } catch {}
83749
+ }
83750
+ async executeEnsureRunning(key, slot, opts) {
83751
+ try {
83752
+ await this.killExistingBeforeSpawn(opts.chatroomId, opts.role);
83753
+ return await this.doEnsureRunning(key, slot, opts);
83754
+ } finally {
83755
+ if (slot.pendingOperation) {
83756
+ slot.pendingOperation = undefined;
83757
+ }
83758
+ }
83759
+ }
83658
83760
  queueExitRetry(item) {
83659
83761
  this.exitRetryQueue.push(item);
83660
83762
  if (this.exitRetryTimer === null) {
@@ -83740,12 +83842,6 @@ class AgentProcessManager {
83740
83842
  slot.pendingOperation = undefined;
83741
83843
  return { success: false, error: `Working directory does not exist: ${opts.workingDir}` };
83742
83844
  }
83743
- if (slot.pid) {
83744
- try {
83745
- this.deps.processes.kill(-slot.pid, "SIGTERM");
83746
- } catch {}
83747
- slot.pid = undefined;
83748
- }
83749
83845
  let initPromptResult;
83750
83846
  try {
83751
83847
  initPromptResult = await this.deps.backend.query(api.messages.getInitPrompt, {
@@ -83865,9 +83961,7 @@ class AgentProcessManager {
83865
83961
  let dead = false;
83866
83962
  for (let i2 = 0;i2 < 20; i2++) {
83867
83963
  await this.deps.clock.delay(500);
83868
- try {
83869
- this.deps.processes.kill(pid, 0);
83870
- } catch {
83964
+ if (!isProcessAlive(this.deps.processes.kill, pid)) {
83871
83965
  dead = true;
83872
83966
  break;
83873
83967
  }
@@ -83878,9 +83972,7 @@ class AgentProcessManager {
83878
83972
  } catch {}
83879
83973
  for (let i2 = 0;i2 < 10; i2++) {
83880
83974
  await this.deps.clock.delay(500);
83881
- try {
83882
- this.deps.processes.kill(pid, 0);
83883
- } catch {
83975
+ if (!isProcessAlive(this.deps.processes.kill, pid)) {
83884
83976
  dead = true;
83885
83977
  break;
83886
83978
  }
@@ -83918,6 +84010,7 @@ class AgentProcessManager {
83918
84010
  }
83919
84011
  var AGENT_EXIT_RETRY_INTERVAL_MS = 1e4;
83920
84012
  var init_agent_process_manager = __esm(() => {
84013
+ init_orphan_tracker();
83921
84014
  init_api3();
83922
84015
  init_types();
83923
84016
  init_generator();
@@ -86504,4 +86597,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
86504
86597
  });
86505
86598
  program2.parse();
86506
86599
 
86507
- //# debugId=1017D812F7A83DCE64756E2164756E21
86600
+ //# debugId=4BF4F3B3AF6C84CB64756E2164756E21