@adhdev/daemon-standalone 0.9.32 → 0.9.34

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
@@ -29560,13 +29560,14 @@ var require_dist2 = __commonJS({
29560
29560
  function hydrateCliParsedMessages(parsedMessages, options) {
29561
29561
  const { committedMessages, scope, lastOutputAt } = options;
29562
29562
  const referenceMessages = [...committedMessages];
29563
+ const referenceComparables = referenceMessages.map((message) => normalizeComparableMessageContent(message?.content || ""));
29563
29564
  const usedReferenceIndexes = /* @__PURE__ */ new Set();
29564
29565
  const now = options.now ?? Date.now();
29565
29566
  const findReferenceTimestamp = (role, content, parsedIndex) => {
29566
29567
  const normalizedContent = normalizeComparableMessageContent(content);
29567
29568
  if (!normalizedContent) return void 0;
29568
29569
  const sameIndex = referenceMessages[parsedIndex];
29569
- if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && normalizeComparableMessageContent(sameIndex.content) === normalizedContent && typeof sameIndex.timestamp === "number" && Number.isFinite(sameIndex.timestamp)) {
29570
+ if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && referenceComparables[parsedIndex] === normalizedContent && typeof sameIndex.timestamp === "number" && Number.isFinite(sameIndex.timestamp)) {
29570
29571
  usedReferenceIndexes.add(parsedIndex);
29571
29572
  return sameIndex.timestamp;
29572
29573
  }
@@ -29574,7 +29575,7 @@ var require_dist2 = __commonJS({
29574
29575
  if (usedReferenceIndexes.has(i)) continue;
29575
29576
  const candidate = referenceMessages[i];
29576
29577
  if (!candidate || candidate.role !== role) continue;
29577
- const candidateContent = normalizeComparableMessageContent(candidate.content);
29578
+ const candidateContent = referenceComparables[i];
29578
29579
  if (!candidateContent) continue;
29579
29580
  const exactMatch = candidateContent === normalizedContent;
29580
29581
  const fuzzyMatch = candidateContent.includes(normalizedContent) || normalizedContent.includes(candidateContent);
@@ -30663,7 +30664,7 @@ var require_dist2 = __commonJS({
30663
30664
  return;
30664
30665
  }
30665
30666
  if (this.currentTurnScope && !lastParsedAssistant) {
30666
- LOG2.info(
30667
+ LOG2.debug(
30667
30668
  "CLI",
30668
30669
  `[${this.cliType}] Settled without assistant: prompt=${JSON.stringify(this.currentTurnScope.prompt).slice(0, 140)} responseBuffer=${JSON.stringify(summarizeCliTraceText(this.responseBuffer, 220)).slice(0, 260)} screen=${JSON.stringify(summarizeCliTraceText(screenText, 220)).slice(0, 260)} providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"}`
30669
30670
  );
@@ -31479,9 +31480,43 @@ var require_dist2 = __commonJS({
31479
31480
  }
31480
31481
  armResponseTimeout() {
31481
31482
  if (this.responseTimeout) clearTimeout(this.responseTimeout);
31483
+ const timeoutMs = this.timeouts.maxResponse;
31484
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
31485
+ this.responseTimeout = null;
31486
+ return;
31487
+ }
31482
31488
  this.responseTimeout = setTimeout(() => {
31483
- if (this.isWaitingForResponse) this.finishResponse();
31484
- }, this.timeouts.maxResponse);
31489
+ this.responseTimeout = null;
31490
+ if (!this.isWaitingForResponse) return;
31491
+ const detectedStatusBeforeEval = this.runDetectStatus(this.recentOutputBuffer);
31492
+ this.recordTrace("response_timeout_check", {
31493
+ timeoutMs,
31494
+ detectedStatus: detectedStatusBeforeEval,
31495
+ currentStatus: this.currentStatus,
31496
+ isWaitingForResponse: this.isWaitingForResponse,
31497
+ hasActionableApproval: this.hasActionableApproval(),
31498
+ ...buildCliTraceParseSnapshot({
31499
+ accumulatedBuffer: this.accumulatedBuffer,
31500
+ accumulatedRawBuffer: this.accumulatedRawBuffer,
31501
+ responseBuffer: this.responseBuffer,
31502
+ partialResponse: this.responseBuffer,
31503
+ scope: this.currentTurnScope
31504
+ })
31505
+ });
31506
+ this.settledBuffer = this.recentOutputBuffer;
31507
+ this.evaluateSettled();
31508
+ if (this.isWaitingForResponse && !this.hasActionableApproval()) {
31509
+ const detectedStatusAfterEval = this.runDetectStatus(this.recentOutputBuffer);
31510
+ this.recordTrace("response_timeout_kept_open", {
31511
+ timeoutMs,
31512
+ detectedStatusBeforeEval,
31513
+ detectedStatusAfterEval,
31514
+ currentStatus: this.currentStatus,
31515
+ isWaitingForResponse: this.isWaitingForResponse
31516
+ });
31517
+ this.armResponseTimeout();
31518
+ }
31519
+ }, timeoutMs);
31485
31520
  }
31486
31521
  writeSubmitKeyForRetry(mode) {
31487
31522
  void this.writeToPty(this.sendKey).catch((error48) => {
@@ -38292,6 +38327,26 @@ ${effect.notification.body || ""}`.trim();
38292
38327
  historyDedupKey: deriveHistoryDedupKey(message)
38293
38328
  }));
38294
38329
  }
38330
+ function findLastMessageIndexBySignature(messages, signature) {
38331
+ if (!signature) return -1;
38332
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
38333
+ if (getChatMessageSignature(messages[index]) === signature) {
38334
+ return index;
38335
+ }
38336
+ }
38337
+ return -1;
38338
+ }
38339
+ function buildBoundedTailSync(messages, cursor) {
38340
+ const totalMessages = messages.length;
38341
+ const tailMessages = cursor.tailLimit > 0 && totalMessages > cursor.tailLimit ? messages.slice(-cursor.tailLimit) : messages;
38342
+ return {
38343
+ syncMode: "full",
38344
+ replaceFrom: 0,
38345
+ messages: tailMessages,
38346
+ totalMessages,
38347
+ lastMessageSignature: getChatMessageSignature(messages[totalMessages - 1])
38348
+ };
38349
+ }
38295
38350
  function computeReadChatSync(messages, cursor) {
38296
38351
  const totalMessages = messages.length;
38297
38352
  const lastMessageSignature = getChatMessageSignature(messages[totalMessages - 1]);
@@ -38323,6 +38378,15 @@ ${effect.notification.body || ""}`.trim();
38323
38378
  lastMessageSignature
38324
38379
  };
38325
38380
  }
38381
+ if (cursor.tailLimit > 0 && knownSignature === lastMessageSignature) {
38382
+ return {
38383
+ syncMode: "noop",
38384
+ replaceFrom: totalMessages,
38385
+ messages: [],
38386
+ totalMessages,
38387
+ lastMessageSignature
38388
+ };
38389
+ }
38326
38390
  if (knownMessageCount < totalMessages) {
38327
38391
  const anchorSignature = getChatMessageSignature(messages[knownMessageCount - 1]);
38328
38392
  if (anchorSignature === knownSignature) {
@@ -38334,6 +38398,19 @@ ${effect.notification.body || ""}`.trim();
38334
38398
  lastMessageSignature
38335
38399
  };
38336
38400
  }
38401
+ if (cursor.tailLimit > 0) {
38402
+ const signatureIndex = findLastMessageIndexBySignature(messages, knownSignature);
38403
+ if (signatureIndex >= 0) {
38404
+ return {
38405
+ syncMode: "append",
38406
+ replaceFrom: knownMessageCount,
38407
+ messages: messages.slice(signatureIndex + 1),
38408
+ totalMessages,
38409
+ lastMessageSignature
38410
+ };
38411
+ }
38412
+ return buildBoundedTailSync(messages, cursor);
38413
+ }
38337
38414
  }
38338
38415
  const replaceFrom = Math.max(0, Math.min(knownMessageCount - 1, totalMessages));
38339
38416
  return {
@@ -41122,6 +41199,20 @@ ${effect.notification.body || ""}`.trim();
41122
41199
  getPresentationMode() {
41123
41200
  return this.presentationMode;
41124
41201
  }
41202
+ getHotChatSessionState() {
41203
+ const adapterStatus = this.adapter.getStatus();
41204
+ const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
41205
+ const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
41206
+ const runtime = this.adapter.getRuntimeMetadata();
41207
+ return {
41208
+ id: this.instanceId,
41209
+ status: visibleStatus,
41210
+ runtimeLifecycle: runtime?.lifecycle ?? null,
41211
+ runtimeSurfaceKind: runtime?.surfaceKind,
41212
+ runtimeRestoredFromStorage: runtime?.restoredFromStorage === true,
41213
+ runtimeRecoveryState: runtime?.recoveryState ?? null
41214
+ };
41215
+ }
41125
41216
  updateSettings(newSettings) {
41126
41217
  this.settings = { ...newSettings };
41127
41218
  this.adapter.updateRuntimeSettings?.(this.settings);
@@ -41277,6 +41368,15 @@ ${effect.notification.body || ""}`.trim();
41277
41368
  this.completedDebouncePending = { chatTitle, duration: duration3, timestamp: now };
41278
41369
  this.completedDebounceTimer = setTimeout(() => {
41279
41370
  if (this.completedDebouncePending) {
41371
+ const latestStatus = this.adapter.getStatus();
41372
+ const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldAutoApprove();
41373
+ const latestVisibleStatus = latestAutoApproveActive ? "generating" : latestStatus.status;
41374
+ if (latestVisibleStatus !== "idle") {
41375
+ LOG2.info("CLI", `[${this.type}] cancelled pending completed (resumed ${latestVisibleStatus})`);
41376
+ this.completedDebouncePending = null;
41377
+ this.completedDebounceTimer = null;
41378
+ return;
41379
+ }
41280
41380
  LOG2.info("CLI", `[${this.type}] completed in ${this.completedDebouncePending.duration}s`);
41281
41381
  this.pushEvent({ event: "agent:generating_completed", ...this.completedDebouncePending });
41282
41382
  this.completedDebouncePending = null;
@@ -44296,10 +44396,22 @@ Run 'adhdev doctor' for detailed diagnostics.`
44296
44396
  setMachineProviderEnabled(type, enabled) {
44297
44397
  return this.setMachineProviderConfig(type, { enabled });
44298
44398
  }
44399
+ getEffectiveProviderAvailability(type) {
44400
+ const providerType = this.resolveAlias(type);
44401
+ const availability = this.providerAvailability.get(providerType);
44402
+ if (availability) return availability;
44403
+ const machineConfig = this.getMachineProviderConfig(providerType);
44404
+ const lastDetection = machineConfig.lastDetection;
44405
+ if (!lastDetection) return void 0;
44406
+ return {
44407
+ installed: lastDetection.ok === true,
44408
+ detectedPath: typeof lastDetection.path === "string" && lastDetection.path.trim() ? lastDetection.path.trim() : null
44409
+ };
44410
+ }
44299
44411
  getMachineProviderStatus(type) {
44300
44412
  const providerType = this.resolveAlias(type);
44301
44413
  if (!this.isMachineProviderEnabled(providerType)) return "disabled";
44302
- const availability = this.providerAvailability.get(providerType);
44414
+ const availability = this.getEffectiveProviderAvailability(providerType);
44303
44415
  if (!availability) return "enabled_unchecked";
44304
44416
  return availability.installed ? "detected" : "not_detected";
44305
44417
  }
@@ -44427,7 +44539,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
44427
44539
  }
44428
44540
  getAvailableProviderInfos() {
44429
44541
  return this.getAll().map((provider) => {
44430
- const availability = this.providerAvailability.get(provider.type);
44542
+ const availability = this.getEffectiveProviderAvailability(provider.type);
44431
44543
  const enabled = this.isMachineProviderEnabled(provider.type);
44432
44544
  const machineConfig = this.getMachineProviderConfig(provider.type);
44433
44545
  return {
@@ -46243,6 +46355,51 @@ Run 'adhdev doctor' for detailed diagnostics.`
46243
46355
  return false;
46244
46356
  }
46245
46357
  }
46358
+ function getWindowsProcessCommandLine(pid) {
46359
+ const pidFilter = `ProcessId=${pid}`;
46360
+ try {
46361
+ const psOut = (0, import_child_process8.execFileSync)("powershell.exe", [
46362
+ "-NoProfile",
46363
+ "-NonInteractive",
46364
+ "-ExecutionPolicy",
46365
+ "Bypass",
46366
+ "-Command",
46367
+ `(Get-CimInstance Win32_Process -Filter "${pidFilter}").CommandLine`
46368
+ ], { encoding: "utf8", timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).trim();
46369
+ if (psOut) return psOut;
46370
+ } catch {
46371
+ }
46372
+ try {
46373
+ const wmicOut = (0, import_child_process8.execFileSync)("wmic", [
46374
+ "process",
46375
+ "where",
46376
+ pidFilter,
46377
+ "get",
46378
+ "CommandLine"
46379
+ ], { encoding: "utf8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }).trim();
46380
+ if (wmicOut) return wmicOut;
46381
+ } catch {
46382
+ }
46383
+ return null;
46384
+ }
46385
+ function getProcessCommandLine(pid) {
46386
+ if (!Number.isFinite(pid) || pid <= 0) return null;
46387
+ if (process.platform === "win32") return getWindowsProcessCommandLine(pid);
46388
+ try {
46389
+ const text = (0, import_child_process8.execFileSync)("ps", ["-o", "command=", "-p", String(pid)], {
46390
+ encoding: "utf8",
46391
+ timeout: 3e3,
46392
+ stdio: ["ignore", "pipe", "ignore"]
46393
+ }).trim();
46394
+ return text || null;
46395
+ } catch {
46396
+ return null;
46397
+ }
46398
+ }
46399
+ function isManagedSessionHostPid(pid) {
46400
+ const commandLine = getProcessCommandLine(pid);
46401
+ return !!commandLine && /session-host-daemon/i.test(commandLine);
46402
+ }
46246
46403
  async function waitForPidExit(pid, timeoutMs) {
46247
46404
  const start = Date.now();
46248
46405
  while (Date.now() - start < timeoutMs) {
@@ -46259,7 +46416,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
46259
46416
  try {
46260
46417
  if (fs8.existsSync(pidFile)) {
46261
46418
  const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
46262
- if (Number.isFinite(pid)) {
46419
+ if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
46263
46420
  killPid2(pid);
46264
46421
  }
46265
46422
  }
@@ -46270,18 +46427,6 @@ Run 'adhdev doctor' for detailed diagnostics.`
46270
46427
  } catch {
46271
46428
  }
46272
46429
  }
46273
- if (process.platform !== "win32") {
46274
- try {
46275
- const raw = (0, import_child_process8.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
46276
- for (const line of raw.split("\n")) {
46277
- const pid = Number.parseInt(line.trim(), 10);
46278
- if (Number.isFinite(pid)) {
46279
- killPid2(pid);
46280
- }
46281
- }
46282
- } catch {
46283
- }
46284
- }
46285
46430
  }
46286
46431
  function removeDaemonPidFile() {
46287
46432
  const pidFile = path16.join(os17.homedir(), ".adhdev", "daemon.pid");
@@ -48494,6 +48639,20 @@ Run 'adhdev doctor' for detailed diagnostics.`
48494
48639
  }
48495
48640
  }
48496
48641
  init_logger();
48642
+ function projectHotChatSessionStatesFromProviderState(state) {
48643
+ const project = (item) => ({
48644
+ id: item.instanceId,
48645
+ status: item.activeChat?.status || item.status,
48646
+ runtimeLifecycle: item.runtime?.lifecycle ?? null,
48647
+ runtimeSurfaceKind: item.runtime?.surfaceKind,
48648
+ runtimeRestoredFromStorage: item.runtime?.restoredFromStorage === true,
48649
+ runtimeRecoveryState: item.runtime?.recoveryState ?? null
48650
+ });
48651
+ if (state.category === "ide") {
48652
+ return [project(state), ...state.extensions.map(project)];
48653
+ }
48654
+ return [project(state)];
48655
+ }
48497
48656
  var ProviderInstanceManager = class {
48498
48657
  instances = /* @__PURE__ */ new Map();
48499
48658
  tickTimer = null;
@@ -48589,6 +48748,27 @@ Run 'adhdev doctor' for detailed diagnostics.`
48589
48748
  }
48590
48749
  return states;
48591
48750
  }
48751
+ collectHotChatSessionStates() {
48752
+ const sessions = [];
48753
+ for (const [id, instance] of this.instances) {
48754
+ try {
48755
+ const projected = instance.getHotChatSessionState?.();
48756
+ if (Array.isArray(projected)) {
48757
+ sessions.push(...projected.filter((session) => !!session?.id));
48758
+ continue;
48759
+ }
48760
+ if (projected?.id) {
48761
+ sessions.push(projected);
48762
+ continue;
48763
+ }
48764
+ const state = instance.getState();
48765
+ sessions.push(...projectHotChatSessionStatesFromProviderState(state));
48766
+ } catch (e) {
48767
+ LOG2.warn("InstanceMgr", `[InstanceManager] Failed to collect hot chat metadata from ${id}: ${e.message}`);
48768
+ }
48769
+ }
48770
+ return sessions;
48771
+ }
48592
48772
  /**
48593
48773
  * Per-category status collect
48594
48774
  */