@adhdev/daemon-core 0.9.30 → 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.mjs CHANGED
@@ -348,14 +348,13 @@ function daemonLog(category, msg, level = "info") {
348
348
  const shouldOutput = LEVEL_NUM[level] >= LEVEL_NUM[currentLevel];
349
349
  const label = LEVEL_LABEL[level];
350
350
  const line = `[${ts()}] [${label}] [${category}] ${msg}`;
351
+ if (!shouldOutput) return;
351
352
  writeToFile(line);
352
353
  ringBuffer.push({ ts: Date.now(), level, category, message: msg });
353
354
  if (ringBuffer.length > RING_BUFFER_SIZE) {
354
355
  ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
355
356
  }
356
- if (shouldOutput) {
357
- origConsoleLog(line);
358
- }
357
+ origConsoleLog(line);
359
358
  }
360
359
  function installGlobalInterceptor() {
361
360
  if (interceptorInstalled) return;
@@ -2161,6 +2160,7 @@ var init_provider_cli_adapter = __esm({
2161
2160
  static STATUS_HOT_PATH_PARSE_MIN_INTERVAL_MS = 1e3;
2162
2161
  static SCREEN_SNAPSHOT_MIN_INTERVAL_MS = 250;
2163
2162
  static MAX_TRACE_ENTRIES = 250;
2163
+ static PARSE_MESSAGE_TAIL_LIMIT = 100;
2164
2164
  providerResolutionMeta;
2165
2165
  static FINISH_RETRY_DELAY_MS = 300;
2166
2166
  static MAX_FINISH_RETRIES = 2;
@@ -2192,6 +2192,32 @@ var init_provider_cli_adapter = __esm({
2192
2192
  }
2193
2193
  return null;
2194
2194
  }
2195
+ selectParseBaseMessages(baseMessages) {
2196
+ if (baseMessages.length <= _ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT) return baseMessages;
2197
+ return baseMessages.slice(-_ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT);
2198
+ }
2199
+ messagesComparable(left, right) {
2200
+ if (!left || !right) return false;
2201
+ if ((left.role || "") !== (right.role || "")) return false;
2202
+ const leftText = normalizeComparableTranscriptText(left.content);
2203
+ const rightText = normalizeComparableTranscriptText(right.content);
2204
+ return !!leftText && leftText === rightText;
2205
+ }
2206
+ stitchParsedMessagesWithCommittedBase(parsedMessages, fullBaseMessages, parseBaseMessages) {
2207
+ if (!Array.isArray(parsedMessages) || parsedMessages.length === 0) return parsedMessages;
2208
+ if (fullBaseMessages.length <= parseBaseMessages.length) return parsedMessages;
2209
+ const parsedFirst = parsedMessages[0];
2210
+ const fullFirst = fullBaseMessages[0];
2211
+ if (parsedMessages.length >= fullBaseMessages.length && this.messagesComparable(parsedFirst, fullFirst)) {
2212
+ return parsedMessages;
2213
+ }
2214
+ const tailFirst = parseBaseMessages[0];
2215
+ if (tailFirst && this.messagesComparable(parsedFirst, tailFirst)) {
2216
+ const prefixLength = fullBaseMessages.length - parseBaseMessages.length;
2217
+ return [...fullBaseMessages.slice(0, prefixLength), ...parsedMessages];
2218
+ }
2219
+ return [...fullBaseMessages, ...parsedMessages];
2220
+ }
2195
2221
  getIdleFinishConfirmMs() {
2196
2222
  return this.timeouts.idleFinishConfirm;
2197
2223
  }
@@ -2777,7 +2803,7 @@ var init_provider_cli_adapter = __esm({
2777
2803
  const ctx = { now, modal, status, parsedMessages, lastParsedAssistant, parsedStatus: parsedStatus || null, prevStatus };
2778
2804
  if (!this.applyPendingScriptStatusDebounce(ctx)) return;
2779
2805
  const recentInteractiveActivity = this.hasRecentInteractiveActivity(now);
2780
- LOG.info(
2806
+ LOG.debug(
2781
2807
  "CLI",
2782
2808
  `[${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)}`
2783
2809
  );
@@ -3144,18 +3170,26 @@ var init_provider_cli_adapter = __esm({
3144
3170
  try {
3145
3171
  const screenText = this.terminalScreen.getText();
3146
3172
  const tail = this.recentOutputBuffer.slice(-500);
3173
+ const parseBaseMessages = this.selectParseBaseMessages(this.committedMessages);
3147
3174
  const input = buildCliParseInput({
3148
3175
  accumulatedBuffer: this.accumulatedBuffer,
3149
3176
  accumulatedRawBuffer: this.accumulatedRawBuffer,
3150
3177
  recentOutputBuffer: this.recentOutputBuffer,
3151
3178
  terminalScreenText: screenText,
3152
- baseMessages: this.committedMessages,
3179
+ baseMessages: parseBaseMessages,
3153
3180
  partialResponse: this.responseBuffer,
3154
3181
  isWaitingForResponse: this.isWaitingForResponse,
3155
3182
  scope: this.currentTurnScope,
3156
3183
  runtimeSettings: this.runtimeSettings
3157
3184
  });
3158
3185
  const session = this.cliScripts.parseSession({ ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
3186
+ if (session && typeof session === "object" && Array.isArray(session.messages)) {
3187
+ session.messages = this.stitchParsedMessagesWithCommittedBase(
3188
+ session.messages,
3189
+ this.committedMessages,
3190
+ parseBaseMessages
3191
+ );
3192
+ }
3159
3193
  this.parseErrorMessage = null;
3160
3194
  return session && typeof session === "object" ? session : null;
3161
3195
  } catch (e) {
@@ -3476,12 +3510,13 @@ var init_provider_cli_adapter = __esm({
3476
3510
  }
3477
3511
  try {
3478
3512
  const screenText = typeof screenTextOverride === "string" ? screenTextOverride : this.terminalScreen.getText();
3513
+ const parseBaseMessages = this.selectParseBaseMessages(baseMessages);
3479
3514
  const input = buildCliParseInput({
3480
3515
  accumulatedBuffer: this.accumulatedBuffer,
3481
3516
  accumulatedRawBuffer: this.accumulatedRawBuffer,
3482
3517
  recentOutputBuffer: this.recentOutputBuffer,
3483
3518
  terminalScreenText: screenText,
3484
- baseMessages,
3519
+ baseMessages: parseBaseMessages,
3485
3520
  partialResponse,
3486
3521
  isWaitingForResponse: this.isWaitingForResponse,
3487
3522
  scope,
@@ -3493,6 +3528,11 @@ var init_provider_cli_adapter = __esm({
3493
3528
  }
3494
3529
  const normalizedParsed = this.suppressStaleParsedApproval(parsed, input.recentBuffer, input.screenText);
3495
3530
  if (normalizedParsed && Array.isArray(normalizedParsed.messages)) {
3531
+ normalizedParsed.messages = this.stitchParsedMessagesWithCommittedBase(
3532
+ normalizedParsed.messages,
3533
+ baseMessages,
3534
+ parseBaseMessages
3535
+ );
3496
3536
  this.trimLastAssistantEcho(normalizedParsed.messages, scope?.prompt || getLastUserPromptText(baseMessages));
3497
3537
  }
3498
3538
  this.parseErrorMessage = null;
@@ -4993,6 +5033,7 @@ function classifyHotChatSessionsForSubscriptionFlush(sessions, previousHotSessio
4993
5033
  Number.isFinite(options.recentMessageGraceMs) ? Number(options.recentMessageGraceMs) : DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS
4994
5034
  );
4995
5035
  const activeStatuses = options.activeStatuses ?? DEFAULT_ACTIVE_CHAT_POLL_STATUSES;
5036
+ const activeSessionIds = options.activeSessionIds ?? /* @__PURE__ */ new Set();
4996
5037
  const active = /* @__PURE__ */ new Set();
4997
5038
  const excluded = /* @__PURE__ */ new Set();
4998
5039
  for (const session of sessions) {
@@ -5002,6 +5043,10 @@ function classifyHotChatSessionsForSubscriptionFlush(sessions, previousHotSessio
5002
5043
  excluded.add(sessionId);
5003
5044
  continue;
5004
5045
  }
5046
+ if (activeSessionIds.has(sessionId)) {
5047
+ active.add(sessionId);
5048
+ continue;
5049
+ }
5005
5050
  const status = String(session?.status || "").toLowerCase();
5006
5051
  const unread = session?.unread === true;
5007
5052
  const inboxBucket = String(session?.inboxBucket || "").toLowerCase();
@@ -10547,6 +10592,7 @@ async function handleReadChat(h, args) {
10547
10592
  return { success: false, error: `${transport} adapter not found` };
10548
10593
  }
10549
10594
  if (isExtensionTransport(transport)) {
10595
+ let extensionReadChatError = "";
10550
10596
  try {
10551
10597
  const evalResult = await h.evaluateProviderScript("readChat", void 0, READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS);
10552
10598
  if (evalResult?.result) {
@@ -10554,7 +10600,8 @@ async function handleReadChat(h, args) {
10554
10600
  if (typeof parsed === "string") {
10555
10601
  try {
10556
10602
  parsed = JSON.parse(parsed);
10557
- } catch {
10603
+ } catch (e) {
10604
+ extensionReadChatError = `extension read_chat parse failed: ${e?.message || String(e)}`;
10558
10605
  }
10559
10606
  }
10560
10607
  if (parsed && typeof parsed === "object") {
@@ -10579,8 +10626,14 @@ async function handleReadChat(h, args) {
10579
10626
  );
10580
10627
  return buildReadChatCommandResult(validated, args);
10581
10628
  }
10629
+ if (!extensionReadChatError) {
10630
+ extensionReadChatError = "extension read_chat returned a non-object payload";
10631
+ }
10632
+ } else {
10633
+ extensionReadChatError = "extension read_chat returned no payload";
10582
10634
  }
10583
10635
  } catch (e) {
10636
+ extensionReadChatError = `extension read_chat failed: ${e?.message || String(e)}`;
10584
10637
  _log(`Extension error: ${e.message}`);
10585
10638
  traceProviderEvent(args, "provider", "extension.read_chat.error", {
10586
10639
  h,
@@ -10594,8 +10647,8 @@ async function handleReadChat(h, args) {
10594
10647
  const parentSessionId = h.currentSession?.parentSessionId;
10595
10648
  if (cdp2 && parentSessionId) {
10596
10649
  const stream = await h.agentStream.collectActiveSession(cdp2, parentSessionId);
10597
- if (stream?.agentType !== provider?.type) {
10598
- return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
10650
+ if (stream && stream.agentType !== provider?.type) {
10651
+ return { success: false, error: `extension read_chat stream agent mismatch for ${provider?.type || "unknown_extension"}` };
10599
10652
  }
10600
10653
  if (stream) {
10601
10654
  h.historyWriter.appendNewMessages(
@@ -10613,12 +10666,13 @@ async function handleReadChat(h, args) {
10613
10666
  }
10614
10667
  }
10615
10668
  }
10616
- return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
10669
+ return { success: false, error: extensionReadChatError || "extension read_chat unavailable" };
10617
10670
  }
10618
10671
  const cdp = h.getCdp();
10619
10672
  if (!cdp?.isConnected) return { success: false, error: "CDP not connected" };
10620
10673
  const webviewScript = h.getProviderScript("webviewReadChat") || h.getProviderScript("webview_read_chat");
10621
10674
  if (webviewScript) {
10675
+ let webviewReadChatError = "";
10622
10676
  try {
10623
10677
  const matchText = provider?.webviewMatchText;
10624
10678
  const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
@@ -10628,7 +10682,8 @@ async function handleReadChat(h, args) {
10628
10682
  if (typeof parsed === "string") {
10629
10683
  try {
10630
10684
  parsed = JSON.parse(parsed);
10631
- } catch {
10685
+ } catch (e) {
10686
+ webviewReadChatError = `webview read_chat parse failed: ${e?.message || String(e)}`;
10632
10687
  }
10633
10688
  }
10634
10689
  if (parsed && typeof parsed === "object") {
@@ -10643,14 +10698,21 @@ async function handleReadChat(h, args) {
10643
10698
  );
10644
10699
  return buildReadChatCommandResult(validated, args);
10645
10700
  }
10701
+ if (!webviewReadChatError) {
10702
+ webviewReadChatError = "webview read_chat returned a non-object payload";
10703
+ }
10704
+ } else {
10705
+ webviewReadChatError = "webview read_chat returned no payload";
10646
10706
  }
10647
10707
  } catch (e) {
10708
+ webviewReadChatError = `webview read_chat failed: ${e?.message || String(e)}`;
10648
10709
  _log(`Webview readChat error: ${e.message}`);
10649
10710
  }
10650
- return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
10711
+ return { success: false, error: webviewReadChatError || "webview read_chat unavailable" };
10651
10712
  }
10652
10713
  const script = h.getProviderScript("readChat") || h.getProviderScript("read_chat");
10653
10714
  if (script) {
10715
+ let ideReadChatError = "";
10654
10716
  try {
10655
10717
  const evalResult = await h.evaluateProviderScript("readChat", void 0, READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS);
10656
10718
  if (evalResult?.result) {
@@ -10658,12 +10720,13 @@ async function handleReadChat(h, args) {
10658
10720
  if (typeof parsed === "string") {
10659
10721
  try {
10660
10722
  parsed = JSON.parse(parsed);
10661
- } catch {
10723
+ } catch (e) {
10724
+ ideReadChatError = `ide read_chat parse failed: ${e?.message || String(e)}`;
10662
10725
  }
10663
10726
  }
10664
- if (parsed && typeof parsed === "object" && parsed.messages?.length > 0) {
10727
+ if (parsed && typeof parsed === "object") {
10665
10728
  const validated = validateReadChatResultPayload(parsed, "ide read_chat");
10666
- _log(`OK: ${validated.messages?.length} msgs`);
10729
+ _log(`OK: ${validated.messages?.length || 0} msgs`);
10667
10730
  traceProviderEvent(args, "provider", "ide.read_chat.success", {
10668
10731
  h,
10669
10732
  provider,
@@ -10683,8 +10746,14 @@ async function handleReadChat(h, args) {
10683
10746
  );
10684
10747
  return buildReadChatCommandResult(validated, args);
10685
10748
  }
10749
+ if (!ideReadChatError) {
10750
+ ideReadChatError = "ide read_chat returned a non-object payload";
10751
+ }
10752
+ } else {
10753
+ ideReadChatError = "ide read_chat returned no payload";
10686
10754
  }
10687
10755
  } catch (e) {
10756
+ ideReadChatError = `ide read_chat failed: ${e?.message || String(e)}`;
10688
10757
  LOG.info("Command", `[read_chat] Script error: ${e.message}`);
10689
10758
  traceProviderEvent(args, "provider", "ide.read_chat.error", {
10690
10759
  h,
@@ -10693,8 +10762,9 @@ async function handleReadChat(h, args) {
10693
10762
  payload: { method: "evaluate", error: e.message }
10694
10763
  });
10695
10764
  }
10765
+ return { success: false, error: ideReadChatError || "ide read_chat unavailable" };
10696
10766
  }
10697
- return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
10767
+ return { success: false, error: "read_chat unavailable" };
10698
10768
  }
10699
10769
  async function handleSendChat(h, args) {
10700
10770
  const input = getSendChatInputEnvelope(args);
@@ -15941,6 +16011,9 @@ var ProviderLoader = class _ProviderLoader {
15941
16011
  log(msg) {
15942
16012
  this.logFn(`[ProviderLoader] ${msg}`);
15943
16013
  }
16014
+ debugLog(msg) {
16015
+ LOG.debug("Provider", `[ProviderLoader] ${msg}`);
16016
+ }
15944
16017
  // ─── Public API ────────────────────────────────
15945
16018
  /**
15946
16019
  * User override root (~/.adhdev/providers by default).
@@ -16547,7 +16620,7 @@ var ProviderLoader = class _ProviderLoader {
16547
16620
  const loaded = this.loadScriptsFromDir(type, entry.scriptDir);
16548
16621
  if (loaded) {
16549
16622
  resolved.scripts = loaded;
16550
- this.log(` [compatibility] ${type} v${currentVersion} \u2192 ${entry.scriptDir}`);
16623
+ this.debugLog(` [compatibility] ${type} v${currentVersion} \u2192 ${entry.scriptDir}`);
16551
16624
  resolved._resolvedScriptDir = entry.scriptDir;
16552
16625
  resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
16553
16626
  if (providerDir) {
@@ -16563,7 +16636,7 @@ var ProviderLoader = class _ProviderLoader {
16563
16636
  const loaded = this.loadScriptsFromDir(type, base.defaultScriptDir);
16564
16637
  if (loaded) {
16565
16638
  resolved.scripts = loaded;
16566
- this.log(` [compatibility] ${type} v${currentVersion} \u2192 default: ${base.defaultScriptDir}`);
16639
+ this.debugLog(` [compatibility] ${type} v${currentVersion} \u2192 default: ${base.defaultScriptDir}`);
16567
16640
  resolved._resolvedScriptDir = base.defaultScriptDir;
16568
16641
  resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
16569
16642
  if (providerDir) {
@@ -16598,7 +16671,7 @@ var ProviderLoader = class _ProviderLoader {
16598
16671
  const loaded = this.loadScriptsFromDir(type, base.defaultScriptDir);
16599
16672
  if (loaded) {
16600
16673
  resolved.scripts = loaded;
16601
- this.log(` [compatibility] ${type} no version detected \u2192 default: ${base.defaultScriptDir}`);
16674
+ this.debugLog(` [compatibility] ${type} no version detected \u2192 default: ${base.defaultScriptDir}`);
16602
16675
  resolved._resolvedScriptDir = base.defaultScriptDir;
16603
16676
  resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
16604
16677
  if (providerDir) {