@slock-ai/daemon 0.57.3 → 0.57.4

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.
@@ -1058,6 +1058,143 @@ function shortMessageId(value) {
1058
1058
  return value.slice(0, 8);
1059
1059
  }
1060
1060
 
1061
+ // ../shared/src/externalAgentIntegration.ts
1062
+ import { z as z2 } from "zod";
1063
+ var EXTERNAL_AGENT_COMMS_PROTOCOL_VERSION = "agent-comms-core.v1";
1064
+ var EXTERNAL_AGENT_PROOF_SCHEMA_VERSION = "agent-proof.v1";
1065
+ var EXTERNAL_RUNTIME_INTEGRATION_MANIFEST_SCHEMA = "slock-external-runtime-integration.v1";
1066
+ var EXTERNAL_AGENT_WAKE_EVENT_SCHEMA = "slock-external-agent-wake-event.v1";
1067
+ var externalAgentCommsModeValues = ["spawn-core", "attach-core", "import-core"];
1068
+ var externalAgentIntegrationPatternValues = ["external-harness-plugin", "integrated-runtime"];
1069
+ var externalAgentIsolationValues = ["profile-scoped", "session-scoped"];
1070
+ var externalAgentWakeAdapterKindValues = ["claude-code-channels", "hermes-in-process"];
1071
+ var externalAgentWakeProofLevelValues = [
1072
+ "server_delivered",
1073
+ "harness_accepted",
1074
+ "wake_injected"
1075
+ ];
1076
+ var externalAgentProofLevelValues = [
1077
+ ...externalAgentWakeProofLevelValues,
1078
+ "model_seen"
1079
+ ];
1080
+ var externalAgentCommsLifecycleStateValues = [
1081
+ "unbound",
1082
+ "bound_stopped",
1083
+ "starting",
1084
+ "connected_replaying",
1085
+ "listening_idle",
1086
+ "handoff_pending",
1087
+ "degraded_backoff",
1088
+ "stopping",
1089
+ "stopped",
1090
+ "auth_revoked"
1091
+ ];
1092
+ var externalAgentLifecycleSourceValues = ["server_core", "comms_core", "wake_adapter", "server"];
1093
+ var externalAgentLifecycleProvenanceValues = [
1094
+ "slock_core",
1095
+ "adapter_observed",
1096
+ "agent_reported"
1097
+ ];
1098
+ var externalAgentAdapterFailureValues = [
1099
+ "no_session",
1100
+ "busy",
1101
+ "injection_failed",
1102
+ "protocol_mismatch",
1103
+ "auth_revoked"
1104
+ ];
1105
+ var externalAgentServerApiModeValues = ["interim-agent-api-events", "agent-inbox-protocol"];
1106
+ var nonEmptyStringSchema = z2.string().min(1);
1107
+ var isoTimestampSchema = z2.string().refine((value) => !Number.isNaN(Date.parse(value)), {
1108
+ message: "must be a parseable timestamp"
1109
+ });
1110
+ var externalRuntimeIntegrationManifestSchema = z2.object({
1111
+ schema: z2.literal(EXTERNAL_RUNTIME_INTEGRATION_MANIFEST_SCHEMA),
1112
+ runtimeId: nonEmptyStringSchema,
1113
+ integrationPattern: z2.enum(externalAgentIntegrationPatternValues),
1114
+ commsMode: z2.enum(externalAgentCommsModeValues),
1115
+ commsProtocolVersion: z2.literal(EXTERNAL_AGENT_COMMS_PROTOCOL_VERSION),
1116
+ proofSchemaVersion: z2.literal(EXTERNAL_AGENT_PROOF_SCHEMA_VERSION),
1117
+ minSlockCliVersion: nonEmptyStringSchema,
1118
+ multiplex: z2.boolean(),
1119
+ agentIsolation: z2.enum(externalAgentIsolationValues),
1120
+ bridgeLifecycle: z2.object({
1121
+ explicitStartOnly: z2.literal(true),
1122
+ oneShotCommandsBridgeIndependent: z2.literal(true),
1123
+ requiresBridgeFailureCodes: z2.array(z2.enum(["BRIDGE_NOT_RUNNING", "NO_CORE_SESSION"])).min(1),
1124
+ autoStartDefault: z2.literal(false)
1125
+ }).strict(),
1126
+ serverApi: z2.object({
1127
+ mode: z2.enum(externalAgentServerApiModeValues),
1128
+ deliveryOnly: z2.boolean(),
1129
+ cursorAuthority: z2.literal("model_seen_only")
1130
+ }).strict(),
1131
+ wakeAdapter: z2.object({
1132
+ kind: z2.enum(externalAgentWakeAdapterKindValues),
1133
+ protocol: nonEmptyStringSchema,
1134
+ requiresInteractiveSession: z2.boolean().optional()
1135
+ }).strict()
1136
+ }).strict().superRefine((value, ctx) => {
1137
+ if (!value.bridgeLifecycle.requiresBridgeFailureCodes.includes("BRIDGE_NOT_RUNNING")) {
1138
+ ctx.addIssue({
1139
+ code: "custom",
1140
+ path: ["bridgeLifecycle", "requiresBridgeFailureCodes"],
1141
+ message: "bridge-dependent surfaces must include BRIDGE_NOT_RUNNING"
1142
+ });
1143
+ }
1144
+ if (!value.bridgeLifecycle.requiresBridgeFailureCodes.includes("NO_CORE_SESSION")) {
1145
+ ctx.addIssue({
1146
+ code: "custom",
1147
+ path: ["bridgeLifecycle", "requiresBridgeFailureCodes"],
1148
+ message: "bridge-dependent surfaces must include NO_CORE_SESSION"
1149
+ });
1150
+ }
1151
+ if (value.serverApi.mode === "interim-agent-api-events" && value.serverApi.deliveryOnly !== true) {
1152
+ ctx.addIssue({
1153
+ code: "custom",
1154
+ path: ["serverApi", "deliveryOnly"],
1155
+ message: "interim agent-api events mode must be delivery-only"
1156
+ });
1157
+ }
1158
+ });
1159
+ var externalAgentWakeEventBaseSchema = z2.object({
1160
+ schema: z2.literal(EXTERNAL_AGENT_WAKE_EVENT_SCHEMA),
1161
+ eventId: nonEmptyStringSchema,
1162
+ attemptId: nonEmptyStringSchema,
1163
+ messageId: nonEmptyStringSchema,
1164
+ agentId: nonEmptyStringSchema,
1165
+ profile: nonEmptyStringSchema,
1166
+ coreSessionId: nonEmptyStringSchema,
1167
+ adapterInstance: nonEmptyStringSchema,
1168
+ runtimeSession: nonEmptyStringSchema.nullable(),
1169
+ occurredAt: isoTimestampSchema,
1170
+ lifecycleState: z2.enum(externalAgentCommsLifecycleStateValues),
1171
+ authority: z2.object({
1172
+ source: z2.enum(externalAgentLifecycleSourceValues),
1173
+ provenance: z2.enum(externalAgentLifecycleProvenanceValues)
1174
+ }).strict()
1175
+ }).strict();
1176
+ var externalAgentProofEventEnvelopeSchema = externalAgentWakeEventBaseSchema.extend({
1177
+ kind: z2.literal("proof"),
1178
+ proofLevel: z2.enum(externalAgentWakeProofLevelValues),
1179
+ outcome: z2.literal("ok"),
1180
+ failureMeta: z2.undefined().optional(),
1181
+ reason: z2.string().optional()
1182
+ });
1183
+ var externalAgentFailedWakeEventEnvelopeSchema = externalAgentWakeEventBaseSchema.extend({
1184
+ kind: z2.literal("wake_attempt"),
1185
+ proofLevel: z2.undefined().optional(),
1186
+ outcome: z2.literal("failed"),
1187
+ failureMeta: z2.object({
1188
+ failureClass: z2.enum(externalAgentAdapterFailureValues),
1189
+ retryAfterMs: z2.number().int().positive().optional()
1190
+ }).strict(),
1191
+ reason: nonEmptyStringSchema
1192
+ });
1193
+ var externalAgentWakeEventEnvelopeSchema = z2.discriminatedUnion("kind", [
1194
+ externalAgentProofEventEnvelopeSchema,
1195
+ externalAgentFailedWakeEventEnvelopeSchema
1196
+ ]);
1197
+
1061
1198
  // ../shared/src/translationLanguages.ts
1062
1199
  var SUPPORTED_TRANSLATION_LANGUAGE_CODES = [
1063
1200
  "en",
@@ -6513,6 +6650,7 @@ import {
6513
6650
  VERSION as PI_SDK_VERSION
6514
6651
  } from "@earendil-works/pi-coding-agent";
6515
6652
  var PI_SESSION_DIR = ".pi-sessions";
6653
+ var PI_SDK_COMPACTION_ENABLED = true;
6516
6654
  var PI_PROVIDER_LABELS = {
6517
6655
  google: "Google",
6518
6656
  openai: "OpenAI",
@@ -6711,7 +6849,7 @@ async function createPiAgentSessionForContext(ctx, sessionId) {
6711
6849
  if (launchRuntimeFields.model && launchRuntimeFields.model !== "default" && !model) {
6712
6850
  throw new Error(`Pi model not found: ${launchRuntimeFields.model}`);
6713
6851
  }
6714
- const settingsManager = SettingsManager.inMemory({ compaction: { enabled: false } });
6852
+ const settingsManager = SettingsManager.inMemory({ compaction: { enabled: PI_SDK_COMPACTION_ENABLED } });
6715
6853
  const resourceLoader = new DefaultResourceLoader({
6716
6854
  cwd: ctx.workingDirectory,
6717
6855
  agentDir,
@@ -8843,6 +8981,7 @@ var AgentProcessManager = class _AgentProcessManager {
8843
8981
  maxConcurrentAgentStarts;
8844
8982
  agentStartIntervalMs;
8845
8983
  startingInboxes = /* @__PURE__ */ new Map();
8984
+ pendingStartRebinds = /* @__PURE__ */ new Map();
8846
8985
  /** Cached configs for agents whose process exited normally — enables auto-restart on next message */
8847
8986
  idleAgentConfigs = /* @__PURE__ */ new Map();
8848
8987
  slockCliPath;
@@ -9488,6 +9627,92 @@ var AgentProcessManager = class _AgentProcessManager {
9488
9627
  ...attrs
9489
9628
  };
9490
9629
  }
9630
+ recordStartRebind(agentId, start, reason, previousLaunchId, nextLaunchId, sessionId) {
9631
+ this.recordDaemonTrace("daemon.agent.start.rebound", {
9632
+ ...this.startQueueTraceAttrs(
9633
+ agentId,
9634
+ start.config,
9635
+ start.wakeMessage,
9636
+ start.unreadSummary,
9637
+ start.resumePrompt,
9638
+ start.launchId,
9639
+ start.wakeMessageTransient ?? false
9640
+ ),
9641
+ reason,
9642
+ previous_launch_id_present: Boolean(previousLaunchId),
9643
+ next_launch_id_present: Boolean(nextLaunchId),
9644
+ session_id_present: Boolean(sessionId)
9645
+ });
9646
+ }
9647
+ sameWakeMessage(left, right) {
9648
+ if (!left || !right) return left === right;
9649
+ if (left.message_id && right.message_id) return left.message_id === right.message_id;
9650
+ return left === right;
9651
+ }
9652
+ rebindQueuedStart(agentId, start, reason) {
9653
+ const item = this.queuedAgentStarts.get(agentId);
9654
+ if (!item) {
9655
+ return false;
9656
+ }
9657
+ const previousLaunchId = item.launchId || null;
9658
+ const nextLaunchId = start.launchId || previousLaunchId;
9659
+ const previousWakeMessage = item.wakeMessage;
9660
+ if (previousWakeMessage && start.wakeMessage && !this.sameWakeMessage(previousWakeMessage, start.wakeMessage)) {
9661
+ const pending = this.startingInboxes.get(agentId) || [];
9662
+ pending.push(previousWakeMessage);
9663
+ this.startingInboxes.set(agentId, pending);
9664
+ }
9665
+ item.config = start.config;
9666
+ item.unreadSummary = start.unreadSummary;
9667
+ item.resumePrompt = start.resumePrompt;
9668
+ item.launchId = nextLaunchId || void 0;
9669
+ if (start.wakeMessage) {
9670
+ item.wakeMessage = start.wakeMessage;
9671
+ item.wakeMessageTransient = start.wakeMessageTransient;
9672
+ }
9673
+ this.recordStartRebind(
9674
+ agentId,
9675
+ { ...start, launchId: nextLaunchId || void 0 },
9676
+ reason,
9677
+ previousLaunchId,
9678
+ nextLaunchId,
9679
+ null
9680
+ );
9681
+ return true;
9682
+ }
9683
+ rebindRunningStart(agentId, start, reason) {
9684
+ const ap = this.agents.get(agentId);
9685
+ if (!ap) {
9686
+ this.pendingStartRebinds.set(agentId, start);
9687
+ return false;
9688
+ }
9689
+ const previousLaunchId = ap.launchId;
9690
+ const nextLaunchId = start.launchId || ap.launchId || null;
9691
+ const nextSessionId = ap.sessionId || start.config.sessionId || null;
9692
+ ap.launchId = nextLaunchId;
9693
+ ap.sessionId = nextSessionId;
9694
+ ap.config = {
9695
+ ...start.config,
9696
+ sessionId: nextSessionId
9697
+ };
9698
+ this.idleAgentConfigs.set(agentId, {
9699
+ config: { ...stripManagedRunnerCredential(ap.config), sessionId: nextSessionId },
9700
+ sessionId: nextSessionId,
9701
+ launchId: nextLaunchId
9702
+ });
9703
+ this.recordStartRebind(agentId, start, reason, previousLaunchId, nextLaunchId, nextSessionId);
9704
+ this.sendAgentStatus(agentId, "active", nextLaunchId);
9705
+ if (nextSessionId) {
9706
+ this.sendToServer({ type: "agent:session", agentId, sessionId: nextSessionId, launchId: nextLaunchId || void 0 });
9707
+ }
9708
+ if (start.wakeMessage) {
9709
+ const accepted = this.deliverMessage(agentId, start.wakeMessage, { transient: start.wakeMessageTransient === true });
9710
+ if (accepted instanceof Promise) {
9711
+ accepted.catch((err) => logger.error(`[Agent ${agentId}] Failed to deliver wake message after start rebind`, err));
9712
+ }
9713
+ }
9714
+ return true;
9715
+ }
9491
9716
  async startAgent(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient = false) {
9492
9717
  this.recordDaemonTrace("daemon.agent.start.requested", this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient));
9493
9718
  if (this.agents.has(agentId)) {
@@ -9495,7 +9720,8 @@ var AgentProcessManager = class _AgentProcessManager {
9495
9720
  ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
9496
9721
  reason: "already_running"
9497
9722
  });
9498
- logger.info(`[Agent ${agentId}] Start ignored (already running)`);
9723
+ this.rebindRunningStart(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient }, "already_running");
9724
+ logger.info(`[Agent ${agentId}] Start rebound (already running)`);
9499
9725
  return;
9500
9726
  }
9501
9727
  if (this.agentsStarting.has(agentId)) {
@@ -9503,7 +9729,8 @@ var AgentProcessManager = class _AgentProcessManager {
9503
9729
  ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
9504
9730
  reason: "already_starting"
9505
9731
  });
9506
- logger.info(`[Agent ${agentId}] Start ignored (startup in progress)`);
9732
+ this.pendingStartRebinds.set(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient });
9733
+ logger.info(`[Agent ${agentId}] Start rebind deferred (startup in progress)`);
9507
9734
  return;
9508
9735
  }
9509
9736
  if (this.queuedAgentStarts.has(agentId)) {
@@ -9511,7 +9738,8 @@ var AgentProcessManager = class _AgentProcessManager {
9511
9738
  ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
9512
9739
  reason: "already_queued"
9513
9740
  });
9514
- logger.info(`[Agent ${agentId}] Start ignored (startup already queued)`);
9741
+ this.rebindQueuedStart(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient }, "already_queued");
9742
+ logger.info(`[Agent ${agentId}] Queued start rebound (startup already queued)`);
9515
9743
  return;
9516
9744
  }
9517
9745
  return new Promise((resolve, reject) => {
@@ -9570,6 +9798,11 @@ var AgentProcessManager = class _AgentProcessManager {
9570
9798
  ...this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient),
9571
9799
  reason: "already_running_or_starting"
9572
9800
  });
9801
+ if (this.agents.has(item.agentId)) {
9802
+ this.rebindRunningStart(item.agentId, item, "already_running_or_starting");
9803
+ } else {
9804
+ this.pendingStartRebinds.set(item.agentId, item);
9805
+ }
9573
9806
  logger.info(`[Agent ${item.agentId}] Queued start skipped (already running or starting)`);
9574
9807
  item.resolve();
9575
9808
  this.pumpAgentStartQueue();
@@ -9656,7 +9889,8 @@ var AgentProcessManager = class _AgentProcessManager {
9656
9889
  ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
9657
9890
  reason: "already_running"
9658
9891
  });
9659
- logger.info(`[Agent ${agentId}] Start ignored (already running)`);
9892
+ this.rebindRunningStart(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient }, "already_running");
9893
+ logger.info(`[Agent ${agentId}] Start rebound (already running)`);
9660
9894
  return;
9661
9895
  }
9662
9896
  if (this.agentsStarting.has(agentId)) {
@@ -9664,7 +9898,8 @@ var AgentProcessManager = class _AgentProcessManager {
9664
9898
  ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
9665
9899
  reason: "already_starting"
9666
9900
  });
9667
- logger.info(`[Agent ${agentId}] Start ignored (startup in progress)`);
9901
+ this.pendingStartRebinds.set(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient });
9902
+ logger.info(`[Agent ${agentId}] Start rebind deferred (startup in progress)`);
9668
9903
  return;
9669
9904
  }
9670
9905
  this.agentsStarting.add(agentId);
@@ -9792,7 +10027,12 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
9792
10027
  nativeStandingPrompt: Boolean(driver.supportsNativeStandingPrompt)
9793
10028
  });
9794
10029
  const effectiveConfig = await this.buildSpawnConfig(agentId, runtimeConfig);
9795
- const canDeferEmptyStart = driver.deferSpawnUntilMessage === true && !wakeMessage && !runtimeConfig.runtimeProfileControl && (!unreadSummary || Object.keys(unreadSummary).length === 0);
10030
+ const pendingStartRebind = this.pendingStartRebinds.get(agentId);
10031
+ if (pendingStartRebind) {
10032
+ this.pendingStartRebinds.delete(agentId);
10033
+ }
10034
+ const effectiveLaunchId = pendingStartRebind?.launchId || launchId || null;
10035
+ const canDeferEmptyStart = driver.deferSpawnUntilMessage === true && !wakeMessage && !pendingStartRebind?.wakeMessage && !runtimeConfig.runtimeProfileControl && (!unreadSummary || Object.keys(unreadSummary).length === 0);
9796
10036
  if (canDeferEmptyStart) {
9797
10037
  const pendingMessages = this.startingInboxes.get(agentId) || [];
9798
10038
  this.startingInboxes.delete(agentId);
@@ -9800,12 +10040,12 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
9800
10040
  this.idleAgentConfigs.set(agentId, {
9801
10041
  config: effectiveConfig,
9802
10042
  sessionId: effectiveConfig.sessionId || null,
9803
- launchId: launchId || null
10043
+ launchId: effectiveLaunchId
9804
10044
  });
9805
- this.sendAgentStatus(agentId, "active", launchId || null);
10045
+ this.sendAgentStatus(agentId, "active", effectiveLaunchId);
9806
10046
  this.broadcastActivity(agentId, "online", "Process idle");
9807
10047
  this.recordDaemonTrace("daemon.agent.spawn.deferred", {
9808
- ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
10048
+ ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, effectiveLaunchId || void 0, wakeMessageTransient),
9809
10049
  pending_messages_count: pendingMessages.length,
9810
10050
  reason: "defer_until_concrete_message"
9811
10051
  });
@@ -9823,7 +10063,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
9823
10063
  workingDirectory: agentDataDir,
9824
10064
  slockCliPath: this.slockCliPath,
9825
10065
  daemonApiKey: this.daemonApiKey,
9826
- launchId: launchId || null,
10066
+ launchId: effectiveLaunchId,
9827
10067
  agentCredentialProxyInboxCoordinator: this.createAgentProxyInboxCoordinator(agentId),
9828
10068
  cliTransportTraceDir: this.cliTransportTraceDir
9829
10069
  };
@@ -9834,7 +10074,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
9834
10074
  inbox: wakeMessageDeliveredAsInboxUpdate && wakeMessage ? [wakeMessage, ...startingInboxMessages] : startingInboxMessages,
9835
10075
  config: runtimeConfig,
9836
10076
  sessionId: runtimeConfig.sessionId || null,
9837
- launchId: launchId || null,
10077
+ launchId: effectiveLaunchId,
9838
10078
  startupWakeMessage: wakeMessage,
9839
10079
  startupUnreadSummary: unreadSummary,
9840
10080
  startupResumePrompt: resumePrompt,
@@ -9870,8 +10110,11 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
9870
10110
  this.idleAgentConfigs.set(agentId, {
9871
10111
  config: { ...effectiveConfig, sessionId: effectiveConfig.sessionId || null },
9872
10112
  sessionId: effectiveConfig.sessionId || null,
9873
- launchId: launchId || null
10113
+ launchId: effectiveLaunchId
9874
10114
  });
10115
+ if (pendingStartRebind) {
10116
+ this.recordStartRebind(agentId, pendingStartRebind, "startup_registered", launchId || null, effectiveLaunchId, agentProcess.sessionId);
10117
+ }
9875
10118
  this.startRuntimeTrace(agentId, agentProcess, "spawn", wakeMessage ? [wakeMessage] : void 0, runtimeInputTraceAttrs);
9876
10119
  this.agentsStarting.delete(agentId);
9877
10120
  if (runtimeConfig.runtimeProfileControl) {
@@ -10106,16 +10349,26 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10106
10349
  throw new Error(`Runtime session failed to start: ${startResult.reason}${startResult.error ? ` (${startResult.error})` : ""}`);
10107
10350
  }
10108
10351
  this.recordDaemonTrace("daemon.agent.spawn.created", {
10109
- ...this.startQueueTraceAttrs(agentId, effectiveConfig, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
10352
+ ...this.startQueueTraceAttrs(agentId, effectiveConfig, wakeMessage, unreadSummary, resumePrompt, agentProcess.launchId || void 0, wakeMessageTransient),
10110
10353
  detached: false,
10111
10354
  new_session: false,
10112
10355
  process_pid_present: typeof runtime.pid === "number"
10113
10356
  });
10114
- this.sendAgentStatus(agentId, "active", launchId || null);
10357
+ this.sendAgentStatus(agentId, "active", agentProcess.launchId);
10358
+ if (pendingStartRebind && agentProcess.sessionId) {
10359
+ this.sendToServer({ type: "agent:session", agentId, sessionId: agentProcess.sessionId, launchId: agentProcess.launchId || void 0 });
10360
+ }
10361
+ if (pendingStartRebind?.wakeMessage) {
10362
+ const accepted = this.deliverMessage(agentId, pendingStartRebind.wakeMessage, { transient: pendingStartRebind.wakeMessageTransient === true });
10363
+ if (accepted instanceof Promise) {
10364
+ accepted.catch((err) => logger.error(`[Agent ${agentId}] Failed to deliver wake message after startup rebind`, err));
10365
+ }
10366
+ }
10115
10367
  this.broadcastActivity(agentId, "working", "Starting\u2026");
10116
10368
  this.startRuntimeStartupTimeout(agentId, agentProcess);
10117
10369
  } catch (err) {
10118
10370
  this.agentsStarting.delete(agentId);
10371
+ this.pendingStartRebinds.delete(agentId);
10119
10372
  this.cleanupFailedRuntimeStart(agentId, agentProcess, err);
10120
10373
  throw err;
10121
10374
  }
@@ -10384,6 +10637,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10384
10637
  }
10385
10638
  async stopAgent(agentId, { wait = false, silent = false } = {}) {
10386
10639
  this.cancelQueuedAgentStart(agentId, "stop requested");
10640
+ this.pendingStartRebinds.delete(agentId);
10387
10641
  this.idleAgentConfigs.delete(agentId);
10388
10642
  const ap = this.agents.get(agentId);
10389
10643
  if (!ap) {