chatroom-cli 1.102.0 → 1.102.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
@@ -27764,6 +27764,30 @@ var init_base_cli_agent_service = __esm(() => {
27764
27764
  retrySchedule = exports_Schedule.exponential(exports_Duration.millis(DETECTION_RETRY_POLICY.initialDelayMs), DETECTION_RETRY_POLICY.backoffFactor).pipe(exports_Schedule.either(exports_Schedule.spaced(exports_Duration.millis(DETECTION_RETRY_POLICY.maxDelayMs))), exports_Schedule.compose(exports_Schedule.recurs(DETECTION_RETRY_POLICY.maxAttempts - 1)));
27765
27765
  });
27766
27766
 
27767
+ // src/daemon/infrastructure/agent-process-manager/harness-activity-emitter.ts
27768
+ function createHarnessActivityEmitter() {
27769
+ let progressReportedForTurn = false;
27770
+ const listeners = new Set;
27771
+ return {
27772
+ beginTurn: () => {
27773
+ progressReportedForTurn = false;
27774
+ },
27775
+ emit: (event) => {
27776
+ const isFirstForTurn = event.kind === "progress" && !progressReportedForTurn;
27777
+ if (event.kind === "progress")
27778
+ progressReportedForTurn = true;
27779
+ const signal = { ...event, isFirstForTurn };
27780
+ for (const cb of listeners)
27781
+ cb(signal);
27782
+ },
27783
+ onActivity: (cb) => {
27784
+ listeners.add(cb);
27785
+ return () => listeners.delete(cb);
27786
+ }
27787
+ };
27788
+ }
27789
+ var init_harness_activity_emitter = () => {};
27790
+
27767
27791
  // src/daemon/infrastructure/local/harness/services/session-log-callbacks.ts
27768
27792
  function createSessionLogCallbacks() {
27769
27793
  let logCb;
@@ -27779,6 +27803,7 @@ function createSessionLogCallbacks() {
27779
27803
  // src/daemon/infrastructure/local/harness/services/opencode/opencode-agent-service.ts
27780
27804
  var OPENCODE_COMMAND = "opencode", OpenCodeAgentService;
27781
27805
  var init_opencode_agent_service = __esm(() => {
27806
+ init_harness_activity_emitter();
27782
27807
  init_base_cli_agent_service();
27783
27808
  OpenCodeAgentService = class OpenCodeAgentService extends BaseCLIAgentService {
27784
27809
  id = "opencode";
@@ -27808,6 +27833,8 @@ var init_opencode_agent_service = __esm(() => {
27808
27833
  const fullPrompt = options.systemPrompt ? `${options.systemPrompt}
27809
27834
 
27810
27835
  ${options.prompt}` : options.prompt;
27836
+ const activityEmitter = createHarnessActivityEmitter();
27837
+ activityEmitter.beginTurn();
27811
27838
  const childProcess = this.deps.spawn(OPENCODE_COMMAND, args2, {
27812
27839
  cwd: options.workingDir,
27813
27840
  stdio: ["pipe", "pipe", "pipe"],
@@ -27822,9 +27849,18 @@ ${options.prompt}` : options.prompt;
27822
27849
  const entry = this.registerProcess(pid, context5);
27823
27850
  const { onLogLine, emitFormatted } = createSessionLogCallbacks();
27824
27851
  const outputCallbacks = [];
27852
+ let processFailureEmitted = false;
27853
+ const emitActivity = (kind, source) => {
27854
+ activityEmitter.emit({ kind, source, at: Date.now() });
27855
+ };
27825
27856
  if (childProcess.stdout) {
27826
27857
  childProcess.stdout.on("data", (chunk2) => {
27827
- emitFormatted(chunk2.toString("utf8"), "stdout");
27858
+ const text = chunk2.toString("utf8");
27859
+ emitActivity("transport", "opencode-cli.stdout");
27860
+ if (text.trim().length > 0) {
27861
+ emitActivity("progress", "opencode-cli.assistant.text");
27862
+ }
27863
+ emitFormatted(text, "stdout");
27828
27864
  entry.lastOutputAt = Date.now();
27829
27865
  for (const cb of outputCallbacks)
27830
27866
  cb();
@@ -27832,6 +27868,7 @@ ${options.prompt}` : options.prompt;
27832
27868
  }
27833
27869
  if (childProcess.stderr) {
27834
27870
  childProcess.stderr.on("data", (chunk2) => {
27871
+ emitActivity("transport", "opencode-cli.stderr");
27835
27872
  emitFormatted(chunk2.toString("utf8"), "stderr");
27836
27873
  entry.lastOutputAt = Date.now();
27837
27874
  for (const cb of outputCallbacks)
@@ -27840,9 +27877,14 @@ ${options.prompt}` : options.prompt;
27840
27877
  }
27841
27878
  return {
27842
27879
  pid,
27880
+ activityEmitter,
27843
27881
  onExit: (cb) => {
27844
27882
  childProcess.on("exit", (code2, signal) => {
27845
27883
  this.deleteProcess(pid);
27884
+ if (!processFailureEmitted && (code2 !== null && code2 !== 0 || signal !== null)) {
27885
+ processFailureEmitted = true;
27886
+ emitActivity("failure", "opencode-cli.process");
27887
+ }
27846
27888
  cb({ code: code2, signal, context: context5 });
27847
27889
  });
27848
27890
  },
@@ -27906,10 +27948,19 @@ class PiRpcReader {
27906
27948
  } catch {
27907
27949
  return;
27908
27950
  }
27951
+ const metadata = {
27952
+ type: typeof event["type"] === "string" ? event["type"] : "unknown",
27953
+ isError: this._isErrorEvent(event)
27954
+ };
27909
27955
  for (const cb of this.anyEventCallbacks)
27910
- cb();
27956
+ cb(metadata);
27911
27957
  this._dispatchEvent(event);
27912
27958
  }
27959
+ _isErrorEvent(event) {
27960
+ if (event["is_error"] === true || event["isError"] === true)
27961
+ return true;
27962
+ return "error" in event && event["error"] !== undefined;
27963
+ }
27913
27964
  eventHandlers = {
27914
27965
  response: (event) => {
27915
27966
  if (event["command"] === "get_state")
@@ -28066,6 +28117,14 @@ var BASH_TOOL_KIND = "tool: bash", BASH_RUNNING_PREFIX = "running:";
28066
28117
 
28067
28118
  // src/daemon/infrastructure/local/harness/services/pi/pi-agent-service.ts
28068
28119
  import { join as join6 } from "node:path";
28120
+ function isExplicitToolError(result) {
28121
+ if (result === null || typeof result !== "object")
28122
+ return false;
28123
+ const obj = result;
28124
+ if (obj.is_error === true || obj.isError === true)
28125
+ return true;
28126
+ return "error" in obj && obj.error !== undefined;
28127
+ }
28069
28128
  function getPiSessionDir(workingDir) {
28070
28129
  return join6(workingDir, ".chatroom", "pi-sessions");
28071
28130
  }
@@ -28073,6 +28132,7 @@ var PI_COMMAND = "pi", GET_STATE_TIMEOUT_MS = 5000, SPAWN_READY_DELAY_MS2 = 500,
28073
28132
  var init_pi_agent_service = __esm(() => {
28074
28133
  init_pi_rpc_reader();
28075
28134
  init_spawn_env();
28135
+ init_harness_activity_emitter();
28076
28136
  init_base_cli_agent_service();
28077
28137
  PiAgentService = class PiAgentService extends BaseCLIAgentService {
28078
28138
  id = "pi";
@@ -28120,14 +28180,17 @@ var init_pi_agent_service = __esm(() => {
28120
28180
  if (!childProcess.stdout) {
28121
28181
  throw new Error("Pi RPC process has no stdout");
28122
28182
  }
28183
+ const activityEmitter = createHarnessActivityEmitter();
28123
28184
  const reader = new PiRpcReader(childProcess.stdout);
28124
28185
  const harnessSessionId = await this.querySessionId(reader, childProcess.stdin);
28186
+ activityEmitter.beginTurn();
28125
28187
  await this.writePrompt(childProcess, prompt);
28126
28188
  return this.wireRpcProcess({
28127
28189
  childProcess,
28128
28190
  context: context5,
28129
28191
  harnessSessionId,
28130
- reader
28192
+ reader,
28193
+ activityEmitter
28131
28194
  });
28132
28195
  }
28133
28196
  spawnPiRpcProcess(args2) {
@@ -28184,7 +28247,7 @@ var init_pi_agent_service = __esm(() => {
28184
28247
  });
28185
28248
  }
28186
28249
  wireRpcProcess(args2) {
28187
- const { childProcess, context: context5, harnessSessionId } = args2;
28250
+ const { childProcess, context: context5, harnessSessionId, activityEmitter } = args2;
28188
28251
  const pid = childProcess.pid;
28189
28252
  if (pid == null) {
28190
28253
  throw new Error("Pi RPC process has no PID");
@@ -28216,12 +28279,17 @@ var init_pi_agent_service = __esm(() => {
28216
28279
  const baseResult = {
28217
28280
  pid,
28218
28281
  harnessSessionId,
28282
+ activityEmitter,
28219
28283
  onExit: onExit4,
28220
28284
  onOutput,
28221
28285
  onLogLine
28222
28286
  };
28223
28287
  const log4 = createAgentLogWriter(logPrefix, { emitLogLine, suppressConsole: true });
28288
+ const emitActivity = (kind, source) => {
28289
+ activityEmitter.emit({ kind, source, at: Date.now() });
28290
+ };
28224
28291
  const onStderrData = (chunk2) => {
28292
+ emitActivity("transport", "pi-cli.stderr");
28225
28293
  entry.lastOutputAt = Date.now();
28226
28294
  for (const cb of outputCallbacks)
28227
28295
  cb();
@@ -28256,6 +28324,7 @@ var init_pi_agent_service = __esm(() => {
28256
28324
  cb();
28257
28325
  };
28258
28326
  reader.onTextDelta((delta) => {
28327
+ emitActivity("progress", "pi-cli.assistant.text");
28259
28328
  flushThinking();
28260
28329
  textBuffer += delta;
28261
28330
  if (textBuffer.includes(`
@@ -28264,6 +28333,7 @@ var init_pi_agent_service = __esm(() => {
28264
28333
  notifyOutput();
28265
28334
  });
28266
28335
  reader.onThinkingDelta((delta) => {
28336
+ emitActivity("progress", "pi-cli.assistant.thinking");
28267
28337
  flushText();
28268
28338
  thinkingBuffer += delta;
28269
28339
  if (thinkingBuffer.includes(`
@@ -28271,8 +28341,12 @@ var init_pi_agent_service = __esm(() => {
28271
28341
  flushThinking();
28272
28342
  notifyOutput();
28273
28343
  });
28274
- reader.onAnyEvent(() => {
28344
+ reader.onAnyEvent((metadata) => {
28275
28345
  notifyOutput();
28346
+ emitActivity("transport", "pi-cli.message");
28347
+ if (metadata.isError) {
28348
+ emitActivity("failure", "pi-cli.message");
28349
+ }
28276
28350
  });
28277
28351
  reader.onAgentEnd(() => {
28278
28352
  flushText();
@@ -28282,6 +28356,8 @@ var init_pi_agent_service = __esm(() => {
28282
28356
  cb();
28283
28357
  });
28284
28358
  reader.onToolCall((name, toolArgs) => {
28359
+ emitActivity("progress", "pi-cli.tool-call");
28360
+ emitActivity("waiting", "pi-cli.tool-call");
28285
28361
  flushText();
28286
28362
  flushThinking();
28287
28363
  const bashCmd = resolveBashCommandForLog(name, toolArgs);
@@ -28293,6 +28369,10 @@ var init_pi_agent_service = __esm(() => {
28293
28369
  log4.write("tool", `${name}${argsStr}`);
28294
28370
  });
28295
28371
  reader.onToolResult((name, result) => {
28372
+ emitActivity("progress", "pi-cli.tool-result");
28373
+ if (isExplicitToolError(result)) {
28374
+ emitActivity("failure", "pi-cli.tool-result");
28375
+ }
28296
28376
  const resultStr = typeof result === "string" ? result : JSON.stringify(result);
28297
28377
  log4.write("tool_result", `${name} result: ${resultStr}`);
28298
28378
  });
@@ -28353,10 +28433,23 @@ class CursorStreamReader {
28353
28433
  } catch {
28354
28434
  return;
28355
28435
  }
28436
+ const metadata = {
28437
+ type: typeof event["type"] === "string" ? event["type"] : "unknown",
28438
+ subtype: typeof event["subtype"] === "string" ? event["subtype"] : undefined,
28439
+ isError: this._isErrorEvent(event)
28440
+ };
28356
28441
  for (const cb of this.anyEventCallbacks)
28357
- cb();
28442
+ cb(metadata);
28358
28443
  this._dispatchEvent(event);
28359
28444
  }
28445
+ _isErrorEvent(event) {
28446
+ if (event["is_error"] === true)
28447
+ return true;
28448
+ if (event["type"] === "result") {
28449
+ return event["subtype"] !== "success";
28450
+ }
28451
+ return false;
28452
+ }
28360
28453
  _dispatchEvent(event) {
28361
28454
  const type = event["type"];
28362
28455
  if (type === "assistant") {
@@ -28766,6 +28859,14 @@ var init_cursor_models = __esm(() => {
28766
28859
  });
28767
28860
 
28768
28861
  // src/daemon/infrastructure/local/harness/services/cursor/cursor-agent-service.ts
28862
+ function isExplicitToolError2(toolCall) {
28863
+ if (toolCall === null || typeof toolCall !== "object")
28864
+ return false;
28865
+ const obj = toolCall;
28866
+ if (obj.is_error === true || obj.isError === true)
28867
+ return true;
28868
+ return "error" in obj && obj.error !== undefined;
28869
+ }
28769
28870
  function resolveCursorCliModel(model) {
28770
28871
  const prefix = `${CURSOR_PROVIDER2}/`;
28771
28872
  return model.startsWith(prefix) ? model.slice(prefix.length) : model;
@@ -28773,6 +28874,7 @@ function resolveCursorCliModel(model) {
28773
28874
  var CURSOR_COMMAND = "agent", CURSOR_PROVIDER2 = "cursor", NO_SUBAGENT_DIRECTIVE = "NEVER spawn subagents. Follow the chatroom instructions strictly.", CursorAgentService;
28774
28875
  var init_cursor_agent_service = __esm(() => {
28775
28876
  init_cursor_stream_reader();
28877
+ init_harness_activity_emitter();
28776
28878
  init_base_cli_agent_service();
28777
28879
  init_cursor_models();
28778
28880
  init_cursor_sdk_model_catalog();
@@ -28804,6 +28906,8 @@ ${options.systemPrompt}` : NO_SUBAGENT_DIRECTIVE;
28804
28906
  const fullPrompt = `${systemPrompt}
28805
28907
 
28806
28908
  ${options.prompt}`;
28909
+ const activityEmitter = createHarnessActivityEmitter();
28910
+ activityEmitter.beginTurn();
28807
28911
  const childProcess = this.deps.spawn(CURSOR_COMMAND, args2, {
28808
28912
  cwd: options.workingDir,
28809
28913
  stdio: ["pipe", "pipe", "pipe"],
@@ -28828,6 +28932,9 @@ ${options.prompt}`;
28828
28932
  if (childProcess.stdout) {
28829
28933
  const reader = new CursorStreamReader(childProcess.stdout);
28830
28934
  let textBuffer = "";
28935
+ const emitActivity = (kind, source) => {
28936
+ activityEmitter.emit({ kind, source, at: Date.now() });
28937
+ };
28831
28938
  const flushText = () => {
28832
28939
  if (!textBuffer)
28833
28940
  return;
@@ -28839,6 +28946,7 @@ ${options.prompt}`;
28839
28946
  textBuffer = "";
28840
28947
  };
28841
28948
  reader.onText((text) => {
28949
+ emitActivity("progress", "cursor-cli.assistant.text");
28842
28950
  textBuffer += text;
28843
28951
  if (textBuffer.includes(`
28844
28952
  `))
@@ -28847,8 +28955,12 @@ ${options.prompt}`;
28847
28955
  for (const cb of outputCallbacks)
28848
28956
  cb();
28849
28957
  });
28850
- reader.onAnyEvent(() => {
28958
+ reader.onAnyEvent((metadata) => {
28851
28959
  entry.lastOutputAt = Date.now();
28960
+ emitActivity("transport", "cursor-cli.message");
28961
+ if (metadata.isError) {
28962
+ emitActivity("failure", "cursor-cli.message");
28963
+ }
28852
28964
  for (const cb of outputCallbacks)
28853
28965
  cb();
28854
28966
  });
@@ -28858,6 +28970,8 @@ ${options.prompt}`;
28858
28970
  `);
28859
28971
  });
28860
28972
  reader.onToolCall((callId, toolCall) => {
28973
+ emitActivity("progress", "cursor-cli.tool-call");
28974
+ emitActivity("waiting", "cursor-cli.tool-call");
28861
28975
  flushText();
28862
28976
  const bashCmd = extractBashCommandFromCursorToolCall(toolCall);
28863
28977
  if (bashCmd !== null) {
@@ -28866,7 +28980,11 @@ ${options.prompt}`;
28866
28980
  }
28867
28981
  emitLog(formatAgentLogLine(logPrefix, "tool", `${callId} ${JSON.stringify(toolCall)}`));
28868
28982
  });
28869
- reader.onToolResult((callId) => {
28983
+ reader.onToolResult((callId, toolCall) => {
28984
+ emitActivity("progress", "cursor-cli.tool-result");
28985
+ if (isExplicitToolError2(toolCall)) {
28986
+ emitActivity("failure", "cursor-cli.tool-result");
28987
+ }
28870
28988
  flushText();
28871
28989
  process.stdout.write(`${formatAgentLogLine(logPrefix, "tool_result", callId)}
28872
28990
  `);
@@ -28874,6 +28992,7 @@ ${options.prompt}`;
28874
28992
  if (childProcess.stderr) {
28875
28993
  childProcess.stderr.pipe(process.stderr, { end: false });
28876
28994
  childProcess.stderr.on("data", () => {
28995
+ activityEmitter.emit({ kind: "transport", source: "cursor-cli.stderr", at: Date.now() });
28877
28996
  entry.lastOutputAt = Date.now();
28878
28997
  for (const cb of outputCallbacks)
28879
28998
  cb();
@@ -28881,6 +29000,7 @@ ${options.prompt}`;
28881
29000
  }
28882
29001
  return {
28883
29002
  pid,
29003
+ activityEmitter,
28884
29004
  onExit: (cb) => {
28885
29005
  childProcess.on("exit", (code2, signal) => {
28886
29006
  this.deleteProcess(pid);
@@ -28899,6 +29019,7 @@ ${options.prompt}`;
28899
29019
  if (childProcess.stderr) {
28900
29020
  childProcess.stderr.pipe(process.stderr, { end: false });
28901
29021
  childProcess.stderr.on("data", () => {
29022
+ activityEmitter.emit({ kind: "transport", source: "cursor-cli.stderr", at: Date.now() });
28902
29023
  entry.lastOutputAt = Date.now();
28903
29024
  for (const cb of outputCallbacks)
28904
29025
  cb();
@@ -28906,6 +29027,7 @@ ${options.prompt}`;
28906
29027
  }
28907
29028
  return {
28908
29029
  pid,
29030
+ activityEmitter,
28909
29031
  onExit: (cb) => {
28910
29032
  childProcess.on("exit", (code2, signal) => {
28911
29033
  this.deleteProcess(pid);
@@ -28986,6 +29108,7 @@ function resolveCopilotSpawnModel(model) {
28986
29108
  var COPILOT_COMMAND = "copilot", CopilotAgentService;
28987
29109
  var init_copilot_agent_service = __esm(() => {
28988
29110
  init_model_provider();
29111
+ init_harness_activity_emitter();
28989
29112
  init_base_cli_agent_service();
28990
29113
  init_copilot_stream_reader();
28991
29114
  CopilotAgentService = class CopilotAgentService extends BaseCLIAgentService {
@@ -29013,6 +29136,8 @@ var init_copilot_agent_service = __esm(() => {
29013
29136
  }
29014
29137
  args2.push("--allow-all");
29015
29138
  args2.push(prompt);
29139
+ const activityEmitter = createHarnessActivityEmitter();
29140
+ activityEmitter.beginTurn();
29016
29141
  const childProcess = this.deps.spawn(COPILOT_COMMAND, args2, {
29017
29142
  cwd: options.workingDir,
29018
29143
  stdio: ["pipe", "pipe", "pipe"],
@@ -29028,13 +29153,19 @@ var init_copilot_agent_service = __esm(() => {
29028
29153
  const logPrefix = `[copilot:${roleTag}${chatroomSuffix}]`;
29029
29154
  const { onLogLine, emitFormatted } = createSessionLogCallbacks();
29030
29155
  const outputCallbacks = [];
29156
+ let processFailureEmitted = false;
29157
+ const emitActivity = (kind, source) => {
29158
+ activityEmitter.emit({ kind, source, at: Date.now() });
29159
+ };
29031
29160
  if (childProcess.stdout) {
29032
29161
  const reader = new CopilotStreamReader(childProcess.stdout);
29033
29162
  reader.onText((text) => {
29163
+ emitActivity("progress", "copilot-cli.assistant.text");
29034
29164
  emitFormatted(`${logPrefix} ${text}`);
29035
29165
  });
29036
29166
  reader.onAnyEvent(() => {
29037
29167
  entry.lastOutputAt = Date.now();
29168
+ emitActivity("transport", "copilot-cli.message");
29038
29169
  for (const cb of outputCallbacks)
29039
29170
  cb();
29040
29171
  });
@@ -29044,6 +29175,7 @@ var init_copilot_agent_service = __esm(() => {
29044
29175
  }
29045
29176
  if (childProcess.stderr) {
29046
29177
  childProcess.stderr.on("data", (chunk2) => {
29178
+ emitActivity("transport", "copilot-cli.stderr");
29047
29179
  emitFormatted(chunk2.toString("utf8"), "stderr");
29048
29180
  entry.lastOutputAt = Date.now();
29049
29181
  for (const cb of outputCallbacks)
@@ -29052,9 +29184,14 @@ var init_copilot_agent_service = __esm(() => {
29052
29184
  }
29053
29185
  return {
29054
29186
  pid,
29187
+ activityEmitter,
29055
29188
  onExit: (cb) => {
29056
29189
  childProcess.on("exit", (code2, signal) => {
29057
29190
  this.deleteProcess(pid);
29191
+ if (!processFailureEmitted && (code2 !== null && code2 !== 0 || signal !== null)) {
29192
+ processFailureEmitted = true;
29193
+ emitActivity("failure", "copilot-cli.process");
29194
+ }
29058
29195
  cb({ code: code2, signal, context: context5 });
29059
29196
  });
29060
29197
  },
@@ -29154,6 +29291,7 @@ class ClaudeStreamReader {
29154
29291
  thinkingCallbacks = [];
29155
29292
  endCallbacks = [];
29156
29293
  toolUseCallbacks = [];
29294
+ anyEventCallbacks = [];
29157
29295
  constructor(stream) {
29158
29296
  attachLineReader(stream, (line) => this._handleLine(line));
29159
29297
  }
@@ -29169,14 +29307,33 @@ class ClaudeStreamReader {
29169
29307
  onToolUse(cb) {
29170
29308
  this.toolUseCallbacks.push(cb);
29171
29309
  }
29310
+ onAnyEvent(cb) {
29311
+ this.anyEventCallbacks.push(cb);
29312
+ }
29172
29313
  _handleLine(line) {
29173
29314
  if (!line.trim())
29174
29315
  return;
29175
29316
  try {
29176
29317
  const event = JSON.parse(line);
29318
+ const metadata = {
29319
+ type: typeof event.type === "string" ? event.type : "unknown",
29320
+ subtype: typeof event.subtype === "string" ? event.subtype : undefined,
29321
+ isError: this._isErrorEvent(event)
29322
+ };
29323
+ for (const cb of this.anyEventCallbacks)
29324
+ cb(metadata);
29177
29325
  this._dispatchEvent(event);
29178
29326
  } catch {}
29179
29327
  }
29328
+ _isErrorEvent(event) {
29329
+ if (event.is_error === true)
29330
+ return true;
29331
+ if (event.type === "assistant") {
29332
+ const err = event.error ?? event.message?.error;
29333
+ return typeof err === "string" && err.length > 0;
29334
+ }
29335
+ return false;
29336
+ }
29180
29337
  _dispatchEvent(event) {
29181
29338
  const { type } = event;
29182
29339
  if (type === "system")
@@ -29242,6 +29399,7 @@ var CLAUDE_COMMAND = "claude", DEFAULT_MAX_TURNS = 200, ClaudeCodeAgentService;
29242
29399
  var init_claude_code_agent_service = __esm(() => {
29243
29400
  init_claude_models();
29244
29401
  init_claude_stream_reader();
29402
+ init_harness_activity_emitter();
29245
29403
  init_base_cli_agent_service();
29246
29404
  ClaudeCodeAgentService = class ClaudeCodeAgentService extends BaseCLIAgentService {
29247
29405
  id = "claude";
@@ -29275,6 +29433,8 @@ var init_claude_code_agent_service = __esm(() => {
29275
29433
  args2.push("--system-prompt", systemPrompt);
29276
29434
  }
29277
29435
  args2.push(prompt);
29436
+ const activityEmitter = createHarnessActivityEmitter();
29437
+ activityEmitter.beginTurn();
29278
29438
  const childProcess = this.deps.spawn(CLAUDE_COMMAND, args2, {
29279
29439
  cwd: options.workingDir,
29280
29440
  stdio: ["ignore", "pipe", "pipe"],
@@ -29292,6 +29452,9 @@ var init_claude_code_agent_service = __esm(() => {
29292
29452
  const reader = new ClaudeStreamReader(childProcess.stdout);
29293
29453
  let textBuffer = "";
29294
29454
  let thinkingBuffer = "";
29455
+ const emitActivity = (kind, source) => {
29456
+ activityEmitter.emit({ kind, source, at: Date.now() });
29457
+ };
29295
29458
  const flushText = () => {
29296
29459
  if (!textBuffer)
29297
29460
  return;
@@ -29313,6 +29476,7 @@ var init_claude_code_agent_service = __esm(() => {
29313
29476
  thinkingBuffer = "";
29314
29477
  };
29315
29478
  reader.onText((text) => {
29479
+ emitActivity("progress", "claude-cli.assistant.text");
29316
29480
  entry.lastOutputAt = Date.now();
29317
29481
  textBuffer += text;
29318
29482
  if (text.includes(`
@@ -29325,6 +29489,7 @@ var init_claude_code_agent_service = __esm(() => {
29325
29489
  cb();
29326
29490
  });
29327
29491
  reader.onThinking((thinking) => {
29492
+ emitActivity("progress", "claude-cli.assistant.thinking");
29328
29493
  entry.lastOutputAt = Date.now();
29329
29494
  thinkingBuffer += thinking;
29330
29495
  if (thinking.includes(`
@@ -29337,6 +29502,8 @@ var init_claude_code_agent_service = __esm(() => {
29337
29502
  cb();
29338
29503
  });
29339
29504
  reader.onToolUse((name, input) => {
29505
+ emitActivity("progress", "claude-cli.tool-use");
29506
+ emitActivity("waiting", "claude-cli.tool-use");
29340
29507
  entry.lastOutputAt = Date.now();
29341
29508
  const bashCmd = extractBashCommandFromToolInput(name, input);
29342
29509
  if (bashCmd !== null) {
@@ -29357,9 +29524,19 @@ var init_claude_code_agent_service = __esm(() => {
29357
29524
  for (const cb of outputCallbacks)
29358
29525
  cb();
29359
29526
  });
29527
+ reader.onAnyEvent((metadata) => {
29528
+ entry.lastOutputAt = Date.now();
29529
+ emitActivity("transport", "claude-cli.message");
29530
+ if (metadata.isError) {
29531
+ emitActivity("failure", "claude-cli.message");
29532
+ }
29533
+ for (const cb of outputCallbacks)
29534
+ cb();
29535
+ });
29360
29536
  }
29361
29537
  if (childProcess.stderr) {
29362
29538
  childProcess.stderr.on("data", (chunk2) => {
29539
+ activityEmitter.emit({ kind: "transport", source: "claude-cli.stderr", at: Date.now() });
29363
29540
  emitFormatted(chunk2.toString("utf8"), "stderr");
29364
29541
  entry.lastOutputAt = Date.now();
29365
29542
  for (const cb of outputCallbacks)
@@ -29368,6 +29545,7 @@ var init_claude_code_agent_service = __esm(() => {
29368
29545
  }
29369
29546
  return {
29370
29547
  pid,
29548
+ activityEmitter,
29371
29549
  onExit: (cb) => {
29372
29550
  childProcess.on("exit", (code2, signal) => {
29373
29551
  this.deleteProcess(pid);
@@ -29528,9 +29706,11 @@ class NativeStreamAdapterBase {
29528
29706
  outputCallbacks = [];
29529
29707
  agentEndEmitted = false;
29530
29708
  assistantTextCapture = createAssistantTextCapture();
29531
- constructor(logPrefix, emitLogLine) {
29709
+ activityEmitter;
29710
+ constructor(logPrefix, emitLogLine, activityEmitter = createHarnessActivityEmitter()) {
29532
29711
  this.logPrefix = logPrefix;
29533
29712
  this.emitLogLine = emitLogLine;
29713
+ this.activityEmitter = activityEmitter;
29534
29714
  }
29535
29715
  setAssistantTextCapture(cb) {
29536
29716
  this.assistantTextCapture.setAssistantTextCapture(cb);
@@ -29541,15 +29721,43 @@ class NativeStreamAdapterBase {
29541
29721
  onOutput(cb) {
29542
29722
  this.outputCallbacks.push(cb);
29543
29723
  }
29544
- notifyOutput() {
29724
+ notifyOutput(source = "native-sdk.event") {
29725
+ this.activityEmitter.emit({
29726
+ kind: "transport",
29727
+ source,
29728
+ at: Date.now()
29729
+ });
29545
29730
  for (const cb of this.outputCallbacks)
29546
29731
  cb();
29547
29732
  }
29733
+ notifyProgress(source) {
29734
+ this.activityEmitter.emit({
29735
+ kind: "progress",
29736
+ source,
29737
+ at: Date.now()
29738
+ });
29739
+ }
29740
+ notifyWaiting(source) {
29741
+ this.activityEmitter.emit({
29742
+ kind: "waiting",
29743
+ source,
29744
+ at: Date.now()
29745
+ });
29746
+ }
29747
+ notifyFailure(source) {
29748
+ this.activityEmitter.emit({
29749
+ kind: "failure",
29750
+ source,
29751
+ at: Date.now()
29752
+ });
29753
+ }
29548
29754
  writeLine(line) {
29549
29755
  this.emitLogLine?.(line);
29550
29756
  }
29551
29757
  }
29552
- var init_native_stream_adapter_base = () => {};
29758
+ var init_native_stream_adapter_base = __esm(() => {
29759
+ init_harness_activity_emitter();
29760
+ });
29553
29761
 
29554
29762
  // src/daemon/infrastructure/local/harness/services/claude-sdk/claude-sdk-stream-adapter.ts
29555
29763
  var ClaudeSdkStreamAdapter;
@@ -29558,29 +29766,39 @@ var init_claude_sdk_stream_adapter = __esm(() => {
29558
29766
  ClaudeSdkStreamAdapter = class ClaudeSdkStreamAdapter extends NativeStreamAdapterBase {
29559
29767
  textBuffer = "";
29560
29768
  thinkingBuffer = "";
29769
+ constructor(logPrefix, emitLogLine, activityEmitter) {
29770
+ super(logPrefix, emitLogLine, activityEmitter);
29771
+ }
29561
29772
  handleMessage(message) {
29562
- this.notifyOutput();
29773
+ this.notifyOutput("claude-sdk.message");
29563
29774
  switch (message.type) {
29564
29775
  case "stream_event":
29565
29776
  this.handleStreamEvent(message);
29566
29777
  break;
29567
29778
  case "assistant":
29779
+ this.notifyProgress("claude-sdk.assistant");
29780
+ if (message.error) {
29781
+ this.notifyFailure("claude-sdk.assistant");
29782
+ }
29568
29783
  this.handleAssistant(message);
29569
29784
  break;
29570
29785
  case "user":
29571
29786
  this.handleUser(message);
29572
29787
  break;
29573
29788
  case "system":
29574
- if (message.subtype === "init") {
29575
- this.writeLine(formatAgentLogLine(this.logPrefix, "system: init"));
29576
- }
29789
+ this.handleSystem(message);
29577
29790
  break;
29578
29791
  case "result":
29579
29792
  if (message.is_error) {
29793
+ this.notifyFailure("claude-sdk.result");
29580
29794
  const errors2 = "errors" in message && Array.isArray(message.errors) ? message.errors.join("; ") : "turn failed";
29581
29795
  this.writeLine(formatAgentLogLine(this.logPrefix, "run-error", errors2));
29582
29796
  }
29583
29797
  break;
29798
+ case "tool_progress":
29799
+ this.notifyProgress("claude-sdk.tool-progress");
29800
+ this.notifyWaiting("claude-sdk.tool-progress");
29801
+ break;
29584
29802
  default:
29585
29803
  break;
29586
29804
  }
@@ -29595,9 +29813,22 @@ var init_claude_sdk_stream_adapter = __esm(() => {
29595
29813
  if (event.type === "content_block_delta") {
29596
29814
  const delta = event.delta;
29597
29815
  if (delta.type === "text_delta") {
29816
+ this.notifyProgress("claude-sdk.stream.text-delta");
29598
29817
  this.appendText(delta.text);
29599
29818
  } else if (delta.type === "thinking_delta") {
29819
+ this.notifyProgress("claude-sdk.stream.thinking-delta");
29600
29820
  this.appendThinking(delta.thinking);
29821
+ } else if (delta.type === "input_json_delta") {
29822
+ this.notifyProgress("claude-sdk.stream.tool-input");
29823
+ this.notifyWaiting("claude-sdk.stream.tool-input");
29824
+ }
29825
+ return;
29826
+ }
29827
+ if (event.type === "content_block_start") {
29828
+ const block = event.content_block;
29829
+ if (block.type === "tool_use") {
29830
+ this.notifyProgress("claude-sdk.stream.tool-use");
29831
+ this.notifyWaiting("claude-sdk.stream.tool-use");
29601
29832
  }
29602
29833
  }
29603
29834
  }
@@ -29613,6 +29844,7 @@ var init_claude_sdk_stream_adapter = __esm(() => {
29613
29844
  this.appendThinking(block.thinking);
29614
29845
  this.flushThinking();
29615
29846
  } else if (block.type === "tool_use") {
29847
+ this.notifyWaiting("claude-sdk.assistant.tool-use");
29616
29848
  this.flushText();
29617
29849
  this.flushThinking();
29618
29850
  const bashCmd = resolveBashCommandForLog(block.name, block.input);
@@ -29634,11 +29866,35 @@ var init_claude_sdk_stream_adapter = __esm(() => {
29634
29866
  if (typeof block === "string")
29635
29867
  continue;
29636
29868
  if (block.type === "tool_result") {
29869
+ this.notifyProgress("claude-sdk.user.tool-result");
29870
+ if (block.is_error === true) {
29871
+ this.notifyFailure("claude-sdk.user.tool-result");
29872
+ }
29637
29873
  const resultStr = typeof block.content === "string" ? block.content : JSON.stringify(block.content);
29638
29874
  this.writeLine(formatAgentLogLine(this.logPrefix, "tool_result", `tool result: ${resultStr}`));
29639
29875
  }
29640
29876
  }
29641
29877
  }
29878
+ handleSystem(message) {
29879
+ switch (message.subtype) {
29880
+ case "init":
29881
+ this.writeLine(formatAgentLogLine(this.logPrefix, "system: init"));
29882
+ break;
29883
+ case "task_started":
29884
+ case "task_progress":
29885
+ this.notifyProgress("claude-sdk.task-progress");
29886
+ this.notifyWaiting("claude-sdk.task-progress");
29887
+ break;
29888
+ case "task_updated":
29889
+ this.notifyProgress("claude-sdk.task-progress");
29890
+ break;
29891
+ case "permission_denied":
29892
+ this.notifyFailure("claude-sdk.permission-denied");
29893
+ break;
29894
+ default:
29895
+ break;
29896
+ }
29897
+ }
29642
29898
  emitAgentEnd() {
29643
29899
  if (this.agentEndEmitted)
29644
29900
  return;
@@ -29808,6 +30064,7 @@ var init_claude_sdk_agent_service = __esm(() => {
29808
30064
  init_esm();
29809
30065
  init_claude_sdk_package();
29810
30066
  init_claude_sdk_stream_adapter();
30067
+ init_harness_activity_emitter();
29811
30068
  init_base_cli_agent_service();
29812
30069
  init_claude_models();
29813
30070
  init_detection_result();
@@ -29908,6 +30165,7 @@ var init_claude_sdk_agent_service = __esm(() => {
29908
30165
  resumedProviderSessionId
29909
30166
  } = args2;
29910
30167
  const entry = this.registerProcess(pid, context5);
30168
+ const activityEmitter = createHarnessActivityEmitter();
29911
30169
  const logPrefix = buildAgentLogPrefix("claude-sdk", context5);
29912
30170
  const sdkSession = {
29913
30171
  keeper,
@@ -29951,7 +30209,8 @@ var init_claude_sdk_agent_service = __esm(() => {
29951
30209
  outputCallbacks,
29952
30210
  agentEndCallbacks,
29953
30211
  assistantTextCallbacks,
29954
- emitLogLine
30212
+ emitLogLine,
30213
+ activityEmitter
29955
30214
  });
29956
30215
  return {
29957
30216
  pid,
@@ -29980,7 +30239,8 @@ var init_claude_sdk_agent_service = __esm(() => {
29980
30239
  source: "provider_allocated"
29981
30240
  });
29982
30241
  }
29983
- }
30242
+ },
30243
+ activityEmitter
29984
30244
  };
29985
30245
  }
29986
30246
  runTurnLoop(args2) {
@@ -30000,7 +30260,8 @@ var init_claude_sdk_agent_service = __esm(() => {
30000
30260
  outputCallbacks,
30001
30261
  agentEndCallbacks,
30002
30262
  assistantTextCallbacks,
30003
- emitLogLine
30263
+ emitLogLine,
30264
+ activityEmitter
30004
30265
  } = args2;
30005
30266
  let exited = false;
30006
30267
  this.executeTurnLoop({
@@ -30020,6 +30281,7 @@ var init_claude_sdk_agent_service = __esm(() => {
30020
30281
  agentEndCallbacks,
30021
30282
  assistantTextCallbacks,
30022
30283
  emitLogLine,
30284
+ activityEmitter,
30023
30285
  isExited: () => exited,
30024
30286
  markExited: () => {
30025
30287
  exited = true;
@@ -30053,6 +30315,7 @@ var init_claude_sdk_agent_service = __esm(() => {
30053
30315
  agentEndCallbacks,
30054
30316
  assistantTextCallbacks,
30055
30317
  emitLogLine,
30318
+ activityEmitter,
30056
30319
  isExited,
30057
30320
  markExited
30058
30321
  } = args2;
@@ -30075,7 +30338,8 @@ var init_claude_sdk_agent_service = __esm(() => {
30075
30338
  }
30076
30339
  nextPrompt = deferredResume;
30077
30340
  }
30078
- const adapter = new ClaudeSdkStreamAdapter(logPrefix, emitLogLine);
30341
+ activityEmitter.beginTurn();
30342
+ const adapter = new ClaudeSdkStreamAdapter(logPrefix, emitLogLine, activityEmitter);
30079
30343
  wireNativeStreamAdapter({
30080
30344
  adapter,
30081
30345
  assistantTextCallbacks,
@@ -30605,12 +30869,16 @@ var init_codex_sdk_stream_adapter = __esm(() => {
30605
30869
  init_native_stream_adapter_base();
30606
30870
  CodexSdkStreamAdapter = class CodexSdkStreamAdapter extends NativeStreamAdapterBase {
30607
30871
  textBuffer = "";
30872
+ constructor(logPrefix, emitLogLine, activityEmitter) {
30873
+ super(logPrefix, emitLogLine, activityEmitter);
30874
+ }
30608
30875
  handleEvent(event) {
30609
- this.notifyOutput();
30876
+ this.notifyOutput(`codex-sdk.${event.type}`);
30610
30877
  switch (event.type) {
30611
30878
  case "item.started":
30612
30879
  case "item.updated":
30613
30880
  case "item.completed":
30881
+ this.notifyItemActivity(event.type, event.item);
30614
30882
  this.handleItem(event.item);
30615
30883
  break;
30616
30884
  case "turn.completed":
@@ -30619,11 +30887,13 @@ var init_codex_sdk_stream_adapter = __esm(() => {
30619
30887
  this.flushText();
30620
30888
  this.writeProviderUnavailableMarker(event.error.message);
30621
30889
  this.writeLine(formatAgentLogLine(this.logPrefix, "run-error", event.error.message));
30890
+ this.notifyFailure("codex-sdk.turn.failed");
30622
30891
  break;
30623
30892
  case "error":
30624
30893
  this.flushText();
30625
30894
  this.writeProviderUnavailableMarker(event.message);
30626
30895
  this.writeLine(formatAgentLogLine(this.logPrefix, "run-error", event.message));
30896
+ this.notifyFailure("codex-sdk.error");
30627
30897
  break;
30628
30898
  case "thread.started":
30629
30899
  case "turn.started":
@@ -30635,6 +30905,50 @@ var init_codex_sdk_stream_adapter = __esm(() => {
30635
30905
  this.flushText();
30636
30906
  this.emitAgentEnd();
30637
30907
  }
30908
+ notifyItemActivity(lifecycle, item) {
30909
+ switch (item.type) {
30910
+ case "agent_message":
30911
+ this.notifyProgress("codex-sdk.item.agent-message");
30912
+ break;
30913
+ case "reasoning":
30914
+ this.notifyProgress("codex-sdk.item.reasoning");
30915
+ break;
30916
+ case "command_execution":
30917
+ this.notifyProgress("codex-sdk.item.command-execution");
30918
+ if (item.status === "in_progress") {
30919
+ this.notifyWaiting("codex-sdk.item.command-execution");
30920
+ }
30921
+ break;
30922
+ case "file_change":
30923
+ this.notifyProgress("codex-sdk.item.file-change");
30924
+ if (item.status === "failed") {
30925
+ this.notifyFailure("codex-sdk.item.file-change");
30926
+ }
30927
+ break;
30928
+ case "mcp_tool_call":
30929
+ this.notifyProgress("codex-sdk.item.mcp-tool-call");
30930
+ if (item.status === "in_progress") {
30931
+ this.notifyWaiting("codex-sdk.item.mcp-tool-call");
30932
+ }
30933
+ if (item.status === "failed" || item.error) {
30934
+ this.notifyFailure("codex-sdk.item.mcp-tool-call");
30935
+ }
30936
+ break;
30937
+ case "web_search":
30938
+ this.notifyProgress("codex-sdk.item.web-search");
30939
+ if (lifecycle === "item.started") {
30940
+ this.notifyWaiting("codex-sdk.item.web-search");
30941
+ }
30942
+ break;
30943
+ case "error":
30944
+ this.notifyFailure("codex-sdk.item.error");
30945
+ break;
30946
+ case "todo_list":
30947
+ break;
30948
+ default:
30949
+ break;
30950
+ }
30951
+ }
30638
30952
  handleItem(item) {
30639
30953
  switch (item.type) {
30640
30954
  case "agent_message":
@@ -30837,6 +31151,7 @@ var init_codex_sdk_agent_service = __esm(() => {
30837
31151
  init_codex_sdk_package();
30838
31152
  init_codex_sdk_stream_adapter();
30839
31153
  init_spawn_env();
31154
+ init_harness_activity_emitter();
30840
31155
  init_base_cli_agent_service();
30841
31156
  init_detection_result();
30842
31157
  CodexSdkAgentService = class CodexSdkAgentService extends BaseCLIAgentService {
@@ -30956,6 +31271,7 @@ var init_codex_sdk_agent_service = __esm(() => {
30956
31271
  };
30957
31272
  this.sessions.set(pid, session2);
30958
31273
  const callbacks = this.buildSessionCallbacks(pid, context5);
31274
+ const activityEmitter = createHarnessActivityEmitter();
30959
31275
  this.runTurnLoop({
30960
31276
  session: session2,
30961
31277
  correlationId: harnessSessionId,
@@ -30968,7 +31284,8 @@ var init_codex_sdk_agent_service = __esm(() => {
30968
31284
  outputCallbacks: callbacks.outputCallbacks,
30969
31285
  agentEndCallbacks: callbacks.agentEndCallbacks,
30970
31286
  assistantTextCallbacks: callbacks.assistantTextCallbacks,
30971
- emitLogLine: callbacks.emitLogLine
31287
+ emitLogLine: callbacks.emitLogLine,
31288
+ activityEmitter
30972
31289
  });
30973
31290
  return this.buildSpawnResult({
30974
31291
  pid,
@@ -30979,7 +31296,8 @@ var init_codex_sdk_agent_service = __esm(() => {
30979
31296
  agentEndCallbacks: callbacks.agentEndCallbacks,
30980
31297
  logLineCallbacks: callbacks.logLineCallbacks,
30981
31298
  assistantTextCallbacks: callbacks.assistantTextCallbacks,
30982
- sessionIdUpdatedCallbacks: callbacks.sessionIdUpdatedCallbacks
31299
+ sessionIdUpdatedCallbacks: callbacks.sessionIdUpdatedCallbacks,
31300
+ activityEmitter
30983
31301
  });
30984
31302
  }
30985
31303
  buildSessionCallbacks(pid, context5) {
@@ -31021,11 +31339,13 @@ var init_codex_sdk_agent_service = __esm(() => {
31021
31339
  agentEndCallbacks,
31022
31340
  logLineCallbacks,
31023
31341
  assistantTextCallbacks,
31024
- sessionIdUpdatedCallbacks
31342
+ sessionIdUpdatedCallbacks,
31343
+ activityEmitter
31025
31344
  } = args2;
31026
31345
  return {
31027
31346
  pid,
31028
31347
  harnessSessionId,
31348
+ activityEmitter,
31029
31349
  onExit: (cb) => {
31030
31350
  exitCallbacks.push(cb);
31031
31351
  },
@@ -31066,7 +31386,8 @@ var init_codex_sdk_agent_service = __esm(() => {
31066
31386
  outputCallbacks,
31067
31387
  agentEndCallbacks,
31068
31388
  assistantTextCallbacks,
31069
- emitLogLine
31389
+ emitLogLine,
31390
+ activityEmitter
31070
31391
  } = args2;
31071
31392
  let exited = false;
31072
31393
  (async () => {
@@ -31102,7 +31423,8 @@ ${deferredResume}` : deferredResume;
31102
31423
  outputCallbacks,
31103
31424
  agentEndCallbacks,
31104
31425
  assistantTextCallbacks,
31105
- emitLogLine
31426
+ emitLogLine,
31427
+ activityEmitter
31106
31428
  });
31107
31429
  nextPrompt = null;
31108
31430
  } catch (turnErr) {
@@ -31152,9 +31474,11 @@ ${deferredResume}` : deferredResume;
31152
31474
  outputCallbacks,
31153
31475
  agentEndCallbacks,
31154
31476
  assistantTextCallbacks,
31155
- emitLogLine
31477
+ emitLogLine,
31478
+ activityEmitter
31156
31479
  } = args2;
31157
- const adapter = new CodexSdkStreamAdapter(logPrefix, emitLogLine);
31480
+ activityEmitter.beginTurn();
31481
+ const adapter = new CodexSdkStreamAdapter(logPrefix, emitLogLine, activityEmitter);
31158
31482
  wireNativeStreamAdapter({
31159
31483
  adapter,
31160
31484
  assistantTextCallbacks,
@@ -31300,6 +31624,7 @@ var init_command_code_stream_reader = () => {};
31300
31624
  var COMMANDCODE_COMMAND = "cmd", COMMANDCODE_MODELS, CommandCodeAgentService;
31301
31625
  var init_command_code_agent_service = __esm(() => {
31302
31626
  init_model_provider();
31627
+ init_harness_activity_emitter();
31303
31628
  init_base_cli_agent_service();
31304
31629
  init_command_code_stream_reader();
31305
31630
  COMMANDCODE_MODELS = [
@@ -31342,12 +31667,21 @@ var init_command_code_agent_service = __esm(() => {
31342
31667
  async listModels() {
31343
31668
  return COMMANDCODE_MODELS.map((model) => prefixModelWithProvider(inferCommandCodeModelProvider(model), model));
31344
31669
  }
31345
- createExitSubscription(childProcess, pid, context5) {
31670
+ createExitSubscription(childProcess, pid, context5, activityEmitter) {
31346
31671
  let exitInfo = null;
31672
+ let failureEmitted = false;
31347
31673
  const exitCallbacks = [];
31348
31674
  childProcess.on("exit", (code2, signal) => {
31349
31675
  this.deleteProcess(pid);
31350
31676
  exitInfo = { code: code2, signal };
31677
+ if (activityEmitter && !failureEmitted && (code2 !== null && code2 !== 0 || signal !== null)) {
31678
+ failureEmitted = true;
31679
+ activityEmitter.emit({
31680
+ kind: "failure",
31681
+ source: "commandcode-cli.process",
31682
+ at: Date.now()
31683
+ });
31684
+ }
31351
31685
  for (const cb of exitCallbacks) {
31352
31686
  cb({ code: code2, signal, context: context5 });
31353
31687
  }
@@ -31368,6 +31702,8 @@ var init_command_code_agent_service = __esm(() => {
31368
31702
  const fullPrompt = options.systemPrompt ? `${options.systemPrompt}
31369
31703
 
31370
31704
  ${options.prompt}` : options.prompt;
31705
+ const activityEmitter = createHarnessActivityEmitter();
31706
+ activityEmitter.beginTurn();
31371
31707
  const childProcess = this.deps.spawn(COMMANDCODE_COMMAND, args2, {
31372
31708
  cwd: options.workingDir,
31373
31709
  stdio: ["pipe", "pipe", "pipe"],
@@ -31385,6 +31721,9 @@ ${options.prompt}` : options.prompt;
31385
31721
  const logPrefix = `[commandcode:${roleTag}${chatroomSuffix}`;
31386
31722
  const { onLogLine, emitFormatted } = createSessionLogCallbacks();
31387
31723
  const outputCallbacks = [];
31724
+ const emitActivity = (kind, source) => {
31725
+ activityEmitter.emit({ kind, source, at: Date.now() });
31726
+ };
31388
31727
  if (childProcess.stdout) {
31389
31728
  const reader = new CommandCodeStreamReader(childProcess.stdout);
31390
31729
  let textBuffer = "";
@@ -31399,6 +31738,7 @@ ${options.prompt}` : options.prompt;
31399
31738
  textBuffer = "";
31400
31739
  };
31401
31740
  reader.onText((text) => {
31741
+ emitActivity("progress", "commandcode-cli.assistant.text");
31402
31742
  textBuffer += text;
31403
31743
  if (textBuffer.includes(`
31404
31744
  `))
@@ -31409,6 +31749,7 @@ ${options.prompt}` : options.prompt;
31409
31749
  });
31410
31750
  reader.onAnyEvent(() => {
31411
31751
  entry.lastOutputAt = Date.now();
31752
+ emitActivity("transport", "commandcode-cli.message");
31412
31753
  for (const cb of outputCallbacks)
31413
31754
  cb();
31414
31755
  });
@@ -31418,15 +31759,17 @@ ${options.prompt}` : options.prompt;
31418
31759
  });
31419
31760
  if (childProcess.stderr) {
31420
31761
  childProcess.stderr.on("data", (chunk2) => {
31762
+ emitActivity("transport", "commandcode-cli.stderr");
31421
31763
  emitFormatted(chunk2.toString("utf8"), "stderr");
31422
31764
  entry.lastOutputAt = Date.now();
31423
31765
  for (const cb of outputCallbacks)
31424
31766
  cb();
31425
31767
  });
31426
31768
  }
31427
- const onExit5 = this.createExitSubscription(childProcess, pid, context5);
31769
+ const onExit5 = this.createExitSubscription(childProcess, pid, context5, activityEmitter);
31428
31770
  return {
31429
31771
  pid,
31772
+ activityEmitter,
31430
31773
  onExit: onExit5,
31431
31774
  onOutput: (cb) => {
31432
31775
  outputCallbacks.push(cb);
@@ -31437,9 +31780,10 @@ ${options.prompt}` : options.prompt;
31437
31780
  onLogLine
31438
31781
  };
31439
31782
  }
31440
- const onExit4 = this.createExitSubscription(childProcess, pid, context5);
31783
+ const onExit4 = this.createExitSubscription(childProcess, pid, context5, activityEmitter);
31441
31784
  if (childProcess.stderr) {
31442
31785
  childProcess.stderr.on("data", (chunk2) => {
31786
+ emitActivity("transport", "commandcode-cli.stderr");
31443
31787
  emitFormatted(chunk2.toString("utf8"), "stderr");
31444
31788
  entry.lastOutputAt = Date.now();
31445
31789
  for (const cb of outputCallbacks)
@@ -31448,6 +31792,7 @@ ${options.prompt}` : options.prompt;
31448
31792
  }
31449
31793
  return {
31450
31794
  pid,
31795
+ activityEmitter,
31451
31796
  onExit: onExit4,
31452
31797
  onOutput: (cb) => {
31453
31798
  outputCallbacks.push(cb);
@@ -31497,13 +31842,23 @@ var init_cursor_sdk_stream_adapter = __esm(() => {
31497
31842
  CursorSdkStreamAdapter = class CursorSdkStreamAdapter extends NativeStreamAdapterBase {
31498
31843
  textBuffer = "";
31499
31844
  sawTextDelta = false;
31845
+ constructor(logPrefix, emitLogLine, activityEmitter) {
31846
+ super(logPrefix, emitLogLine, activityEmitter);
31847
+ }
31500
31848
  handleMessage(message) {
31501
- this.notifyOutput();
31849
+ this.notifyOutput("cursor-sdk.message");
31502
31850
  switch (message.type) {
31503
31851
  case "assistant":
31852
+ this.notifyProgress("cursor-sdk.assistant");
31504
31853
  this.handleAssistant(message);
31505
31854
  break;
31506
31855
  case "tool_call": {
31856
+ this.notifyProgress("cursor-sdk.tool_call");
31857
+ if (message.status === "running") {
31858
+ this.notifyWaiting("cursor-sdk.tool_call");
31859
+ } else if (message.status === "error") {
31860
+ this.notifyFailure("cursor-sdk.tool_call");
31861
+ }
31507
31862
  this.flushText();
31508
31863
  if (message.status === "error") {
31509
31864
  const detail = message.result !== undefined ? JSON.stringify(message.result) : "no result";
@@ -31519,11 +31874,17 @@ var init_cursor_sdk_stream_adapter = __esm(() => {
31519
31874
  break;
31520
31875
  }
31521
31876
  case "status": {
31877
+ if (message.status === "RUNNING") {
31878
+ this.notifyProgress("cursor-sdk.status");
31879
+ } else if (message.status === "ERROR") {
31880
+ this.notifyFailure("cursor-sdk.status");
31881
+ }
31522
31882
  const payload = message.message ? `${message.status}: ${message.message}` : message.status;
31523
31883
  this.writeLine(formatAgentLogLine(this.logPrefix, "status", payload));
31524
31884
  break;
31525
31885
  }
31526
31886
  case "thinking":
31887
+ this.notifyProgress("cursor-sdk.thinking");
31527
31888
  break;
31528
31889
  case "system":
31529
31890
  if (message.subtype === "init") {
@@ -31531,6 +31892,7 @@ var init_cursor_sdk_stream_adapter = __esm(() => {
31531
31892
  }
31532
31893
  break;
31533
31894
  case "task":
31895
+ this.notifyProgress("cursor-sdk.task");
31534
31896
  this.writeLine(formatAgentLogLine(this.logPrefix, "task", [message.status, message.text].filter(Boolean).join(": ")));
31535
31897
  break;
31536
31898
  case "usage":
@@ -31545,36 +31907,56 @@ var init_cursor_sdk_stream_adapter = __esm(() => {
31545
31907
  }
31546
31908
  }
31547
31909
  handleInteractionDelta(update5) {
31548
- this.notifyOutput();
31910
+ this.notifyOutput("cursor-sdk.interaction");
31549
31911
  switch (update5.type) {
31550
31912
  case "text-delta":
31913
+ this.notifyProgress("cursor-sdk.interaction.text-delta");
31551
31914
  this.sawTextDelta = true;
31552
31915
  this.appendAssistantText(update5.text);
31553
31916
  break;
31554
31917
  case "thinking-delta":
31918
+ this.notifyProgress("cursor-sdk.interaction.thinking-delta");
31555
31919
  this.writeLine(formatAgentLogLine(this.logPrefix, "thinking", update5.text));
31556
31920
  break;
31557
31921
  case "tool-call-started":
31922
+ this.notifyProgress("cursor-sdk.interaction.tool-call-started");
31923
+ this.notifyWaiting("cursor-sdk.interaction.tool-call-started");
31558
31924
  this.flushText();
31559
31925
  this.logToolCallStarted(update5);
31560
31926
  break;
31561
31927
  case "tool-call-completed":
31928
+ this.notifyProgress("cursor-sdk.interaction.tool-call-completed");
31562
31929
  this.flushText();
31563
31930
  break;
31564
31931
  case "tool-call-delta":
31932
+ this.notifyProgress("cursor-sdk.interaction.tool-call-delta");
31565
31933
  this.handleToolCallDelta(update5);
31566
31934
  break;
31567
- case "turn-ended":
31568
- case "thinking-completed":
31569
- case "token-delta":
31570
- case "summary-started":
31571
- case "summary-completed":
31572
- case "summary":
31573
- case "user-message-appended":
31574
31935
  case "partial-tool-call":
31936
+ this.notifyProgress("cursor-sdk.interaction.partial-tool-call");
31937
+ break;
31575
31938
  case "shell-output-delta":
31939
+ this.notifyProgress("cursor-sdk.interaction.shell-output-delta");
31940
+ break;
31576
31941
  case "step-started":
31942
+ this.notifyProgress("cursor-sdk.interaction.step-started");
31943
+ break;
31577
31944
  case "step-completed":
31945
+ this.notifyProgress("cursor-sdk.interaction.step-completed");
31946
+ break;
31947
+ case "summary-started":
31948
+ this.notifyProgress("cursor-sdk.interaction.summary-started");
31949
+ break;
31950
+ case "summary-completed":
31951
+ this.notifyProgress("cursor-sdk.interaction.summary-completed");
31952
+ break;
31953
+ case "summary":
31954
+ this.notifyProgress("cursor-sdk.interaction.summary");
31955
+ break;
31956
+ case "turn-ended":
31957
+ case "thinking-completed":
31958
+ case "token-delta":
31959
+ case "user-message-appended":
31578
31960
  break;
31579
31961
  default:
31580
31962
  logUnhandledInteractionDelta(this.logPrefix, update5, (line) => this.writeLine(line));
@@ -31610,6 +31992,8 @@ var init_cursor_sdk_stream_adapter = __esm(() => {
31610
31992
  this.appendAssistantText(nested2.text);
31611
31993
  break;
31612
31994
  case "tool-call-started":
31995
+ this.notifyProgress("cursor-sdk.interaction.tool-call-started");
31996
+ this.notifyWaiting("cursor-sdk.interaction.tool-call-started");
31613
31997
  this.flushText();
31614
31998
  this.logToolCallStarted(nested2);
31615
31999
  break;
@@ -31655,25 +32039,6 @@ var init_cursor_sdk_stream_adapter = __esm(() => {
31655
32039
  };
31656
32040
  });
31657
32041
 
31658
- // src/daemon/infrastructure/agent-process-manager/harness-activity-emitter.ts
31659
- function createHarnessActivityEmitter() {
31660
- const listeners = new Set;
31661
- return {
31662
- onActivity: (cb) => {
31663
- listeners.add(cb);
31664
- },
31665
- emit: (kind) => {
31666
- for (const cb of listeners)
31667
- cb(kind);
31668
- },
31669
- subscribe: (cb) => {
31670
- listeners.add(cb);
31671
- return () => listeners.delete(cb);
31672
- }
31673
- };
31674
- }
31675
- var init_harness_activity_emitter = () => {};
31676
-
31677
32042
  // src/daemon/infrastructure/local/harness/services/tap-process-stream-writes.ts
31678
32043
  function tapProcessStreamWrites(onWrite) {
31679
32044
  const stdoutOriginal = process.stdout.write.bind(process.stdout);
@@ -32037,19 +32402,17 @@ ${deferredResume}` : deferredResume;
32037
32402
  isFirstTurn = true;
32038
32403
  }
32039
32404
  }
32040
- let turnActivityReported = false;
32041
- const notifyTurnActivityOnce = () => {
32042
- if (turnActivityReported)
32043
- return;
32044
- turnActivityReported = true;
32045
- activityEmitter.emit("busy");
32046
- };
32047
32405
  const notifyHarnessOutput = () => {
32048
32406
  entry.lastOutputAt = Date.now();
32049
- notifyTurnActivityOnce();
32407
+ activityEmitter.emit({
32408
+ kind: "transport",
32409
+ source: "cursor-sdk.process-stream",
32410
+ at: Date.now()
32411
+ });
32050
32412
  for (const cb of outputCallbacks)
32051
32413
  cb();
32052
32414
  };
32415
+ activityEmitter.beginTurn();
32053
32416
  const restoreStreamTap = tapProcessStreamWrites(notifyHarnessOutput);
32054
32417
  try {
32055
32418
  let adapter;
@@ -32062,7 +32425,7 @@ ${deferredResume}` : deferredResume;
32062
32425
  }), SEND_TIMEOUT_MS, "agent.send");
32063
32426
  session2.run = run3;
32064
32427
  isFirstTurn = false;
32065
- adapter = new CursorSdkStreamAdapter(logPrefix, emitLogLine);
32428
+ adapter = new CursorSdkStreamAdapter(logPrefix, emitLogLine, activityEmitter);
32066
32429
  wireNativeStreamAdapter({
32067
32430
  adapter,
32068
32431
  assistantTextCallbacks,
@@ -32070,9 +32433,6 @@ ${deferredResume}` : deferredResume;
32070
32433
  agentEndCallbacks,
32071
32434
  entry
32072
32435
  });
32073
- adapter.onOutput(() => {
32074
- notifyTurnActivityOnce();
32075
- });
32076
32436
  try {
32077
32437
  for await (const message of run3.stream()) {
32078
32438
  if (session2.aborted)
@@ -34257,6 +34617,26 @@ function startSessionEventForwarder(client4, options) {
34257
34617
  recentLogLines.shift();
34258
34618
  }
34259
34619
  }
34620
+ function emitActivity(kind, source) {
34621
+ options.onActivity?.({ kind, source, at: Date.now() });
34622
+ }
34623
+ function semanticSourceForLogKind(kind) {
34624
+ switch (kind) {
34625
+ case "text":
34626
+ return "opencode.message.part.updated.text";
34627
+ case "thinking":
34628
+ return "opencode.message.part.updated.reasoning";
34629
+ case "file":
34630
+ return "opencode.file.edited";
34631
+ case "compacted":
34632
+ return "opencode.session.compacted";
34633
+ default:
34634
+ if (kind.startsWith("tool:")) {
34635
+ return "opencode.message.part.updated.tool";
34636
+ }
34637
+ return;
34638
+ }
34639
+ }
34260
34640
  function isAgentActivityKind(kind) {
34261
34641
  return kind === "text" || kind === "thinking" || kind === "file" || kind === "compacted" || kind.startsWith("tool:");
34262
34642
  }
@@ -34269,7 +34649,10 @@ function startSessionEventForwarder(client4, options) {
34269
34649
  `);
34270
34650
  recordRecentLogLine(line);
34271
34651
  if (isAgentActivityKind(kind)) {
34272
- options.onActivity?.();
34652
+ const source = semanticSourceForLogKind(kind);
34653
+ if (source) {
34654
+ emitActivity("progress", source);
34655
+ }
34273
34656
  }
34274
34657
  }
34275
34658
  function clearRetryIdleTimeout() {
@@ -34414,6 +34797,7 @@ function startSessionEventForwarder(client4, options) {
34414
34797
  abortTerminalProviderError();
34415
34798
  return;
34416
34799
  }
34800
+ emitActivity("waiting", "opencode.session.status.retry");
34417
34801
  scheduleRetryIdleTimeout();
34418
34802
  return;
34419
34803
  }
@@ -34424,7 +34808,7 @@ function startSessionEventForwarder(client4, options) {
34424
34808
  }
34425
34809
  case "busy": {
34426
34810
  clearRetryIdleTimeout();
34427
- options.onActivity?.();
34811
+ emitActivity("progress", "opencode.session.status.busy");
34428
34812
  return;
34429
34813
  }
34430
34814
  default: {
@@ -34433,6 +34817,7 @@ function startSessionEventForwarder(client4, options) {
34433
34817
  }
34434
34818
  }
34435
34819
  async function handleSessionError(props) {
34820
+ emitActivity("failure", "opencode.session.error");
34436
34821
  const err = props?.error;
34437
34822
  const errMsg = formatErrorName(err);
34438
34823
  const context5 = formatErrorContext(props);
@@ -34468,6 +34853,7 @@ function startSessionEventForwarder(client4, options) {
34468
34853
  const eventSession = eventSessionId(event);
34469
34854
  if (!shouldProcessEvent(event, eventSession))
34470
34855
  return;
34856
+ emitActivity("transport", `opencode.event.${event.type}`);
34471
34857
  if (!sessionStarted) {
34472
34858
  sessionStarted = true;
34473
34859
  logLine(target, "session] Started", `role: ${options.role}`);
@@ -34652,11 +35038,13 @@ var init_opencode_sdk_agent_service = __esm(() => {
34652
35038
  init_session_event_forwarder();
34653
35039
  init_session_metadata_store();
34654
35040
  init_spawn_env();
35041
+ init_harness_activity_emitter();
34655
35042
  init_binary_agent_service();
34656
35043
  OpenCodeSdkAgentService = class OpenCodeSdkAgentService extends OpenCodeBinaryAgentService {
34657
35044
  agentEndCallbacksByPid = new Map;
34658
35045
  assistantTextCallbacksByPid = new Map;
34659
35046
  outputCallbacksByPid = new Map;
35047
+ activityEmittersByPid = new Map;
34660
35048
  id = "opencode-sdk";
34661
35049
  displayName = "OpenCode (SDK)";
34662
35050
  listModelsHarnessId = "opencode-sdk";
@@ -34724,10 +35112,15 @@ var init_opencode_sdk_agent_service = __esm(() => {
34724
35112
  baseUrl
34725
35113
  };
34726
35114
  }
34727
- wireChildOutput(childProcess, pid, entry, emitLogLine, outputCallbacks) {
35115
+ wireChildOutput(childProcess, pid, entry, emitLogLine, outputCallbacks, activityEmitter) {
34728
35116
  if (childProcess.stdout) {
34729
35117
  childProcess.stdout.on("data", () => {
34730
35118
  entry.lastOutputAt = Date.now();
35119
+ activityEmitter.emit({
35120
+ kind: "transport",
35121
+ source: "opencode.process.stdout",
35122
+ at: Date.now()
35123
+ });
34731
35124
  for (const cb of outputCallbacks)
34732
35125
  cb();
34733
35126
  });
@@ -34739,6 +35132,11 @@ var init_opencode_sdk_agent_service = __esm(() => {
34739
35132
  });
34740
35133
  childProcess.stderr.on("data", (chunk2) => {
34741
35134
  entry.lastOutputAt = Date.now();
35135
+ activityEmitter.emit({
35136
+ kind: "transport",
35137
+ source: "opencode.process.stderr",
35138
+ at: Date.now()
35139
+ });
34742
35140
  for (const cb of outputCallbacks)
34743
35141
  cb();
34744
35142
  stderrBuffer.append(chunk2.toString());
@@ -34748,15 +35146,18 @@ var init_opencode_sdk_agent_service = __esm(() => {
34748
35146
  });
34749
35147
  }
34750
35148
  }
34751
- createSessionForwarder(client4, sessionId, context5, emitLogLine, emitAssistantText, outputCallbacks) {
35149
+ createSessionForwarder(client4, sessionId, context5, emitLogLine, emitAssistantText, outputCallbacks, activityEmitter) {
34752
35150
  return startSessionEventForwarder(client4, {
34753
35151
  sessionId,
34754
35152
  role: context5.role,
34755
35153
  onLogLine: emitLogLine,
34756
35154
  onAssistantText: emitAssistantText,
34757
- onActivity: () => {
34758
- for (const cb of outputCallbacks)
34759
- cb();
35155
+ onActivity: (event) => {
35156
+ activityEmitter.emit(event);
35157
+ if (event.kind === "progress") {
35158
+ for (const cb of outputCallbacks)
35159
+ cb();
35160
+ }
34760
35161
  }
34761
35162
  });
34762
35163
  }
@@ -34795,8 +35196,9 @@ var init_opencode_sdk_agent_service = __esm(() => {
34795
35196
  if (args2.outputCallbacks) {
34796
35197
  this.outputCallbacksByPid.set(pid, args2.outputCallbacks);
34797
35198
  }
35199
+ this.activityEmittersByPid.set(pid, args2.activityEmitter);
34798
35200
  const outputCallbacks = args2.outputCallbacks ?? [];
34799
- this.wireChildOutput(childProcess, pid, entry, emitLogLine, outputCallbacks);
35201
+ this.wireChildOutput(childProcess, pid, entry, emitLogLine, outputCallbacks, args2.activityEmitter);
34800
35202
  return {
34801
35203
  pid,
34802
35204
  harnessSessionId: sessionId,
@@ -34804,6 +35206,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
34804
35206
  agentName,
34805
35207
  ...model ? { model } : {}
34806
35208
  },
35209
+ activityEmitter: args2.activityEmitter,
34807
35210
  onExit: (cb) => {
34808
35211
  childProcess.on("exit", (code2, signal) => {
34809
35212
  const fwd = this.forwarders.get(pid);
@@ -34815,6 +35218,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
34815
35218
  this.agentEndCallbacksByPid.delete(pid);
34816
35219
  this.assistantTextCallbacksByPid.delete(pid);
34817
35220
  this.outputCallbacksByPid.delete(pid);
35221
+ this.activityEmittersByPid.delete(pid);
34818
35222
  this.deleteProcess(pid);
34819
35223
  cb({ code: code2, signal, context: context5 });
34820
35224
  });
@@ -34906,6 +35310,10 @@ var init_opencode_sdk_agent_service = __esm(() => {
34906
35310
  const newSessionId2 = sessionCreateResult.data.id;
34907
35311
  const { emitLogLine } = this.createLogLineEmitter();
34908
35312
  const pidOutputCallbacks = this.outputCallbacksByPid.get(args2.pid) ?? [];
35313
+ const activityEmitter = this.activityEmittersByPid.get(args2.pid);
35314
+ if (!activityEmitter) {
35315
+ throw new Error(`No activity emitter for pid=${args2.pid}`);
35316
+ }
34909
35317
  const forwarder = startSessionEventForwarder(client4, {
34910
35318
  sessionId: newSessionId2,
34911
35319
  role: args2.context.role,
@@ -34915,9 +35323,12 @@ var init_opencode_sdk_agent_service = __esm(() => {
34915
35323
  for (const cb of callbacks2)
34916
35324
  cb(text);
34917
35325
  },
34918
- onActivity: () => {
34919
- for (const cb of pidOutputCallbacks)
34920
- cb();
35326
+ onActivity: (event) => {
35327
+ activityEmitter.emit(event);
35328
+ if (event.kind === "progress") {
35329
+ for (const cb of pidOutputCallbacks)
35330
+ cb();
35331
+ }
34921
35332
  }
34922
35333
  });
34923
35334
  const callbacks = this.agentEndCallbacksByPid.get(args2.pid) ?? [];
@@ -34939,6 +35350,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
34939
35350
  createdAt: new Date().toISOString(),
34940
35351
  baseUrl: args2.baseUrl
34941
35352
  });
35353
+ activityEmitter.beginTurn();
34942
35354
  await this.promptSessionAsync(client4, newSessionId2, buildDisabledToolsPromptBody({
34943
35355
  agentName: args2.agentName,
34944
35356
  prompt: args2.prompt,
@@ -34953,6 +35365,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
34953
35365
  const workingDir = session2.workingDir;
34954
35366
  const { childProcess, pid, baseUrl, client: client4 } = await this.startServeAndClient(workingDir, options.resolvedConvexUrl);
34955
35367
  let forwarder;
35368
+ const activityEmitter = createHarnessActivityEmitter();
34956
35369
  const { logLineCallbacks, emitLogLine } = this.createLogLineEmitter();
34957
35370
  const { assistantTextCallbacks, emitAssistantText } = this.createAssistantTextEmitter();
34958
35371
  const outputCallbacks = [];
@@ -34961,10 +35374,11 @@ var init_opencode_sdk_agent_service = __esm(() => {
34961
35374
  if (!sessionInfo.data?.id) {
34962
35375
  throw new Error(`OpenCode session ${sessionId} not found (sessions may not survive serve restart)`);
34963
35376
  }
34964
- forwarder = this.createSessionForwarder(client4, sessionId, context5, emitLogLine, emitAssistantText, outputCallbacks);
35377
+ forwarder = this.createSessionForwarder(client4, sessionId, context5, emitLogLine, emitAssistantText, outputCallbacks, activityEmitter);
34965
35378
  const availableAgents = await this.listAvailableAgents(client4);
34966
35379
  const agentDef = availableAgents.find((a) => a.name === agentName);
34967
35380
  const composedSystem = composeSystemPrompt(agentDef?.prompt, systemPrompt);
35381
+ activityEmitter.beginTurn();
34968
35382
  await this.promptSessionAsync(client4, sessionId, buildDisabledToolsPromptBody({
34969
35383
  agentName,
34970
35384
  prompt,
@@ -34989,7 +35403,8 @@ var init_opencode_sdk_agent_service = __esm(() => {
34989
35403
  workingDir,
34990
35404
  logLineCallbacks,
34991
35405
  assistantTextCallbacks,
34992
- outputCallbacks
35406
+ outputCallbacks,
35407
+ activityEmitter
34993
35408
  });
34994
35409
  }
34995
35410
  async spawn(options) {
@@ -35000,6 +35415,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
35000
35415
  let forwarder;
35001
35416
  let agentName;
35002
35417
  let deferredSystemPrompt;
35418
+ const activityEmitter = createHarnessActivityEmitter();
35003
35419
  const { logLineCallbacks, emitLogLine } = this.createLogLineEmitter();
35004
35420
  const { assistantTextCallbacks, emitAssistantText } = this.createAssistantTextEmitter();
35005
35421
  const outputCallbacks = [];
@@ -35009,7 +35425,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
35009
35425
  throw new Error("Failed to create session");
35010
35426
  }
35011
35427
  sessionId = sessionCreateResult.data.id;
35012
- forwarder = this.createSessionForwarder(client4, sessionId, context5, emitLogLine, emitAssistantText, outputCallbacks);
35428
+ forwarder = this.createSessionForwarder(client4, sessionId, context5, emitLogLine, emitAssistantText, outputCallbacks, activityEmitter);
35013
35429
  const availableAgents = await this.listAvailableAgents(client4);
35014
35430
  const selected = selectAgent(availableAgents);
35015
35431
  agentName = selected.name;
@@ -35018,6 +35434,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
35018
35434
  deferredSystemPrompt = composedSystem;
35019
35435
  }
35020
35436
  if (!deferInitialTurn) {
35437
+ activityEmitter.beginTurn();
35021
35438
  await this.promptSessionAsync(client4, sessionId, buildDisabledToolsPromptBody({
35022
35439
  agentName: selected.name,
35023
35440
  prompt,
@@ -35046,7 +35463,8 @@ var init_opencode_sdk_agent_service = __esm(() => {
35046
35463
  logLineCallbacks,
35047
35464
  assistantTextCallbacks,
35048
35465
  deferredSystemPrompt,
35049
- outputCallbacks
35466
+ outputCallbacks,
35467
+ activityEmitter
35050
35468
  });
35051
35469
  }
35052
35470
  getHarnessReconnectContext(pid) {
@@ -35067,6 +35485,8 @@ var init_opencode_sdk_agent_service = __esm(() => {
35067
35485
  return;
35068
35486
  }
35069
35487
  this.forwarders.get(pid)?.armTurnEnd();
35488
+ const activityEmitter = this.activityEmittersByPid.get(pid);
35489
+ activityEmitter?.beginTurn();
35070
35490
  const client4 = createOpencodeClient({ baseUrl: meta.baseUrl });
35071
35491
  const deferredSystem = meta.deferredSystemPrompt;
35072
35492
  const context5 = {
@@ -35205,10 +35625,14 @@ var init_pi_sdk_stream_adapter = __esm(() => {
35205
35625
  PiSdkStreamAdapter = class PiSdkStreamAdapter extends NativeStreamAdapterBase {
35206
35626
  textBuffer = "";
35207
35627
  thinkingBuffer = "";
35628
+ constructor(logPrefix, emitLogLine, activityEmitter) {
35629
+ super(logPrefix, emitLogLine, activityEmitter);
35630
+ }
35208
35631
  handleEvent(event) {
35209
- this.notifyOutput();
35632
+ this.notifyOutput(`pi-sdk.${event.type}`);
35210
35633
  switch (event.type) {
35211
35634
  case "message_update": {
35635
+ this.notifyProgress(`pi-sdk.message.${event.assistantMessageEvent.type}`);
35212
35636
  const assistantEvent = event.assistantMessageEvent;
35213
35637
  if (assistantEvent.type === "text_delta") {
35214
35638
  this.appendText(assistantEvent.delta);
@@ -35218,6 +35642,8 @@ var init_pi_sdk_stream_adapter = __esm(() => {
35218
35642
  break;
35219
35643
  }
35220
35644
  case "tool_execution_start": {
35645
+ this.notifyProgress("pi-sdk.tool_execution_start");
35646
+ this.notifyWaiting("pi-sdk.tool_execution_start");
35221
35647
  this.flushText();
35222
35648
  this.flushThinking();
35223
35649
  const bashCmd = resolveBashCommandForLog(event.toolName, event.args);
@@ -35230,6 +35656,10 @@ var init_pi_sdk_stream_adapter = __esm(() => {
35230
35656
  break;
35231
35657
  }
35232
35658
  case "tool_execution_end": {
35659
+ this.notifyProgress("pi-sdk.tool_execution_end");
35660
+ if (event.isError === true) {
35661
+ this.notifyFailure("pi-sdk.tool_execution_end");
35662
+ }
35233
35663
  const resultStr = typeof event.result === "string" ? event.result : JSON.stringify(event.result);
35234
35664
  this.writeLine(formatAgentLogLine(this.logPrefix, "tool_result", `${event.toolName} result: ${resultStr}`));
35235
35665
  break;
@@ -35369,6 +35799,7 @@ var init_pi_sdk_agent_service = __esm(() => {
35369
35799
  init_esm();
35370
35800
  init_pi_sdk_package();
35371
35801
  init_pi_sdk_stream_adapter();
35802
+ init_harness_activity_emitter();
35372
35803
  init_base_cli_agent_service();
35373
35804
  init_detection_result();
35374
35805
  init_pi_agent_service();
@@ -35508,6 +35939,7 @@ var init_pi_sdk_agent_service = __esm(() => {
35508
35939
  storedSystemPrompt
35509
35940
  } = args2;
35510
35941
  const entry = this.registerProcess(pid, context5);
35942
+ const activityEmitter = createHarnessActivityEmitter();
35511
35943
  const logPrefix = buildAgentLogPrefix("pi-sdk", context5);
35512
35944
  const sdkSession = {
35513
35945
  session: session2,
@@ -35543,7 +35975,8 @@ var init_pi_sdk_agent_service = __esm(() => {
35543
35975
  outputCallbacks,
35544
35976
  agentEndCallbacks,
35545
35977
  assistantTextCallbacks,
35546
- emitLogLine
35978
+ emitLogLine,
35979
+ activityEmitter
35547
35980
  });
35548
35981
  return {
35549
35982
  pid,
@@ -35562,7 +35995,8 @@ var init_pi_sdk_agent_service = __esm(() => {
35562
35995
  },
35563
35996
  onAssistantText: (cb) => {
35564
35997
  assistantTextCallbacks.push(cb);
35565
- }
35998
+ },
35999
+ activityEmitter
35566
36000
  };
35567
36001
  }
35568
36002
  runTurnLoop(args2) {
@@ -35576,7 +36010,8 @@ var init_pi_sdk_agent_service = __esm(() => {
35576
36010
  outputCallbacks,
35577
36011
  agentEndCallbacks,
35578
36012
  assistantTextCallbacks,
35579
- emitLogLine
36013
+ emitLogLine,
36014
+ activityEmitter
35580
36015
  } = args2;
35581
36016
  let exited = false;
35582
36017
  (async () => {
@@ -35602,7 +36037,8 @@ var init_pi_sdk_agent_service = __esm(() => {
35602
36037
  ${deferredResume}` : deferredResume;
35603
36038
  prependSystemOnNextResume = false;
35604
36039
  }
35605
- const adapter = new PiSdkStreamAdapter(logPrefix, emitLogLine);
36040
+ activityEmitter.beginTurn();
36041
+ const adapter = new PiSdkStreamAdapter(logPrefix, emitLogLine, activityEmitter);
35606
36042
  wireNativeStreamAdapter({
35607
36043
  adapter,
35608
36044
  assistantTextCallbacks,
@@ -84511,12 +84947,11 @@ var init_stop_agent_confirmed_adapter = __esm(() => {
84511
84947
  });
84512
84948
 
84513
84949
  // ../../services/backend/config/reliability.ts
84514
- var HARNESS_SESSION_READY_TIMEOUT_MS = 5000, DAEMON_HEARTBEAT_INTERVAL_MS, DAEMON_HEARTBEAT_TTL_MS, AGENT_REQUEST_DEADLINE_MS = 120000, MACHINE_COMMAND_LEASE_RENEWAL_INTERVAL_MS = 20000, MACHINE_COMMAND_DAEMON_ROUTINE_TTL_MS, OBSERVATION_TTL_MS = 60000, OBSERVED_SAFETY_POLL_MS = 30000, WORKSPACE_LIST_RECONCILE_MS, AGENT_STOP_TERMINAL_RETENTION_MS, SCOPE_TARGET_STOP_TIMEOUT_MS = 1e4, CONNECTION_CLOSE_REQUEST_TTL_MS, ENHANCER_TERMINAL_JOB_RETENTION_MS;
84950
+ var HARNESS_SESSION_READY_TIMEOUT_MS = 5000, DAEMON_HEARTBEAT_INTERVAL_MS, DAEMON_HEARTBEAT_TTL_MS, AGENT_REQUEST_DEADLINE_MS = 120000, MACHINE_COMMAND_LEASE_RENEWAL_INTERVAL_MS = 20000, MACHINE_COMMAND_DAEMON_ROUTINE_TTL_MS, AGENT_STOP_TERMINAL_RETENTION_MS, SCOPE_TARGET_STOP_TIMEOUT_MS = 1e4, CONNECTION_CLOSE_REQUEST_TTL_MS, ENHANCER_TERMINAL_JOB_RETENTION_MS;
84515
84951
  var init_reliability = __esm(() => {
84516
84952
  DAEMON_HEARTBEAT_INTERVAL_MS = 5 * 60000;
84517
84953
  DAEMON_HEARTBEAT_TTL_MS = 6 * DAEMON_HEARTBEAT_INTERVAL_MS;
84518
84954
  MACHINE_COMMAND_DAEMON_ROUTINE_TTL_MS = 5 * 60000;
84519
- WORKSPACE_LIST_RECONCILE_MS = 60 * 60 * 1000;
84520
84955
  AGENT_STOP_TERMINAL_RETENTION_MS = 30 * 24 * 60 * 60 * 1000;
84521
84956
  CONNECTION_CLOSE_REQUEST_TTL_MS = 10 * 60000;
84522
84957
  ENHANCER_TERMINAL_JOB_RETENTION_MS = 30 * 24 * 60 * 60 * 1000;
@@ -100353,21 +100788,6 @@ var init_native_stale_turn_phase = __esm(() => {
100353
100788
  init_check_agent_slot();
100354
100789
  });
100355
100790
 
100356
- // src/daemon/domain/native-integration/predicates.ts
100357
- function isStaleCliGetNextTaskWaiting(task) {
100358
- const lastSeenAt = task.participant?.lastSeenAt ?? 0;
100359
- return task.participant?.lastSeenAction === GET_NEXT_TASK_STARTED_ACTION && task.createdAt > lastSeenAt;
100360
- }
100361
- function isCliIdleNotListening(task, now, thresholdMs) {
100362
- const lastSeenAt = task.participant?.lastSeenAt ?? 0;
100363
- if (lastSeenAt === 0)
100364
- return now - task.createdAt > thresholdMs;
100365
- return now - lastSeenAt > thresholdMs;
100366
- }
100367
- var init_predicates = __esm(() => {
100368
- init_participant();
100369
- });
100370
-
100371
100791
  // src/daemon/infrastructure/local/harness/services/spawn-prompt.ts
100372
100792
  function createSpawnPrompt(raw, opts) {
100373
100793
  if (opts?.nativeBootstrap) {
@@ -100396,7 +100816,6 @@ var init_spawn_policy = __esm(() => {
100396
100816
  // src/daemon/domain/native-integration/index.ts
100397
100817
  var init_native_integration = __esm(() => {
100398
100818
  init_types();
100399
- init_predicates();
100400
100819
  init_spawn_policy();
100401
100820
  });
100402
100821
 
@@ -102597,7 +103016,11 @@ async function emitNativeWaitingAfterSpawn(ctx, harness, opts) {
102597
103016
  try {
102598
103017
  if (!ctx.lifecycleOutbox)
102599
103018
  throw new Error("lifecycle outbox missing");
102600
- await ctx.lifecycleOutbox.enqueue(buildActivityLifecycleFact({ chatroomId: ctx.chatroomId, role: ctx.role, action: NATIVE_WAITING_ACTION }));
103019
+ await ctx.lifecycleOutbox.enqueue(buildActivityLifecycleFact({
103020
+ chatroomId: ctx.chatroomId,
103021
+ role: ctx.role,
103022
+ action: NATIVE_WAITING_ACTION
103023
+ }));
102601
103024
  return true;
102602
103025
  } catch (err) {
102603
103026
  const error51 = err instanceof Error ? err : new Error(String(err));
@@ -102622,7 +103045,9 @@ function wireTokenActivityReporting(opts) {
102622
103045
  if (!isTeamAgentRole(opts.role))
102623
103046
  return;
102624
103047
  if (opts.activityEmitter) {
102625
- opts.activityEmitter.onActivity(() => {
103048
+ opts.activityEmitter.onActivity((signal) => {
103049
+ if (signal.kind !== "progress" || !signal.isFirstForTurn)
103050
+ return;
102626
103051
  opts.backend.mutation(api.participants.updateTokenActivity, {
102627
103052
  sessionId: opts.sessionId,
102628
103053
  chatroomId: opts.chatroomId,
@@ -102949,6 +103374,10 @@ class AgentProcessManager {
102949
103374
  }
102950
103375
  async runHandleAgentEnd(opts) {
102951
103376
  const slot = this.slots.get(agentKey3(opts.chatroomId, opts.role));
103377
+ if (!slot || slot.pid !== opts.pid || slot.harness !== opts.harness || slot.state !== "running") {
103378
+ console.log(`[AgentProcessManager] Ignoring stale agent_end: role=${opts.role} callbackPid=${opts.pid} currentPid=${slot?.pid ?? "none"} currentState=${slot?.state ?? "none"}`);
103379
+ return;
103380
+ }
102952
103381
  const capabilities = getHarnessCapabilities(opts.harness);
102953
103382
  this.updateSlotsMirror(opts.chatroomId, opts.role, {
102954
103383
  state: slot?.state ?? "idle",
@@ -107202,7 +107631,7 @@ var init_start_subscriptions = __esm(() => {
107202
107631
  // src/daemon/entry/workspace-git/workspace-cache.ts
107203
107632
  async function getWorkspacesForMachine(deps) {
107204
107633
  const store = deps.workspaceListStore;
107205
- if (store && store.updatedAt > 0) {
107634
+ if (store && store.updatedAt > 0 && !deps.forceRefresh) {
107206
107635
  return store.workspaces;
107207
107636
  }
107208
107637
  try {
@@ -108113,11 +108542,8 @@ function toSyncWorkspaces(workingDirs) {
108113
108542
  async function reconcileWorkspaceList(session2) {
108114
108543
  const workspaces = await session2.backend.query(api.workspaces.listRecentlyObservedWorkspacesForMachine, {
108115
108544
  sessionId: session2.sessionId,
108116
- machineId: session2.machineId,
108117
- recencyWindowMs: OBSERVATION_TTL_MS
108545
+ machineId: session2.machineId
108118
108546
  });
108119
- if (workspaces == null)
108120
- return;
108121
108547
  if (!session2.workspaceListStore) {
108122
108548
  session2.workspaceListStore = { workspaces: [], updatedAt: 0 };
108123
108549
  }
@@ -108128,20 +108554,13 @@ var startWorkspaceListSubscriptionEffect = () => exports_Effect.gen(function* ()
108128
108554
  const session2 = yield* DaemonSessionService;
108129
108555
  session2.workspaceListStore = { workspaces: [], updatedAt: 0 };
108130
108556
  yield* exports_Effect.promise(() => reconcileWorkspaceList(session2));
108131
- const interval = setInterval(() => {
108132
- reconcileWorkspaceList(session2).catch(() => {
108133
- return;
108134
- });
108135
- }, OBSERVED_SAFETY_POLL_MS);
108136
108557
  return {
108137
108558
  stop: () => {
108138
- clearInterval(interval);
108139
108559
  session2.workspaceListStore = undefined;
108140
108560
  }
108141
108561
  };
108142
108562
  });
108143
108563
  var init_workspace_list_subscription = __esm(() => {
108144
- init_reliability();
108145
108564
  init_esm();
108146
108565
  init_api3();
108147
108566
  init_daemon_services();
@@ -110831,17 +111250,21 @@ var init_file_content_classifier = __esm(() => {
110831
111250
 
110832
111251
  // src/infrastructure/services/workspace/assert-registered-working-dir.ts
110833
111252
  async function assertRegisteredWorkingDir(session2, workingDir) {
110834
- const workspaces = await getWorkspacesForMachine({
111253
+ const normalizedWorkingDir = normalizeWorkingDirForLookup(workingDir);
111254
+ const deps = {
110835
111255
  workspaceListStore: session2.workspaceListStore,
110836
111256
  sessionId: session2.sessionId,
110837
111257
  machineId: session2.machineId,
110838
111258
  backend: session2.backend
110839
- });
110840
- const normalizedWorkingDir = normalizeWorkingDirForLookup(workingDir);
110841
- if (!workspaces.some((w) => normalizeWorkingDirForLookup(w.workingDir) === normalizedWorkingDir)) {
110842
- return { ok: false, error: "Workspace not registered for this machine" };
111259
+ };
111260
+ const isRegistered = (workspaces) => workspaces.some((workspace) => normalizeWorkingDirForLookup(workspace.workingDir) === normalizedWorkingDir);
111261
+ if (isRegistered(await getWorkspacesForMachine(deps))) {
111262
+ return { ok: true };
110843
111263
  }
110844
- return { ok: true };
111264
+ if (isRegistered(await getWorkspacesForMachine({ ...deps, forceRefresh: true }))) {
111265
+ return { ok: true };
111266
+ }
111267
+ return { ok: false, error: "Workspace not registered for this machine" };
110845
111268
  }
110846
111269
  var init_assert_registered_working_dir = __esm(() => {
110847
111270
  init_workspace_cache();
@@ -116425,11 +116848,6 @@ var init_command_run_subscription = __esm(() => {
116425
116848
  });
116426
116849
 
116427
116850
  // src/daemon/entry/task-delivery/task-delivery-logic.ts
116428
- function isPendingAliveRunningTask(task) {
116429
- const { agentConfig, status: status3 } = task;
116430
- const op = getNativeDeliverySession()?.agentOperationalReadModel?.get(task.chatroomId, agentConfig.role);
116431
- return status3 === "pending" && (agentConfig.spawnedAgentPid != null || op?.isAlive === true) && isOperationalDesiredRunning(op);
116432
- }
116433
116851
  function isSlotUnavailableForPid(slot, pid, isPidAlive, now = Date.now()) {
116434
116852
  if (!slot) {
116435
116853
  return true;
@@ -116516,31 +116934,11 @@ function listNativePendingTasksNeedingWake(tasks, cooldown, now) {
116516
116934
  return true;
116517
116935
  });
116518
116936
  }
116519
- function shouldNudgeCliPendingTask(task, now, pendingIdleThresholdMs) {
116520
- if (!isPendingAliveRunningTask(task))
116521
- return false;
116522
- return isStaleCliGetNextTaskWaiting(task) || isCliIdleNotListening(task, now, pendingIdleThresholdMs);
116523
- }
116524
- function shouldNudgePendingTask(task, now, pendingIdleThresholdMs = PENDING_IDLE_NUDGE_MS) {
116525
- if (isNativeHarness(task.agentConfig.agentHarness)) {
116526
- return shouldNudgeNativePendingTask(task, now, pendingIdleThresholdMs);
116527
- }
116528
- return shouldNudgeCliPendingTask(task, now, pendingIdleThresholdMs);
116529
- }
116530
- function shouldNudgeNativePendingTask(task, now, pendingIdleThresholdMs, slot) {
116531
- if (!isPendingAliveRunningTask(task))
116532
- return false;
116533
- if (!isAgentReadyForNativeDelivery(task, slot))
116534
- return false;
116535
- const lastSeenAt = task.participant?.lastSeenAt ?? 0;
116536
- const idleSince = lastSeenAt > 0 ? now - lastSeenAt : now - task.createdAt;
116537
- return idleSince > pendingIdleThresholdMs;
116538
- }
116539
116937
 
116540
116938
  class RecoveryCooldown {
116541
116939
  cooldownMs;
116542
116940
  lastAttemptAt = new Map;
116543
- constructor(cooldownMs = NUDGE_COOLDOWN_MS) {
116941
+ constructor(cooldownMs = RECOVERY_COOLDOWN_MS) {
116544
116942
  this.cooldownMs = cooldownMs;
116545
116943
  }
116546
116944
  canAttempt(chatroomId, role, kind, now) {
@@ -116552,37 +116950,12 @@ class RecoveryCooldown {
116552
116950
  this.lastAttemptAt.set(`${kind}:${chatroomId}:${role}`, now);
116553
116951
  }
116554
116952
  }
116555
- function isTaskReadyForNudge(task, now, cooldown, getSlot) {
116556
- if (isNativeHarness(task.agentConfig.agentHarness)) {
116557
- const slot = getSlot?.(task.chatroomId, task.agentConfig.role);
116558
- if (!shouldNudgeNativePendingTask(task, now, PENDING_IDLE_NUDGE_MS, slot))
116559
- return false;
116560
- } else if (!shouldNudgePendingTask(task, now)) {
116561
- return false;
116562
- }
116563
- const { chatroomId, agentConfig } = task;
116564
- if (!cooldown.canAttempt(chatroomId, agentConfig.role, "nudge", now))
116565
- return false;
116566
- if (!agentConfig.workingDir)
116567
- return false;
116568
- return true;
116569
- }
116570
- function listTasksReadyForNudge(tasks, now, cooldown, getSlot) {
116571
- return tasks.filter((task) => {
116572
- if (!isTaskReadyForNudge(task, now, cooldown, getSlot))
116573
- return false;
116574
- cooldown.recordAttempt(task.chatroomId, task.agentConfig.role, "nudge", now);
116575
- return true;
116576
- });
116577
- }
116578
- var PENDING_IDLE_NUDGE_MS = 15000, NUDGE_COOLDOWN_MS = 60000;
116953
+ var RECOVERY_COOLDOWN_MS = 60000;
116579
116954
  var init_task_delivery_logic = __esm(() => {
116580
116955
  init_check_agent_slot();
116581
- init_predicates();
116582
116956
  init_agent_process_manager();
116583
116957
  init_execute_stop_targets_adapter();
116584
116958
  init_native_delivery_session_registry();
116585
- init_native_ready_invariant();
116586
116959
  init_native_task_injector_logic();
116587
116960
  });
116588
116961
 
@@ -116590,14 +116963,6 @@ var init_task_delivery_logic = __esm(() => {
116590
116963
  function resolveTaskWantResume(task) {
116591
116964
  return sessionAugmentationToWantResume(resolveSessionAugmentationForTask({ content: task.taskContent ?? "", startInNewSession: task.startInNewSession }, task.agentConfig.role));
116592
116965
  }
116593
- function buildCliNudgeLogLine(task) {
116594
- const { chatroomId, agentConfig } = task;
116595
- const { role } = agentConfig;
116596
- const lastSeenAction = task.participant?.lastSeenAction ?? "unknown";
116597
- const augmentationMode = resolveSessionAugmentationForTask({ content: task.taskContent ?? "", startInNewSession: task.startInNewSession }, role);
116598
- const wantResume = resolveTaskWantResume(task);
116599
- return `[TaskMonitor] nudging ${role}@${chatroomId} — pending task ${task.taskId}, lastSeenAction=${lastSeenAction}, session_augmentation=${augmentationMode}, wantResume=${wantResume}`;
116600
- }
116601
116966
  function resolveTaskRunnerContextFromFull(task) {
116602
116967
  const { chatroomId, agentConfig } = task;
116603
116968
  const { role } = agentConfig;
@@ -116612,58 +116977,6 @@ function resolveTaskRunnerContextFromFull(task) {
116612
116977
  wantResume: resolveTaskWantResume(task)
116613
116978
  };
116614
116979
  }
116615
- function executeCliNudge(task, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
116616
- const ctx = resolveTaskRunnerContextFromFull(task);
116617
- if (!ctx)
116618
- return;
116619
- const { chatroomId, agentConfig, role, workingDir, wantResume } = ctx;
116620
- const augmentationMode = resolveSessionAugmentationForTask({ content: task.taskContent ?? "", startInNewSession: task.startInNewSession }, role);
116621
- exports_Runtime.runFork(runtime4)(exports_Effect.gen(function* () {
116622
- yield* agentMgr.stop({
116623
- chatroomId,
116624
- role,
116625
- reason: AgentStopReasonEnum["platform.task_monitor_nudge"]
116626
- });
116627
- yield* agentMgr.ensureRunning({
116628
- chatroomId,
116629
- role,
116630
- agentHarness: agentConfig.agentHarness,
116631
- model: agentConfig.model,
116632
- workingDir,
116633
- reason: AgentStartReasonEnum["platform.task_monitor_nudge"],
116634
- wantResume,
116635
- lifecycleRevision: task.agentConfig.configLifecycleRevision,
116636
- taskId: task.taskId
116637
- });
116638
- if (shouldEmitSessionAugmentation(role, augmentationMode)) {
116639
- yield* exports_Effect.tryPromise({
116640
- try: async () => {
116641
- await logDaemonAuditEvent(sessionDeps.logEvent ?? (async () => {
116642
- return;
116643
- }), {
116644
- type: "agent.sessionAugmented",
116645
- chatroomId,
116646
- role,
116647
- machineId,
116648
- taskId: task.taskId,
116649
- mode: augmentationMode,
116650
- newSessionStarted: sessionAugmentationNewSessionStarted(augmentationMode)
116651
- });
116652
- await sessionDeps.backend.mutation(api.daemon.agentEvents.sessionAugmented, {
116653
- sessionId: sessionDeps.sessionId,
116654
- machineId,
116655
- chatroomId,
116656
- role,
116657
- taskId: task.taskId,
116658
- mode: augmentationMode,
116659
- newSessionStarted: sessionAugmentationNewSessionStarted(augmentationMode)
116660
- });
116661
- },
116662
- catch: (err) => err
116663
- }).pipe(exports_Effect.catchAll(() => exports_Effect.void));
116664
- }
116665
- }).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[TaskMonitor] nudge failed for ${role}@${chatroomId}: ${getErrorMessage(err)}`)))));
116666
- }
116667
116980
  function runNativeReviveEffect(task, runtime4, effectContext2, agentMgr) {
116668
116981
  const ctx = resolveTaskRunnerContextFromFull(task);
116669
116982
  if (!ctx)
@@ -116713,27 +117026,12 @@ async function fetchTaskForAction(sessionDeps, machineId, snapshotRow) {
116713
117026
  });
116714
117027
  return result ? mapAssignedTaskView(result) : null;
116715
117028
  }
116716
- function runCliNudgeEffect(task, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
116717
- console.log(buildCliNudgeLogLine(task));
116718
- executeCliNudge(task, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
116719
- }
116720
117029
  async function clearStuckStoppingSlotIfNeeded(agentMgr, chatroomId, role) {
116721
117030
  const cleared = await agentMgr.clearStuckStoppingSlot(chatroomId, role);
116722
117031
  if (cleared) {
116723
117032
  console.log(`[TaskMonitor] cleared stuck stopping slot for ${role}@${chatroomId}`);
116724
117033
  }
116725
117034
  }
116726
- async function nudgeStuckTasks(tasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
116727
- const getSlot = (chatroomId, role) => agentMgr.getSlot(chatroomId, role);
116728
- const cliTasks = tasks.filter((task) => !isNativeHarness(task.agentConfig.agentHarness));
116729
- for (const row of listTasksReadyForNudge(cliTasks, now, cooldown, getSlot)) {
116730
- await clearStuckStoppingSlotIfNeeded(agentMgr, row.chatroomId, row.agentConfig.role);
116731
- const full = await fetchTaskForAction(sessionDeps, machineId, row);
116732
- if (!full)
116733
- continue;
116734
- runCliNudgeEffect(full, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
116735
- }
116736
- }
116737
117035
  async function reviveNativeTasks(tasks, localHealth, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
116738
117036
  for (const row of listNativeTasksNeedingRevive(tasks, localHealth, now, cooldown)) {
116739
117037
  if (isRestartOrchestratorInFlight(row.chatroomId, row.agentConfig.role))
@@ -116780,14 +117078,12 @@ async function processTasksUpdate(runtime4, effectContext2, cooldown, agentMgr,
116780
117078
  sessionDeps,
116781
117079
  machineId
116782
117080
  });
116783
- await nudgeStuckTasks(filteredTasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
116784
117081
  }
116785
117082
  var init_task_delivery_processor = __esm(() => {
116786
117083
  init_agent2();
116787
117084
  init_parse_session_augmentation();
116788
117085
  init_esm();
116789
117086
  init_native_task_delivery_coordinator();
116790
- init_native_task_injector_logic();
116791
117087
  init_api3();
116792
117088
  init_convex_error();
116793
117089
  init_restart_orchestrator_in_flight();
@@ -134466,4 +134762,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
134466
134762
  });
134467
134763
  program2.parse();
134468
134764
 
134469
- //# debugId=471FD0F14F27D83064756E2164756E21
134765
+ //# debugId=B34E804643624D4B64756E2164756E21