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/index.js CHANGED
@@ -4990,6 +4990,15 @@ var init_extension_provider_instance = __esm({
4990
4990
  pendingEvents: this.flushEvents()
4991
4991
  };
4992
4992
  }
4993
+ getSessionModalState(sessionId) {
4994
+ if (sessionId && sessionId !== this.instanceId) return null;
4995
+ return {
4996
+ id: this.instanceId,
4997
+ status: this.currentStatus,
4998
+ title: this.chatTitle || this.agentName || this.provider.name,
4999
+ activeModal: this.activeModal
5000
+ };
5001
+ }
4993
5002
  onEvent(event, data) {
4994
5003
  if (event === "stream_update") {
4995
5004
  if (data?.streams) this.agentStreams = data.streams;
@@ -5617,6 +5626,23 @@ var init_ide_provider_instance = __esm({
5617
5626
  pendingEvents: this.flushEvents()
5618
5627
  };
5619
5628
  }
5629
+ getSessionModalState(sessionId) {
5630
+ if (sessionId && sessionId !== this.instanceId) {
5631
+ for (const ext of this.extensions.values()) {
5632
+ const projected = ext.getSessionModalState?.(sessionId);
5633
+ if (projected?.id === sessionId) return projected;
5634
+ }
5635
+ return null;
5636
+ }
5637
+ const autoApproveActive = (this.currentStatus === "waiting_approval" || this.cachedChat?.status === "waiting_approval") && this.canAutoApprove();
5638
+ const visibleStatus = autoApproveActive ? "generating" : this.currentStatus;
5639
+ return {
5640
+ id: this.instanceId,
5641
+ status: autoApproveActive && this.cachedChat?.status === "waiting_approval" ? "generating" : this.cachedChat?.status || visibleStatus,
5642
+ title: this.cachedChat?.title || this.type,
5643
+ activeModal: autoApproveActive ? null : this.cachedChat?.activeModal || null
5644
+ };
5645
+ }
5620
5646
  onEvent(event, data) {
5621
5647
  if (event === "cdp_connected") {
5622
5648
  } else if (event === "cdp_disconnected") {
@@ -7372,68 +7398,66 @@ function normalizeReadChatMessages(payload) {
7372
7398
  const messages = Array.isArray(payload.messages) ? payload.messages : [];
7373
7399
  return normalizeChatMessages(messages);
7374
7400
  }
7375
- function buildReadChatReplayCollapseSignature(message) {
7376
- if (!message) return "";
7401
+ function normalizeReadChatReplayTextContent(content) {
7402
+ return flattenContent(content || "").replace(/\s+/g, " ").trim();
7403
+ }
7404
+ function getReadChatReplayCollapseInfo(message) {
7405
+ if (!message) return null;
7377
7406
  const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
7378
7407
  const kind = typeof message.kind === "string" ? message.kind.trim().toLowerCase() : "standard";
7379
7408
  const senderName = typeof message.senderName === "string" ? message.senderName.trim().toLowerCase() : "";
7380
- const content = flattenContent(message.content || "").replace(/\s+/g, " ").trim();
7381
- return `${role}:${kind}:${senderName}:${content}`;
7382
- }
7383
- function shouldCollapseReadChatReplayDuplicate(message) {
7384
- if (!message) return false;
7385
- const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
7386
- return role === "assistant" || role === "system";
7387
- }
7388
- function normalizeReadChatReplayText(message) {
7389
- return flattenContent(message?.content || "").replace(/\s+/g, " ").trim();
7409
+ const collapsible = role === "assistant" || role === "system";
7410
+ if (!collapsible) return { role, kind, senderName, content: "", signature: "", collapsible };
7411
+ const content = normalizeReadChatReplayTextContent(message.content);
7412
+ return {
7413
+ role,
7414
+ kind,
7415
+ senderName,
7416
+ content,
7417
+ signature: `${role}:${kind}:${senderName}:${content}`,
7418
+ collapsible
7419
+ };
7390
7420
  }
7391
- function isStableReadChatAssistantAnswer(message) {
7392
- if (!message) return false;
7393
- const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
7394
- const kind = typeof message.kind === "string" ? message.kind.trim().toLowerCase() : "standard";
7395
- if (role !== "assistant") return false;
7396
- if (kind && kind !== "standard") return false;
7397
- const content = normalizeReadChatReplayText(message);
7398
- if (content.length < 160) return false;
7399
- if (/^(bash|shell|terminal) command\b/i.test(content)) return false;
7421
+ function isStableReadChatAssistantAnswerInfo(info) {
7422
+ if (!info) return false;
7423
+ if (info.role !== "assistant") return false;
7424
+ if (info.kind && info.kind !== "standard") return false;
7425
+ if (info.content.length < 160) return false;
7426
+ if (/^(bash|shell|terminal) command\b/i.test(info.content)) return false;
7400
7427
  return true;
7401
7428
  }
7402
- function isReplayedAssistantAnswerAfterStableAnswer(message, stableAnswer) {
7403
- if (!message || !stableAnswer) return false;
7404
- const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
7405
- const kind = typeof message.kind === "string" ? message.kind.trim().toLowerCase() : "standard";
7406
- if (role !== "assistant") return false;
7407
- if (kind && kind !== "standard") return false;
7408
- const content = normalizeReadChatReplayText(message);
7409
- const stableContent = normalizeReadChatReplayText(stableAnswer);
7429
+ function isReplayedAssistantAnswerAfterStableAnswerInfo(info, stableContent) {
7430
+ if (!info || !stableContent) return false;
7431
+ if (info.role !== "assistant") return false;
7432
+ if (info.kind && info.kind !== "standard") return false;
7433
+ const content = info.content;
7410
7434
  if (content.length < 80 || stableContent.length < 80) return false;
7411
7435
  return content === stableContent || content.startsWith(stableContent) || stableContent.startsWith(content);
7412
7436
  }
7413
7437
  function collapseReplayDuplicatesFromReadChat(messages) {
7414
7438
  const collapsed = [];
7415
7439
  const replaySignaturesInCurrentTurn = /* @__PURE__ */ new Set();
7416
- let stableAssistantAnswerInCurrentTurn = null;
7440
+ let stableAssistantAnswerContentInCurrentTurn = "";
7441
+ let previousReplaySignature = "";
7417
7442
  for (const message of messages) {
7418
- const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
7419
- if (role === "user") {
7443
+ const info = getReadChatReplayCollapseInfo(message);
7444
+ if (info?.role === "user") {
7420
7445
  replaySignaturesInCurrentTurn.clear();
7421
- stableAssistantAnswerInCurrentTurn = null;
7446
+ stableAssistantAnswerContentInCurrentTurn = "";
7447
+ previousReplaySignature = "";
7422
7448
  }
7423
- const signature = buildReadChatReplayCollapseSignature(message);
7424
- const previous = collapsed[collapsed.length - 1];
7425
- const previousSignature = buildReadChatReplayCollapseSignature(previous);
7426
- if (shouldCollapseReadChatReplayDuplicate(message) && signature) {
7427
- if (previousSignature === signature) continue;
7428
- if (replaySignaturesInCurrentTurn.has(signature)) continue;
7429
- if (isReplayedAssistantAnswerAfterStableAnswer(message, stableAssistantAnswerInCurrentTurn)) continue;
7449
+ if (info?.collapsible && info.signature) {
7450
+ if (previousReplaySignature === info.signature) continue;
7451
+ if (replaySignaturesInCurrentTurn.has(info.signature)) continue;
7452
+ if (isReplayedAssistantAnswerAfterStableAnswerInfo(info, stableAssistantAnswerContentInCurrentTurn)) continue;
7430
7453
  }
7431
7454
  collapsed.push(message);
7432
- if (shouldCollapseReadChatReplayDuplicate(message) && signature) {
7433
- replaySignaturesInCurrentTurn.add(signature);
7455
+ previousReplaySignature = info?.collapsible ? info.signature : "";
7456
+ if (info?.collapsible && info.signature) {
7457
+ replaySignaturesInCurrentTurn.add(info.signature);
7434
7458
  }
7435
- if (isStableReadChatAssistantAnswer(message)) {
7436
- stableAssistantAnswerInCurrentTurn = message;
7459
+ if (isStableReadChatAssistantAnswerInfo(info)) {
7460
+ stableAssistantAnswerContentInCurrentTurn = info?.content || "";
7437
7461
  }
7438
7462
  }
7439
7463
  return collapsed;
@@ -7513,13 +7537,17 @@ function computeReadChatSync(messages, cursor) {
7513
7537
  };
7514
7538
  }
7515
7539
  if (cursor.tailLimit > 0 && knownSignature === lastMessageSignature) {
7516
- return {
7517
- syncMode: "noop",
7518
- replaceFrom: totalMessages,
7519
- messages: [],
7520
- totalMessages,
7521
- lastMessageSignature
7522
- };
7540
+ const requestedTailCount = Math.min(totalMessages, cursor.tailLimit);
7541
+ if (knownMessageCount >= requestedTailCount) {
7542
+ return {
7543
+ syncMode: "noop",
7544
+ replaceFrom: totalMessages,
7545
+ messages: [],
7546
+ totalMessages,
7547
+ lastMessageSignature
7548
+ };
7549
+ }
7550
+ return buildBoundedTailSync(messages, cursor);
7523
7551
  }
7524
7552
  if (knownMessageCount < totalMessages) {
7525
7553
  const anchorSignature = getChatMessageSignature(messages[knownMessageCount - 1]);
@@ -11522,9 +11550,7 @@ function hydrateCliParsedMessages(parsedMessages, options) {
11522
11550
  };
11523
11551
  });
11524
11552
  }
11525
- function chooseMoreComparableCliMessage(left2, right2) {
11526
- const leftComparable = normalizeComparableMessageContent(left2.content || "");
11527
- const rightComparable = normalizeComparableMessageContent(right2.content || "");
11553
+ function chooseMoreComparableCliMessage(left2, right2, leftComparable = normalizeComparableMessageContent(left2.content || ""), rightComparable = normalizeComparableMessageContent(right2.content || "")) {
11528
11554
  if (leftComparable && leftComparable === rightComparable) {
11529
11555
  const leftNewlines = String(left2.content || "").split(/\r\n|\n|\r/g).length - 1;
11530
11556
  const rightNewlines = String(right2.content || "").split(/\r\n|\n|\r/g).length - 1;
@@ -11539,24 +11565,32 @@ function dedupeConsecutiveComparableCliMessages(messages) {
11539
11565
  ...message,
11540
11566
  content: typeof message.content === "string" ? message.content : String(message.content || "")
11541
11567
  };
11568
+ const currentComparable = normalizeComparableMessageContent(current.content || "");
11542
11569
  const previous = deduped[deduped.length - 1];
11543
11570
  if (!previous) {
11544
- deduped.push(current);
11571
+ deduped.push({ message: current, comparable: currentComparable });
11545
11572
  continue;
11546
11573
  }
11547
- const previousComparable = normalizeComparableMessageContent(previous.content || "");
11548
- const currentComparable = normalizeComparableMessageContent(current.content || "");
11549
- const sameRole = previous.role === current.role;
11550
- const sameKind = (previous.kind || "standard") === (current.kind || "standard");
11551
- const sameSender = (previous.senderName || "") === (current.senderName || "");
11552
- const comparableMatch = previousComparable && previousComparable === currentComparable;
11574
+ const sameRole = previous.message.role === current.role;
11575
+ const sameKind = (previous.message.kind || "standard") === (current.kind || "standard");
11576
+ const sameSender = (previous.message.senderName || "") === (current.senderName || "");
11577
+ const comparableMatch = previous.comparable && previous.comparable === currentComparable;
11553
11578
  if (sameRole && sameKind && sameSender && comparableMatch) {
11554
- deduped[deduped.length - 1] = chooseMoreComparableCliMessage(previous, current);
11579
+ const selected = chooseMoreComparableCliMessage(
11580
+ previous.message,
11581
+ current,
11582
+ previous.comparable,
11583
+ currentComparable
11584
+ );
11585
+ deduped[deduped.length - 1] = {
11586
+ message: selected,
11587
+ comparable: selected === current ? currentComparable : previous.comparable
11588
+ };
11555
11589
  continue;
11556
11590
  }
11557
- deduped.push(current);
11591
+ deduped.push({ message: current, comparable: currentComparable });
11558
11592
  }
11559
- return deduped;
11593
+ return deduped.map((entry) => entry.message);
11560
11594
  }
11561
11595
  function normalizeCliParsedMessages(parsedMessages, options) {
11562
11596
  return dedupeConsecutiveComparableCliMessages(hydrateCliParsedMessages(parsedMessages, options).map((message) => ({
@@ -12007,7 +12041,7 @@ var init_provider_cli_adapter = __esm({
12007
12041
  }
12008
12042
  getFreshParsedStatusCache() {
12009
12043
  const cached2 = this.parsedStatusCache;
12010
- 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) {
12044
+ 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) {
12011
12045
  return cached2.result;
12012
12046
  }
12013
12047
  return null;
@@ -13255,7 +13289,7 @@ var init_provider_cli_adapter = __esm({
13255
13289
  getScriptParsedStatus() {
13256
13290
  const screenText = this.readTerminalScreenText();
13257
13291
  const cached2 = this.parsedStatusCache;
13258
- 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) {
13292
+ 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) {
13259
13293
  return cached2.result;
13260
13294
  }
13261
13295
  const parsed = this.parseCurrentTranscript(
@@ -13374,12 +13408,10 @@ var init_provider_cli_adapter = __esm({
13374
13408
  currentTurnScope: this.currentTurnScope,
13375
13409
  recentOutputBuffer: this.recentOutputBuffer,
13376
13410
  accumulatedBuffer: this.accumulatedBuffer,
13377
- accumulatedRawBuffer: this.accumulatedRawBuffer,
13378
13411
  screenText,
13379
13412
  currentStatus: this.currentStatus,
13380
13413
  activeModal: this.activeModal,
13381
13414
  cliName: this.cliName,
13382
- lastOutputAt: this.lastOutputAt,
13383
13415
  result
13384
13416
  };
13385
13417
  return result;
@@ -14468,6 +14500,18 @@ var init_cli_provider_instance = __esm({
14468
14500
  runtimeRecoveryState: runtime?.recoveryState ?? null
14469
14501
  };
14470
14502
  }
14503
+ getSessionModalState() {
14504
+ const adapterStatus = this.adapter.getStatus({ allowParse: false });
14505
+ const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
14506
+ const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
14507
+ const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
14508
+ return {
14509
+ id: this.instanceId,
14510
+ status: visibleStatus,
14511
+ title: dirName,
14512
+ activeModal: autoApproveActive ? null : adapterStatus.activeModal
14513
+ };
14514
+ }
14471
14515
  updateSettings(newSettings) {
14472
14516
  this.settings = { ...newSettings };
14473
14517
  this.adapter.updateRuntimeSettings?.(this.settings);
@@ -31505,6 +31549,18 @@ var init_acp_provider_instance = __esm({
31505
31549
  this.detectStatusTransition();
31506
31550
  }
31507
31551
  }
31552
+ getSessionModalState() {
31553
+ const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
31554
+ return {
31555
+ id: this.instanceId,
31556
+ status: this.currentStatus,
31557
+ title: `${this.provider.name} \xB7 ${dirName}`,
31558
+ activeModal: this.currentStatus === "waiting_approval" ? {
31559
+ message: this.activeToolCalls.find((t) => t.status === "running")?.name || "Permission requested",
31560
+ buttons: ["Approve", "Reject"]
31561
+ } : null
31562
+ };
31563
+ }
31508
31564
  getState() {
31509
31565
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
31510
31566
  const recentMessages = normalizeChatMessages(this.messages.map((m) => {
@@ -40302,6 +40358,29 @@ var init_provider_instance_manager = __esm({
40302
40358
  }
40303
40359
  return sessions;
40304
40360
  }
40361
+ getSessionModalState(sessionId, options = {}) {
40362
+ if (!sessionId) return null;
40363
+ const candidates = [sessionId];
40364
+ if (options.instanceKey && options.instanceKey !== sessionId) {
40365
+ candidates.push(options.instanceKey);
40366
+ }
40367
+ for (const id of candidates) {
40368
+ const instance = this.instances.get(id);
40369
+ if (!instance?.getSessionModalState) continue;
40370
+ try {
40371
+ const projected = instance.getSessionModalState(sessionId);
40372
+ if (!projected?.id) continue;
40373
+ if (projected.id !== sessionId) {
40374
+ LOG.warn("InstanceMgr", `[InstanceManager] Ignoring mismatched session modal projection from ${id}: requested=${sessionId} projected=${projected.id}`);
40375
+ continue;
40376
+ }
40377
+ return projected;
40378
+ } catch (e) {
40379
+ LOG.warn("InstanceMgr", `[InstanceManager] Failed to project session modal metadata from ${id}: ${e.message}`);
40380
+ }
40381
+ }
40382
+ return null;
40383
+ }
40305
40384
  /**
40306
40385
  * Per-category status collect
40307
40386
  */
@@ -56592,7 +56671,7 @@ var init_adhdev_daemon = __esm({
56592
56671
  init_version();
56593
56672
  init_src();
56594
56673
  init_runtime_defaults();
56595
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.39" });
56674
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.41" });
56596
56675
  AdhdevDaemon = class _AdhdevDaemon {
56597
56676
  localHttpServer = null;
56598
56677
  localWss = null;
@@ -56908,37 +56987,20 @@ var init_adhdev_daemon = __esm({
56908
56987
  async (subscription) => this.buildSessionHostDiagnosticsUpdateForSubscription(subscription)
56909
56988
  );
56910
56989
  }
56911
- findProviderStateBySessionId(sessionId) {
56990
+ findSessionModalStateBySessionId(sessionId) {
56912
56991
  if (!this.components || !sessionId) return null;
56913
- const directInstance = this.components.instanceManager.getInstance(sessionId);
56914
- if (directInstance) {
56915
- try {
56916
- return directInstance.getState();
56917
- } catch (error48) {
56918
- LOG.warn("P2P", `Failed to collect subscribed session state for ${sessionId}: ${error48?.message || String(error48)}`);
56919
- return null;
56920
- }
56921
- }
56922
- for (const instance of this.components.instanceManager.getByCategory("ide")) {
56923
- try {
56924
- const state = instance.getState();
56925
- if (state.instanceId === sessionId) return state;
56926
- if (state.category !== "ide") continue;
56927
- const child = state.extensions.find((entry) => entry.instanceId === sessionId);
56928
- if (child) return child;
56929
- } catch (error48) {
56930
- LOG.warn("P2P", `Failed to collect IDE child state for ${sessionId}: ${error48?.message || String(error48)}`);
56931
- }
56932
- }
56933
- return null;
56992
+ const target = this.components.sessionRegistry.get(sessionId);
56993
+ return this.components.instanceManager.getSessionModalState(sessionId, {
56994
+ instanceKey: target?.instanceKey
56995
+ });
56934
56996
  }
56935
56997
  buildSessionModalUpdateForSubscription(subscription) {
56936
- const state = this.findProviderStateBySessionId(subscription.params.targetSessionId);
56998
+ const state = this.findSessionModalStateBySessionId(subscription.params.targetSessionId);
56937
56999
  if (!state) return null;
56938
57000
  const now = Date.now();
56939
- const activeModal = state.activeChat?.activeModal;
56940
- const status = String(state.activeChat?.status || state.status || "idle");
56941
- const title = typeof state.activeChat?.title === "string" ? state.activeChat.title : void 0;
57001
+ const activeModal = state.activeModal;
57002
+ const status = String(state.status || "idle");
57003
+ const title = typeof state.title === "string" ? state.title : void 0;
56942
57004
  const interactionId = this.getSessionInteractionId(subscription.params.targetSessionId);
56943
57005
  const prepared = prepareSessionModalUpdate({
56944
57006
  key: subscription.key,