adhdev 0.9.31 → 0.9.32

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/cli/index.js CHANGED
@@ -1738,6 +1738,7 @@ function classifyHotChatSessionsForSubscriptionFlush(sessions, previousHotSessio
1738
1738
  Number.isFinite(options.recentMessageGraceMs) ? Number(options.recentMessageGraceMs) : DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS
1739
1739
  );
1740
1740
  const activeStatuses = options.activeStatuses ?? DEFAULT_ACTIVE_CHAT_POLL_STATUSES;
1741
+ const activeSessionIds = options.activeSessionIds ?? /* @__PURE__ */ new Set();
1741
1742
  const active = /* @__PURE__ */ new Set();
1742
1743
  const excluded = /* @__PURE__ */ new Set();
1743
1744
  for (const session of sessions) {
@@ -1747,6 +1748,10 @@ function classifyHotChatSessionsForSubscriptionFlush(sessions, previousHotSessio
1747
1748
  excluded.add(sessionId);
1748
1749
  continue;
1749
1750
  }
1751
+ if (activeSessionIds.has(sessionId)) {
1752
+ active.add(sessionId);
1753
+ continue;
1754
+ }
1750
1755
  const status = String(session?.status || "").toLowerCase();
1751
1756
  const unread = session?.unread === true;
1752
1757
  const inboxBucket = String(session?.inboxBucket || "").toLowerCase();
@@ -1862,14 +1867,13 @@ function daemonLog(category, msg, level = "info") {
1862
1867
  const shouldOutput = LEVEL_NUM[level] >= LEVEL_NUM[currentLevel];
1863
1868
  const label = LEVEL_LABEL[level];
1864
1869
  const line = `[${ts()}] [${label}] [${category}] ${msg}`;
1870
+ if (!shouldOutput) return;
1865
1871
  writeToFile(line);
1866
1872
  ringBuffer.push({ ts: Date.now(), level, category, message: msg });
1867
1873
  if (ringBuffer.length > RING_BUFFER_SIZE) {
1868
1874
  ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
1869
1875
  }
1870
- if (shouldOutput) {
1871
- origConsoleLog(line);
1872
- }
1876
+ origConsoleLog(line);
1873
1877
  }
1874
1878
  function installGlobalInterceptor() {
1875
1879
  if (interceptorInstalled) return;
@@ -12796,6 +12800,7 @@ var init_provider_cli_adapter = __esm({
12796
12800
  static STATUS_HOT_PATH_PARSE_MIN_INTERVAL_MS = 1e3;
12797
12801
  static SCREEN_SNAPSHOT_MIN_INTERVAL_MS = 250;
12798
12802
  static MAX_TRACE_ENTRIES = 250;
12803
+ static PARSE_MESSAGE_TAIL_LIMIT = 100;
12799
12804
  providerResolutionMeta;
12800
12805
  static FINISH_RETRY_DELAY_MS = 300;
12801
12806
  static MAX_FINISH_RETRIES = 2;
@@ -12827,6 +12832,32 @@ var init_provider_cli_adapter = __esm({
12827
12832
  }
12828
12833
  return null;
12829
12834
  }
12835
+ selectParseBaseMessages(baseMessages) {
12836
+ if (baseMessages.length <= _ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT) return baseMessages;
12837
+ return baseMessages.slice(-_ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT);
12838
+ }
12839
+ messagesComparable(left2, right2) {
12840
+ if (!left2 || !right2) return false;
12841
+ if ((left2.role || "") !== (right2.role || "")) return false;
12842
+ const leftText = normalizeComparableTranscriptText(left2.content);
12843
+ const rightText = normalizeComparableTranscriptText(right2.content);
12844
+ return !!leftText && leftText === rightText;
12845
+ }
12846
+ stitchParsedMessagesWithCommittedBase(parsedMessages, fullBaseMessages, parseBaseMessages) {
12847
+ if (!Array.isArray(parsedMessages) || parsedMessages.length === 0) return parsedMessages;
12848
+ if (fullBaseMessages.length <= parseBaseMessages.length) return parsedMessages;
12849
+ const parsedFirst = parsedMessages[0];
12850
+ const fullFirst = fullBaseMessages[0];
12851
+ if (parsedMessages.length >= fullBaseMessages.length && this.messagesComparable(parsedFirst, fullFirst)) {
12852
+ return parsedMessages;
12853
+ }
12854
+ const tailFirst = parseBaseMessages[0];
12855
+ if (tailFirst && this.messagesComparable(parsedFirst, tailFirst)) {
12856
+ const prefixLength = fullBaseMessages.length - parseBaseMessages.length;
12857
+ return [...fullBaseMessages.slice(0, prefixLength), ...parsedMessages];
12858
+ }
12859
+ return [...fullBaseMessages, ...parsedMessages];
12860
+ }
12830
12861
  getIdleFinishConfirmMs() {
12831
12862
  return this.timeouts.idleFinishConfirm;
12832
12863
  }
@@ -13412,7 +13443,7 @@ var init_provider_cli_adapter = __esm({
13412
13443
  const ctx = { now, modal, status, parsedMessages, lastParsedAssistant, parsedStatus: parsedStatus || null, prevStatus };
13413
13444
  if (!this.applyPendingScriptStatusDebounce(ctx)) return;
13414
13445
  const recentInteractiveActivity = this.hasRecentInteractiveActivity(now);
13415
- LOG.info(
13446
+ LOG.debug(
13416
13447
  "CLI",
13417
13448
  `[${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)}`
13418
13449
  );
@@ -13779,18 +13810,26 @@ var init_provider_cli_adapter = __esm({
13779
13810
  try {
13780
13811
  const screenText = this.terminalScreen.getText();
13781
13812
  const tail = this.recentOutputBuffer.slice(-500);
13813
+ const parseBaseMessages = this.selectParseBaseMessages(this.committedMessages);
13782
13814
  const input = buildCliParseInput({
13783
13815
  accumulatedBuffer: this.accumulatedBuffer,
13784
13816
  accumulatedRawBuffer: this.accumulatedRawBuffer,
13785
13817
  recentOutputBuffer: this.recentOutputBuffer,
13786
13818
  terminalScreenText: screenText,
13787
- baseMessages: this.committedMessages,
13819
+ baseMessages: parseBaseMessages,
13788
13820
  partialResponse: this.responseBuffer,
13789
13821
  isWaitingForResponse: this.isWaitingForResponse,
13790
13822
  scope: this.currentTurnScope,
13791
13823
  runtimeSettings: this.runtimeSettings
13792
13824
  });
13793
13825
  const session = this.cliScripts.parseSession({ ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
13826
+ if (session && typeof session === "object" && Array.isArray(session.messages)) {
13827
+ session.messages = this.stitchParsedMessagesWithCommittedBase(
13828
+ session.messages,
13829
+ this.committedMessages,
13830
+ parseBaseMessages
13831
+ );
13832
+ }
13794
13833
  this.parseErrorMessage = null;
13795
13834
  return session && typeof session === "object" ? session : null;
13796
13835
  } catch (e) {
@@ -14111,12 +14150,13 @@ var init_provider_cli_adapter = __esm({
14111
14150
  }
14112
14151
  try {
14113
14152
  const screenText = typeof screenTextOverride === "string" ? screenTextOverride : this.terminalScreen.getText();
14153
+ const parseBaseMessages = this.selectParseBaseMessages(baseMessages);
14114
14154
  const input = buildCliParseInput({
14115
14155
  accumulatedBuffer: this.accumulatedBuffer,
14116
14156
  accumulatedRawBuffer: this.accumulatedRawBuffer,
14117
14157
  recentOutputBuffer: this.recentOutputBuffer,
14118
14158
  terminalScreenText: screenText,
14119
- baseMessages,
14159
+ baseMessages: parseBaseMessages,
14120
14160
  partialResponse,
14121
14161
  isWaitingForResponse: this.isWaitingForResponse,
14122
14162
  scope,
@@ -14128,6 +14168,11 @@ var init_provider_cli_adapter = __esm({
14128
14168
  }
14129
14169
  const normalizedParsed = this.suppressStaleParsedApproval(parsed, input.recentBuffer, input.screenText);
14130
14170
  if (normalizedParsed && Array.isArray(normalizedParsed.messages)) {
14171
+ normalizedParsed.messages = this.stitchParsedMessagesWithCommittedBase(
14172
+ normalizedParsed.messages,
14173
+ baseMessages,
14174
+ parseBaseMessages
14175
+ );
14131
14176
  this.trimLastAssistantEcho(normalizedParsed.messages, scope?.prompt || getLastUserPromptText(baseMessages));
14132
14177
  }
14133
14178
  this.parseErrorMessage = null;
@@ -35988,6 +36033,9 @@ var init_provider_loader = __esm({
35988
36033
  log(msg) {
35989
36034
  this.logFn(`[ProviderLoader] ${msg}`);
35990
36035
  }
36036
+ debugLog(msg) {
36037
+ LOG.debug("Provider", `[ProviderLoader] ${msg}`);
36038
+ }
35991
36039
  // ─── Public API ────────────────────────────────
35992
36040
  /**
35993
36041
  * User override root (~/.adhdev/providers by default).
@@ -36594,7 +36642,7 @@ var init_provider_loader = __esm({
36594
36642
  const loaded = this.loadScriptsFromDir(type, entry.scriptDir);
36595
36643
  if (loaded) {
36596
36644
  resolved.scripts = loaded;
36597
- this.log(` [compatibility] ${type} v${currentVersion} \u2192 ${entry.scriptDir}`);
36645
+ this.debugLog(` [compatibility] ${type} v${currentVersion} \u2192 ${entry.scriptDir}`);
36598
36646
  resolved._resolvedScriptDir = entry.scriptDir;
36599
36647
  resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
36600
36648
  if (providerDir) {
@@ -36610,7 +36658,7 @@ var init_provider_loader = __esm({
36610
36658
  const loaded = this.loadScriptsFromDir(type, base.defaultScriptDir);
36611
36659
  if (loaded) {
36612
36660
  resolved.scripts = loaded;
36613
- this.log(` [compatibility] ${type} v${currentVersion} \u2192 default: ${base.defaultScriptDir}`);
36661
+ this.debugLog(` [compatibility] ${type} v${currentVersion} \u2192 default: ${base.defaultScriptDir}`);
36614
36662
  resolved._resolvedScriptDir = base.defaultScriptDir;
36615
36663
  resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
36616
36664
  if (providerDir) {
@@ -36645,7 +36693,7 @@ var init_provider_loader = __esm({
36645
36693
  const loaded = this.loadScriptsFromDir(type, base.defaultScriptDir);
36646
36694
  if (loaded) {
36647
36695
  resolved.scripts = loaded;
36648
- this.log(` [compatibility] ${type} no version detected \u2192 default: ${base.defaultScriptDir}`);
36696
+ this.debugLog(` [compatibility] ${type} no version detected \u2192 default: ${base.defaultScriptDir}`);
36649
36697
  resolved._resolvedScriptDir = base.defaultScriptDir;
36650
36698
  resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
36651
36699
  if (providerDir) {
@@ -87791,7 +87839,7 @@ var init_adhdev_daemon = __esm({
87791
87839
  init_version();
87792
87840
  init_src();
87793
87841
  init_runtime_defaults();
87794
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.31" });
87842
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.32" });
87795
87843
  AdhdevDaemon = class _AdhdevDaemon {
87796
87844
  localHttpServer = null;
87797
87845
  localWss = null;
@@ -87805,8 +87853,12 @@ var init_adhdev_daemon = __esm({
87805
87853
  pendingP2PChatFlush = false;
87806
87854
  pendingP2PChatFlushOnlyActive = true;
87807
87855
  hotP2PChatSessionIds = /* @__PURE__ */ new Set();
87856
+ p2pChatOutputActiveAt = /* @__PURE__ */ new Map();
87857
+ p2pChatOutputFlushTimer = null;
87808
87858
  hotChatSnapshotCache = null;
87809
87859
  static HOT_CHAT_SNAPSHOT_CACHE_TTL_MS = 1500;
87860
+ static CHAT_OUTPUT_ACTIVITY_HOT_MS = DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS;
87861
+ static CHAT_OUTPUT_FLUSH_DEBOUNCE_MS = 700;
87810
87862
  components = null;
87811
87863
  sessionHostEndpoint = null;
87812
87864
  sessionHostController = null;
@@ -87991,6 +88043,26 @@ var init_adhdev_daemon = __esm({
87991
88043
  invalidateHotChatSnapshotCache() {
87992
88044
  this.hotChatSnapshotCache = null;
87993
88045
  }
88046
+ getRecentlyOutputActiveChatSessionIds(now) {
88047
+ const active = /* @__PURE__ */ new Set();
88048
+ for (const [sessionId, lastOutputAt] of this.p2pChatOutputActiveAt) {
88049
+ if (now - lastOutputAt <= _AdhdevDaemon.CHAT_OUTPUT_ACTIVITY_HOT_MS) {
88050
+ active.add(sessionId);
88051
+ } else {
88052
+ this.p2pChatOutputActiveAt.delete(sessionId);
88053
+ }
88054
+ }
88055
+ return active;
88056
+ }
88057
+ markP2PChatOutputActivity(sessionId) {
88058
+ if (!sessionId || !this.isCliSession(sessionId)) return;
88059
+ this.p2pChatOutputActiveAt.set(sessionId, Date.now());
88060
+ if (this.p2pChatOutputFlushTimer || !this.p2p?.isConnected || !this.p2p.hasChatSubscriptions()) return;
88061
+ this.p2pChatOutputFlushTimer = setTimeout(() => {
88062
+ this.p2pChatOutputFlushTimer = null;
88063
+ void this.flushP2PChatSubscriptions({ onlyActive: true });
88064
+ }, _AdhdevDaemon.CHAT_OUTPUT_FLUSH_DEBOUNCE_MS);
88065
+ }
87994
88066
  getHotChatSessionIdsForP2PFlush() {
87995
88067
  const now = Date.now();
87996
88068
  const cached2 = this.hotChatSnapshotCache;
@@ -88001,7 +88073,8 @@ var init_adhdev_daemon = __esm({
88001
88073
  })();
88002
88074
  const hotSessions = classifyHotChatSessionsForSubscriptionFlush(
88003
88075
  sessions,
88004
- this.hotP2PChatSessionIds
88076
+ this.hotP2PChatSessionIds,
88077
+ { activeSessionIds: this.getRecentlyOutputActiveChatSessionIds(now) }
88005
88078
  );
88006
88079
  this.hotP2PChatSessionIds = hotSessions.active;
88007
88080
  return hotSessions;
@@ -88226,6 +88299,7 @@ ${err?.stack || ""}`);
88226
88299
  getP2p: () => ({
88227
88300
  broadcastSessionOutput: (key, data) => {
88228
88301
  if (!this.isCliSession(key)) return;
88302
+ this.markP2PChatOutputActivity(key);
88229
88303
  this.p2p?.broadcastSessionOutput(key, data);
88230
88304
  }
88231
88305
  }),