@adhdev/daemon-standalone 0.9.31 → 0.9.33

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
@@ -28204,14 +28204,13 @@ var require_dist2 = __commonJS({
28204
28204
  const shouldOutput = LEVEL_NUM[level] >= LEVEL_NUM[currentLevel];
28205
28205
  const label = LEVEL_LABEL[level];
28206
28206
  const line = `[${ts2()}] [${label}] [${category}] ${msg}`;
28207
+ if (!shouldOutput) return;
28207
28208
  writeToFile(line);
28208
28209
  ringBuffer.push({ ts: Date.now(), level, category, message: msg });
28209
28210
  if (ringBuffer.length > RING_BUFFER_SIZE) {
28210
28211
  ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
28211
28212
  }
28212
- if (shouldOutput) {
28213
- origConsoleLog(line);
28214
- }
28213
+ origConsoleLog(line);
28215
28214
  }
28216
28215
  function installGlobalInterceptor() {
28217
28216
  if (interceptorInstalled) return;
@@ -30031,6 +30030,7 @@ var require_dist2 = __commonJS({
30031
30030
  static STATUS_HOT_PATH_PARSE_MIN_INTERVAL_MS = 1e3;
30032
30031
  static SCREEN_SNAPSHOT_MIN_INTERVAL_MS = 250;
30033
30032
  static MAX_TRACE_ENTRIES = 250;
30033
+ static PARSE_MESSAGE_TAIL_LIMIT = 100;
30034
30034
  providerResolutionMeta;
30035
30035
  static FINISH_RETRY_DELAY_MS = 300;
30036
30036
  static MAX_FINISH_RETRIES = 2;
@@ -30062,6 +30062,32 @@ var require_dist2 = __commonJS({
30062
30062
  }
30063
30063
  return null;
30064
30064
  }
30065
+ selectParseBaseMessages(baseMessages) {
30066
+ if (baseMessages.length <= _ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT) return baseMessages;
30067
+ return baseMessages.slice(-_ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT);
30068
+ }
30069
+ messagesComparable(left, right) {
30070
+ if (!left || !right) return false;
30071
+ if ((left.role || "") !== (right.role || "")) return false;
30072
+ const leftText = normalizeComparableTranscriptText(left.content);
30073
+ const rightText = normalizeComparableTranscriptText(right.content);
30074
+ return !!leftText && leftText === rightText;
30075
+ }
30076
+ stitchParsedMessagesWithCommittedBase(parsedMessages, fullBaseMessages, parseBaseMessages) {
30077
+ if (!Array.isArray(parsedMessages) || parsedMessages.length === 0) return parsedMessages;
30078
+ if (fullBaseMessages.length <= parseBaseMessages.length) return parsedMessages;
30079
+ const parsedFirst = parsedMessages[0];
30080
+ const fullFirst = fullBaseMessages[0];
30081
+ if (parsedMessages.length >= fullBaseMessages.length && this.messagesComparable(parsedFirst, fullFirst)) {
30082
+ return parsedMessages;
30083
+ }
30084
+ const tailFirst = parseBaseMessages[0];
30085
+ if (tailFirst && this.messagesComparable(parsedFirst, tailFirst)) {
30086
+ const prefixLength = fullBaseMessages.length - parseBaseMessages.length;
30087
+ return [...fullBaseMessages.slice(0, prefixLength), ...parsedMessages];
30088
+ }
30089
+ return [...fullBaseMessages, ...parsedMessages];
30090
+ }
30065
30091
  getIdleFinishConfirmMs() {
30066
30092
  return this.timeouts.idleFinishConfirm;
30067
30093
  }
@@ -30647,7 +30673,7 @@ var require_dist2 = __commonJS({
30647
30673
  const ctx = { now, modal, status, parsedMessages, lastParsedAssistant, parsedStatus: parsedStatus || null, prevStatus };
30648
30674
  if (!this.applyPendingScriptStatusDebounce(ctx)) return;
30649
30675
  const recentInteractiveActivity = this.hasRecentInteractiveActivity(now);
30650
- LOG2.info(
30676
+ LOG2.debug(
30651
30677
  "CLI",
30652
30678
  `[${this.cliType}] settled diagnostics prompt=${JSON.stringify(this.currentTurnScope?.prompt || "").slice(0, 140)} status=${String(status || "")} parsedStatus=${String(parsedStatus || "")} parsedMsgCount=${parsedMessages.length} lastParsedAssistant=${JSON.stringify(summarizeCliTraceText(lastParsedAssistant?.content || "", 120)).slice(0, 160)} responseBuffer=${JSON.stringify(summarizeCliTraceText(this.responseBuffer, 160)).slice(0, 220)} screen=${JSON.stringify(summarizeCliTraceText(screenText, 160)).slice(0, 220)}`
30653
30679
  );
@@ -31014,18 +31040,26 @@ var require_dist2 = __commonJS({
31014
31040
  try {
31015
31041
  const screenText = this.terminalScreen.getText();
31016
31042
  const tail = this.recentOutputBuffer.slice(-500);
31043
+ const parseBaseMessages = this.selectParseBaseMessages(this.committedMessages);
31017
31044
  const input = buildCliParseInput({
31018
31045
  accumulatedBuffer: this.accumulatedBuffer,
31019
31046
  accumulatedRawBuffer: this.accumulatedRawBuffer,
31020
31047
  recentOutputBuffer: this.recentOutputBuffer,
31021
31048
  terminalScreenText: screenText,
31022
- baseMessages: this.committedMessages,
31049
+ baseMessages: parseBaseMessages,
31023
31050
  partialResponse: this.responseBuffer,
31024
31051
  isWaitingForResponse: this.isWaitingForResponse,
31025
31052
  scope: this.currentTurnScope,
31026
31053
  runtimeSettings: this.runtimeSettings
31027
31054
  });
31028
31055
  const session = this.cliScripts.parseSession({ ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
31056
+ if (session && typeof session === "object" && Array.isArray(session.messages)) {
31057
+ session.messages = this.stitchParsedMessagesWithCommittedBase(
31058
+ session.messages,
31059
+ this.committedMessages,
31060
+ parseBaseMessages
31061
+ );
31062
+ }
31029
31063
  this.parseErrorMessage = null;
31030
31064
  return session && typeof session === "object" ? session : null;
31031
31065
  } catch (e) {
@@ -31346,12 +31380,13 @@ var require_dist2 = __commonJS({
31346
31380
  }
31347
31381
  try {
31348
31382
  const screenText = typeof screenTextOverride === "string" ? screenTextOverride : this.terminalScreen.getText();
31383
+ const parseBaseMessages = this.selectParseBaseMessages(baseMessages);
31349
31384
  const input = buildCliParseInput({
31350
31385
  accumulatedBuffer: this.accumulatedBuffer,
31351
31386
  accumulatedRawBuffer: this.accumulatedRawBuffer,
31352
31387
  recentOutputBuffer: this.recentOutputBuffer,
31353
31388
  terminalScreenText: screenText,
31354
- baseMessages,
31389
+ baseMessages: parseBaseMessages,
31355
31390
  partialResponse,
31356
31391
  isWaitingForResponse: this.isWaitingForResponse,
31357
31392
  scope,
@@ -31363,6 +31398,11 @@ var require_dist2 = __commonJS({
31363
31398
  }
31364
31399
  const normalizedParsed = this.suppressStaleParsedApproval(parsed, input.recentBuffer, input.screenText);
31365
31400
  if (normalizedParsed && Array.isArray(normalizedParsed.messages)) {
31401
+ normalizedParsed.messages = this.stitchParsedMessagesWithCommittedBase(
31402
+ normalizedParsed.messages,
31403
+ baseMessages,
31404
+ parseBaseMessages
31405
+ );
31366
31406
  this.trimLastAssistantEcho(normalizedParsed.messages, scope?.prompt || getLastUserPromptText(baseMessages));
31367
31407
  }
31368
31408
  this.parseErrorMessage = null;
@@ -31972,7 +32012,7 @@ var require_dist2 = __commonJS({
31972
32012
  DEFAULT_ACTIVE_CHAT_POLL_STATUSES: () => DEFAULT_ACTIVE_CHAT_POLL_STATUSES,
31973
32013
  DEFAULT_CDP_DISCOVERY_INTERVAL_MS: () => DEFAULT_CDP_DISCOVERY_INTERVAL_MS,
31974
32014
  DEFAULT_CDP_SCAN_INTERVAL_MS: () => DEFAULT_CDP_SCAN_INTERVAL_MS,
31975
- DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS: () => DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS,
32015
+ DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS: () => DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS2,
31976
32016
  DEFAULT_DAEMON_PORT: () => DEFAULT_DAEMON_PORT,
31977
32017
  DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS2,
31978
32018
  DEFAULT_SESSION_HOST_APP_NAME: () => DEFAULT_SESSION_HOST_APP_NAME,
@@ -32955,7 +32995,7 @@ var require_dist2 = __commonJS({
32955
32995
  "waiting_approval",
32956
32996
  "starting"
32957
32997
  ]);
32958
- var DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS = 8e3;
32998
+ var DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS2 = 8e3;
32959
32999
  var LIVE_RUNTIME_LIFECYCLES = /* @__PURE__ */ new Set(["starting", "running", "stopping", "interrupted"]);
32960
33000
  function parseMessageTimestamp(value) {
32961
33001
  if (typeof value === "number" && Number.isFinite(value)) return value;
@@ -32986,9 +33026,10 @@ var require_dist2 = __commonJS({
32986
33026
  const now = options.now ?? Date.now();
32987
33027
  const recentMessageGraceMs = Math.max(
32988
33028
  0,
32989
- Number.isFinite(options.recentMessageGraceMs) ? Number(options.recentMessageGraceMs) : DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS
33029
+ Number.isFinite(options.recentMessageGraceMs) ? Number(options.recentMessageGraceMs) : DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS2
32990
33030
  );
32991
33031
  const activeStatuses = options.activeStatuses ?? DEFAULT_ACTIVE_CHAT_POLL_STATUSES;
33032
+ const activeSessionIds = options.activeSessionIds ?? /* @__PURE__ */ new Set();
32992
33033
  const active = /* @__PURE__ */ new Set();
32993
33034
  const excluded = /* @__PURE__ */ new Set();
32994
33035
  for (const session of sessions) {
@@ -32998,6 +33039,10 @@ var require_dist2 = __commonJS({
32998
33039
  excluded.add(sessionId);
32999
33040
  continue;
33000
33041
  }
33042
+ if (activeSessionIds.has(sessionId)) {
33043
+ active.add(sessionId);
33044
+ continue;
33045
+ }
33001
33046
  const status = String(session?.status || "").toLowerCase();
33002
33047
  const unread = session?.unread === true;
33003
33048
  const inboxBucket = String(session?.inboxBucket || "").toLowerCase();
@@ -38247,6 +38292,26 @@ ${effect.notification.body || ""}`.trim();
38247
38292
  historyDedupKey: deriveHistoryDedupKey(message)
38248
38293
  }));
38249
38294
  }
38295
+ function findLastMessageIndexBySignature(messages, signature) {
38296
+ if (!signature) return -1;
38297
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
38298
+ if (getChatMessageSignature(messages[index]) === signature) {
38299
+ return index;
38300
+ }
38301
+ }
38302
+ return -1;
38303
+ }
38304
+ function buildBoundedTailSync(messages, cursor) {
38305
+ const totalMessages = messages.length;
38306
+ const tailMessages = cursor.tailLimit > 0 && totalMessages > cursor.tailLimit ? messages.slice(-cursor.tailLimit) : messages;
38307
+ return {
38308
+ syncMode: "full",
38309
+ replaceFrom: 0,
38310
+ messages: tailMessages,
38311
+ totalMessages,
38312
+ lastMessageSignature: getChatMessageSignature(messages[totalMessages - 1])
38313
+ };
38314
+ }
38250
38315
  function computeReadChatSync(messages, cursor) {
38251
38316
  const totalMessages = messages.length;
38252
38317
  const lastMessageSignature = getChatMessageSignature(messages[totalMessages - 1]);
@@ -38278,6 +38343,15 @@ ${effect.notification.body || ""}`.trim();
38278
38343
  lastMessageSignature
38279
38344
  };
38280
38345
  }
38346
+ if (cursor.tailLimit > 0 && knownSignature === lastMessageSignature) {
38347
+ return {
38348
+ syncMode: "noop",
38349
+ replaceFrom: totalMessages,
38350
+ messages: [],
38351
+ totalMessages,
38352
+ lastMessageSignature
38353
+ };
38354
+ }
38281
38355
  if (knownMessageCount < totalMessages) {
38282
38356
  const anchorSignature = getChatMessageSignature(messages[knownMessageCount - 1]);
38283
38357
  if (anchorSignature === knownSignature) {
@@ -38289,6 +38363,19 @@ ${effect.notification.body || ""}`.trim();
38289
38363
  lastMessageSignature
38290
38364
  };
38291
38365
  }
38366
+ if (cursor.tailLimit > 0) {
38367
+ const signatureIndex = findLastMessageIndexBySignature(messages, knownSignature);
38368
+ if (signatureIndex >= 0) {
38369
+ return {
38370
+ syncMode: "append",
38371
+ replaceFrom: knownMessageCount,
38372
+ messages: messages.slice(signatureIndex + 1),
38373
+ totalMessages,
38374
+ lastMessageSignature
38375
+ };
38376
+ }
38377
+ return buildBoundedTailSync(messages, cursor);
38378
+ }
38292
38379
  }
38293
38380
  const replaceFrom = Math.max(0, Math.min(knownMessageCount - 1, totalMessages));
38294
38381
  return {
@@ -43859,6 +43946,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
43859
43946
  log(msg) {
43860
43947
  this.logFn(`[ProviderLoader] ${msg}`);
43861
43948
  }
43949
+ debugLog(msg) {
43950
+ LOG2.debug("Provider", `[ProviderLoader] ${msg}`);
43951
+ }
43862
43952
  // ─── Public API ────────────────────────────────
43863
43953
  /**
43864
43954
  * User override root (~/.adhdev/providers by default).
@@ -44248,10 +44338,22 @@ Run 'adhdev doctor' for detailed diagnostics.`
44248
44338
  setMachineProviderEnabled(type, enabled) {
44249
44339
  return this.setMachineProviderConfig(type, { enabled });
44250
44340
  }
44341
+ getEffectiveProviderAvailability(type) {
44342
+ const providerType = this.resolveAlias(type);
44343
+ const availability = this.providerAvailability.get(providerType);
44344
+ if (availability) return availability;
44345
+ const machineConfig = this.getMachineProviderConfig(providerType);
44346
+ const lastDetection = machineConfig.lastDetection;
44347
+ if (!lastDetection) return void 0;
44348
+ return {
44349
+ installed: lastDetection.ok === true,
44350
+ detectedPath: typeof lastDetection.path === "string" && lastDetection.path.trim() ? lastDetection.path.trim() : null
44351
+ };
44352
+ }
44251
44353
  getMachineProviderStatus(type) {
44252
44354
  const providerType = this.resolveAlias(type);
44253
44355
  if (!this.isMachineProviderEnabled(providerType)) return "disabled";
44254
- const availability = this.providerAvailability.get(providerType);
44356
+ const availability = this.getEffectiveProviderAvailability(providerType);
44255
44357
  if (!availability) return "enabled_unchecked";
44256
44358
  return availability.installed ? "detected" : "not_detected";
44257
44359
  }
@@ -44379,7 +44481,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
44379
44481
  }
44380
44482
  getAvailableProviderInfos() {
44381
44483
  return this.getAll().map((provider) => {
44382
- const availability = this.providerAvailability.get(provider.type);
44484
+ const availability = this.getEffectiveProviderAvailability(provider.type);
44383
44485
  const enabled = this.isMachineProviderEnabled(provider.type);
44384
44486
  const machineConfig = this.getMachineProviderConfig(provider.type);
44385
44487
  return {
@@ -44465,7 +44567,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
44465
44567
  const loaded = this.loadScriptsFromDir(type, entry.scriptDir);
44466
44568
  if (loaded) {
44467
44569
  resolved.scripts = loaded;
44468
- this.log(` [compatibility] ${type} v${currentVersion} \u2192 ${entry.scriptDir}`);
44570
+ this.debugLog(` [compatibility] ${type} v${currentVersion} \u2192 ${entry.scriptDir}`);
44469
44571
  resolved._resolvedScriptDir = entry.scriptDir;
44470
44572
  resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
44471
44573
  if (providerDir) {
@@ -44481,7 +44583,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
44481
44583
  const loaded = this.loadScriptsFromDir(type, base.defaultScriptDir);
44482
44584
  if (loaded) {
44483
44585
  resolved.scripts = loaded;
44484
- this.log(` [compatibility] ${type} v${currentVersion} \u2192 default: ${base.defaultScriptDir}`);
44586
+ this.debugLog(` [compatibility] ${type} v${currentVersion} \u2192 default: ${base.defaultScriptDir}`);
44485
44587
  resolved._resolvedScriptDir = base.defaultScriptDir;
44486
44588
  resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
44487
44589
  if (providerDir) {
@@ -44516,7 +44618,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
44516
44618
  const loaded = this.loadScriptsFromDir(type, base.defaultScriptDir);
44517
44619
  if (loaded) {
44518
44620
  resolved.scripts = loaded;
44519
- this.log(` [compatibility] ${type} no version detected \u2192 default: ${base.defaultScriptDir}`);
44621
+ this.debugLog(` [compatibility] ${type} no version detected \u2192 default: ${base.defaultScriptDir}`);
44520
44622
  resolved._resolvedScriptDir = base.defaultScriptDir;
44521
44623
  resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
44522
44624
  if (providerDir) {
@@ -55536,6 +55638,8 @@ async function getWorkspaceSocketInfo(workspaceName) {
55536
55638
  var import_daemon_core3 = __toESM(require_dist2());
55537
55639
  var DEFAULT_PORT = 3847;
55538
55640
  var STATUS_INTERVAL = 2e3;
55641
+ var CHAT_OUTPUT_ACTIVITY_HOT_MS = import_daemon_core3.DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS;
55642
+ var CHAT_OUTPUT_FLUSH_DEBOUNCE_MS = 700;
55539
55643
  var STANDALONE_AUTH_SESSION_COOKIE = "adhdev_standalone_session";
55540
55644
  var STANDALONE_PASSWORD_CONFIG_FILE = "standalone-auth.json";
55541
55645
  var STANDALONE_PREFERENCES_CONFIG_FILE = "standalone-network.json";
@@ -55736,6 +55840,8 @@ var StandaloneServer = class {
55736
55840
  wsChatFlushInFlight = false;
55737
55841
  pendingWsChatFlush = null;
55738
55842
  hotWsChatSessionIds = /* @__PURE__ */ new Set();
55843
+ wsChatOutputActiveAt = /* @__PURE__ */ new Map();
55844
+ wsChatOutputFlushTimer = null;
55739
55845
  running = false;
55740
55846
  components = null;
55741
55847
  devServer = null;
@@ -55785,6 +55891,26 @@ var StandaloneServer = class {
55785
55891
  const mode = this.getCliPresentationMode(sessionId);
55786
55892
  return mode === "chat" || mode === "terminal";
55787
55893
  }
55894
+ getRecentlyOutputActiveChatSessionIds(now) {
55895
+ const active = /* @__PURE__ */ new Set();
55896
+ for (const [sessionId, lastOutputAt] of this.wsChatOutputActiveAt) {
55897
+ if (now - lastOutputAt <= CHAT_OUTPUT_ACTIVITY_HOT_MS) {
55898
+ active.add(sessionId);
55899
+ } else {
55900
+ this.wsChatOutputActiveAt.delete(sessionId);
55901
+ }
55902
+ }
55903
+ return active;
55904
+ }
55905
+ markWsChatOutputActivity(sessionId) {
55906
+ if (!sessionId || !this.isCliSession(sessionId)) return;
55907
+ this.wsChatOutputActiveAt.set(sessionId, Date.now());
55908
+ if (this.wsChatOutputFlushTimer || this.clients.size === 0) return;
55909
+ this.wsChatOutputFlushTimer = setTimeout(() => {
55910
+ this.wsChatOutputFlushTimer = null;
55911
+ void this.flushWsChatSubscriptions(void 0, { onlyActive: true });
55912
+ }, CHAT_OUTPUT_FLUSH_DEBOUNCE_MS);
55913
+ }
55788
55914
  hasPasswordAuth() {
55789
55915
  return !!this.passwordConfig;
55790
55916
  }
@@ -55882,6 +56008,7 @@ var StandaloneServer = class {
55882
56008
  getP2p: () => ({
55883
56009
  broadcastSessionOutput: (key, data) => {
55884
56010
  if (this.clients.size === 0 || !this.isCliSession(key)) return;
56011
+ this.markWsChatOutputActivity(key);
55885
56012
  const msg = JSON.stringify({ type: "session_output", sessionId: key, data });
55886
56013
  for (const client of this.clients) {
55887
56014
  if (client.readyState === 1) {
@@ -56642,10 +56769,12 @@ var StandaloneServer = class {
56642
56769
  return prepared.update;
56643
56770
  }
56644
56771
  getHotChatSessionIdsForWsFlush() {
56772
+ const now = Date.now();
56645
56773
  const snapshot = this.buildSharedSnapshot("live");
56646
56774
  const hotSessions = (0, import_daemon_core3.classifyHotChatSessionsForSubscriptionFlush)(
56647
56775
  snapshot.sessions,
56648
- this.hotWsChatSessionIds
56776
+ this.hotWsChatSessionIds,
56777
+ { now, activeSessionIds: this.getRecentlyOutputActiveChatSessionIds(now) }
56649
56778
  );
56650
56779
  this.hotWsChatSessionIds = hotSessions.active;
56651
56780
  return hotSessions;