adhdev 0.9.39 → 0.9.41

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
@@ -5510,6 +5510,15 @@ var init_extension_provider_instance = __esm({
5510
5510
  pendingEvents: this.flushEvents()
5511
5511
  };
5512
5512
  }
5513
+ getSessionModalState(sessionId) {
5514
+ if (sessionId && sessionId !== this.instanceId) return null;
5515
+ return {
5516
+ id: this.instanceId,
5517
+ status: this.currentStatus,
5518
+ title: this.chatTitle || this.agentName || this.provider.name,
5519
+ activeModal: this.activeModal
5520
+ };
5521
+ }
5513
5522
  onEvent(event, data) {
5514
5523
  if (event === "stream_update") {
5515
5524
  if (data?.streams) this.agentStreams = data.streams;
@@ -6137,6 +6146,23 @@ var init_ide_provider_instance = __esm({
6137
6146
  pendingEvents: this.flushEvents()
6138
6147
  };
6139
6148
  }
6149
+ getSessionModalState(sessionId) {
6150
+ if (sessionId && sessionId !== this.instanceId) {
6151
+ for (const ext of this.extensions.values()) {
6152
+ const projected = ext.getSessionModalState?.(sessionId);
6153
+ if (projected?.id === sessionId) return projected;
6154
+ }
6155
+ return null;
6156
+ }
6157
+ const autoApproveActive = (this.currentStatus === "waiting_approval" || this.cachedChat?.status === "waiting_approval") && this.canAutoApprove();
6158
+ const visibleStatus = autoApproveActive ? "generating" : this.currentStatus;
6159
+ return {
6160
+ id: this.instanceId,
6161
+ status: autoApproveActive && this.cachedChat?.status === "waiting_approval" ? "generating" : this.cachedChat?.status || visibleStatus,
6162
+ title: this.cachedChat?.title || this.type,
6163
+ activeModal: autoApproveActive ? null : this.cachedChat?.activeModal || null
6164
+ };
6165
+ }
6140
6166
  onEvent(event, data) {
6141
6167
  if (event === "cdp_connected") {
6142
6168
  } else if (event === "cdp_disconnected") {
@@ -7892,68 +7918,66 @@ function normalizeReadChatMessages(payload) {
7892
7918
  const messages = Array.isArray(payload.messages) ? payload.messages : [];
7893
7919
  return normalizeChatMessages(messages);
7894
7920
  }
7895
- function buildReadChatReplayCollapseSignature(message) {
7896
- if (!message) return "";
7921
+ function normalizeReadChatReplayTextContent(content) {
7922
+ return flattenContent(content || "").replace(/\s+/g, " ").trim();
7923
+ }
7924
+ function getReadChatReplayCollapseInfo(message) {
7925
+ if (!message) return null;
7897
7926
  const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
7898
7927
  const kind = typeof message.kind === "string" ? message.kind.trim().toLowerCase() : "standard";
7899
7928
  const senderName = typeof message.senderName === "string" ? message.senderName.trim().toLowerCase() : "";
7900
- const content = flattenContent(message.content || "").replace(/\s+/g, " ").trim();
7901
- return `${role}:${kind}:${senderName}:${content}`;
7902
- }
7903
- function shouldCollapseReadChatReplayDuplicate(message) {
7904
- if (!message) return false;
7905
- const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
7906
- return role === "assistant" || role === "system";
7907
- }
7908
- function normalizeReadChatReplayText(message) {
7909
- return flattenContent(message?.content || "").replace(/\s+/g, " ").trim();
7929
+ const collapsible = role === "assistant" || role === "system";
7930
+ if (!collapsible) return { role, kind, senderName, content: "", signature: "", collapsible };
7931
+ const content = normalizeReadChatReplayTextContent(message.content);
7932
+ return {
7933
+ role,
7934
+ kind,
7935
+ senderName,
7936
+ content,
7937
+ signature: `${role}:${kind}:${senderName}:${content}`,
7938
+ collapsible
7939
+ };
7910
7940
  }
7911
- function isStableReadChatAssistantAnswer(message) {
7912
- if (!message) return false;
7913
- const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
7914
- const kind = typeof message.kind === "string" ? message.kind.trim().toLowerCase() : "standard";
7915
- if (role !== "assistant") return false;
7916
- if (kind && kind !== "standard") return false;
7917
- const content = normalizeReadChatReplayText(message);
7918
- if (content.length < 160) return false;
7919
- if (/^(bash|shell|terminal) command\b/i.test(content)) return false;
7941
+ function isStableReadChatAssistantAnswerInfo(info) {
7942
+ if (!info) return false;
7943
+ if (info.role !== "assistant") return false;
7944
+ if (info.kind && info.kind !== "standard") return false;
7945
+ if (info.content.length < 160) return false;
7946
+ if (/^(bash|shell|terminal) command\b/i.test(info.content)) return false;
7920
7947
  return true;
7921
7948
  }
7922
- function isReplayedAssistantAnswerAfterStableAnswer(message, stableAnswer) {
7923
- if (!message || !stableAnswer) return false;
7924
- const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
7925
- const kind = typeof message.kind === "string" ? message.kind.trim().toLowerCase() : "standard";
7926
- if (role !== "assistant") return false;
7927
- if (kind && kind !== "standard") return false;
7928
- const content = normalizeReadChatReplayText(message);
7929
- const stableContent = normalizeReadChatReplayText(stableAnswer);
7949
+ function isReplayedAssistantAnswerAfterStableAnswerInfo(info, stableContent) {
7950
+ if (!info || !stableContent) return false;
7951
+ if (info.role !== "assistant") return false;
7952
+ if (info.kind && info.kind !== "standard") return false;
7953
+ const content = info.content;
7930
7954
  if (content.length < 80 || stableContent.length < 80) return false;
7931
7955
  return content === stableContent || content.startsWith(stableContent) || stableContent.startsWith(content);
7932
7956
  }
7933
7957
  function collapseReplayDuplicatesFromReadChat(messages) {
7934
7958
  const collapsed = [];
7935
7959
  const replaySignaturesInCurrentTurn = /* @__PURE__ */ new Set();
7936
- let stableAssistantAnswerInCurrentTurn = null;
7960
+ let stableAssistantAnswerContentInCurrentTurn = "";
7961
+ let previousReplaySignature = "";
7937
7962
  for (const message of messages) {
7938
- const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
7939
- if (role === "user") {
7963
+ const info = getReadChatReplayCollapseInfo(message);
7964
+ if (info?.role === "user") {
7940
7965
  replaySignaturesInCurrentTurn.clear();
7941
- stableAssistantAnswerInCurrentTurn = null;
7966
+ stableAssistantAnswerContentInCurrentTurn = "";
7967
+ previousReplaySignature = "";
7942
7968
  }
7943
- const signature = buildReadChatReplayCollapseSignature(message);
7944
- const previous = collapsed[collapsed.length - 1];
7945
- const previousSignature = buildReadChatReplayCollapseSignature(previous);
7946
- if (shouldCollapseReadChatReplayDuplicate(message) && signature) {
7947
- if (previousSignature === signature) continue;
7948
- if (replaySignaturesInCurrentTurn.has(signature)) continue;
7949
- if (isReplayedAssistantAnswerAfterStableAnswer(message, stableAssistantAnswerInCurrentTurn)) continue;
7969
+ if (info?.collapsible && info.signature) {
7970
+ if (previousReplaySignature === info.signature) continue;
7971
+ if (replaySignaturesInCurrentTurn.has(info.signature)) continue;
7972
+ if (isReplayedAssistantAnswerAfterStableAnswerInfo(info, stableAssistantAnswerContentInCurrentTurn)) continue;
7950
7973
  }
7951
7974
  collapsed.push(message);
7952
- if (shouldCollapseReadChatReplayDuplicate(message) && signature) {
7953
- replaySignaturesInCurrentTurn.add(signature);
7975
+ previousReplaySignature = info?.collapsible ? info.signature : "";
7976
+ if (info?.collapsible && info.signature) {
7977
+ replaySignaturesInCurrentTurn.add(info.signature);
7954
7978
  }
7955
- if (isStableReadChatAssistantAnswer(message)) {
7956
- stableAssistantAnswerInCurrentTurn = message;
7979
+ if (isStableReadChatAssistantAnswerInfo(info)) {
7980
+ stableAssistantAnswerContentInCurrentTurn = info?.content || "";
7957
7981
  }
7958
7982
  }
7959
7983
  return collapsed;
@@ -8033,13 +8057,17 @@ function computeReadChatSync(messages, cursor) {
8033
8057
  };
8034
8058
  }
8035
8059
  if (cursor.tailLimit > 0 && knownSignature === lastMessageSignature) {
8036
- return {
8037
- syncMode: "noop",
8038
- replaceFrom: totalMessages,
8039
- messages: [],
8040
- totalMessages,
8041
- lastMessageSignature
8042
- };
8060
+ const requestedTailCount = Math.min(totalMessages, cursor.tailLimit);
8061
+ if (knownMessageCount >= requestedTailCount) {
8062
+ return {
8063
+ syncMode: "noop",
8064
+ replaceFrom: totalMessages,
8065
+ messages: [],
8066
+ totalMessages,
8067
+ lastMessageSignature
8068
+ };
8069
+ }
8070
+ return buildBoundedTailSync(messages, cursor);
8043
8071
  }
8044
8072
  if (knownMessageCount < totalMessages) {
8045
8073
  const anchorSignature = getChatMessageSignature(messages[knownMessageCount - 1]);
@@ -12478,9 +12506,7 @@ function hydrateCliParsedMessages(parsedMessages, options) {
12478
12506
  };
12479
12507
  });
12480
12508
  }
12481
- function chooseMoreComparableCliMessage(left2, right2) {
12482
- const leftComparable = normalizeComparableMessageContent(left2.content || "");
12483
- const rightComparable = normalizeComparableMessageContent(right2.content || "");
12509
+ function chooseMoreComparableCliMessage(left2, right2, leftComparable = normalizeComparableMessageContent(left2.content || ""), rightComparable = normalizeComparableMessageContent(right2.content || "")) {
12484
12510
  if (leftComparable && leftComparable === rightComparable) {
12485
12511
  const leftNewlines = String(left2.content || "").split(/\r\n|\n|\r/g).length - 1;
12486
12512
  const rightNewlines = String(right2.content || "").split(/\r\n|\n|\r/g).length - 1;
@@ -12495,24 +12521,32 @@ function dedupeConsecutiveComparableCliMessages(messages) {
12495
12521
  ...message,
12496
12522
  content: typeof message.content === "string" ? message.content : String(message.content || "")
12497
12523
  };
12524
+ const currentComparable = normalizeComparableMessageContent(current.content || "");
12498
12525
  const previous = deduped[deduped.length - 1];
12499
12526
  if (!previous) {
12500
- deduped.push(current);
12527
+ deduped.push({ message: current, comparable: currentComparable });
12501
12528
  continue;
12502
12529
  }
12503
- const previousComparable = normalizeComparableMessageContent(previous.content || "");
12504
- const currentComparable = normalizeComparableMessageContent(current.content || "");
12505
- const sameRole = previous.role === current.role;
12506
- const sameKind = (previous.kind || "standard") === (current.kind || "standard");
12507
- const sameSender = (previous.senderName || "") === (current.senderName || "");
12508
- const comparableMatch = previousComparable && previousComparable === currentComparable;
12530
+ const sameRole = previous.message.role === current.role;
12531
+ const sameKind = (previous.message.kind || "standard") === (current.kind || "standard");
12532
+ const sameSender = (previous.message.senderName || "") === (current.senderName || "");
12533
+ const comparableMatch = previous.comparable && previous.comparable === currentComparable;
12509
12534
  if (sameRole && sameKind && sameSender && comparableMatch) {
12510
- deduped[deduped.length - 1] = chooseMoreComparableCliMessage(previous, current);
12535
+ const selected = chooseMoreComparableCliMessage(
12536
+ previous.message,
12537
+ current,
12538
+ previous.comparable,
12539
+ currentComparable
12540
+ );
12541
+ deduped[deduped.length - 1] = {
12542
+ message: selected,
12543
+ comparable: selected === current ? currentComparable : previous.comparable
12544
+ };
12511
12545
  continue;
12512
12546
  }
12513
- deduped.push(current);
12547
+ deduped.push({ message: current, comparable: currentComparable });
12514
12548
  }
12515
- return deduped;
12549
+ return deduped.map((entry) => entry.message);
12516
12550
  }
12517
12551
  function normalizeCliParsedMessages(parsedMessages, options) {
12518
12552
  return dedupeConsecutiveComparableCliMessages(hydrateCliParsedMessages(parsedMessages, options).map((message) => ({
@@ -12963,7 +12997,7 @@ var init_provider_cli_adapter = __esm({
12963
12997
  }
12964
12998
  getFreshParsedStatusCache() {
12965
12999
  const cached2 = this.parsedStatusCache;
12966
- if (cached2 && cached2.committedMessagesRef === this.committedMessages && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.accumulatedRawBuffer === this.accumulatedRawBuffer && cached2.screenText === this.lastScreenText && cached2.currentStatus === this.currentStatus && cached2.activeModal === this.activeModal && cached2.cliName === this.cliName && cached2.lastOutputAt === this.lastOutputAt) {
13000
+ if (cached2 && cached2.committedMessagesRef === this.committedMessages && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.screenText === this.lastScreenText && cached2.currentStatus === this.currentStatus && cached2.activeModal === this.activeModal && cached2.cliName === this.cliName) {
12967
13001
  return cached2.result;
12968
13002
  }
12969
13003
  return null;
@@ -14211,7 +14245,7 @@ var init_provider_cli_adapter = __esm({
14211
14245
  getScriptParsedStatus() {
14212
14246
  const screenText = this.readTerminalScreenText();
14213
14247
  const cached2 = this.parsedStatusCache;
14214
- if (cached2 && cached2.committedMessagesRef === this.committedMessages && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.accumulatedRawBuffer === this.accumulatedRawBuffer && cached2.screenText === screenText && cached2.currentStatus === this.currentStatus && cached2.activeModal === this.activeModal && cached2.cliName === this.cliName && cached2.lastOutputAt === this.lastOutputAt) {
14248
+ if (cached2 && cached2.committedMessagesRef === this.committedMessages && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.screenText === screenText && cached2.currentStatus === this.currentStatus && cached2.activeModal === this.activeModal && cached2.cliName === this.cliName) {
14215
14249
  return cached2.result;
14216
14250
  }
14217
14251
  const parsed = this.parseCurrentTranscript(
@@ -14330,12 +14364,10 @@ var init_provider_cli_adapter = __esm({
14330
14364
  currentTurnScope: this.currentTurnScope,
14331
14365
  recentOutputBuffer: this.recentOutputBuffer,
14332
14366
  accumulatedBuffer: this.accumulatedBuffer,
14333
- accumulatedRawBuffer: this.accumulatedRawBuffer,
14334
14367
  screenText,
14335
14368
  currentStatus: this.currentStatus,
14336
14369
  activeModal: this.activeModal,
14337
14370
  cliName: this.cliName,
14338
- lastOutputAt: this.lastOutputAt,
14339
14371
  result
14340
14372
  };
14341
14373
  return result;
@@ -15424,6 +15456,18 @@ var init_cli_provider_instance = __esm({
15424
15456
  runtimeRecoveryState: runtime?.recoveryState ?? null
15425
15457
  };
15426
15458
  }
15459
+ getSessionModalState() {
15460
+ const adapterStatus = this.adapter.getStatus({ allowParse: false });
15461
+ const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
15462
+ const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
15463
+ const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
15464
+ return {
15465
+ id: this.instanceId,
15466
+ status: visibleStatus,
15467
+ title: dirName,
15468
+ activeModal: autoApproveActive ? null : adapterStatus.activeModal
15469
+ };
15470
+ }
15427
15471
  updateSettings(newSettings) {
15428
15472
  this.settings = { ...newSettings };
15429
15473
  this.adapter.updateRuntimeSettings?.(this.settings);
@@ -32461,6 +32505,18 @@ var init_acp_provider_instance = __esm({
32461
32505
  this.detectStatusTransition();
32462
32506
  }
32463
32507
  }
32508
+ getSessionModalState() {
32509
+ const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
32510
+ return {
32511
+ id: this.instanceId,
32512
+ status: this.currentStatus,
32513
+ title: `${this.provider.name} \xB7 ${dirName}`,
32514
+ activeModal: this.currentStatus === "waiting_approval" ? {
32515
+ message: this.activeToolCalls.find((t) => t.status === "running")?.name || "Permission requested",
32516
+ buttons: ["Approve", "Reject"]
32517
+ } : null
32518
+ };
32519
+ }
32464
32520
  getState() {
32465
32521
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
32466
32522
  const recentMessages = normalizeChatMessages(this.messages.map((m) => {
@@ -41258,6 +41314,29 @@ var init_provider_instance_manager = __esm({
41258
41314
  }
41259
41315
  return sessions;
41260
41316
  }
41317
+ getSessionModalState(sessionId, options = {}) {
41318
+ if (!sessionId) return null;
41319
+ const candidates = [sessionId];
41320
+ if (options.instanceKey && options.instanceKey !== sessionId) {
41321
+ candidates.push(options.instanceKey);
41322
+ }
41323
+ for (const id of candidates) {
41324
+ const instance = this.instances.get(id);
41325
+ if (!instance?.getSessionModalState) continue;
41326
+ try {
41327
+ const projected = instance.getSessionModalState(sessionId);
41328
+ if (!projected?.id) continue;
41329
+ if (projected.id !== sessionId) {
41330
+ LOG.warn("InstanceMgr", `[InstanceManager] Ignoring mismatched session modal projection from ${id}: requested=${sessionId} projected=${projected.id}`);
41331
+ continue;
41332
+ }
41333
+ return projected;
41334
+ } catch (e) {
41335
+ LOG.warn("InstanceMgr", `[InstanceManager] Failed to project session modal metadata from ${id}: ${e.message}`);
41336
+ }
41337
+ }
41338
+ return null;
41339
+ }
41261
41340
  /**
41262
41341
  * Per-category status collect
41263
41342
  */
@@ -88312,7 +88391,7 @@ var init_adhdev_daemon = __esm({
88312
88391
  init_version();
88313
88392
  init_src();
88314
88393
  init_runtime_defaults();
88315
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.39" });
88394
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.41" });
88316
88395
  AdhdevDaemon = class _AdhdevDaemon {
88317
88396
  localHttpServer = null;
88318
88397
  localWss = null;
@@ -88628,37 +88707,20 @@ var init_adhdev_daemon = __esm({
88628
88707
  async (subscription) => this.buildSessionHostDiagnosticsUpdateForSubscription(subscription)
88629
88708
  );
88630
88709
  }
88631
- findProviderStateBySessionId(sessionId) {
88710
+ findSessionModalStateBySessionId(sessionId) {
88632
88711
  if (!this.components || !sessionId) return null;
88633
- const directInstance = this.components.instanceManager.getInstance(sessionId);
88634
- if (directInstance) {
88635
- try {
88636
- return directInstance.getState();
88637
- } catch (error48) {
88638
- LOG.warn("P2P", `Failed to collect subscribed session state for ${sessionId}: ${error48?.message || String(error48)}`);
88639
- return null;
88640
- }
88641
- }
88642
- for (const instance of this.components.instanceManager.getByCategory("ide")) {
88643
- try {
88644
- const state = instance.getState();
88645
- if (state.instanceId === sessionId) return state;
88646
- if (state.category !== "ide") continue;
88647
- const child = state.extensions.find((entry) => entry.instanceId === sessionId);
88648
- if (child) return child;
88649
- } catch (error48) {
88650
- LOG.warn("P2P", `Failed to collect IDE child state for ${sessionId}: ${error48?.message || String(error48)}`);
88651
- }
88652
- }
88653
- return null;
88712
+ const target = this.components.sessionRegistry.get(sessionId);
88713
+ return this.components.instanceManager.getSessionModalState(sessionId, {
88714
+ instanceKey: target?.instanceKey
88715
+ });
88654
88716
  }
88655
88717
  buildSessionModalUpdateForSubscription(subscription) {
88656
- const state = this.findProviderStateBySessionId(subscription.params.targetSessionId);
88718
+ const state = this.findSessionModalStateBySessionId(subscription.params.targetSessionId);
88657
88719
  if (!state) return null;
88658
88720
  const now = Date.now();
88659
- const activeModal = state.activeChat?.activeModal;
88660
- const status = String(state.activeChat?.status || state.status || "idle");
88661
- const title = typeof state.activeChat?.title === "string" ? state.activeChat.title : void 0;
88721
+ const activeModal = state.activeModal;
88722
+ const status = String(state.status || "idle");
88723
+ const title = typeof state.title === "string" ? state.title : void 0;
88662
88724
  const interactionId = this.getSessionInteractionId(subscription.params.targetSessionId);
88663
88725
  const prepared = prepareSessionModalUpdate({
88664
88726
  key: subscription.key,