adhdev 0.8.71 → 0.8.74

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
@@ -1153,6 +1153,31 @@ var init_saved_sessions = __esm({
1153
1153
  }
1154
1154
  });
1155
1155
 
1156
+ // ../../oss/packages/daemon-core/src/providers/provider-session-id.ts
1157
+ function normalizeProviderSessionId(providerType, providerSessionId) {
1158
+ const normalizedProviderType = typeof providerType === "string" ? providerType.trim() : "";
1159
+ const normalizedId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
1160
+ if (!normalizedId) return "";
1161
+ const lowered = normalizedId.toLowerCase();
1162
+ if (lowered === "undefined" || lowered === "null") return "";
1163
+ if (normalizedProviderType === "hermes-cli" && !HERMES_SESSION_ID_RE.test(normalizedId)) {
1164
+ return "";
1165
+ }
1166
+ return normalizedId;
1167
+ }
1168
+ function isLegacyVolatileSessionReadKey(key) {
1169
+ const normalizedKey = typeof key === "string" ? key.trim() : "";
1170
+ if (!normalizedKey) return false;
1171
+ return normalizedKey.startsWith("provider:codex:vscode-webview://");
1172
+ }
1173
+ var HERMES_SESSION_ID_RE;
1174
+ var init_provider_session_id = __esm({
1175
+ "../../oss/packages/daemon-core/src/providers/provider-session-id.ts"() {
1176
+ "use strict";
1177
+ HERMES_SESSION_ID_RE = /^\d{8}_\d{6}_[a-z0-9]+$/i;
1178
+ }
1179
+ });
1180
+
1156
1181
  // ../../oss/packages/daemon-core/src/config/state-store.ts
1157
1182
  function isPlainObject2(value) {
1158
1183
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -1162,15 +1187,31 @@ function getStatePath() {
1162
1187
  }
1163
1188
  function normalizeState(raw) {
1164
1189
  const parsed = isPlainObject2(raw) ? raw : {};
1190
+ const recentActivity = (Array.isArray(parsed.recentActivity) ? parsed.recentActivity : []).filter((entry) => {
1191
+ if (!isPlainObject2(entry)) return false;
1192
+ const normalizedId = normalizeProviderSessionId(
1193
+ typeof entry.providerType === "string" ? entry.providerType : "",
1194
+ typeof entry.providerSessionId === "string" ? entry.providerSessionId : ""
1195
+ );
1196
+ if (typeof entry.providerSessionId === "string" && !normalizedId) return false;
1197
+ return true;
1198
+ });
1199
+ const savedProviderSessions = (Array.isArray(parsed.savedProviderSessions) ? parsed.savedProviderSessions : []).filter((entry) => {
1200
+ if (!isPlainObject2(entry)) return false;
1201
+ return !!normalizeProviderSessionId(
1202
+ typeof entry.providerType === "string" ? entry.providerType : "",
1203
+ typeof entry.providerSessionId === "string" ? entry.providerSessionId : ""
1204
+ );
1205
+ });
1165
1206
  const sessionReads = Object.fromEntries(
1166
- Object.entries(isPlainObject2(parsed.sessionReads) ? parsed.sessionReads : {}).filter(([, value]) => typeof value === "number" && Number.isFinite(value))
1207
+ Object.entries(isPlainObject2(parsed.sessionReads) ? parsed.sessionReads : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "number" && Number.isFinite(value))
1167
1208
  );
1168
1209
  const sessionReadMarkers = Object.fromEntries(
1169
- Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([, value]) => typeof value === "string")
1210
+ Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string")
1170
1211
  );
1171
1212
  return {
1172
- recentActivity: Array.isArray(parsed.recentActivity) ? parsed.recentActivity : [],
1173
- savedProviderSessions: Array.isArray(parsed.savedProviderSessions) ? parsed.savedProviderSessions : [],
1213
+ recentActivity,
1214
+ savedProviderSessions,
1174
1215
  sessionReads,
1175
1216
  sessionReadMarkers
1176
1217
  };
@@ -1202,6 +1243,7 @@ var init_state_store = __esm({
1202
1243
  import_fs2 = require("fs");
1203
1244
  import_path2 = require("path");
1204
1245
  init_config();
1246
+ init_provider_session_id();
1205
1247
  DEFAULT_STATE = {
1206
1248
  recentActivity: [],
1207
1249
  savedProviderSessions: [],
@@ -3820,19 +3862,91 @@ function sanitizeHistoryMessage(agentType, message) {
3820
3862
  content
3821
3863
  };
3822
3864
  }
3823
- function readChatHistory(agentType, offset = 0, limit = 30, historySessionId) {
3865
+ function sanitizeHistoryFileSegment(value) {
3866
+ return String(value || "").replace(/[^a-zA-Z0-9_-]/g, "_");
3867
+ }
3868
+ function listHistoryFiles(dir, historySessionId) {
3869
+ const sanitizedSessionId = historySessionId ? sanitizeHistoryFileSegment(historySessionId) : "";
3870
+ return fs3.readdirSync(dir).filter((file2) => {
3871
+ if (!file2.endsWith(".jsonl")) return false;
3872
+ if (sanitizedSessionId) {
3873
+ return file2.startsWith(`${sanitizedSessionId}_`);
3874
+ }
3875
+ return true;
3876
+ }).sort().reverse();
3877
+ }
3878
+ function buildSavedHistoryCacheSignature(dir, files) {
3879
+ return files.map((file2) => {
3880
+ try {
3881
+ const stat4 = fs3.statSync(path7.join(dir, file2));
3882
+ return `${file2}:${stat4.size}:${Math.trunc(stat4.mtimeMs)}`;
3883
+ } catch {
3884
+ return `${file2}:missing`;
3885
+ }
3886
+ }).join("|");
3887
+ }
3888
+ function computeSavedHistorySessionSummaries(agentType, dir, files) {
3889
+ const groupedFiles = /* @__PURE__ */ new Map();
3890
+ const filePattern = /^([A-Za-z0-9_-]+)_\d{4}-\d{2}-\d{2}\.jsonl$/;
3891
+ for (const file2 of files) {
3892
+ const match = file2.match(filePattern);
3893
+ if (!match?.[1]) continue;
3894
+ const historySessionId = match[1];
3895
+ const grouped = groupedFiles.get(historySessionId) || [];
3896
+ grouped.push(file2);
3897
+ groupedFiles.set(historySessionId, grouped);
3898
+ }
3899
+ const summaries = [];
3900
+ for (const [historySessionId, grouped] of groupedFiles.entries()) {
3901
+ let messageCount = 0;
3902
+ let firstMessageAt = 0;
3903
+ let lastMessageAt = 0;
3904
+ let sessionTitle = "";
3905
+ let preview = "";
3906
+ let workspace = "";
3907
+ for (const file2 of grouped.sort()) {
3908
+ const filePath = path7.join(dir, file2);
3909
+ const content = fs3.readFileSync(filePath, "utf-8");
3910
+ const lines = content.split("\n").filter(Boolean);
3911
+ for (const line of lines) {
3912
+ let parsed = null;
3913
+ try {
3914
+ parsed = JSON.parse(line);
3915
+ } catch {
3916
+ parsed = null;
3917
+ }
3918
+ if (!parsed || parsed.historySessionId !== historySessionId) continue;
3919
+ if (parsed.kind === "session_start") {
3920
+ if (!workspace && parsed.workspace) workspace = parsed.workspace;
3921
+ continue;
3922
+ }
3923
+ messageCount += 1;
3924
+ if (!firstMessageAt || parsed.receivedAt < firstMessageAt) firstMessageAt = parsed.receivedAt;
3925
+ if (!lastMessageAt || parsed.receivedAt > lastMessageAt) lastMessageAt = parsed.receivedAt;
3926
+ if (parsed.sessionTitle) sessionTitle = parsed.sessionTitle;
3927
+ if (parsed.role !== "system" && parsed.content.trim()) preview = parsed.content.trim();
3928
+ }
3929
+ }
3930
+ if (messageCount === 0 || !lastMessageAt) continue;
3931
+ summaries.push({
3932
+ historySessionId,
3933
+ sessionTitle: sessionTitle || void 0,
3934
+ messageCount,
3935
+ firstMessageAt,
3936
+ lastMessageAt,
3937
+ preview: preview || void 0,
3938
+ workspace: workspace || void 0
3939
+ });
3940
+ }
3941
+ summaries.sort((a, b) => b.lastMessageAt - a.lastMessageAt);
3942
+ return summaries;
3943
+ }
3944
+ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0) {
3824
3945
  try {
3825
3946
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
3826
3947
  const dir = path7.join(HISTORY_DIR, sanitized);
3827
3948
  if (!fs3.existsSync(dir)) return { messages: [], hasMore: false };
3828
- const sanitizedInstance = historySessionId?.replace(/[^a-zA-Z0-9_-]/g, "_");
3829
- const files = fs3.readdirSync(dir).filter((f) => {
3830
- if (!f.endsWith(".jsonl")) return false;
3831
- if (sanitizedInstance) {
3832
- return f.startsWith(`${sanitizedInstance}_`);
3833
- }
3834
- return true;
3835
- }).sort().reverse();
3949
+ const files = listHistoryFiles(dir, historySessionId);
3836
3950
  const allMessages = [];
3837
3951
  const seen = /* @__PURE__ */ new Set();
3838
3952
  for (const file2 of files) {
@@ -3863,8 +3977,13 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId) {
3863
3977
  if (message.role !== "system") lastTurn = message;
3864
3978
  }
3865
3979
  const collapsed = collapseReplayAssistantTurns(agentType, chronological);
3866
- const sliced = collapsed.slice(offset, offset + limit);
3867
- const hasMore = collapsed.length > offset + limit;
3980
+ const boundedLimit = Math.max(1, limit);
3981
+ const boundedOffset = Math.max(0, offset);
3982
+ const boundedExclude = Math.max(0, Math.min(excludeRecentCount, collapsed.length));
3983
+ const endExclusive = Math.max(0, collapsed.length - boundedExclude - boundedOffset);
3984
+ const startInclusive = Math.max(0, endExclusive - boundedLimit);
3985
+ const sliced = collapsed.slice(startInclusive, endExclusive);
3986
+ const hasMore = startInclusive > 0;
3868
3987
  return { messages: sliced, hasMore };
3869
3988
  } catch {
3870
3989
  return { messages: [], hasMore: false };
@@ -3874,61 +3993,20 @@ function listSavedHistorySessions(agentType, options = {}) {
3874
3993
  try {
3875
3994
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
3876
3995
  const dir = path7.join(HISTORY_DIR, sanitized);
3877
- if (!fs3.existsSync(dir)) return { sessions: [], hasMore: false };
3878
- const groupedFiles = /* @__PURE__ */ new Map();
3879
- const filePattern = /^([A-Za-z0-9_-]+)_\d{4}-\d{2}-\d{2}\.jsonl$/;
3880
- for (const file2 of fs3.readdirSync(dir)) {
3881
- if (!file2.endsWith(".jsonl")) continue;
3882
- const match = file2.match(filePattern);
3883
- if (!match?.[1]) continue;
3884
- const historySessionId = match[1];
3885
- const files = groupedFiles.get(historySessionId) || [];
3886
- files.push(file2);
3887
- groupedFiles.set(historySessionId, files);
3888
- }
3889
- const summaries = [];
3890
- for (const [historySessionId, files] of groupedFiles.entries()) {
3891
- let messageCount = 0;
3892
- let firstMessageAt = 0;
3893
- let lastMessageAt = 0;
3894
- let sessionTitle = "";
3895
- let preview = "";
3896
- let workspace = "";
3897
- for (const file2 of files.sort()) {
3898
- const filePath = path7.join(dir, file2);
3899
- const content = fs3.readFileSync(filePath, "utf-8");
3900
- const lines = content.split("\n").filter(Boolean);
3901
- for (const line of lines) {
3902
- let parsed = null;
3903
- try {
3904
- parsed = JSON.parse(line);
3905
- } catch {
3906
- parsed = null;
3907
- }
3908
- if (!parsed || parsed.historySessionId !== historySessionId) continue;
3909
- if (parsed.kind === "session_start") {
3910
- if (!workspace && parsed.workspace) workspace = parsed.workspace;
3911
- continue;
3912
- }
3913
- messageCount += 1;
3914
- if (!firstMessageAt || parsed.receivedAt < firstMessageAt) firstMessageAt = parsed.receivedAt;
3915
- if (!lastMessageAt || parsed.receivedAt > lastMessageAt) lastMessageAt = parsed.receivedAt;
3916
- if (parsed.sessionTitle) sessionTitle = parsed.sessionTitle;
3917
- if (parsed.role !== "system" && parsed.content.trim()) preview = parsed.content.trim();
3918
- }
3919
- }
3920
- if (messageCount === 0 || !lastMessageAt) continue;
3921
- summaries.push({
3922
- historySessionId,
3923
- sessionTitle: sessionTitle || void 0,
3924
- messageCount,
3925
- firstMessageAt,
3926
- lastMessageAt,
3927
- preview: preview || void 0,
3928
- workspace: workspace || void 0
3996
+ if (!fs3.existsSync(dir)) {
3997
+ savedHistorySessionCache.delete(sanitized);
3998
+ return { sessions: [], hasMore: false };
3999
+ }
4000
+ const files = listHistoryFiles(dir);
4001
+ const signature = buildSavedHistoryCacheSignature(dir, files);
4002
+ const cached2 = savedHistorySessionCache.get(sanitized);
4003
+ const summaries = cached2?.signature === signature ? cached2.summaries : computeSavedHistorySessionSummaries(agentType, dir, files);
4004
+ if (!cached2 || cached2.signature !== signature) {
4005
+ savedHistorySessionCache.set(sanitized, {
4006
+ signature,
4007
+ summaries
3929
4008
  });
3930
4009
  }
3931
- summaries.sort((a, b) => b.lastMessageAt - a.lastMessageAt);
3932
4010
  const offset = Math.max(0, options.offset || 0);
3933
4011
  const limit = Math.max(1, options.limit || 30);
3934
4012
  const sliced = summaries.slice(offset, offset + limit);
@@ -3940,7 +4018,7 @@ function listSavedHistorySessions(agentType, options = {}) {
3940
4018
  return { sessions: [], hasMore: false };
3941
4019
  }
3942
4020
  }
3943
- var fs3, path7, os6, HISTORY_DIR, RETAIN_DAYS, CODEX_STARTER_PROMPT_RE, ChatHistoryWriter;
4021
+ var fs3, path7, os6, HISTORY_DIR, RETAIN_DAYS, savedHistorySessionCache, CODEX_STARTER_PROMPT_RE, ChatHistoryWriter;
3944
4022
  var init_chat_history = __esm({
3945
4023
  "../../oss/packages/daemon-core/src/config/chat-history.ts"() {
3946
4024
  "use strict";
@@ -3950,6 +4028,7 @@ var init_chat_history = __esm({
3950
4028
  init_chat_message_normalization();
3951
4029
  HISTORY_DIR = path7.join(os6.homedir(), ".adhdev", "history");
3952
4030
  RETAIN_DAYS = 30;
4031
+ savedHistorySessionCache = /* @__PURE__ */ new Map();
3953
4032
  CODEX_STARTER_PROMPT_RE = /^(?:[›❯]\s*)?(?:Find and fix a bug in @filename|Improve documentation in @filename|Write tests for @filename|Explain this codebase|Summarize recent commits|Implement \{feature\}|Use \/skills(?: to list available skills)?|Run \/review on my current changes)$/i;
3954
4033
  ChatHistoryWriter = class {
3955
4034
  /** Last seen message count per agent (deduplication) */
@@ -4912,7 +4991,7 @@ var init_read_chat_contract = __esm({
4912
4991
 
4913
4992
  // ../../oss/packages/daemon-core/src/providers/approval-utils.ts
4914
4993
  function normalizeApprovalLabel(value) {
4915
- return String(value || "").toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
4994
+ return String(value || "").toLowerCase().replace(/^[\s\[(<{]*\d+(?:\s*[.)\]}>:-]|\s)+/, "").replace(/[^\p{L}\p{N}]+/gu, " ").trim();
4916
4995
  }
4917
4996
  function getApprovalPositiveHints(provider) {
4918
4997
  const customHints = Array.isArray(provider?.approvalPositiveHints) ? provider.approvalPositiveHints.map((hint) => normalizeApprovalLabel(String(hint || ""))).filter(Boolean) : [];
@@ -4946,19 +5025,19 @@ var init_approval_utils = __esm({
4946
5025
  "../../oss/packages/daemon-core/src/providers/approval-utils.ts"() {
4947
5026
  "use strict";
4948
5027
  DEFAULT_APPROVAL_POSITIVE_HINTS = [
4949
- "run",
5028
+ "yes",
5029
+ "allow once",
4950
5030
  "approve",
4951
5031
  "accept",
4952
- "allow once",
4953
- "always allow",
4954
- "allow",
4955
- "yes",
4956
- "proceed",
4957
5032
  "continue",
5033
+ "run",
5034
+ "proceed",
4958
5035
  "confirm",
4959
5036
  "save",
4960
5037
  "ok",
4961
- "trust"
5038
+ "trust",
5039
+ "allow",
5040
+ "always allow"
4962
5041
  ];
4963
5042
  }
4964
5043
  });
@@ -6382,6 +6461,37 @@ var init_reconcile = __esm({
6382
6461
  }
6383
6462
  });
6384
6463
 
6464
+ // ../../oss/packages/daemon-core/src/commands/provider-script-resolver.ts
6465
+ function resolveLegacyProviderScript(fn, scriptName, params) {
6466
+ if (typeof fn !== "function") return null;
6467
+ if (params && typeof params === "object" && !Array.isArray(params) && Object.keys(params).length > 0) {
6468
+ const firstVal = Object.values(params)[0];
6469
+ if (scriptName === "sendMessage" && typeof firstVal === "string") {
6470
+ const legacyScript = fn(firstVal);
6471
+ if (legacyScript) return legacyScript;
6472
+ }
6473
+ const script = fn(params);
6474
+ const likelyLegacyObjectLeak = typeof script === "string" && script.includes("[object Object]") && typeof firstVal === "string";
6475
+ if (!likelyLegacyObjectLeak && script) return script;
6476
+ if (firstVal !== void 0) {
6477
+ const legacyScript = fn(firstVal);
6478
+ if (legacyScript) return legacyScript;
6479
+ }
6480
+ if (script) return script;
6481
+ return null;
6482
+ }
6483
+ if (params !== void 0) {
6484
+ const script = fn(params);
6485
+ if (script) return script;
6486
+ }
6487
+ return fn() || null;
6488
+ }
6489
+ var init_provider_script_resolver = __esm({
6490
+ "../../oss/packages/daemon-core/src/commands/provider-script-resolver.ts"() {
6491
+ "use strict";
6492
+ }
6493
+ });
6494
+
6385
6495
  // ../../oss/packages/daemon-core/src/providers/provider-input-support.ts
6386
6496
  function getProviderLabel(provider) {
6387
6497
  return provider?.name || provider?.type || "This provider";
@@ -6582,7 +6692,7 @@ var init_debug_trace = __esm({
6582
6692
  }
6583
6693
  });
6584
6694
 
6585
- // ../../oss/packages/daemon-core/src/commands/chat-commands.ts
6695
+ // ../../oss/packages/daemon-core/src/chat/chat-signatures.ts
6586
6696
  function hashSignatureParts(parts) {
6587
6697
  let hash2 = 2166136261;
6588
6698
  for (const part of parts) {
@@ -6596,6 +6706,60 @@ function hashSignatureParts(parts) {
6596
6706
  }
6597
6707
  return hash2.toString(16).padStart(8, "0");
6598
6708
  }
6709
+ function stringifySignatureContent(content) {
6710
+ try {
6711
+ return JSON.stringify(content ?? "");
6712
+ } catch {
6713
+ return String(content ?? "");
6714
+ }
6715
+ }
6716
+ function stringifySignatureMessages(messages) {
6717
+ try {
6718
+ return JSON.stringify(messages);
6719
+ } catch {
6720
+ return String(messages.length);
6721
+ }
6722
+ }
6723
+ function buildChatMessageSignature(message) {
6724
+ if (!message) return "";
6725
+ return hashSignatureParts([
6726
+ String(message.id || ""),
6727
+ String(message.index ?? ""),
6728
+ String(message.role || ""),
6729
+ String(message.receivedAt ?? message.timestamp ?? ""),
6730
+ stringifySignatureContent(message.content)
6731
+ ]);
6732
+ }
6733
+ function buildChatTailDeliverySignature(payload) {
6734
+ return hashSignatureParts([
6735
+ payload.sessionId,
6736
+ payload.historySessionId || "",
6737
+ payload.status,
6738
+ payload.title || "",
6739
+ payload.syncMode,
6740
+ String(payload.replaceFrom),
6741
+ String(payload.totalMessages),
6742
+ payload.lastMessageSignature,
6743
+ payload.activeModal ? `${payload.activeModal.message}|${payload.activeModal.buttons.join("")}` : "",
6744
+ stringifySignatureMessages(payload.messages)
6745
+ ]);
6746
+ }
6747
+ function buildSessionModalDeliverySignature(payload) {
6748
+ return hashSignatureParts([
6749
+ payload.sessionId,
6750
+ payload.status,
6751
+ payload.title || "",
6752
+ payload.modalMessage || "",
6753
+ Array.isArray(payload.modalButtons) ? payload.modalButtons.join("") : ""
6754
+ ]);
6755
+ }
6756
+ var init_chat_signatures = __esm({
6757
+ "../../oss/packages/daemon-core/src/chat/chat-signatures.ts"() {
6758
+ "use strict";
6759
+ }
6760
+ });
6761
+
6762
+ // ../../oss/packages/daemon-core/src/commands/chat-commands.ts
6599
6763
  function getCurrentProviderType(h, fallback2 = "") {
6600
6764
  return h.currentSession?.providerType || h.currentProviderType || fallback2;
6601
6765
  }
@@ -6692,20 +6856,7 @@ function parseMaybeJson(value) {
6692
6856
  }
6693
6857
  }
6694
6858
  function getChatMessageSignature(message) {
6695
- if (!message) return "";
6696
- let content = "";
6697
- try {
6698
- content = JSON.stringify(message.content ?? "");
6699
- } catch {
6700
- content = String(message.content ?? "");
6701
- }
6702
- return hashSignatureParts([
6703
- String(message.id || ""),
6704
- String(message.index ?? ""),
6705
- String(message.role || ""),
6706
- String(message.receivedAt ?? message.timestamp ?? ""),
6707
- content
6708
- ]);
6859
+ return buildChatMessageSignature(message);
6709
6860
  }
6710
6861
  function normalizeReadChatCursor(args) {
6711
6862
  const knownMessageCount = Math.max(0, Number(args?.knownMessageCount || 0));
@@ -6717,6 +6868,41 @@ function normalizeReadChatMessages(payload) {
6717
6868
  const messages = Array.isArray(payload.messages) ? payload.messages : [];
6718
6869
  return normalizeChatMessages(messages);
6719
6870
  }
6871
+ function buildReadChatReplayCollapseSignature(message) {
6872
+ if (!message) return "";
6873
+ const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
6874
+ const kind = typeof message.kind === "string" ? message.kind.trim().toLowerCase() : "standard";
6875
+ const senderName = typeof message.senderName === "string" ? message.senderName.trim().toLowerCase() : "";
6876
+ const content = flattenContent(message.content || "").replace(/\s+/g, " ").trim();
6877
+ return `${role}:${kind}:${senderName}:${content}`;
6878
+ }
6879
+ function shouldCollapseReadChatReplayDuplicate(message) {
6880
+ if (!message) return false;
6881
+ const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
6882
+ if (role !== "assistant" && role !== "system") return false;
6883
+ const kind = typeof message.kind === "string" ? message.kind.trim().toLowerCase() : "standard";
6884
+ return kind === "tool" || kind === "terminal" || kind === "thought" || kind === "system";
6885
+ }
6886
+ function collapseReplayDuplicatesFromReadChat(messages) {
6887
+ const collapsed = [];
6888
+ let lastReplayTurnSignature = "";
6889
+ for (const message of messages) {
6890
+ const signature = buildReadChatReplayCollapseSignature(message);
6891
+ const previous = collapsed[collapsed.length - 1];
6892
+ const previousSignature = buildReadChatReplayCollapseSignature(previous);
6893
+ if (shouldCollapseReadChatReplayDuplicate(message) && signature) {
6894
+ if (previousSignature === signature) continue;
6895
+ if (lastReplayTurnSignature === signature) continue;
6896
+ }
6897
+ collapsed.push(message);
6898
+ if (shouldCollapseReadChatReplayDuplicate(message) && signature) {
6899
+ lastReplayTurnSignature = signature;
6900
+ } else if ((message.role || "").toLowerCase() === "user") {
6901
+ lastReplayTurnSignature = "";
6902
+ }
6903
+ }
6904
+ return collapsed;
6905
+ }
6720
6906
  function deriveHistoryDedupKey(message) {
6721
6907
  const unitKey = typeof message._unitKey === "string" ? message._unitKey.trim() : "";
6722
6908
  if (unitKey) return `read_chat:${unitKey}`;
@@ -6792,14 +6978,38 @@ function computeReadChatSync(messages, cursor) {
6792
6978
  lastMessageSignature
6793
6979
  };
6794
6980
  }
6981
+ function hasNonEmptyModalButtons(activeModal) {
6982
+ if (!activeModal || typeof activeModal !== "object") return false;
6983
+ const buttons = activeModal.buttons;
6984
+ return Array.isArray(buttons) && buttons.some((button) => typeof button === "string" && button.trim().length > 0);
6985
+ }
6986
+ function normalizeReadChatCommandStatus(status, activeModal) {
6987
+ const raw = typeof status === "string" ? status.trim() : "";
6988
+ if (!raw) {
6989
+ return hasNonEmptyModalButtons(activeModal) ? "waiting_approval" : "idle";
6990
+ }
6991
+ switch (raw) {
6992
+ case "starting":
6993
+ return hasNonEmptyModalButtons(activeModal) ? "waiting_approval" : "generating";
6994
+ case "stopped":
6995
+ case "disconnected":
6996
+ case "not_monitored":
6997
+ return "error";
6998
+ default:
6999
+ return raw;
7000
+ }
7001
+ }
6795
7002
  function buildReadChatCommandResult(payload, args) {
6796
7003
  let validatedPayload;
6797
7004
  try {
6798
- validatedPayload = validateReadChatResultPayload(payload, "read_chat command result");
7005
+ validatedPayload = validateReadChatResultPayload({
7006
+ ...payload,
7007
+ status: normalizeReadChatCommandStatus(payload?.status, payload?.activeModal)
7008
+ }, "read_chat command result");
6799
7009
  } catch (error48) {
6800
7010
  return { success: false, error: error48?.message || String(error48) };
6801
7011
  }
6802
- const messages = normalizeReadChatMessages(validatedPayload);
7012
+ const messages = collapseReplayDuplicatesFromReadChat(normalizeReadChatMessages(validatedPayload));
6803
7013
  const cursor = normalizeReadChatCursor(args);
6804
7014
  if (!cursor.knownMessageCount && !cursor.lastMessageSignature && cursor.tailLimit > 0 && messages.length > cursor.tailLimit) {
6805
7015
  const tailMessages = messages.slice(-cursor.tailLimit);
@@ -6881,7 +7091,15 @@ async function handleChatHistory(h, args) {
6881
7091
  try {
6882
7092
  const provider = h.getProvider(agentType);
6883
7093
  const agentStr = provider?.type || agentType || getCurrentProviderType(h);
6884
- const result = readChatHistory(agentStr, offset || 0, limit || 30, historySessionId);
7094
+ const transport = getTargetTransport(h, provider);
7095
+ let excludeRecentCount = Math.max(0, Number(args?.excludeRecentCount || 0));
7096
+ if (isCliLikeTransport(transport)) {
7097
+ const adapter = getTargetedCliAdapter(h, args, provider?.type);
7098
+ const status = adapter?.getStatus?.();
7099
+ const visibleCount = Array.isArray(status?.messages) ? status.messages.length : 0;
7100
+ if (visibleCount > excludeRecentCount) excludeRecentCount = visibleCount;
7101
+ }
7102
+ const result = readChatHistory(agentStr, offset || 0, limit || 30, historySessionId, excludeRecentCount);
6885
7103
  return { success: true, ...result, agent: agentStr };
6886
7104
  } catch (e) {
6887
7105
  return { success: false, error: e.message };
@@ -7728,6 +7946,7 @@ var init_chat_commands = __esm({
7728
7946
  init_chat_history();
7729
7947
  init_logger();
7730
7948
  init_debug_trace();
7949
+ init_chat_signatures();
7731
7950
  init_chat_message_normalization();
7732
7951
  RECENT_SEND_WINDOW_MS = 1200;
7733
7952
  recentSendByTarget = /* @__PURE__ */ new Map();
@@ -8168,13 +8387,6 @@ var init_cli_script_results = __esm({
8168
8387
  });
8169
8388
 
8170
8389
  // ../../oss/packages/daemon-core/src/commands/stream-commands.ts
8171
- function getCliPresentationMode(h, targetSessionId) {
8172
- if (!targetSessionId) return null;
8173
- const instance = h.ctx.instanceManager?.getInstance(targetSessionId);
8174
- if (instance?.category !== "cli") return null;
8175
- const mode = instance.getPresentationMode?.();
8176
- return mode === "chat" || mode === "terminal" ? mode : null;
8177
- }
8178
8390
  function normalizeOpenPanelCommandResult(result) {
8179
8391
  const payload = Object.prototype.hasOwnProperty.call(result, "result") ? result.result : result;
8180
8392
  if (payload === true) return { opened: true, visible: true, focused: false };
@@ -8247,9 +8459,6 @@ async function handleOpenPanel(h, args) {
8247
8459
  function handlePtyInput(h, args) {
8248
8460
  const { cliType, data, targetSessionId } = args || {};
8249
8461
  if (!data) return { success: false, error: "data required" };
8250
- if (getCliPresentationMode(h, targetSessionId) === "chat") {
8251
- return { success: false, error: "CLI session is in chat mode", code: "CLI_VIEW_MODE_NOT_TERMINAL" };
8252
- }
8253
8462
  const adapter = h.getCliAdapter(targetSessionId || cliType);
8254
8463
  if (!adapter || typeof adapter.writeRaw !== "function") {
8255
8464
  return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
@@ -8257,24 +8466,10 @@ function handlePtyInput(h, args) {
8257
8466
  adapter.writeRaw(data);
8258
8467
  return { success: true };
8259
8468
  }
8260
- function handlePtyResize(h, args) {
8261
- const { cliType, cols, rows, force, targetSessionId } = args || {};
8469
+ function handlePtyResize(_h, args) {
8470
+ const { cols, rows } = args || {};
8262
8471
  if (!cols || !rows) return { success: false, error: "cols and rows required" };
8263
- if (getCliPresentationMode(h, targetSessionId) === "chat") {
8264
- return { success: false, error: "CLI session is in chat mode", code: "CLI_VIEW_MODE_NOT_TERMINAL" };
8265
- }
8266
- const adapter = h.getCliAdapter(targetSessionId || cliType);
8267
- if (!adapter || typeof adapter.resize !== "function") {
8268
- return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
8269
- }
8270
- const resize = adapter.resize;
8271
- if (force) {
8272
- resize(cols - 1, rows);
8273
- setTimeout(() => resize(cols, rows), 50);
8274
- } else {
8275
- resize(cols, rows);
8276
- }
8277
- return { success: true };
8472
+ return { success: false, error: "PTY resize temporarily disabled", code: "PTY_RESIZE_DISABLED" };
8278
8473
  }
8279
8474
  function handleGetProviderSettings(h, args) {
8280
8475
  const loader = h.ctx.providerLoader;
@@ -8361,15 +8556,45 @@ function normalizeProviderScriptArgs(args, scriptName) {
8361
8556
  }
8362
8557
  function buildControlScriptResult(scriptName, payload) {
8363
8558
  if (!payload || typeof payload !== "object") return {};
8364
- if (Array.isArray(payload.options)) {
8365
- return { controlResult: normalizeControlListResult(payload) };
8559
+ const legacyListPayload = (() => {
8560
+ if (Array.isArray(payload.options)) return payload;
8561
+ if (/^listmodels$/i.test(scriptName) && Array.isArray(payload.models)) {
8562
+ return {
8563
+ options: payload.models,
8564
+ currentValue: payload.currentValue ?? payload.current ?? payload.currentModel,
8565
+ ...typeof payload.error === "string" ? { error: payload.error } : {}
8566
+ };
8567
+ }
8568
+ if (/^listmodes$/i.test(scriptName) && Array.isArray(payload.modes)) {
8569
+ return {
8570
+ options: payload.modes,
8571
+ currentValue: payload.currentValue ?? payload.current ?? payload.currentMode ?? payload.mode,
8572
+ ...typeof payload.error === "string" ? { error: payload.error } : {}
8573
+ };
8574
+ }
8575
+ return null;
8576
+ })();
8577
+ if (legacyListPayload) {
8578
+ return { controlResult: normalizeControlListResult(legacyListPayload) };
8366
8579
  }
8367
- const looksLikeValueMutation = /^set|^change/i.test(scriptName) || payload.currentValue !== void 0 || payload.value !== void 0;
8580
+ const legacyMutationPayload = (() => {
8581
+ if (typeof payload.ok === "boolean") return payload;
8582
+ if (typeof payload.success === "boolean") {
8583
+ return {
8584
+ ok: payload.success,
8585
+ currentValue: payload.currentValue ?? payload.value ?? payload.model ?? payload.mode ?? payload.selectedModel ?? payload.selectedMode,
8586
+ ...Array.isArray(payload.effects) ? { effects: payload.effects } : {},
8587
+ ...typeof payload.error === "string" ? { error: payload.error } : {}
8588
+ };
8589
+ }
8590
+ return null;
8591
+ })();
8592
+ const looksLikeValueMutation = /^set|^change/i.test(scriptName) || payload.currentValue !== void 0 || payload.value !== void 0 || payload.success !== void 0;
8368
8593
  if (looksLikeValueMutation) {
8369
- return { controlResult: normalizeControlSetResult(payload) };
8594
+ return { controlResult: normalizeControlSetResult(legacyMutationPayload || payload) };
8370
8595
  }
8371
8596
  if (payload.ok !== void 0 || Array.isArray(payload.effects) || typeof payload.error === "string") {
8372
- return { controlResult: normalizeControlInvokeResult(payload) };
8597
+ return { controlResult: normalizeControlInvokeResult(legacyMutationPayload || payload) };
8373
8598
  }
8374
8599
  return {};
8375
8600
  }
@@ -8444,7 +8669,7 @@ async function executeProviderScript(h, args, scriptName) {
8444
8669
  }
8445
8670
  const managed = runtimeSessionId ? h.agentStream?.getManagedSession(runtimeSessionId) : null;
8446
8671
  const targetSessionId = managed?.cdpSessionId || null;
8447
- const IDE_LEVEL_SCRIPTS = provider.type === "claude-code-vscode" ? ["listModes", "setMode"] : ["listModes", "setMode", "listModels", "setModel"];
8672
+ const IDE_LEVEL_SCRIPTS = provider.type === "claude-code-vscode" ? ["listModes", "setMode", "listModels", "setModel", "setModelGui"] : ["listModes", "setMode", "listModels", "setModel"];
8448
8673
  if (IDE_LEVEL_SCRIPTS.includes(scriptName)) {
8449
8674
  if (targetSessionId) {
8450
8675
  try {
@@ -8734,6 +8959,7 @@ var init_handler = __esm({
8734
8959
  init_chat_history();
8735
8960
  init_reconcile();
8736
8961
  init_logger();
8962
+ init_provider_script_resolver();
8737
8963
  init_chat_commands();
8738
8964
  init_cdp_commands();
8739
8965
  init_stream_commands();
@@ -8809,27 +9035,7 @@ var init_handler = __esm({
8809
9035
  if (provider?.scripts) {
8810
9036
  const fn = provider.scripts[scriptName];
8811
9037
  if (typeof fn === "function") {
8812
- const callScript = fn;
8813
- if (params && Object.keys(params).length > 0) {
8814
- const firstVal = Object.values(params)[0];
8815
- if (scriptName === "sendMessage" && typeof firstVal === "string") {
8816
- const legacyScript = callScript(firstVal);
8817
- if (legacyScript) return legacyScript;
8818
- }
8819
- const script = callScript(params);
8820
- if (script) {
8821
- const likelyLegacyObjectLeak = typeof script === "string" && script.includes("[object Object]") && typeof firstVal === "string";
8822
- if (!likelyLegacyObjectLeak) return script;
8823
- }
8824
- if (firstVal !== void 0) {
8825
- const legacyScript = callScript(firstVal);
8826
- if (legacyScript) return legacyScript;
8827
- }
8828
- if (script) return script;
8829
- } else {
8830
- const script = callScript();
8831
- if (script) return script;
8832
- }
9038
+ return resolveLegacyProviderScript(fn, scriptName, params);
8833
9039
  }
8834
9040
  }
8835
9041
  return null;
@@ -12395,6 +12601,8 @@ ${data.message || ""}`.trim();
12395
12601
  }
12396
12602
  async sendMessage(text) {
12397
12603
  if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
12604
+ const allowInputDuringGeneration = this.provider.allowInputDuringGeneration === true;
12605
+ const allowInterventionPrompt = allowInputDuringGeneration && this.isWaitingForResponse && this.currentStatus !== "waiting_approval";
12398
12606
  if (this.startupParseGate) {
12399
12607
  const deadline = Date.now() + 1e4;
12400
12608
  while (this.startupParseGate && Date.now() < deadline) {
@@ -12402,7 +12610,9 @@ ${data.message || ""}`.trim();
12402
12610
  await new Promise((resolve17) => setTimeout(resolve17, 50));
12403
12611
  }
12404
12612
  }
12405
- await this.waitForInteractivePrompt();
12613
+ if (!allowInterventionPrompt) {
12614
+ await this.waitForInteractivePrompt();
12615
+ }
12406
12616
  if (!this.ready) {
12407
12617
  this.resolveStartupState("send_precheck");
12408
12618
  const screenText = this.terminalScreen.getText() || "";
@@ -12414,7 +12624,7 @@ ${data.message || ""}`.trim();
12414
12624
  }
12415
12625
  }
12416
12626
  if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
12417
- if (this.isWaitingForResponse) {
12627
+ if (this.isWaitingForResponse && !allowInputDuringGeneration) {
12418
12628
  throw new Error(`${this.cliName} is still processing the previous prompt`);
12419
12629
  }
12420
12630
  const blockingModal = this.activeModal || this.getStartupConfirmationModal(this.terminalScreen.getText() || "");
@@ -12995,6 +13205,7 @@ var init_cli_provider_instance = __esm({
12995
13205
  init_approval_utils();
12996
13206
  init_cli_script_results();
12997
13207
  init_provider_patch_state();
13208
+ init_provider_session_id();
12998
13209
  init_chat_message_normalization();
12999
13210
  CachedDatabaseSync = null;
13000
13211
  CliProviderInstance = class {
@@ -13157,7 +13368,10 @@ var init_cli_provider_instance = __esm({
13157
13368
  const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
13158
13369
  const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
13159
13370
  const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
13160
- const parsedProviderSessionId = typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId.trim() : "";
13371
+ const parsedProviderSessionId = normalizeProviderSessionId(
13372
+ this.type,
13373
+ typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId : ""
13374
+ );
13161
13375
  if (parsedProviderSessionId) {
13162
13376
  this.promoteProviderSessionId(parsedProviderSessionId);
13163
13377
  }
@@ -13421,7 +13635,10 @@ var init_cli_provider_instance = __esm({
13421
13635
  }
13422
13636
  applyProviderResponse(data, options) {
13423
13637
  if (!data || typeof data !== "object") return;
13424
- const patchedProviderSessionId = typeof data.providerSessionId === "string" ? data.providerSessionId.trim() : "";
13638
+ const patchedProviderSessionId = normalizeProviderSessionId(
13639
+ this.type,
13640
+ typeof data.providerSessionId === "string" ? data.providerSessionId : ""
13641
+ );
13425
13642
  if (patchedProviderSessionId) {
13426
13643
  this.promoteProviderSessionId(patchedProviderSessionId);
13427
13644
  }
@@ -37165,6 +37382,147 @@ var init_ipc_protocol = __esm({
37165
37382
  }
37166
37383
  });
37167
37384
 
37385
+ // ../../oss/packages/daemon-core/src/chat/subscription-updates.ts
37386
+ function normalizeSyncMode(syncMode) {
37387
+ return syncMode === "append" || syncMode === "replace_tail" || syncMode === "noop" || syncMode === "full" ? syncMode : "full";
37388
+ }
37389
+ function normalizeModalButtons(value) {
37390
+ return Array.isArray(value) ? value.filter((button) => typeof button === "string") : [];
37391
+ }
37392
+ function normalizeModalMessage(value) {
37393
+ return typeof value === "string" ? value : void 0;
37394
+ }
37395
+ function normalizeChatTailActiveModal(activeModal) {
37396
+ if (!activeModal || typeof activeModal !== "object") return null;
37397
+ const message = normalizeModalMessage(activeModal.message);
37398
+ if (!message) return null;
37399
+ const rawButtons = activeModal.buttons;
37400
+ if (!Array.isArray(rawButtons)) return null;
37401
+ return {
37402
+ message,
37403
+ buttons: normalizeModalButtons(rawButtons)
37404
+ };
37405
+ }
37406
+ function normalizeSessionModalFields(activeModal) {
37407
+ if (!activeModal || typeof activeModal !== "object") {
37408
+ return { modalButtons: [] };
37409
+ }
37410
+ return {
37411
+ modalMessage: normalizeModalMessage(activeModal.message),
37412
+ modalButtons: normalizeModalButtons(activeModal.buttons)
37413
+ };
37414
+ }
37415
+ function buildNextChatCursor(cursor, result) {
37416
+ return {
37417
+ knownMessageCount: Math.max(0, Number(result.totalMessages || cursor.knownMessageCount)),
37418
+ lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : cursor.lastMessageSignature,
37419
+ tailLimit: cursor.tailLimit
37420
+ };
37421
+ }
37422
+ function prepareSessionChatTailUpdate(input) {
37423
+ const result = input.result;
37424
+ if (!result?.success || result.syncMode === "noop") {
37425
+ return {
37426
+ cursor: result?.success ? buildNextChatCursor(input.cursor, result) : input.cursor,
37427
+ seq: input.seq,
37428
+ lastDeliveredSignature: input.lastDeliveredSignature,
37429
+ update: null
37430
+ };
37431
+ }
37432
+ const syncMode = normalizeSyncMode(result.syncMode);
37433
+ const cursor = {
37434
+ knownMessageCount: Math.max(0, Number(result.totalMessages || 0)),
37435
+ lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : "",
37436
+ tailLimit: input.cursor.tailLimit
37437
+ };
37438
+ const title = typeof result.title === "string" ? result.title : void 0;
37439
+ const activeModal = normalizeChatTailActiveModal(result.activeModal);
37440
+ const status = typeof result.status === "string" ? result.status : "idle";
37441
+ const deliverySignature = buildChatTailDeliverySignature({
37442
+ sessionId: input.sessionId,
37443
+ ...input.historySessionId ? { historySessionId: input.historySessionId } : {},
37444
+ messages: Array.isArray(result.messages) ? result.messages : [],
37445
+ status,
37446
+ ...title ? { title } : {},
37447
+ ...activeModal ? { activeModal } : {},
37448
+ syncMode,
37449
+ replaceFrom: Number(result.replaceFrom || 0),
37450
+ totalMessages: Number(result.totalMessages || 0),
37451
+ lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
37452
+ });
37453
+ const seq = input.seq + 1;
37454
+ if (deliverySignature === input.lastDeliveredSignature) {
37455
+ return {
37456
+ cursor,
37457
+ seq,
37458
+ lastDeliveredSignature: input.lastDeliveredSignature,
37459
+ update: null
37460
+ };
37461
+ }
37462
+ return {
37463
+ cursor,
37464
+ seq,
37465
+ lastDeliveredSignature: deliverySignature,
37466
+ update: {
37467
+ topic: "session.chat_tail",
37468
+ key: input.key,
37469
+ sessionId: input.sessionId,
37470
+ ...input.historySessionId ? { historySessionId: input.historySessionId } : {},
37471
+ ...input.interactionId ? { interactionId: input.interactionId } : {},
37472
+ seq,
37473
+ timestamp: input.timestamp,
37474
+ messages: Array.isArray(result.messages) ? result.messages : [],
37475
+ status,
37476
+ ...title ? { title } : {},
37477
+ ...activeModal ? { activeModal } : {},
37478
+ syncMode,
37479
+ replaceFrom: Number(result.replaceFrom || 0),
37480
+ totalMessages: Number(result.totalMessages || 0),
37481
+ lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
37482
+ }
37483
+ };
37484
+ }
37485
+ function prepareSessionModalUpdate(input) {
37486
+ const { modalMessage, modalButtons } = normalizeSessionModalFields(input.activeModal);
37487
+ const deliverySignature = buildSessionModalDeliverySignature({
37488
+ sessionId: input.sessionId,
37489
+ status: input.status,
37490
+ ...input.title ? { title: input.title } : {},
37491
+ ...modalMessage ? { modalMessage } : {},
37492
+ ...modalButtons.length > 0 ? { modalButtons } : {}
37493
+ });
37494
+ if (deliverySignature === input.lastDeliveredSignature) {
37495
+ return {
37496
+ seq: input.seq,
37497
+ lastDeliveredSignature: input.lastDeliveredSignature,
37498
+ update: null
37499
+ };
37500
+ }
37501
+ const seq = input.seq + 1;
37502
+ return {
37503
+ seq,
37504
+ lastDeliveredSignature: deliverySignature,
37505
+ update: {
37506
+ topic: "session.modal",
37507
+ key: input.key,
37508
+ sessionId: input.sessionId,
37509
+ status: input.status,
37510
+ ...input.title ? { title: input.title } : {},
37511
+ ...modalMessage ? { modalMessage } : {},
37512
+ ...modalButtons.length > 0 ? { modalButtons } : {},
37513
+ ...input.interactionId ? { interactionId: input.interactionId } : {},
37514
+ seq,
37515
+ timestamp: input.timestamp
37516
+ }
37517
+ };
37518
+ }
37519
+ var init_subscription_updates = __esm({
37520
+ "../../oss/packages/daemon-core/src/chat/subscription-updates.ts"() {
37521
+ "use strict";
37522
+ init_chat_signatures();
37523
+ }
37524
+ });
37525
+
37168
37526
  // ../../oss/packages/daemon-core/src/agent-stream/provider-adapter.ts
37169
37527
  var ProviderStreamAdapter;
37170
37528
  var init_provider_adapter = __esm({
@@ -42184,6 +42542,7 @@ var init_dev_server = __esm({
42184
42542
  init_logger();
42185
42543
  init_builders();
42186
42544
  init_dev_cdp_handlers();
42545
+ init_provider_script_resolver();
42187
42546
  init_dev_cli_debug();
42188
42547
  init_dev_auto_implement();
42189
42548
  DEV_SERVER_PORT = 19280;
@@ -42447,7 +42806,8 @@ var init_dev_server = __esm({
42447
42806
  }
42448
42807
  async handleRunScript(type, req, res, parsedBody) {
42449
42808
  const body = parsedBody || await this.readBody(req);
42450
- const { script: scriptName, params, ideType: scriptIdeType } = body;
42809
+ const { script: scriptName, params, args, ideType: scriptIdeType } = body;
42810
+ const rawParams = args !== void 0 ? args : params;
42451
42811
  const provider = this.providerLoader.resolve(type);
42452
42812
  if (!provider) {
42453
42813
  this.json(res, 404, { error: `Provider '${type}' not found` });
@@ -42464,13 +42824,7 @@ var init_dev_server = __esm({
42464
42824
  return;
42465
42825
  }
42466
42826
  try {
42467
- let scriptCode = null;
42468
- if (["sendMessage", "webviewSendMessage", "switchSession", "webviewSwitchSession", "setMode", "webviewSetMode", "setModel", "webviewSetModel"].includes(scriptName)) {
42469
- const firstVal = params && typeof params === "object" && Object.keys(params).length > 0 ? Object.values(params)[0] : params;
42470
- scriptCode = firstVal !== void 0 ? fn(firstVal) : fn();
42471
- } else {
42472
- scriptCode = params !== void 0 ? fn(params) : fn();
42473
- }
42827
+ const scriptCode = resolveLegacyProviderScript(fn, scriptName, rawParams);
42474
42828
  if (!scriptCode) {
42475
42829
  this.json(res, 500, { error: "Script function returned null" });
42476
42830
  return;
@@ -42487,6 +42841,17 @@ var init_dev_server = __esm({
42487
42841
  break;
42488
42842
  }
42489
42843
  }
42844
+ if (!sessionId) {
42845
+ try {
42846
+ const discovered = await cdp.discoverAgentWebviews();
42847
+ const target = discovered.find((entry) => entry.agentType === type);
42848
+ if (target) {
42849
+ sessionId = await cdp.attachToAgent(target);
42850
+ }
42851
+ } catch (error48) {
42852
+ this.log(`Extension attach fallback failed for ${type}: ${error48?.message || String(error48)}`);
42853
+ }
42854
+ }
42490
42855
  if (sessionId) {
42491
42856
  raw = await cdp.evaluateInSessionFrame(sessionId, scriptCode);
42492
42857
  } else if (cdp.evaluateInWebviewFrame) {
@@ -42551,6 +42916,20 @@ var init_dev_server = __esm({
42551
42916
  async handleReload(_req, res) {
42552
42917
  try {
42553
42918
  this.providerLoader.reload();
42919
+ let refreshedInstances = 0;
42920
+ if (this.instanceManager) {
42921
+ for (const id of this.instanceManager.listInstanceIds()) {
42922
+ const instance = this.instanceManager.getInstance(id);
42923
+ const providerType = typeof instance?.type === "string" ? instance.type : "";
42924
+ if (!providerType) continue;
42925
+ const resolved = this.providerLoader.resolve(providerType);
42926
+ if (!resolved) continue;
42927
+ if (instance && typeof instance === "object" && "provider" in instance) {
42928
+ instance.provider = resolved;
42929
+ refreshedInstances += 1;
42930
+ }
42931
+ }
42932
+ }
42554
42933
  const providers = this.providerLoader.getAll().map((p) => ({
42555
42934
  type: p.type,
42556
42935
  name: p.name,
@@ -42561,7 +42940,7 @@ var init_dev_server = __esm({
42561
42940
  cdp.clearTargetId();
42562
42941
  }
42563
42942
  }
42564
- this.json(res, 200, { reloaded: true, providers });
42943
+ this.json(res, 200, { reloaded: true, refreshedInstances, providers });
42565
42944
  } catch (e) {
42566
42945
  this.json(res, 500, { error: e.message });
42567
42946
  }
@@ -44057,10 +44436,19 @@ var init_session_host_transport = __esm({
44057
44436
  });
44058
44437
 
44059
44438
  // ../../oss/packages/daemon-core/src/session-host/app-name.ts
44439
+ function validateStandaloneSessionHostAppName(explicit) {
44440
+ if (explicit !== DEFAULT_SESSION_HOST_APP_NAME) return;
44441
+ throw new Error(
44442
+ `Standalone session-host namespace '${DEFAULT_SESSION_HOST_APP_NAME}' is reserved for the global daemon. Use '${DEFAULT_STANDALONE_SESSION_HOST_APP_NAME}' or another non-default namespace.`
44443
+ );
44444
+ }
44060
44445
  function resolveSessionHostAppName(options = {}) {
44061
44446
  const env3 = options.env || process.env;
44062
44447
  const explicit = typeof env3.ADHDEV_SESSION_HOST_NAME === "string" ? env3.ADHDEV_SESSION_HOST_NAME.trim() : "";
44063
- if (explicit) return explicit;
44448
+ if (explicit) {
44449
+ if (options.standalone) validateStandaloneSessionHostAppName(explicit);
44450
+ return explicit;
44451
+ }
44064
44452
  return options.standalone ? DEFAULT_STANDALONE_SESSION_HOST_APP_NAME : DEFAULT_SESSION_HOST_APP_NAME;
44065
44453
  }
44066
44454
  var DEFAULT_SESSION_HOST_APP_NAME, DEFAULT_STANDALONE_SESSION_HOST_APP_NAME;
@@ -44687,9 +45075,12 @@ __export(src_exports, {
44687
45075
  appendRecentActivity: () => appendRecentActivity,
44688
45076
  buildAssistantChatMessage: () => buildAssistantChatMessage,
44689
45077
  buildChatMessage: () => buildChatMessage,
45078
+ buildChatMessageSignature: () => buildChatMessageSignature,
45079
+ buildChatTailDeliverySignature: () => buildChatTailDeliverySignature,
44690
45080
  buildMachineInfo: () => buildMachineInfo,
44691
45081
  buildRuntimeSystemChatMessage: () => buildRuntimeSystemChatMessage,
44692
45082
  buildSessionEntries: () => buildSessionEntries,
45083
+ buildSessionModalDeliverySignature: () => buildSessionModalDeliverySignature,
44693
45084
  buildStatusSnapshot: () => buildStatusSnapshot,
44694
45085
  buildSystemChatMessage: () => buildSystemChatMessage,
44695
45086
  buildTerminalChatMessage: () => buildTerminalChatMessage,
@@ -44725,6 +45116,7 @@ __export(src_exports, {
44725
45116
  getSessionHostSurfaceKind: () => getSessionHostSurfaceKind2,
44726
45117
  getWorkspaceState: () => getWorkspaceState,
44727
45118
  hasCdpManager: () => hasCdpManager,
45119
+ hashSignatureParts: () => hashSignatureParts,
44728
45120
  initDaemonComponents: () => initDaemonComponents,
44729
45121
  installExtensions: () => installExtensions,
44730
45122
  installGlobalInterceptor: () => installGlobalInterceptor,
@@ -44750,12 +45142,16 @@ __export(src_exports, {
44750
45142
  normalizeChatMessage: () => normalizeChatMessage,
44751
45143
  normalizeChatMessageKind: () => normalizeChatMessageKind,
44752
45144
  normalizeChatMessages: () => normalizeChatMessages,
45145
+ normalizeChatTailActiveModal: () => normalizeChatTailActiveModal,
44753
45146
  normalizeInputEnvelope: () => normalizeInputEnvelope,
44754
45147
  normalizeManagedStatus: () => normalizeManagedStatus,
44755
45148
  normalizeMessageParts: () => normalizeMessageParts,
45149
+ normalizeSessionModalFields: () => normalizeSessionModalFields,
44756
45150
  parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
44757
45151
  partitionSessionHostDiagnosticsSessions: () => partitionSessionHostDiagnosticsSessions,
44758
45152
  partitionSessionHostRecords: () => partitionSessionHostRecords,
45153
+ prepareSessionChatTailUpdate: () => prepareSessionChatTailUpdate,
45154
+ prepareSessionModalUpdate: () => prepareSessionModalUpdate,
44759
45155
  probeCdpPort: () => probeCdpPort,
44760
45156
  readChatHistory: () => readChatHistory,
44761
45157
  recordDebugTrace: () => recordDebugTrace,
@@ -44811,6 +45207,8 @@ var init_src = __esm({
44811
45207
  init_launch();
44812
45208
  init_ipc_protocol();
44813
45209
  init_chat_history();
45210
+ init_chat_signatures();
45211
+ init_subscription_updates();
44814
45212
  init_agent_stream();
44815
45213
  init_agent_stream();
44816
45214
  init_forward();
@@ -76516,15 +76914,7 @@ function routeDataChannelMessage(peerId, msg, peers, handlers) {
76516
76914
  return;
76517
76915
  }
76518
76916
  if (parsed.type === "pty_resize") {
76519
- const permission = peers.get(peerId)?.sharePermission;
76520
- if (permission) {
76521
- log(`pty_resize: REJECTED \u2014 permission=${permission} peer=${peerId}`);
76522
- return;
76523
- }
76524
- const sessionId = parsed.sessionId || parsed.targetSessionId || parsed.cliId || parsed.cliType || "";
76525
- if (handlers.ptyResizeHandler && parsed.cols && parsed.rows && sessionId) {
76526
- handlers.ptyResizeHandler(sessionId, parsed.cols, parsed.rows);
76527
- }
76917
+ logDebug(`pty_resize ignored: peer=${peerId} reason=temporarily_disabled`);
76528
76918
  return;
76529
76919
  }
76530
76920
  handleFileRequest(peerId, parsed, peers, handlers);
@@ -84745,48 +85135,6 @@ __export(adhdev_daemon_exports, {
84745
85135
  isDaemonRunning: () => isDaemonRunning,
84746
85136
  stopDaemon: () => stopDaemon
84747
85137
  });
84748
- function hashSignatureParts2(parts) {
84749
- let hash2 = 2166136261;
84750
- for (const part of parts) {
84751
- const text = String(part || "");
84752
- for (let i = 0; i < text.length; i += 1) {
84753
- hash2 ^= text.charCodeAt(i);
84754
- hash2 = Math.imul(hash2, 16777619) >>> 0;
84755
- }
84756
- hash2 ^= 255;
84757
- hash2 = Math.imul(hash2, 16777619) >>> 0;
84758
- }
84759
- return hash2.toString(16).padStart(8, "0");
84760
- }
84761
- function buildChatTailDeliverySignature(payload) {
84762
- let messages = "";
84763
- try {
84764
- messages = JSON.stringify(payload.messages);
84765
- } catch {
84766
- messages = String(payload.messages.length);
84767
- }
84768
- return hashSignatureParts2([
84769
- payload.sessionId,
84770
- payload.historySessionId || "",
84771
- payload.status,
84772
- payload.title || "",
84773
- payload.syncMode,
84774
- String(payload.replaceFrom),
84775
- String(payload.totalMessages),
84776
- payload.lastMessageSignature,
84777
- payload.activeModal ? `${payload.activeModal.message}|${payload.activeModal.buttons.join("")}` : "",
84778
- messages
84779
- ]);
84780
- }
84781
- function buildSessionModalDeliverySignature(payload) {
84782
- return hashSignatureParts2([
84783
- payload.sessionId,
84784
- payload.status,
84785
- payload.title || "",
84786
- payload.modalMessage || "",
84787
- Array.isArray(payload.modalButtons) ? payload.modalButtons.join("") : ""
84788
- ]);
84789
- }
84790
85138
  function resolveDaemonPort(ref = {}) {
84791
85139
  return Number.isFinite(ref.port) && Number(ref.port) > 0 ? Number(ref.port) : DEFAULT_DAEMON_PORT;
84792
85140
  }
@@ -84919,7 +85267,7 @@ var init_adhdev_daemon = __esm({
84919
85267
  init_source();
84920
85268
  init_version();
84921
85269
  init_src();
84922
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.71" });
85270
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.74" });
84923
85271
  AdhdevDaemon = class _AdhdevDaemon {
84924
85272
  localHttpServer = null;
84925
85273
  localWss = null;
@@ -84990,9 +85338,6 @@ var init_adhdev_daemon = __esm({
84990
85338
  const mode = instance.getPresentationMode?.();
84991
85339
  return mode === "chat" || mode === "terminal" ? mode : null;
84992
85340
  }
84993
- isTerminalCliSession(sessionId) {
84994
- return this.getCliPresentationMode(sessionId) === "terminal";
84995
- }
84996
85341
  isCliSession(sessionId) {
84997
85342
  const mode = this.getCliPresentationMode(sessionId);
84998
85343
  return mode === "chat" || mode === "terminal";
@@ -85060,44 +85405,24 @@ var init_adhdev_daemon = __esm({
85060
85405
  lastMessageSignature: subscription.cursor.lastMessageSignature,
85061
85406
  ...subscription.cursor.tailLimit > 0 ? { tailLimit: subscription.cursor.tailLimit } : {}
85062
85407
  }, "p2p");
85063
- if (!result?.success || result.syncMode === "noop") {
85064
- if (result?.success) {
85065
- subscription.cursor = {
85066
- knownMessageCount: Math.max(0, Number(result.totalMessages || subscription.cursor.knownMessageCount)),
85067
- lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : subscription.cursor.lastMessageSignature,
85068
- tailLimit: subscription.cursor.tailLimit
85069
- };
85070
- }
85071
- return null;
85072
- }
85073
- subscription.seq += 1;
85074
- const syncMode = result.syncMode === "append" || result.syncMode === "replace_tail" || result.syncMode === "noop" || result.syncMode === "full" ? result.syncMode : "full";
85075
- subscription.cursor = {
85076
- knownMessageCount: Math.max(0, Number(result.totalMessages || 0)),
85077
- lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : "",
85078
- tailLimit: subscription.cursor.tailLimit
85079
- };
85080
- const activeModal = result.activeModal && typeof result.activeModal === "object" && typeof result.activeModal.message === "string" && Array.isArray(result.activeModal.buttons) ? {
85081
- message: result.activeModal.message,
85082
- buttons: result.activeModal.buttons.filter((button) => typeof button === "string")
85083
- } : null;
85084
- const deliverySignature = buildChatTailDeliverySignature({
85408
+ const interactionId = this.getSessionInteractionId(subscription.params.targetSessionId);
85409
+ const prepared = prepareSessionChatTailUpdate({
85410
+ key: subscription.key,
85085
85411
  sessionId: subscription.params.targetSessionId,
85086
85412
  ...subscription.params.historySessionId ? { historySessionId: subscription.params.historySessionId } : {},
85087
- messages: Array.isArray(result.messages) ? result.messages : [],
85088
- status: typeof result.status === "string" ? result.status : "idle",
85089
- ...typeof result.title === "string" ? { title: result.title } : {},
85090
- ...activeModal ? { activeModal } : {},
85091
- syncMode,
85092
- replaceFrom: Number(result.replaceFrom || 0),
85093
- totalMessages: Number(result.totalMessages || 0),
85094
- lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
85413
+ seq: subscription.seq,
85414
+ timestamp: Date.now(),
85415
+ ...interactionId ? { interactionId } : {},
85416
+ cursor: subscription.cursor,
85417
+ lastDeliveredSignature: subscription.lastDeliveredSignature,
85418
+ result
85095
85419
  });
85096
- if (deliverySignature === subscription.lastDeliveredSignature) {
85420
+ subscription.cursor = prepared.cursor;
85421
+ subscription.seq = prepared.seq;
85422
+ subscription.lastDeliveredSignature = prepared.lastDeliveredSignature;
85423
+ if (!prepared.update) {
85097
85424
  return null;
85098
85425
  }
85099
- subscription.lastDeliveredSignature = deliverySignature;
85100
- const interactionId = this.getSessionInteractionId(subscription.params.targetSessionId);
85101
85426
  recordDebugTrace({
85102
85427
  interactionId,
85103
85428
  category: "topic",
@@ -85105,30 +85430,14 @@ var init_adhdev_daemon = __esm({
85105
85430
  level: "info",
85106
85431
  sessionId: subscription.params.targetSessionId,
85107
85432
  payload: {
85108
- syncMode,
85109
- totalMessages: Number(result.totalMessages || 0),
85110
- replaceFrom: Number(result.replaceFrom || 0),
85111
- hasModal: !!activeModal,
85112
- hasTitle: typeof result.title === "string"
85433
+ syncMode: prepared.update.syncMode,
85434
+ totalMessages: prepared.update.totalMessages,
85435
+ replaceFrom: prepared.update.replaceFrom,
85436
+ hasModal: !!prepared.update.activeModal,
85437
+ hasTitle: typeof prepared.update.title === "string"
85113
85438
  }
85114
85439
  });
85115
- return {
85116
- topic: "session.chat_tail",
85117
- key: subscription.key,
85118
- sessionId: subscription.params.targetSessionId,
85119
- ...subscription.params.historySessionId ? { historySessionId: subscription.params.historySessionId } : {},
85120
- ...interactionId ? { interactionId } : {},
85121
- seq: subscription.seq,
85122
- timestamp: Date.now(),
85123
- messages: Array.isArray(result.messages) ? result.messages : [],
85124
- status: typeof result.status === "string" ? result.status : "idle",
85125
- ...typeof result.title === "string" ? { title: result.title } : {},
85126
- ...activeModal ? { activeModal } : {},
85127
- syncMode,
85128
- replaceFrom: Number(result.replaceFrom || 0),
85129
- totalMessages: Number(result.totalMessages || 0),
85130
- lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
85131
- };
85440
+ return prepared.update;
85132
85441
  }
85133
85442
  buildLiveStatusSnapshot() {
85134
85443
  return buildStatusSnapshot({
@@ -85244,24 +85553,26 @@ var init_adhdev_daemon = __esm({
85244
85553
  if (!state) return null;
85245
85554
  const now = Date.now();
85246
85555
  const activeModal = state.activeChat?.activeModal;
85247
- const modalButtons = Array.isArray(activeModal?.buttons) ? activeModal.buttons.filter((button) => typeof button === "string") : [];
85248
85556
  const status = String(state.activeChat?.status || state.status || "idle");
85249
85557
  const title = typeof state.activeChat?.title === "string" ? state.activeChat.title : void 0;
85250
- const modalMessage = typeof activeModal?.message === "string" ? activeModal.message : void 0;
85251
- const deliverySignature = buildSessionModalDeliverySignature({
85558
+ const interactionId = this.getSessionInteractionId(subscription.params.targetSessionId);
85559
+ const prepared = prepareSessionModalUpdate({
85560
+ key: subscription.key,
85252
85561
  sessionId: subscription.params.targetSessionId,
85253
85562
  status,
85254
- ...title ? { title } : {},
85255
- ...modalMessage ? { modalMessage } : {},
85256
- ...modalButtons.length > 0 ? { modalButtons } : {}
85563
+ title,
85564
+ activeModal,
85565
+ seq: subscription.seq,
85566
+ timestamp: now,
85567
+ ...interactionId ? { interactionId } : {},
85568
+ lastDeliveredSignature: subscription.lastDeliveredSignature
85257
85569
  });
85258
- if (deliverySignature === subscription.lastDeliveredSignature) {
85570
+ subscription.seq = prepared.seq;
85571
+ subscription.lastDeliveredSignature = prepared.lastDeliveredSignature;
85572
+ if (!prepared.update) {
85259
85573
  return null;
85260
85574
  }
85261
- subscription.lastDeliveredSignature = deliverySignature;
85262
- subscription.seq += 1;
85263
85575
  subscription.lastSentAt = now;
85264
- const interactionId = this.getSessionInteractionId(subscription.params.targetSessionId);
85265
85576
  recordDebugTrace({
85266
85577
  interactionId,
85267
85578
  category: "topic",
@@ -85270,23 +85581,12 @@ var init_adhdev_daemon = __esm({
85270
85581
  sessionId: subscription.params.targetSessionId,
85271
85582
  payload: {
85272
85583
  status,
85273
- hasTitle: !!title,
85274
- modalMessage: modalMessage ? modalMessage.slice(0, 140) : void 0,
85275
- modalButtonCount: modalButtons.length
85584
+ hasTitle: !!prepared.update.title,
85585
+ modalMessage: prepared.update.modalMessage ? prepared.update.modalMessage.slice(0, 140) : void 0,
85586
+ modalButtonCount: prepared.update.modalButtons?.length || 0
85276
85587
  }
85277
85588
  });
85278
- return {
85279
- topic: "session.modal",
85280
- key: subscription.key,
85281
- sessionId: subscription.params.targetSessionId,
85282
- status,
85283
- ...title ? { title } : {},
85284
- ...modalMessage ? { modalMessage } : {},
85285
- ...modalButtons.length > 0 ? { modalButtons } : {},
85286
- ...interactionId ? { interactionId } : {},
85287
- seq: subscription.seq,
85288
- timestamp: now
85289
- };
85589
+ return prepared.update;
85290
85590
  }
85291
85591
  async flushP2PSessionModalSubscriptions() {
85292
85592
  if (!this.p2p?.isConnected || !this.p2p.hasSessionModalSubscriptions()) return;
@@ -85475,14 +85775,14 @@ ${err?.stack || ""}`);
85475
85775
  }
85476
85776
  });
85477
85777
  this.p2p.onPtyInput((sessionId, data) => {
85478
- if (!this.isTerminalCliSession(sessionId)) return;
85778
+ if (!this.isCliSession(sessionId)) return;
85479
85779
  const found = this.components.cliManager.findAdapter(sessionId, { instanceKey: sessionId });
85480
85780
  if (found && typeof found.adapter.writeRaw === "function") {
85481
85781
  found.adapter.writeRaw(data);
85482
85782
  }
85483
85783
  });
85484
85784
  this.p2p.onPtyResize((sessionId, cols, rows) => {
85485
- if (!this.isTerminalCliSession(sessionId)) return;
85785
+ if (!this.isCliSession(sessionId)) return;
85486
85786
  const found = this.components.cliManager.findAdapter(sessionId, { instanceKey: sessionId });
85487
85787
  if (found && typeof found.adapter.resize === "function") {
85488
85788
  found.adapter.resize(cols, rows);
@@ -88703,7 +89003,16 @@ function registerDaemonCommands(program2, pkgVersion3) {
88703
89003
  if (options.open === false) args.push("--no-open");
88704
89004
  if (options.token) args.push("--token", options.token);
88705
89005
  if (options.dev) args.push("--dev");
88706
- const sessionHostName = resolveSessionHostAppName2({ standalone: true, env: process.env });
89006
+ let sessionHostName;
89007
+ try {
89008
+ sessionHostName = resolveSessionHostAppName2({ standalone: true, env: process.env });
89009
+ } catch (error48) {
89010
+ console.error(source_default.red(`
89011
+ \u2717 ${error48 instanceof Error ? error48.message : String(error48)}
89012
+ `));
89013
+ process.exitCode = 1;
89014
+ return;
89015
+ }
88707
89016
  const standaloneEnv = {
88708
89017
  ...process.env,
88709
89018
  ADHDEV_SESSION_HOST_NAME: process.env.ADHDEV_SESSION_HOST_NAME || sessionHostName