chatroom-cli 1.49.0 → 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
@@ -27494,9 +27494,6 @@ class CursorSdkStreamAdapter {
27494
27494
  case "status":
27495
27495
  process.stdout.write(`${this.logPrefix} status: ${message.status}]
27496
27496
  `);
27497
- if (TERMINAL_STATUS.has(message.status)) {
27498
- this.emitAgentEnd();
27499
- }
27500
27497
  break;
27501
27498
  case "thinking":
27502
27499
  process.stdout.write(`${this.logPrefix} thinking] ${message.text}
@@ -27512,6 +27509,9 @@ class CursorSdkStreamAdapter {
27512
27509
  break;
27513
27510
  }
27514
27511
  }
27512
+ flushPendingOutput() {
27513
+ this.flushText();
27514
+ }
27515
27515
  finish() {
27516
27516
  this.flushText();
27517
27517
  this.emitAgentEnd();
@@ -27553,10 +27553,6 @@ class CursorSdkStreamAdapter {
27553
27553
  cb();
27554
27554
  }
27555
27555
  }
27556
- var TERMINAL_STATUS;
27557
- var init_cursor_sdk_stream_adapter = __esm(() => {
27558
- TERMINAL_STATUS = new Set(["FINISHED", "ERROR", "CANCELLED"]);
27559
- });
27560
27556
 
27561
27557
  // src/infrastructure/services/remote-agents/cursor-sdk/cursor-sdk-agent-service.ts
27562
27558
  import { readFileSync as readFileSync2 } from "node:fs";
@@ -27634,7 +27630,6 @@ var init_cursor_sdk_agent_service = __esm(() => {
27634
27630
  init_base_cli_agent_service();
27635
27631
  init_detection_result();
27636
27632
  init_cursor_models();
27637
- init_cursor_sdk_stream_adapter();
27638
27633
  CursorSdkAgentService = class CursorSdkAgentService extends BaseCLIAgentService {
27639
27634
  id = "cursor-sdk";
27640
27635
  displayName = "Cursor (SDK)";
@@ -27790,6 +27785,10 @@ ${options.prompt}` : options.prompt;
27790
27785
  for (const cb of outputCallbacks)
27791
27786
  cb();
27792
27787
  });
27788
+ adapter.onAgentEnd(() => {
27789
+ for (const cb of agentEndCallbacks)
27790
+ cb();
27791
+ });
27793
27792
  for await (const message of run3.stream()) {
27794
27793
  if (session.aborted)
27795
27794
  break;
@@ -27801,15 +27800,14 @@ ${options.prompt}` : options.prompt;
27801
27800
  break;
27802
27801
  }
27803
27802
  const result = await withTimeout(run3.wait(), RUN_WAIT_TIMEOUT_MS, "run.wait");
27804
- adapter.finish();
27803
+ adapter.flushPendingOutput();
27805
27804
  if (result.status === "error") {
27806
27805
  exitCode = 2;
27807
27806
  process.stderr.write(`${logPrefix} run-error] run ${result.id} failed
27808
27807
  `);
27809
27808
  break;
27810
27809
  }
27811
- for (const cb of agentEndCallbacks)
27812
- cb();
27810
+ adapter.finish();
27813
27811
  const resumePrompt = await waitForResumeOrAbort(session);
27814
27812
  if (resumePrompt === null || session.aborted) {
27815
27813
  if (session.aborted) {
@@ -27857,7 +27855,6 @@ ${options.prompt}` : options.prompt;
27857
27855
  // src/infrastructure/services/remote-agents/cursor-sdk/index.ts
27858
27856
  var init_cursor_sdk = __esm(() => {
27859
27857
  init_cursor_sdk_agent_service();
27860
- init_cursor_sdk_stream_adapter();
27861
27858
  });
27862
27859
 
27863
27860
  // ../../node_modules/.pnpm/@opencode-ai+sdk@1.15.11/node_modules/@opencode-ai/sdk/dist/gen/types.gen.js
@@ -30143,6 +30140,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
30143
30140
  } catch (err) {
30144
30141
  console.warn(`[opencode-sdk] session.abort for pid=${pid} sessionId=${meta.sessionId} failed (continuing with SIGTERM):`, err instanceof Error ? err.message : err);
30145
30142
  }
30143
+ this.sessionStore.remove(meta.sessionId);
30146
30144
  }
30147
30145
  await super.stop(pid);
30148
30146
  }
@@ -83330,6 +83328,16 @@ var init_crash_loop_tracker = __esm(() => {
83330
83328
  ];
83331
83329
  });
83332
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
+
83333
83341
  // src/infrastructure/machine/stop-reason.ts
83334
83342
  function resolveStopReason(code2, signal) {
83335
83343
  if (signal !== null)
@@ -83452,16 +83460,24 @@ class AgentProcessManager {
83452
83460
  async ensureRunning(opts) {
83453
83461
  const key = agentKey2(opts.chatroomId, opts.role);
83454
83462
  const slot = this.getOrCreateSlot(key);
83455
- if (slot.state === "running") {
83456
- return { success: true, pid: slot.pid };
83457
- }
83458
- if (slot.state === "spawning" && slot.pendingOperation) {
83459
- 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;
83460
83472
  }
83461
- if (slot.state === "stopping" && slot.pendingOperation) {
83462
- await slot.pendingOperation;
83473
+ if (slot.pendingOperation) {
83474
+ if (slot.state === "stopping") {
83475
+ await slot.pendingOperation;
83476
+ } else {
83477
+ return slot.pendingOperation;
83478
+ }
83463
83479
  }
83464
- const operation = this.doEnsureRunning(key, slot, opts);
83480
+ const operation = this.executeEnsureRunning(key, slot, opts);
83465
83481
  slot.pendingOperation = operation;
83466
83482
  return operation;
83467
83483
  }
@@ -83624,31 +83640,38 @@ class AgentProcessManager {
83624
83640
  } catch (err) {
83625
83641
  console.warn(`[AgentProcessManager] ⚠️ Failed to load persisted agent entries: ${err.message}`);
83626
83642
  }
83627
- let recovered = 0;
83643
+ let killed = 0;
83628
83644
  let cleaned = 0;
83629
83645
  for (const { chatroomId, role, entry } of entries2) {
83630
- const key = agentKey2(chatroomId, role);
83631
- let alive = false;
83632
- try {
83633
- this.deps.processes.kill(entry.pid, 0);
83634
- alive = true;
83635
- } catch {
83636
- alive = false;
83637
- }
83638
- if (alive) {
83639
- this.slots.set(key, {
83640
- 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,
83641
83653
  pid: entry.pid,
83642
- harness: entry.harness,
83643
- 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 });
83644
83662
  });
83645
- recovered++;
83663
+ try {
83664
+ await this.deps.persistence.clearAgentPid(this.deps.machineId, chatroomId, role);
83665
+ } catch {}
83666
+ killed++;
83646
83667
  } else {
83647
- this.deps.persistence.clearAgentPid(this.deps.machineId, chatroomId, role);
83668
+ try {
83669
+ await this.deps.persistence.clearAgentPid(this.deps.machineId, chatroomId, role);
83670
+ } catch {}
83648
83671
  cleaned++;
83649
83672
  }
83650
83673
  }
83651
- console.log(`[AgentProcessManager] Recovery: ${recovered} alive, ${cleaned} cleaned up`);
83674
+ console.log(`[AgentProcessManager] Recovery: ${killed} killed, ${cleaned} cleaned up`);
83652
83675
  }
83653
83676
  getOrCreateSlot(key) {
83654
83677
  let slot = this.slots.get(key);
@@ -83658,6 +83681,82 @@ class AgentProcessManager {
83658
83681
  }
83659
83682
  return slot;
83660
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
+ }
83661
83760
  queueExitRetry(item) {
83662
83761
  this.exitRetryQueue.push(item);
83663
83762
  if (this.exitRetryTimer === null) {
@@ -83743,12 +83842,6 @@ class AgentProcessManager {
83743
83842
  slot.pendingOperation = undefined;
83744
83843
  return { success: false, error: `Working directory does not exist: ${opts.workingDir}` };
83745
83844
  }
83746
- if (slot.pid) {
83747
- try {
83748
- this.deps.processes.kill(-slot.pid, "SIGTERM");
83749
- } catch {}
83750
- slot.pid = undefined;
83751
- }
83752
83845
  let initPromptResult;
83753
83846
  try {
83754
83847
  initPromptResult = await this.deps.backend.query(api.messages.getInitPrompt, {
@@ -83868,9 +83961,7 @@ class AgentProcessManager {
83868
83961
  let dead = false;
83869
83962
  for (let i2 = 0;i2 < 20; i2++) {
83870
83963
  await this.deps.clock.delay(500);
83871
- try {
83872
- this.deps.processes.kill(pid, 0);
83873
- } catch {
83964
+ if (!isProcessAlive(this.deps.processes.kill, pid)) {
83874
83965
  dead = true;
83875
83966
  break;
83876
83967
  }
@@ -83881,9 +83972,7 @@ class AgentProcessManager {
83881
83972
  } catch {}
83882
83973
  for (let i2 = 0;i2 < 10; i2++) {
83883
83974
  await this.deps.clock.delay(500);
83884
- try {
83885
- this.deps.processes.kill(pid, 0);
83886
- } catch {
83975
+ if (!isProcessAlive(this.deps.processes.kill, pid)) {
83887
83976
  dead = true;
83888
83977
  break;
83889
83978
  }
@@ -83921,6 +84010,7 @@ class AgentProcessManager {
83921
84010
  }
83922
84011
  var AGENT_EXIT_RETRY_INTERVAL_MS = 1e4;
83923
84012
  var init_agent_process_manager = __esm(() => {
84013
+ init_orphan_tracker();
83924
84014
  init_api3();
83925
84015
  init_types();
83926
84016
  init_generator();
@@ -86507,4 +86597,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
86507
86597
  });
86508
86598
  program2.parse();
86509
86599
 
86510
- //# debugId=2DBCEF13548BACBB64756E2164756E21
86600
+ //# debugId=4BF4F3B3AF6C84CB64756E2164756E21