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/index.js CHANGED
@@ -1218,6 +1218,7 @@ function classifyHotChatSessionsForSubscriptionFlush(sessions, previousHotSessio
1218
1218
  Number.isFinite(options.recentMessageGraceMs) ? Number(options.recentMessageGraceMs) : DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS
1219
1219
  );
1220
1220
  const activeStatuses = options.activeStatuses ?? DEFAULT_ACTIVE_CHAT_POLL_STATUSES;
1221
+ const activeSessionIds = options.activeSessionIds ?? /* @__PURE__ */ new Set();
1221
1222
  const active = /* @__PURE__ */ new Set();
1222
1223
  const excluded = /* @__PURE__ */ new Set();
1223
1224
  for (const session of sessions) {
@@ -1227,6 +1228,10 @@ function classifyHotChatSessionsForSubscriptionFlush(sessions, previousHotSessio
1227
1228
  excluded.add(sessionId);
1228
1229
  continue;
1229
1230
  }
1231
+ if (activeSessionIds.has(sessionId)) {
1232
+ active.add(sessionId);
1233
+ continue;
1234
+ }
1230
1235
  const status = String(session?.status || "").toLowerCase();
1231
1236
  const unread = session?.unread === true;
1232
1237
  const inboxBucket = String(session?.inboxBucket || "").toLowerCase();
@@ -1342,14 +1347,13 @@ function daemonLog(category, msg, level = "info") {
1342
1347
  const shouldOutput = LEVEL_NUM[level] >= LEVEL_NUM[currentLevel];
1343
1348
  const label = LEVEL_LABEL[level];
1344
1349
  const line = `[${ts()}] [${label}] [${category}] ${msg}`;
1350
+ if (!shouldOutput) return;
1345
1351
  writeToFile(line);
1346
1352
  ringBuffer.push({ ts: Date.now(), level, category, message: msg });
1347
1353
  if (ringBuffer.length > RING_BUFFER_SIZE) {
1348
1354
  ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
1349
1355
  }
1350
- if (shouldOutput) {
1351
- origConsoleLog(line);
1352
- }
1356
+ origConsoleLog(line);
1353
1357
  }
1354
1358
  function installGlobalInterceptor() {
1355
1359
  if (interceptorInstalled) return;
@@ -11840,6 +11844,7 @@ var init_provider_cli_adapter = __esm({
11840
11844
  static STATUS_HOT_PATH_PARSE_MIN_INTERVAL_MS = 1e3;
11841
11845
  static SCREEN_SNAPSHOT_MIN_INTERVAL_MS = 250;
11842
11846
  static MAX_TRACE_ENTRIES = 250;
11847
+ static PARSE_MESSAGE_TAIL_LIMIT = 100;
11843
11848
  providerResolutionMeta;
11844
11849
  static FINISH_RETRY_DELAY_MS = 300;
11845
11850
  static MAX_FINISH_RETRIES = 2;
@@ -11871,6 +11876,32 @@ var init_provider_cli_adapter = __esm({
11871
11876
  }
11872
11877
  return null;
11873
11878
  }
11879
+ selectParseBaseMessages(baseMessages) {
11880
+ if (baseMessages.length <= _ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT) return baseMessages;
11881
+ return baseMessages.slice(-_ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT);
11882
+ }
11883
+ messagesComparable(left2, right2) {
11884
+ if (!left2 || !right2) return false;
11885
+ if ((left2.role || "") !== (right2.role || "")) return false;
11886
+ const leftText = normalizeComparableTranscriptText(left2.content);
11887
+ const rightText = normalizeComparableTranscriptText(right2.content);
11888
+ return !!leftText && leftText === rightText;
11889
+ }
11890
+ stitchParsedMessagesWithCommittedBase(parsedMessages, fullBaseMessages, parseBaseMessages) {
11891
+ if (!Array.isArray(parsedMessages) || parsedMessages.length === 0) return parsedMessages;
11892
+ if (fullBaseMessages.length <= parseBaseMessages.length) return parsedMessages;
11893
+ const parsedFirst = parsedMessages[0];
11894
+ const fullFirst = fullBaseMessages[0];
11895
+ if (parsedMessages.length >= fullBaseMessages.length && this.messagesComparable(parsedFirst, fullFirst)) {
11896
+ return parsedMessages;
11897
+ }
11898
+ const tailFirst = parseBaseMessages[0];
11899
+ if (tailFirst && this.messagesComparable(parsedFirst, tailFirst)) {
11900
+ const prefixLength = fullBaseMessages.length - parseBaseMessages.length;
11901
+ return [...fullBaseMessages.slice(0, prefixLength), ...parsedMessages];
11902
+ }
11903
+ return [...fullBaseMessages, ...parsedMessages];
11904
+ }
11874
11905
  getIdleFinishConfirmMs() {
11875
11906
  return this.timeouts.idleFinishConfirm;
11876
11907
  }
@@ -12456,7 +12487,7 @@ var init_provider_cli_adapter = __esm({
12456
12487
  const ctx = { now, modal, status, parsedMessages, lastParsedAssistant, parsedStatus: parsedStatus || null, prevStatus };
12457
12488
  if (!this.applyPendingScriptStatusDebounce(ctx)) return;
12458
12489
  const recentInteractiveActivity = this.hasRecentInteractiveActivity(now);
12459
- LOG.info(
12490
+ LOG.debug(
12460
12491
  "CLI",
12461
12492
  `[${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)}`
12462
12493
  );
@@ -12823,18 +12854,26 @@ var init_provider_cli_adapter = __esm({
12823
12854
  try {
12824
12855
  const screenText = this.terminalScreen.getText();
12825
12856
  const tail = this.recentOutputBuffer.slice(-500);
12857
+ const parseBaseMessages = this.selectParseBaseMessages(this.committedMessages);
12826
12858
  const input = buildCliParseInput({
12827
12859
  accumulatedBuffer: this.accumulatedBuffer,
12828
12860
  accumulatedRawBuffer: this.accumulatedRawBuffer,
12829
12861
  recentOutputBuffer: this.recentOutputBuffer,
12830
12862
  terminalScreenText: screenText,
12831
- baseMessages: this.committedMessages,
12863
+ baseMessages: parseBaseMessages,
12832
12864
  partialResponse: this.responseBuffer,
12833
12865
  isWaitingForResponse: this.isWaitingForResponse,
12834
12866
  scope: this.currentTurnScope,
12835
12867
  runtimeSettings: this.runtimeSettings
12836
12868
  });
12837
12869
  const session = this.cliScripts.parseSession({ ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
12870
+ if (session && typeof session === "object" && Array.isArray(session.messages)) {
12871
+ session.messages = this.stitchParsedMessagesWithCommittedBase(
12872
+ session.messages,
12873
+ this.committedMessages,
12874
+ parseBaseMessages
12875
+ );
12876
+ }
12838
12877
  this.parseErrorMessage = null;
12839
12878
  return session && typeof session === "object" ? session : null;
12840
12879
  } catch (e) {
@@ -13155,12 +13194,13 @@ var init_provider_cli_adapter = __esm({
13155
13194
  }
13156
13195
  try {
13157
13196
  const screenText = typeof screenTextOverride === "string" ? screenTextOverride : this.terminalScreen.getText();
13197
+ const parseBaseMessages = this.selectParseBaseMessages(baseMessages);
13158
13198
  const input = buildCliParseInput({
13159
13199
  accumulatedBuffer: this.accumulatedBuffer,
13160
13200
  accumulatedRawBuffer: this.accumulatedRawBuffer,
13161
13201
  recentOutputBuffer: this.recentOutputBuffer,
13162
13202
  terminalScreenText: screenText,
13163
- baseMessages,
13203
+ baseMessages: parseBaseMessages,
13164
13204
  partialResponse,
13165
13205
  isWaitingForResponse: this.isWaitingForResponse,
13166
13206
  scope,
@@ -13172,6 +13212,11 @@ var init_provider_cli_adapter = __esm({
13172
13212
  }
13173
13213
  const normalizedParsed = this.suppressStaleParsedApproval(parsed, input.recentBuffer, input.screenText);
13174
13214
  if (normalizedParsed && Array.isArray(normalizedParsed.messages)) {
13215
+ normalizedParsed.messages = this.stitchParsedMessagesWithCommittedBase(
13216
+ normalizedParsed.messages,
13217
+ baseMessages,
13218
+ parseBaseMessages
13219
+ );
13175
13220
  this.trimLastAssistantEcho(normalizedParsed.messages, scope?.prompt || getLastUserPromptText(baseMessages));
13176
13221
  }
13177
13222
  this.parseErrorMessage = null;
@@ -35032,6 +35077,9 @@ var init_provider_loader = __esm({
35032
35077
  log(msg) {
35033
35078
  this.logFn(`[ProviderLoader] ${msg}`);
35034
35079
  }
35080
+ debugLog(msg) {
35081
+ LOG.debug("Provider", `[ProviderLoader] ${msg}`);
35082
+ }
35035
35083
  // ─── Public API ────────────────────────────────
35036
35084
  /**
35037
35085
  * User override root (~/.adhdev/providers by default).
@@ -35638,7 +35686,7 @@ var init_provider_loader = __esm({
35638
35686
  const loaded = this.loadScriptsFromDir(type, entry.scriptDir);
35639
35687
  if (loaded) {
35640
35688
  resolved.scripts = loaded;
35641
- this.log(` [compatibility] ${type} v${currentVersion} \u2192 ${entry.scriptDir}`);
35689
+ this.debugLog(` [compatibility] ${type} v${currentVersion} \u2192 ${entry.scriptDir}`);
35642
35690
  resolved._resolvedScriptDir = entry.scriptDir;
35643
35691
  resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
35644
35692
  if (providerDir) {
@@ -35654,7 +35702,7 @@ var init_provider_loader = __esm({
35654
35702
  const loaded = this.loadScriptsFromDir(type, base.defaultScriptDir);
35655
35703
  if (loaded) {
35656
35704
  resolved.scripts = loaded;
35657
- this.log(` [compatibility] ${type} v${currentVersion} \u2192 default: ${base.defaultScriptDir}`);
35705
+ this.debugLog(` [compatibility] ${type} v${currentVersion} \u2192 default: ${base.defaultScriptDir}`);
35658
35706
  resolved._resolvedScriptDir = base.defaultScriptDir;
35659
35707
  resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
35660
35708
  if (providerDir) {
@@ -35689,7 +35737,7 @@ var init_provider_loader = __esm({
35689
35737
  const loaded = this.loadScriptsFromDir(type, base.defaultScriptDir);
35690
35738
  if (loaded) {
35691
35739
  resolved.scripts = loaded;
35692
- this.log(` [compatibility] ${type} no version detected \u2192 default: ${base.defaultScriptDir}`);
35740
+ this.debugLog(` [compatibility] ${type} no version detected \u2192 default: ${base.defaultScriptDir}`);
35693
35741
  resolved._resolvedScriptDir = base.defaultScriptDir;
35694
35742
  resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
35695
35743
  if (providerDir) {
@@ -56071,7 +56119,7 @@ var init_adhdev_daemon = __esm({
56071
56119
  init_version();
56072
56120
  init_src();
56073
56121
  init_runtime_defaults();
56074
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.31" });
56122
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.32" });
56075
56123
  AdhdevDaemon = class _AdhdevDaemon {
56076
56124
  localHttpServer = null;
56077
56125
  localWss = null;
@@ -56085,8 +56133,12 @@ var init_adhdev_daemon = __esm({
56085
56133
  pendingP2PChatFlush = false;
56086
56134
  pendingP2PChatFlushOnlyActive = true;
56087
56135
  hotP2PChatSessionIds = /* @__PURE__ */ new Set();
56136
+ p2pChatOutputActiveAt = /* @__PURE__ */ new Map();
56137
+ p2pChatOutputFlushTimer = null;
56088
56138
  hotChatSnapshotCache = null;
56089
56139
  static HOT_CHAT_SNAPSHOT_CACHE_TTL_MS = 1500;
56140
+ static CHAT_OUTPUT_ACTIVITY_HOT_MS = DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS;
56141
+ static CHAT_OUTPUT_FLUSH_DEBOUNCE_MS = 700;
56090
56142
  components = null;
56091
56143
  sessionHostEndpoint = null;
56092
56144
  sessionHostController = null;
@@ -56271,6 +56323,26 @@ var init_adhdev_daemon = __esm({
56271
56323
  invalidateHotChatSnapshotCache() {
56272
56324
  this.hotChatSnapshotCache = null;
56273
56325
  }
56326
+ getRecentlyOutputActiveChatSessionIds(now) {
56327
+ const active = /* @__PURE__ */ new Set();
56328
+ for (const [sessionId, lastOutputAt] of this.p2pChatOutputActiveAt) {
56329
+ if (now - lastOutputAt <= _AdhdevDaemon.CHAT_OUTPUT_ACTIVITY_HOT_MS) {
56330
+ active.add(sessionId);
56331
+ } else {
56332
+ this.p2pChatOutputActiveAt.delete(sessionId);
56333
+ }
56334
+ }
56335
+ return active;
56336
+ }
56337
+ markP2PChatOutputActivity(sessionId) {
56338
+ if (!sessionId || !this.isCliSession(sessionId)) return;
56339
+ this.p2pChatOutputActiveAt.set(sessionId, Date.now());
56340
+ if (this.p2pChatOutputFlushTimer || !this.p2p?.isConnected || !this.p2p.hasChatSubscriptions()) return;
56341
+ this.p2pChatOutputFlushTimer = setTimeout(() => {
56342
+ this.p2pChatOutputFlushTimer = null;
56343
+ void this.flushP2PChatSubscriptions({ onlyActive: true });
56344
+ }, _AdhdevDaemon.CHAT_OUTPUT_FLUSH_DEBOUNCE_MS);
56345
+ }
56274
56346
  getHotChatSessionIdsForP2PFlush() {
56275
56347
  const now = Date.now();
56276
56348
  const cached2 = this.hotChatSnapshotCache;
@@ -56281,7 +56353,8 @@ var init_adhdev_daemon = __esm({
56281
56353
  })();
56282
56354
  const hotSessions = classifyHotChatSessionsForSubscriptionFlush(
56283
56355
  sessions,
56284
- this.hotP2PChatSessionIds
56356
+ this.hotP2PChatSessionIds,
56357
+ { activeSessionIds: this.getRecentlyOutputActiveChatSessionIds(now) }
56285
56358
  );
56286
56359
  this.hotP2PChatSessionIds = hotSessions.active;
56287
56360
  return hotSessions;
@@ -56506,6 +56579,7 @@ ${err?.stack || ""}`);
56506
56579
  getP2p: () => ({
56507
56580
  broadcastSessionOutput: (key, data) => {
56508
56581
  if (!this.isCliSession(key)) return;
56582
+ this.markP2PChatOutputActivity(key);
56509
56583
  this.p2p?.broadcastSessionOutput(key, data);
56510
56584
  }
56511
56585
  }),