@adhdev/daemon-standalone 0.9.33 → 0.9.35

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);
@@ -29953,6 +29954,8 @@ var require_dist2 = __commonJS({
29953
29954
  messages = [];
29954
29955
  committedMessages = [];
29955
29956
  structuredMessages = [];
29957
+ committedMessagesActivitySignature = "";
29958
+ committedMessagesChangedAt = 0;
29956
29959
  currentStatus = "starting";
29957
29960
  onStatusChange = null;
29958
29961
  responseBuffer = "";
@@ -30034,10 +30037,35 @@ var require_dist2 = __commonJS({
30034
30037
  providerResolutionMeta;
30035
30038
  static FINISH_RETRY_DELAY_MS = 300;
30036
30039
  static MAX_FINISH_RETRIES = 2;
30040
+ buildCommittedMessagesActivitySignature() {
30041
+ const last = this.committedMessages[this.committedMessages.length - 1];
30042
+ return [
30043
+ String(this.committedMessages.length),
30044
+ String(last?.role || ""),
30045
+ String(last?.kind || ""),
30046
+ String(last?.senderName || ""),
30047
+ String(last?.timestamp || ""),
30048
+ String(last?.receivedAt || ""),
30049
+ normalizeComparableMessageContent(last?.content || "").slice(-240)
30050
+ ].join("|");
30051
+ }
30037
30052
  syncMessageViews() {
30053
+ const signature = this.buildCommittedMessagesActivitySignature();
30054
+ if (signature !== this.committedMessagesActivitySignature) {
30055
+ this.committedMessagesActivitySignature = signature;
30056
+ this.committedMessagesChangedAt = Date.now();
30057
+ }
30038
30058
  this.messages = [...this.committedMessages];
30039
30059
  this.structuredMessages = [...this.committedMessages];
30040
30060
  }
30061
+ getLastCommittedMessageActivityAt() {
30062
+ const last = this.committedMessages[this.committedMessages.length - 1];
30063
+ const messageTime = Math.max(
30064
+ typeof last?.receivedAt === "number" && Number.isFinite(last.receivedAt) ? last.receivedAt : 0,
30065
+ typeof last?.timestamp === "number" && Number.isFinite(last.timestamp) ? last.timestamp : 0
30066
+ );
30067
+ return Math.max(messageTime, this.committedMessagesChangedAt || 0);
30068
+ }
30041
30069
  readTerminalScreenText(now = Date.now()) {
30042
30070
  const screenText = this.terminalScreen.getText() || "";
30043
30071
  this.lastScreenText = screenText;
@@ -30177,9 +30205,16 @@ var require_dist2 = __commonJS({
30177
30205
  /** Inject CLI scripts after construction (e.g. when resolved by ProviderLoader) */
30178
30206
  setCliScripts(scripts) {
30179
30207
  this.cliScripts = scripts;
30208
+ this.parsedStatusCache = null;
30209
+ this.parseErrorMessage = null;
30180
30210
  const scriptNames = listCliScriptNames(scripts);
30181
30211
  LOG2.info("CLI", `[${this.cliType}] CLI scripts injected: [${scriptNames.join(", ")}]`);
30182
30212
  }
30213
+ /** Refresh provider scripts/config used by this adapter without restarting the PTY runtime. */
30214
+ refreshProviderDefinition(provider) {
30215
+ this.provider = provider;
30216
+ this.setCliScripts(provider.scripts || {});
30217
+ }
30183
30218
  updateRuntimeSettings(settings) {
30184
30219
  this.runtimeSettings = { ...settings };
30185
30220
  }
@@ -30663,7 +30698,7 @@ var require_dist2 = __commonJS({
30663
30698
  return;
30664
30699
  }
30665
30700
  if (this.currentTurnScope && !lastParsedAssistant) {
30666
- LOG2.info(
30701
+ LOG2.debug(
30667
30702
  "CLI",
30668
30703
  `[${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
30704
  );
@@ -31479,9 +31514,43 @@ var require_dist2 = __commonJS({
31479
31514
  }
31480
31515
  armResponseTimeout() {
31481
31516
  if (this.responseTimeout) clearTimeout(this.responseTimeout);
31517
+ const timeoutMs = this.timeouts.maxResponse;
31518
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
31519
+ this.responseTimeout = null;
31520
+ return;
31521
+ }
31482
31522
  this.responseTimeout = setTimeout(() => {
31483
- if (this.isWaitingForResponse) this.finishResponse();
31484
- }, this.timeouts.maxResponse);
31523
+ this.responseTimeout = null;
31524
+ if (!this.isWaitingForResponse) return;
31525
+ const detectedStatusBeforeEval = this.runDetectStatus(this.recentOutputBuffer);
31526
+ this.recordTrace("response_timeout_check", {
31527
+ timeoutMs,
31528
+ detectedStatus: detectedStatusBeforeEval,
31529
+ currentStatus: this.currentStatus,
31530
+ isWaitingForResponse: this.isWaitingForResponse,
31531
+ hasActionableApproval: this.hasActionableApproval(),
31532
+ ...buildCliTraceParseSnapshot({
31533
+ accumulatedBuffer: this.accumulatedBuffer,
31534
+ accumulatedRawBuffer: this.accumulatedRawBuffer,
31535
+ responseBuffer: this.responseBuffer,
31536
+ partialResponse: this.responseBuffer,
31537
+ scope: this.currentTurnScope
31538
+ })
31539
+ });
31540
+ this.settledBuffer = this.recentOutputBuffer;
31541
+ this.evaluateSettled();
31542
+ if (this.isWaitingForResponse && !this.hasActionableApproval()) {
31543
+ const detectedStatusAfterEval = this.runDetectStatus(this.recentOutputBuffer);
31544
+ this.recordTrace("response_timeout_kept_open", {
31545
+ timeoutMs,
31546
+ detectedStatusBeforeEval,
31547
+ detectedStatusAfterEval,
31548
+ currentStatus: this.currentStatus,
31549
+ isWaitingForResponse: this.isWaitingForResponse
31550
+ });
31551
+ this.armResponseTimeout();
31552
+ }
31553
+ }, timeoutMs);
31485
31554
  }
31486
31555
  writeSubmitKeyForRetry(mode) {
31487
31556
  void this.writeToPty(this.sendKey).catch((error48) => {
@@ -40712,7 +40781,14 @@ ${effect.notification.body || ""}`.trim();
40712
40781
  await this._ctx.providerLoader.fetchLatest().catch(() => {
40713
40782
  });
40714
40783
  this._ctx.providerLoader.reload();
40715
- return { success: true };
40784
+ this._ctx.providerLoader.registerToDetector();
40785
+ const refreshedInstances = this._ctx.instanceManager ? this._ctx.instanceManager.refreshProviderDefinitions((providerType) => this._ctx.providerLoader.resolve(providerType)) : 0;
40786
+ const providers = this._ctx.providerLoader.getAll().map((provider) => ({
40787
+ type: provider.type,
40788
+ name: provider.name,
40789
+ category: provider.category
40790
+ }));
40791
+ return { success: true, refreshedInstances, providers };
40716
40792
  }
40717
40793
  return { success: false, error: "ProviderLoader not initialized" };
40718
40794
  }
@@ -40959,6 +41035,11 @@ ${effect.notification.body || ""}`.trim();
40959
41035
  launchMode;
40960
41036
  startedAt = Date.now();
40961
41037
  onProviderSessionResolved;
41038
+ refreshProviderDefinition(provider) {
41039
+ if (provider.type !== this.type || provider.category !== "cli") return;
41040
+ this.provider = provider;
41041
+ this.adapter.refreshProviderDefinition(provider);
41042
+ }
40962
41043
  // ─── Lifecycle ─────────────────────────────────
40963
41044
  async init(context) {
40964
41045
  this.context = context;
@@ -41164,6 +41245,22 @@ ${effect.notification.body || ""}`.trim();
41164
41245
  getPresentationMode() {
41165
41246
  return this.presentationMode;
41166
41247
  }
41248
+ getHotChatSessionState() {
41249
+ const adapterStatus = this.adapter.getStatus();
41250
+ const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
41251
+ const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
41252
+ const runtime = this.adapter.getRuntimeMetadata();
41253
+ const lastCommittedMessageActivityAt = typeof this.adapter.getLastCommittedMessageActivityAt === "function" ? this.adapter.getLastCommittedMessageActivityAt() : 0;
41254
+ return {
41255
+ id: this.instanceId,
41256
+ status: visibleStatus,
41257
+ lastMessageAt: lastCommittedMessageActivityAt || void 0,
41258
+ runtimeLifecycle: runtime?.lifecycle ?? null,
41259
+ runtimeSurfaceKind: runtime?.surfaceKind,
41260
+ runtimeRestoredFromStorage: runtime?.restoredFromStorage === true,
41261
+ runtimeRecoveryState: runtime?.recoveryState ?? null
41262
+ };
41263
+ }
41167
41264
  updateSettings(newSettings) {
41168
41265
  this.settings = { ...newSettings };
41169
41266
  this.adapter.updateRuntimeSettings?.(this.settings);
@@ -41319,6 +41416,15 @@ ${effect.notification.body || ""}`.trim();
41319
41416
  this.completedDebouncePending = { chatTitle, duration: duration3, timestamp: now };
41320
41417
  this.completedDebounceTimer = setTimeout(() => {
41321
41418
  if (this.completedDebouncePending) {
41419
+ const latestStatus = this.adapter.getStatus();
41420
+ const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldAutoApprove();
41421
+ const latestVisibleStatus = latestAutoApproveActive ? "generating" : latestStatus.status;
41422
+ if (latestVisibleStatus !== "idle") {
41423
+ LOG2.info("CLI", `[${this.type}] cancelled pending completed (resumed ${latestVisibleStatus})`);
41424
+ this.completedDebouncePending = null;
41425
+ this.completedDebounceTimer = null;
41426
+ return;
41427
+ }
41322
41428
  LOG2.info("CLI", `[${this.type}] completed in ${this.completedDebouncePending.duration}s`);
41323
41429
  this.pushEvent({ event: "agent:generating_completed", ...this.completedDebouncePending });
41324
41430
  this.completedDebouncePending = null;
@@ -46297,6 +46403,51 @@ Run 'adhdev doctor' for detailed diagnostics.`
46297
46403
  return false;
46298
46404
  }
46299
46405
  }
46406
+ function getWindowsProcessCommandLine(pid) {
46407
+ const pidFilter = `ProcessId=${pid}`;
46408
+ try {
46409
+ const psOut = (0, import_child_process8.execFileSync)("powershell.exe", [
46410
+ "-NoProfile",
46411
+ "-NonInteractive",
46412
+ "-ExecutionPolicy",
46413
+ "Bypass",
46414
+ "-Command",
46415
+ `(Get-CimInstance Win32_Process -Filter "${pidFilter}").CommandLine`
46416
+ ], { encoding: "utf8", timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).trim();
46417
+ if (psOut) return psOut;
46418
+ } catch {
46419
+ }
46420
+ try {
46421
+ const wmicOut = (0, import_child_process8.execFileSync)("wmic", [
46422
+ "process",
46423
+ "where",
46424
+ pidFilter,
46425
+ "get",
46426
+ "CommandLine"
46427
+ ], { encoding: "utf8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }).trim();
46428
+ if (wmicOut) return wmicOut;
46429
+ } catch {
46430
+ }
46431
+ return null;
46432
+ }
46433
+ function getProcessCommandLine(pid) {
46434
+ if (!Number.isFinite(pid) || pid <= 0) return null;
46435
+ if (process.platform === "win32") return getWindowsProcessCommandLine(pid);
46436
+ try {
46437
+ const text = (0, import_child_process8.execFileSync)("ps", ["-o", "command=", "-p", String(pid)], {
46438
+ encoding: "utf8",
46439
+ timeout: 3e3,
46440
+ stdio: ["ignore", "pipe", "ignore"]
46441
+ }).trim();
46442
+ return text || null;
46443
+ } catch {
46444
+ return null;
46445
+ }
46446
+ }
46447
+ function isManagedSessionHostPid(pid) {
46448
+ const commandLine = getProcessCommandLine(pid);
46449
+ return !!commandLine && /session-host-daemon/i.test(commandLine);
46450
+ }
46300
46451
  async function waitForPidExit(pid, timeoutMs) {
46301
46452
  const start = Date.now();
46302
46453
  while (Date.now() - start < timeoutMs) {
@@ -46313,7 +46464,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
46313
46464
  try {
46314
46465
  if (fs8.existsSync(pidFile)) {
46315
46466
  const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
46316
- if (Number.isFinite(pid)) {
46467
+ if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
46317
46468
  killPid2(pid);
46318
46469
  }
46319
46470
  }
@@ -46324,18 +46475,6 @@ Run 'adhdev doctor' for detailed diagnostics.`
46324
46475
  } catch {
46325
46476
  }
46326
46477
  }
46327
- if (process.platform !== "win32") {
46328
- try {
46329
- const raw = (0, import_child_process8.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
46330
- for (const line of raw.split("\n")) {
46331
- const pid = Number.parseInt(line.trim(), 10);
46332
- if (Number.isFinite(pid)) {
46333
- killPid2(pid);
46334
- }
46335
- }
46336
- } catch {
46337
- }
46338
- }
46339
46478
  }
46340
46479
  function removeDaemonPidFile() {
46341
46480
  const pidFile = path16.join(os17.homedir(), ".adhdev", "daemon.pid");
@@ -48548,6 +48687,23 @@ Run 'adhdev doctor' for detailed diagnostics.`
48548
48687
  }
48549
48688
  }
48550
48689
  init_logger();
48690
+ function projectHotChatSessionStatesFromProviderState(state) {
48691
+ const project = (item) => ({
48692
+ id: item.instanceId,
48693
+ status: item.activeChat?.status || item.status,
48694
+ unread: item.unread,
48695
+ inboxBucket: item.inboxBucket,
48696
+ lastMessageAt: item.lastMessageAt ?? item.activeChat?.lastMessageAt,
48697
+ runtimeLifecycle: item.runtime?.lifecycle ?? null,
48698
+ runtimeSurfaceKind: item.runtime?.surfaceKind,
48699
+ runtimeRestoredFromStorage: item.runtime?.restoredFromStorage === true,
48700
+ runtimeRecoveryState: item.runtime?.recoveryState ?? null
48701
+ });
48702
+ if (state.category === "ide") {
48703
+ return [project(state), ...state.extensions.map(project)];
48704
+ }
48705
+ return [project(state)];
48706
+ }
48551
48707
  var ProviderInstanceManager = class {
48552
48708
  instances = /* @__PURE__ */ new Map();
48553
48709
  tickTimer = null;
@@ -48643,6 +48799,27 @@ Run 'adhdev doctor' for detailed diagnostics.`
48643
48799
  }
48644
48800
  return states;
48645
48801
  }
48802
+ collectHotChatSessionStates() {
48803
+ const sessions = [];
48804
+ for (const [id, instance] of this.instances) {
48805
+ try {
48806
+ const projected = instance.getHotChatSessionState?.();
48807
+ if (Array.isArray(projected)) {
48808
+ sessions.push(...projected.filter((session) => !!session?.id));
48809
+ continue;
48810
+ }
48811
+ if (projected?.id) {
48812
+ sessions.push(projected);
48813
+ continue;
48814
+ }
48815
+ const state = instance.getState();
48816
+ sessions.push(...projectHotChatSessionStatesFromProviderState(state));
48817
+ } catch (e) {
48818
+ LOG2.warn("InstanceMgr", `[InstanceManager] Failed to collect hot chat metadata from ${id}: ${e.message}`);
48819
+ }
48820
+ }
48821
+ return sessions;
48822
+ }
48646
48823
  /**
48647
48824
  * Per-category status collect
48648
48825
  */
@@ -48724,6 +48901,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
48724
48901
  }
48725
48902
  return updated;
48726
48903
  }
48904
+ refreshProviderDefinitions(resolveProvider) {
48905
+ let refreshed = 0;
48906
+ for (const instance of this.instances.values()) {
48907
+ if (typeof instance.refreshProviderDefinition !== "function") continue;
48908
+ const provider = resolveProvider(instance.type);
48909
+ if (!provider || typeof provider !== "object") continue;
48910
+ instance.refreshProviderDefinition(provider);
48911
+ refreshed += 1;
48912
+ }
48913
+ return refreshed;
48914
+ }
48727
48915
  // ─── cleanup ──────────────────────────────────────
48728
48916
  /**
48729
48917
  * All terminate
@@ -52950,20 +53138,7 @@ data: ${JSON.stringify(msg.data)}
52950
53138
  async handleReload(_req, res) {
52951
53139
  try {
52952
53140
  this.providerLoader.reload();
52953
- let refreshedInstances = 0;
52954
- if (this.instanceManager) {
52955
- for (const id of this.instanceManager.listInstanceIds()) {
52956
- const instance = this.instanceManager.getInstance(id);
52957
- const providerType = typeof instance?.type === "string" ? instance.type : "";
52958
- if (!providerType) continue;
52959
- const resolved = this.providerLoader.resolve(providerType);
52960
- if (!resolved) continue;
52961
- if (instance && typeof instance === "object" && "provider" in instance) {
52962
- instance.provider = resolved;
52963
- refreshedInstances += 1;
52964
- }
52965
- }
52966
- }
53141
+ const refreshedInstances = this.instanceManager ? this.instanceManager.refreshProviderDefinitions((providerType) => this.providerLoader.resolve(providerType)) : 0;
52967
53142
  const providers = this.providerLoader.getAll().map((p) => ({
52968
53143
  type: p.type,
52969
53144
  name: p.name,