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/index.js CHANGED
@@ -633,6 +633,31 @@ var init_saved_sessions = __esm({
633
633
  }
634
634
  });
635
635
 
636
+ // ../../oss/packages/daemon-core/src/providers/provider-session-id.ts
637
+ function normalizeProviderSessionId(providerType, providerSessionId) {
638
+ const normalizedProviderType = typeof providerType === "string" ? providerType.trim() : "";
639
+ const normalizedId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
640
+ if (!normalizedId) return "";
641
+ const lowered = normalizedId.toLowerCase();
642
+ if (lowered === "undefined" || lowered === "null") return "";
643
+ if (normalizedProviderType === "hermes-cli" && !HERMES_SESSION_ID_RE.test(normalizedId)) {
644
+ return "";
645
+ }
646
+ return normalizedId;
647
+ }
648
+ function isLegacyVolatileSessionReadKey(key) {
649
+ const normalizedKey = typeof key === "string" ? key.trim() : "";
650
+ if (!normalizedKey) return false;
651
+ return normalizedKey.startsWith("provider:codex:vscode-webview://");
652
+ }
653
+ var HERMES_SESSION_ID_RE;
654
+ var init_provider_session_id = __esm({
655
+ "../../oss/packages/daemon-core/src/providers/provider-session-id.ts"() {
656
+ "use strict";
657
+ HERMES_SESSION_ID_RE = /^\d{8}_\d{6}_[a-z0-9]+$/i;
658
+ }
659
+ });
660
+
636
661
  // ../../oss/packages/daemon-core/src/config/state-store.ts
637
662
  function isPlainObject2(value) {
638
663
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -642,15 +667,31 @@ function getStatePath() {
642
667
  }
643
668
  function normalizeState(raw) {
644
669
  const parsed = isPlainObject2(raw) ? raw : {};
670
+ const recentActivity = (Array.isArray(parsed.recentActivity) ? parsed.recentActivity : []).filter((entry) => {
671
+ if (!isPlainObject2(entry)) return false;
672
+ const normalizedId = normalizeProviderSessionId(
673
+ typeof entry.providerType === "string" ? entry.providerType : "",
674
+ typeof entry.providerSessionId === "string" ? entry.providerSessionId : ""
675
+ );
676
+ if (typeof entry.providerSessionId === "string" && !normalizedId) return false;
677
+ return true;
678
+ });
679
+ const savedProviderSessions = (Array.isArray(parsed.savedProviderSessions) ? parsed.savedProviderSessions : []).filter((entry) => {
680
+ if (!isPlainObject2(entry)) return false;
681
+ return !!normalizeProviderSessionId(
682
+ typeof entry.providerType === "string" ? entry.providerType : "",
683
+ typeof entry.providerSessionId === "string" ? entry.providerSessionId : ""
684
+ );
685
+ });
645
686
  const sessionReads = Object.fromEntries(
646
- Object.entries(isPlainObject2(parsed.sessionReads) ? parsed.sessionReads : {}).filter(([, value]) => typeof value === "number" && Number.isFinite(value))
687
+ Object.entries(isPlainObject2(parsed.sessionReads) ? parsed.sessionReads : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "number" && Number.isFinite(value))
647
688
  );
648
689
  const sessionReadMarkers = Object.fromEntries(
649
- Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([, value]) => typeof value === "string")
690
+ Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string")
650
691
  );
651
692
  return {
652
- recentActivity: Array.isArray(parsed.recentActivity) ? parsed.recentActivity : [],
653
- savedProviderSessions: Array.isArray(parsed.savedProviderSessions) ? parsed.savedProviderSessions : [],
693
+ recentActivity,
694
+ savedProviderSessions,
654
695
  sessionReads,
655
696
  sessionReadMarkers
656
697
  };
@@ -682,6 +723,7 @@ var init_state_store = __esm({
682
723
  import_fs2 = require("fs");
683
724
  import_path2 = require("path");
684
725
  init_config();
726
+ init_provider_session_id();
685
727
  DEFAULT_STATE = {
686
728
  recentActivity: [],
687
729
  savedProviderSessions: [],
@@ -3300,19 +3342,91 @@ function sanitizeHistoryMessage(agentType, message) {
3300
3342
  content
3301
3343
  };
3302
3344
  }
3303
- function readChatHistory(agentType, offset = 0, limit = 30, historySessionId) {
3345
+ function sanitizeHistoryFileSegment(value) {
3346
+ return String(value || "").replace(/[^a-zA-Z0-9_-]/g, "_");
3347
+ }
3348
+ function listHistoryFiles(dir, historySessionId) {
3349
+ const sanitizedSessionId = historySessionId ? sanitizeHistoryFileSegment(historySessionId) : "";
3350
+ return fs3.readdirSync(dir).filter((file2) => {
3351
+ if (!file2.endsWith(".jsonl")) return false;
3352
+ if (sanitizedSessionId) {
3353
+ return file2.startsWith(`${sanitizedSessionId}_`);
3354
+ }
3355
+ return true;
3356
+ }).sort().reverse();
3357
+ }
3358
+ function buildSavedHistoryCacheSignature(dir, files) {
3359
+ return files.map((file2) => {
3360
+ try {
3361
+ const stat4 = fs3.statSync(path7.join(dir, file2));
3362
+ return `${file2}:${stat4.size}:${Math.trunc(stat4.mtimeMs)}`;
3363
+ } catch {
3364
+ return `${file2}:missing`;
3365
+ }
3366
+ }).join("|");
3367
+ }
3368
+ function computeSavedHistorySessionSummaries(agentType, dir, files) {
3369
+ const groupedFiles = /* @__PURE__ */ new Map();
3370
+ const filePattern = /^([A-Za-z0-9_-]+)_\d{4}-\d{2}-\d{2}\.jsonl$/;
3371
+ for (const file2 of files) {
3372
+ const match = file2.match(filePattern);
3373
+ if (!match?.[1]) continue;
3374
+ const historySessionId = match[1];
3375
+ const grouped = groupedFiles.get(historySessionId) || [];
3376
+ grouped.push(file2);
3377
+ groupedFiles.set(historySessionId, grouped);
3378
+ }
3379
+ const summaries = [];
3380
+ for (const [historySessionId, grouped] of groupedFiles.entries()) {
3381
+ let messageCount = 0;
3382
+ let firstMessageAt = 0;
3383
+ let lastMessageAt = 0;
3384
+ let sessionTitle = "";
3385
+ let preview = "";
3386
+ let workspace = "";
3387
+ for (const file2 of grouped.sort()) {
3388
+ const filePath = path7.join(dir, file2);
3389
+ const content = fs3.readFileSync(filePath, "utf-8");
3390
+ const lines = content.split("\n").filter(Boolean);
3391
+ for (const line of lines) {
3392
+ let parsed = null;
3393
+ try {
3394
+ parsed = JSON.parse(line);
3395
+ } catch {
3396
+ parsed = null;
3397
+ }
3398
+ if (!parsed || parsed.historySessionId !== historySessionId) continue;
3399
+ if (parsed.kind === "session_start") {
3400
+ if (!workspace && parsed.workspace) workspace = parsed.workspace;
3401
+ continue;
3402
+ }
3403
+ messageCount += 1;
3404
+ if (!firstMessageAt || parsed.receivedAt < firstMessageAt) firstMessageAt = parsed.receivedAt;
3405
+ if (!lastMessageAt || parsed.receivedAt > lastMessageAt) lastMessageAt = parsed.receivedAt;
3406
+ if (parsed.sessionTitle) sessionTitle = parsed.sessionTitle;
3407
+ if (parsed.role !== "system" && parsed.content.trim()) preview = parsed.content.trim();
3408
+ }
3409
+ }
3410
+ if (messageCount === 0 || !lastMessageAt) continue;
3411
+ summaries.push({
3412
+ historySessionId,
3413
+ sessionTitle: sessionTitle || void 0,
3414
+ messageCount,
3415
+ firstMessageAt,
3416
+ lastMessageAt,
3417
+ preview: preview || void 0,
3418
+ workspace: workspace || void 0
3419
+ });
3420
+ }
3421
+ summaries.sort((a, b) => b.lastMessageAt - a.lastMessageAt);
3422
+ return summaries;
3423
+ }
3424
+ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0) {
3304
3425
  try {
3305
3426
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
3306
3427
  const dir = path7.join(HISTORY_DIR, sanitized);
3307
3428
  if (!fs3.existsSync(dir)) return { messages: [], hasMore: false };
3308
- const sanitizedInstance = historySessionId?.replace(/[^a-zA-Z0-9_-]/g, "_");
3309
- const files = fs3.readdirSync(dir).filter((f) => {
3310
- if (!f.endsWith(".jsonl")) return false;
3311
- if (sanitizedInstance) {
3312
- return f.startsWith(`${sanitizedInstance}_`);
3313
- }
3314
- return true;
3315
- }).sort().reverse();
3429
+ const files = listHistoryFiles(dir, historySessionId);
3316
3430
  const allMessages = [];
3317
3431
  const seen = /* @__PURE__ */ new Set();
3318
3432
  for (const file2 of files) {
@@ -3343,8 +3457,13 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId) {
3343
3457
  if (message.role !== "system") lastTurn = message;
3344
3458
  }
3345
3459
  const collapsed = collapseReplayAssistantTurns(agentType, chronological);
3346
- const sliced = collapsed.slice(offset, offset + limit);
3347
- const hasMore = collapsed.length > offset + limit;
3460
+ const boundedLimit = Math.max(1, limit);
3461
+ const boundedOffset = Math.max(0, offset);
3462
+ const boundedExclude = Math.max(0, Math.min(excludeRecentCount, collapsed.length));
3463
+ const endExclusive = Math.max(0, collapsed.length - boundedExclude - boundedOffset);
3464
+ const startInclusive = Math.max(0, endExclusive - boundedLimit);
3465
+ const sliced = collapsed.slice(startInclusive, endExclusive);
3466
+ const hasMore = startInclusive > 0;
3348
3467
  return { messages: sliced, hasMore };
3349
3468
  } catch {
3350
3469
  return { messages: [], hasMore: false };
@@ -3354,61 +3473,20 @@ function listSavedHistorySessions(agentType, options = {}) {
3354
3473
  try {
3355
3474
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
3356
3475
  const dir = path7.join(HISTORY_DIR, sanitized);
3357
- if (!fs3.existsSync(dir)) return { sessions: [], hasMore: false };
3358
- const groupedFiles = /* @__PURE__ */ new Map();
3359
- const filePattern = /^([A-Za-z0-9_-]+)_\d{4}-\d{2}-\d{2}\.jsonl$/;
3360
- for (const file2 of fs3.readdirSync(dir)) {
3361
- if (!file2.endsWith(".jsonl")) continue;
3362
- const match = file2.match(filePattern);
3363
- if (!match?.[1]) continue;
3364
- const historySessionId = match[1];
3365
- const files = groupedFiles.get(historySessionId) || [];
3366
- files.push(file2);
3367
- groupedFiles.set(historySessionId, files);
3368
- }
3369
- const summaries = [];
3370
- for (const [historySessionId, files] of groupedFiles.entries()) {
3371
- let messageCount = 0;
3372
- let firstMessageAt = 0;
3373
- let lastMessageAt = 0;
3374
- let sessionTitle = "";
3375
- let preview = "";
3376
- let workspace = "";
3377
- for (const file2 of files.sort()) {
3378
- const filePath = path7.join(dir, file2);
3379
- const content = fs3.readFileSync(filePath, "utf-8");
3380
- const lines = content.split("\n").filter(Boolean);
3381
- for (const line of lines) {
3382
- let parsed = null;
3383
- try {
3384
- parsed = JSON.parse(line);
3385
- } catch {
3386
- parsed = null;
3387
- }
3388
- if (!parsed || parsed.historySessionId !== historySessionId) continue;
3389
- if (parsed.kind === "session_start") {
3390
- if (!workspace && parsed.workspace) workspace = parsed.workspace;
3391
- continue;
3392
- }
3393
- messageCount += 1;
3394
- if (!firstMessageAt || parsed.receivedAt < firstMessageAt) firstMessageAt = parsed.receivedAt;
3395
- if (!lastMessageAt || parsed.receivedAt > lastMessageAt) lastMessageAt = parsed.receivedAt;
3396
- if (parsed.sessionTitle) sessionTitle = parsed.sessionTitle;
3397
- if (parsed.role !== "system" && parsed.content.trim()) preview = parsed.content.trim();
3398
- }
3399
- }
3400
- if (messageCount === 0 || !lastMessageAt) continue;
3401
- summaries.push({
3402
- historySessionId,
3403
- sessionTitle: sessionTitle || void 0,
3404
- messageCount,
3405
- firstMessageAt,
3406
- lastMessageAt,
3407
- preview: preview || void 0,
3408
- workspace: workspace || void 0
3476
+ if (!fs3.existsSync(dir)) {
3477
+ savedHistorySessionCache.delete(sanitized);
3478
+ return { sessions: [], hasMore: false };
3479
+ }
3480
+ const files = listHistoryFiles(dir);
3481
+ const signature = buildSavedHistoryCacheSignature(dir, files);
3482
+ const cached2 = savedHistorySessionCache.get(sanitized);
3483
+ const summaries = cached2?.signature === signature ? cached2.summaries : computeSavedHistorySessionSummaries(agentType, dir, files);
3484
+ if (!cached2 || cached2.signature !== signature) {
3485
+ savedHistorySessionCache.set(sanitized, {
3486
+ signature,
3487
+ summaries
3409
3488
  });
3410
3489
  }
3411
- summaries.sort((a, b) => b.lastMessageAt - a.lastMessageAt);
3412
3490
  const offset = Math.max(0, options.offset || 0);
3413
3491
  const limit = Math.max(1, options.limit || 30);
3414
3492
  const sliced = summaries.slice(offset, offset + limit);
@@ -3420,7 +3498,7 @@ function listSavedHistorySessions(agentType, options = {}) {
3420
3498
  return { sessions: [], hasMore: false };
3421
3499
  }
3422
3500
  }
3423
- var fs3, path7, os5, HISTORY_DIR, RETAIN_DAYS, CODEX_STARTER_PROMPT_RE, ChatHistoryWriter;
3501
+ var fs3, path7, os5, HISTORY_DIR, RETAIN_DAYS, savedHistorySessionCache, CODEX_STARTER_PROMPT_RE, ChatHistoryWriter;
3424
3502
  var init_chat_history = __esm({
3425
3503
  "../../oss/packages/daemon-core/src/config/chat-history.ts"() {
3426
3504
  "use strict";
@@ -3430,6 +3508,7 @@ var init_chat_history = __esm({
3430
3508
  init_chat_message_normalization();
3431
3509
  HISTORY_DIR = path7.join(os5.homedir(), ".adhdev", "history");
3432
3510
  RETAIN_DAYS = 30;
3511
+ savedHistorySessionCache = /* @__PURE__ */ new Map();
3433
3512
  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;
3434
3513
  ChatHistoryWriter = class {
3435
3514
  /** Last seen message count per agent (deduplication) */
@@ -4392,7 +4471,7 @@ var init_read_chat_contract = __esm({
4392
4471
 
4393
4472
  // ../../oss/packages/daemon-core/src/providers/approval-utils.ts
4394
4473
  function normalizeApprovalLabel(value) {
4395
- return String(value || "").toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
4474
+ return String(value || "").toLowerCase().replace(/^[\s\[(<{]*\d+(?:\s*[.)\]}>:-]|\s)+/, "").replace(/[^\p{L}\p{N}]+/gu, " ").trim();
4396
4475
  }
4397
4476
  function getApprovalPositiveHints(provider) {
4398
4477
  const customHints = Array.isArray(provider?.approvalPositiveHints) ? provider.approvalPositiveHints.map((hint) => normalizeApprovalLabel(String(hint || ""))).filter(Boolean) : [];
@@ -4426,19 +4505,19 @@ var init_approval_utils = __esm({
4426
4505
  "../../oss/packages/daemon-core/src/providers/approval-utils.ts"() {
4427
4506
  "use strict";
4428
4507
  DEFAULT_APPROVAL_POSITIVE_HINTS = [
4429
- "run",
4508
+ "yes",
4509
+ "allow once",
4430
4510
  "approve",
4431
4511
  "accept",
4432
- "allow once",
4433
- "always allow",
4434
- "allow",
4435
- "yes",
4436
- "proceed",
4437
4512
  "continue",
4513
+ "run",
4514
+ "proceed",
4438
4515
  "confirm",
4439
4516
  "save",
4440
4517
  "ok",
4441
- "trust"
4518
+ "trust",
4519
+ "allow",
4520
+ "always allow"
4442
4521
  ];
4443
4522
  }
4444
4523
  });
@@ -5862,6 +5941,37 @@ var init_reconcile = __esm({
5862
5941
  }
5863
5942
  });
5864
5943
 
5944
+ // ../../oss/packages/daemon-core/src/commands/provider-script-resolver.ts
5945
+ function resolveLegacyProviderScript(fn, scriptName, params) {
5946
+ if (typeof fn !== "function") return null;
5947
+ if (params && typeof params === "object" && !Array.isArray(params) && Object.keys(params).length > 0) {
5948
+ const firstVal = Object.values(params)[0];
5949
+ if (scriptName === "sendMessage" && typeof firstVal === "string") {
5950
+ const legacyScript = fn(firstVal);
5951
+ if (legacyScript) return legacyScript;
5952
+ }
5953
+ const script = fn(params);
5954
+ const likelyLegacyObjectLeak = typeof script === "string" && script.includes("[object Object]") && typeof firstVal === "string";
5955
+ if (!likelyLegacyObjectLeak && script) return script;
5956
+ if (firstVal !== void 0) {
5957
+ const legacyScript = fn(firstVal);
5958
+ if (legacyScript) return legacyScript;
5959
+ }
5960
+ if (script) return script;
5961
+ return null;
5962
+ }
5963
+ if (params !== void 0) {
5964
+ const script = fn(params);
5965
+ if (script) return script;
5966
+ }
5967
+ return fn() || null;
5968
+ }
5969
+ var init_provider_script_resolver = __esm({
5970
+ "../../oss/packages/daemon-core/src/commands/provider-script-resolver.ts"() {
5971
+ "use strict";
5972
+ }
5973
+ });
5974
+
5865
5975
  // ../../oss/packages/daemon-core/src/providers/provider-input-support.ts
5866
5976
  function getProviderLabel(provider) {
5867
5977
  return provider?.name || provider?.type || "This provider";
@@ -6062,7 +6172,7 @@ var init_debug_trace = __esm({
6062
6172
  }
6063
6173
  });
6064
6174
 
6065
- // ../../oss/packages/daemon-core/src/commands/chat-commands.ts
6175
+ // ../../oss/packages/daemon-core/src/chat/chat-signatures.ts
6066
6176
  function hashSignatureParts(parts) {
6067
6177
  let hash2 = 2166136261;
6068
6178
  for (const part of parts) {
@@ -6076,6 +6186,60 @@ function hashSignatureParts(parts) {
6076
6186
  }
6077
6187
  return hash2.toString(16).padStart(8, "0");
6078
6188
  }
6189
+ function stringifySignatureContent(content) {
6190
+ try {
6191
+ return JSON.stringify(content ?? "");
6192
+ } catch {
6193
+ return String(content ?? "");
6194
+ }
6195
+ }
6196
+ function stringifySignatureMessages(messages) {
6197
+ try {
6198
+ return JSON.stringify(messages);
6199
+ } catch {
6200
+ return String(messages.length);
6201
+ }
6202
+ }
6203
+ function buildChatMessageSignature(message) {
6204
+ if (!message) return "";
6205
+ return hashSignatureParts([
6206
+ String(message.id || ""),
6207
+ String(message.index ?? ""),
6208
+ String(message.role || ""),
6209
+ String(message.receivedAt ?? message.timestamp ?? ""),
6210
+ stringifySignatureContent(message.content)
6211
+ ]);
6212
+ }
6213
+ function buildChatTailDeliverySignature(payload) {
6214
+ return hashSignatureParts([
6215
+ payload.sessionId,
6216
+ payload.historySessionId || "",
6217
+ payload.status,
6218
+ payload.title || "",
6219
+ payload.syncMode,
6220
+ String(payload.replaceFrom),
6221
+ String(payload.totalMessages),
6222
+ payload.lastMessageSignature,
6223
+ payload.activeModal ? `${payload.activeModal.message}|${payload.activeModal.buttons.join("")}` : "",
6224
+ stringifySignatureMessages(payload.messages)
6225
+ ]);
6226
+ }
6227
+ function buildSessionModalDeliverySignature(payload) {
6228
+ return hashSignatureParts([
6229
+ payload.sessionId,
6230
+ payload.status,
6231
+ payload.title || "",
6232
+ payload.modalMessage || "",
6233
+ Array.isArray(payload.modalButtons) ? payload.modalButtons.join("") : ""
6234
+ ]);
6235
+ }
6236
+ var init_chat_signatures = __esm({
6237
+ "../../oss/packages/daemon-core/src/chat/chat-signatures.ts"() {
6238
+ "use strict";
6239
+ }
6240
+ });
6241
+
6242
+ // ../../oss/packages/daemon-core/src/commands/chat-commands.ts
6079
6243
  function getCurrentProviderType(h, fallback2 = "") {
6080
6244
  return h.currentSession?.providerType || h.currentProviderType || fallback2;
6081
6245
  }
@@ -6172,20 +6336,7 @@ function parseMaybeJson(value) {
6172
6336
  }
6173
6337
  }
6174
6338
  function getChatMessageSignature(message) {
6175
- if (!message) return "";
6176
- let content = "";
6177
- try {
6178
- content = JSON.stringify(message.content ?? "");
6179
- } catch {
6180
- content = String(message.content ?? "");
6181
- }
6182
- return hashSignatureParts([
6183
- String(message.id || ""),
6184
- String(message.index ?? ""),
6185
- String(message.role || ""),
6186
- String(message.receivedAt ?? message.timestamp ?? ""),
6187
- content
6188
- ]);
6339
+ return buildChatMessageSignature(message);
6189
6340
  }
6190
6341
  function normalizeReadChatCursor(args) {
6191
6342
  const knownMessageCount = Math.max(0, Number(args?.knownMessageCount || 0));
@@ -6197,6 +6348,41 @@ function normalizeReadChatMessages(payload) {
6197
6348
  const messages = Array.isArray(payload.messages) ? payload.messages : [];
6198
6349
  return normalizeChatMessages(messages);
6199
6350
  }
6351
+ function buildReadChatReplayCollapseSignature(message) {
6352
+ if (!message) return "";
6353
+ const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
6354
+ const kind = typeof message.kind === "string" ? message.kind.trim().toLowerCase() : "standard";
6355
+ const senderName = typeof message.senderName === "string" ? message.senderName.trim().toLowerCase() : "";
6356
+ const content = flattenContent(message.content || "").replace(/\s+/g, " ").trim();
6357
+ return `${role}:${kind}:${senderName}:${content}`;
6358
+ }
6359
+ function shouldCollapseReadChatReplayDuplicate(message) {
6360
+ if (!message) return false;
6361
+ const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
6362
+ if (role !== "assistant" && role !== "system") return false;
6363
+ const kind = typeof message.kind === "string" ? message.kind.trim().toLowerCase() : "standard";
6364
+ return kind === "tool" || kind === "terminal" || kind === "thought" || kind === "system";
6365
+ }
6366
+ function collapseReplayDuplicatesFromReadChat(messages) {
6367
+ const collapsed = [];
6368
+ let lastReplayTurnSignature = "";
6369
+ for (const message of messages) {
6370
+ const signature = buildReadChatReplayCollapseSignature(message);
6371
+ const previous = collapsed[collapsed.length - 1];
6372
+ const previousSignature = buildReadChatReplayCollapseSignature(previous);
6373
+ if (shouldCollapseReadChatReplayDuplicate(message) && signature) {
6374
+ if (previousSignature === signature) continue;
6375
+ if (lastReplayTurnSignature === signature) continue;
6376
+ }
6377
+ collapsed.push(message);
6378
+ if (shouldCollapseReadChatReplayDuplicate(message) && signature) {
6379
+ lastReplayTurnSignature = signature;
6380
+ } else if ((message.role || "").toLowerCase() === "user") {
6381
+ lastReplayTurnSignature = "";
6382
+ }
6383
+ }
6384
+ return collapsed;
6385
+ }
6200
6386
  function deriveHistoryDedupKey(message) {
6201
6387
  const unitKey = typeof message._unitKey === "string" ? message._unitKey.trim() : "";
6202
6388
  if (unitKey) return `read_chat:${unitKey}`;
@@ -6272,14 +6458,38 @@ function computeReadChatSync(messages, cursor) {
6272
6458
  lastMessageSignature
6273
6459
  };
6274
6460
  }
6461
+ function hasNonEmptyModalButtons(activeModal) {
6462
+ if (!activeModal || typeof activeModal !== "object") return false;
6463
+ const buttons = activeModal.buttons;
6464
+ return Array.isArray(buttons) && buttons.some((button) => typeof button === "string" && button.trim().length > 0);
6465
+ }
6466
+ function normalizeReadChatCommandStatus(status, activeModal) {
6467
+ const raw = typeof status === "string" ? status.trim() : "";
6468
+ if (!raw) {
6469
+ return hasNonEmptyModalButtons(activeModal) ? "waiting_approval" : "idle";
6470
+ }
6471
+ switch (raw) {
6472
+ case "starting":
6473
+ return hasNonEmptyModalButtons(activeModal) ? "waiting_approval" : "generating";
6474
+ case "stopped":
6475
+ case "disconnected":
6476
+ case "not_monitored":
6477
+ return "error";
6478
+ default:
6479
+ return raw;
6480
+ }
6481
+ }
6275
6482
  function buildReadChatCommandResult(payload, args) {
6276
6483
  let validatedPayload;
6277
6484
  try {
6278
- validatedPayload = validateReadChatResultPayload(payload, "read_chat command result");
6485
+ validatedPayload = validateReadChatResultPayload({
6486
+ ...payload,
6487
+ status: normalizeReadChatCommandStatus(payload?.status, payload?.activeModal)
6488
+ }, "read_chat command result");
6279
6489
  } catch (error48) {
6280
6490
  return { success: false, error: error48?.message || String(error48) };
6281
6491
  }
6282
- const messages = normalizeReadChatMessages(validatedPayload);
6492
+ const messages = collapseReplayDuplicatesFromReadChat(normalizeReadChatMessages(validatedPayload));
6283
6493
  const cursor = normalizeReadChatCursor(args);
6284
6494
  if (!cursor.knownMessageCount && !cursor.lastMessageSignature && cursor.tailLimit > 0 && messages.length > cursor.tailLimit) {
6285
6495
  const tailMessages = messages.slice(-cursor.tailLimit);
@@ -6361,7 +6571,15 @@ async function handleChatHistory(h, args) {
6361
6571
  try {
6362
6572
  const provider = h.getProvider(agentType);
6363
6573
  const agentStr = provider?.type || agentType || getCurrentProviderType(h);
6364
- const result = readChatHistory(agentStr, offset || 0, limit || 30, historySessionId);
6574
+ const transport = getTargetTransport(h, provider);
6575
+ let excludeRecentCount = Math.max(0, Number(args?.excludeRecentCount || 0));
6576
+ if (isCliLikeTransport(transport)) {
6577
+ const adapter = getTargetedCliAdapter(h, args, provider?.type);
6578
+ const status = adapter?.getStatus?.();
6579
+ const visibleCount = Array.isArray(status?.messages) ? status.messages.length : 0;
6580
+ if (visibleCount > excludeRecentCount) excludeRecentCount = visibleCount;
6581
+ }
6582
+ const result = readChatHistory(agentStr, offset || 0, limit || 30, historySessionId, excludeRecentCount);
6365
6583
  return { success: true, ...result, agent: agentStr };
6366
6584
  } catch (e) {
6367
6585
  return { success: false, error: e.message };
@@ -7208,6 +7426,7 @@ var init_chat_commands = __esm({
7208
7426
  init_chat_history();
7209
7427
  init_logger();
7210
7428
  init_debug_trace();
7429
+ init_chat_signatures();
7211
7430
  init_chat_message_normalization();
7212
7431
  RECENT_SEND_WINDOW_MS = 1200;
7213
7432
  recentSendByTarget = /* @__PURE__ */ new Map();
@@ -7648,13 +7867,6 @@ var init_cli_script_results = __esm({
7648
7867
  });
7649
7868
 
7650
7869
  // ../../oss/packages/daemon-core/src/commands/stream-commands.ts
7651
- function getCliPresentationMode(h, targetSessionId) {
7652
- if (!targetSessionId) return null;
7653
- const instance = h.ctx.instanceManager?.getInstance(targetSessionId);
7654
- if (instance?.category !== "cli") return null;
7655
- const mode = instance.getPresentationMode?.();
7656
- return mode === "chat" || mode === "terminal" ? mode : null;
7657
- }
7658
7870
  function normalizeOpenPanelCommandResult(result) {
7659
7871
  const payload = Object.prototype.hasOwnProperty.call(result, "result") ? result.result : result;
7660
7872
  if (payload === true) return { opened: true, visible: true, focused: false };
@@ -7727,9 +7939,6 @@ async function handleOpenPanel(h, args) {
7727
7939
  function handlePtyInput(h, args) {
7728
7940
  const { cliType, data, targetSessionId } = args || {};
7729
7941
  if (!data) return { success: false, error: "data required" };
7730
- if (getCliPresentationMode(h, targetSessionId) === "chat") {
7731
- return { success: false, error: "CLI session is in chat mode", code: "CLI_VIEW_MODE_NOT_TERMINAL" };
7732
- }
7733
7942
  const adapter = h.getCliAdapter(targetSessionId || cliType);
7734
7943
  if (!adapter || typeof adapter.writeRaw !== "function") {
7735
7944
  return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
@@ -7737,24 +7946,10 @@ function handlePtyInput(h, args) {
7737
7946
  adapter.writeRaw(data);
7738
7947
  return { success: true };
7739
7948
  }
7740
- function handlePtyResize(h, args) {
7741
- const { cliType, cols, rows, force, targetSessionId } = args || {};
7949
+ function handlePtyResize(_h, args) {
7950
+ const { cols, rows } = args || {};
7742
7951
  if (!cols || !rows) return { success: false, error: "cols and rows required" };
7743
- if (getCliPresentationMode(h, targetSessionId) === "chat") {
7744
- return { success: false, error: "CLI session is in chat mode", code: "CLI_VIEW_MODE_NOT_TERMINAL" };
7745
- }
7746
- const adapter = h.getCliAdapter(targetSessionId || cliType);
7747
- if (!adapter || typeof adapter.resize !== "function") {
7748
- return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
7749
- }
7750
- const resize = adapter.resize;
7751
- if (force) {
7752
- resize(cols - 1, rows);
7753
- setTimeout(() => resize(cols, rows), 50);
7754
- } else {
7755
- resize(cols, rows);
7756
- }
7757
- return { success: true };
7952
+ return { success: false, error: "PTY resize temporarily disabled", code: "PTY_RESIZE_DISABLED" };
7758
7953
  }
7759
7954
  function handleGetProviderSettings(h, args) {
7760
7955
  const loader = h.ctx.providerLoader;
@@ -7841,15 +8036,45 @@ function normalizeProviderScriptArgs(args, scriptName) {
7841
8036
  }
7842
8037
  function buildControlScriptResult(scriptName, payload) {
7843
8038
  if (!payload || typeof payload !== "object") return {};
7844
- if (Array.isArray(payload.options)) {
7845
- return { controlResult: normalizeControlListResult(payload) };
8039
+ const legacyListPayload = (() => {
8040
+ if (Array.isArray(payload.options)) return payload;
8041
+ if (/^listmodels$/i.test(scriptName) && Array.isArray(payload.models)) {
8042
+ return {
8043
+ options: payload.models,
8044
+ currentValue: payload.currentValue ?? payload.current ?? payload.currentModel,
8045
+ ...typeof payload.error === "string" ? { error: payload.error } : {}
8046
+ };
8047
+ }
8048
+ if (/^listmodes$/i.test(scriptName) && Array.isArray(payload.modes)) {
8049
+ return {
8050
+ options: payload.modes,
8051
+ currentValue: payload.currentValue ?? payload.current ?? payload.currentMode ?? payload.mode,
8052
+ ...typeof payload.error === "string" ? { error: payload.error } : {}
8053
+ };
8054
+ }
8055
+ return null;
8056
+ })();
8057
+ if (legacyListPayload) {
8058
+ return { controlResult: normalizeControlListResult(legacyListPayload) };
7846
8059
  }
7847
- const looksLikeValueMutation = /^set|^change/i.test(scriptName) || payload.currentValue !== void 0 || payload.value !== void 0;
8060
+ const legacyMutationPayload = (() => {
8061
+ if (typeof payload.ok === "boolean") return payload;
8062
+ if (typeof payload.success === "boolean") {
8063
+ return {
8064
+ ok: payload.success,
8065
+ currentValue: payload.currentValue ?? payload.value ?? payload.model ?? payload.mode ?? payload.selectedModel ?? payload.selectedMode,
8066
+ ...Array.isArray(payload.effects) ? { effects: payload.effects } : {},
8067
+ ...typeof payload.error === "string" ? { error: payload.error } : {}
8068
+ };
8069
+ }
8070
+ return null;
8071
+ })();
8072
+ const looksLikeValueMutation = /^set|^change/i.test(scriptName) || payload.currentValue !== void 0 || payload.value !== void 0 || payload.success !== void 0;
7848
8073
  if (looksLikeValueMutation) {
7849
- return { controlResult: normalizeControlSetResult(payload) };
8074
+ return { controlResult: normalizeControlSetResult(legacyMutationPayload || payload) };
7850
8075
  }
7851
8076
  if (payload.ok !== void 0 || Array.isArray(payload.effects) || typeof payload.error === "string") {
7852
- return { controlResult: normalizeControlInvokeResult(payload) };
8077
+ return { controlResult: normalizeControlInvokeResult(legacyMutationPayload || payload) };
7853
8078
  }
7854
8079
  return {};
7855
8080
  }
@@ -7924,7 +8149,7 @@ async function executeProviderScript(h, args, scriptName) {
7924
8149
  }
7925
8150
  const managed = runtimeSessionId ? h.agentStream?.getManagedSession(runtimeSessionId) : null;
7926
8151
  const targetSessionId = managed?.cdpSessionId || null;
7927
- const IDE_LEVEL_SCRIPTS = provider.type === "claude-code-vscode" ? ["listModes", "setMode"] : ["listModes", "setMode", "listModels", "setModel"];
8152
+ const IDE_LEVEL_SCRIPTS = provider.type === "claude-code-vscode" ? ["listModes", "setMode", "listModels", "setModel", "setModelGui"] : ["listModes", "setMode", "listModels", "setModel"];
7928
8153
  if (IDE_LEVEL_SCRIPTS.includes(scriptName)) {
7929
8154
  if (targetSessionId) {
7930
8155
  try {
@@ -8214,6 +8439,7 @@ var init_handler = __esm({
8214
8439
  init_chat_history();
8215
8440
  init_reconcile();
8216
8441
  init_logger();
8442
+ init_provider_script_resolver();
8217
8443
  init_chat_commands();
8218
8444
  init_cdp_commands();
8219
8445
  init_stream_commands();
@@ -8289,27 +8515,7 @@ var init_handler = __esm({
8289
8515
  if (provider?.scripts) {
8290
8516
  const fn = provider.scripts[scriptName];
8291
8517
  if (typeof fn === "function") {
8292
- const callScript = fn;
8293
- if (params && Object.keys(params).length > 0) {
8294
- const firstVal = Object.values(params)[0];
8295
- if (scriptName === "sendMessage" && typeof firstVal === "string") {
8296
- const legacyScript = callScript(firstVal);
8297
- if (legacyScript) return legacyScript;
8298
- }
8299
- const script = callScript(params);
8300
- if (script) {
8301
- const likelyLegacyObjectLeak = typeof script === "string" && script.includes("[object Object]") && typeof firstVal === "string";
8302
- if (!likelyLegacyObjectLeak) return script;
8303
- }
8304
- if (firstVal !== void 0) {
8305
- const legacyScript = callScript(firstVal);
8306
- if (legacyScript) return legacyScript;
8307
- }
8308
- if (script) return script;
8309
- } else {
8310
- const script = callScript();
8311
- if (script) return script;
8312
- }
8518
+ return resolveLegacyProviderScript(fn, scriptName, params);
8313
8519
  }
8314
8520
  }
8315
8521
  return null;
@@ -11454,6 +11660,8 @@ ${data.message || ""}`.trim();
11454
11660
  }
11455
11661
  async sendMessage(text) {
11456
11662
  if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
11663
+ const allowInputDuringGeneration = this.provider.allowInputDuringGeneration === true;
11664
+ const allowInterventionPrompt = allowInputDuringGeneration && this.isWaitingForResponse && this.currentStatus !== "waiting_approval";
11457
11665
  if (this.startupParseGate) {
11458
11666
  const deadline = Date.now() + 1e4;
11459
11667
  while (this.startupParseGate && Date.now() < deadline) {
@@ -11461,7 +11669,9 @@ ${data.message || ""}`.trim();
11461
11669
  await new Promise((resolve15) => setTimeout(resolve15, 50));
11462
11670
  }
11463
11671
  }
11464
- await this.waitForInteractivePrompt();
11672
+ if (!allowInterventionPrompt) {
11673
+ await this.waitForInteractivePrompt();
11674
+ }
11465
11675
  if (!this.ready) {
11466
11676
  this.resolveStartupState("send_precheck");
11467
11677
  const screenText = this.terminalScreen.getText() || "";
@@ -11473,7 +11683,7 @@ ${data.message || ""}`.trim();
11473
11683
  }
11474
11684
  }
11475
11685
  if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
11476
- if (this.isWaitingForResponse) {
11686
+ if (this.isWaitingForResponse && !allowInputDuringGeneration) {
11477
11687
  throw new Error(`${this.cliName} is still processing the previous prompt`);
11478
11688
  }
11479
11689
  const blockingModal = this.activeModal || this.getStartupConfirmationModal(this.terminalScreen.getText() || "");
@@ -12054,6 +12264,7 @@ var init_cli_provider_instance = __esm({
12054
12264
  init_approval_utils();
12055
12265
  init_cli_script_results();
12056
12266
  init_provider_patch_state();
12267
+ init_provider_session_id();
12057
12268
  init_chat_message_normalization();
12058
12269
  CachedDatabaseSync = null;
12059
12270
  CliProviderInstance = class {
@@ -12216,7 +12427,10 @@ var init_cli_provider_instance = __esm({
12216
12427
  const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
12217
12428
  const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
12218
12429
  const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
12219
- const parsedProviderSessionId = typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId.trim() : "";
12430
+ const parsedProviderSessionId = normalizeProviderSessionId(
12431
+ this.type,
12432
+ typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId : ""
12433
+ );
12220
12434
  if (parsedProviderSessionId) {
12221
12435
  this.promoteProviderSessionId(parsedProviderSessionId);
12222
12436
  }
@@ -12480,7 +12694,10 @@ var init_cli_provider_instance = __esm({
12480
12694
  }
12481
12695
  applyProviderResponse(data, options) {
12482
12696
  if (!data || typeof data !== "object") return;
12483
- const patchedProviderSessionId = typeof data.providerSessionId === "string" ? data.providerSessionId.trim() : "";
12697
+ const patchedProviderSessionId = normalizeProviderSessionId(
12698
+ this.type,
12699
+ typeof data.providerSessionId === "string" ? data.providerSessionId : ""
12700
+ );
12484
12701
  if (patchedProviderSessionId) {
12485
12702
  this.promoteProviderSessionId(patchedProviderSessionId);
12486
12703
  }
@@ -36224,6 +36441,147 @@ var init_ipc_protocol = __esm({
36224
36441
  }
36225
36442
  });
36226
36443
 
36444
+ // ../../oss/packages/daemon-core/src/chat/subscription-updates.ts
36445
+ function normalizeSyncMode(syncMode) {
36446
+ return syncMode === "append" || syncMode === "replace_tail" || syncMode === "noop" || syncMode === "full" ? syncMode : "full";
36447
+ }
36448
+ function normalizeModalButtons(value) {
36449
+ return Array.isArray(value) ? value.filter((button) => typeof button === "string") : [];
36450
+ }
36451
+ function normalizeModalMessage(value) {
36452
+ return typeof value === "string" ? value : void 0;
36453
+ }
36454
+ function normalizeChatTailActiveModal(activeModal) {
36455
+ if (!activeModal || typeof activeModal !== "object") return null;
36456
+ const message = normalizeModalMessage(activeModal.message);
36457
+ if (!message) return null;
36458
+ const rawButtons = activeModal.buttons;
36459
+ if (!Array.isArray(rawButtons)) return null;
36460
+ return {
36461
+ message,
36462
+ buttons: normalizeModalButtons(rawButtons)
36463
+ };
36464
+ }
36465
+ function normalizeSessionModalFields(activeModal) {
36466
+ if (!activeModal || typeof activeModal !== "object") {
36467
+ return { modalButtons: [] };
36468
+ }
36469
+ return {
36470
+ modalMessage: normalizeModalMessage(activeModal.message),
36471
+ modalButtons: normalizeModalButtons(activeModal.buttons)
36472
+ };
36473
+ }
36474
+ function buildNextChatCursor(cursor, result) {
36475
+ return {
36476
+ knownMessageCount: Math.max(0, Number(result.totalMessages || cursor.knownMessageCount)),
36477
+ lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : cursor.lastMessageSignature,
36478
+ tailLimit: cursor.tailLimit
36479
+ };
36480
+ }
36481
+ function prepareSessionChatTailUpdate(input) {
36482
+ const result = input.result;
36483
+ if (!result?.success || result.syncMode === "noop") {
36484
+ return {
36485
+ cursor: result?.success ? buildNextChatCursor(input.cursor, result) : input.cursor,
36486
+ seq: input.seq,
36487
+ lastDeliveredSignature: input.lastDeliveredSignature,
36488
+ update: null
36489
+ };
36490
+ }
36491
+ const syncMode = normalizeSyncMode(result.syncMode);
36492
+ const cursor = {
36493
+ knownMessageCount: Math.max(0, Number(result.totalMessages || 0)),
36494
+ lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : "",
36495
+ tailLimit: input.cursor.tailLimit
36496
+ };
36497
+ const title = typeof result.title === "string" ? result.title : void 0;
36498
+ const activeModal = normalizeChatTailActiveModal(result.activeModal);
36499
+ const status = typeof result.status === "string" ? result.status : "idle";
36500
+ const deliverySignature = buildChatTailDeliverySignature({
36501
+ sessionId: input.sessionId,
36502
+ ...input.historySessionId ? { historySessionId: input.historySessionId } : {},
36503
+ messages: Array.isArray(result.messages) ? result.messages : [],
36504
+ status,
36505
+ ...title ? { title } : {},
36506
+ ...activeModal ? { activeModal } : {},
36507
+ syncMode,
36508
+ replaceFrom: Number(result.replaceFrom || 0),
36509
+ totalMessages: Number(result.totalMessages || 0),
36510
+ lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
36511
+ });
36512
+ const seq = input.seq + 1;
36513
+ if (deliverySignature === input.lastDeliveredSignature) {
36514
+ return {
36515
+ cursor,
36516
+ seq,
36517
+ lastDeliveredSignature: input.lastDeliveredSignature,
36518
+ update: null
36519
+ };
36520
+ }
36521
+ return {
36522
+ cursor,
36523
+ seq,
36524
+ lastDeliveredSignature: deliverySignature,
36525
+ update: {
36526
+ topic: "session.chat_tail",
36527
+ key: input.key,
36528
+ sessionId: input.sessionId,
36529
+ ...input.historySessionId ? { historySessionId: input.historySessionId } : {},
36530
+ ...input.interactionId ? { interactionId: input.interactionId } : {},
36531
+ seq,
36532
+ timestamp: input.timestamp,
36533
+ messages: Array.isArray(result.messages) ? result.messages : [],
36534
+ status,
36535
+ ...title ? { title } : {},
36536
+ ...activeModal ? { activeModal } : {},
36537
+ syncMode,
36538
+ replaceFrom: Number(result.replaceFrom || 0),
36539
+ totalMessages: Number(result.totalMessages || 0),
36540
+ lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
36541
+ }
36542
+ };
36543
+ }
36544
+ function prepareSessionModalUpdate(input) {
36545
+ const { modalMessage, modalButtons } = normalizeSessionModalFields(input.activeModal);
36546
+ const deliverySignature = buildSessionModalDeliverySignature({
36547
+ sessionId: input.sessionId,
36548
+ status: input.status,
36549
+ ...input.title ? { title: input.title } : {},
36550
+ ...modalMessage ? { modalMessage } : {},
36551
+ ...modalButtons.length > 0 ? { modalButtons } : {}
36552
+ });
36553
+ if (deliverySignature === input.lastDeliveredSignature) {
36554
+ return {
36555
+ seq: input.seq,
36556
+ lastDeliveredSignature: input.lastDeliveredSignature,
36557
+ update: null
36558
+ };
36559
+ }
36560
+ const seq = input.seq + 1;
36561
+ return {
36562
+ seq,
36563
+ lastDeliveredSignature: deliverySignature,
36564
+ update: {
36565
+ topic: "session.modal",
36566
+ key: input.key,
36567
+ sessionId: input.sessionId,
36568
+ status: input.status,
36569
+ ...input.title ? { title: input.title } : {},
36570
+ ...modalMessage ? { modalMessage } : {},
36571
+ ...modalButtons.length > 0 ? { modalButtons } : {},
36572
+ ...input.interactionId ? { interactionId: input.interactionId } : {},
36573
+ seq,
36574
+ timestamp: input.timestamp
36575
+ }
36576
+ };
36577
+ }
36578
+ var init_subscription_updates = __esm({
36579
+ "../../oss/packages/daemon-core/src/chat/subscription-updates.ts"() {
36580
+ "use strict";
36581
+ init_chat_signatures();
36582
+ }
36583
+ });
36584
+
36227
36585
  // ../../oss/packages/daemon-core/src/agent-stream/provider-adapter.ts
36228
36586
  var ProviderStreamAdapter;
36229
36587
  var init_provider_adapter = __esm({
@@ -41243,6 +41601,7 @@ var init_dev_server = __esm({
41243
41601
  init_logger();
41244
41602
  init_builders();
41245
41603
  init_dev_cdp_handlers();
41604
+ init_provider_script_resolver();
41246
41605
  init_dev_cli_debug();
41247
41606
  init_dev_auto_implement();
41248
41607
  DEV_SERVER_PORT = 19280;
@@ -41506,7 +41865,8 @@ var init_dev_server = __esm({
41506
41865
  }
41507
41866
  async handleRunScript(type, req, res, parsedBody) {
41508
41867
  const body = parsedBody || await this.readBody(req);
41509
- const { script: scriptName, params, ideType: scriptIdeType } = body;
41868
+ const { script: scriptName, params, args, ideType: scriptIdeType } = body;
41869
+ const rawParams = args !== void 0 ? args : params;
41510
41870
  const provider = this.providerLoader.resolve(type);
41511
41871
  if (!provider) {
41512
41872
  this.json(res, 404, { error: `Provider '${type}' not found` });
@@ -41523,13 +41883,7 @@ var init_dev_server = __esm({
41523
41883
  return;
41524
41884
  }
41525
41885
  try {
41526
- let scriptCode = null;
41527
- if (["sendMessage", "webviewSendMessage", "switchSession", "webviewSwitchSession", "setMode", "webviewSetMode", "setModel", "webviewSetModel"].includes(scriptName)) {
41528
- const firstVal = params && typeof params === "object" && Object.keys(params).length > 0 ? Object.values(params)[0] : params;
41529
- scriptCode = firstVal !== void 0 ? fn(firstVal) : fn();
41530
- } else {
41531
- scriptCode = params !== void 0 ? fn(params) : fn();
41532
- }
41886
+ const scriptCode = resolveLegacyProviderScript(fn, scriptName, rawParams);
41533
41887
  if (!scriptCode) {
41534
41888
  this.json(res, 500, { error: "Script function returned null" });
41535
41889
  return;
@@ -41546,6 +41900,17 @@ var init_dev_server = __esm({
41546
41900
  break;
41547
41901
  }
41548
41902
  }
41903
+ if (!sessionId) {
41904
+ try {
41905
+ const discovered = await cdp.discoverAgentWebviews();
41906
+ const target = discovered.find((entry) => entry.agentType === type);
41907
+ if (target) {
41908
+ sessionId = await cdp.attachToAgent(target);
41909
+ }
41910
+ } catch (error48) {
41911
+ this.log(`Extension attach fallback failed for ${type}: ${error48?.message || String(error48)}`);
41912
+ }
41913
+ }
41549
41914
  if (sessionId) {
41550
41915
  raw = await cdp.evaluateInSessionFrame(sessionId, scriptCode);
41551
41916
  } else if (cdp.evaluateInWebviewFrame) {
@@ -41610,6 +41975,20 @@ var init_dev_server = __esm({
41610
41975
  async handleReload(_req, res) {
41611
41976
  try {
41612
41977
  this.providerLoader.reload();
41978
+ let refreshedInstances = 0;
41979
+ if (this.instanceManager) {
41980
+ for (const id of this.instanceManager.listInstanceIds()) {
41981
+ const instance = this.instanceManager.getInstance(id);
41982
+ const providerType = typeof instance?.type === "string" ? instance.type : "";
41983
+ if (!providerType) continue;
41984
+ const resolved = this.providerLoader.resolve(providerType);
41985
+ if (!resolved) continue;
41986
+ if (instance && typeof instance === "object" && "provider" in instance) {
41987
+ instance.provider = resolved;
41988
+ refreshedInstances += 1;
41989
+ }
41990
+ }
41991
+ }
41613
41992
  const providers = this.providerLoader.getAll().map((p) => ({
41614
41993
  type: p.type,
41615
41994
  name: p.name,
@@ -41620,7 +41999,7 @@ var init_dev_server = __esm({
41620
41999
  cdp.clearTargetId();
41621
42000
  }
41622
42001
  }
41623
- this.json(res, 200, { reloaded: true, providers });
42002
+ this.json(res, 200, { reloaded: true, refreshedInstances, providers });
41624
42003
  } catch (e) {
41625
42004
  this.json(res, 500, { error: e.message });
41626
42005
  }
@@ -43116,10 +43495,19 @@ var init_session_host_transport = __esm({
43116
43495
  });
43117
43496
 
43118
43497
  // ../../oss/packages/daemon-core/src/session-host/app-name.ts
43498
+ function validateStandaloneSessionHostAppName(explicit) {
43499
+ if (explicit !== DEFAULT_SESSION_HOST_APP_NAME) return;
43500
+ throw new Error(
43501
+ `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.`
43502
+ );
43503
+ }
43119
43504
  function resolveSessionHostAppName(options = {}) {
43120
43505
  const env3 = options.env || process.env;
43121
43506
  const explicit = typeof env3.ADHDEV_SESSION_HOST_NAME === "string" ? env3.ADHDEV_SESSION_HOST_NAME.trim() : "";
43122
- if (explicit) return explicit;
43507
+ if (explicit) {
43508
+ if (options.standalone) validateStandaloneSessionHostAppName(explicit);
43509
+ return explicit;
43510
+ }
43123
43511
  return options.standalone ? DEFAULT_STANDALONE_SESSION_HOST_APP_NAME : DEFAULT_SESSION_HOST_APP_NAME;
43124
43512
  }
43125
43513
  var DEFAULT_SESSION_HOST_APP_NAME, DEFAULT_STANDALONE_SESSION_HOST_APP_NAME;
@@ -43746,9 +44134,12 @@ __export(src_exports, {
43746
44134
  appendRecentActivity: () => appendRecentActivity,
43747
44135
  buildAssistantChatMessage: () => buildAssistantChatMessage,
43748
44136
  buildChatMessage: () => buildChatMessage,
44137
+ buildChatMessageSignature: () => buildChatMessageSignature,
44138
+ buildChatTailDeliverySignature: () => buildChatTailDeliverySignature,
43749
44139
  buildMachineInfo: () => buildMachineInfo,
43750
44140
  buildRuntimeSystemChatMessage: () => buildRuntimeSystemChatMessage,
43751
44141
  buildSessionEntries: () => buildSessionEntries,
44142
+ buildSessionModalDeliverySignature: () => buildSessionModalDeliverySignature,
43752
44143
  buildStatusSnapshot: () => buildStatusSnapshot,
43753
44144
  buildSystemChatMessage: () => buildSystemChatMessage,
43754
44145
  buildTerminalChatMessage: () => buildTerminalChatMessage,
@@ -43784,6 +44175,7 @@ __export(src_exports, {
43784
44175
  getSessionHostSurfaceKind: () => getSessionHostSurfaceKind,
43785
44176
  getWorkspaceState: () => getWorkspaceState,
43786
44177
  hasCdpManager: () => hasCdpManager,
44178
+ hashSignatureParts: () => hashSignatureParts,
43787
44179
  initDaemonComponents: () => initDaemonComponents,
43788
44180
  installExtensions: () => installExtensions,
43789
44181
  installGlobalInterceptor: () => installGlobalInterceptor,
@@ -43809,12 +44201,16 @@ __export(src_exports, {
43809
44201
  normalizeChatMessage: () => normalizeChatMessage,
43810
44202
  normalizeChatMessageKind: () => normalizeChatMessageKind,
43811
44203
  normalizeChatMessages: () => normalizeChatMessages,
44204
+ normalizeChatTailActiveModal: () => normalizeChatTailActiveModal,
43812
44205
  normalizeInputEnvelope: () => normalizeInputEnvelope,
43813
44206
  normalizeManagedStatus: () => normalizeManagedStatus,
43814
44207
  normalizeMessageParts: () => normalizeMessageParts,
44208
+ normalizeSessionModalFields: () => normalizeSessionModalFields,
43815
44209
  parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
43816
44210
  partitionSessionHostDiagnosticsSessions: () => partitionSessionHostDiagnosticsSessions,
43817
44211
  partitionSessionHostRecords: () => partitionSessionHostRecords,
44212
+ prepareSessionChatTailUpdate: () => prepareSessionChatTailUpdate,
44213
+ prepareSessionModalUpdate: () => prepareSessionModalUpdate,
43818
44214
  probeCdpPort: () => probeCdpPort,
43819
44215
  readChatHistory: () => readChatHistory,
43820
44216
  recordDebugTrace: () => recordDebugTrace,
@@ -43870,6 +44266,8 @@ var init_src = __esm({
43870
44266
  init_launch();
43871
44267
  init_ipc_protocol();
43872
44268
  init_chat_history();
44269
+ init_chat_signatures();
44270
+ init_subscription_updates();
43873
44271
  init_agent_stream();
43874
44272
  init_agent_stream();
43875
44273
  init_forward();
@@ -44345,15 +44743,7 @@ function routeDataChannelMessage(peerId, msg, peers, handlers) {
44345
44743
  return;
44346
44744
  }
44347
44745
  if (parsed.type === "pty_resize") {
44348
- const permission = peers.get(peerId)?.sharePermission;
44349
- if (permission) {
44350
- log(`pty_resize: REJECTED \u2014 permission=${permission} peer=${peerId}`);
44351
- return;
44352
- }
44353
- const sessionId = parsed.sessionId || parsed.targetSessionId || parsed.cliId || parsed.cliType || "";
44354
- if (handlers.ptyResizeHandler && parsed.cols && parsed.rows && sessionId) {
44355
- handlers.ptyResizeHandler(sessionId, parsed.cols, parsed.rows);
44356
- }
44746
+ logDebug(`pty_resize ignored: peer=${peerId} reason=temporarily_disabled`);
44357
44747
  return;
44358
44748
  }
44359
44749
  handleFileRequest(peerId, parsed, peers, handlers);
@@ -53041,48 +53431,6 @@ __export(adhdev_daemon_exports, {
53041
53431
  isDaemonRunning: () => isDaemonRunning,
53042
53432
  stopDaemon: () => stopDaemon
53043
53433
  });
53044
- function hashSignatureParts2(parts) {
53045
- let hash2 = 2166136261;
53046
- for (const part of parts) {
53047
- const text = String(part || "");
53048
- for (let i = 0; i < text.length; i += 1) {
53049
- hash2 ^= text.charCodeAt(i);
53050
- hash2 = Math.imul(hash2, 16777619) >>> 0;
53051
- }
53052
- hash2 ^= 255;
53053
- hash2 = Math.imul(hash2, 16777619) >>> 0;
53054
- }
53055
- return hash2.toString(16).padStart(8, "0");
53056
- }
53057
- function buildChatTailDeliverySignature(payload) {
53058
- let messages = "";
53059
- try {
53060
- messages = JSON.stringify(payload.messages);
53061
- } catch {
53062
- messages = String(payload.messages.length);
53063
- }
53064
- return hashSignatureParts2([
53065
- payload.sessionId,
53066
- payload.historySessionId || "",
53067
- payload.status,
53068
- payload.title || "",
53069
- payload.syncMode,
53070
- String(payload.replaceFrom),
53071
- String(payload.totalMessages),
53072
- payload.lastMessageSignature,
53073
- payload.activeModal ? `${payload.activeModal.message}|${payload.activeModal.buttons.join("")}` : "",
53074
- messages
53075
- ]);
53076
- }
53077
- function buildSessionModalDeliverySignature(payload) {
53078
- return hashSignatureParts2([
53079
- payload.sessionId,
53080
- payload.status,
53081
- payload.title || "",
53082
- payload.modalMessage || "",
53083
- Array.isArray(payload.modalButtons) ? payload.modalButtons.join("") : ""
53084
- ]);
53085
- }
53086
53434
  function resolveDaemonPort(ref = {}) {
53087
53435
  return Number.isFinite(ref.port) && Number(ref.port) > 0 ? Number(ref.port) : DEFAULT_DAEMON_PORT;
53088
53436
  }
@@ -53215,7 +53563,7 @@ var init_adhdev_daemon = __esm({
53215
53563
  init_source2();
53216
53564
  init_version();
53217
53565
  init_src();
53218
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.71" });
53566
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.74" });
53219
53567
  AdhdevDaemon = class _AdhdevDaemon {
53220
53568
  localHttpServer = null;
53221
53569
  localWss = null;
@@ -53286,9 +53634,6 @@ var init_adhdev_daemon = __esm({
53286
53634
  const mode = instance.getPresentationMode?.();
53287
53635
  return mode === "chat" || mode === "terminal" ? mode : null;
53288
53636
  }
53289
- isTerminalCliSession(sessionId) {
53290
- return this.getCliPresentationMode(sessionId) === "terminal";
53291
- }
53292
53637
  isCliSession(sessionId) {
53293
53638
  const mode = this.getCliPresentationMode(sessionId);
53294
53639
  return mode === "chat" || mode === "terminal";
@@ -53356,44 +53701,24 @@ var init_adhdev_daemon = __esm({
53356
53701
  lastMessageSignature: subscription.cursor.lastMessageSignature,
53357
53702
  ...subscription.cursor.tailLimit > 0 ? { tailLimit: subscription.cursor.tailLimit } : {}
53358
53703
  }, "p2p");
53359
- if (!result?.success || result.syncMode === "noop") {
53360
- if (result?.success) {
53361
- subscription.cursor = {
53362
- knownMessageCount: Math.max(0, Number(result.totalMessages || subscription.cursor.knownMessageCount)),
53363
- lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : subscription.cursor.lastMessageSignature,
53364
- tailLimit: subscription.cursor.tailLimit
53365
- };
53366
- }
53367
- return null;
53368
- }
53369
- subscription.seq += 1;
53370
- const syncMode = result.syncMode === "append" || result.syncMode === "replace_tail" || result.syncMode === "noop" || result.syncMode === "full" ? result.syncMode : "full";
53371
- subscription.cursor = {
53372
- knownMessageCount: Math.max(0, Number(result.totalMessages || 0)),
53373
- lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : "",
53374
- tailLimit: subscription.cursor.tailLimit
53375
- };
53376
- const activeModal = result.activeModal && typeof result.activeModal === "object" && typeof result.activeModal.message === "string" && Array.isArray(result.activeModal.buttons) ? {
53377
- message: result.activeModal.message,
53378
- buttons: result.activeModal.buttons.filter((button) => typeof button === "string")
53379
- } : null;
53380
- const deliverySignature = buildChatTailDeliverySignature({
53704
+ const interactionId = this.getSessionInteractionId(subscription.params.targetSessionId);
53705
+ const prepared = prepareSessionChatTailUpdate({
53706
+ key: subscription.key,
53381
53707
  sessionId: subscription.params.targetSessionId,
53382
53708
  ...subscription.params.historySessionId ? { historySessionId: subscription.params.historySessionId } : {},
53383
- messages: Array.isArray(result.messages) ? result.messages : [],
53384
- status: typeof result.status === "string" ? result.status : "idle",
53385
- ...typeof result.title === "string" ? { title: result.title } : {},
53386
- ...activeModal ? { activeModal } : {},
53387
- syncMode,
53388
- replaceFrom: Number(result.replaceFrom || 0),
53389
- totalMessages: Number(result.totalMessages || 0),
53390
- lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
53709
+ seq: subscription.seq,
53710
+ timestamp: Date.now(),
53711
+ ...interactionId ? { interactionId } : {},
53712
+ cursor: subscription.cursor,
53713
+ lastDeliveredSignature: subscription.lastDeliveredSignature,
53714
+ result
53391
53715
  });
53392
- if (deliverySignature === subscription.lastDeliveredSignature) {
53716
+ subscription.cursor = prepared.cursor;
53717
+ subscription.seq = prepared.seq;
53718
+ subscription.lastDeliveredSignature = prepared.lastDeliveredSignature;
53719
+ if (!prepared.update) {
53393
53720
  return null;
53394
53721
  }
53395
- subscription.lastDeliveredSignature = deliverySignature;
53396
- const interactionId = this.getSessionInteractionId(subscription.params.targetSessionId);
53397
53722
  recordDebugTrace({
53398
53723
  interactionId,
53399
53724
  category: "topic",
@@ -53401,30 +53726,14 @@ var init_adhdev_daemon = __esm({
53401
53726
  level: "info",
53402
53727
  sessionId: subscription.params.targetSessionId,
53403
53728
  payload: {
53404
- syncMode,
53405
- totalMessages: Number(result.totalMessages || 0),
53406
- replaceFrom: Number(result.replaceFrom || 0),
53407
- hasModal: !!activeModal,
53408
- hasTitle: typeof result.title === "string"
53729
+ syncMode: prepared.update.syncMode,
53730
+ totalMessages: prepared.update.totalMessages,
53731
+ replaceFrom: prepared.update.replaceFrom,
53732
+ hasModal: !!prepared.update.activeModal,
53733
+ hasTitle: typeof prepared.update.title === "string"
53409
53734
  }
53410
53735
  });
53411
- return {
53412
- topic: "session.chat_tail",
53413
- key: subscription.key,
53414
- sessionId: subscription.params.targetSessionId,
53415
- ...subscription.params.historySessionId ? { historySessionId: subscription.params.historySessionId } : {},
53416
- ...interactionId ? { interactionId } : {},
53417
- seq: subscription.seq,
53418
- timestamp: Date.now(),
53419
- messages: Array.isArray(result.messages) ? result.messages : [],
53420
- status: typeof result.status === "string" ? result.status : "idle",
53421
- ...typeof result.title === "string" ? { title: result.title } : {},
53422
- ...activeModal ? { activeModal } : {},
53423
- syncMode,
53424
- replaceFrom: Number(result.replaceFrom || 0),
53425
- totalMessages: Number(result.totalMessages || 0),
53426
- lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
53427
- };
53736
+ return prepared.update;
53428
53737
  }
53429
53738
  buildLiveStatusSnapshot() {
53430
53739
  return buildStatusSnapshot({
@@ -53540,24 +53849,26 @@ var init_adhdev_daemon = __esm({
53540
53849
  if (!state) return null;
53541
53850
  const now = Date.now();
53542
53851
  const activeModal = state.activeChat?.activeModal;
53543
- const modalButtons = Array.isArray(activeModal?.buttons) ? activeModal.buttons.filter((button) => typeof button === "string") : [];
53544
53852
  const status = String(state.activeChat?.status || state.status || "idle");
53545
53853
  const title = typeof state.activeChat?.title === "string" ? state.activeChat.title : void 0;
53546
- const modalMessage = typeof activeModal?.message === "string" ? activeModal.message : void 0;
53547
- const deliverySignature = buildSessionModalDeliverySignature({
53854
+ const interactionId = this.getSessionInteractionId(subscription.params.targetSessionId);
53855
+ const prepared = prepareSessionModalUpdate({
53856
+ key: subscription.key,
53548
53857
  sessionId: subscription.params.targetSessionId,
53549
53858
  status,
53550
- ...title ? { title } : {},
53551
- ...modalMessage ? { modalMessage } : {},
53552
- ...modalButtons.length > 0 ? { modalButtons } : {}
53859
+ title,
53860
+ activeModal,
53861
+ seq: subscription.seq,
53862
+ timestamp: now,
53863
+ ...interactionId ? { interactionId } : {},
53864
+ lastDeliveredSignature: subscription.lastDeliveredSignature
53553
53865
  });
53554
- if (deliverySignature === subscription.lastDeliveredSignature) {
53866
+ subscription.seq = prepared.seq;
53867
+ subscription.lastDeliveredSignature = prepared.lastDeliveredSignature;
53868
+ if (!prepared.update) {
53555
53869
  return null;
53556
53870
  }
53557
- subscription.lastDeliveredSignature = deliverySignature;
53558
- subscription.seq += 1;
53559
53871
  subscription.lastSentAt = now;
53560
- const interactionId = this.getSessionInteractionId(subscription.params.targetSessionId);
53561
53872
  recordDebugTrace({
53562
53873
  interactionId,
53563
53874
  category: "topic",
@@ -53566,23 +53877,12 @@ var init_adhdev_daemon = __esm({
53566
53877
  sessionId: subscription.params.targetSessionId,
53567
53878
  payload: {
53568
53879
  status,
53569
- hasTitle: !!title,
53570
- modalMessage: modalMessage ? modalMessage.slice(0, 140) : void 0,
53571
- modalButtonCount: modalButtons.length
53880
+ hasTitle: !!prepared.update.title,
53881
+ modalMessage: prepared.update.modalMessage ? prepared.update.modalMessage.slice(0, 140) : void 0,
53882
+ modalButtonCount: prepared.update.modalButtons?.length || 0
53572
53883
  }
53573
53884
  });
53574
- return {
53575
- topic: "session.modal",
53576
- key: subscription.key,
53577
- sessionId: subscription.params.targetSessionId,
53578
- status,
53579
- ...title ? { title } : {},
53580
- ...modalMessage ? { modalMessage } : {},
53581
- ...modalButtons.length > 0 ? { modalButtons } : {},
53582
- ...interactionId ? { interactionId } : {},
53583
- seq: subscription.seq,
53584
- timestamp: now
53585
- };
53885
+ return prepared.update;
53586
53886
  }
53587
53887
  async flushP2PSessionModalSubscriptions() {
53588
53888
  if (!this.p2p?.isConnected || !this.p2p.hasSessionModalSubscriptions()) return;
@@ -53771,14 +54071,14 @@ ${err?.stack || ""}`);
53771
54071
  }
53772
54072
  });
53773
54073
  this.p2p.onPtyInput((sessionId, data) => {
53774
- if (!this.isTerminalCliSession(sessionId)) return;
54074
+ if (!this.isCliSession(sessionId)) return;
53775
54075
  const found = this.components.cliManager.findAdapter(sessionId, { instanceKey: sessionId });
53776
54076
  if (found && typeof found.adapter.writeRaw === "function") {
53777
54077
  found.adapter.writeRaw(data);
53778
54078
  }
53779
54079
  });
53780
54080
  this.p2p.onPtyResize((sessionId, cols, rows) => {
53781
- if (!this.isTerminalCliSession(sessionId)) return;
54081
+ if (!this.isCliSession(sessionId)) return;
53782
54082
  const found = this.components.cliManager.findAdapter(sessionId, { instanceKey: sessionId });
53783
54083
  if (found && typeof found.adapter.resize === "function") {
53784
54084
  found.adapter.resize(cols, rows);