adhdev 0.8.63 → 0.8.66

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
@@ -1494,6 +1494,51 @@ var init_host_memory = __esm({
1494
1494
  }
1495
1495
  });
1496
1496
 
1497
+ // ../../oss/packages/daemon-core/src/status/chat-tail-hot-sessions.ts
1498
+ function parseMessageTimestamp(value) {
1499
+ if (typeof value === "number" && Number.isFinite(value)) return value;
1500
+ if (typeof value === "string") {
1501
+ const parsed = Date.parse(value);
1502
+ if (Number.isFinite(parsed)) return parsed;
1503
+ }
1504
+ return 0;
1505
+ }
1506
+ function classifyHotChatSessionsForSubscriptionFlush(sessions, previousHotSessionIds, options = {}) {
1507
+ const now = options.now ?? Date.now();
1508
+ const recentMessageGraceMs = Math.max(
1509
+ 0,
1510
+ Number.isFinite(options.recentMessageGraceMs) ? Number(options.recentMessageGraceMs) : DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS
1511
+ );
1512
+ const activeStatuses = options.activeStatuses ?? DEFAULT_ACTIVE_CHAT_POLL_STATUSES;
1513
+ const active = /* @__PURE__ */ new Set();
1514
+ for (const session of sessions) {
1515
+ const sessionId = typeof session?.id === "string" ? session.id : "";
1516
+ if (!sessionId) continue;
1517
+ const status = String(session?.status || "").toLowerCase();
1518
+ const lastMessageAt = parseMessageTimestamp(session?.lastMessageAt);
1519
+ const recentlyUpdated = lastMessageAt > 0 && now - lastMessageAt <= recentMessageGraceMs;
1520
+ if (activeStatuses.has(status) || recentlyUpdated) {
1521
+ active.add(sessionId);
1522
+ }
1523
+ }
1524
+ const finalizing = new Set(
1525
+ Array.from(previousHotSessionIds).filter((sessionId) => !active.has(sessionId))
1526
+ );
1527
+ return { active, finalizing };
1528
+ }
1529
+ var DEFAULT_ACTIVE_CHAT_POLL_STATUSES, DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS;
1530
+ var init_chat_tail_hot_sessions = __esm({
1531
+ "../../oss/packages/daemon-core/src/status/chat-tail-hot-sessions.ts"() {
1532
+ "use strict";
1533
+ DEFAULT_ACTIVE_CHAT_POLL_STATUSES = /* @__PURE__ */ new Set([
1534
+ "generating",
1535
+ "waiting_approval",
1536
+ "starting"
1537
+ ]);
1538
+ DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS = 8e3;
1539
+ }
1540
+ });
1541
+
1497
1542
  // ../../oss/packages/daemon-core/src/logging/logger.ts
1498
1543
  function setLogLevel(level) {
1499
1544
  currentLevel = level;
@@ -3359,19 +3404,75 @@ var init_status_monitor = __esm({
3359
3404
  });
3360
3405
 
3361
3406
  // ../../oss/packages/daemon-core/src/providers/chat-message-normalization.ts
3407
+ function canonicalizeKindHint(value) {
3408
+ return value.trim().toLowerCase().replace(/[\s-]+/g, "_");
3409
+ }
3410
+ function resolveBuiltinOrAliasKind(kind) {
3411
+ if (typeof kind !== "string") return null;
3412
+ const normalizedKind = canonicalizeKindHint(kind);
3413
+ if (!normalizedKind) return null;
3414
+ if (KNOWN_CHAT_MESSAGE_KINDS.has(normalizedKind)) return normalizedKind;
3415
+ return CHAT_MESSAGE_KIND_ALIASES[normalizedKind] || null;
3416
+ }
3417
+ function inferHintKind(value) {
3418
+ const direct = resolveBuiltinOrAliasKind(value);
3419
+ if (direct) return direct;
3420
+ if (typeof value !== "string") return null;
3421
+ const normalized = canonicalizeKindHint(value);
3422
+ if (!normalized) return null;
3423
+ if (/thought|thinking|reasoning/.test(normalized)) return "thought";
3424
+ if (/tool/.test(normalized)) return "tool";
3425
+ if (/terminal|command|shell|console/.test(normalized)) return "terminal";
3426
+ return null;
3427
+ }
3428
+ function inferKindFromToolCalls(message) {
3429
+ const toolCalls = Array.isArray(message?.toolCalls) ? message.toolCalls : [];
3430
+ if (toolCalls.length === 0) return null;
3431
+ if (toolCalls.some((toolCall) => toolCall?.kind === "think")) return "thought";
3432
+ if (toolCalls.some((toolCall) => toolCall?.kind === "execute")) return "terminal";
3433
+ if (toolCalls.some((toolCall) => Array.isArray(toolCall?.content) && toolCall.content.some((entry) => entry?.type === "terminal"))) {
3434
+ return "terminal";
3435
+ }
3436
+ return "tool";
3437
+ }
3438
+ function inferMissingChatMessageKind(message) {
3439
+ const role = typeof message?.role === "string" ? message.role.trim().toLowerCase() : "";
3440
+ if (role === "system") return "system";
3441
+ const meta3 = message?.meta && typeof message.meta === "object" ? message.meta : void 0;
3442
+ const hintCandidates = [
3443
+ message?._sub,
3444
+ message?._type,
3445
+ meta3?.label,
3446
+ typeof message?.senderName === "string" ? message.senderName : void 0
3447
+ ];
3448
+ for (const candidate of hintCandidates) {
3449
+ const inferred = inferHintKind(candidate);
3450
+ if (inferred) return inferred;
3451
+ }
3452
+ const inferredFromToolCalls = inferKindFromToolCalls(message);
3453
+ if (inferredFromToolCalls) return inferredFromToolCalls;
3454
+ return null;
3455
+ }
3362
3456
  function isBuiltinChatMessageKind(kind) {
3363
- return typeof kind === "string" && KNOWN_CHAT_MESSAGE_KINDS.has(kind.trim().toLowerCase());
3457
+ return resolveBuiltinOrAliasKind(kind) !== null;
3364
3458
  }
3365
3459
  function normalizeChatMessageKind(kind, role) {
3366
- const normalizedKind = typeof kind === "string" ? kind.trim().toLowerCase() : "";
3367
- if (normalizedKind && KNOWN_CHAT_MESSAGE_KINDS.has(normalizedKind)) return normalizedKind;
3460
+ const resolvedKind = resolveBuiltinOrAliasKind(kind);
3461
+ if (resolvedKind) return resolvedKind;
3368
3462
  const normalizedRole = typeof role === "string" ? role.trim().toLowerCase() : "";
3369
3463
  return normalizedRole === "system" ? "system" : "standard";
3370
3464
  }
3465
+ function resolveChatMessageKind(message) {
3466
+ const explicitKind = resolveBuiltinOrAliasKind(message?.kind);
3467
+ if (explicitKind) return explicitKind;
3468
+ const inferredKind = inferMissingChatMessageKind(message);
3469
+ if (inferredKind) return inferredKind;
3470
+ return normalizeChatMessageKind(message?.kind, message?.role);
3471
+ }
3371
3472
  function buildChatMessage(message) {
3372
3473
  return {
3373
3474
  ...message,
3374
- kind: normalizeChatMessageKind(message?.kind, message?.role)
3475
+ kind: resolveChatMessageKind(message)
3375
3476
  };
3376
3477
  }
3377
3478
  function buildSystemChatMessage(message) {
@@ -3394,6 +3495,24 @@ function buildAssistantChatMessage(message) {
3394
3495
  kind: message?.kind || "standard"
3395
3496
  });
3396
3497
  }
3498
+ function buildThoughtChatMessage(message) {
3499
+ return buildAssistantChatMessage({
3500
+ ...message,
3501
+ kind: message?.kind || "thought"
3502
+ });
3503
+ }
3504
+ function buildToolChatMessage(message) {
3505
+ return buildAssistantChatMessage({
3506
+ ...message,
3507
+ kind: message?.kind || "tool"
3508
+ });
3509
+ }
3510
+ function buildTerminalChatMessage(message) {
3511
+ return buildAssistantChatMessage({
3512
+ ...message,
3513
+ kind: message?.kind || "terminal"
3514
+ });
3515
+ }
3397
3516
  function buildUserChatMessage(message) {
3398
3517
  return buildChatMessage({
3399
3518
  ...message,
@@ -3407,12 +3526,30 @@ function normalizeChatMessage(message) {
3407
3526
  function normalizeChatMessages(messages) {
3408
3527
  return (Array.isArray(messages) ? messages : []).map((message) => normalizeChatMessage(message));
3409
3528
  }
3410
- var BUILTIN_CHAT_MESSAGE_KINDS, KNOWN_CHAT_MESSAGE_KINDS;
3529
+ var BUILTIN_CHAT_MESSAGE_KINDS, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES;
3411
3530
  var init_chat_message_normalization = __esm({
3412
3531
  "../../oss/packages/daemon-core/src/providers/chat-message-normalization.ts"() {
3413
3532
  "use strict";
3414
3533
  BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
3415
3534
  KNOWN_CHAT_MESSAGE_KINDS = new Set(BUILTIN_CHAT_MESSAGE_KINDS);
3535
+ CHAT_MESSAGE_KIND_ALIASES = {
3536
+ text: "standard",
3537
+ message: "standard",
3538
+ assistant: "standard",
3539
+ thinking: "thought",
3540
+ think: "thought",
3541
+ reasoning: "thought",
3542
+ reason: "thought",
3543
+ toolcall: "tool",
3544
+ tool_call: "tool",
3545
+ tooluse: "tool",
3546
+ tool_use: "tool",
3547
+ action: "tool",
3548
+ command: "terminal",
3549
+ cmd: "terminal",
3550
+ shell: "terminal",
3551
+ console: "terminal"
3552
+ };
3416
3553
  }
3417
3554
  });
3418
3555
 
@@ -3537,38 +3674,37 @@ function buildPersistedProviderEffectMessage(effect) {
3537
3674
  return null;
3538
3675
  }
3539
3676
  function normalizeControlListResult(data) {
3540
- if (data && typeof data === "object" && Array.isArray(data.options)) {
3541
- return {
3542
- options: normalizeControlOptions(data.options),
3543
- ...isScalarControlValue(data.currentValue) ? { currentValue: data.currentValue } : {},
3544
- ...typeof data.error === "string" ? { error: data.error } : {}
3545
- };
3677
+ if (!data || typeof data !== "object" || !Array.isArray(data.options)) {
3678
+ throw new Error("Provider control list results must use the typed shape { options, currentValue?, error? }");
3546
3679
  }
3547
- const rawOptions = Array.isArray(data?.models) ? data.models : Array.isArray(data?.modes) ? data.modes : Array.isArray(data?.options) ? data.options : [];
3548
- const options = normalizeControlOptions(rawOptions);
3549
3680
  return {
3550
- options,
3551
- ...isScalarControlValue(data?.current) ? { currentValue: data.current } : {},
3552
- ...isScalarControlValue(data?.currentValue) ? { currentValue: data.currentValue } : {},
3553
- ...typeof data?.error === "string" ? { error: data.error } : {}
3681
+ options: normalizeControlOptions(data.options),
3682
+ ...isScalarControlValue(data.currentValue) ? { currentValue: data.currentValue } : {},
3683
+ ...typeof data.error === "string" ? { error: data.error } : {}
3554
3684
  };
3555
3685
  }
3556
3686
  function normalizeControlSetResult(data) {
3557
- const currentValue = isScalarControlValue(data?.currentValue) ? data.currentValue : isScalarControlValue(data?.value) ? data.value : void 0;
3687
+ if (!data || typeof data !== "object" || typeof data.ok !== "boolean") {
3688
+ throw new Error("Provider control set results must use the typed shape { ok, currentValue?, effects?, error? }");
3689
+ }
3690
+ const currentValue = isScalarControlValue(data.currentValue) ? data.currentValue : isScalarControlValue(data.value) ? data.value : void 0;
3558
3691
  return {
3559
- ok: data?.ok === true || data?.success === true,
3692
+ ok: data.ok,
3560
3693
  ...currentValue !== void 0 ? { currentValue } : {},
3561
- ...Array.isArray(data?.effects) ? { effects: normalizeProviderEffects(data) } : {},
3562
- ...typeof data?.error === "string" ? { error: data.error } : {}
3694
+ ...Array.isArray(data.effects) ? { effects: normalizeProviderEffects(data) } : {},
3695
+ ...typeof data.error === "string" ? { error: data.error } : {}
3563
3696
  };
3564
3697
  }
3565
3698
  function normalizeControlInvokeResult(data) {
3566
- const currentValue = isScalarControlValue(data?.currentValue) ? data.currentValue : isScalarControlValue(data?.value) ? data.value : void 0;
3699
+ if (!data || typeof data !== "object" || typeof data.ok !== "boolean") {
3700
+ throw new Error("Provider control invoke results must use the typed shape { ok, currentValue?, effects?, error? }");
3701
+ }
3702
+ const currentValue = isScalarControlValue(data.currentValue) ? data.currentValue : isScalarControlValue(data.value) ? data.value : void 0;
3567
3703
  return {
3568
- ok: data?.ok === true || data?.success === true,
3704
+ ok: data.ok,
3569
3705
  ...currentValue !== void 0 ? { currentValue } : {},
3570
- ...Array.isArray(data?.effects) ? { effects: normalizeProviderEffects(data) } : {},
3571
- ...typeof data?.error === "string" ? { error: data.error } : {}
3706
+ ...Array.isArray(data.effects) ? { effects: normalizeProviderEffects(data) } : {},
3707
+ ...typeof data.error === "string" ? { error: data.error } : {}
3572
3708
  };
3573
3709
  }
3574
3710
  function normalizeControlOptions(options) {
@@ -4488,19 +4624,37 @@ var init_extension_provider_instance = __esm({
4488
4624
  );
4489
4625
  }
4490
4626
  }
4627
+ buildSyntheticTurnKey(message, occurrence) {
4628
+ const role = typeof message?.role === "string" ? message.role : "";
4629
+ const kind = typeof message?.kind === "string" ? message.kind : "";
4630
+ const senderName = typeof message?.senderName === "string" ? message.senderName : "";
4631
+ const content = flattenContent(message?.content).replace(/\s+/g, " ").trim().slice(0, 500);
4632
+ return `${role}|${kind}|${senderName}|${content}|${occurrence}`;
4633
+ }
4491
4634
  /**
4492
- * Assign stable receivedAt to extension messages.
4493
- * Same pattern as IdeProviderInstance.readChat() prevByHash
4494
- * preserves first-seen timestamp across polling cycles.
4635
+ * Assign stable receivedAt / synthetic _turnKey to extension messages.
4636
+ * Same transcript should keep the same identity across polling cycles and
4637
+ * stream resets, while repeated identical text later in the transcript still
4638
+ * produces a distinct completion marker via the occurrence suffix.
4495
4639
  */
4496
4640
  assignReceivedAt(messages) {
4497
4641
  const now = Date.now();
4498
4642
  const nextHashes = /* @__PURE__ */ new Map();
4643
+ const occurrenceByBaseKey = /* @__PURE__ */ new Map();
4499
4644
  for (const msg of messages) {
4500
- const hash2 = `${msg.role}:${(msg.content || "").slice(0, 100)}`;
4501
- const prevTime = this.prevMessageHashes.get(hash2);
4645
+ const explicitTurnKey = typeof msg?._turnKey === "string" && msg._turnKey.trim() ? msg._turnKey.trim() : "";
4646
+ const explicitId = typeof msg?.id === "string" && msg.id.trim() ? `id:${msg.id.trim()}` : "";
4647
+ const explicitIndex = typeof msg?.index === "number" && Number.isFinite(msg.index) ? `idx:${msg.index}` : "";
4648
+ const baseKey = explicitTurnKey || explicitId || explicitIndex || `${msg?.role || ""}:${flattenContent(msg?.content || "").slice(0, 500)}`;
4649
+ const occurrence = (occurrenceByBaseKey.get(baseKey) || 0) + 1;
4650
+ occurrenceByBaseKey.set(baseKey, occurrence);
4651
+ const syntheticTurnKey = explicitTurnKey || explicitId || explicitIndex || this.buildSyntheticTurnKey(msg, occurrence);
4652
+ if (!explicitTurnKey && !explicitId && !explicitIndex) {
4653
+ msg._turnKey = syntheticTurnKey;
4654
+ }
4655
+ const prevTime = this.prevMessageHashes.get(syntheticTurnKey);
4502
4656
  msg.receivedAt = prevTime || now;
4503
- nextHashes.set(hash2, msg.receivedAt);
4657
+ nextHashes.set(syntheticTurnKey, msg.receivedAt);
4504
4658
  }
4505
4659
  this.prevMessageHashes = nextHashes;
4506
4660
  return normalizeChatMessages(messages);
@@ -4577,6 +4731,128 @@ ${effect.notification.body || ""}`.trim();
4577
4731
  }
4578
4732
  });
4579
4733
 
4734
+ // ../../oss/packages/daemon-core/src/providers/read-chat-contract.ts
4735
+ function isPlainObject3(value) {
4736
+ return !!value && typeof value === "object" && !Array.isArray(value);
4737
+ }
4738
+ function isFiniteNumber(value) {
4739
+ return typeof value === "number" && Number.isFinite(value);
4740
+ }
4741
+ function validateStatus(status, source) {
4742
+ if (typeof status !== "string" || !VALID_STATUSES.includes(status)) {
4743
+ throw new Error(`${source}: status must be one of ${VALID_STATUSES.join(", ")}`);
4744
+ }
4745
+ return status;
4746
+ }
4747
+ function validateRole(role, source, index) {
4748
+ if (typeof role !== "string" || !VALID_ROLES.includes(role)) {
4749
+ throw new Error(`${source}: messages[${index}].role must be one of ${VALID_ROLES.join(", ")}`);
4750
+ }
4751
+ return role;
4752
+ }
4753
+ function validateMessageContent(content, source, index) {
4754
+ if (typeof content === "string") return content;
4755
+ if (Array.isArray(content)) return normalizeMessageParts(content);
4756
+ throw new Error(`${source}: messages[${index}].content must be a string or structured content array`);
4757
+ }
4758
+ function validateMessage(message, source, index) {
4759
+ if (!isPlainObject3(message)) {
4760
+ throw new Error(`${source}: messages[${index}] must be an object`);
4761
+ }
4762
+ const normalized = {
4763
+ role: validateRole(message.role, source, index),
4764
+ content: validateMessageContent(message.content, source, index)
4765
+ };
4766
+ if (typeof message.kind === "string") normalized.kind = message.kind;
4767
+ if (typeof message.id === "string") normalized.id = message.id;
4768
+ if (isFiniteNumber(message.index)) normalized.index = message.index;
4769
+ if (isFiniteNumber(message.timestamp)) normalized.timestamp = message.timestamp;
4770
+ if (isFiniteNumber(message.receivedAt)) normalized.receivedAt = message.receivedAt;
4771
+ if (Array.isArray(message.toolCalls)) normalized.toolCalls = message.toolCalls;
4772
+ if (isPlainObject3(message.meta)) normalized.meta = message.meta;
4773
+ if (typeof message.senderName === "string") normalized.senderName = message.senderName;
4774
+ if (typeof message._type === "string") normalized._type = message._type;
4775
+ if (typeof message._sub === "string") normalized._sub = message._sub;
4776
+ return normalized;
4777
+ }
4778
+ function validateModal(activeModal, status, source) {
4779
+ if (activeModal == null) {
4780
+ if (status === "waiting_approval") {
4781
+ throw new Error(`${source}: waiting_approval status requires activeModal with buttons`);
4782
+ }
4783
+ return activeModal === null ? null : void 0;
4784
+ }
4785
+ if (!isPlainObject3(activeModal)) {
4786
+ throw new Error(`${source}: activeModal must be an object when provided`);
4787
+ }
4788
+ if (typeof activeModal.message !== "string") {
4789
+ throw new Error(`${source}: activeModal.message must be a string`);
4790
+ }
4791
+ if (!Array.isArray(activeModal.buttons) || activeModal.buttons.some((button) => typeof button !== "string" || !button.trim())) {
4792
+ throw new Error(`${source}: activeModal.buttons must be a non-empty string array`);
4793
+ }
4794
+ const normalized = {
4795
+ message: activeModal.message,
4796
+ buttons: activeModal.buttons.map((button) => button.trim())
4797
+ };
4798
+ if (isFiniteNumber(activeModal.width)) normalized.width = activeModal.width;
4799
+ if (isFiniteNumber(activeModal.height)) normalized.height = activeModal.height;
4800
+ return normalized;
4801
+ }
4802
+ function validateControlValues(controlValues, source) {
4803
+ if (controlValues === void 0) return void 0;
4804
+ if (!isPlainObject3(controlValues)) {
4805
+ throw new Error(`${source}: controlValues must be an object when provided`);
4806
+ }
4807
+ const normalized = {};
4808
+ for (const [key, value] of Object.entries(controlValues)) {
4809
+ if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") {
4810
+ throw new Error(`${source}: controlValues.${key} must be string, number, or boolean`);
4811
+ }
4812
+ normalized[key] = value;
4813
+ }
4814
+ return normalized;
4815
+ }
4816
+ function validateReadChatResultPayload(raw, source = "read_chat") {
4817
+ if (!isPlainObject3(raw)) {
4818
+ throw new Error(`${source}: payload must be an object`);
4819
+ }
4820
+ const status = validateStatus(raw.status, source);
4821
+ if (!Array.isArray(raw.messages)) {
4822
+ throw new Error(`${source}: messages must be an array`);
4823
+ }
4824
+ const messages = raw.messages.map((message, index) => validateMessage(message, source, index));
4825
+ const activeModal = validateModal(raw.activeModal, status, source);
4826
+ const controlValues = validateControlValues(raw.controlValues, source);
4827
+ const normalized = {
4828
+ status,
4829
+ messages
4830
+ };
4831
+ if (activeModal !== void 0) normalized.activeModal = activeModal;
4832
+ if (typeof raw.id === "string") normalized.id = raw.id;
4833
+ if (typeof raw.title === "string") normalized.title = raw.title;
4834
+ if (typeof raw.agentType === "string") normalized.agentType = raw.agentType;
4835
+ if (typeof raw.agentName === "string") normalized.agentName = raw.agentName;
4836
+ if (typeof raw.extensionId === "string") normalized.extensionId = raw.extensionId;
4837
+ if (typeof raw.inputContent === "string") normalized.inputContent = raw.inputContent;
4838
+ if (typeof raw.isVisible === "boolean") normalized.isVisible = raw.isVisible;
4839
+ if (typeof raw.isWelcomeScreen === "boolean") normalized.isWelcomeScreen = raw.isWelcomeScreen;
4840
+ if (controlValues) normalized.controlValues = controlValues;
4841
+ if (raw.summaryMetadata !== void 0) normalized.summaryMetadata = raw.summaryMetadata;
4842
+ if (Array.isArray(raw.effects)) normalized.effects = raw.effects;
4843
+ if (typeof raw.providerSessionId === "string") normalized.providerSessionId = raw.providerSessionId;
4844
+ return normalized;
4845
+ }
4846
+ var VALID_STATUSES, VALID_ROLES;
4847
+ var init_read_chat_contract = __esm({
4848
+ "../../oss/packages/daemon-core/src/providers/read-chat-contract.ts"() {
4849
+ "use strict";
4850
+ init_contracts();
4851
+ VALID_STATUSES = ["idle", "generating", "waiting_approval", "error", "panel_hidden", "streaming", "long_generating"];
4852
+ VALID_ROLES = ["user", "assistant", "system", "human"];
4853
+ }
4854
+ });
4855
+
4580
4856
  // ../../oss/packages/daemon-core/src/providers/approval-utils.ts
4581
4857
  function normalizeApprovalLabel(value) {
4582
4858
  return String(value || "").toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
@@ -4642,6 +4918,7 @@ var init_ide_provider_instance = __esm({
4642
4918
  init_chat_history();
4643
4919
  init_logger();
4644
4920
  init_control_effects();
4921
+ init_read_chat_contract();
4645
4922
  init_approval_utils();
4646
4923
  init_provider_patch_state();
4647
4924
  init_chat_message_normalization();
@@ -4876,7 +5153,7 @@ var init_ide_provider_instance = __esm({
4876
5153
  }
4877
5154
  }
4878
5155
  if (!raw || typeof raw !== "object") return;
4879
- const chat = raw;
5156
+ const chat = validateReadChatResultPayload(raw, `${this.type} readChat`);
4880
5157
  let { activeModal } = chat;
4881
5158
  if (activeModal) {
4882
5159
  const w = activeModal.width ?? Infinity;
@@ -4897,11 +5174,13 @@ var init_ide_provider_instance = __esm({
4897
5174
  if (pm.receivedAt) prevByHash.set(h, pm.receivedAt);
4898
5175
  }
4899
5176
  const now = Date.now();
4900
- const messages = chat.messages || [];
4901
- for (const msg of messages) {
5177
+ const rawMessages = chat.messages || [];
5178
+ for (const msg of rawMessages) {
4902
5179
  const h = `${msg.role}:${(msg.content || "").slice(0, 100)}`;
4903
5180
  msg.receivedAt = prevByHash.get(h) || now;
4904
5181
  }
5182
+ chat.messages = normalizeChatMessages(rawMessages);
5183
+ const messages = chat.messages || [];
4905
5184
  if (messages.length > 0) {
4906
5185
  const hiddenKinds = /* @__PURE__ */ new Set();
4907
5186
  if (this.settings.showThinking === false) hiddenKinds.add("thought");
@@ -6061,6 +6340,67 @@ var init_reconcile = __esm({
6061
6340
  }
6062
6341
  });
6063
6342
 
6343
+ // ../../oss/packages/daemon-core/src/providers/provider-input-support.ts
6344
+ function getProviderLabel(provider) {
6345
+ return provider?.name || provider?.type || "This provider";
6346
+ }
6347
+ function hasNonEmptyFallbackText(input) {
6348
+ return typeof input.textFallback === "string" && input.textFallback.trim().length > 0;
6349
+ }
6350
+ function getRequestedInputMediaTypes(input) {
6351
+ const types = /* @__PURE__ */ new Set();
6352
+ if (hasNonEmptyFallbackText(input) && !input.parts.some((part) => part.type === "text")) {
6353
+ types.add("text");
6354
+ }
6355
+ for (const part of input.parts) {
6356
+ if (VALID_INPUT_MEDIA_TYPES.has(part.type)) {
6357
+ types.add(part.type);
6358
+ }
6359
+ }
6360
+ return Array.from(types);
6361
+ }
6362
+ function getEffectiveSemanticPartCount(input) {
6363
+ let count = input.parts.length;
6364
+ if (hasNonEmptyFallbackText(input) && !input.parts.some((part) => part.type === "text")) {
6365
+ count += 1;
6366
+ }
6367
+ return count;
6368
+ }
6369
+ function assertTextOnlyInput(provider, input) {
6370
+ const unsupported = getRequestedInputMediaTypes(input).filter((type) => type !== "text");
6371
+ if (unsupported.length === 0) return;
6372
+ const label = getProviderLabel(provider);
6373
+ const suffix = unsupported.length === 1 ? "" : "s";
6374
+ throw new Error(`${label} only supports text input; unsupported input type${suffix}: ${unsupported.join(", ")}`);
6375
+ }
6376
+ function getDeclaredProviderInputSupport(provider) {
6377
+ const rawMediaTypes = Array.isArray(provider?.capabilities?.input?.mediaTypes) ? provider?.capabilities?.input?.mediaTypes.filter((type) => VALID_INPUT_MEDIA_TYPES.has(type)) : [];
6378
+ return {
6379
+ multipart: provider?.capabilities?.input?.multipart === true,
6380
+ mediaTypes: new Set(rawMediaTypes.length > 0 ? rawMediaTypes : ["text"])
6381
+ };
6382
+ }
6383
+ function assertProviderSupportsDeclaredInput(provider, input) {
6384
+ const label = getProviderLabel(provider);
6385
+ const support = getDeclaredProviderInputSupport(provider);
6386
+ const requestedTypes = getRequestedInputMediaTypes(input);
6387
+ const unsupported = requestedTypes.filter((type) => !support.mediaTypes.has(type));
6388
+ if (unsupported.length > 0) {
6389
+ const suffix = unsupported.length === 1 ? "" : "s";
6390
+ throw new Error(`${label} does not support input type${suffix}: ${unsupported.join(", ")}`);
6391
+ }
6392
+ if (getEffectiveSemanticPartCount(input) > 1 && !support.multipart) {
6393
+ throw new Error(`${label} does not support multipart input`);
6394
+ }
6395
+ }
6396
+ var VALID_INPUT_MEDIA_TYPES;
6397
+ var init_provider_input_support = __esm({
6398
+ "../../oss/packages/daemon-core/src/providers/provider-input-support.ts"() {
6399
+ "use strict";
6400
+ VALID_INPUT_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
6401
+ }
6402
+ });
6403
+
6064
6404
  // ../../oss/packages/daemon-core/src/logging/debug-config.ts
6065
6405
  function normalizeCategories(categories) {
6066
6406
  if (!Array.isArray(categories)) return [];
@@ -6250,10 +6590,15 @@ function isCliLikeTransport(transport) {
6250
6590
  function isExtensionTransport(transport) {
6251
6591
  return transport === "cdp-webview";
6252
6592
  }
6253
- function buildRecentSendKey(h, args, provider, text) {
6593
+ function buildRecentSendKey(h, args, provider, signature) {
6254
6594
  const transport = getTargetTransport(h, provider) || "unknown";
6255
6595
  const target = args?.targetSessionId || args?.agentType || h.currentSession?.providerType || h.currentProviderType || h.currentManagerKey || "unknown";
6256
- return `${transport}:${target}:${text.trim()}`;
6596
+ return `${transport}:${target}:${signature.trim()}`;
6597
+ }
6598
+ function buildSendInputSignature(input) {
6599
+ const text = typeof input.textFallback === "string" ? input.textFallback.trim() : "";
6600
+ if (text) return text;
6601
+ return JSON.stringify(input.parts || []);
6257
6602
  }
6258
6603
  function getSendChatInputEnvelope(args) {
6259
6604
  return normalizeInputEnvelope(args?.input ? { input: args.input } : args);
@@ -6406,14 +6751,20 @@ function computeReadChatSync(messages, cursor) {
6406
6751
  };
6407
6752
  }
6408
6753
  function buildReadChatCommandResult(payload, args) {
6409
- const messages = normalizeReadChatMessages(payload);
6754
+ let validatedPayload;
6755
+ try {
6756
+ validatedPayload = validateReadChatResultPayload(payload, "read_chat command result");
6757
+ } catch (error48) {
6758
+ return { success: false, error: error48?.message || String(error48) };
6759
+ }
6760
+ const messages = normalizeReadChatMessages(validatedPayload);
6410
6761
  const cursor = normalizeReadChatCursor(args);
6411
6762
  if (!cursor.knownMessageCount && !cursor.lastMessageSignature && cursor.tailLimit > 0 && messages.length > cursor.tailLimit) {
6412
6763
  const tailMessages = messages.slice(-cursor.tailLimit);
6413
6764
  const lastMessageSignature = getChatMessageSignature(tailMessages[tailMessages.length - 1]);
6414
6765
  return {
6415
6766
  success: true,
6416
- ...payload,
6767
+ ...validatedPayload,
6417
6768
  messages: tailMessages,
6418
6769
  syncMode: "full",
6419
6770
  replaceFrom: 0,
@@ -6424,7 +6775,7 @@ function buildReadChatCommandResult(payload, args) {
6424
6775
  const sync = computeReadChatSync(messages, cursor);
6425
6776
  return {
6426
6777
  success: true,
6427
- ...payload,
6778
+ ...validatedPayload,
6428
6779
  messages: sync.messages,
6429
6780
  syncMode: sync.syncMode,
6430
6781
  replaceFrom: sync.replaceFrom,
@@ -6503,12 +6854,18 @@ async function handleReadChat(h, args) {
6503
6854
  const adapter = getTargetedCliAdapter(h, args, provider?.type);
6504
6855
  if (adapter) {
6505
6856
  _log(`${transport} adapter: ${adapter.cliType}`);
6506
- const status = adapter.getStatus();
6857
+ const parsedStatus = typeof adapter.getScriptParsedStatus === "function" ? parseMaybeJson(adapter.getScriptParsedStatus()) : null;
6858
+ const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
6859
+ const status = parsedRecord || adapter.getStatus();
6860
+ const title = typeof parsedRecord?.title === "string" ? parsedRecord.title : void 0;
6861
+ const providerSessionId = typeof parsedRecord?.providerSessionId === "string" ? parsedRecord.providerSessionId : void 0;
6507
6862
  if (status) {
6508
6863
  return buildReadChatCommandResult({
6509
6864
  messages: status.messages || [],
6510
6865
  status: status.status,
6511
- activeModal: status.activeModal
6866
+ activeModal: status.activeModal,
6867
+ ...title ? { title } : {},
6868
+ ...providerSessionId ? { providerSessionId } : {}
6512
6869
  }, args);
6513
6870
  }
6514
6871
  }
@@ -6526,25 +6883,26 @@ async function handleReadChat(h, args) {
6526
6883
  }
6527
6884
  }
6528
6885
  if (parsed && typeof parsed === "object") {
6529
- _log(`Extension OK: ${parsed.messages?.length || 0} msgs`);
6886
+ const validated = validateReadChatResultPayload(parsed, "extension read_chat");
6887
+ _log(`Extension OK: ${validated.messages?.length || 0} msgs`);
6530
6888
  traceProviderEvent(args, "provider", "extension.read_chat.success", {
6531
6889
  h,
6532
6890
  provider,
6533
6891
  payload: {
6534
6892
  method: "evaluateProviderScript",
6535
6893
  result: evalResult.result,
6536
- parsed,
6537
- messageCount: Array.isArray(parsed.messages) ? parsed.messages.length : 0
6894
+ parsed: validated,
6895
+ messageCount: Array.isArray(validated.messages) ? validated.messages.length : 0
6538
6896
  }
6539
6897
  });
6540
6898
  h.historyWriter.appendNewMessages(
6541
6899
  provider?.type || "unknown_extension",
6542
- toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
6543
- parsed.title,
6900
+ toHistoryPersistedMessages(normalizeReadChatMessages(validated)),
6901
+ validated.title,
6544
6902
  args?.targetSessionId,
6545
6903
  historySessionId
6546
6904
  );
6547
- return buildReadChatCommandResult(parsed, args);
6905
+ return buildReadChatCommandResult(validated, args);
6548
6906
  }
6549
6907
  }
6550
6908
  } catch (e) {
@@ -6599,15 +6957,16 @@ async function handleReadChat(h, args) {
6599
6957
  }
6600
6958
  }
6601
6959
  if (parsed && typeof parsed === "object") {
6602
- _log(`Webview OK: ${parsed.messages?.length || 0} msgs`);
6960
+ const validated = validateReadChatResultPayload(parsed, "webview read_chat");
6961
+ _log(`Webview OK: ${validated.messages?.length || 0} msgs`);
6603
6962
  h.historyWriter.appendNewMessages(
6604
6963
  provider?.type || getCurrentProviderType(h, "unknown_webview"),
6605
- toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
6606
- parsed.title,
6964
+ toHistoryPersistedMessages(normalizeReadChatMessages(validated)),
6965
+ validated.title,
6607
6966
  args?.targetSessionId,
6608
6967
  historySessionId
6609
6968
  );
6610
- return buildReadChatCommandResult(parsed, args);
6969
+ return buildReadChatCommandResult(validated, args);
6611
6970
  }
6612
6971
  }
6613
6972
  } catch (e) {
@@ -6628,25 +6987,26 @@ async function handleReadChat(h, args) {
6628
6987
  }
6629
6988
  }
6630
6989
  if (parsed && typeof parsed === "object" && parsed.messages?.length > 0) {
6631
- _log(`OK: ${parsed.messages?.length} msgs`);
6990
+ const validated = validateReadChatResultPayload(parsed, "ide read_chat");
6991
+ _log(`OK: ${validated.messages?.length} msgs`);
6632
6992
  traceProviderEvent(args, "provider", "ide.read_chat.success", {
6633
6993
  h,
6634
6994
  provider,
6635
6995
  payload: {
6636
6996
  method: "evaluate",
6637
6997
  result: evalResult.result,
6638
- parsed,
6639
- messageCount: Array.isArray(parsed.messages) ? parsed.messages.length : 0
6998
+ parsed: validated,
6999
+ messageCount: Array.isArray(validated.messages) ? validated.messages.length : 0
6640
7000
  }
6641
7001
  });
6642
7002
  h.historyWriter.appendNewMessages(
6643
7003
  provider?.type || getCurrentProviderType(h, "unknown_ide"),
6644
- toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
6645
- parsed.title,
7004
+ toHistoryPersistedMessages(normalizeReadChatMessages(validated)),
7005
+ validated.title,
6646
7006
  args?.targetSessionId,
6647
7007
  historySessionId
6648
7008
  );
6649
- return buildReadChatCommandResult(parsed, args);
7009
+ return buildReadChatCommandResult(validated, args);
6650
7010
  }
6651
7011
  }
6652
7012
  } catch (e) {
@@ -6664,11 +7024,12 @@ async function handleReadChat(h, args) {
6664
7024
  async function handleSendChat(h, args) {
6665
7025
  const input = getSendChatInputEnvelope(args);
6666
7026
  const text = input.textFallback;
6667
- if (!text) return { success: false, error: "text required" };
7027
+ const hasInput = input.parts.length > 0 || typeof text === "string" && text.trim().length > 0;
7028
+ if (!hasInput) return { success: false, error: "input required" };
6668
7029
  const _log = (msg) => LOG.debug("Command", `[send_chat] ${msg}`);
6669
7030
  const provider = h.getProvider(args?.agentType);
6670
7031
  const transport = getTargetTransport(h, provider);
6671
- const dedupeKey = buildRecentSendKey(h, args, provider, text);
7032
+ const dedupeKey = buildRecentSendKey(h, args, provider, buildSendInputSignature(input));
6672
7033
  const _logSendSuccess = (method, targetAgent) => {
6673
7034
  return { success: true, sent: true, method, targetAgent };
6674
7035
  };
@@ -6676,11 +7037,26 @@ async function handleSendChat(h, args) {
6676
7037
  _log(`Suppressed duplicate send for ${dedupeKey}`);
6677
7038
  return { success: true, sent: false, deduplicated: true };
6678
7039
  }
6679
- if (isCliLikeTransport(transport)) {
7040
+ if (transport === "acp") {
7041
+ const target = getTargetInstance(h, args);
7042
+ if (!target || target.category !== "acp") {
7043
+ return { success: false, error: `ACP instance not found for ${provider?.type || args?.agentType || "unknown"}` };
7044
+ }
7045
+ try {
7046
+ assertProviderSupportsDeclaredInput(provider, input);
7047
+ target.onEvent("send_message", { input });
7048
+ return _logSendSuccess("acp-instance", target.type);
7049
+ } catch (e) {
7050
+ return { success: false, error: `acp send failed: ${e.message}` };
7051
+ }
7052
+ }
7053
+ if (transport === "pty") {
6680
7054
  const adapter = getTargetedCliAdapter(h, args, provider?.type);
6681
7055
  if (adapter) {
6682
7056
  _log(`${transport} adapter: ${adapter.cliType}`);
6683
7057
  try {
7058
+ assertTextOnlyInput(provider, input);
7059
+ if (!text) return { success: false, error: "text required for PTY send" };
6684
7060
  await adapter.sendMessage(text);
6685
7061
  return _logSendSuccess(`${transport}-adapter`, adapter.cliType);
6686
7062
  } catch (e) {
@@ -6688,6 +7064,8 @@ async function handleSendChat(h, args) {
6688
7064
  }
6689
7065
  }
6690
7066
  }
7067
+ assertTextOnlyInput(provider, input);
7068
+ if (!text) return { success: false, error: "text required" };
6691
7069
  if (isExtensionTransport(transport)) {
6692
7070
  _log(`Extension: ${provider?.type || "unknown_extension"}`);
6693
7071
  try {
@@ -7303,6 +7681,8 @@ var init_chat_commands = __esm({
7303
7681
  "../../oss/packages/daemon-core/src/commands/chat-commands.ts"() {
7304
7682
  "use strict";
7305
7683
  init_contracts();
7684
+ init_provider_input_support();
7685
+ init_read_chat_contract();
7306
7686
  init_chat_history();
7307
7687
  init_logger();
7308
7688
  init_debug_trace();
@@ -7877,14 +8257,14 @@ function normalizeProviderScriptArgs(args, scriptName) {
7877
8257
  }
7878
8258
  function buildControlScriptResult(scriptName, payload) {
7879
8259
  if (!payload || typeof payload !== "object") return {};
7880
- if (Array.isArray(payload.options) || Array.isArray(payload.models) || Array.isArray(payload.modes)) {
8260
+ if (Array.isArray(payload.options)) {
7881
8261
  return { controlResult: normalizeControlListResult(payload) };
7882
8262
  }
7883
8263
  const looksLikeValueMutation = /^set|^change/i.test(scriptName) || payload.currentValue !== void 0 || payload.value !== void 0;
7884
8264
  if (looksLikeValueMutation) {
7885
8265
  return { controlResult: normalizeControlSetResult(payload) };
7886
8266
  }
7887
- if (payload.ok !== void 0 || payload.success !== void 0 || Array.isArray(payload.effects)) {
8267
+ if (payload.ok !== void 0 || Array.isArray(payload.effects) || typeof payload.error === "string") {
7888
8268
  return { controlResult: normalizeControlInvokeResult(payload) };
7889
8269
  }
7890
8270
  return {};
@@ -10713,6 +11093,7 @@ var init_provider_cli_adapter = __esm({
10713
11093
  init_pty_transport();
10714
11094
  init_provider_cli_shared();
10715
11095
  init_chat_message_normalization();
11096
+ init_read_chat_contract();
10716
11097
  init_provider_cli_parse();
10717
11098
  init_provider_cli_config();
10718
11099
  init_provider_cli_runtime();
@@ -11858,6 +12239,9 @@ var init_provider_cli_adapter = __esm({
11858
12239
  runtimeSettings: this.runtimeSettings
11859
12240
  });
11860
12241
  const parsed = this.cliScripts.parseOutput(input);
12242
+ if (parsed && typeof parsed === "object") {
12243
+ Object.assign(parsed, validateReadChatResultPayload(parsed, `${this.cliType} parseOutput`));
12244
+ }
11861
12245
  const refinedStatus = this.refineDetectedStatus(typeof parsed?.status === "string" ? parsed.status : null, input.recentBuffer, input.screenText);
11862
12246
  if (parsed && refinedStatus && parsed.status !== refinedStatus) {
11863
12247
  parsed.status = refinedStatus;
@@ -12494,6 +12878,7 @@ var init_cli_provider_instance = __esm({
12494
12878
  fs5 = __toESM(require("fs"));
12495
12879
  import_node_module = require("module");
12496
12880
  init_contracts();
12881
+ init_provider_input_support();
12497
12882
  init_provider_cli_adapter();
12498
12883
  init_status_monitor();
12499
12884
  init_chat_history();
@@ -12754,6 +13139,7 @@ var init_cli_provider_instance = __esm({
12754
13139
  onEvent(event, data) {
12755
13140
  if (event === "send_message") {
12756
13141
  const input = normalizeInputEnvelope(data);
13142
+ assertTextOnlyInput(this.provider, input);
12757
13143
  if (input.textFallback) {
12758
13144
  void this.adapter.sendMessage(input.textFallback).catch((e) => {
12759
13145
  LOG.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
@@ -13309,7 +13695,7 @@ __export(util_exports, {
13309
13695
  getSizableOrigin: () => getSizableOrigin,
13310
13696
  hexToUint8Array: () => hexToUint8Array,
13311
13697
  isObject: () => isObject,
13312
- isPlainObject: () => isPlainObject3,
13698
+ isPlainObject: () => isPlainObject4,
13313
13699
  issue: () => issue,
13314
13700
  joinValues: () => joinValues,
13315
13701
  jsonStringifyReplacer: () => jsonStringifyReplacer,
@@ -13445,10 +13831,10 @@ function mergeDefs(...defs) {
13445
13831
  function cloneDef(schema) {
13446
13832
  return mergeDefs(schema._zod.def);
13447
13833
  }
13448
- function getElementAtPath(obj, path36) {
13449
- if (!path36)
13834
+ function getElementAtPath(obj, path35) {
13835
+ if (!path35)
13450
13836
  return obj;
13451
- return path36.reduce((acc, key) => acc?.[key], obj);
13837
+ return path35.reduce((acc, key) => acc?.[key], obj);
13452
13838
  }
13453
13839
  function promiseAllObject(promisesObj) {
13454
13840
  const keys = Object.keys(promisesObj);
@@ -13478,7 +13864,7 @@ function slugify(input) {
13478
13864
  function isObject(data) {
13479
13865
  return typeof data === "object" && data !== null && !Array.isArray(data);
13480
13866
  }
13481
- function isPlainObject3(o) {
13867
+ function isPlainObject4(o) {
13482
13868
  if (isObject(o) === false)
13483
13869
  return false;
13484
13870
  const ctor = o.constructor;
@@ -13495,7 +13881,7 @@ function isPlainObject3(o) {
13495
13881
  return true;
13496
13882
  }
13497
13883
  function shallowClone(o) {
13498
- if (isPlainObject3(o))
13884
+ if (isPlainObject4(o))
13499
13885
  return { ...o };
13500
13886
  if (Array.isArray(o))
13501
13887
  return [...o];
@@ -13631,7 +14017,7 @@ function omit(schema, mask2) {
13631
14017
  return clone(schema, def);
13632
14018
  }
13633
14019
  function extend(schema, shape) {
13634
- if (!isPlainObject3(shape)) {
14020
+ if (!isPlainObject4(shape)) {
13635
14021
  throw new Error("Invalid input to extend: expected a plain object");
13636
14022
  }
13637
14023
  const checks = schema._zod.def.checks;
@@ -13654,7 +14040,7 @@ function extend(schema, shape) {
13654
14040
  return clone(schema, def);
13655
14041
  }
13656
14042
  function safeExtend(schema, shape) {
13657
- if (!isPlainObject3(shape)) {
14043
+ if (!isPlainObject4(shape)) {
13658
14044
  throw new Error("Invalid input to safeExtend: expected a plain object");
13659
14045
  }
13660
14046
  const def = mergeDefs(schema._zod.def, {
@@ -13760,11 +14146,11 @@ function aborted(x, startIndex = 0) {
13760
14146
  }
13761
14147
  return false;
13762
14148
  }
13763
- function prefixIssues(path36, issues) {
14149
+ function prefixIssues(path35, issues) {
13764
14150
  return issues.map((iss) => {
13765
14151
  var _a2;
13766
14152
  (_a2 = iss).path ?? (_a2.path = []);
13767
- iss.path.unshift(path36);
14153
+ iss.path.unshift(path35);
13768
14154
  return iss;
13769
14155
  });
13770
14156
  }
@@ -14007,7 +14393,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
14007
14393
  }
14008
14394
  function treeifyError(error48, mapper = (issue2) => issue2.message) {
14009
14395
  const result = { errors: [] };
14010
- const processError = (error49, path36 = []) => {
14396
+ const processError = (error49, path35 = []) => {
14011
14397
  var _a2, _b;
14012
14398
  for (const issue2 of error49.issues) {
14013
14399
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -14017,7 +14403,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
14017
14403
  } else if (issue2.code === "invalid_element") {
14018
14404
  processError({ issues: issue2.issues }, issue2.path);
14019
14405
  } else {
14020
- const fullpath = [...path36, ...issue2.path];
14406
+ const fullpath = [...path35, ...issue2.path];
14021
14407
  if (fullpath.length === 0) {
14022
14408
  result.errors.push(mapper(issue2));
14023
14409
  continue;
@@ -14049,8 +14435,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
14049
14435
  }
14050
14436
  function toDotPath(_path) {
14051
14437
  const segs = [];
14052
- const path36 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
14053
- for (const seg of path36) {
14438
+ const path35 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
14439
+ for (const seg of path35) {
14054
14440
  if (typeof seg === "number")
14055
14441
  segs.push(`[${seg}]`);
14056
14442
  else if (typeof seg === "symbol")
@@ -15137,7 +15523,7 @@ function mergeValues(a, b) {
15137
15523
  if (a instanceof Date && b instanceof Date && +a === +b) {
15138
15524
  return { valid: true, data: a };
15139
15525
  }
15140
- if (isPlainObject3(a) && isPlainObject3(b)) {
15526
+ if (isPlainObject4(a) && isPlainObject4(b)) {
15141
15527
  const bKeys = Object.keys(b);
15142
15528
  const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1);
15143
15529
  const newObj = { ...a, ...b };
@@ -16332,7 +16718,7 @@ var init_schemas = __esm({
16332
16718
  $ZodType.init(inst, def);
16333
16719
  inst._zod.parse = (payload, ctx) => {
16334
16720
  const input = payload.value;
16335
- if (!isPlainObject3(input)) {
16721
+ if (!isPlainObject4(input)) {
16336
16722
  payload.issues.push({
16337
16723
  expected: "record",
16338
16724
  code: "invalid_type",
@@ -26814,13 +27200,13 @@ function resolveRef(ref, ctx) {
26814
27200
  if (!ref.startsWith("#")) {
26815
27201
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
26816
27202
  }
26817
- const path36 = ref.slice(1).split("/").filter(Boolean);
26818
- if (path36.length === 0) {
27203
+ const path35 = ref.slice(1).split("/").filter(Boolean);
27204
+ if (path35.length === 0) {
26819
27205
  return ctx.rootSchema;
26820
27206
  }
26821
27207
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
26822
- if (path36[0] === defsKey) {
26823
- const key = path36[1];
27208
+ if (path35[0] === defsKey) {
27209
+ const key = path35[1];
26824
27210
  if (!key || !ctx.defs[key]) {
26825
27211
  throw new Error(`Reference not found: ${ref}`);
26826
27212
  }
@@ -29502,25 +29888,6 @@ function getPromptCapabilityFlags(agentCapabilities) {
29502
29888
  embeddedContext: prompt2.embeddedContext === true
29503
29889
  };
29504
29890
  }
29505
- function getResourceNameFromUri(uri, fallback2) {
29506
- try {
29507
- if (uri.startsWith("file://")) {
29508
- return path13.basename(new URL(uri).pathname) || fallback2;
29509
- }
29510
- return path13.basename(uri) || fallback2;
29511
- } catch {
29512
- return fallback2;
29513
- }
29514
- }
29515
- function inputPartToResourceLink(part, fallbackName) {
29516
- if (!part.uri) return null;
29517
- return {
29518
- type: "resource_link",
29519
- uri: part.uri,
29520
- name: getResourceNameFromUri(part.uri, fallbackName),
29521
- ...part.mimeType ? { mimeType: part.mimeType } : {}
29522
- };
29523
- }
29524
29891
  function appendPromptText(promptParts, text) {
29525
29892
  const normalized = typeof text === "string" ? text.trim() : "";
29526
29893
  if (!normalized) return;
@@ -29537,67 +29904,72 @@ function buildAcpPromptParts(input, agentCapabilities) {
29537
29904
  continue;
29538
29905
  }
29539
29906
  if (part.type === "image") {
29540
- if (caps.image && part.data) {
29541
- promptParts.push({
29542
- type: "image",
29543
- data: part.data,
29544
- mimeType: part.mimeType,
29545
- ...part.uri ? { uri: part.uri } : {}
29546
- });
29547
- continue;
29907
+ if (!caps.image) {
29908
+ throw new Error("ACP agent does not support input type: image");
29548
29909
  }
29549
- const fallback2 = inputPartToResourceLink(part, "image");
29550
- if (fallback2) promptParts.push(fallback2);
29551
- appendPromptText(promptParts, part.alt || (!part.uri ? `Attached image (${part.mimeType})` : void 0));
29910
+ if (!part.data) {
29911
+ throw new Error("ACP image input requires inline image data");
29912
+ }
29913
+ promptParts.push({
29914
+ type: "image",
29915
+ data: part.data,
29916
+ mimeType: part.mimeType,
29917
+ ...part.uri ? { uri: part.uri } : {}
29918
+ });
29552
29919
  continue;
29553
29920
  }
29554
29921
  if (part.type === "audio") {
29555
- if (caps.audio && part.data) {
29556
- promptParts.push({
29557
- type: "audio",
29558
- data: part.data,
29559
- mimeType: part.mimeType
29560
- });
29561
- continue;
29922
+ if (!caps.audio) {
29923
+ throw new Error("ACP agent does not support input type: audio");
29924
+ }
29925
+ if (!part.data) {
29926
+ throw new Error("ACP audio input requires inline audio data");
29562
29927
  }
29563
- const fallback2 = inputPartToResourceLink(part, "audio");
29564
- if (fallback2) promptParts.push(fallback2);
29565
- appendPromptText(promptParts, part.transcript || (!part.uri ? `Attached audio (${part.mimeType})` : void 0));
29928
+ promptParts.push({
29929
+ type: "audio",
29930
+ data: part.data,
29931
+ mimeType: part.mimeType
29932
+ });
29566
29933
  continue;
29567
29934
  }
29568
29935
  if (part.type === "resource") {
29569
- if (caps.embeddedContext && (part.text || part.data)) {
29936
+ if (!caps.embeddedContext) {
29937
+ throw new Error("ACP agent does not support input type: resource");
29938
+ }
29939
+ if (part.text) {
29570
29940
  promptParts.push({
29571
29941
  type: "resource",
29572
- resource: part.text ? { uri: part.uri, text: part.text, mimeType: part.mimeType ?? null } : { uri: part.uri, blob: part.data || "", mimeType: part.mimeType ?? null }
29942
+ resource: { uri: part.uri, text: part.text, mimeType: part.mimeType ?? null }
29573
29943
  });
29574
29944
  continue;
29575
29945
  }
29576
- const fallback2 = inputPartToResourceLink(part, part.name || "resource");
29577
- if (fallback2) promptParts.push(fallback2);
29578
- appendPromptText(promptParts, part.text || (!part.uri && part.name ? part.name : void 0));
29579
- continue;
29946
+ if (part.data) {
29947
+ promptParts.push({
29948
+ type: "resource",
29949
+ resource: { uri: part.uri, blob: part.data, mimeType: part.mimeType ?? null }
29950
+ });
29951
+ continue;
29952
+ }
29953
+ throw new Error("ACP resource input requires embedded text or binary data");
29580
29954
  }
29581
29955
  if (part.type === "video") {
29582
- const fallback2 = inputPartToResourceLink(part, "video");
29583
- if (fallback2) promptParts.push(fallback2);
29584
- appendPromptText(promptParts, !part.uri ? `Attached video (${part.mimeType})` : void 0);
29956
+ throw new Error("ACP agent does not support input type: video");
29585
29957
  }
29586
29958
  }
29587
29959
  if (!promptParts.some((part) => part.type === "text") && input.textFallback) {
29588
- promptParts.unshift({ type: "text", text: input.textFallback });
29960
+ appendPromptText(promptParts, input.textFallback);
29589
29961
  }
29590
29962
  return promptParts;
29591
29963
  }
29592
- var path13, import_stream, import_child_process5, AcpProviderInstance;
29964
+ var import_stream, import_child_process5, AcpProviderInstance;
29593
29965
  var init_acp_provider_instance = __esm({
29594
29966
  "../../oss/packages/daemon-core/src/providers/acp-provider-instance.ts"() {
29595
29967
  "use strict";
29596
- path13 = __toESM(require("path"));
29597
29968
  import_stream = require("stream");
29598
29969
  import_child_process5 = require("child_process");
29599
29970
  init_acp();
29600
29971
  init_contracts();
29972
+ init_provider_input_support();
29601
29973
  init_status_monitor();
29602
29974
  init_summary_metadata();
29603
29975
  init_chat_message_normalization();
@@ -29633,6 +30005,7 @@ var init_acp_provider_instance = __esm({
29633
30005
  activeToolCalls = [];
29634
30006
  stopReason = null;
29635
30007
  partialContent = "";
30008
+ partialThoughtContent = "";
29636
30009
  /** Rich content blocks accumulated during streaming */
29637
30010
  partialBlocks = [];
29638
30011
  /** Tool calls collected during current turn */
@@ -29678,6 +30051,10 @@ var init_acp_provider_instance = __esm({
29678
30051
  content
29679
30052
  });
29680
30053
  }));
30054
+ if (this.currentStatus === "generating") {
30055
+ const partialThoughtMessage = this.buildPartialThoughtMessage(Date.now());
30056
+ if (partialThoughtMessage) recentMessages.push(partialThoughtMessage);
30057
+ }
29681
30058
  if (this.currentStatus === "generating" && (this.partialContent || this.partialBlocks.length > 0)) {
29682
30059
  const blocks = this.buildPartialBlocks();
29683
30060
  if (blocks.length > 0) {
@@ -29724,6 +30101,7 @@ var init_acp_provider_instance = __esm({
29724
30101
  onEvent(event, data) {
29725
30102
  if (event === "send_message") {
29726
30103
  const input = normalizeInputEnvelope(data);
30104
+ assertProviderSupportsDeclaredInput(this.provider, input);
29727
30105
  const promptParts = buildAcpPromptParts(input, this.agentCapabilities);
29728
30106
  this.sendPrompt(input.textFallback, promptParts.length > 0 ? promptParts : void 0).catch(
29729
30107
  (e) => this.log.warn(`[${this.type}] sendPrompt error: ${e?.message}`)
@@ -30236,6 +30614,7 @@ var init_acp_provider_instance = __esm({
30236
30614
  }));
30237
30615
  this.currentStatus = "generating";
30238
30616
  this.partialContent = "";
30617
+ this.partialThoughtContent = "";
30239
30618
  this.partialBlocks = [];
30240
30619
  this.turnToolCalls = [];
30241
30620
  this.detectStatusTransition();
@@ -30318,7 +30697,14 @@ var init_acp_provider_instance = __esm({
30318
30697
  this.currentStatus = "generating";
30319
30698
  break;
30320
30699
  }
30321
- case "agent_thought_chunk":
30700
+ case "agent_thought_chunk": {
30701
+ const content = update.content;
30702
+ if (content?.type === "text" && typeof content.text === "string") {
30703
+ this.partialThoughtContent += content.text;
30704
+ }
30705
+ this.currentStatus = "generating";
30706
+ break;
30707
+ }
30322
30708
  case "user_message_chunk": {
30323
30709
  break;
30324
30710
  }
@@ -30473,8 +30859,82 @@ var init_acp_provider_instance = __esm({
30473
30859
  blocks.push(...this.partialBlocks);
30474
30860
  return blocks;
30475
30861
  }
30862
+ buildPartialThoughtMessage(timestamp = Date.now()) {
30863
+ const content = this.partialThoughtContent.trim();
30864
+ if (!content) return null;
30865
+ return buildThoughtChatMessage({
30866
+ content,
30867
+ timestamp,
30868
+ meta: {
30869
+ label: "Thought",
30870
+ isRunning: this.currentStatus === "generating"
30871
+ }
30872
+ });
30873
+ }
30874
+ buildToolCallBubbleKind(toolCall) {
30875
+ if (toolCall.kind === "think") return "thought";
30876
+ if (toolCall.kind === "execute") return "terminal";
30877
+ if (Array.isArray(toolCall.content) && toolCall.content.some((entry) => entry?.type === "terminal")) return "terminal";
30878
+ return "tool";
30879
+ }
30880
+ summarizeToolCallBubbleContent(toolCall) {
30881
+ const rawOutput = typeof toolCall.rawOutput === "string" ? toolCall.rawOutput.trim() : toolCall.rawOutput != null ? JSON.stringify(toolCall.rawOutput) : "";
30882
+ if (rawOutput) return rawOutput;
30883
+ const contentText = Array.isArray(toolCall.content) ? toolCall.content.map((entry) => {
30884
+ if (!entry || typeof entry !== "object") return "";
30885
+ if (entry.type === "content") return flattenContent([entry.content]).trim();
30886
+ if (entry.type === "diff") return `${entry.path}
30887
+ ${entry.newText || ""}`.trim();
30888
+ if (entry.type === "terminal") return `Terminal: ${entry.terminalId || ""}`.trim();
30889
+ return "";
30890
+ }).filter(Boolean).join("\n\n").trim() : "";
30891
+ if (contentText) return contentText;
30892
+ const rawInput = typeof toolCall.rawInput === "string" ? toolCall.rawInput.trim() : toolCall.rawInput != null ? JSON.stringify(toolCall.rawInput) : "";
30893
+ if (rawInput) {
30894
+ return toolCall.title ? `${toolCall.title}
30895
+ ${rawInput}` : rawInput;
30896
+ }
30897
+ return toolCall.title || "";
30898
+ }
30899
+ buildTurnToolCallMessages(timestamp = Date.now()) {
30900
+ return this.turnToolCalls.map((toolCall) => {
30901
+ const content = this.summarizeToolCallBubbleContent(toolCall);
30902
+ if (!content) return null;
30903
+ const isRunning = toolCall.status === "pending" || toolCall.status === "in_progress";
30904
+ const label = toolCall.title || void 0;
30905
+ const kind = this.buildToolCallBubbleKind(toolCall);
30906
+ if (kind === "thought") {
30907
+ return buildThoughtChatMessage({
30908
+ content,
30909
+ timestamp,
30910
+ meta: { label: label || "Thought", isRunning }
30911
+ });
30912
+ }
30913
+ if (kind === "terminal") {
30914
+ return buildTerminalChatMessage({
30915
+ content,
30916
+ timestamp,
30917
+ meta: { label: label || "Ran command", isRunning }
30918
+ });
30919
+ }
30920
+ return buildToolChatMessage({
30921
+ content,
30922
+ timestamp,
30923
+ meta: { label: label || "Tool call", isRunning }
30924
+ });
30925
+ }).filter(Boolean);
30926
+ }
30476
30927
  /** Finalize streaming content into an assistant message */
30477
30928
  finalizeAssistantMessage() {
30929
+ const timestamp = Date.now();
30930
+ const thoughtMessage = this.buildPartialThoughtMessage(timestamp);
30931
+ if (thoughtMessage) {
30932
+ this.messages.push(thoughtMessage);
30933
+ }
30934
+ const toolCallMessages = this.buildTurnToolCallMessages(timestamp);
30935
+ if (toolCallMessages.length > 0) {
30936
+ this.messages.push(...toolCallMessages);
30937
+ }
30478
30938
  const blocks = this.buildPartialBlocks();
30479
30939
  const finalBlocks = blocks.map((b) => {
30480
30940
  if (b.type === "text" && b.text.endsWith("...")) {
@@ -30490,6 +30950,7 @@ var init_acp_provider_instance = __esm({
30490
30950
  }));
30491
30951
  }
30492
30952
  this.partialContent = "";
30953
+ this.partialThoughtContent = "";
30493
30954
  this.partialBlocks = [];
30494
30955
  this.turnToolCalls = [];
30495
30956
  }
@@ -30700,12 +31161,12 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
30700
31161
  launchMode: "new"
30701
31162
  };
30702
31163
  }
30703
- var os15, path14, crypto4, chalkModule, chalkApi, DaemonCliManager;
31164
+ var os15, path13, crypto4, chalkModule, chalkApi, DaemonCliManager;
30704
31165
  var init_cli_manager = __esm({
30705
31166
  "../../oss/packages/daemon-core/src/commands/cli-manager.ts"() {
30706
31167
  "use strict";
30707
31168
  os15 = __toESM(require("os"));
30708
- path14 = __toESM(require("path"));
31169
+ path13 = __toESM(require("path"));
30709
31170
  crypto4 = __toESM(require("crypto"));
30710
31171
  init_source2();
30711
31172
  init_provider_cli_adapter();
@@ -30719,6 +31180,7 @@ var init_cli_manager = __esm({
30719
31180
  init_cli_provider_instance();
30720
31181
  init_acp_provider_instance();
30721
31182
  init_contracts();
31183
+ init_provider_input_support();
30722
31184
  init_logger();
30723
31185
  init_hosted_runtime_restore();
30724
31186
  chalkModule = source_default2;
@@ -30865,7 +31327,7 @@ var init_cli_manager = __esm({
30865
31327
  async startSession(cliType, workingDir, cliArgs, initialModel, options) {
30866
31328
  const trimmed = (workingDir || "").trim();
30867
31329
  if (!trimmed) throw new Error("working directory required");
30868
- const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os15.homedir()) : path14.resolve(trimmed);
31330
+ const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os15.homedir()) : path13.resolve(trimmed);
30869
31331
  const normalizedType = this.providerLoader.resolveAlias(cliType);
30870
31332
  const provider = this.providerLoader.getByAlias(cliType);
30871
31333
  const key = crypto4.randomUUID();
@@ -31324,6 +31786,12 @@ Run 'adhdev doctor' for detailed diagnostics.`
31324
31786
  const { adapter, key } = found;
31325
31787
  if (action === "send_chat") {
31326
31788
  const input = normalizeInputEnvelope(args?.input ? { input: args.input } : args);
31789
+ const provider = this.providerLoader.resolve(agentType) || this.providerLoader.getMeta(agentType);
31790
+ if (provider?.category === "acp") {
31791
+ assertProviderSupportsDeclaredInput(provider, input);
31792
+ } else {
31793
+ assertTextOnlyInput(provider, input);
31794
+ }
31327
31795
  const message = input.textFallback;
31328
31796
  if (!message) throw new Error("message required for send_chat");
31329
31797
  await adapter.sendMessage(message);
@@ -31448,7 +31916,7 @@ var init_readdirp = __esm({
31448
31916
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
31449
31917
  const statMethod = opts.lstat ? import_promises.lstat : import_promises.stat;
31450
31918
  if (wantBigintFsStats) {
31451
- this._stat = (path36) => statMethod(path36, { bigint: true });
31919
+ this._stat = (path35) => statMethod(path35, { bigint: true });
31452
31920
  } else {
31453
31921
  this._stat = statMethod;
31454
31922
  }
@@ -31473,8 +31941,8 @@ var init_readdirp = __esm({
31473
31941
  const par = this.parent;
31474
31942
  const fil = par && par.files;
31475
31943
  if (fil && fil.length > 0) {
31476
- const { path: path36, depth } = par;
31477
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path36));
31944
+ const { path: path35, depth } = par;
31945
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path35));
31478
31946
  const awaited = await Promise.all(slice);
31479
31947
  for (const entry of awaited) {
31480
31948
  if (!entry)
@@ -31514,21 +31982,21 @@ var init_readdirp = __esm({
31514
31982
  this.reading = false;
31515
31983
  }
31516
31984
  }
31517
- async _exploreDir(path36, depth) {
31985
+ async _exploreDir(path35, depth) {
31518
31986
  let files;
31519
31987
  try {
31520
- files = await (0, import_promises.readdir)(path36, this._rdOptions);
31988
+ files = await (0, import_promises.readdir)(path35, this._rdOptions);
31521
31989
  } catch (error48) {
31522
31990
  this._onError(error48);
31523
31991
  }
31524
- return { files, depth, path: path36 };
31992
+ return { files, depth, path: path35 };
31525
31993
  }
31526
- async _formatEntry(dirent, path36) {
31994
+ async _formatEntry(dirent, path35) {
31527
31995
  let entry;
31528
- const basename10 = this._isDirent ? dirent.name : dirent;
31996
+ const basename9 = this._isDirent ? dirent.name : dirent;
31529
31997
  try {
31530
- const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path36, basename10));
31531
- entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename10 };
31998
+ const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path35, basename9));
31999
+ entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename9 };
31532
32000
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
31533
32001
  } catch (err) {
31534
32002
  this._onError(err);
@@ -31584,16 +32052,16 @@ var init_readdirp = __esm({
31584
32052
  });
31585
32053
 
31586
32054
  // ../../oss/packages/daemon-core/node_modules/chokidar/handler.js
31587
- function createFsWatchInstance(path36, options, listener, errHandler, emitRaw) {
32055
+ function createFsWatchInstance(path35, options, listener, errHandler, emitRaw) {
31588
32056
  const handleEvent = (rawEvent, evPath) => {
31589
- listener(path36);
31590
- emitRaw(rawEvent, evPath, { watchedPath: path36 });
31591
- if (evPath && path36 !== evPath) {
31592
- fsWatchBroadcast(sp.resolve(path36, evPath), KEY_LISTENERS, sp.join(path36, evPath));
32057
+ listener(path35);
32058
+ emitRaw(rawEvent, evPath, { watchedPath: path35 });
32059
+ if (evPath && path35 !== evPath) {
32060
+ fsWatchBroadcast(sp.resolve(path35, evPath), KEY_LISTENERS, sp.join(path35, evPath));
31593
32061
  }
31594
32062
  };
31595
32063
  try {
31596
- return (0, import_node_fs.watch)(path36, {
32064
+ return (0, import_node_fs.watch)(path35, {
31597
32065
  persistent: options.persistent
31598
32066
  }, handleEvent);
31599
32067
  } catch (error48) {
@@ -31942,12 +32410,12 @@ var init_handler2 = __esm({
31942
32410
  listener(val1, val2, val3);
31943
32411
  });
31944
32412
  };
31945
- setFsWatchListener = (path36, fullPath, options, handlers) => {
32413
+ setFsWatchListener = (path35, fullPath, options, handlers) => {
31946
32414
  const { listener, errHandler, rawEmitter } = handlers;
31947
32415
  let cont = FsWatchInstances.get(fullPath);
31948
32416
  let watcher;
31949
32417
  if (!options.persistent) {
31950
- watcher = createFsWatchInstance(path36, options, listener, errHandler, rawEmitter);
32418
+ watcher = createFsWatchInstance(path35, options, listener, errHandler, rawEmitter);
31951
32419
  if (!watcher)
31952
32420
  return;
31953
32421
  return watcher.close.bind(watcher);
@@ -31958,7 +32426,7 @@ var init_handler2 = __esm({
31958
32426
  addAndConvert(cont, KEY_RAW, rawEmitter);
31959
32427
  } else {
31960
32428
  watcher = createFsWatchInstance(
31961
- path36,
32429
+ path35,
31962
32430
  options,
31963
32431
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
31964
32432
  errHandler,
@@ -31973,7 +32441,7 @@ var init_handler2 = __esm({
31973
32441
  cont.watcherUnusable = true;
31974
32442
  if (isWindows && error48.code === "EPERM") {
31975
32443
  try {
31976
- const fd = await (0, import_promises2.open)(path36, "r");
32444
+ const fd = await (0, import_promises2.open)(path35, "r");
31977
32445
  await fd.close();
31978
32446
  broadcastErr(error48);
31979
32447
  } catch (err) {
@@ -32004,7 +32472,7 @@ var init_handler2 = __esm({
32004
32472
  };
32005
32473
  };
32006
32474
  FsWatchFileInstances = /* @__PURE__ */ new Map();
32007
- setFsWatchFileListener = (path36, fullPath, options, handlers) => {
32475
+ setFsWatchFileListener = (path35, fullPath, options, handlers) => {
32008
32476
  const { listener, rawEmitter } = handlers;
32009
32477
  let cont = FsWatchFileInstances.get(fullPath);
32010
32478
  const copts = cont && cont.options;
@@ -32026,7 +32494,7 @@ var init_handler2 = __esm({
32026
32494
  });
32027
32495
  const currmtime = curr.mtimeMs;
32028
32496
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
32029
- foreach(cont.listeners, (listener2) => listener2(path36, curr));
32497
+ foreach(cont.listeners, (listener2) => listener2(path35, curr));
32030
32498
  }
32031
32499
  })
32032
32500
  };
@@ -32056,13 +32524,13 @@ var init_handler2 = __esm({
32056
32524
  * @param listener on fs change
32057
32525
  * @returns closer for the watcher instance
32058
32526
  */
32059
- _watchWithNodeFs(path36, listener) {
32527
+ _watchWithNodeFs(path35, listener) {
32060
32528
  const opts = this.fsw.options;
32061
- const directory = sp.dirname(path36);
32062
- const basename10 = sp.basename(path36);
32529
+ const directory = sp.dirname(path35);
32530
+ const basename9 = sp.basename(path35);
32063
32531
  const parent = this.fsw._getWatchedDir(directory);
32064
- parent.add(basename10);
32065
- const absolutePath = sp.resolve(path36);
32532
+ parent.add(basename9);
32533
+ const absolutePath = sp.resolve(path35);
32066
32534
  const options = {
32067
32535
  persistent: opts.persistent
32068
32536
  };
@@ -32071,13 +32539,13 @@ var init_handler2 = __esm({
32071
32539
  let closer;
32072
32540
  if (opts.usePolling) {
32073
32541
  const enableBin = opts.interval !== opts.binaryInterval;
32074
- options.interval = enableBin && isBinaryPath(basename10) ? opts.binaryInterval : opts.interval;
32075
- closer = setFsWatchFileListener(path36, absolutePath, options, {
32542
+ options.interval = enableBin && isBinaryPath(basename9) ? opts.binaryInterval : opts.interval;
32543
+ closer = setFsWatchFileListener(path35, absolutePath, options, {
32076
32544
  listener,
32077
32545
  rawEmitter: this.fsw._emitRaw
32078
32546
  });
32079
32547
  } else {
32080
- closer = setFsWatchListener(path36, absolutePath, options, {
32548
+ closer = setFsWatchListener(path35, absolutePath, options, {
32081
32549
  listener,
32082
32550
  errHandler: this._boundHandleError,
32083
32551
  rawEmitter: this.fsw._emitRaw
@@ -32094,12 +32562,12 @@ var init_handler2 = __esm({
32094
32562
  return;
32095
32563
  }
32096
32564
  const dirname10 = sp.dirname(file2);
32097
- const basename10 = sp.basename(file2);
32565
+ const basename9 = sp.basename(file2);
32098
32566
  const parent = this.fsw._getWatchedDir(dirname10);
32099
32567
  let prevStats = stats;
32100
- if (parent.has(basename10))
32568
+ if (parent.has(basename9))
32101
32569
  return;
32102
- const listener = async (path36, newStats) => {
32570
+ const listener = async (path35, newStats) => {
32103
32571
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file2, 5))
32104
32572
  return;
32105
32573
  if (!newStats || newStats.mtimeMs === 0) {
@@ -32113,18 +32581,18 @@ var init_handler2 = __esm({
32113
32581
  this.fsw._emit(EV.CHANGE, file2, newStats2);
32114
32582
  }
32115
32583
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
32116
- this.fsw._closeFile(path36);
32584
+ this.fsw._closeFile(path35);
32117
32585
  prevStats = newStats2;
32118
32586
  const closer2 = this._watchWithNodeFs(file2, listener);
32119
32587
  if (closer2)
32120
- this.fsw._addPathCloser(path36, closer2);
32588
+ this.fsw._addPathCloser(path35, closer2);
32121
32589
  } else {
32122
32590
  prevStats = newStats2;
32123
32591
  }
32124
32592
  } catch (error48) {
32125
- this.fsw._remove(dirname10, basename10);
32593
+ this.fsw._remove(dirname10, basename9);
32126
32594
  }
32127
- } else if (parent.has(basename10)) {
32595
+ } else if (parent.has(basename9)) {
32128
32596
  const at = newStats.atimeMs;
32129
32597
  const mt = newStats.mtimeMs;
32130
32598
  if (!at || at <= mt || mt !== prevStats.mtimeMs) {
@@ -32149,7 +32617,7 @@ var init_handler2 = __esm({
32149
32617
  * @param item basename of this item
32150
32618
  * @returns true if no more processing is needed for this entry.
32151
32619
  */
32152
- async _handleSymlink(entry, directory, path36, item) {
32620
+ async _handleSymlink(entry, directory, path35, item) {
32153
32621
  if (this.fsw.closed) {
32154
32622
  return;
32155
32623
  }
@@ -32159,7 +32627,7 @@ var init_handler2 = __esm({
32159
32627
  this.fsw._incrReadyCount();
32160
32628
  let linkPath;
32161
32629
  try {
32162
- linkPath = await (0, import_promises2.realpath)(path36);
32630
+ linkPath = await (0, import_promises2.realpath)(path35);
32163
32631
  } catch (e) {
32164
32632
  this.fsw._emitReady();
32165
32633
  return true;
@@ -32169,12 +32637,12 @@ var init_handler2 = __esm({
32169
32637
  if (dir.has(item)) {
32170
32638
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
32171
32639
  this.fsw._symlinkPaths.set(full, linkPath);
32172
- this.fsw._emit(EV.CHANGE, path36, entry.stats);
32640
+ this.fsw._emit(EV.CHANGE, path35, entry.stats);
32173
32641
  }
32174
32642
  } else {
32175
32643
  dir.add(item);
32176
32644
  this.fsw._symlinkPaths.set(full, linkPath);
32177
- this.fsw._emit(EV.ADD, path36, entry.stats);
32645
+ this.fsw._emit(EV.ADD, path35, entry.stats);
32178
32646
  }
32179
32647
  this.fsw._emitReady();
32180
32648
  return true;
@@ -32204,9 +32672,9 @@ var init_handler2 = __esm({
32204
32672
  return;
32205
32673
  }
32206
32674
  const item = entry.path;
32207
- let path36 = sp.join(directory, item);
32675
+ let path35 = sp.join(directory, item);
32208
32676
  current.add(item);
32209
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path36, item)) {
32677
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path35, item)) {
32210
32678
  return;
32211
32679
  }
32212
32680
  if (this.fsw.closed) {
@@ -32215,8 +32683,8 @@ var init_handler2 = __esm({
32215
32683
  }
32216
32684
  if (item === target || !target && !previous.has(item)) {
32217
32685
  this.fsw._incrReadyCount();
32218
- path36 = sp.join(dir, sp.relative(dir, path36));
32219
- this._addToNodeFs(path36, initialAdd, wh, depth + 1);
32686
+ path35 = sp.join(dir, sp.relative(dir, path35));
32687
+ this._addToNodeFs(path35, initialAdd, wh, depth + 1);
32220
32688
  }
32221
32689
  }).on(EV.ERROR, this._boundHandleError);
32222
32690
  return new Promise((resolve17, reject) => {
@@ -32285,13 +32753,13 @@ var init_handler2 = __esm({
32285
32753
  * @param depth Child path actually targeted for watch
32286
32754
  * @param target Child path actually targeted for watch
32287
32755
  */
32288
- async _addToNodeFs(path36, initialAdd, priorWh, depth, target) {
32756
+ async _addToNodeFs(path35, initialAdd, priorWh, depth, target) {
32289
32757
  const ready = this.fsw._emitReady;
32290
- if (this.fsw._isIgnored(path36) || this.fsw.closed) {
32758
+ if (this.fsw._isIgnored(path35) || this.fsw.closed) {
32291
32759
  ready();
32292
32760
  return false;
32293
32761
  }
32294
- const wh = this.fsw._getWatchHelpers(path36);
32762
+ const wh = this.fsw._getWatchHelpers(path35);
32295
32763
  if (priorWh) {
32296
32764
  wh.filterPath = (entry) => priorWh.filterPath(entry);
32297
32765
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -32307,8 +32775,8 @@ var init_handler2 = __esm({
32307
32775
  const follow = this.fsw.options.followSymlinks;
32308
32776
  let closer;
32309
32777
  if (stats.isDirectory()) {
32310
- const absPath = sp.resolve(path36);
32311
- const targetPath = follow ? await (0, import_promises2.realpath)(path36) : path36;
32778
+ const absPath = sp.resolve(path35);
32779
+ const targetPath = follow ? await (0, import_promises2.realpath)(path35) : path35;
32312
32780
  if (this.fsw.closed)
32313
32781
  return;
32314
32782
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -32318,29 +32786,29 @@ var init_handler2 = __esm({
32318
32786
  this.fsw._symlinkPaths.set(absPath, targetPath);
32319
32787
  }
32320
32788
  } else if (stats.isSymbolicLink()) {
32321
- const targetPath = follow ? await (0, import_promises2.realpath)(path36) : path36;
32789
+ const targetPath = follow ? await (0, import_promises2.realpath)(path35) : path35;
32322
32790
  if (this.fsw.closed)
32323
32791
  return;
32324
32792
  const parent = sp.dirname(wh.watchPath);
32325
32793
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
32326
32794
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
32327
- closer = await this._handleDir(parent, stats, initialAdd, depth, path36, wh, targetPath);
32795
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path35, wh, targetPath);
32328
32796
  if (this.fsw.closed)
32329
32797
  return;
32330
32798
  if (targetPath !== void 0) {
32331
- this.fsw._symlinkPaths.set(sp.resolve(path36), targetPath);
32799
+ this.fsw._symlinkPaths.set(sp.resolve(path35), targetPath);
32332
32800
  }
32333
32801
  } else {
32334
32802
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
32335
32803
  }
32336
32804
  ready();
32337
32805
  if (closer)
32338
- this.fsw._addPathCloser(path36, closer);
32806
+ this.fsw._addPathCloser(path35, closer);
32339
32807
  return false;
32340
32808
  } catch (error48) {
32341
32809
  if (this.fsw._handleError(error48)) {
32342
32810
  ready();
32343
- return path36;
32811
+ return path35;
32344
32812
  }
32345
32813
  }
32346
32814
  }
@@ -32375,24 +32843,24 @@ function createPattern(matcher) {
32375
32843
  }
32376
32844
  return () => false;
32377
32845
  }
32378
- function normalizePath(path36) {
32379
- if (typeof path36 !== "string")
32846
+ function normalizePath(path35) {
32847
+ if (typeof path35 !== "string")
32380
32848
  throw new Error("string expected");
32381
- path36 = sp2.normalize(path36);
32382
- path36 = path36.replace(/\\/g, "/");
32849
+ path35 = sp2.normalize(path35);
32850
+ path35 = path35.replace(/\\/g, "/");
32383
32851
  let prepend = false;
32384
- if (path36.startsWith("//"))
32852
+ if (path35.startsWith("//"))
32385
32853
  prepend = true;
32386
- path36 = path36.replace(DOUBLE_SLASH_RE, "/");
32854
+ path35 = path35.replace(DOUBLE_SLASH_RE, "/");
32387
32855
  if (prepend)
32388
- path36 = "/" + path36;
32389
- return path36;
32856
+ path35 = "/" + path35;
32857
+ return path35;
32390
32858
  }
32391
32859
  function matchPatterns(patterns, testString, stats) {
32392
- const path36 = normalizePath(testString);
32860
+ const path35 = normalizePath(testString);
32393
32861
  for (let index = 0; index < patterns.length; index++) {
32394
32862
  const pattern = patterns[index];
32395
- if (pattern(path36, stats)) {
32863
+ if (pattern(path35, stats)) {
32396
32864
  return true;
32397
32865
  }
32398
32866
  }
@@ -32455,19 +32923,19 @@ var init_chokidar = __esm({
32455
32923
  }
32456
32924
  return str;
32457
32925
  };
32458
- normalizePathToUnix = (path36) => toUnix(sp2.normalize(toUnix(path36)));
32459
- normalizeIgnored = (cwd = "") => (path36) => {
32460
- if (typeof path36 === "string") {
32461
- return normalizePathToUnix(sp2.isAbsolute(path36) ? path36 : sp2.join(cwd, path36));
32926
+ normalizePathToUnix = (path35) => toUnix(sp2.normalize(toUnix(path35)));
32927
+ normalizeIgnored = (cwd = "") => (path35) => {
32928
+ if (typeof path35 === "string") {
32929
+ return normalizePathToUnix(sp2.isAbsolute(path35) ? path35 : sp2.join(cwd, path35));
32462
32930
  } else {
32463
- return path36;
32931
+ return path35;
32464
32932
  }
32465
32933
  };
32466
- getAbsolutePath = (path36, cwd) => {
32467
- if (sp2.isAbsolute(path36)) {
32468
- return path36;
32934
+ getAbsolutePath = (path35, cwd) => {
32935
+ if (sp2.isAbsolute(path35)) {
32936
+ return path35;
32469
32937
  }
32470
- return sp2.join(cwd, path36);
32938
+ return sp2.join(cwd, path35);
32471
32939
  };
32472
32940
  EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
32473
32941
  DirEntry = class {
@@ -32532,10 +33000,10 @@ var init_chokidar = __esm({
32532
33000
  dirParts;
32533
33001
  followSymlinks;
32534
33002
  statMethod;
32535
- constructor(path36, follow, fsw) {
33003
+ constructor(path35, follow, fsw) {
32536
33004
  this.fsw = fsw;
32537
- const watchPath = path36;
32538
- this.path = path36 = path36.replace(REPLACER_RE, "");
33005
+ const watchPath = path35;
33006
+ this.path = path35 = path35.replace(REPLACER_RE, "");
32539
33007
  this.watchPath = watchPath;
32540
33008
  this.fullWatchPath = sp2.resolve(watchPath);
32541
33009
  this.dirParts = [];
@@ -32675,20 +33143,20 @@ var init_chokidar = __esm({
32675
33143
  this._closePromise = void 0;
32676
33144
  let paths = unifyPaths(paths_);
32677
33145
  if (cwd) {
32678
- paths = paths.map((path36) => {
32679
- const absPath = getAbsolutePath(path36, cwd);
33146
+ paths = paths.map((path35) => {
33147
+ const absPath = getAbsolutePath(path35, cwd);
32680
33148
  return absPath;
32681
33149
  });
32682
33150
  }
32683
- paths.forEach((path36) => {
32684
- this._removeIgnoredPath(path36);
33151
+ paths.forEach((path35) => {
33152
+ this._removeIgnoredPath(path35);
32685
33153
  });
32686
33154
  this._userIgnored = void 0;
32687
33155
  if (!this._readyCount)
32688
33156
  this._readyCount = 0;
32689
33157
  this._readyCount += paths.length;
32690
- Promise.all(paths.map(async (path36) => {
32691
- const res = await this._nodeFsHandler._addToNodeFs(path36, !_internal, void 0, 0, _origAdd);
33158
+ Promise.all(paths.map(async (path35) => {
33159
+ const res = await this._nodeFsHandler._addToNodeFs(path35, !_internal, void 0, 0, _origAdd);
32692
33160
  if (res)
32693
33161
  this._emitReady();
32694
33162
  return res;
@@ -32710,17 +33178,17 @@ var init_chokidar = __esm({
32710
33178
  return this;
32711
33179
  const paths = unifyPaths(paths_);
32712
33180
  const { cwd } = this.options;
32713
- paths.forEach((path36) => {
32714
- if (!sp2.isAbsolute(path36) && !this._closers.has(path36)) {
33181
+ paths.forEach((path35) => {
33182
+ if (!sp2.isAbsolute(path35) && !this._closers.has(path35)) {
32715
33183
  if (cwd)
32716
- path36 = sp2.join(cwd, path36);
32717
- path36 = sp2.resolve(path36);
33184
+ path35 = sp2.join(cwd, path35);
33185
+ path35 = sp2.resolve(path35);
32718
33186
  }
32719
- this._closePath(path36);
32720
- this._addIgnoredPath(path36);
32721
- if (this._watched.has(path36)) {
33187
+ this._closePath(path35);
33188
+ this._addIgnoredPath(path35);
33189
+ if (this._watched.has(path35)) {
32722
33190
  this._addIgnoredPath({
32723
- path: path36,
33191
+ path: path35,
32724
33192
  recursive: true
32725
33193
  });
32726
33194
  }
@@ -32784,38 +33252,38 @@ var init_chokidar = __esm({
32784
33252
  * @param stats arguments to be passed with event
32785
33253
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
32786
33254
  */
32787
- async _emit(event, path36, stats) {
33255
+ async _emit(event, path35, stats) {
32788
33256
  if (this.closed)
32789
33257
  return;
32790
33258
  const opts = this.options;
32791
33259
  if (isWindows)
32792
- path36 = sp2.normalize(path36);
33260
+ path35 = sp2.normalize(path35);
32793
33261
  if (opts.cwd)
32794
- path36 = sp2.relative(opts.cwd, path36);
32795
- const args = [path36];
33262
+ path35 = sp2.relative(opts.cwd, path35);
33263
+ const args = [path35];
32796
33264
  if (stats != null)
32797
33265
  args.push(stats);
32798
33266
  const awf = opts.awaitWriteFinish;
32799
33267
  let pw;
32800
- if (awf && (pw = this._pendingWrites.get(path36))) {
33268
+ if (awf && (pw = this._pendingWrites.get(path35))) {
32801
33269
  pw.lastChange = /* @__PURE__ */ new Date();
32802
33270
  return this;
32803
33271
  }
32804
33272
  if (opts.atomic) {
32805
33273
  if (event === EVENTS.UNLINK) {
32806
- this._pendingUnlinks.set(path36, [event, ...args]);
33274
+ this._pendingUnlinks.set(path35, [event, ...args]);
32807
33275
  setTimeout(() => {
32808
- this._pendingUnlinks.forEach((entry, path37) => {
33276
+ this._pendingUnlinks.forEach((entry, path36) => {
32809
33277
  this.emit(...entry);
32810
33278
  this.emit(EVENTS.ALL, ...entry);
32811
- this._pendingUnlinks.delete(path37);
33279
+ this._pendingUnlinks.delete(path36);
32812
33280
  });
32813
33281
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
32814
33282
  return this;
32815
33283
  }
32816
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path36)) {
33284
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path35)) {
32817
33285
  event = EVENTS.CHANGE;
32818
- this._pendingUnlinks.delete(path36);
33286
+ this._pendingUnlinks.delete(path35);
32819
33287
  }
32820
33288
  }
32821
33289
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -32833,16 +33301,16 @@ var init_chokidar = __esm({
32833
33301
  this.emitWithAll(event, args);
32834
33302
  }
32835
33303
  };
32836
- this._awaitWriteFinish(path36, awf.stabilityThreshold, event, awfEmit);
33304
+ this._awaitWriteFinish(path35, awf.stabilityThreshold, event, awfEmit);
32837
33305
  return this;
32838
33306
  }
32839
33307
  if (event === EVENTS.CHANGE) {
32840
- const isThrottled = !this._throttle(EVENTS.CHANGE, path36, 50);
33308
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path35, 50);
32841
33309
  if (isThrottled)
32842
33310
  return this;
32843
33311
  }
32844
33312
  if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
32845
- const fullPath = opts.cwd ? sp2.join(opts.cwd, path36) : path36;
33313
+ const fullPath = opts.cwd ? sp2.join(opts.cwd, path35) : path35;
32846
33314
  let stats2;
32847
33315
  try {
32848
33316
  stats2 = await (0, import_promises3.stat)(fullPath);
@@ -32873,23 +33341,23 @@ var init_chokidar = __esm({
32873
33341
  * @param timeout duration of time to suppress duplicate actions
32874
33342
  * @returns tracking object or false if action should be suppressed
32875
33343
  */
32876
- _throttle(actionType, path36, timeout) {
33344
+ _throttle(actionType, path35, timeout) {
32877
33345
  if (!this._throttled.has(actionType)) {
32878
33346
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
32879
33347
  }
32880
33348
  const action = this._throttled.get(actionType);
32881
33349
  if (!action)
32882
33350
  throw new Error("invalid throttle");
32883
- const actionPath = action.get(path36);
33351
+ const actionPath = action.get(path35);
32884
33352
  if (actionPath) {
32885
33353
  actionPath.count++;
32886
33354
  return false;
32887
33355
  }
32888
33356
  let timeoutObject;
32889
33357
  const clear = () => {
32890
- const item = action.get(path36);
33358
+ const item = action.get(path35);
32891
33359
  const count = item ? item.count : 0;
32892
- action.delete(path36);
33360
+ action.delete(path35);
32893
33361
  clearTimeout(timeoutObject);
32894
33362
  if (item)
32895
33363
  clearTimeout(item.timeoutObject);
@@ -32897,7 +33365,7 @@ var init_chokidar = __esm({
32897
33365
  };
32898
33366
  timeoutObject = setTimeout(clear, timeout);
32899
33367
  const thr = { timeoutObject, clear, count: 0 };
32900
- action.set(path36, thr);
33368
+ action.set(path35, thr);
32901
33369
  return thr;
32902
33370
  }
32903
33371
  _incrReadyCount() {
@@ -32911,44 +33379,44 @@ var init_chokidar = __esm({
32911
33379
  * @param event
32912
33380
  * @param awfEmit Callback to be called when ready for event to be emitted.
32913
33381
  */
32914
- _awaitWriteFinish(path36, threshold, event, awfEmit) {
33382
+ _awaitWriteFinish(path35, threshold, event, awfEmit) {
32915
33383
  const awf = this.options.awaitWriteFinish;
32916
33384
  if (typeof awf !== "object")
32917
33385
  return;
32918
33386
  const pollInterval = awf.pollInterval;
32919
33387
  let timeoutHandler;
32920
- let fullPath = path36;
32921
- if (this.options.cwd && !sp2.isAbsolute(path36)) {
32922
- fullPath = sp2.join(this.options.cwd, path36);
33388
+ let fullPath = path35;
33389
+ if (this.options.cwd && !sp2.isAbsolute(path35)) {
33390
+ fullPath = sp2.join(this.options.cwd, path35);
32923
33391
  }
32924
33392
  const now = /* @__PURE__ */ new Date();
32925
33393
  const writes = this._pendingWrites;
32926
33394
  function awaitWriteFinishFn(prevStat) {
32927
33395
  (0, import_node_fs2.stat)(fullPath, (err, curStat) => {
32928
- if (err || !writes.has(path36)) {
33396
+ if (err || !writes.has(path35)) {
32929
33397
  if (err && err.code !== "ENOENT")
32930
33398
  awfEmit(err);
32931
33399
  return;
32932
33400
  }
32933
33401
  const now2 = Number(/* @__PURE__ */ new Date());
32934
33402
  if (prevStat && curStat.size !== prevStat.size) {
32935
- writes.get(path36).lastChange = now2;
33403
+ writes.get(path35).lastChange = now2;
32936
33404
  }
32937
- const pw = writes.get(path36);
33405
+ const pw = writes.get(path35);
32938
33406
  const df = now2 - pw.lastChange;
32939
33407
  if (df >= threshold) {
32940
- writes.delete(path36);
33408
+ writes.delete(path35);
32941
33409
  awfEmit(void 0, curStat);
32942
33410
  } else {
32943
33411
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
32944
33412
  }
32945
33413
  });
32946
33414
  }
32947
- if (!writes.has(path36)) {
32948
- writes.set(path36, {
33415
+ if (!writes.has(path35)) {
33416
+ writes.set(path35, {
32949
33417
  lastChange: now,
32950
33418
  cancelWait: () => {
32951
- writes.delete(path36);
33419
+ writes.delete(path35);
32952
33420
  clearTimeout(timeoutHandler);
32953
33421
  return event;
32954
33422
  }
@@ -32959,8 +33427,8 @@ var init_chokidar = __esm({
32959
33427
  /**
32960
33428
  * Determines whether user has asked to ignore this path.
32961
33429
  */
32962
- _isIgnored(path36, stats) {
32963
- if (this.options.atomic && DOT_RE.test(path36))
33430
+ _isIgnored(path35, stats) {
33431
+ if (this.options.atomic && DOT_RE.test(path35))
32964
33432
  return true;
32965
33433
  if (!this._userIgnored) {
32966
33434
  const { cwd } = this.options;
@@ -32970,17 +33438,17 @@ var init_chokidar = __esm({
32970
33438
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
32971
33439
  this._userIgnored = anymatch(list, void 0);
32972
33440
  }
32973
- return this._userIgnored(path36, stats);
33441
+ return this._userIgnored(path35, stats);
32974
33442
  }
32975
- _isntIgnored(path36, stat4) {
32976
- return !this._isIgnored(path36, stat4);
33443
+ _isntIgnored(path35, stat4) {
33444
+ return !this._isIgnored(path35, stat4);
32977
33445
  }
32978
33446
  /**
32979
33447
  * Provides a set of common helpers and properties relating to symlink handling.
32980
33448
  * @param path file or directory pattern being watched
32981
33449
  */
32982
- _getWatchHelpers(path36) {
32983
- return new WatchHelper(path36, this.options.followSymlinks, this);
33450
+ _getWatchHelpers(path35) {
33451
+ return new WatchHelper(path35, this.options.followSymlinks, this);
32984
33452
  }
32985
33453
  // Directory helpers
32986
33454
  // -----------------
@@ -33012,63 +33480,63 @@ var init_chokidar = __esm({
33012
33480
  * @param item base path of item/directory
33013
33481
  */
33014
33482
  _remove(directory, item, isDirectory) {
33015
- const path36 = sp2.join(directory, item);
33016
- const fullPath = sp2.resolve(path36);
33017
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path36) || this._watched.has(fullPath);
33018
- if (!this._throttle("remove", path36, 100))
33483
+ const path35 = sp2.join(directory, item);
33484
+ const fullPath = sp2.resolve(path35);
33485
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path35) || this._watched.has(fullPath);
33486
+ if (!this._throttle("remove", path35, 100))
33019
33487
  return;
33020
33488
  if (!isDirectory && this._watched.size === 1) {
33021
33489
  this.add(directory, item, true);
33022
33490
  }
33023
- const wp = this._getWatchedDir(path36);
33491
+ const wp = this._getWatchedDir(path35);
33024
33492
  const nestedDirectoryChildren = wp.getChildren();
33025
- nestedDirectoryChildren.forEach((nested) => this._remove(path36, nested));
33493
+ nestedDirectoryChildren.forEach((nested) => this._remove(path35, nested));
33026
33494
  const parent = this._getWatchedDir(directory);
33027
33495
  const wasTracked = parent.has(item);
33028
33496
  parent.remove(item);
33029
33497
  if (this._symlinkPaths.has(fullPath)) {
33030
33498
  this._symlinkPaths.delete(fullPath);
33031
33499
  }
33032
- let relPath = path36;
33500
+ let relPath = path35;
33033
33501
  if (this.options.cwd)
33034
- relPath = sp2.relative(this.options.cwd, path36);
33502
+ relPath = sp2.relative(this.options.cwd, path35);
33035
33503
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
33036
33504
  const event = this._pendingWrites.get(relPath).cancelWait();
33037
33505
  if (event === EVENTS.ADD)
33038
33506
  return;
33039
33507
  }
33040
- this._watched.delete(path36);
33508
+ this._watched.delete(path35);
33041
33509
  this._watched.delete(fullPath);
33042
33510
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
33043
- if (wasTracked && !this._isIgnored(path36))
33044
- this._emit(eventName, path36);
33045
- this._closePath(path36);
33511
+ if (wasTracked && !this._isIgnored(path35))
33512
+ this._emit(eventName, path35);
33513
+ this._closePath(path35);
33046
33514
  }
33047
33515
  /**
33048
33516
  * Closes all watchers for a path
33049
33517
  */
33050
- _closePath(path36) {
33051
- this._closeFile(path36);
33052
- const dir = sp2.dirname(path36);
33053
- this._getWatchedDir(dir).remove(sp2.basename(path36));
33518
+ _closePath(path35) {
33519
+ this._closeFile(path35);
33520
+ const dir = sp2.dirname(path35);
33521
+ this._getWatchedDir(dir).remove(sp2.basename(path35));
33054
33522
  }
33055
33523
  /**
33056
33524
  * Closes only file-specific watchers
33057
33525
  */
33058
- _closeFile(path36) {
33059
- const closers = this._closers.get(path36);
33526
+ _closeFile(path35) {
33527
+ const closers = this._closers.get(path35);
33060
33528
  if (!closers)
33061
33529
  return;
33062
33530
  closers.forEach((closer) => closer());
33063
- this._closers.delete(path36);
33531
+ this._closers.delete(path35);
33064
33532
  }
33065
- _addPathCloser(path36, closer) {
33533
+ _addPathCloser(path35, closer) {
33066
33534
  if (!closer)
33067
33535
  return;
33068
- let list = this._closers.get(path36);
33536
+ let list = this._closers.get(path35);
33069
33537
  if (!list) {
33070
33538
  list = [];
33071
- this._closers.set(path36, list);
33539
+ this._closers.set(path35, list);
33072
33540
  }
33073
33541
  list.push(closer);
33074
33542
  }
@@ -33117,6 +33585,7 @@ function validateProviderDefinition(raw) {
33117
33585
  warnings.push("disableUpstream is deprecated in provider definitions; use machine-level provider source policy instead");
33118
33586
  }
33119
33587
  const category = provider.category;
33588
+ const controls = Array.isArray(provider.controls) ? provider.controls : [];
33120
33589
  if (category === "cli" || category === "acp") {
33121
33590
  const spawn6 = provider.spawn;
33122
33591
  const command = spawn6 && typeof spawn6 === "object" ? spawn6.command : void 0;
@@ -33134,11 +33603,61 @@ function validateProviderDefinition(raw) {
33134
33603
  if (category === "extension" && !provider.extensionId) {
33135
33604
  warnings.push("Extension providers should have extensionId");
33136
33605
  }
33137
- for (const control of Array.isArray(provider.controls) ? provider.controls : []) {
33606
+ validateCapabilities(provider, controls, errors);
33607
+ for (const control of controls) {
33138
33608
  validateControl(control, errors);
33139
33609
  }
33140
33610
  return { errors, warnings };
33141
33611
  }
33612
+ function validateCapabilities(provider, controls, errors) {
33613
+ const capabilities = provider.capabilities;
33614
+ if (provider.contractVersion === 2) {
33615
+ if (!capabilities || typeof capabilities !== "object") {
33616
+ errors.push("contractVersion 2 providers must declare capabilities");
33617
+ return;
33618
+ }
33619
+ }
33620
+ if (!capabilities || typeof capabilities !== "object") {
33621
+ return;
33622
+ }
33623
+ const input = capabilities.input;
33624
+ if (!input || typeof input !== "object") {
33625
+ errors.push("capabilities.input is required");
33626
+ } else {
33627
+ if (typeof input.multipart !== "boolean") {
33628
+ errors.push("capabilities.input.multipart must be boolean");
33629
+ }
33630
+ if (!Array.isArray(input.mediaTypes) || input.mediaTypes.length === 0) {
33631
+ errors.push("capabilities.input.mediaTypes must be a non-empty array");
33632
+ } else if (input.mediaTypes.some((type) => typeof type !== "string" || !VALID_CAPABILITY_MEDIA_TYPES.has(type))) {
33633
+ errors.push(`capabilities.input.mediaTypes must only include: ${Array.from(VALID_CAPABILITY_MEDIA_TYPES).join(", ")}`);
33634
+ }
33635
+ }
33636
+ const output = capabilities.output;
33637
+ if (!output || typeof output !== "object") {
33638
+ errors.push("capabilities.output is required");
33639
+ } else {
33640
+ if (typeof output.richContent !== "boolean") {
33641
+ errors.push("capabilities.output.richContent must be boolean");
33642
+ }
33643
+ if (!Array.isArray(output.mediaTypes) || output.mediaTypes.length === 0) {
33644
+ errors.push("capabilities.output.mediaTypes must be a non-empty array");
33645
+ } else if (output.mediaTypes.some((type) => typeof type !== "string" || !VALID_CAPABILITY_MEDIA_TYPES.has(type))) {
33646
+ errors.push(`capabilities.output.mediaTypes must only include: ${Array.from(VALID_CAPABILITY_MEDIA_TYPES).join(", ")}`);
33647
+ }
33648
+ }
33649
+ const controlCapabilities = capabilities.controls;
33650
+ if (!controlCapabilities || typeof controlCapabilities !== "object") {
33651
+ errors.push("capabilities.controls is required");
33652
+ return;
33653
+ }
33654
+ if (typeof controlCapabilities.typedResults !== "boolean") {
33655
+ errors.push("capabilities.controls.typedResults must be boolean");
33656
+ }
33657
+ if (controls.length > 0 && controlCapabilities.typedResults !== true) {
33658
+ errors.push("providers declaring controls must set capabilities.controls.typedResults=true");
33659
+ }
33660
+ }
33142
33661
  function validateControl(control, errors) {
33143
33662
  if (!control || typeof control !== "object") {
33144
33663
  errors.push("controls: each control must be an object");
@@ -33170,10 +33689,11 @@ function validateControl(control, errors) {
33170
33689
  errors.push(`${prefix}: readFrom must be a non-empty string when provided`);
33171
33690
  }
33172
33691
  }
33173
- var KNOWN_PROVIDER_FIELDS, VALUE_CONTROL_TYPES;
33692
+ var VALID_CAPABILITY_MEDIA_TYPES, KNOWN_PROVIDER_FIELDS, VALUE_CONTROL_TYPES;
33174
33693
  var init_provider_schema = __esm({
33175
33694
  "../../oss/packages/daemon-core/src/providers/provider-schema.ts"() {
33176
33695
  "use strict";
33696
+ VALID_CAPABILITY_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
33177
33697
  KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
33178
33698
  "type",
33179
33699
  "name",
@@ -33224,6 +33744,7 @@ var init_provider_schema = __esm({
33224
33744
  "sendDelayMs",
33225
33745
  "sendKey",
33226
33746
  "submitStrategy",
33747
+ "timeouts",
33227
33748
  "disableUpstream"
33228
33749
  ]);
33229
33750
  VALUE_CONTROL_TYPES = /* @__PURE__ */ new Set(["select", "toggle", "cycle", "slider"]);
@@ -33231,12 +33752,12 @@ var init_provider_schema = __esm({
33231
33752
  });
33232
33753
 
33233
33754
  // ../../oss/packages/daemon-core/src/providers/provider-loader.ts
33234
- var fs6, path15, os16, ProviderLoader;
33755
+ var fs6, path14, os16, ProviderLoader;
33235
33756
  var init_provider_loader = __esm({
33236
33757
  "../../oss/packages/daemon-core/src/providers/provider-loader.ts"() {
33237
33758
  "use strict";
33238
33759
  fs6 = __toESM(require("fs"));
33239
- path15 = __toESM(require("path"));
33760
+ path14 = __toESM(require("path"));
33240
33761
  os16 = __toESM(require("os"));
33241
33762
  init_chokidar();
33242
33763
  init_ide_detector();
@@ -33263,9 +33784,9 @@ var init_provider_loader = __esm({
33263
33784
  static META_FILE = ".meta.json";
33264
33785
  constructor(options) {
33265
33786
  this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
33266
- this.defaultProvidersDir = path15.join(os16.homedir(), ".adhdev", "providers");
33787
+ this.defaultProvidersDir = path14.join(os16.homedir(), ".adhdev", "providers");
33267
33788
  this.userDir = this.defaultProvidersDir;
33268
- this.upstreamDir = path15.join(this.defaultProvidersDir, ".upstream");
33789
+ this.upstreamDir = path14.join(this.defaultProvidersDir, ".upstream");
33269
33790
  this.disableUpstream = false;
33270
33791
  this.applySourceConfig({
33271
33792
  userDir: options?.userDir,
@@ -33313,7 +33834,7 @@ var init_provider_loader = __esm({
33313
33834
  }
33314
33835
  this.sourceMode = nextSourceMode;
33315
33836
  this.userDir = this.explicitProviderDir || this.defaultProvidersDir;
33316
- this.upstreamDir = path15.join(this.defaultProvidersDir, ".upstream");
33837
+ this.upstreamDir = path14.join(this.defaultProvidersDir, ".upstream");
33317
33838
  this.disableUpstream = this.sourceMode === "no-upstream";
33318
33839
  if (this.explicitProviderDir) {
33319
33840
  this.log(`Config 'providerDir' applied: ${this.userDir}`);
@@ -33327,7 +33848,7 @@ var init_provider_loader = __esm({
33327
33848
  * Canonical provider directory shape for a given root.
33328
33849
  */
33329
33850
  getProviderDir(root, category, type) {
33330
- return path15.join(root, category, type);
33851
+ return path14.join(root, category, type);
33331
33852
  }
33332
33853
  /**
33333
33854
  * Canonical user override directory for a provider.
@@ -33354,7 +33875,7 @@ var init_provider_loader = __esm({
33354
33875
  resolveProviderFile(type, ...segments) {
33355
33876
  const dir = this.findProviderDirInternal(type);
33356
33877
  if (!dir) return null;
33357
- return path15.join(dir, ...segments);
33878
+ return path14.join(dir, ...segments);
33358
33879
  }
33359
33880
  /**
33360
33881
  * Load all providers (3-tier priority)
@@ -33393,7 +33914,7 @@ var init_provider_loader = __esm({
33393
33914
  if (!fs6.existsSync(this.upstreamDir)) return false;
33394
33915
  try {
33395
33916
  return fs6.readdirSync(this.upstreamDir).some(
33396
- (d) => fs6.statSync(path15.join(this.upstreamDir, d)).isDirectory()
33917
+ (d) => fs6.statSync(path14.join(this.upstreamDir, d)).isDirectory()
33397
33918
  );
33398
33919
  } catch {
33399
33920
  return false;
@@ -33708,8 +34229,8 @@ var init_provider_loader = __esm({
33708
34229
  resolved._resolvedScriptDir = entry.scriptDir;
33709
34230
  resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
33710
34231
  if (providerDir) {
33711
- const fullDir = path15.join(providerDir, entry.scriptDir);
33712
- resolved._resolvedScriptsPath = fs6.existsSync(path15.join(fullDir, "scripts.js")) ? path15.join(fullDir, "scripts.js") : fullDir;
34232
+ const fullDir = path14.join(providerDir, entry.scriptDir);
34233
+ resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
33713
34234
  }
33714
34235
  matched = true;
33715
34236
  }
@@ -33724,8 +34245,8 @@ var init_provider_loader = __esm({
33724
34245
  resolved._resolvedScriptDir = base.defaultScriptDir;
33725
34246
  resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
33726
34247
  if (providerDir) {
33727
- const fullDir = path15.join(providerDir, base.defaultScriptDir);
33728
- resolved._resolvedScriptsPath = fs6.existsSync(path15.join(fullDir, "scripts.js")) ? path15.join(fullDir, "scripts.js") : fullDir;
34248
+ const fullDir = path14.join(providerDir, base.defaultScriptDir);
34249
+ resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
33729
34250
  }
33730
34251
  }
33731
34252
  resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
@@ -33742,8 +34263,8 @@ var init_provider_loader = __esm({
33742
34263
  resolved._resolvedScriptDir = dirOverride;
33743
34264
  resolved._resolvedScriptsSource = `versions:${range}`;
33744
34265
  if (providerDir) {
33745
- const fullDir = path15.join(providerDir, dirOverride);
33746
- resolved._resolvedScriptsPath = fs6.existsSync(path15.join(fullDir, "scripts.js")) ? path15.join(fullDir, "scripts.js") : fullDir;
34266
+ const fullDir = path14.join(providerDir, dirOverride);
34267
+ resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
33747
34268
  }
33748
34269
  }
33749
34270
  } else if (override.scripts) {
@@ -33759,8 +34280,8 @@ var init_provider_loader = __esm({
33759
34280
  resolved._resolvedScriptDir = base.defaultScriptDir;
33760
34281
  resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
33761
34282
  if (providerDir) {
33762
- const fullDir = path15.join(providerDir, base.defaultScriptDir);
33763
- resolved._resolvedScriptsPath = fs6.existsSync(path15.join(fullDir, "scripts.js")) ? path15.join(fullDir, "scripts.js") : fullDir;
34283
+ const fullDir = path14.join(providerDir, base.defaultScriptDir);
34284
+ resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
33764
34285
  }
33765
34286
  }
33766
34287
  }
@@ -33785,14 +34306,14 @@ var init_provider_loader = __esm({
33785
34306
  this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
33786
34307
  return null;
33787
34308
  }
33788
- const dir = path15.join(providerDir, scriptDir);
34309
+ const dir = path14.join(providerDir, scriptDir);
33789
34310
  if (!fs6.existsSync(dir)) {
33790
34311
  this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
33791
34312
  return null;
33792
34313
  }
33793
34314
  const cached2 = this.scriptsCache.get(dir);
33794
34315
  if (cached2) return cached2;
33795
- const scriptsJs = path15.join(dir, "scripts.js");
34316
+ const scriptsJs = path14.join(dir, "scripts.js");
33796
34317
  if (fs6.existsSync(scriptsJs)) {
33797
34318
  try {
33798
34319
  delete require.cache[require.resolve(scriptsJs)];
@@ -33834,7 +34355,7 @@ var init_provider_loader = __esm({
33834
34355
  return;
33835
34356
  }
33836
34357
  if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
33837
- this.log(`File changed: ${path15.basename(filePath)}, reloading...`);
34358
+ this.log(`File changed: ${path14.basename(filePath)}, reloading...`);
33838
34359
  this.reload();
33839
34360
  }
33840
34361
  };
@@ -33889,7 +34410,7 @@ var init_provider_loader = __esm({
33889
34410
  }
33890
34411
  const https = require("https");
33891
34412
  const { execSync: execSync8 } = require("child_process");
33892
- const metaPath = path15.join(this.upstreamDir, _ProviderLoader.META_FILE);
34413
+ const metaPath = path14.join(this.upstreamDir, _ProviderLoader.META_FILE);
33893
34414
  let prevEtag = "";
33894
34415
  let prevTimestamp = 0;
33895
34416
  try {
@@ -33949,17 +34470,17 @@ var init_provider_loader = __esm({
33949
34470
  return { updated: false };
33950
34471
  }
33951
34472
  this.log("Downloading latest providers from GitHub...");
33952
- const tmpTar = path15.join(os16.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
33953
- const tmpExtract = path15.join(os16.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
34473
+ const tmpTar = path14.join(os16.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
34474
+ const tmpExtract = path14.join(os16.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
33954
34475
  await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
33955
34476
  fs6.mkdirSync(tmpExtract, { recursive: true });
33956
34477
  execSync8(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
33957
34478
  const extracted = fs6.readdirSync(tmpExtract);
33958
34479
  const rootDir = extracted.find(
33959
- (d) => fs6.statSync(path15.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
34480
+ (d) => fs6.statSync(path14.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
33960
34481
  );
33961
34482
  if (!rootDir) throw new Error("Unexpected tarball structure");
33962
- const sourceDir = path15.join(tmpExtract, rootDir);
34483
+ const sourceDir = path14.join(tmpExtract, rootDir);
33963
34484
  const backupDir = this.upstreamDir + ".bak";
33964
34485
  if (fs6.existsSync(this.upstreamDir)) {
33965
34486
  if (fs6.existsSync(backupDir)) fs6.rmSync(backupDir, { recursive: true, force: true });
@@ -34034,8 +34555,8 @@ var init_provider_loader = __esm({
34034
34555
  copyDirRecursive(src, dest) {
34035
34556
  fs6.mkdirSync(dest, { recursive: true });
34036
34557
  for (const entry of fs6.readdirSync(src, { withFileTypes: true })) {
34037
- const srcPath = path15.join(src, entry.name);
34038
- const destPath = path15.join(dest, entry.name);
34558
+ const srcPath = path14.join(src, entry.name);
34559
+ const destPath = path14.join(dest, entry.name);
34039
34560
  if (entry.isDirectory()) {
34040
34561
  this.copyDirRecursive(srcPath, destPath);
34041
34562
  } else {
@@ -34046,7 +34567,7 @@ var init_provider_loader = __esm({
34046
34567
  /** .meta.json save */
34047
34568
  writeMeta(metaPath, etag, timestamp) {
34048
34569
  try {
34049
- fs6.mkdirSync(path15.dirname(metaPath), { recursive: true });
34570
+ fs6.mkdirSync(path14.dirname(metaPath), { recursive: true });
34050
34571
  fs6.writeFileSync(metaPath, JSON.stringify({
34051
34572
  etag,
34052
34573
  timestamp,
@@ -34063,7 +34584,7 @@ var init_provider_loader = __esm({
34063
34584
  const scan = (d) => {
34064
34585
  try {
34065
34586
  for (const entry of fs6.readdirSync(d, { withFileTypes: true })) {
34066
- if (entry.isDirectory()) scan(path15.join(d, entry.name));
34587
+ if (entry.isDirectory()) scan(path14.join(d, entry.name));
34067
34588
  else if (entry.name === "provider.json") count++;
34068
34589
  }
34069
34590
  } catch {
@@ -34248,17 +34769,17 @@ var init_provider_loader = __esm({
34248
34769
  for (const root of searchRoots) {
34249
34770
  if (!fs6.existsSync(root)) continue;
34250
34771
  const candidate = this.getProviderDir(root, cat, type);
34251
- if (fs6.existsSync(path15.join(candidate, "provider.json"))) return candidate;
34252
- const catDir = path15.join(root, cat);
34772
+ if (fs6.existsSync(path14.join(candidate, "provider.json"))) return candidate;
34773
+ const catDir = path14.join(root, cat);
34253
34774
  if (fs6.existsSync(catDir)) {
34254
34775
  try {
34255
34776
  for (const entry of fs6.readdirSync(catDir, { withFileTypes: true })) {
34256
34777
  if (!entry.isDirectory()) continue;
34257
- const jsonPath = path15.join(catDir, entry.name, "provider.json");
34778
+ const jsonPath = path14.join(catDir, entry.name, "provider.json");
34258
34779
  if (fs6.existsSync(jsonPath)) {
34259
34780
  try {
34260
34781
  const data = JSON.parse(fs6.readFileSync(jsonPath, "utf-8"));
34261
- if (data.type === type) return path15.join(catDir, entry.name);
34782
+ if (data.type === type) return path14.join(catDir, entry.name);
34262
34783
  } catch {
34263
34784
  }
34264
34785
  }
@@ -34275,7 +34796,7 @@ var init_provider_loader = __esm({
34275
34796
  * (template substitution is NOT applied here — scripts.js handles that)
34276
34797
  */
34277
34798
  buildScriptWrappersFromDir(dir) {
34278
- const scriptsJs = path15.join(dir, "scripts.js");
34799
+ const scriptsJs = path14.join(dir, "scripts.js");
34279
34800
  if (fs6.existsSync(scriptsJs)) {
34280
34801
  try {
34281
34802
  delete require.cache[require.resolve(scriptsJs)];
@@ -34289,7 +34810,7 @@ var init_provider_loader = __esm({
34289
34810
  for (const file2 of fs6.readdirSync(dir)) {
34290
34811
  if (!file2.endsWith(".js")) continue;
34291
34812
  const scriptName = toCamel(file2.replace(".js", ""));
34292
- const filePath = path15.join(dir, file2);
34813
+ const filePath = path14.join(dir, file2);
34293
34814
  result[scriptName] = (...args) => {
34294
34815
  try {
34295
34816
  let content = fs6.readFileSync(filePath, "utf-8");
@@ -34349,7 +34870,7 @@ var init_provider_loader = __esm({
34349
34870
  }
34350
34871
  const hasJson = entries.some((e) => e.name === "provider.json");
34351
34872
  if (hasJson) {
34352
- const jsonPath = path15.join(d, "provider.json");
34873
+ const jsonPath = path14.join(d, "provider.json");
34353
34874
  try {
34354
34875
  const raw = fs6.readFileSync(jsonPath, "utf-8");
34355
34876
  const mod = JSON.parse(raw);
@@ -34370,7 +34891,7 @@ var init_provider_loader = __esm({
34370
34891
  this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
34371
34892
  } else {
34372
34893
  const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
34373
- const scriptsPath = path15.join(d, "scripts.js");
34894
+ const scriptsPath = path14.join(d, "scripts.js");
34374
34895
  if (!hasCompatibility && fs6.existsSync(scriptsPath)) {
34375
34896
  try {
34376
34897
  delete require.cache[require.resolve(scriptsPath)];
@@ -34396,7 +34917,7 @@ var init_provider_loader = __esm({
34396
34917
  if (!entry.isDirectory()) continue;
34397
34918
  if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
34398
34919
  if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
34399
- scan(path15.join(d, entry.name));
34920
+ scan(path14.join(d, entry.name));
34400
34921
  }
34401
34922
  }
34402
34923
  };
@@ -34655,8 +35176,8 @@ function detectCurrentWorkspace(ideId) {
34655
35176
  const appNameMap = getMacAppIdentifiers();
34656
35177
  const appName = appNameMap[ideId];
34657
35178
  if (appName) {
34658
- const storagePath = path16.join(
34659
- process.env.APPDATA || path16.join(os17.homedir(), "AppData", "Roaming"),
35179
+ const storagePath = path15.join(
35180
+ process.env.APPDATA || path15.join(os17.homedir(), "AppData", "Roaming"),
34660
35181
  appName,
34661
35182
  "storage.json"
34662
35183
  );
@@ -34827,14 +35348,14 @@ async function launchLinux(ide, port, workspace, newWindow) {
34827
35348
  function getAvailableIdeIds() {
34828
35349
  return getProviderLoader().getAvailableIdeTypes();
34829
35350
  }
34830
- var import_child_process6, net2, os17, path16, _providerLoader;
35351
+ var import_child_process6, net2, os17, path15, _providerLoader;
34831
35352
  var init_launch = __esm({
34832
35353
  "../../oss/packages/daemon-core/src/launch.ts"() {
34833
35354
  "use strict";
34834
35355
  import_child_process6 = require("child_process");
34835
35356
  net2 = __toESM(require("net"));
34836
35357
  os17 = __toESM(require("os"));
34837
- path16 = __toESM(require("path"));
35358
+ path15 = __toESM(require("path"));
34838
35359
  init_ide_detector();
34839
35360
  init_provider_loader();
34840
35361
  _providerLoader = null;
@@ -34865,7 +35386,7 @@ function checkRotation() {
34865
35386
  const today = getDateStr2();
34866
35387
  if (today !== currentDate2) {
34867
35388
  currentDate2 = today;
34868
- currentFile = path17.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
35389
+ currentFile = path16.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
34869
35390
  cleanOldFiles();
34870
35391
  }
34871
35392
  }
@@ -34879,7 +35400,7 @@ function cleanOldFiles() {
34879
35400
  const dateMatch = file2.match(/commands-(\d{4}-\d{2}-\d{2})/);
34880
35401
  if (dateMatch && dateMatch[1] < cutoffStr) {
34881
35402
  try {
34882
- fs7.unlinkSync(path17.join(LOG_DIR2, file2));
35403
+ fs7.unlinkSync(path16.join(LOG_DIR2, file2));
34883
35404
  } catch {
34884
35405
  }
34885
35406
  }
@@ -34948,14 +35469,14 @@ function getRecentCommands(count = 50) {
34948
35469
  return [];
34949
35470
  }
34950
35471
  }
34951
- var fs7, path17, os18, LOG_DIR2, MAX_FILE_SIZE, MAX_DAYS, SENSITIVE_KEYS, currentDate2, currentFile, writeCount2, SKIP_COMMANDS;
35472
+ var fs7, path16, os18, LOG_DIR2, MAX_FILE_SIZE, MAX_DAYS, SENSITIVE_KEYS, currentDate2, currentFile, writeCount2, SKIP_COMMANDS;
34952
35473
  var init_command_log = __esm({
34953
35474
  "../../oss/packages/daemon-core/src/logging/command-log.ts"() {
34954
35475
  "use strict";
34955
35476
  fs7 = __toESM(require("fs"));
34956
- path17 = __toESM(require("path"));
35477
+ path16 = __toESM(require("path"));
34957
35478
  os18 = __toESM(require("os"));
34958
- LOG_DIR2 = process.platform === "win32" ? path17.join(process.env.LOCALAPPDATA || process.env.APPDATA || path17.join(os18.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path17.join(os18.homedir(), "Library", "Logs", "adhdev") : path17.join(os18.homedir(), ".local", "share", "adhdev", "logs");
35479
+ LOG_DIR2 = process.platform === "win32" ? path16.join(process.env.LOCALAPPDATA || process.env.APPDATA || path16.join(os18.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path16.join(os18.homedir(), "Library", "Logs", "adhdev") : path16.join(os18.homedir(), ".local", "share", "adhdev", "logs");
34959
35480
  MAX_FILE_SIZE = 5 * 1024 * 1024;
34960
35481
  MAX_DAYS = 7;
34961
35482
  try {
@@ -34974,7 +35495,7 @@ var init_command_log = __esm({
34974
35495
  "text"
34975
35496
  ]);
34976
35497
  currentDate2 = getDateStr2();
34977
- currentFile = path17.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
35498
+ currentFile = path16.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
34978
35499
  writeCount2 = 0;
34979
35500
  SKIP_COMMANDS = /* @__PURE__ */ new Set([
34980
35501
  "heartbeat",
@@ -35128,6 +35649,9 @@ function parseMessageTime(value) {
35128
35649
  }
35129
35650
  return 0;
35130
35651
  }
35652
+ function getMessageEventTime(message) {
35653
+ return parseMessageTime(message?.receivedAt) || parseMessageTime(message?.timestamp) || 0;
35654
+ }
35131
35655
  function stringifyPreviewContent(content) {
35132
35656
  if (typeof content === "string") return content;
35133
35657
  if (Array.isArray(content)) {
@@ -35172,7 +35696,7 @@ function getLastDisplayMessage(session) {
35172
35696
  return {
35173
35697
  role,
35174
35698
  preview,
35175
- receivedAt: parseMessageTime(candidate?.receivedAt),
35699
+ receivedAt: getMessageEventTime(candidate),
35176
35700
  hash: simplePreviewHash(`${role}:${preview}`)
35177
35701
  };
35178
35702
  }
@@ -35181,7 +35705,7 @@ function getLastDisplayMessage(session) {
35181
35705
  function getSessionMessageUpdatedAt(session) {
35182
35706
  const lastMessage = session.activeChat?.messages?.at?.(-1);
35183
35707
  if (!lastMessage) return 0;
35184
- return parseMessageTime(lastMessage.receivedAt) || 0;
35708
+ return getMessageEventTime(lastMessage);
35185
35709
  }
35186
35710
  function getSessionCompletionMarker(session) {
35187
35711
  const lastMessage = session.activeChat?.messages?.at?.(-1);
@@ -35191,7 +35715,7 @@ function getSessionCompletionMarker(session) {
35191
35715
  if (typeof lastMessage._turnKey === "string" && lastMessage._turnKey) return `turn:${lastMessage._turnKey}`;
35192
35716
  if (typeof lastMessage.id === "string" && lastMessage.id) return `id:${lastMessage.id}`;
35193
35717
  if (typeof lastMessage.index === "number" && Number.isFinite(lastMessage.index)) return `idx:${lastMessage.index}`;
35194
- const timestamp = parseMessageTime(lastMessage.receivedAt);
35718
+ const timestamp = getMessageEventTime(lastMessage);
35195
35719
  return timestamp > 0 ? `ts:${timestamp}` : "";
35196
35720
  }
35197
35721
  function getSessionLastUsedAt(session) {
@@ -35331,9 +35855,9 @@ var init_snapshot = __esm({
35331
35855
  // ../../oss/packages/daemon-core/src/commands/upgrade-helper.ts
35332
35856
  function getUpgradeLogPath() {
35333
35857
  const home = os20.homedir();
35334
- const dir = path18.join(home, ".adhdev");
35858
+ const dir = path17.join(home, ".adhdev");
35335
35859
  fs8.mkdirSync(dir, { recursive: true });
35336
- return path18.join(dir, "daemon-upgrade.log");
35860
+ return path17.join(dir, "daemon-upgrade.log");
35337
35861
  }
35338
35862
  function appendUpgradeLog(message) {
35339
35863
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
@@ -35373,7 +35897,7 @@ async function waitForPidExit(pid, timeoutMs) {
35373
35897
  }
35374
35898
  }
35375
35899
  function stopSessionHostProcesses(appName) {
35376
- const pidFile = path18.join(os20.homedir(), ".adhdev", `${appName}-session-host.pid`);
35900
+ const pidFile = path17.join(os20.homedir(), ".adhdev", `${appName}-session-host.pid`);
35377
35901
  try {
35378
35902
  if (fs8.existsSync(pidFile)) {
35379
35903
  const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
@@ -35402,7 +35926,7 @@ function stopSessionHostProcesses(appName) {
35402
35926
  }
35403
35927
  }
35404
35928
  function removeDaemonPidFile() {
35405
- const pidFile = path18.join(os20.homedir(), ".adhdev", "daemon.pid");
35929
+ const pidFile = path17.join(os20.homedir(), ".adhdev", "daemon.pid");
35406
35930
  try {
35407
35931
  fs8.unlinkSync(pidFile);
35408
35932
  } catch {
@@ -35413,7 +35937,7 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
35413
35937
  const npmRoot = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["root", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
35414
35938
  if (!npmRoot) return;
35415
35939
  const npmPrefix = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["prefix", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
35416
- const binDir = process.platform === "win32" ? npmPrefix : path18.join(npmPrefix, "bin");
35940
+ const binDir = process.platform === "win32" ? npmPrefix : path17.join(npmPrefix, "bin");
35417
35941
  const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
35418
35942
  const binNames = /* @__PURE__ */ new Set([packageBaseName]);
35419
35943
  if (pkgName === "@adhdev/daemon-standalone") {
@@ -35421,25 +35945,25 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
35421
35945
  }
35422
35946
  if (pkgName.startsWith("@")) {
35423
35947
  const [scope, name] = pkgName.split("/");
35424
- const scopeDir = path18.join(npmRoot, scope);
35948
+ const scopeDir = path17.join(npmRoot, scope);
35425
35949
  if (!fs8.existsSync(scopeDir)) return;
35426
35950
  for (const entry of fs8.readdirSync(scopeDir)) {
35427
35951
  if (!entry.startsWith(`.${name}-`)) continue;
35428
- fs8.rmSync(path18.join(scopeDir, entry), { recursive: true, force: true });
35429
- appendUpgradeLog(`Removed stale scoped staging dir: ${path18.join(scopeDir, entry)}`);
35952
+ fs8.rmSync(path17.join(scopeDir, entry), { recursive: true, force: true });
35953
+ appendUpgradeLog(`Removed stale scoped staging dir: ${path17.join(scopeDir, entry)}`);
35430
35954
  }
35431
35955
  } else {
35432
35956
  for (const entry of fs8.readdirSync(npmRoot)) {
35433
35957
  if (!entry.startsWith(`.${pkgName}-`)) continue;
35434
- fs8.rmSync(path18.join(npmRoot, entry), { recursive: true, force: true });
35435
- appendUpgradeLog(`Removed stale staging dir: ${path18.join(npmRoot, entry)}`);
35958
+ fs8.rmSync(path17.join(npmRoot, entry), { recursive: true, force: true });
35959
+ appendUpgradeLog(`Removed stale staging dir: ${path17.join(npmRoot, entry)}`);
35436
35960
  }
35437
35961
  }
35438
35962
  if (fs8.existsSync(binDir)) {
35439
35963
  for (const entry of fs8.readdirSync(binDir)) {
35440
35964
  if (![...binNames].some((name) => entry.startsWith(`.${name}-`))) continue;
35441
- fs8.rmSync(path18.join(binDir, entry), { recursive: true, force: true });
35442
- appendUpgradeLog(`Removed stale bin staging entry: ${path18.join(binDir, entry)}`);
35965
+ fs8.rmSync(path17.join(binDir, entry), { recursive: true, force: true });
35966
+ appendUpgradeLog(`Removed stale bin staging entry: ${path17.join(binDir, entry)}`);
35443
35967
  }
35444
35968
  }
35445
35969
  }
@@ -35514,7 +36038,7 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
35514
36038
  process.exit(1);
35515
36039
  }
35516
36040
  }
35517
- var import_child_process7, import_child_process8, fs8, os20, path18, UPGRADE_HELPER_ENV;
36041
+ var import_child_process7, import_child_process8, fs8, os20, path17, UPGRADE_HELPER_ENV;
35518
36042
  var init_upgrade_helper = __esm({
35519
36043
  "../../oss/packages/daemon-core/src/commands/upgrade-helper.ts"() {
35520
36044
  "use strict";
@@ -35522,7 +36046,7 @@ var init_upgrade_helper = __esm({
35522
36046
  import_child_process8 = require("child_process");
35523
36047
  fs8 = __toESM(require("fs"));
35524
36048
  os20 = __toESM(require("os"));
35525
- path18 = __toESM(require("path"));
36049
+ path17 = __toESM(require("path"));
35526
36050
  UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
35527
36051
  }
35528
36052
  });
@@ -36523,7 +37047,9 @@ var init_provider_adapter = __esm({
36523
37047
  "../../oss/packages/daemon-core/src/agent-stream/provider-adapter.ts"() {
36524
37048
  "use strict";
36525
37049
  init_control_effects();
37050
+ init_read_chat_contract();
36526
37051
  init_provider_patch_state();
37052
+ init_chat_message_normalization();
36527
37053
  ProviderStreamAdapter = class {
36528
37054
  agentType;
36529
37055
  agentName;
@@ -36628,26 +37154,29 @@ var init_provider_adapter = __esm({
36628
37154
  }
36629
37155
  return state2;
36630
37156
  }
37157
+ const validated = validateReadChatResultPayload(data, `${this.agentType} readChat`);
37158
+ const validatedStatus = validated.status;
37159
+ const streamStatus = validatedStatus === "generating" || validatedStatus === "long_generating" ? "streaming" : validatedStatus;
36631
37160
  const state = {
36632
37161
  agentType: this.agentType,
36633
37162
  agentName: this.agentName,
36634
37163
  extensionId: this.extensionId,
36635
- status: data.status || "idle",
36636
- messages: data.messages || [],
36637
- inputContent: data.inputContent || "",
36638
- activeModal: data.activeModal
37164
+ status: streamStatus,
37165
+ messages: normalizeChatMessages(validated.messages),
37166
+ inputContent: typeof validated.inputContent === "string" ? validated.inputContent : "",
37167
+ ...validated.activeModal ? { activeModal: validated.activeModal } : {}
36639
37168
  };
36640
- if (typeof data.title === "string" && data.title.trim()) {
36641
- state.title = data.title.trim();
37169
+ if (typeof validated.title === "string" && validated.title.trim()) {
37170
+ state.title = validated.title.trim();
36642
37171
  }
36643
- const controlValues = extractProviderControlValues(this.provider.controls, data);
37172
+ const controlValues = extractProviderControlValues(this.provider.controls, validated);
36644
37173
  const surface = resolveProviderStateSurface({
36645
37174
  controlValues,
36646
- summaryMetadata: data.summaryMetadata
37175
+ summaryMetadata: validated.summaryMetadata
36647
37176
  });
36648
37177
  if (surface.controlValues) state.controlValues = surface.controlValues;
36649
37178
  if (surface.summaryMetadata) state.summaryMetadata = surface.summaryMetadata;
36650
- const effects = normalizeProviderEffects(data);
37179
+ const effects = normalizeProviderEffects(validated);
36651
37180
  if (effects.length > 0) state.effects = effects;
36652
37181
  if (state.messages.length > 0) {
36653
37182
  this.lastSuccessState = state;
@@ -37584,7 +38113,7 @@ function checkPathExists2(paths) {
37584
38113
  for (const p of paths) {
37585
38114
  if (p.includes("*")) {
37586
38115
  const home = os21.homedir();
37587
- const resolved = p.replace(/\*/g, home.split(path19.sep).pop() || "");
38116
+ const resolved = p.replace(/\*/g, home.split(path18.sep).pop() || "");
37588
38117
  if (fs10.existsSync(resolved)) return resolved;
37589
38118
  } else {
37590
38119
  if (fs10.existsSync(p)) return p;
@@ -37594,7 +38123,7 @@ function checkPathExists2(paths) {
37594
38123
  }
37595
38124
  function getMacAppVersion(appPath) {
37596
38125
  if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
37597
- const plistPath = path19.join(appPath, "Contents", "Info.plist");
38126
+ const plistPath = path18.join(appPath, "Contents", "Info.plist");
37598
38127
  if (!fs10.existsSync(plistPath)) return null;
37599
38128
  const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
37600
38129
  return raw || null;
@@ -37620,7 +38149,7 @@ async function detectAllVersions(loader, archive) {
37620
38149
  const cliBin = provider.cli ? findBinary2(provider.cli) : null;
37621
38150
  let resolvedBin = cliBin;
37622
38151
  if (!resolvedBin && appPath && currentOs === "darwin") {
37623
- const bundled = path19.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
38152
+ const bundled = path18.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
37624
38153
  if (provider.cli && fs10.existsSync(bundled)) resolvedBin = bundled;
37625
38154
  }
37626
38155
  info.installed = !!(appPath || resolvedBin);
@@ -37657,16 +38186,16 @@ async function detectAllVersions(loader, archive) {
37657
38186
  }
37658
38187
  return results;
37659
38188
  }
37660
- var fs10, path19, os21, import_child_process9, import_os3, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive;
38189
+ var fs10, path18, os21, import_child_process9, import_os3, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive;
37661
38190
  var init_version_archive = __esm({
37662
38191
  "../../oss/packages/daemon-core/src/providers/version-archive.ts"() {
37663
38192
  "use strict";
37664
38193
  fs10 = __toESM(require("fs"));
37665
- path19 = __toESM(require("path"));
38194
+ path18 = __toESM(require("path"));
37666
38195
  os21 = __toESM(require("os"));
37667
38196
  import_child_process9 = require("child_process");
37668
38197
  import_os3 = require("os");
37669
- ARCHIVE_PATH = path19.join(os21.homedir(), ".adhdev", "version-history.json");
38198
+ ARCHIVE_PATH = path18.join(os21.homedir(), ".adhdev", "version-history.json");
37670
38199
  MAX_ENTRIES_PER_PROVIDER = 20;
37671
38200
  VersionArchive = class {
37672
38201
  history = {};
@@ -37713,7 +38242,7 @@ var init_version_archive = __esm({
37713
38242
  }
37714
38243
  save() {
37715
38244
  try {
37716
- fs10.mkdirSync(path19.dirname(ARCHIVE_PATH), { recursive: true });
38245
+ fs10.mkdirSync(path18.dirname(ARCHIVE_PATH), { recursive: true });
37717
38246
  fs10.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
37718
38247
  } catch {
37719
38248
  }
@@ -38241,17 +38770,17 @@ async function handleScriptHints(ctx, type, _req, res) {
38241
38770
  return;
38242
38771
  }
38243
38772
  let scriptsPath = "";
38244
- const directScripts = path20.join(dir, "scripts.js");
38773
+ const directScripts = path19.join(dir, "scripts.js");
38245
38774
  if (fs11.existsSync(directScripts)) {
38246
38775
  scriptsPath = directScripts;
38247
38776
  } else {
38248
- const scriptsDir = path20.join(dir, "scripts");
38777
+ const scriptsDir = path19.join(dir, "scripts");
38249
38778
  if (fs11.existsSync(scriptsDir)) {
38250
38779
  const versions = fs11.readdirSync(scriptsDir).filter((d) => {
38251
- return fs11.statSync(path20.join(scriptsDir, d)).isDirectory();
38780
+ return fs11.statSync(path19.join(scriptsDir, d)).isDirectory();
38252
38781
  }).sort().reverse();
38253
38782
  for (const ver of versions) {
38254
- const p = path20.join(scriptsDir, ver, "scripts.js");
38783
+ const p = path19.join(scriptsDir, ver, "scripts.js");
38255
38784
  if (fs11.existsSync(p)) {
38256
38785
  scriptsPath = p;
38257
38786
  break;
@@ -39077,12 +39606,12 @@ async function handleDomContext(ctx, type, req, res) {
39077
39606
  ctx.json(res, 500, { error: `DOM context collection failed: ${e.message}` });
39078
39607
  }
39079
39608
  }
39080
- var fs11, path20;
39609
+ var fs11, path19;
39081
39610
  var init_dev_cdp_handlers = __esm({
39082
39611
  "../../oss/packages/daemon-core/src/daemon/dev-cdp-handlers.ts"() {
39083
39612
  "use strict";
39084
39613
  fs11 = __toESM(require("fs"));
39085
- path20 = __toESM(require("path"));
39614
+ path19 = __toESM(require("path"));
39086
39615
  init_logger();
39087
39616
  }
39088
39617
  });
@@ -39097,11 +39626,11 @@ function getCliFixtureDir(ctx, type) {
39097
39626
  if (!providerDir) {
39098
39627
  throw new Error(`Provider directory not found for '${type}'`);
39099
39628
  }
39100
- return path21.join(providerDir, "fixtures");
39629
+ return path20.join(providerDir, "fixtures");
39101
39630
  }
39102
39631
  function readCliFixture(ctx, type, name) {
39103
39632
  const fixtureDir = getCliFixtureDir(ctx, type);
39104
- const filePath = path21.join(fixtureDir, `${name}.json`);
39633
+ const filePath = path20.join(fixtureDir, `${name}.json`);
39105
39634
  if (!fs12.existsSync(filePath)) {
39106
39635
  throw new Error(`Fixture not found: ${filePath}`);
39107
39636
  }
@@ -39868,7 +40397,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
39868
40397
  },
39869
40398
  notes: typeof body?.notes === "string" ? body.notes : void 0
39870
40399
  };
39871
- const filePath = path21.join(fixtureDir, `${name}.json`);
40400
+ const filePath = path20.join(fixtureDir, `${name}.json`);
39872
40401
  fs12.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
39873
40402
  ctx.json(res, 200, {
39874
40403
  saved: true,
@@ -39892,7 +40421,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
39892
40421
  return;
39893
40422
  }
39894
40423
  const fixtures = fs12.readdirSync(fixtureDir).filter((file2) => file2.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file2) => {
39895
- const fullPath = path21.join(fixtureDir, file2);
40424
+ const fullPath = path20.join(fixtureDir, file2);
39896
40425
  try {
39897
40426
  const raw = JSON.parse(fs12.readFileSync(fullPath, "utf-8"));
39898
40427
  return {
@@ -40025,12 +40554,12 @@ async function handleCliRaw(ctx, req, res) {
40025
40554
  ctx.json(res, 500, { error: `Raw send failed: ${e.message}` });
40026
40555
  }
40027
40556
  }
40028
- var fs12, path21;
40557
+ var fs12, path20;
40029
40558
  var init_dev_cli_debug = __esm({
40030
40559
  "../../oss/packages/daemon-core/src/daemon/dev-cli-debug.ts"() {
40031
40560
  "use strict";
40032
40561
  fs12 = __toESM(require("fs"));
40033
- path21 = __toESM(require("path"));
40562
+ path20 = __toESM(require("path"));
40034
40563
  }
40035
40564
  });
40036
40565
 
@@ -40090,22 +40619,22 @@ function getLatestScriptVersionDir(scriptsDir) {
40090
40619
  if (!fs13.existsSync(scriptsDir)) return null;
40091
40620
  const versions = fs13.readdirSync(scriptsDir).filter((d) => {
40092
40621
  try {
40093
- return fs13.statSync(path23.join(scriptsDir, d)).isDirectory();
40622
+ return fs13.statSync(path21.join(scriptsDir, d)).isDirectory();
40094
40623
  } catch {
40095
40624
  return false;
40096
40625
  }
40097
40626
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
40098
40627
  if (versions.length === 0) return null;
40099
- return path23.join(scriptsDir, versions[0]);
40628
+ return path21.join(scriptsDir, versions[0]);
40100
40629
  }
40101
40630
  function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
40102
- const canonicalUserDir = path23.resolve(ctx.providerLoader.getUserProviderDir(category, type));
40103
- const desiredDir = requestedDir ? path23.resolve(requestedDir) : canonicalUserDir;
40104
- const upstreamRoot = path23.resolve(ctx.providerLoader.getUpstreamDir());
40105
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path23.sep}`)) {
40631
+ const canonicalUserDir = path21.resolve(ctx.providerLoader.getUserProviderDir(category, type));
40632
+ const desiredDir = requestedDir ? path21.resolve(requestedDir) : canonicalUserDir;
40633
+ const upstreamRoot = path21.resolve(ctx.providerLoader.getUpstreamDir());
40634
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path21.sep}`)) {
40106
40635
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
40107
40636
  }
40108
- if (path23.basename(desiredDir) !== type) {
40637
+ if (path21.basename(desiredDir) !== type) {
40109
40638
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
40110
40639
  }
40111
40640
  const sourceDir = ctx.findProviderDir(type);
@@ -40113,11 +40642,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
40113
40642
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
40114
40643
  }
40115
40644
  if (!fs13.existsSync(desiredDir)) {
40116
- fs13.mkdirSync(path23.dirname(desiredDir), { recursive: true });
40645
+ fs13.mkdirSync(path21.dirname(desiredDir), { recursive: true });
40117
40646
  fs13.cpSync(sourceDir, desiredDir, { recursive: true });
40118
40647
  ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
40119
40648
  }
40120
- const providerJson = path23.join(desiredDir, "provider.json");
40649
+ const providerJson = path21.join(desiredDir, "provider.json");
40121
40650
  if (!fs13.existsSync(providerJson)) {
40122
40651
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
40123
40652
  }
@@ -40128,13 +40657,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
40128
40657
  const refDir = ctx.findProviderDir(referenceType);
40129
40658
  if (!refDir || !fs13.existsSync(refDir)) return {};
40130
40659
  const referenceScripts = {};
40131
- const scriptsDir = path23.join(refDir, "scripts");
40660
+ const scriptsDir = path21.join(refDir, "scripts");
40132
40661
  const latestDir = getLatestScriptVersionDir(scriptsDir);
40133
40662
  if (!latestDir) return referenceScripts;
40134
40663
  for (const file2 of fs13.readdirSync(latestDir)) {
40135
40664
  if (!file2.endsWith(".js")) continue;
40136
40665
  try {
40137
- referenceScripts[file2] = fs13.readFileSync(path23.join(latestDir, file2), "utf-8");
40666
+ referenceScripts[file2] = fs13.readFileSync(path21.join(latestDir, file2), "utf-8");
40138
40667
  } catch {
40139
40668
  }
40140
40669
  }
@@ -40242,9 +40771,9 @@ async function handleAutoImplement(ctx, type, req, res) {
40242
40771
  });
40243
40772
  const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
40244
40773
  const prompt2 = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
40245
- const tmpDir = path23.join(os23.tmpdir(), "adhdev-autoimpl");
40774
+ const tmpDir = path21.join(os23.tmpdir(), "adhdev-autoimpl");
40246
40775
  if (!fs13.existsSync(tmpDir)) fs13.mkdirSync(tmpDir, { recursive: true });
40247
- const promptFile = path23.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
40776
+ const promptFile = path21.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
40248
40777
  fs13.writeFileSync(promptFile, prompt2, "utf-8");
40249
40778
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt2.length} chars)`);
40250
40779
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
@@ -40681,7 +41210,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
40681
41210
  setMode: "set_mode.js"
40682
41211
  };
40683
41212
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
40684
- const scriptsDir = path23.join(providerDir, "scripts");
41213
+ const scriptsDir = path21.join(providerDir, "scripts");
40685
41214
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
40686
41215
  if (latestScriptsDir) {
40687
41216
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -40692,7 +41221,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
40692
41221
  for (const file2 of fs13.readdirSync(latestScriptsDir)) {
40693
41222
  if (file2.endsWith(".js") && targetFileNames.has(file2)) {
40694
41223
  try {
40695
- const content = fs13.readFileSync(path23.join(latestScriptsDir, file2), "utf-8");
41224
+ const content = fs13.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
40696
41225
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
40697
41226
  lines.push("```javascript");
40698
41227
  lines.push(content);
@@ -40709,7 +41238,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
40709
41238
  lines.push("");
40710
41239
  for (const file2 of refFiles) {
40711
41240
  try {
40712
- const content = fs13.readFileSync(path23.join(latestScriptsDir, file2), "utf-8");
41241
+ const content = fs13.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
40713
41242
  lines.push(`### \`${file2}\` \u{1F512}`);
40714
41243
  lines.push("```javascript");
40715
41244
  lines.push(content);
@@ -40750,10 +41279,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
40750
41279
  lines.push("");
40751
41280
  }
40752
41281
  }
40753
- const docsDir = path23.join(providerDir, "../../docs");
41282
+ const docsDir = path21.join(providerDir, "../../docs");
40754
41283
  const loadGuide = (name) => {
40755
41284
  try {
40756
- const p = path23.join(docsDir, name);
41285
+ const p = path21.join(docsDir, name);
40757
41286
  if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
40758
41287
  } catch {
40759
41288
  }
@@ -40990,7 +41519,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
40990
41519
  parseApproval: "parse_approval.js"
40991
41520
  };
40992
41521
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
40993
- const scriptsDir = path23.join(providerDir, "scripts");
41522
+ const scriptsDir = path21.join(providerDir, "scripts");
40994
41523
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
40995
41524
  if (latestScriptsDir) {
40996
41525
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -41002,7 +41531,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
41002
41531
  if (!file2.endsWith(".js")) continue;
41003
41532
  if (!targetFileNames.has(file2)) continue;
41004
41533
  try {
41005
- const content = fs13.readFileSync(path23.join(latestScriptsDir, file2), "utf-8");
41534
+ const content = fs13.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
41006
41535
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
41007
41536
  lines.push("```javascript");
41008
41537
  lines.push(content);
@@ -41018,7 +41547,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
41018
41547
  lines.push("");
41019
41548
  for (const file2 of refFiles) {
41020
41549
  try {
41021
- const content = fs13.readFileSync(path23.join(latestScriptsDir, file2), "utf-8");
41550
+ const content = fs13.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
41022
41551
  lines.push(`### \`${file2}\` \u{1F512}`);
41023
41552
  lines.push("```javascript");
41024
41553
  lines.push(content);
@@ -41051,10 +41580,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
41051
41580
  lines.push("");
41052
41581
  }
41053
41582
  }
41054
- const docsDir = path23.join(providerDir, "../../docs");
41583
+ const docsDir = path21.join(providerDir, "../../docs");
41055
41584
  const loadGuide = (name) => {
41056
41585
  try {
41057
- const p = path23.join(docsDir, name);
41586
+ const p = path21.join(docsDir, name);
41058
41587
  if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
41059
41588
  } catch {
41060
41589
  }
@@ -41366,12 +41895,12 @@ data: ${JSON.stringify(msg.data)}
41366
41895
  }
41367
41896
  }
41368
41897
  }
41369
- var fs13, path23, os23;
41898
+ var fs13, path21, os23;
41370
41899
  var init_dev_auto_implement = __esm({
41371
41900
  "../../oss/packages/daemon-core/src/daemon/dev-auto-implement.ts"() {
41372
41901
  "use strict";
41373
41902
  fs13 = __toESM(require("fs"));
41374
- path23 = __toESM(require("path"));
41903
+ path21 = __toESM(require("path"));
41375
41904
  os23 = __toESM(require("os"));
41376
41905
  init_dev_server();
41377
41906
  init_dev_cli_debug();
@@ -41411,13 +41940,13 @@ function toProviderListEntry(provider) {
41411
41940
  }
41412
41941
  return base;
41413
41942
  }
41414
- var http2, fs14, path24, DEV_SERVER_PORT, DevServer;
41943
+ var http2, fs14, path23, DEV_SERVER_PORT, DevServer;
41415
41944
  var init_dev_server = __esm({
41416
41945
  "../../oss/packages/daemon-core/src/daemon/dev-server.ts"() {
41417
41946
  "use strict";
41418
41947
  http2 = __toESM(require("http"));
41419
41948
  fs14 = __toESM(require("fs"));
41420
- path24 = __toESM(require("path"));
41949
+ path23 = __toESM(require("path"));
41421
41950
  init_provider_schema();
41422
41951
  init_config();
41423
41952
  init_provider_source_config();
@@ -41529,8 +42058,8 @@ var init_dev_server = __esm({
41529
42058
  }
41530
42059
  getEndpointList() {
41531
42060
  return this.routes.map((r) => {
41532
- const path36 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
41533
- return `${r.method.padEnd(5)} ${path36}`;
42061
+ const path35 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
42062
+ return `${r.method.padEnd(5)} ${path35}`;
41534
42063
  });
41535
42064
  }
41536
42065
  async start(port = DEV_SERVER_PORT) {
@@ -41811,12 +42340,12 @@ var init_dev_server = __esm({
41811
42340
  // ─── DevConsole SPA ───
41812
42341
  getConsoleDistDir() {
41813
42342
  const candidates = [
41814
- path24.resolve(__dirname, "../../web-devconsole/dist"),
41815
- path24.resolve(__dirname, "../../../web-devconsole/dist"),
41816
- path24.join(process.cwd(), "packages/web-devconsole/dist")
42343
+ path23.resolve(__dirname, "../../web-devconsole/dist"),
42344
+ path23.resolve(__dirname, "../../../web-devconsole/dist"),
42345
+ path23.join(process.cwd(), "packages/web-devconsole/dist")
41817
42346
  ];
41818
42347
  for (const dir of candidates) {
41819
- if (fs14.existsSync(path24.join(dir, "index.html"))) return dir;
42348
+ if (fs14.existsSync(path23.join(dir, "index.html"))) return dir;
41820
42349
  }
41821
42350
  return null;
41822
42351
  }
@@ -41826,7 +42355,7 @@ var init_dev_server = __esm({
41826
42355
  this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
41827
42356
  return;
41828
42357
  }
41829
- const htmlPath = path24.join(distDir, "index.html");
42358
+ const htmlPath = path23.join(distDir, "index.html");
41830
42359
  try {
41831
42360
  const html = fs14.readFileSync(htmlPath, "utf-8");
41832
42361
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
@@ -41851,15 +42380,15 @@ var init_dev_server = __esm({
41851
42380
  this.json(res, 404, { error: "Not found" });
41852
42381
  return;
41853
42382
  }
41854
- const safePath = path24.normalize(pathname).replace(/^\.\.\//, "");
41855
- const filePath = path24.join(distDir, safePath);
42383
+ const safePath = path23.normalize(pathname).replace(/^\.\.\//, "");
42384
+ const filePath = path23.join(distDir, safePath);
41856
42385
  if (!filePath.startsWith(distDir)) {
41857
42386
  this.json(res, 403, { error: "Forbidden" });
41858
42387
  return;
41859
42388
  }
41860
42389
  try {
41861
42390
  const content = fs14.readFileSync(filePath);
41862
- const ext = path24.extname(filePath);
42391
+ const ext = path23.extname(filePath);
41863
42392
  const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
41864
42393
  res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
41865
42394
  res.end(content);
@@ -41972,9 +42501,9 @@ var init_dev_server = __esm({
41972
42501
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
41973
42502
  if (entry.isDirectory()) {
41974
42503
  files.push({ path: rel, size: 0, type: "dir" });
41975
- scan(path24.join(d, entry.name), rel);
42504
+ scan(path23.join(d, entry.name), rel);
41976
42505
  } else {
41977
- const stat4 = fs14.statSync(path24.join(d, entry.name));
42506
+ const stat4 = fs14.statSync(path23.join(d, entry.name));
41978
42507
  files.push({ path: rel, size: stat4.size, type: "file" });
41979
42508
  }
41980
42509
  }
@@ -41997,7 +42526,7 @@ var init_dev_server = __esm({
41997
42526
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
41998
42527
  return;
41999
42528
  }
42000
- const fullPath = path24.resolve(dir, path24.normalize(filePath));
42529
+ const fullPath = path23.resolve(dir, path23.normalize(filePath));
42001
42530
  if (!fullPath.startsWith(dir)) {
42002
42531
  this.json(res, 403, { error: "Forbidden" });
42003
42532
  return;
@@ -42022,14 +42551,14 @@ var init_dev_server = __esm({
42022
42551
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
42023
42552
  return;
42024
42553
  }
42025
- const fullPath = path24.resolve(dir, path24.normalize(filePath));
42554
+ const fullPath = path23.resolve(dir, path23.normalize(filePath));
42026
42555
  if (!fullPath.startsWith(dir)) {
42027
42556
  this.json(res, 403, { error: "Forbidden" });
42028
42557
  return;
42029
42558
  }
42030
42559
  try {
42031
42560
  if (fs14.existsSync(fullPath)) fs14.copyFileSync(fullPath, fullPath + ".bak");
42032
- fs14.mkdirSync(path24.dirname(fullPath), { recursive: true });
42561
+ fs14.mkdirSync(path23.dirname(fullPath), { recursive: true });
42033
42562
  fs14.writeFileSync(fullPath, content, "utf-8");
42034
42563
  this.log(`File saved: ${fullPath} (${content.length} chars)`);
42035
42564
  this.providerLoader.reload();
@@ -42046,7 +42575,7 @@ var init_dev_server = __esm({
42046
42575
  return;
42047
42576
  }
42048
42577
  for (const name of ["scripts.js", "provider.json"]) {
42049
- const p = path24.join(dir, name);
42578
+ const p = path23.join(dir, name);
42050
42579
  if (fs14.existsSync(p)) {
42051
42580
  const source = fs14.readFileSync(p, "utf-8");
42052
42581
  this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
@@ -42067,8 +42596,8 @@ var init_dev_server = __esm({
42067
42596
  this.json(res, 404, { error: `Provider not found: ${type}` });
42068
42597
  return;
42069
42598
  }
42070
- const target = fs14.existsSync(path24.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
42071
- const targetPath = path24.join(dir, target);
42599
+ const target = fs14.existsSync(path23.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
42600
+ const targetPath = path23.join(dir, target);
42072
42601
  try {
42073
42602
  if (fs14.existsSync(targetPath)) fs14.copyFileSync(targetPath, targetPath + ".bak");
42074
42603
  fs14.writeFileSync(targetPath, source, "utf-8");
@@ -42215,7 +42744,7 @@ var init_dev_server = __esm({
42215
42744
  }
42216
42745
  let targetDir;
42217
42746
  targetDir = this.providerLoader.getUserProviderDir(category, type);
42218
- const jsonPath = path24.join(targetDir, "provider.json");
42747
+ const jsonPath = path23.join(targetDir, "provider.json");
42219
42748
  if (fs14.existsSync(jsonPath)) {
42220
42749
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
42221
42750
  return;
@@ -42227,8 +42756,8 @@ var init_dev_server = __esm({
42227
42756
  const createdFiles = ["provider.json"];
42228
42757
  if (result.files) {
42229
42758
  for (const [relPath, content] of Object.entries(result.files)) {
42230
- const fullPath = path24.join(targetDir, relPath);
42231
- fs14.mkdirSync(path24.dirname(fullPath), { recursive: true });
42759
+ const fullPath = path23.join(targetDir, relPath);
42760
+ fs14.mkdirSync(path23.dirname(fullPath), { recursive: true });
42232
42761
  fs14.writeFileSync(fullPath, content, "utf-8");
42233
42762
  createdFiles.push(relPath);
42234
42763
  }
@@ -42281,22 +42810,22 @@ var init_dev_server = __esm({
42281
42810
  if (!fs14.existsSync(scriptsDir)) return null;
42282
42811
  const versions = fs14.readdirSync(scriptsDir).filter((d) => {
42283
42812
  try {
42284
- return fs14.statSync(path24.join(scriptsDir, d)).isDirectory();
42813
+ return fs14.statSync(path23.join(scriptsDir, d)).isDirectory();
42285
42814
  } catch {
42286
42815
  return false;
42287
42816
  }
42288
42817
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
42289
42818
  if (versions.length === 0) return null;
42290
- return path24.join(scriptsDir, versions[0]);
42819
+ return path23.join(scriptsDir, versions[0]);
42291
42820
  }
42292
42821
  resolveAutoImplWritableProviderDir(category, type, requestedDir) {
42293
- const canonicalUserDir = path24.resolve(this.providerLoader.getUserProviderDir(category, type));
42294
- const desiredDir = requestedDir ? path24.resolve(requestedDir) : canonicalUserDir;
42295
- const upstreamRoot = path24.resolve(this.providerLoader.getUpstreamDir());
42296
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path24.sep}`)) {
42822
+ const canonicalUserDir = path23.resolve(this.providerLoader.getUserProviderDir(category, type));
42823
+ const desiredDir = requestedDir ? path23.resolve(requestedDir) : canonicalUserDir;
42824
+ const upstreamRoot = path23.resolve(this.providerLoader.getUpstreamDir());
42825
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path23.sep}`)) {
42297
42826
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
42298
42827
  }
42299
- if (path24.basename(desiredDir) !== type) {
42828
+ if (path23.basename(desiredDir) !== type) {
42300
42829
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
42301
42830
  }
42302
42831
  const sourceDir = this.findProviderDir(type);
@@ -42304,11 +42833,11 @@ var init_dev_server = __esm({
42304
42833
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
42305
42834
  }
42306
42835
  if (!fs14.existsSync(desiredDir)) {
42307
- fs14.mkdirSync(path24.dirname(desiredDir), { recursive: true });
42836
+ fs14.mkdirSync(path23.dirname(desiredDir), { recursive: true });
42308
42837
  fs14.cpSync(sourceDir, desiredDir, { recursive: true });
42309
42838
  this.log(`Auto-implement writable copy created: ${desiredDir}`);
42310
42839
  }
42311
- const providerJson = path24.join(desiredDir, "provider.json");
42840
+ const providerJson = path23.join(desiredDir, "provider.json");
42312
42841
  if (!fs14.existsSync(providerJson)) {
42313
42842
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
42314
42843
  }
@@ -42344,7 +42873,7 @@ var init_dev_server = __esm({
42344
42873
  setMode: "set_mode.js"
42345
42874
  };
42346
42875
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
42347
- const scriptsDir = path24.join(providerDir, "scripts");
42876
+ const scriptsDir = path23.join(providerDir, "scripts");
42348
42877
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
42349
42878
  if (latestScriptsDir) {
42350
42879
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -42355,7 +42884,7 @@ var init_dev_server = __esm({
42355
42884
  for (const file2 of fs14.readdirSync(latestScriptsDir)) {
42356
42885
  if (file2.endsWith(".js") && targetFileNames.has(file2)) {
42357
42886
  try {
42358
- const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
42887
+ const content = fs14.readFileSync(path23.join(latestScriptsDir, file2), "utf-8");
42359
42888
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
42360
42889
  lines.push("```javascript");
42361
42890
  lines.push(content);
@@ -42372,7 +42901,7 @@ var init_dev_server = __esm({
42372
42901
  lines.push("");
42373
42902
  for (const file2 of refFiles) {
42374
42903
  try {
42375
- const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
42904
+ const content = fs14.readFileSync(path23.join(latestScriptsDir, file2), "utf-8");
42376
42905
  lines.push(`### \`${file2}\` \u{1F512}`);
42377
42906
  lines.push("```javascript");
42378
42907
  lines.push(content);
@@ -42413,10 +42942,10 @@ var init_dev_server = __esm({
42413
42942
  lines.push("");
42414
42943
  }
42415
42944
  }
42416
- const docsDir = path24.join(providerDir, "../../docs");
42945
+ const docsDir = path23.join(providerDir, "../../docs");
42417
42946
  const loadGuide = (name) => {
42418
42947
  try {
42419
- const p = path24.join(docsDir, name);
42948
+ const p = path23.join(docsDir, name);
42420
42949
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
42421
42950
  } catch {
42422
42951
  }
@@ -42590,7 +43119,7 @@ var init_dev_server = __esm({
42590
43119
  parseApproval: "parse_approval.js"
42591
43120
  };
42592
43121
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
42593
- const scriptsDir = path24.join(providerDir, "scripts");
43122
+ const scriptsDir = path23.join(providerDir, "scripts");
42594
43123
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
42595
43124
  if (latestScriptsDir) {
42596
43125
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -42602,7 +43131,7 @@ var init_dev_server = __esm({
42602
43131
  if (!file2.endsWith(".js")) continue;
42603
43132
  if (!targetFileNames.has(file2)) continue;
42604
43133
  try {
42605
- const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
43134
+ const content = fs14.readFileSync(path23.join(latestScriptsDir, file2), "utf-8");
42606
43135
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
42607
43136
  lines.push("```javascript");
42608
43137
  lines.push(content);
@@ -42618,7 +43147,7 @@ var init_dev_server = __esm({
42618
43147
  lines.push("");
42619
43148
  for (const file2 of refFiles) {
42620
43149
  try {
42621
- const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
43150
+ const content = fs14.readFileSync(path23.join(latestScriptsDir, file2), "utf-8");
42622
43151
  lines.push(`### \`${file2}\` \u{1F512}`);
42623
43152
  lines.push("```javascript");
42624
43153
  lines.push(content);
@@ -42651,10 +43180,10 @@ var init_dev_server = __esm({
42651
43180
  lines.push("");
42652
43181
  }
42653
43182
  }
42654
- const docsDir = path24.join(providerDir, "../../docs");
43183
+ const docsDir = path23.join(providerDir, "../../docs");
42655
43184
  const loadGuide = (name) => {
42656
43185
  try {
42657
- const p = path24.join(docsDir, name);
43186
+ const p = path23.join(docsDir, name);
42658
43187
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
42659
43188
  } catch {
42660
43189
  }
@@ -43904,6 +44433,8 @@ __export(src_exports, {
43904
44433
  CdpDomHandlers: () => CdpDomHandlers,
43905
44434
  CliProviderInstance: () => CliProviderInstance,
43906
44435
  DAEMON_WS_PATH: () => DAEMON_WS_PATH,
44436
+ DEFAULT_ACTIVE_CHAT_POLL_STATUSES: () => DEFAULT_ACTIVE_CHAT_POLL_STATUSES,
44437
+ DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS: () => DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS,
43907
44438
  DEFAULT_DAEMON_PORT: () => DEFAULT_DAEMON_PORT,
43908
44439
  DEFAULT_SESSION_HOST_APP_NAME: () => DEFAULT_SESSION_HOST_APP_NAME,
43909
44440
  DEFAULT_STANDALONE_SESSION_HOST_APP_NAME: () => DEFAULT_STANDALONE_SESSION_HOST_APP_NAME,
@@ -43932,7 +44463,11 @@ __export(src_exports, {
43932
44463
  buildSessionEntries: () => buildSessionEntries,
43933
44464
  buildStatusSnapshot: () => buildStatusSnapshot,
43934
44465
  buildSystemChatMessage: () => buildSystemChatMessage,
44466
+ buildTerminalChatMessage: () => buildTerminalChatMessage,
44467
+ buildThoughtChatMessage: () => buildThoughtChatMessage,
44468
+ buildToolChatMessage: () => buildToolChatMessage,
43935
44469
  buildUserChatMessage: () => buildUserChatMessage,
44470
+ classifyHotChatSessionsForSubscriptionFlush: () => classifyHotChatSessionsForSubscriptionFlush,
43936
44471
  clearDebugTrace: () => clearDebugTrace,
43937
44472
  configureDebugTraceStore: () => configureDebugTraceStore,
43938
44473
  connectCdpManager: () => connectCdpManager,
@@ -43999,6 +44534,7 @@ __export(src_exports, {
43999
44534
  resetConfig: () => resetConfig,
44000
44535
  resetDebugRuntimeConfig: () => resetDebugRuntimeConfig,
44001
44536
  resetState: () => resetState,
44537
+ resolveChatMessageKind: () => resolveChatMessageKind,
44002
44538
  resolveDebugRuntimeConfig: () => resolveDebugRuntimeConfig,
44003
44539
  resolveSessionHostAppName: () => resolveSessionHostAppName,
44004
44540
  saveConfig: () => saveConfig,
@@ -44025,6 +44561,7 @@ var init_src = __esm({
44025
44561
  init_ide_detector();
44026
44562
  init_cli_detector();
44027
44563
  init_host_memory();
44564
+ init_chat_tail_hot_sessions();
44028
44565
  init_manager();
44029
44566
  init_devtools();
44030
44567
  init_setup();
@@ -55554,15 +56091,15 @@ var require_route = __commonJS({
55554
56091
  };
55555
56092
  }
55556
56093
  function wrapConversion(toModel, graph) {
55557
- const path36 = [graph[toModel].parent, toModel];
56094
+ const path35 = [graph[toModel].parent, toModel];
55558
56095
  let fn = conversions[graph[toModel].parent][toModel];
55559
56096
  let cur = graph[toModel].parent;
55560
56097
  while (graph[cur].parent) {
55561
- path36.unshift(graph[cur].parent);
56098
+ path35.unshift(graph[cur].parent);
55562
56099
  fn = link(conversions[graph[cur].parent][cur], fn);
55563
56100
  cur = graph[cur].parent;
55564
56101
  }
55565
- fn.conversion = path36;
56102
+ fn.conversion = path35;
55566
56103
  return fn;
55567
56104
  }
55568
56105
  module2.exports = function(fromModel) {
@@ -73432,9 +73969,9 @@ var init_prompt = __esm({
73432
73969
  init_utils();
73433
73970
  init_baseUI();
73434
73971
  _ = {
73435
- set: (obj, path36 = "", value) => {
73972
+ set: (obj, path35 = "", value) => {
73436
73973
  let pointer = obj;
73437
- path36.split(".").forEach((key, index, arr) => {
73974
+ path35.split(".").forEach((key, index, arr) => {
73438
73975
  if (key === "__proto__" || key === "constructor") return;
73439
73976
  if (index === arr.length - 1) {
73440
73977
  pointer[key] = value;
@@ -73444,8 +73981,8 @@ var init_prompt = __esm({
73444
73981
  pointer = pointer[key];
73445
73982
  });
73446
73983
  },
73447
- get: (obj, path36 = "", defaultValue) => {
73448
- const travel = (regexp) => String.prototype.split.call(path36, regexp).filter(Boolean).reduce(
73984
+ get: (obj, path35 = "", defaultValue) => {
73985
+ const travel = (regexp) => String.prototype.split.call(path35, regexp).filter(Boolean).reduce(
73449
73986
  // @ts-expect-error implicit any on res[key]
73450
73987
  (res, key) => res !== null && res !== void 0 ? res[key] : res,
73451
73988
  obj
@@ -76338,12 +76875,12 @@ var init_peer_connection_manager = __esm({
76338
76875
  });
76339
76876
 
76340
76877
  // src/daemon-p2p/index.ts
76341
- var fs20, path27, import_node_module2, esmRequire, DaemonP2PSender;
76878
+ var fs20, path26, import_node_module2, esmRequire, DaemonP2PSender;
76342
76879
  var init_daemon_p2p = __esm({
76343
76880
  "src/daemon-p2p/index.ts"() {
76344
76881
  "use strict";
76345
76882
  fs20 = __toESM(require("fs"));
76346
- path27 = __toESM(require("path"));
76883
+ path26 = __toESM(require("path"));
76347
76884
  import_node_module2 = require("module");
76348
76885
  init_data_channel_router();
76349
76886
  init_screenshot_sender();
@@ -76416,15 +76953,15 @@ ${e?.stack || ""}`);
76416
76953
  const prebuildKey = `${platform13}-${arch4}`;
76417
76954
  try {
76418
76955
  const candidates = [
76419
- path27.join(__dirname, "node_modules", "node-datachannel"),
76420
- path27.join(__dirname, "..", "node_modules", "node-datachannel"),
76421
- path27.join(__dirname, "..", "..", "node_modules", "node-datachannel")
76956
+ path26.join(__dirname, "node_modules", "node-datachannel"),
76957
+ path26.join(__dirname, "..", "node_modules", "node-datachannel"),
76958
+ path26.join(__dirname, "..", "..", "node_modules", "node-datachannel")
76422
76959
  ];
76423
76960
  for (const candidate of candidates) {
76424
- const prebuildPath = path27.join(candidate, "prebuilds", prebuildKey, "node_datachannel.node");
76961
+ const prebuildPath = path26.join(candidate, "prebuilds", prebuildKey, "node_datachannel.node");
76425
76962
  if (fs20.existsSync(prebuildPath)) {
76426
- const targetDir = path27.join(candidate, "build", "Release");
76427
- const targetPath = path27.join(targetDir, "node_datachannel.node");
76963
+ const targetDir = path26.join(candidate, "build", "Release");
76964
+ const targetPath = path26.join(targetDir, "node_datachannel.node");
76428
76965
  fs20.mkdirSync(targetDir, { recursive: true });
76429
76966
  fs20.copyFileSync(prebuildPath, targetPath);
76430
76967
  try {
@@ -76746,16 +77283,16 @@ var require_filesystem = __commonJS({
76746
77283
  var LDD_PATH = "/usr/bin/ldd";
76747
77284
  var SELF_PATH = "/proc/self/exe";
76748
77285
  var MAX_LENGTH = 2048;
76749
- var readFileSync20 = (path36) => {
76750
- const fd = fs27.openSync(path36, "r");
77286
+ var readFileSync20 = (path35) => {
77287
+ const fd = fs27.openSync(path35, "r");
76751
77288
  const buffer = Buffer.alloc(MAX_LENGTH);
76752
77289
  const bytesRead = fs27.readSync(fd, buffer, 0, MAX_LENGTH, 0);
76753
77290
  fs27.close(fd, () => {
76754
77291
  });
76755
77292
  return buffer.subarray(0, bytesRead);
76756
77293
  };
76757
- var readFile = (path36) => new Promise((resolve17, reject) => {
76758
- fs27.open(path36, "r", (err, fd) => {
77294
+ var readFile = (path35) => new Promise((resolve17, reject) => {
77295
+ fs27.open(path35, "r", (err, fd) => {
76759
77296
  if (err) {
76760
77297
  reject(err);
76761
77298
  } else {
@@ -76874,11 +77411,11 @@ var require_detect_libc = __commonJS({
76874
77411
  }
76875
77412
  return null;
76876
77413
  };
76877
- var familyFromInterpreterPath = (path36) => {
76878
- if (path36) {
76879
- if (path36.includes("/ld-musl-")) {
77414
+ var familyFromInterpreterPath = (path35) => {
77415
+ if (path35) {
77416
+ if (path35.includes("/ld-musl-")) {
76880
77417
  return MUSL;
76881
- } else if (path36.includes("/ld-linux-")) {
77418
+ } else if (path35.includes("/ld-linux-")) {
76882
77419
  return GLIBC;
76883
77420
  }
76884
77421
  }
@@ -76925,8 +77462,8 @@ var require_detect_libc = __commonJS({
76925
77462
  cachedFamilyInterpreter = null;
76926
77463
  try {
76927
77464
  const selfContent = await readFile(SELF_PATH);
76928
- const path36 = interpreterPath(selfContent);
76929
- cachedFamilyInterpreter = familyFromInterpreterPath(path36);
77465
+ const path35 = interpreterPath(selfContent);
77466
+ cachedFamilyInterpreter = familyFromInterpreterPath(path35);
76930
77467
  } catch (e) {
76931
77468
  }
76932
77469
  return cachedFamilyInterpreter;
@@ -76938,8 +77475,8 @@ var require_detect_libc = __commonJS({
76938
77475
  cachedFamilyInterpreter = null;
76939
77476
  try {
76940
77477
  const selfContent = readFileSync20(SELF_PATH);
76941
- const path36 = interpreterPath(selfContent);
76942
- cachedFamilyInterpreter = familyFromInterpreterPath(path36);
77478
+ const path35 = interpreterPath(selfContent);
77479
+ cachedFamilyInterpreter = familyFromInterpreterPath(path35);
76943
77480
  } catch (e) {
76944
77481
  }
76945
77482
  return cachedFamilyInterpreter;
@@ -78658,18 +79195,18 @@ var require_sharp = __commonJS({
78658
79195
  `@img/sharp-${runtimePlatform}/sharp.node`,
78659
79196
  "@img/sharp-wasm32/sharp.node"
78660
79197
  ];
78661
- var path36;
79198
+ var path35;
78662
79199
  var sharp;
78663
79200
  var errors = [];
78664
- for (path36 of paths) {
79201
+ for (path35 of paths) {
78665
79202
  try {
78666
- sharp = require(path36);
79203
+ sharp = require(path35);
78667
79204
  break;
78668
79205
  } catch (err) {
78669
79206
  errors.push(err);
78670
79207
  }
78671
79208
  }
78672
- if (sharp && path36.startsWith("@img/sharp-linux-x64") && !sharp._isUsingX64V2()) {
79209
+ if (sharp && path35.startsWith("@img/sharp-linux-x64") && !sharp._isUsingX64V2()) {
78673
79210
  const err = new Error("Prebuilt binaries for linux-x64 require v2 microarchitecture");
78674
79211
  err.code = "Unsupported CPU";
78675
79212
  errors.push(err);
@@ -81578,15 +82115,15 @@ var require_color = __commonJS({
81578
82115
  };
81579
82116
  }
81580
82117
  function wrapConversion(toModel, graph) {
81581
- const path36 = [graph[toModel].parent, toModel];
82118
+ const path35 = [graph[toModel].parent, toModel];
81582
82119
  let fn = conversions_default[graph[toModel].parent][toModel];
81583
82120
  let cur = graph[toModel].parent;
81584
82121
  while (graph[cur].parent) {
81585
- path36.unshift(graph[cur].parent);
82122
+ path35.unshift(graph[cur].parent);
81586
82123
  fn = link(conversions_default[graph[cur].parent][cur], fn);
81587
82124
  cur = graph[cur].parent;
81588
82125
  }
81589
- fn.conversion = path36;
82126
+ fn.conversion = path35;
81590
82127
  return fn;
81591
82128
  }
81592
82129
  function route(fromModel) {
@@ -82203,7 +82740,7 @@ var require_channel = __commonJS({
82203
82740
  var require_output = __commonJS({
82204
82741
  "../../node_modules/sharp/lib/output.js"(exports2, module2) {
82205
82742
  "use strict";
82206
- var path36 = require("path");
82743
+ var path35 = require("path");
82207
82744
  var is = require_is();
82208
82745
  var sharp = require_sharp();
82209
82746
  var formats = /* @__PURE__ */ new Map([
@@ -82234,9 +82771,9 @@ var require_output = __commonJS({
82234
82771
  let err;
82235
82772
  if (!is.string(fileOut)) {
82236
82773
  err = new Error("Missing output file path");
82237
- } else if (is.string(this.options.input.file) && path36.resolve(this.options.input.file) === path36.resolve(fileOut)) {
82774
+ } else if (is.string(this.options.input.file) && path35.resolve(this.options.input.file) === path35.resolve(fileOut)) {
82238
82775
  err = new Error("Cannot use same file for input and output");
82239
- } else if (jp2Regex.test(path36.extname(fileOut)) && !this.constructor.format.jp2k.output.file) {
82776
+ } else if (jp2Regex.test(path35.extname(fileOut)) && !this.constructor.format.jp2k.output.file) {
82240
82777
  err = errJp2Save();
82241
82778
  }
82242
82779
  if (err) {
@@ -83478,11 +84015,11 @@ function quarantineLegacyStandaloneSessions(options) {
83478
84015
  const homeDir = options.homeDir || os26.homedir();
83479
84016
  const now = options.now || (() => /* @__PURE__ */ new Date());
83480
84017
  const isPidRunning = options.isPidRunning || defaultPidRunning;
83481
- const runtimesDir = path28.join(homeDir, ".adhdev", "session-host", options.appName, "runtimes");
84018
+ const runtimesDir = path27.join(homeDir, ".adhdev", "session-host", options.appName, "runtimes");
83482
84019
  if (!fs21.existsSync(runtimesDir)) {
83483
84020
  return { movedCount: 0, skippedActiveCount: 0, backupDir: null };
83484
84021
  }
83485
- const candidates = fs21.readdirSync(runtimesDir).filter((name) => name.endsWith(".json")).map((name) => path28.join(runtimesDir, name));
84022
+ const candidates = fs21.readdirSync(runtimesDir).filter((name) => name.endsWith(".json")).map((name) => path27.join(runtimesDir, name));
83486
84023
  let movedCount = 0;
83487
84024
  let skippedActiveCount = 0;
83488
84025
  let backupDir = null;
@@ -83500,26 +84037,26 @@ function quarantineLegacyStandaloneSessions(options) {
83500
84037
  continue;
83501
84038
  }
83502
84039
  if (!backupDir) {
83503
- backupDir = path28.join(
84040
+ backupDir = path27.join(
83504
84041
  homeDir,
83505
84042
  ".adhdev",
83506
84043
  "session-host-backups",
83507
84044
  `legacy-standalone-${options.appName}-${formatTimestamp(now())}`
83508
84045
  );
83509
- fs21.mkdirSync(path28.join(backupDir, "runtimes"), { recursive: true });
84046
+ fs21.mkdirSync(path27.join(backupDir, "runtimes"), { recursive: true });
83510
84047
  }
83511
- fs21.renameSync(sourcePath, path28.join(backupDir, "runtimes", path28.basename(sourcePath)));
84048
+ fs21.renameSync(sourcePath, path27.join(backupDir, "runtimes", path27.basename(sourcePath)));
83512
84049
  movedCount += 1;
83513
84050
  }
83514
84051
  return { movedCount, skippedActiveCount, backupDir };
83515
84052
  }
83516
- var fs21, os26, path28, LEGACY_STANDALONE_MANAGER_TAG;
84053
+ var fs21, os26, path27, LEGACY_STANDALONE_MANAGER_TAG;
83517
84054
  var init_session_host_hygiene = __esm({
83518
84055
  "src/session-host-hygiene.ts"() {
83519
84056
  "use strict";
83520
84057
  fs21 = __toESM(require("fs"));
83521
84058
  os26 = __toESM(require("os"));
83522
- path28 = __toESM(require("path"));
84059
+ path27 = __toESM(require("path"));
83523
84060
  init_src();
83524
84061
  LEGACY_STANDALONE_MANAGER_TAG = "adhdev-standalone";
83525
84062
  }
@@ -83543,8 +84080,8 @@ function buildSessionHostEnv(baseEnv) {
83543
84080
  }
83544
84081
  function resolveSessionHostEntry() {
83545
84082
  const packagedCandidates = [
83546
- path29.resolve(__dirname, "../vendor/session-host-daemon/index.js"),
83547
- path29.resolve(__dirname, "../../vendor/session-host-daemon/index.js")
84083
+ path28.resolve(__dirname, "../vendor/session-host-daemon/index.js"),
84084
+ path28.resolve(__dirname, "../../vendor/session-host-daemon/index.js")
83548
84085
  ];
83549
84086
  for (const candidate of packagedCandidates) {
83550
84087
  if (fs22.existsSync(candidate)) {
@@ -83554,7 +84091,7 @@ function resolveSessionHostEntry() {
83554
84091
  return require.resolve("@adhdev/session-host-daemon");
83555
84092
  }
83556
84093
  function getSessionHostPidFile() {
83557
- return path29.join(os27.homedir(), ".adhdev", `${SESSION_HOST_APP_NAME}-session-host.pid`);
84094
+ return path28.join(os27.homedir(), ".adhdev", `${SESSION_HOST_APP_NAME}-session-host.pid`);
83558
84095
  }
83559
84096
  function getSessionHostStatusPaths() {
83560
84097
  return {
@@ -83687,9 +84224,9 @@ async function ensureSessionHostReady2() {
83687
84224
  }
83688
84225
  const spawnHost = () => {
83689
84226
  const entry = resolveSessionHostEntry();
83690
- const logDir = path29.join(os27.homedir(), ".adhdev", "logs");
84227
+ const logDir = path28.join(os27.homedir(), ".adhdev", "logs");
83691
84228
  fs22.mkdirSync(logDir, { recursive: true });
83692
- const logFd = fs22.openSync(path29.join(logDir, "session-host.log"), "a");
84229
+ const logFd = fs22.openSync(path28.join(logDir, "session-host.log"), "a");
83693
84230
  const child = (0, import_child_process12.spawn)(process.execPath, [entry], {
83694
84231
  detached: true,
83695
84232
  stdio: ["ignore", logFd, logFd],
@@ -83751,14 +84288,14 @@ async function probeSessionHostStatus() {
83751
84288
  };
83752
84289
  }
83753
84290
  }
83754
- var import_child_process12, fs22, os27, path29, SESSION_HOST_APP_NAME, SESSION_HOST_START_TIMEOUT_MS;
84291
+ var import_child_process12, fs22, os27, path28, SESSION_HOST_APP_NAME, SESSION_HOST_START_TIMEOUT_MS;
83755
84292
  var init_session_host = __esm({
83756
84293
  "src/session-host.ts"() {
83757
84294
  "use strict";
83758
84295
  import_child_process12 = require("child_process");
83759
84296
  fs22 = __toESM(require("fs"));
83760
84297
  os27 = __toESM(require("os"));
83761
- path29 = __toESM(require("path"));
84298
+ path28 = __toESM(require("path"));
83762
84299
  init_src();
83763
84300
  init_dist();
83764
84301
  init_session_host_hygiene();
@@ -83999,10 +84536,10 @@ function resolveDaemonPort(ref = {}) {
83999
84536
  return Number.isFinite(ref.port) && Number(ref.port) > 0 ? Number(ref.port) : DEFAULT_DAEMON_PORT;
84000
84537
  }
84001
84538
  function getDaemonPidFile(ref = {}) {
84002
- const dir = path30.join(ref.homeDir || os28.homedir(), ".adhdev");
84539
+ const dir = path29.join(ref.homeDir || os28.homedir(), ".adhdev");
84003
84540
  if (!fs23.existsSync(dir)) fs23.mkdirSync(dir, { recursive: true });
84004
84541
  const port = resolveDaemonPort(ref);
84005
- return path30.join(dir, port === DEFAULT_DAEMON_PORT ? "daemon.pid" : `daemon-${port}.pid`);
84542
+ return path29.join(dir, port === DEFAULT_DAEMON_PORT ? "daemon.pid" : `daemon-${port}.pid`);
84006
84543
  }
84007
84544
  function writeDaemonPid(pid, ref = {}) {
84008
84545
  const pidFile = getDaemonPidFile(ref);
@@ -84107,7 +84644,7 @@ function stopDaemon(ref = {}) {
84107
84644
  return false;
84108
84645
  }
84109
84646
  }
84110
- var os28, fs23, path30, import_http, import_ws3, pkgVersion, ACTIVE_CHAT_POLL_STATUSES, AdhdevDaemon;
84647
+ var os28, fs23, path29, import_http, import_ws3, pkgVersion, AdhdevDaemon;
84111
84648
  var init_adhdev_daemon = __esm({
84112
84649
  "src/adhdev-daemon.ts"() {
84113
84650
  "use strict";
@@ -84121,17 +84658,13 @@ var init_adhdev_daemon = __esm({
84121
84658
  init_session_host_controller();
84122
84659
  os28 = __toESM(require("os"));
84123
84660
  fs23 = __toESM(require("fs"));
84124
- path30 = __toESM(require("path"));
84661
+ path29 = __toESM(require("path"));
84125
84662
  import_http = require("http");
84126
84663
  import_ws3 = require("ws");
84127
84664
  init_source();
84128
84665
  init_version();
84129
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.63" });
84130
- ACTIVE_CHAT_POLL_STATUSES = /* @__PURE__ */ new Set([
84131
- "generating",
84132
- "waiting_approval",
84133
- "starting"
84134
- ]);
84666
+ init_src();
84667
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.66" });
84135
84668
  AdhdevDaemon = class _AdhdevDaemon {
84136
84669
  localHttpServer = null;
84137
84670
  localWss = null;
@@ -84358,14 +84891,12 @@ var init_adhdev_daemon = __esm({
84358
84891
  }
84359
84892
  getHotChatSessionIdsForP2PFlush() {
84360
84893
  const snapshot = this.buildLiveStatusSnapshot();
84361
- const active = new Set(
84362
- snapshot.sessions.filter((session) => ACTIVE_CHAT_POLL_STATUSES.has(String(session.status || "").toLowerCase())).map((session) => session.id)
84894
+ const hotSessions = classifyHotChatSessionsForSubscriptionFlush(
84895
+ snapshot.sessions,
84896
+ this.hotP2PChatSessionIds
84363
84897
  );
84364
- const finalizing = new Set(
84365
- Array.from(this.hotP2PChatSessionIds).filter((sessionId) => !active.has(sessionId))
84366
- );
84367
- this.hotP2PChatSessionIds = active;
84368
- return { active, finalizing };
84898
+ this.hotP2PChatSessionIds = hotSessions.active;
84899
+ return hotSessions;
84369
84900
  }
84370
84901
  async flushP2PChatSubscriptions(options = {}) {
84371
84902
  if (!this.p2p?.isConnected || !this.p2p.hasChatSubscriptions()) return;
@@ -86757,8 +87288,8 @@ function parsePositiveInteger(value, fallback2) {
86757
87288
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback2;
86758
87289
  }
86759
87290
  function buildHistoryResumeLaunchPayload(cliType, session, overrideDir) {
86760
- const path36 = require("path");
86761
- const dir = typeof overrideDir === "string" && overrideDir.trim() ? path36.resolve(overrideDir.trim()) : typeof session.workspace === "string" && session.workspace.trim() ? path36.resolve(session.workspace.trim()) : "";
87291
+ const path35 = require("path");
87292
+ const dir = typeof overrideDir === "string" && overrideDir.trim() ? path35.resolve(overrideDir.trim()) : typeof session.workspace === "string" && session.workspace.trim() ? path35.resolve(session.workspace.trim()) : "";
86762
87293
  if (!dir) {
86763
87294
  throw new Error(`Saved history ${session.providerSessionId} is missing workspace metadata. Pass --dir to resume it explicitly.`);
86764
87295
  }
@@ -87346,7 +87877,7 @@ function registerSetupCommands(program2, providerLoader) {
87346
87877
  program2.command("uninstall").description("Completely wipe all setting, configuration, stop daemon and uninstall service").option("-f, --force", "Skip confirmation prompt").action(async (options) => {
87347
87878
  const inquirer2 = await Promise.resolve().then(() => (init_lib(), lib_exports));
87348
87879
  const fs27 = await import("fs");
87349
- const path36 = await import("path");
87880
+ const path35 = await import("path");
87350
87881
  const os31 = await import("os");
87351
87882
  const { spawnSync: spawnSync3 } = await import("child_process");
87352
87883
  if (!options.force) {
@@ -87372,7 +87903,7 @@ function registerSetupCommands(program2, providerLoader) {
87372
87903
  }
87373
87904
  console.log(source_default.gray(" Removing OS background service..."));
87374
87905
  spawnSync3(process.execPath, [process.argv[1], "service", "uninstall"], { stdio: "inherit" });
87375
- const adhdevDir = path36.join(os31.homedir(), ".adhdev");
87906
+ const adhdevDir = path35.join(os31.homedir(), ".adhdev");
87376
87907
  if (fs27.existsSync(adhdevDir)) {
87377
87908
  console.log(source_default.gray(` Deleting ${adhdevDir}...`));
87378
87909
  try {
@@ -87395,10 +87926,10 @@ init_source();
87395
87926
 
87396
87927
  // src/cli/runtime-tools.ts
87397
87928
  var fs24 = __toESM(require("fs"));
87398
- var path31 = __toESM(require("path"));
87929
+ var path30 = __toESM(require("path"));
87399
87930
  function defaultPackageRoot() {
87400
87931
  const currentCliPath = process.argv[1] ? fs24.realpathSync.native(process.argv[1]) : process.cwd();
87401
- return path31.resolve(path31.dirname(currentCliPath), "../..");
87932
+ return path30.resolve(path30.dirname(currentCliPath), "../..");
87402
87933
  }
87403
87934
  function normalizePath2(value) {
87404
87935
  return value.replace(/\\/g, "/").toLowerCase();
@@ -87407,19 +87938,19 @@ function shouldPreferSource(currentCliPath, packageRoot) {
87407
87938
  const normalizedCliPath = normalizePath2(currentCliPath || "");
87408
87939
  if (normalizedCliPath.includes("/src/cli/")) return true;
87409
87940
  if (normalizedCliPath.includes("/dist/cli/")) return false;
87410
- return fs24.existsSync(path31.join(packageRoot, "src", "cli", "index.ts"));
87941
+ return fs24.existsSync(path30.join(packageRoot, "src", "cli", "index.ts"));
87411
87942
  }
87412
87943
  function getVendoredToolEntry(packageRoot, tool) {
87413
87944
  if (tool === "session-host-daemon") {
87414
- return path31.join(packageRoot, "vendor", "session-host-daemon", "index.js");
87945
+ return path30.join(packageRoot, "vendor", "session-host-daemon", "index.js");
87415
87946
  }
87416
- return path31.join(packageRoot, "vendor", "terminal-mux-cli", "index.js");
87947
+ return path30.join(packageRoot, "vendor", "terminal-mux-cli", "index.js");
87417
87948
  }
87418
87949
  function getSourceToolEntry(packageRoot, tool) {
87419
87950
  if (tool === "session-host-daemon") {
87420
- return path31.resolve(packageRoot, "../../oss/packages/session-host-daemon/src/index.ts");
87951
+ return path30.resolve(packageRoot, "../../oss/packages/session-host-daemon/src/index.ts");
87421
87952
  }
87422
- return path31.resolve(packageRoot, "../../oss/packages/terminal-mux-cli/src/index.ts");
87953
+ return path30.resolve(packageRoot, "../../oss/packages/terminal-mux-cli/src/index.ts");
87423
87954
  }
87424
87955
  function getGlobalToolCommand(tool) {
87425
87956
  return tool === "session-host-daemon" ? "adhdev-sessiond" : "adhmux";
@@ -88539,7 +89070,7 @@ init_source();
88539
89070
  var import_child_process13 = require("child_process");
88540
89071
  var fs25 = __toESM(require("fs"));
88541
89072
  var os29 = __toESM(require("os"));
88542
- var path33 = __toESM(require("path"));
89073
+ var path31 = __toESM(require("path"));
88543
89074
  init_src();
88544
89075
  init_session_host();
88545
89076
 
@@ -88632,11 +89163,11 @@ function buildDoctorAdvice(input) {
88632
89163
 
88633
89164
  // src/cli/doctor-commands.ts
88634
89165
  function resolvePackageRoot() {
88635
- return path33.resolve(__dirname, "..", "..");
89166
+ return path31.resolve(__dirname, "..", "..");
88636
89167
  }
88637
89168
  function isLinkedInstall(packageRoot) {
88638
- const normalized = path33.normalize(packageRoot);
88639
- return !normalized.includes(`${path33.sep}node_modules${path33.sep}adhdev`);
89169
+ const normalized = path31.normalize(packageRoot);
89170
+ return !normalized.includes(`${path31.sep}node_modules${path31.sep}adhdev`);
88640
89171
  }
88641
89172
  function formatCheck(check2) {
88642
89173
  const icon = check2.ok ? source_default.green("\u2713") : source_default.red("\u2717");
@@ -88720,8 +89251,8 @@ function probeSharpRuntime(packageRoot, nativeSharpPackage) {
88720
89251
  }
88721
89252
  }
88722
89253
  function probeConfigAccess() {
88723
- const configDir = path33.join(os29.homedir(), ".adhdev");
88724
- const configPath = path33.join(configDir, "config.json");
89254
+ const configDir = path31.join(os29.homedir(), ".adhdev");
89255
+ const configPath = path31.join(configDir, "config.json");
88725
89256
  const checks = [];
88726
89257
  try {
88727
89258
  fs25.mkdirSync(configDir, { recursive: true });
@@ -88761,7 +89292,7 @@ function probeConfigAccess() {
88761
89292
  fatal: true
88762
89293
  });
88763
89294
  }
88764
- const probePath = path33.join(configDir, `.doctor-write-${process.pid}-${Date.now()}.tmp`);
89295
+ const probePath = path31.join(configDir, `.doctor-write-${process.pid}-${Date.now()}.tmp`);
88765
89296
  try {
88766
89297
  fs25.writeFileSync(probePath, "ok", "utf-8");
88767
89298
  fs25.rmSync(probePath, { force: true });
@@ -89003,7 +89534,7 @@ function registerDoctorCommands(program2, pkgVersion3) {
89003
89534
  nodeDriftCheck: nodeDriftCheck || void 0,
89004
89535
  sourceCliExample: "node --import tsx packages/daemon-cloud/src/cli/index.ts doctor"
89005
89536
  });
89006
- const sessionHostLogPath = path33.join(os29.homedir(), ".adhdev", "logs", "session-host.log");
89537
+ const sessionHostLogPath = path31.join(os29.homedir(), ".adhdev", "logs", "session-host.log");
89007
89538
  console.log(source_default.bold("\n\u{1FA7A} ADHDev Doctor\n"));
89008
89539
  console.log(source_default.gray(` Version: ${pkgVersion3}`));
89009
89540
  console.log(source_default.gray(` Platform: ${process.platform} ${process.arch}`));
@@ -89045,7 +89576,7 @@ function registerDoctorCommands(program2, pkgVersion3) {
89045
89576
 
89046
89577
  // src/cli/provider-commands.ts
89047
89578
  init_source();
89048
- var path34 = __toESM(require("path"));
89579
+ var path33 = __toESM(require("path"));
89049
89580
  init_cdp_utils();
89050
89581
  var IDE_AUTO_FIX_FUNCTIONS = [
89051
89582
  "openPanel",
@@ -89215,7 +89746,7 @@ function getProviderSourceCandidatePaths(options) {
89215
89746
  const results = [];
89216
89747
  for (const root of roots) {
89217
89748
  for (const name of relativeNames) {
89218
- results.push(path34.join(root, options.category, options.type, name));
89749
+ results.push(path33.join(root, options.category, options.type, name));
89219
89750
  }
89220
89751
  }
89221
89752
  return results;
@@ -89351,7 +89882,7 @@ function registerProviderCommands(program2) {
89351
89882
  let processNames = {};
89352
89883
  if (category === "ide") {
89353
89884
  const fs27 = await import("fs");
89354
- const path36 = await import("path");
89885
+ const path35 = await import("path");
89355
89886
  const os31 = await import("os");
89356
89887
  if (os31.platform() === "darwin") {
89357
89888
  while (true) {
@@ -89364,7 +89895,7 @@ function registerProviderCommands(program2) {
89364
89895
  }
89365
89896
  console.log(source_default.green(` \u2713 Path verified: ${p}`));
89366
89897
  osPaths["darwin"] = [p];
89367
- processNames["darwin"] = path36.basename(p, ".app");
89898
+ processNames["darwin"] = path35.basename(p, ".app");
89368
89899
  break;
89369
89900
  }
89370
89901
  } else if (os31.platform() === "win32") {
@@ -89378,7 +89909,7 @@ function registerProviderCommands(program2) {
89378
89909
  }
89379
89910
  console.log(source_default.green(` \u2713 Path verified: ${p}`));
89380
89911
  osPaths["win32"] = [p];
89381
- processNames["win32"] = path36.basename(p, ".exe");
89912
+ processNames["win32"] = path35.basename(p, ".exe");
89382
89913
  break;
89383
89914
  }
89384
89915
  }