@adhdev/daemon-core 0.9.76-rc.60 → 0.9.76-rc.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -433,10 +433,10 @@ function getMeshConfigPath() {
433
433
  return (0, import_path2.join)(getConfigDir(), "meshes.json");
434
434
  }
435
435
  function loadMeshConfig() {
436
- const path27 = getMeshConfigPath();
437
- if (!(0, import_fs2.existsSync)(path27)) return { meshes: [] };
436
+ const path28 = getMeshConfigPath();
437
+ if (!(0, import_fs2.existsSync)(path28)) return { meshes: [] };
438
438
  try {
439
- const raw = JSON.parse((0, import_fs2.readFileSync)(path27, "utf-8"));
439
+ const raw = JSON.parse((0, import_fs2.readFileSync)(path28, "utf-8"));
440
440
  if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
441
441
  return raw;
442
442
  } catch {
@@ -444,16 +444,16 @@ function loadMeshConfig() {
444
444
  }
445
445
  }
446
446
  function saveMeshConfig(config) {
447
- const path27 = getMeshConfigPath();
448
- (0, import_fs2.writeFileSync)(path27, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
447
+ const path28 = getMeshConfigPath();
448
+ (0, import_fs2.writeFileSync)(path28, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
449
449
  }
450
450
  function normalizeRepoIdentity(remoteUrl) {
451
451
  let identity = remoteUrl.trim();
452
452
  if (identity.startsWith("http://") || identity.startsWith("https://")) {
453
453
  try {
454
454
  const url = new URL(identity);
455
- const path27 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
456
- return `${url.hostname}/${path27}`;
455
+ const path28 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
456
+ return `${url.hostname}/${path28}`;
457
457
  } catch {
458
458
  }
459
459
  }
@@ -610,6 +610,7 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
610
610
  }
611
611
  sections.push(buildPolicySection({ ...DEFAULT_MESH_POLICY, ...mesh.policy || {} }));
612
612
  sections.push(TOOLS_SECTION);
613
+ sections.push(TOOL_EXPOSURE_PREFLIGHT_SECTION);
613
614
  sections.push(WORKFLOW_SECTION);
614
615
  sections.push(buildRulesSection(coordinatorCliType));
615
616
  if (userInstruction) {
@@ -679,7 +680,7 @@ function buildRulesSection(coordinatorCliType) {
679
680
  - **Clean up worktree nodes.** After a worktree task completes and its changes are merged or checkpointed, call \`mesh_remove_node\` to free resources.
680
681
  - **Name worktree branches meaningfully.** Use descriptive names like \`feat/auth-refactor\` or \`fix/build-123\`.${coordinatorNote}`;
681
682
  }
682
- var TOOLS_SECTION, WORKFLOW_SECTION;
683
+ var TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION;
683
684
  var init_coordinator_prompt = __esm({
684
685
  "src/mesh/coordinator-prompt.ts"() {
685
686
  "use strict";
@@ -698,6 +699,9 @@ var init_coordinator_prompt = __esm({
698
699
  | \`mesh_approve\` | Approve/reject a pending agent action |
699
700
  | \`mesh_clone_node\` | Create a worktree node for isolated parallel branch work |
700
701
  | \`mesh_remove_node\` | Remove a node (cleans up worktree if applicable) |`;
702
+ TOOL_EXPOSURE_PREFLIGHT_SECTION = `## Tool Exposure Preflight
703
+
704
+ Before doing any coordinator work, confirm that the actual callable tool list includes \`mesh_status\` and the other \`mesh_*\` tools from the table above. If this Repo Mesh coordinator prompt is present but the callable \`mesh_*\` tools are missing, the MCP server/tool manifest is stale or not injected yet. Do not substitute terminal/file/git tools, do not inspect or edit the repository directly, and do not continue as a non-mesh local coding agent. Stop immediately and tell the user to run \`/reload-mcp\` or start a fresh coordinator session so ADHDev can reconnect \`adhdev-mesh\`.`;
701
705
  WORKFLOW_SECTION = `## Orchestration Workflow
702
706
 
703
707
  1. **Assess** \u2014 Call \`mesh_status\` to see which nodes are healthy and available.
@@ -3819,6 +3823,12 @@ __export(index_exports, {
3819
3823
  AcpProviderInstance: () => AcpProviderInstance,
3820
3824
  AgentStreamPoller: () => AgentStreamPoller,
3821
3825
  BUILTIN_CHAT_MESSAGE_KINDS: () => BUILTIN_CHAT_MESSAGE_KINDS,
3826
+ CHAT_MESSAGE_ACTIVITY_SOURCES: () => CHAT_MESSAGE_ACTIVITY_SOURCES,
3827
+ CHAT_MESSAGE_AUDIENCES: () => CHAT_MESSAGE_AUDIENCES,
3828
+ CHAT_MESSAGE_INTERNAL_SOURCES: () => CHAT_MESSAGE_INTERNAL_SOURCES,
3829
+ CHAT_MESSAGE_SOURCES: () => CHAT_MESSAGE_SOURCES,
3830
+ CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES: () => CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES,
3831
+ CHAT_MESSAGE_VISIBILITIES: () => CHAT_MESSAGE_VISIBILITIES,
3822
3832
  CdpDomHandlers: () => CdpDomHandlers,
3823
3833
  CliProviderInstance: () => CliProviderInstance,
3824
3834
  DAEMON_WS_PATH: () => DAEMON_WS_PATH,
@@ -3881,6 +3891,7 @@ __export(index_exports, {
3881
3891
  buildThoughtChatMessage: () => buildThoughtChatMessage,
3882
3892
  buildToolChatMessage: () => buildToolChatMessage,
3883
3893
  buildUserChatMessage: () => buildUserChatMessage,
3894
+ classifyChatMessageVisibility: () => classifyChatMessageVisibility,
3884
3895
  classifyHotChatSessionsForSubscriptionFlush: () => classifyHotChatSessionsForSubscriptionFlush,
3885
3896
  clearDebugTrace: () => clearDebugTrace,
3886
3897
  compareGitSnapshots: () => compareGitSnapshots,
@@ -3900,6 +3911,9 @@ __export(index_exports, {
3900
3911
  detectIDEs: () => detectIDEs,
3901
3912
  ensureSessionHostReady: () => ensureSessionHostReady,
3902
3913
  execNpmCommandSync: () => execNpmCommandSync,
3914
+ filterActivityChatMessages: () => filterActivityChatMessages,
3915
+ filterChatMessagesByVisibility: () => filterChatMessagesByVisibility,
3916
+ filterInternalChatMessages: () => filterInternalChatMessages,
3903
3917
  filterUserFacingChatMessages: () => filterUserFacingChatMessages,
3904
3918
  findCdpManager: () => findCdpManager,
3905
3919
  flattenMessageParts: () => flattenMessageParts,
@@ -3931,11 +3945,13 @@ __export(index_exports, {
3931
3945
  initDaemonComponents: () => initDaemonComponents,
3932
3946
  installExtensions: () => installExtensions,
3933
3947
  installGlobalInterceptor: () => installGlobalInterceptor,
3948
+ isActivityChatMessage: () => isActivityChatMessage,
3934
3949
  isBuiltinChatMessageKind: () => isBuiltinChatMessageKind,
3935
3950
  isCdpConnected: () => isCdpConnected,
3936
3951
  isExtensionInstalled: () => isExtensionInstalled,
3937
3952
  isGitCommandName: () => isGitCommandName,
3938
3953
  isIdeRunning: () => isIdeRunning,
3954
+ isInternalChatMessage: () => isInternalChatMessage,
3939
3955
  isManagedStatusWaiting: () => isManagedStatusWaiting,
3940
3956
  isManagedStatusWorking: () => isManagedStatusWorking,
3941
3957
  isPathInside: () => isPathInside,
@@ -7720,6 +7736,10 @@ function flattenMessageParts(parts) {
7720
7736
  return parts.map((part) => {
7721
7737
  if (part.type === "text") return part.text;
7722
7738
  if (part.type === "resource") return part.resource.text || "";
7739
+ if (part.type === "image") return part.alt || (part.data ? `[image: ${part.mimeType}]` : "");
7740
+ if (part.type === "audio") return part.transcript || (part.data ? `[audio: ${part.mimeType}]` : "");
7741
+ if (part.type === "video") return part.transcript || (part.data ? `[video: ${part.mimeType}]` : "");
7742
+ if (part.type === "resource_link") return [part.name, part.description].filter(Boolean).join("\n");
7723
7743
  return "";
7724
7744
  }).filter((value) => value.length > 0).join("\n");
7725
7745
  }
@@ -7806,6 +7826,7 @@ function normalizeInputPartObject(raw) {
7806
7826
  mimeType: raw.mimeType,
7807
7827
  ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
7808
7828
  ...typeof raw.data === "string" ? { data: raw.data } : {},
7829
+ ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {},
7809
7830
  ...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
7810
7831
  };
7811
7832
  }
@@ -7821,10 +7842,14 @@ function normalizeInputPartObject(raw) {
7821
7842
  }
7822
7843
  if (type === "resource_link" && typeof raw.uri === "string") {
7823
7844
  return {
7824
- type: "resource",
7845
+ type,
7825
7846
  uri: raw.uri,
7847
+ name: typeof raw.name === "string" ? raw.name : getUriDisplayName(raw.uri, "resource"),
7848
+ ...typeof raw.title === "string" ? { title: raw.title } : {},
7849
+ ...typeof raw.description === "string" ? { description: raw.description } : {},
7826
7850
  ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
7827
- ...typeof raw.name === "string" ? { name: raw.name } : {}
7851
+ ...typeof raw.size === "number" && Number.isFinite(raw.size) ? { size: raw.size } : {},
7852
+ ...normalizeAnnotationsProperty(raw.annotations)
7828
7853
  };
7829
7854
  }
7830
7855
  return null;
@@ -7839,7 +7864,8 @@ function normalizeMessagePartObject(raw) {
7839
7864
  type,
7840
7865
  mimeType: raw.mimeType,
7841
7866
  ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
7842
- ...typeof raw.data === "string" ? { data: raw.data } : {}
7867
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
7868
+ ...typeof raw.alt === "string" ? { alt: raw.alt } : {}
7843
7869
  };
7844
7870
  }
7845
7871
  if (type === "audio" && typeof raw.mimeType === "string") {
@@ -7857,6 +7883,7 @@ function normalizeMessagePartObject(raw) {
7857
7883
  mimeType: raw.mimeType,
7858
7884
  ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
7859
7885
  ...typeof raw.data === "string" ? { data: raw.data } : {},
7886
+ ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {},
7860
7887
  ...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
7861
7888
  };
7862
7889
  }
@@ -7865,8 +7892,11 @@ function normalizeMessagePartObject(raw) {
7865
7892
  type,
7866
7893
  uri: raw.uri,
7867
7894
  name: raw.name,
7895
+ ...typeof raw.title === "string" ? { title: raw.title } : {},
7896
+ ...typeof raw.description === "string" ? { description: raw.description } : {},
7868
7897
  ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
7869
- ...typeof raw.size === "number" ? { size: raw.size } : {}
7898
+ ...typeof raw.size === "number" && Number.isFinite(raw.size) ? { size: raw.size } : {},
7899
+ ...normalizeAnnotationsProperty(raw.annotations)
7870
7900
  };
7871
7901
  }
7872
7902
  if (type === "resource" && raw.resource && typeof raw.resource === "object") {
@@ -7887,11 +7917,35 @@ function normalizeMessagePartObject(raw) {
7887
7917
  function flattenInputParts(parts) {
7888
7918
  return parts.map((part) => {
7889
7919
  if (part.type === "text") return part.text;
7890
- if (part.type === "audio") return part.transcript || "";
7891
- if (part.type === "resource") return part.text || "";
7920
+ if (part.type === "image") return part.alt || (part.data ? `[image: ${part.mimeType}]` : "");
7921
+ if (part.type === "audio") return part.transcript || (part.data ? `[audio: ${part.mimeType}]` : "");
7922
+ if (part.type === "video") return part.transcript || (part.data ? `[video: ${part.mimeType}]` : "");
7923
+ if (part.type === "resource_link") return [part.title, part.name, part.description, part.uri].filter(Boolean).join("\n");
7924
+ if (part.type === "resource") return part.text || part.name || part.uri;
7892
7925
  return "";
7893
7926
  }).filter((value) => value.length > 0).join("\n");
7894
7927
  }
7928
+ function getUriDisplayName(uri, fallback) {
7929
+ try {
7930
+ const pathname = uri.startsWith("file://") ? new URL(uri).pathname : uri;
7931
+ return pathname.split(/[\\/]/).filter(Boolean).pop() || fallback;
7932
+ } catch {
7933
+ return uri.split(/[\\/]/).filter(Boolean).pop() || fallback;
7934
+ }
7935
+ }
7936
+ function normalizeAnnotationsProperty(value) {
7937
+ if (!value || typeof value !== "object") return {};
7938
+ const record = value;
7939
+ const annotations = {};
7940
+ if (Array.isArray(record.audience)) {
7941
+ const audience = record.audience.filter((item) => item === "user" || item === "assistant");
7942
+ if (audience.length > 0) annotations.audience = audience;
7943
+ }
7944
+ if (typeof record.priority === "number" && Number.isFinite(record.priority)) {
7945
+ annotations.priority = record.priority;
7946
+ }
7947
+ return Object.keys(annotations).length > 0 ? { annotations } : {};
7948
+ }
7895
7949
 
7896
7950
  // src/providers/contracts.ts
7897
7951
  function flattenContent(content) {
@@ -8013,6 +8067,20 @@ var StatusMonitor = class {
8013
8067
 
8014
8068
  // src/providers/chat-message-normalization.ts
8015
8069
  var BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
8070
+ var CHAT_MESSAGE_VISIBILITIES = ["user", "debug", "internal", "hidden"];
8071
+ var CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES = ["visible", "chat", "user", "debug", "internal", "hidden"];
8072
+ var CHAT_MESSAGE_AUDIENCES = ["chat", "debug", "trace", "internal"];
8073
+ var CHAT_MESSAGE_SOURCES = [
8074
+ "assistant_text",
8075
+ "tool_call",
8076
+ "terminal_command",
8077
+ "runtime_activity",
8078
+ "runtime_status",
8079
+ "provider_chrome",
8080
+ "control"
8081
+ ];
8082
+ var CHAT_MESSAGE_ACTIVITY_SOURCES = ["tool_call", "terminal_command", "runtime_activity"];
8083
+ var CHAT_MESSAGE_INTERNAL_SOURCES = ["runtime_status", "provider_chrome", "control"];
8016
8084
  var KNOWN_CHAT_MESSAGE_KINDS = new Set(BUILTIN_CHAT_MESSAGE_KINDS);
8017
8085
  var CHAT_MESSAGE_KIND_ALIASES = {
8018
8086
  text: "standard",
@@ -8161,37 +8229,162 @@ function readMessageMeta(message) {
8161
8229
  function readStringField(value) {
8162
8230
  return typeof value === "string" ? value.trim().toLowerCase() : "";
8163
8231
  }
8164
- function readVisibilityField(message, meta) {
8232
+ function readRecordField(message, meta, key) {
8165
8233
  const record = message;
8166
- return readStringField(record.visibility ?? record.transcriptVisibility ?? meta?.visibility ?? meta?.transcriptVisibility);
8234
+ return record[key] ?? meta?.[key];
8167
8235
  }
8168
- function isExplicitlyHiddenFromTranscript(message, meta) {
8169
- const record = message;
8170
- const visibility = readVisibilityField(message, meta);
8171
- const audience = readStringField(record.audience ?? meta?.audience);
8172
- const source = readStringField(record.source ?? meta?.source);
8173
- return visibility === "hidden" || visibility === "debug" || visibility === "internal" || audience === "debug" || audience === "trace" || audience === "internal" || source === "runtime_status" || source === "runtime_activity" || source === "provider_chrome" || source === "control" || record.internal === true || record.isInternal === true || record.debug === true || meta?.internal === true || meta?.isInternal === true || meta?.debug === true || meta?.statusOnly === true || meta?.controlOnly === true;
8236
+ function readVisibilityField(message, meta) {
8237
+ return readStringField(readRecordField(message, meta, "visibility"));
8174
8238
  }
8175
- function isExplicitlyVisibleInTranscript(message, meta) {
8239
+ function readTranscriptVisibilityField(message, meta) {
8176
8240
  const record = message;
8177
- const visibility = readVisibilityField(message, meta);
8178
- const audience = readStringField(record.audience ?? meta?.audience);
8179
- return visibility === "visible" || visibility === "user" || visibility === "chat" || audience === "chat" || record.userFacing === true || meta?.userFacing === true;
8241
+ return readStringField(record.transcriptVisibility ?? meta?.transcriptVisibility ?? record.visibility ?? meta?.visibility);
8242
+ }
8243
+ var EXPLICIT_HIDDEN_VISIBILITIES = /* @__PURE__ */ new Set(["hidden", "debug", "internal"]);
8244
+ var EXPLICIT_VISIBLE_VISIBILITIES = /* @__PURE__ */ new Set(["visible", "user", "chat"]);
8245
+ var HIDDEN_AUDIENCES = /* @__PURE__ */ new Set(["debug", "trace", "internal"]);
8246
+ var ACTIVITY_SOURCE_SET = new Set(CHAT_MESSAGE_ACTIVITY_SOURCES);
8247
+ var INTERNAL_SOURCE_SET = new Set(CHAT_MESSAGE_INTERNAL_SOURCES);
8248
+ function hasBooleanMarker(message, meta, keys) {
8249
+ const record = message;
8250
+ return keys.some((key) => record[key] === true || meta?.[key] === true);
8180
8251
  }
8181
- function isUserFacingChatMessage(message) {
8182
- if (!message) return false;
8183
- const meta = readMessageMeta(message);
8184
- if (isExplicitlyHiddenFromTranscript(message, meta)) return false;
8185
- if (isExplicitlyVisibleInTranscript(message, meta)) return true;
8186
- const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
8187
- const kind = resolveChatMessageKind(message);
8252
+ function isActivityKind(kind) {
8253
+ return kind === "thought" || kind === "tool" || kind === "terminal";
8254
+ }
8255
+ function isOrdinaryVisibleTurn(message, role, kind) {
8188
8256
  if (role === "user" || role === "human") return kind === "standard" || kind === "";
8189
8257
  if (role === "assistant") return kind === "standard" || kind === "";
8190
8258
  return false;
8191
8259
  }
8260
+ function classifyChatMessageVisibility(message) {
8261
+ if (!message) {
8262
+ return {
8263
+ surface: "internal",
8264
+ isUserFacing: false,
8265
+ isActivityFacing: false,
8266
+ isInternal: true,
8267
+ explicitUserFacing: false,
8268
+ explicitHidden: true,
8269
+ role: "",
8270
+ kind: "standard",
8271
+ visibility: "",
8272
+ transcriptVisibility: "",
8273
+ audience: "",
8274
+ source: ""
8275
+ };
8276
+ }
8277
+ const meta = readMessageMeta(message);
8278
+ const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
8279
+ const kind = resolveChatMessageKind(message);
8280
+ const visibility = readVisibilityField(message, meta);
8281
+ const transcriptVisibility = readTranscriptVisibilityField(message, meta);
8282
+ const audience = readStringField(readRecordField(message, meta, "audience"));
8283
+ const source = readStringField(readRecordField(message, meta, "source"));
8284
+ const explicitHidden = EXPLICIT_HIDDEN_VISIBILITIES.has(visibility) || EXPLICIT_HIDDEN_VISIBILITIES.has(transcriptVisibility) || HIDDEN_AUDIENCES.has(audience) || hasBooleanMarker(message, meta, ["internal", "isInternal", "debug", "statusOnly", "controlOnly"]);
8285
+ const explicitUserFacing = EXPLICIT_VISIBLE_VISIBILITIES.has(visibility) || EXPLICIT_VISIBLE_VISIBILITIES.has(transcriptVisibility) || audience === "chat" || hasBooleanMarker(message, meta, ["userFacing"]);
8286
+ if (explicitHidden) {
8287
+ const activityLike = isActivityKind(kind) || ACTIVITY_SOURCE_SET.has(source);
8288
+ return {
8289
+ surface: activityLike ? "activity" : "internal",
8290
+ isUserFacing: false,
8291
+ isActivityFacing: activityLike,
8292
+ isInternal: !activityLike,
8293
+ explicitUserFacing,
8294
+ explicitHidden,
8295
+ role,
8296
+ kind,
8297
+ visibility,
8298
+ transcriptVisibility,
8299
+ audience,
8300
+ source
8301
+ };
8302
+ }
8303
+ if (explicitUserFacing) {
8304
+ return {
8305
+ surface: "chat",
8306
+ isUserFacing: true,
8307
+ isActivityFacing: false,
8308
+ isInternal: false,
8309
+ explicitUserFacing,
8310
+ explicitHidden,
8311
+ role,
8312
+ kind,
8313
+ visibility,
8314
+ transcriptVisibility,
8315
+ audience,
8316
+ source
8317
+ };
8318
+ }
8319
+ if (INTERNAL_SOURCE_SET.has(source) || role === "system" || kind === "system") {
8320
+ return {
8321
+ surface: "internal",
8322
+ isUserFacing: false,
8323
+ isActivityFacing: false,
8324
+ isInternal: true,
8325
+ explicitUserFacing,
8326
+ explicitHidden,
8327
+ role,
8328
+ kind,
8329
+ visibility,
8330
+ transcriptVisibility,
8331
+ audience,
8332
+ source
8333
+ };
8334
+ }
8335
+ if (ACTIVITY_SOURCE_SET.has(source) || isActivityKind(kind)) {
8336
+ return {
8337
+ surface: "activity",
8338
+ isUserFacing: false,
8339
+ isActivityFacing: true,
8340
+ isInternal: false,
8341
+ explicitUserFacing,
8342
+ explicitHidden,
8343
+ role,
8344
+ kind,
8345
+ visibility,
8346
+ transcriptVisibility,
8347
+ audience,
8348
+ source
8349
+ };
8350
+ }
8351
+ const isUserFacing = isOrdinaryVisibleTurn(message, role, kind);
8352
+ return {
8353
+ surface: isUserFacing ? "chat" : "internal",
8354
+ isUserFacing,
8355
+ isActivityFacing: false,
8356
+ isInternal: !isUserFacing,
8357
+ explicitUserFacing,
8358
+ explicitHidden,
8359
+ role,
8360
+ kind,
8361
+ visibility,
8362
+ transcriptVisibility,
8363
+ audience,
8364
+ source
8365
+ };
8366
+ }
8367
+ function isUserFacingChatMessage(message) {
8368
+ return classifyChatMessageVisibility(message).isUserFacing;
8369
+ }
8370
+ function isActivityChatMessage(message) {
8371
+ return classifyChatMessageVisibility(message).isActivityFacing;
8372
+ }
8373
+ function isInternalChatMessage(message) {
8374
+ return classifyChatMessageVisibility(message).isInternal;
8375
+ }
8192
8376
  function filterUserFacingChatMessages(messages) {
8193
8377
  return (Array.isArray(messages) ? messages : []).filter((message) => isUserFacingChatMessage(message));
8194
8378
  }
8379
+ function filterActivityChatMessages(messages) {
8380
+ return (Array.isArray(messages) ? messages : []).filter((message) => isActivityChatMessage(message));
8381
+ }
8382
+ function filterInternalChatMessages(messages) {
8383
+ return (Array.isArray(messages) ? messages : []).filter((message) => isInternalChatMessage(message));
8384
+ }
8385
+ function filterChatMessagesByVisibility(messages, surface) {
8386
+ return (Array.isArray(messages) ? messages : []).filter((message) => classifyChatMessageVisibility(message).surface === surface);
8387
+ }
8195
8388
 
8196
8389
  // src/providers/control-effects.ts
8197
8390
  function extractProviderControlValues(controls, data) {
@@ -11412,6 +11605,147 @@ function normalizeActiveChatData(activeChat, options = FULL_STATUS_ACTIVE_CHAT_O
11412
11605
  return normalized;
11413
11606
  }
11414
11607
 
11608
+ // src/providers/provider-input-support.ts
11609
+ var VALID_INPUT_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
11610
+ var VALID_INPUT_STRATEGIES = /* @__PURE__ */ new Set(["native", "native_acp", "resource_link", "text_fallback", "paste", "upload"]);
11611
+ var TEXT_ONLY_MESSAGE_INPUT_SUPPORT = Object.freeze({
11612
+ text: true,
11613
+ multipart: false,
11614
+ mediaTypes: ["text"],
11615
+ strategies: []
11616
+ });
11617
+ function getProviderLabel(provider) {
11618
+ return provider?.name || provider?.type || "This provider";
11619
+ }
11620
+ function hasNonEmptyFallbackText(input) {
11621
+ return typeof input.textFallback === "string" && input.textFallback.trim().length > 0;
11622
+ }
11623
+ function getRequestedInputMediaTypes(input) {
11624
+ const types = /* @__PURE__ */ new Set();
11625
+ if (hasNonEmptyFallbackText(input) && !input.parts.some((part) => part.type === "text")) {
11626
+ types.add("text");
11627
+ }
11628
+ for (const part of input.parts) {
11629
+ if (VALID_INPUT_MEDIA_TYPES.has(part.type)) {
11630
+ types.add(part.type);
11631
+ }
11632
+ }
11633
+ return Array.from(types);
11634
+ }
11635
+ function getEffectiveSemanticPartCount(input) {
11636
+ let count = input.parts.length;
11637
+ if (hasNonEmptyFallbackText(input) && !input.parts.some((part) => part.type === "text")) {
11638
+ count += 1;
11639
+ }
11640
+ return count;
11641
+ }
11642
+ function assertTextOnlyInput(provider, input) {
11643
+ const unsupported = getRequestedInputMediaTypes(input).filter((type) => type !== "text");
11644
+ if (unsupported.length === 0) return;
11645
+ const label = getProviderLabel(provider);
11646
+ const suffix = unsupported.length === 1 ? "" : "s";
11647
+ throw new Error(`${label} only supports text input; unsupported input type${suffix}: ${unsupported.join(", ")}`);
11648
+ }
11649
+ function getDeclaredProviderInputSupport(provider) {
11650
+ const rawMediaTypes = Array.isArray(provider?.capabilities?.input?.mediaTypes) ? provider?.capabilities?.input?.mediaTypes.filter((type) => VALID_INPUT_MEDIA_TYPES.has(type)) : [];
11651
+ const strategies = normalizeInputStrategyDescriptors(provider?.capabilities?.input?.strategies);
11652
+ return {
11653
+ multipart: provider?.capabilities?.input?.multipart === true,
11654
+ mediaTypes: new Set(rawMediaTypes.length > 0 ? rawMediaTypes : ["text"]),
11655
+ strategies
11656
+ };
11657
+ }
11658
+ function normalizeInputStrategyDescriptors(raw) {
11659
+ if (!Array.isArray(raw)) return [];
11660
+ const result = [];
11661
+ for (const entry of raw) {
11662
+ if (!entry || typeof entry !== "object") continue;
11663
+ const record = entry;
11664
+ const mediaType = record.mediaType;
11665
+ if (typeof mediaType !== "string" || !VALID_INPUT_MEDIA_TYPES.has(mediaType)) continue;
11666
+ const strategies = Array.isArray(record.strategies) ? record.strategies.filter((value) => typeof value === "string" && VALID_INPUT_STRATEGIES.has(value)) : [];
11667
+ const degradation = Array.isArray(record.degradation) ? record.degradation.filter((value) => typeof value === "string" && VALID_INPUT_STRATEGIES.has(value)) : [];
11668
+ if (strategies.length === 0 && degradation.length === 0) continue;
11669
+ result.push({
11670
+ mediaType,
11671
+ strategies,
11672
+ ...typeof record.native === "boolean" ? { native: record.native } : {},
11673
+ ...degradation.length > 0 ? { degradation } : {}
11674
+ });
11675
+ }
11676
+ return result;
11677
+ }
11678
+ function promptCapabilityFlags(runtimeCapabilities) {
11679
+ const prompt = runtimeCapabilities?.promptCapabilities || {};
11680
+ return {
11681
+ image: prompt.image === true,
11682
+ audio: prompt.audio === true,
11683
+ embeddedContext: prompt.embeddedContext === true
11684
+ };
11685
+ }
11686
+ function supportFromDeclared(provider) {
11687
+ const declared = getDeclaredProviderInputSupport(provider);
11688
+ return {
11689
+ text: true,
11690
+ multipart: declared.multipart,
11691
+ mediaTypes: Array.from(declared.mediaTypes),
11692
+ strategies: declared.strategies
11693
+ };
11694
+ }
11695
+ function getEffectiveMessageInputSupport(provider, runtimeCapabilities) {
11696
+ if (provider?.category !== "acp") {
11697
+ const declared2 = supportFromDeclared(provider);
11698
+ return {
11699
+ ...declared2,
11700
+ mediaTypes: [...declared2.mediaTypes],
11701
+ strategies: declared2.strategies.map((strategy) => ({
11702
+ ...strategy,
11703
+ strategies: [...strategy.strategies],
11704
+ ...strategy.degradation ? { degradation: [...strategy.degradation] } : {}
11705
+ }))
11706
+ };
11707
+ }
11708
+ const declared = supportFromDeclared(provider);
11709
+ const caps = promptCapabilityFlags(runtimeCapabilities);
11710
+ const mediaTypes = /* @__PURE__ */ new Set(["text"]);
11711
+ const strategies = [];
11712
+ if (declared.mediaTypes.includes("resource")) {
11713
+ mediaTypes.add("resource");
11714
+ strategies.push({ mediaType: "resource", strategies: caps.embeddedContext ? ["native_acp", "resource_link", "text_fallback"] : ["resource_link", "text_fallback"], native: caps.embeddedContext, degradation: ["resource_link", "text_fallback"] });
11715
+ }
11716
+ if (declared.mediaTypes.includes("video")) {
11717
+ mediaTypes.add("video");
11718
+ strategies.push({ mediaType: "video", strategies: ["resource_link", "text_fallback"], native: false, degradation: ["resource_link", "text_fallback"] });
11719
+ }
11720
+ if (declared.mediaTypes.includes("image")) {
11721
+ mediaTypes.add("image");
11722
+ strategies.push({ mediaType: "image", strategies: caps.image ? ["native_acp", "resource_link", "text_fallback"] : ["resource_link", "text_fallback"], native: caps.image, degradation: ["resource_link", "text_fallback"] });
11723
+ }
11724
+ if (declared.mediaTypes.includes("audio")) {
11725
+ mediaTypes.add("audio");
11726
+ strategies.push({ mediaType: "audio", strategies: caps.audio ? ["native_acp", "resource_link", "text_fallback"] : ["resource_link", "text_fallback"], native: caps.audio, degradation: ["resource_link", "text_fallback"] });
11727
+ }
11728
+ return {
11729
+ text: true,
11730
+ multipart: declared.multipart && mediaTypes.size > 1,
11731
+ mediaTypes: Array.from(mediaTypes),
11732
+ strategies
11733
+ };
11734
+ }
11735
+ function assertProviderSupportsDeclaredInput(provider, input) {
11736
+ const label = getProviderLabel(provider);
11737
+ const support = getDeclaredProviderInputSupport(provider);
11738
+ const requestedTypes = getRequestedInputMediaTypes(input);
11739
+ const unsupported = requestedTypes.filter((type) => !support.mediaTypes.has(type));
11740
+ if (unsupported.length > 0) {
11741
+ const suffix = unsupported.length === 1 ? "" : "s";
11742
+ throw new Error(`${label} does not support input type${suffix}: ${unsupported.join(", ")}`);
11743
+ }
11744
+ if (getEffectiveSemanticPartCount(input) > 1 && !support.multipart) {
11745
+ throw new Error(`${label} does not support multipart input`);
11746
+ }
11747
+ }
11748
+
11415
11749
  // src/status/builders.ts
11416
11750
  function getActiveChatOptions(profile) {
11417
11751
  if (profile === "full") return {};
@@ -11509,7 +11843,7 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
11509
11843
  ...git && { git },
11510
11844
  activeChat,
11511
11845
  ...summaryMetadata && { summaryMetadata },
11512
- ...includeSessionMetadata && { capabilities: state.sessionCapabilities || IDE_SESSION_CAPABILITIES },
11846
+ ...includeSessionMetadata && { capabilities: state.sessionCapabilities || IDE_SESSION_CAPABILITIES, messageInput: state.messageInput || TEXT_ONLY_MESSAGE_INPUT_SUPPORT },
11513
11847
  cdpConnected: state.cdpConnected ?? isCdpConnected(cdpManagers, state.type),
11514
11848
  ...includeSessionControls && {
11515
11849
  ...controlValues && { controlValues },
@@ -11544,7 +11878,7 @@ function buildExtensionAgentSession(parent, ext, options) {
11544
11878
  ...git && { git },
11545
11879
  activeChat,
11546
11880
  ...summaryMetadata && { summaryMetadata },
11547
- ...includeSessionMetadata && { capabilities: ext.sessionCapabilities || EXTENSION_SESSION_CAPABILITIES },
11881
+ ...includeSessionMetadata && { capabilities: ext.sessionCapabilities || EXTENSION_SESSION_CAPABILITIES, messageInput: ext.messageInput || TEXT_ONLY_MESSAGE_INPUT_SUPPORT },
11548
11882
  ...includeSessionControls && {
11549
11883
  ...controlValues && { controlValues },
11550
11884
  providerControls: ext.providerControls
@@ -11608,7 +11942,8 @@ function buildCliSession(state, options) {
11608
11942
  activeChat,
11609
11943
  ...summaryMetadata && { summaryMetadata },
11610
11944
  ...includeSessionMetadata && {
11611
- capabilities: state.mode === "terminal" ? PTY_SESSION_CAPABILITIES : CLI_CHAT_SESSION_CAPABILITIES
11945
+ capabilities: state.mode === "terminal" ? PTY_SESSION_CAPABILITIES : CLI_CHAT_SESSION_CAPABILITIES,
11946
+ messageInput: state.messageInput || TEXT_ONLY_MESSAGE_INPUT_SUPPORT
11612
11947
  },
11613
11948
  ...includeSessionControls && {
11614
11949
  ...controlValues && { controlValues },
@@ -11642,7 +11977,7 @@ function buildAcpSession(state, options) {
11642
11977
  ...git && { git },
11643
11978
  activeChat,
11644
11979
  ...summaryMetadata && { summaryMetadata },
11645
- ...includeSessionMetadata && { capabilities: ACP_SESSION_CAPABILITIES },
11980
+ ...includeSessionMetadata && { capabilities: ACP_SESSION_CAPABILITIES, messageInput: state.messageInput || TEXT_ONLY_MESSAGE_INPUT_SUPPORT },
11646
11981
  ...includeSessionControls && {
11647
11982
  ...controlValues && { controlValues },
11648
11983
  providerControls: state.providerControls
@@ -11761,63 +12096,6 @@ var fs4 = __toESM(require("fs"));
11761
12096
  var os6 = __toESM(require("os"));
11762
12097
  var path12 = __toESM(require("path"));
11763
12098
  var import_node_crypto = require("crypto");
11764
-
11765
- // src/providers/provider-input-support.ts
11766
- var VALID_INPUT_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
11767
- function getProviderLabel(provider) {
11768
- return provider?.name || provider?.type || "This provider";
11769
- }
11770
- function hasNonEmptyFallbackText(input) {
11771
- return typeof input.textFallback === "string" && input.textFallback.trim().length > 0;
11772
- }
11773
- function getRequestedInputMediaTypes(input) {
11774
- const types = /* @__PURE__ */ new Set();
11775
- if (hasNonEmptyFallbackText(input) && !input.parts.some((part) => part.type === "text")) {
11776
- types.add("text");
11777
- }
11778
- for (const part of input.parts) {
11779
- if (VALID_INPUT_MEDIA_TYPES.has(part.type)) {
11780
- types.add(part.type);
11781
- }
11782
- }
11783
- return Array.from(types);
11784
- }
11785
- function getEffectiveSemanticPartCount(input) {
11786
- let count = input.parts.length;
11787
- if (hasNonEmptyFallbackText(input) && !input.parts.some((part) => part.type === "text")) {
11788
- count += 1;
11789
- }
11790
- return count;
11791
- }
11792
- function assertTextOnlyInput(provider, input) {
11793
- const unsupported = getRequestedInputMediaTypes(input).filter((type) => type !== "text");
11794
- if (unsupported.length === 0) return;
11795
- const label = getProviderLabel(provider);
11796
- const suffix = unsupported.length === 1 ? "" : "s";
11797
- throw new Error(`${label} only supports text input; unsupported input type${suffix}: ${unsupported.join(", ")}`);
11798
- }
11799
- function getDeclaredProviderInputSupport(provider) {
11800
- const rawMediaTypes = Array.isArray(provider?.capabilities?.input?.mediaTypes) ? provider?.capabilities?.input?.mediaTypes.filter((type) => VALID_INPUT_MEDIA_TYPES.has(type)) : [];
11801
- return {
11802
- multipart: provider?.capabilities?.input?.multipart === true,
11803
- mediaTypes: new Set(rawMediaTypes.length > 0 ? rawMediaTypes : ["text"])
11804
- };
11805
- }
11806
- function assertProviderSupportsDeclaredInput(provider, input) {
11807
- const label = getProviderLabel(provider);
11808
- const support = getDeclaredProviderInputSupport(provider);
11809
- const requestedTypes = getRequestedInputMediaTypes(input);
11810
- const unsupported = requestedTypes.filter((type) => !support.mediaTypes.has(type));
11811
- if (unsupported.length > 0) {
11812
- const suffix = unsupported.length === 1 ? "" : "s";
11813
- throw new Error(`${label} does not support input type${suffix}: ${unsupported.join(", ")}`);
11814
- }
11815
- if (getEffectiveSemanticPartCount(input) > 1 && !support.multipart) {
11816
- throw new Error(`${label} does not support multipart input`);
11817
- }
11818
- }
11819
-
11820
- // src/commands/chat-commands.ts
11821
12099
  init_logger();
11822
12100
 
11823
12101
  // src/logging/debug-trace.ts
@@ -12007,10 +12285,25 @@ function buildRecentSendKey(h, args, provider, signature) {
12007
12285
  const target = args?.targetSessionId || args?.agentType || h.currentSession?.providerType || h.currentProviderType || h.currentManagerKey || "unknown";
12008
12286
  return `${transport}:${target}:${signature.trim()}`;
12009
12287
  }
12288
+ function summarizeSendInputPart(part) {
12289
+ if (!part || typeof part !== "object") return String(part ?? "");
12290
+ if (part.type === "text") return `text:${String(part.text || "").trim()}`;
12291
+ const fields = [
12292
+ `type=${String(part.type || "")}`,
12293
+ `mime=${String(part.mimeType || "")}`,
12294
+ `uri=${String(part.uri || "")}`,
12295
+ `name=${String(part.name || "")}`
12296
+ ];
12297
+ const data = typeof part.data === "string" ? part.data : typeof part.resource?.blob === "string" ? part.resource.blob : "";
12298
+ if (data) fields.push(`dataLen=${data.length}`, `dataHash=${hashSignatureParts([data]).slice(0, 12)}`);
12299
+ const textish = [part.alt, part.transcript, part.description, part.title, part.resource?.uri].filter((value) => typeof value === "string" && value.trim()).join("");
12300
+ if (textish) fields.push(`meta=${hashSignatureParts([textish]).slice(0, 12)}`);
12301
+ return fields.join(";");
12302
+ }
12010
12303
  function buildSendInputSignature(input) {
12011
12304
  const text = typeof input.textFallback === "string" ? input.textFallback.trim() : "";
12012
- if (text) return text;
12013
- return JSON.stringify(input.parts || []);
12305
+ const partSummaries = (input.parts || []).map(summarizeSendInputPart);
12306
+ return hashSignatureParts([text, ...partSummaries]);
12014
12307
  }
12015
12308
  function getSendChatInputEnvelope(args) {
12016
12309
  return normalizeInputEnvelope(args?.input ? { input: args.input } : args);
@@ -12891,6 +13184,17 @@ async function handleSendChat(h, args) {
12891
13184
  if (adapter) {
12892
13185
  _log(`${transport} adapter: ${adapter.cliType}`);
12893
13186
  try {
13187
+ const hasStructuredParts = input.parts.some((part) => part.type !== "text");
13188
+ if (hasStructuredParts) {
13189
+ const target = getTargetInstance(h, args);
13190
+ if (!target || target.category !== "cli") {
13191
+ return { success: false, error: `CLI instance not found for ${provider?.type || args?.agentType || "unknown"}` };
13192
+ }
13193
+ assertProviderSupportsDeclaredInput(provider, input);
13194
+ await waitOnceForFreshHermesCliStart(adapter, _log);
13195
+ target.onEvent("send_message", { input });
13196
+ return _logSendSuccess(`${transport}-instance`, target.type);
13197
+ }
12894
13198
  assertTextOnlyInput(provider, input);
12895
13199
  if (!text) return { success: false, error: "text required for PTY send" };
12896
13200
  await waitOnceForFreshHermesCliStart(adapter, _log);
@@ -14980,7 +15284,7 @@ var DaemonCommandHandler = class {
14980
15284
 
14981
15285
  // src/commands/cli-manager.ts
14982
15286
  var os13 = __toESM(require("os"));
14983
- var path17 = __toESM(require("path"));
15287
+ var path18 = __toESM(require("path"));
14984
15288
  var crypto4 = __toESM(require("crypto"));
14985
15289
  var import_fs6 = require("fs");
14986
15290
  var import_child_process6 = require("child_process");
@@ -15015,6 +15319,79 @@ function normalizeProviderSessionId(provider, providerSessionId) {
15015
15319
  }
15016
15320
 
15017
15321
  // src/providers/cli-provider-instance.ts
15322
+ var IMAGE_MIME_EXTENSIONS = {
15323
+ "image/png": ".png",
15324
+ "image/jpeg": ".jpg",
15325
+ "image/jpg": ".jpg",
15326
+ "image/gif": ".gif",
15327
+ "image/webp": ".webp",
15328
+ "image/bmp": ".bmp",
15329
+ "image/tiff": ".tiff",
15330
+ "image/svg+xml": ".svg"
15331
+ };
15332
+ function filePathFromUri(uri) {
15333
+ if (!uri) return null;
15334
+ if (uri.startsWith("file://")) {
15335
+ try {
15336
+ return decodeURIComponent(new URL(uri).pathname);
15337
+ } catch {
15338
+ return uri.slice("file://".length);
15339
+ }
15340
+ }
15341
+ if (path16.isAbsolute(uri)) return uri;
15342
+ return null;
15343
+ }
15344
+ function extensionForImageMime(mimeType) {
15345
+ return IMAGE_MIME_EXTENSIONS[mimeType.toLowerCase()] || ".img";
15346
+ }
15347
+ function safeInputImageBasename(index, mimeType) {
15348
+ const extension = extensionForImageMime(mimeType);
15349
+ const suffix = crypto3.randomBytes(6).toString("hex");
15350
+ return `adhdev-input-image-${Date.now()}-${index}-${suffix}${extension}`;
15351
+ }
15352
+ function materializeImageDataPart(part, index, dir) {
15353
+ if (!part.data) return null;
15354
+ const rawData = part.data.includes(",") ? part.data.split(",").pop() || "" : part.data;
15355
+ if (!rawData) return null;
15356
+ fs6.mkdirSync(dir, { recursive: true });
15357
+ const filePath = path16.join(dir, safeInputImageBasename(index, part.mimeType));
15358
+ fs6.writeFileSync(filePath, Buffer.from(rawData, "base64"));
15359
+ return filePath;
15360
+ }
15361
+ function buildCliStructuredInputPrompt(input, options = {}) {
15362
+ const promptParts = [];
15363
+ const imageRefs = [];
15364
+ const resourceRefs = [];
15365
+ const materializeDir = options.materializeDir || path16.join(os12.tmpdir(), "adhdev-input-media");
15366
+ input.parts.forEach((part, index) => {
15367
+ if (part.type === "text" && part.text.trim()) {
15368
+ promptParts.push(part.text.trim());
15369
+ return;
15370
+ }
15371
+ if (part.type === "image") {
15372
+ const localPath = typeof part.uri === "string" ? filePathFromUri(part.uri) : null;
15373
+ const materializedPath = !localPath && part.data ? materializeImageDataPart(part, index, materializeDir) : null;
15374
+ const ref = localPath || materializedPath || part.uri || "";
15375
+ if (ref) imageRefs.push(ref);
15376
+ if (part.alt?.trim()) promptParts.push(part.alt.trim());
15377
+ return;
15378
+ }
15379
+ if (part.type === "resource_link") {
15380
+ resourceRefs.push([part.title, part.name, part.description, part.uri].filter(Boolean).join("\n"));
15381
+ return;
15382
+ }
15383
+ if (part.type === "resource") {
15384
+ resourceRefs.push([part.name, part.text, part.uri].filter(Boolean).join("\n"));
15385
+ }
15386
+ });
15387
+ if (input.textFallback.trim()) promptParts.push(input.textFallback.trim());
15388
+ const ordered = [
15389
+ ...imageRefs,
15390
+ ...promptParts,
15391
+ ...resourceRefs
15392
+ ].filter((value, index, values) => value.trim().length > 0 && values.indexOf(value) === index);
15393
+ return ordered.join("\n");
15394
+ }
15018
15395
  function normalizePersistableCliHistoryContent(content) {
15019
15396
  return flattenContent(content).replace(/\s+/g, " ").trim();
15020
15397
  }
@@ -15334,6 +15711,7 @@ var CliProviderInstance = class {
15334
15711
  resume: this.provider.resume,
15335
15712
  controlValues: surface.controlValues,
15336
15713
  providerControls: this.provider.controls,
15714
+ messageInput: getEffectiveMessageInputSupport(this.provider),
15337
15715
  summaryMetadata: surface.summaryMetadata,
15338
15716
  errorMessage: this.errorMessage,
15339
15717
  errorReason: this.errorReason
@@ -15384,9 +15762,10 @@ var CliProviderInstance = class {
15384
15762
  onEvent(event, data) {
15385
15763
  if (event === "send_message") {
15386
15764
  const input = normalizeInputEnvelope(data);
15387
- assertTextOnlyInput(this.provider, input);
15388
- if (input.textFallback) {
15389
- void this.adapter.sendMessage(input.textFallback).catch((e) => {
15765
+ assertProviderSupportsDeclaredInput(this.provider, input);
15766
+ const promptText = buildCliStructuredInputPrompt(input);
15767
+ if (promptText) {
15768
+ void this.adapter.sendMessage(promptText).catch((e) => {
15390
15769
  LOG.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
15391
15770
  });
15392
15771
  }
@@ -16015,6 +16394,7 @@ ${effect.notification.body || ""}`.trim();
16015
16394
  };
16016
16395
 
16017
16396
  // src/providers/acp-provider-instance.ts
16397
+ var path17 = __toESM(require("path"));
16018
16398
  var import_stream = require("stream");
16019
16399
  var import_child_process5 = require("child_process");
16020
16400
  var import_sdk = require("@agentclientprotocol/sdk");
@@ -16034,6 +16414,31 @@ function appendPromptText(promptParts, text) {
16034
16414
  if (last?.type === "text" && last.text === normalized) return;
16035
16415
  promptParts.push({ type: "text", text: normalized });
16036
16416
  }
16417
+ function getUriDisplayName2(uri, fallback) {
16418
+ if (!uri) return fallback;
16419
+ try {
16420
+ const pathname = uri.startsWith("file://") ? new URL(uri).pathname : uri;
16421
+ return pathname.split(/[\\/]/).filter(Boolean).pop() || fallback;
16422
+ } catch {
16423
+ return uri.split(/[\\/]/).filter(Boolean).pop() || fallback;
16424
+ }
16425
+ }
16426
+ function appendResourceLink(promptParts, uri, fallbackName, mimeType, description, metadata) {
16427
+ promptParts.push({
16428
+ type: "resource_link",
16429
+ uri,
16430
+ name: metadata?.name || getUriDisplayName2(uri, fallbackName),
16431
+ ...metadata?.title ? { title: metadata.title } : {},
16432
+ ...mimeType ? { mimeType } : {},
16433
+ ...description ? { description } : {},
16434
+ ...typeof metadata?.size === "number" ? { size: metadata.size } : {},
16435
+ ...metadata?.annotations ? { annotations: metadata.annotations } : {}
16436
+ });
16437
+ }
16438
+ function appendMediaFallbackText(promptParts, label, details) {
16439
+ const normalizedDetails = details.map((value) => typeof value === "string" ? value.trim() : "").filter(Boolean);
16440
+ appendPromptText(promptParts, `[${[label, ...normalizedDetails].join(": ")}]`);
16441
+ }
16037
16442
  function buildAcpPromptParts(input, agentCapabilities) {
16038
16443
  const caps = getPromptCapabilityFlags(agentCapabilities);
16039
16444
  const promptParts = [];
@@ -16043,56 +16448,76 @@ function buildAcpPromptParts(input, agentCapabilities) {
16043
16448
  continue;
16044
16449
  }
16045
16450
  if (part.type === "image") {
16046
- if (!caps.image) {
16047
- throw new Error("ACP agent does not support input type: image");
16048
- }
16049
- if (!part.data) {
16050
- throw new Error("ACP image input requires inline image data");
16451
+ if (caps.image && part.data) {
16452
+ promptParts.push({
16453
+ type: "image",
16454
+ data: part.data,
16455
+ mimeType: part.mimeType,
16456
+ ...part.uri ? { uri: part.uri } : {},
16457
+ ...part.alt ? { alt: part.alt } : {}
16458
+ });
16459
+ if (part.alt) appendPromptText(promptParts, part.alt);
16460
+ } else if (part.uri) {
16461
+ appendResourceLink(promptParts, part.uri, "image", part.mimeType, part.alt);
16462
+ if (part.alt) appendPromptText(promptParts, part.alt);
16463
+ } else {
16464
+ appendMediaFallbackText(promptParts, "Image attachment", [part.alt, part.mimeType]);
16051
16465
  }
16052
- promptParts.push({
16053
- type: "image",
16054
- data: part.data,
16055
- mimeType: part.mimeType,
16056
- ...part.uri ? { uri: part.uri } : {}
16057
- });
16058
16466
  continue;
16059
16467
  }
16060
16468
  if (part.type === "audio") {
16061
- if (!caps.audio) {
16062
- throw new Error("ACP agent does not support input type: audio");
16063
- }
16064
- if (!part.data) {
16065
- throw new Error("ACP audio input requires inline audio data");
16469
+ if (caps.audio && part.data) {
16470
+ promptParts.push({
16471
+ type: "audio",
16472
+ data: part.data,
16473
+ mimeType: part.mimeType,
16474
+ ...part.uri ? { uri: part.uri } : {},
16475
+ ...part.transcript ? { transcript: part.transcript } : {}
16476
+ });
16477
+ if (part.transcript) appendPromptText(promptParts, part.transcript);
16478
+ } else if (part.uri) {
16479
+ appendResourceLink(promptParts, part.uri, "audio", part.mimeType, part.transcript);
16480
+ if (part.transcript) appendPromptText(promptParts, part.transcript);
16481
+ } else {
16482
+ appendMediaFallbackText(promptParts, "Audio attachment", [part.transcript, part.mimeType]);
16066
16483
  }
16067
- promptParts.push({
16068
- type: "audio",
16069
- data: part.data,
16070
- mimeType: part.mimeType
16071
- });
16072
16484
  continue;
16073
16485
  }
16074
16486
  if (part.type === "resource") {
16075
- if (!caps.embeddedContext) {
16076
- throw new Error("ACP agent does not support input type: resource");
16077
- }
16078
- if (part.text) {
16487
+ if (caps.embeddedContext && part.text) {
16079
16488
  promptParts.push({
16080
16489
  type: "resource",
16081
16490
  resource: { uri: part.uri, text: part.text, mimeType: part.mimeType ?? null }
16082
16491
  });
16083
16492
  continue;
16084
16493
  }
16085
- if (part.data) {
16494
+ if (caps.embeddedContext && part.data) {
16086
16495
  promptParts.push({
16087
16496
  type: "resource",
16088
16497
  resource: { uri: part.uri, blob: part.data, mimeType: part.mimeType ?? null }
16089
16498
  });
16090
16499
  continue;
16091
16500
  }
16092
- throw new Error("ACP resource input requires embedded text or binary data");
16501
+ appendResourceLink(promptParts, part.uri, part.name || "resource", part.mimeType, part.text);
16502
+ if (part.text) appendPromptText(promptParts, part.text);
16503
+ continue;
16504
+ }
16505
+ if (part.type === "resource_link") {
16506
+ appendResourceLink(promptParts, part.uri, part.name, part.mimeType, part.description, {
16507
+ name: part.name,
16508
+ ...part.title ? { title: part.title } : {},
16509
+ ...typeof part.size === "number" ? { size: part.size } : {},
16510
+ ...part.annotations ? { annotations: part.annotations } : {}
16511
+ });
16512
+ continue;
16093
16513
  }
16094
16514
  if (part.type === "video") {
16095
- throw new Error("ACP agent does not support input type: video");
16515
+ if (part.uri) {
16516
+ appendResourceLink(promptParts, part.uri, "video", part.mimeType, part.transcript);
16517
+ if (part.transcript) appendPromptText(promptParts, part.transcript);
16518
+ } else {
16519
+ appendMediaFallbackText(promptParts, "Video attachment", [part.transcript, part.mimeType]);
16520
+ }
16096
16521
  }
16097
16522
  }
16098
16523
  if (!promptParts.some((part) => part.type === "text") && input.textFallback) {
@@ -16225,6 +16650,7 @@ var AcpProviderInstance = class {
16225
16650
  lastUpdated: Date.now(),
16226
16651
  settings: this.settings,
16227
16652
  pendingEvents: this.flushEvents(),
16653
+ messageInput: getEffectiveMessageInputSupport(this.provider, this.agentCapabilities),
16228
16654
  // ACP-specific: expose available models/modes for dashboard
16229
16655
  acpConfigOptions: this.configOptions,
16230
16656
  acpModes: this.availableModes,
@@ -16726,22 +17152,38 @@ var AcpProviderInstance = class {
16726
17152
  type: "image",
16727
17153
  data: b.data,
16728
17154
  mimeType: b.mimeType,
16729
- ...b.uri ? { uri: b.uri } : {}
17155
+ ...b.uri ? { uri: b.uri } : {},
17156
+ ...b.alt ? { alt: b.alt } : {}
16730
17157
  };
16731
17158
  }
16732
17159
  if (b.type === "audio") {
16733
17160
  return {
16734
17161
  type: "audio",
16735
17162
  data: b.data,
16736
- mimeType: b.mimeType
17163
+ mimeType: b.mimeType,
17164
+ ...b.uri ? { uri: b.uri } : {},
17165
+ ...b.transcript ? { transcript: b.transcript } : {}
16737
17166
  };
16738
17167
  }
17168
+ if (b.type === "video") {
17169
+ return b.uri ? {
17170
+ type: "resource_link",
17171
+ uri: b.uri,
17172
+ name: path17.basename(b.uri),
17173
+ mimeType: b.mimeType,
17174
+ ...b.transcript ? { description: b.transcript } : {}
17175
+ } : { type: "text", text: b.transcript || `[Video attachment: ${b.mimeType}]` };
17176
+ }
16739
17177
  if (b.type === "resource_link") {
16740
17178
  return {
16741
17179
  type: "resource_link",
16742
17180
  uri: b.uri,
16743
17181
  name: b.name,
16744
- ...b.mimeType ? { mimeType: b.mimeType } : {}
17182
+ ...b.title ? { title: b.title } : {},
17183
+ ...b.description ? { description: b.description } : {},
17184
+ ...b.mimeType ? { mimeType: b.mimeType } : {},
17185
+ ...typeof b.size === "number" ? { size: b.size } : {},
17186
+ ...b.annotations ? { annotations: b.annotations } : {}
16745
17187
  };
16746
17188
  }
16747
17189
  if (b.type === "resource") return { type: "resource", resource: b.resource };
@@ -16817,7 +17259,18 @@ var AcpProviderInstance = class {
16817
17259
  this.partialBlocks.push({
16818
17260
  type: "audio",
16819
17261
  data: content.data,
16820
- mimeType: content.mimeType
17262
+ mimeType: content.mimeType,
17263
+ ...content.uri ? { uri: content.uri } : {},
17264
+ ...content.transcript ? { transcript: content.transcript } : {}
17265
+ });
17266
+ } else if (content.type === "video") {
17267
+ this.partialBlocks.push({
17268
+ type: "video",
17269
+ data: content.data,
17270
+ mimeType: content.mimeType,
17271
+ ...content.uri ? { uri: content.uri } : {},
17272
+ ...content.transcript ? { transcript: content.transcript } : {},
17273
+ ...content.posterUri ? { posterUri: content.posterUri } : {}
16821
17274
  });
16822
17275
  } else if (content.type === "resource_link") {
16823
17276
  this.partialBlocks.push({
@@ -17174,11 +17627,11 @@ function shouldRestoreHostedRuntime(record, managerTag) {
17174
17627
  // src/commands/cli-manager.ts
17175
17628
  function isExplicitCommand(command) {
17176
17629
  const trimmed = command.trim();
17177
- return path17.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
17630
+ return path18.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
17178
17631
  }
17179
17632
  function expandExecutable(command) {
17180
17633
  const trimmed = command.trim();
17181
- return trimmed.startsWith("~") ? path17.join(os13.homedir(), trimmed.slice(1)) : trimmed;
17634
+ return trimmed.startsWith("~") ? path18.join(os13.homedir(), trimmed.slice(1)) : trimmed;
17182
17635
  }
17183
17636
  function commandExists(command) {
17184
17637
  const trimmed = command.trim();
@@ -17212,10 +17665,10 @@ function hasCliArg(args, flag) {
17212
17665
  return args.some((arg) => arg === flag || arg.startsWith(`${flag}=`));
17213
17666
  }
17214
17667
  function ensureEmptyDelegatedMcpConfig(workspace) {
17215
- const baseDir = path17.join(os13.tmpdir(), "adhdev-delegated-agent-empty-mcp");
17668
+ const baseDir = path18.join(os13.tmpdir(), "adhdev-delegated-agent-empty-mcp");
17216
17669
  (0, import_fs6.mkdirSync)(baseDir, { recursive: true });
17217
- const workspaceHash = crypto4.createHash("sha256").update(path17.resolve(workspace || os13.tmpdir())).digest("hex").slice(0, 16);
17218
- const filePath = path17.join(baseDir, `${workspaceHash}.json`);
17670
+ const workspaceHash = crypto4.createHash("sha256").update(path18.resolve(workspace || os13.tmpdir())).digest("hex").slice(0, 16);
17671
+ const filePath = path18.join(baseDir, `${workspaceHash}.json`);
17219
17672
  (0, import_fs6.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
17220
17673
  return filePath;
17221
17674
  }
@@ -17488,7 +17941,7 @@ var DaemonCliManager = class {
17488
17941
  async startSession(cliType, workingDir, cliArgs, initialModel, options) {
17489
17942
  const trimmed = (workingDir || "").trim();
17490
17943
  if (!trimmed) throw new Error("working directory required");
17491
- const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path17.resolve(trimmed);
17944
+ const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path18.resolve(trimmed);
17492
17945
  const normalizedType = this.providerLoader.resolveAlias(cliType);
17493
17946
  const rawProvider = this.providerLoader.getByAlias(cliType);
17494
17947
  const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
@@ -18002,17 +18455,18 @@ Run 'adhdev doctor' for detailed diagnostics.`
18002
18455
  var import_child_process7 = require("child_process");
18003
18456
  var net = __toESM(require("net"));
18004
18457
  var os15 = __toESM(require("os"));
18005
- var path19 = __toESM(require("path"));
18458
+ var path20 = __toESM(require("path"));
18006
18459
 
18007
18460
  // src/providers/provider-loader.ts
18008
18461
  var fs7 = __toESM(require("fs"));
18009
- var path18 = __toESM(require("path"));
18462
+ var path19 = __toESM(require("path"));
18010
18463
  var os14 = __toESM(require("os"));
18011
18464
  var chokidar = __toESM(require("chokidar"));
18012
18465
  init_logger();
18013
18466
 
18014
18467
  // src/providers/provider-schema.ts
18015
18468
  var VALID_CAPABILITY_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
18469
+ var VALID_INPUT_STRATEGIES2 = /* @__PURE__ */ new Set(["native", "native_acp", "resource_link", "text_fallback", "paste", "upload"]);
18016
18470
  var KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
18017
18471
  "type",
18018
18472
  "name",
@@ -18142,16 +18596,45 @@ function validateCapabilities(provider, controls, errors) {
18142
18596
  return;
18143
18597
  }
18144
18598
  const input = capabilities.input;
18145
- if (!input || typeof input !== "object") {
18146
- errors.push("capabilities.input is required");
18147
- } else {
18148
- if (typeof input.multipart !== "boolean") {
18599
+ if (input !== void 0) {
18600
+ if (!input || typeof input !== "object") {
18601
+ errors.push("capabilities.input must be an object when provided");
18602
+ } else if (typeof input.multipart !== "boolean") {
18149
18603
  errors.push("capabilities.input.multipart must be boolean");
18150
18604
  }
18151
- if (!Array.isArray(input.mediaTypes) || input.mediaTypes.length === 0) {
18152
- errors.push("capabilities.input.mediaTypes must be a non-empty array");
18153
- } else if (input.mediaTypes.some((type) => typeof type !== "string" || !VALID_CAPABILITY_MEDIA_TYPES.has(type))) {
18154
- errors.push(`capabilities.input.mediaTypes must only include: ${Array.from(VALID_CAPABILITY_MEDIA_TYPES).join(", ")}`);
18605
+ if (input && typeof input === "object") {
18606
+ const mediaTypes = Array.isArray(input.mediaTypes) ? input.mediaTypes : void 0;
18607
+ if (!mediaTypes || mediaTypes.length === 0) {
18608
+ errors.push("capabilities.input.mediaTypes must be a non-empty array");
18609
+ } else if (mediaTypes.some((type) => typeof type !== "string" || !VALID_CAPABILITY_MEDIA_TYPES.has(type))) {
18610
+ errors.push(`capabilities.input.mediaTypes must only include: ${Array.from(VALID_CAPABILITY_MEDIA_TYPES).join(", ")}`);
18611
+ }
18612
+ }
18613
+ if (input && typeof input === "object" && input.strategies !== void 0) {
18614
+ if (!Array.isArray(input.strategies)) {
18615
+ errors.push("capabilities.input.strategies must be an array when provided");
18616
+ } else {
18617
+ for (const strategy of input.strategies) {
18618
+ if (!strategy || typeof strategy !== "object" || Array.isArray(strategy)) {
18619
+ errors.push("capabilities.input.strategies entries must be objects");
18620
+ continue;
18621
+ }
18622
+ const entry = strategy;
18623
+ if (typeof entry.mediaType !== "string" || !VALID_CAPABILITY_MEDIA_TYPES.has(entry.mediaType)) {
18624
+ errors.push(`capabilities.input.strategies.mediaType must only include: ${Array.from(VALID_CAPABILITY_MEDIA_TYPES).join(", ")}`);
18625
+ }
18626
+ for (const field of ["strategies", "degradation"]) {
18627
+ const values = entry[field];
18628
+ if (values === void 0) continue;
18629
+ if (!Array.isArray(values) || values.some((value) => typeof value !== "string" || !VALID_INPUT_STRATEGIES2.has(value))) {
18630
+ errors.push(`capabilities.input.strategies.${field} must only include: ${Array.from(VALID_INPUT_STRATEGIES2).join(", ")}`);
18631
+ }
18632
+ }
18633
+ if (entry.native !== void 0 && typeof entry.native !== "boolean") {
18634
+ errors.push("capabilities.input.strategies.native must be boolean when provided");
18635
+ }
18636
+ }
18637
+ }
18155
18638
  }
18156
18639
  }
18157
18640
  const output = capabilities.output;
@@ -18330,7 +18813,7 @@ var ProviderLoader = class _ProviderLoader {
18330
18813
  try {
18331
18814
  if (!fs7.existsSync(candidate) || !fs7.statSync(candidate).isDirectory()) return false;
18332
18815
  return ["ide", "extension", "cli", "acp"].some(
18333
- (category) => fs7.existsSync(path18.join(candidate, category))
18816
+ (category) => fs7.existsSync(path19.join(candidate, category))
18334
18817
  );
18335
18818
  } catch {
18336
18819
  return false;
@@ -18338,20 +18821,20 @@ var ProviderLoader = class _ProviderLoader {
18338
18821
  }
18339
18822
  static hasProviderRootMarker(candidate) {
18340
18823
  try {
18341
- return fs7.existsSync(path18.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
18824
+ return fs7.existsSync(path19.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
18342
18825
  } catch {
18343
18826
  return false;
18344
18827
  }
18345
18828
  }
18346
18829
  detectDefaultUserDir() {
18347
- const fallback = path18.join(os14.homedir(), ".adhdev", "providers");
18830
+ const fallback = path19.join(os14.homedir(), ".adhdev", "providers");
18348
18831
  const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
18349
18832
  const visited = /* @__PURE__ */ new Set();
18350
18833
  for (const start of this.probeStarts) {
18351
- let current = path18.resolve(start);
18834
+ let current = path19.resolve(start);
18352
18835
  while (!visited.has(current)) {
18353
18836
  visited.add(current);
18354
- const siblingCandidate = path18.join(path18.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
18837
+ const siblingCandidate = path19.join(path19.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
18355
18838
  if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
18356
18839
  const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
18357
18840
  if (envOptIn || hasMarker) {
@@ -18373,7 +18856,7 @@ var ProviderLoader = class _ProviderLoader {
18373
18856
  return { path: siblingCandidate, source };
18374
18857
  }
18375
18858
  }
18376
- const parent = path18.dirname(current);
18859
+ const parent = path19.dirname(current);
18377
18860
  if (parent === current) break;
18378
18861
  current = parent;
18379
18862
  }
@@ -18383,11 +18866,11 @@ var ProviderLoader = class _ProviderLoader {
18383
18866
  constructor(options) {
18384
18867
  this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
18385
18868
  this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
18386
- this.defaultProvidersDir = path18.join(os14.homedir(), ".adhdev", "providers");
18869
+ this.defaultProvidersDir = path19.join(os14.homedir(), ".adhdev", "providers");
18387
18870
  const detected = this.detectDefaultUserDir();
18388
18871
  this.userDir = detected.path;
18389
18872
  this.userDirSource = detected.source;
18390
- this.upstreamDir = path18.join(this.defaultProvidersDir, ".upstream");
18873
+ this.upstreamDir = path19.join(this.defaultProvidersDir, ".upstream");
18391
18874
  this.disableUpstream = false;
18392
18875
  this.applySourceConfig({
18393
18876
  userDir: options?.userDir,
@@ -18446,7 +18929,7 @@ var ProviderLoader = class _ProviderLoader {
18446
18929
  this.userDir = detected.path;
18447
18930
  this.userDirSource = detected.source;
18448
18931
  }
18449
- this.upstreamDir = path18.join(this.defaultProvidersDir, ".upstream");
18932
+ this.upstreamDir = path19.join(this.defaultProvidersDir, ".upstream");
18450
18933
  this.disableUpstream = this.sourceMode === "no-upstream";
18451
18934
  if (this.explicitProviderDir) {
18452
18935
  this.log(`Config 'providerDir' applied: ${this.userDir}`);
@@ -18460,7 +18943,7 @@ var ProviderLoader = class _ProviderLoader {
18460
18943
  * Canonical provider directory shape for a given root.
18461
18944
  */
18462
18945
  getProviderDir(root, category, type) {
18463
- return path18.join(root, category, type);
18946
+ return path19.join(root, category, type);
18464
18947
  }
18465
18948
  /**
18466
18949
  * Canonical user override directory for a provider.
@@ -18487,7 +18970,7 @@ var ProviderLoader = class _ProviderLoader {
18487
18970
  resolveProviderFile(type, ...segments) {
18488
18971
  const dir = this.findProviderDirInternal(type);
18489
18972
  if (!dir) return null;
18490
- return path18.join(dir, ...segments);
18973
+ return path19.join(dir, ...segments);
18491
18974
  }
18492
18975
  /**
18493
18976
  * Load all providers (3-tier priority)
@@ -18526,7 +19009,7 @@ var ProviderLoader = class _ProviderLoader {
18526
19009
  if (!fs7.existsSync(this.upstreamDir)) return false;
18527
19010
  try {
18528
19011
  return fs7.readdirSync(this.upstreamDir).some(
18529
- (d) => fs7.statSync(path18.join(this.upstreamDir, d)).isDirectory()
19012
+ (d) => fs7.statSync(path19.join(this.upstreamDir, d)).isDirectory()
18530
19013
  );
18531
19014
  } catch {
18532
19015
  return false;
@@ -19023,8 +19506,8 @@ var ProviderLoader = class _ProviderLoader {
19023
19506
  resolved._resolvedScriptDir = entry.scriptDir;
19024
19507
  resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
19025
19508
  if (providerDir) {
19026
- const fullDir = path18.join(providerDir, entry.scriptDir);
19027
- resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
19509
+ const fullDir = path19.join(providerDir, entry.scriptDir);
19510
+ resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
19028
19511
  }
19029
19512
  matched = true;
19030
19513
  }
@@ -19039,8 +19522,8 @@ var ProviderLoader = class _ProviderLoader {
19039
19522
  resolved._resolvedScriptDir = base.defaultScriptDir;
19040
19523
  resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
19041
19524
  if (providerDir) {
19042
- const fullDir = path18.join(providerDir, base.defaultScriptDir);
19043
- resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
19525
+ const fullDir = path19.join(providerDir, base.defaultScriptDir);
19526
+ resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
19044
19527
  }
19045
19528
  }
19046
19529
  resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
@@ -19057,8 +19540,8 @@ var ProviderLoader = class _ProviderLoader {
19057
19540
  resolved._resolvedScriptDir = dirOverride;
19058
19541
  resolved._resolvedScriptsSource = `versions:${range}`;
19059
19542
  if (providerDir) {
19060
- const fullDir = path18.join(providerDir, dirOverride);
19061
- resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
19543
+ const fullDir = path19.join(providerDir, dirOverride);
19544
+ resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
19062
19545
  }
19063
19546
  }
19064
19547
  } else if (override.scripts) {
@@ -19074,8 +19557,8 @@ var ProviderLoader = class _ProviderLoader {
19074
19557
  resolved._resolvedScriptDir = base.defaultScriptDir;
19075
19558
  resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
19076
19559
  if (providerDir) {
19077
- const fullDir = path18.join(providerDir, base.defaultScriptDir);
19078
- resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
19560
+ const fullDir = path19.join(providerDir, base.defaultScriptDir);
19561
+ resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
19079
19562
  }
19080
19563
  }
19081
19564
  }
@@ -19107,14 +19590,14 @@ var ProviderLoader = class _ProviderLoader {
19107
19590
  this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
19108
19591
  return null;
19109
19592
  }
19110
- const dir = path18.join(providerDir, scriptDir);
19593
+ const dir = path19.join(providerDir, scriptDir);
19111
19594
  if (!fs7.existsSync(dir)) {
19112
19595
  this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
19113
19596
  return null;
19114
19597
  }
19115
19598
  const cached = this.scriptsCache.get(dir);
19116
19599
  if (cached) return cached;
19117
- const scriptsJs = path18.join(dir, "scripts.js");
19600
+ const scriptsJs = path19.join(dir, "scripts.js");
19118
19601
  if (fs7.existsSync(scriptsJs)) {
19119
19602
  try {
19120
19603
  delete require.cache[require.resolve(scriptsJs)];
@@ -19156,7 +19639,7 @@ var ProviderLoader = class _ProviderLoader {
19156
19639
  return;
19157
19640
  }
19158
19641
  if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
19159
- this.log(`File changed: ${path18.basename(filePath)}, reloading...`);
19642
+ this.log(`File changed: ${path19.basename(filePath)}, reloading...`);
19160
19643
  this.reload();
19161
19644
  }
19162
19645
  };
@@ -19211,7 +19694,7 @@ var ProviderLoader = class _ProviderLoader {
19211
19694
  }
19212
19695
  const https = require("https");
19213
19696
  const { execSync: execSync7 } = require("child_process");
19214
- const metaPath = path18.join(this.upstreamDir, _ProviderLoader.META_FILE);
19697
+ const metaPath = path19.join(this.upstreamDir, _ProviderLoader.META_FILE);
19215
19698
  let prevEtag = "";
19216
19699
  let prevTimestamp = 0;
19217
19700
  try {
@@ -19271,17 +19754,17 @@ var ProviderLoader = class _ProviderLoader {
19271
19754
  return { updated: false };
19272
19755
  }
19273
19756
  this.log("Downloading latest providers from GitHub...");
19274
- const tmpTar = path18.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
19275
- const tmpExtract = path18.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
19757
+ const tmpTar = path19.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
19758
+ const tmpExtract = path19.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
19276
19759
  await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
19277
19760
  fs7.mkdirSync(tmpExtract, { recursive: true });
19278
19761
  execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
19279
19762
  const extracted = fs7.readdirSync(tmpExtract);
19280
19763
  const rootDir = extracted.find(
19281
- (d) => fs7.statSync(path18.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
19764
+ (d) => fs7.statSync(path19.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
19282
19765
  );
19283
19766
  if (!rootDir) throw new Error("Unexpected tarball structure");
19284
- const sourceDir = path18.join(tmpExtract, rootDir);
19767
+ const sourceDir = path19.join(tmpExtract, rootDir);
19285
19768
  const backupDir = this.upstreamDir + ".bak";
19286
19769
  if (fs7.existsSync(this.upstreamDir)) {
19287
19770
  if (fs7.existsSync(backupDir)) fs7.rmSync(backupDir, { recursive: true, force: true });
@@ -19356,8 +19839,8 @@ var ProviderLoader = class _ProviderLoader {
19356
19839
  copyDirRecursive(src, dest) {
19357
19840
  fs7.mkdirSync(dest, { recursive: true });
19358
19841
  for (const entry of fs7.readdirSync(src, { withFileTypes: true })) {
19359
- const srcPath = path18.join(src, entry.name);
19360
- const destPath = path18.join(dest, entry.name);
19842
+ const srcPath = path19.join(src, entry.name);
19843
+ const destPath = path19.join(dest, entry.name);
19361
19844
  if (entry.isDirectory()) {
19362
19845
  this.copyDirRecursive(srcPath, destPath);
19363
19846
  } else {
@@ -19368,7 +19851,7 @@ var ProviderLoader = class _ProviderLoader {
19368
19851
  /** .meta.json save */
19369
19852
  writeMeta(metaPath, etag, timestamp) {
19370
19853
  try {
19371
- fs7.mkdirSync(path18.dirname(metaPath), { recursive: true });
19854
+ fs7.mkdirSync(path19.dirname(metaPath), { recursive: true });
19372
19855
  fs7.writeFileSync(metaPath, JSON.stringify({
19373
19856
  etag,
19374
19857
  timestamp,
@@ -19385,7 +19868,7 @@ var ProviderLoader = class _ProviderLoader {
19385
19868
  const scan = (d) => {
19386
19869
  try {
19387
19870
  for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
19388
- if (entry.isDirectory()) scan(path18.join(d, entry.name));
19871
+ if (entry.isDirectory()) scan(path19.join(d, entry.name));
19389
19872
  else if (entry.name === "provider.json") count++;
19390
19873
  }
19391
19874
  } catch {
@@ -19613,17 +20096,17 @@ var ProviderLoader = class _ProviderLoader {
19613
20096
  for (const root of searchRoots) {
19614
20097
  if (!fs7.existsSync(root)) continue;
19615
20098
  const candidate = this.getProviderDir(root, cat, type);
19616
- if (fs7.existsSync(path18.join(candidate, "provider.json"))) return candidate;
19617
- const catDir = path18.join(root, cat);
20099
+ if (fs7.existsSync(path19.join(candidate, "provider.json"))) return candidate;
20100
+ const catDir = path19.join(root, cat);
19618
20101
  if (fs7.existsSync(catDir)) {
19619
20102
  try {
19620
20103
  for (const entry of fs7.readdirSync(catDir, { withFileTypes: true })) {
19621
20104
  if (!entry.isDirectory()) continue;
19622
- const jsonPath = path18.join(catDir, entry.name, "provider.json");
20105
+ const jsonPath = path19.join(catDir, entry.name, "provider.json");
19623
20106
  if (fs7.existsSync(jsonPath)) {
19624
20107
  try {
19625
20108
  const data = JSON.parse(fs7.readFileSync(jsonPath, "utf-8"));
19626
- if (data.type === type) return path18.join(catDir, entry.name);
20109
+ if (data.type === type) return path19.join(catDir, entry.name);
19627
20110
  } catch {
19628
20111
  }
19629
20112
  }
@@ -19640,7 +20123,7 @@ var ProviderLoader = class _ProviderLoader {
19640
20123
  * (template substitution is NOT applied here — scripts.js handles that)
19641
20124
  */
19642
20125
  buildScriptWrappersFromDir(dir) {
19643
- const scriptsJs = path18.join(dir, "scripts.js");
20126
+ const scriptsJs = path19.join(dir, "scripts.js");
19644
20127
  if (fs7.existsSync(scriptsJs)) {
19645
20128
  try {
19646
20129
  delete require.cache[require.resolve(scriptsJs)];
@@ -19654,7 +20137,7 @@ var ProviderLoader = class _ProviderLoader {
19654
20137
  for (const file of fs7.readdirSync(dir)) {
19655
20138
  if (!file.endsWith(".js")) continue;
19656
20139
  const scriptName = toCamel(file.replace(".js", ""));
19657
- const filePath = path18.join(dir, file);
20140
+ const filePath = path19.join(dir, file);
19658
20141
  result[scriptName] = (...args) => {
19659
20142
  try {
19660
20143
  let content = fs7.readFileSync(filePath, "utf-8");
@@ -19714,7 +20197,7 @@ var ProviderLoader = class _ProviderLoader {
19714
20197
  }
19715
20198
  const hasJson = entries.some((e) => e.name === "provider.json");
19716
20199
  if (hasJson) {
19717
- const jsonPath = path18.join(d, "provider.json");
20200
+ const jsonPath = path19.join(d, "provider.json");
19718
20201
  try {
19719
20202
  const raw = fs7.readFileSync(jsonPath, "utf-8");
19720
20203
  const mod = JSON.parse(raw);
@@ -19735,7 +20218,7 @@ var ProviderLoader = class _ProviderLoader {
19735
20218
  this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
19736
20219
  } else {
19737
20220
  const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
19738
- const scriptsPath = path18.join(d, "scripts.js");
20221
+ const scriptsPath = path19.join(d, "scripts.js");
19739
20222
  if (!hasCompatibility && fs7.existsSync(scriptsPath)) {
19740
20223
  try {
19741
20224
  delete require.cache[require.resolve(scriptsPath)];
@@ -19761,7 +20244,7 @@ var ProviderLoader = class _ProviderLoader {
19761
20244
  if (!entry.isDirectory()) continue;
19762
20245
  if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
19763
20246
  if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
19764
- scan(path18.join(d, entry.name));
20247
+ scan(path19.join(d, entry.name));
19765
20248
  }
19766
20249
  }
19767
20250
  };
@@ -20086,8 +20569,8 @@ function detectCurrentWorkspace(ideId) {
20086
20569
  const appNameMap = getMacAppIdentifiers();
20087
20570
  const appName = appNameMap[ideId];
20088
20571
  if (appName) {
20089
- const storagePath = path19.join(
20090
- process.env.APPDATA || path19.join(os15.homedir(), "AppData", "Roaming"),
20572
+ const storagePath = path20.join(
20573
+ process.env.APPDATA || path20.join(os15.homedir(), "AppData", "Roaming"),
20091
20574
  appName,
20092
20575
  "storage.json"
20093
20576
  );
@@ -20276,9 +20759,9 @@ init_logger();
20276
20759
 
20277
20760
  // src/logging/command-log.ts
20278
20761
  var fs8 = __toESM(require("fs"));
20279
- var path20 = __toESM(require("path"));
20762
+ var path21 = __toESM(require("path"));
20280
20763
  var os16 = __toESM(require("os"));
20281
- var LOG_DIR2 = process.platform === "win32" ? path20.join(process.env.LOCALAPPDATA || process.env.APPDATA || path20.join(os16.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path20.join(os16.homedir(), "Library", "Logs", "adhdev") : path20.join(os16.homedir(), ".local", "share", "adhdev", "logs");
20764
+ var LOG_DIR2 = process.platform === "win32" ? path21.join(process.env.LOCALAPPDATA || process.env.APPDATA || path21.join(os16.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path21.join(os16.homedir(), "Library", "Logs", "adhdev") : path21.join(os16.homedir(), ".local", "share", "adhdev", "logs");
20282
20765
  var MAX_FILE_SIZE = 5 * 1024 * 1024;
20283
20766
  var MAX_DAYS = 7;
20284
20767
  try {
@@ -20316,13 +20799,13 @@ function getDateStr2() {
20316
20799
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
20317
20800
  }
20318
20801
  var currentDate2 = getDateStr2();
20319
- var currentFile = path20.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
20802
+ var currentFile = path21.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
20320
20803
  var writeCount2 = 0;
20321
20804
  function checkRotation() {
20322
20805
  const today = getDateStr2();
20323
20806
  if (today !== currentDate2) {
20324
20807
  currentDate2 = today;
20325
- currentFile = path20.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
20808
+ currentFile = path21.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
20326
20809
  cleanOldFiles();
20327
20810
  }
20328
20811
  }
@@ -20336,7 +20819,7 @@ function cleanOldFiles() {
20336
20819
  const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
20337
20820
  if (dateMatch && dateMatch[1] < cutoffStr) {
20338
20821
  try {
20339
- fs8.unlinkSync(path20.join(LOG_DIR2, file));
20822
+ fs8.unlinkSync(path21.join(LOG_DIR2, file));
20340
20823
  } catch {
20341
20824
  }
20342
20825
  }
@@ -20424,6 +20907,7 @@ init_logger();
20424
20907
 
20425
20908
  // src/commands/mesh-coordinator.ts
20426
20909
  var import_node_child_process3 = require("child_process");
20910
+ var import_node_crypto2 = require("crypto");
20427
20911
  var import_node_fs3 = require("fs");
20428
20912
  var import_node_module2 = require("module");
20429
20913
  var os17 = __toESM(require("os"));
@@ -20448,7 +20932,7 @@ function resolveHermesMeshCoordinatorSetup(options) {
20448
20932
  reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
20449
20933
  };
20450
20934
  }
20451
- const configPath = resolveMcpConfigPath(HERMES_MCP_CONFIG_PATH, options.workspace);
20935
+ const configPath = (0, import_node_path.join)(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
20452
20936
  if (!configPath.trim()) {
20453
20937
  return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
20454
20938
  }
@@ -20500,8 +20984,8 @@ function resolveMeshCoordinatorSetup(options) {
20500
20984
  }
20501
20985
  const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
20502
20986
  if (mcpConfig.mode === "auto_import") {
20503
- const path27 = mcpConfig.path?.trim();
20504
- if (!path27) {
20987
+ const path28 = mcpConfig.path?.trim();
20988
+ if (!path28) {
20505
20989
  return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
20506
20990
  }
20507
20991
  const mcpServer = resolveAdhdevMcpServerLaunch({
@@ -20518,7 +21002,7 @@ function resolveMeshCoordinatorSetup(options) {
20518
21002
  return {
20519
21003
  kind: "auto_import",
20520
21004
  serverName,
20521
- configPath: resolveMcpConfigPath(path27, workspace),
21005
+ configPath: resolveMcpConfigPath(path28, workspace),
20522
21006
  configFormat: mcpConfig.format,
20523
21007
  mcpServer
20524
21008
  };
@@ -20552,6 +21036,12 @@ function resolveMeshCoordinatorSetup(options) {
20552
21036
  function renderMeshCoordinatorTemplate(template, values) {
20553
21037
  return template.replace(/\{\{\s*(meshId|workspace|serverName|adhdevMcpCommand)\s*\}\}/g, (_, key) => values[key] || "");
20554
21038
  }
21039
+ function resolveHermesCoordinatorHome(meshId, workspace) {
21040
+ const key = `${meshId || "mesh"}
21041
+ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
21042
+ const hash = (0, import_node_crypto2.createHash)("sha256").update(key).digest("hex").slice(0, 16);
21043
+ return (0, import_node_path.join)(os17.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
21044
+ }
20555
21045
  function resolveMcpConfigPath(configPath, workspace) {
20556
21046
  const trimmed = configPath.trim();
20557
21047
  if (trimmed === "~") return os17.homedir();
@@ -21085,13 +21575,13 @@ var import_child_process8 = require("child_process");
21085
21575
  var import_child_process9 = require("child_process");
21086
21576
  var fs9 = __toESM(require("fs"));
21087
21577
  var os19 = __toESM(require("os"));
21088
- var path21 = __toESM(require("path"));
21578
+ var path22 = __toESM(require("path"));
21089
21579
  var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
21090
21580
  function getUpgradeLogPath() {
21091
21581
  const home = os19.homedir();
21092
- const dir = path21.join(home, ".adhdev");
21582
+ const dir = path22.join(home, ".adhdev");
21093
21583
  fs9.mkdirSync(dir, { recursive: true });
21094
- return path21.join(dir, "daemon-upgrade.log");
21584
+ return path22.join(dir, "daemon-upgrade.log");
21095
21585
  }
21096
21586
  function appendUpgradeLog(message) {
21097
21587
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
@@ -21102,14 +21592,14 @@ function appendUpgradeLog(message) {
21102
21592
  }
21103
21593
  }
21104
21594
  function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
21105
- const binDir = path21.dirname(nodeExecutable);
21595
+ const binDir = path22.dirname(nodeExecutable);
21106
21596
  if (platform10 === "win32") {
21107
- const npmCliPath = path21.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
21597
+ const npmCliPath = path22.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
21108
21598
  if (fs9.existsSync(npmCliPath)) {
21109
21599
  return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
21110
21600
  }
21111
21601
  for (const candidate of ["npm.exe", "npm"]) {
21112
- const candidatePath = path21.join(binDir, candidate);
21602
+ const candidatePath = path22.join(binDir, candidate);
21113
21603
  if (fs9.existsSync(candidatePath)) {
21114
21604
  return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
21115
21605
  }
@@ -21117,7 +21607,7 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
21117
21607
  return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
21118
21608
  }
21119
21609
  for (const candidate of ["npm"]) {
21120
- const candidatePath = path21.join(binDir, candidate);
21610
+ const candidatePath = path22.join(binDir, candidate);
21121
21611
  if (fs9.existsSync(candidatePath)) {
21122
21612
  return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
21123
21613
  }
@@ -21134,13 +21624,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
21134
21624
  let currentDir = resolvedPath;
21135
21625
  try {
21136
21626
  if (fs9.statSync(resolvedPath).isFile()) {
21137
- currentDir = path21.dirname(resolvedPath);
21627
+ currentDir = path22.dirname(resolvedPath);
21138
21628
  }
21139
21629
  } catch {
21140
- currentDir = path21.dirname(resolvedPath);
21630
+ currentDir = path22.dirname(resolvedPath);
21141
21631
  }
21142
21632
  while (true) {
21143
- const packageJsonPath = path21.join(currentDir, "package.json");
21633
+ const packageJsonPath = path22.join(currentDir, "package.json");
21144
21634
  try {
21145
21635
  if (fs9.existsSync(packageJsonPath)) {
21146
21636
  const parsed = JSON.parse(fs9.readFileSync(packageJsonPath, "utf8"));
@@ -21151,7 +21641,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
21151
21641
  }
21152
21642
  } catch {
21153
21643
  }
21154
- const parentDir = path21.dirname(currentDir);
21644
+ const parentDir = path22.dirname(currentDir);
21155
21645
  if (parentDir === currentDir) {
21156
21646
  return null;
21157
21647
  }
@@ -21159,13 +21649,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
21159
21649
  }
21160
21650
  }
21161
21651
  function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
21162
- const nodeModulesDir = packageName.startsWith("@") ? path21.dirname(path21.dirname(packageRoot)) : path21.dirname(packageRoot);
21163
- if (path21.basename(nodeModulesDir) !== "node_modules") {
21652
+ const nodeModulesDir = packageName.startsWith("@") ? path22.dirname(path22.dirname(packageRoot)) : path22.dirname(packageRoot);
21653
+ if (path22.basename(nodeModulesDir) !== "node_modules") {
21164
21654
  return null;
21165
21655
  }
21166
- const maybeLibDir = path21.dirname(nodeModulesDir);
21167
- if (path21.basename(maybeLibDir) === "lib") {
21168
- return path21.dirname(maybeLibDir);
21656
+ const maybeLibDir = path22.dirname(nodeModulesDir);
21657
+ if (path22.basename(maybeLibDir) === "lib") {
21658
+ return path22.dirname(maybeLibDir);
21169
21659
  }
21170
21660
  return maybeLibDir;
21171
21661
  }
@@ -21280,7 +21770,7 @@ async function waitForPidExit(pid, timeoutMs) {
21280
21770
  }
21281
21771
  }
21282
21772
  function stopSessionHostProcesses(appName) {
21283
- const pidFile = path21.join(os19.homedir(), ".adhdev", `${appName}-session-host.pid`);
21773
+ const pidFile = path22.join(os19.homedir(), ".adhdev", `${appName}-session-host.pid`);
21284
21774
  try {
21285
21775
  if (fs9.existsSync(pidFile)) {
21286
21776
  const pid = Number.parseInt(fs9.readFileSync(pidFile, "utf8").trim(), 10);
@@ -21297,7 +21787,7 @@ function stopSessionHostProcesses(appName) {
21297
21787
  }
21298
21788
  }
21299
21789
  function removeDaemonPidFile() {
21300
- const pidFile = path21.join(os19.homedir(), ".adhdev", "daemon.pid");
21790
+ const pidFile = path22.join(os19.homedir(), ".adhdev", "daemon.pid");
21301
21791
  try {
21302
21792
  fs9.unlinkSync(pidFile);
21303
21793
  } catch {
@@ -21308,7 +21798,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
21308
21798
  const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
21309
21799
  if (!npmRoot) return;
21310
21800
  const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
21311
- const binDir = process.platform === "win32" ? npmPrefix : path21.join(npmPrefix, "bin");
21801
+ const binDir = process.platform === "win32" ? npmPrefix : path22.join(npmPrefix, "bin");
21312
21802
  const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
21313
21803
  const binNames = /* @__PURE__ */ new Set([packageBaseName]);
21314
21804
  if (pkgName === "@adhdev/daemon-standalone") {
@@ -21316,25 +21806,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
21316
21806
  }
21317
21807
  if (pkgName.startsWith("@")) {
21318
21808
  const [scope, name] = pkgName.split("/");
21319
- const scopeDir = path21.join(npmRoot, scope);
21809
+ const scopeDir = path22.join(npmRoot, scope);
21320
21810
  if (!fs9.existsSync(scopeDir)) return;
21321
21811
  for (const entry of fs9.readdirSync(scopeDir)) {
21322
21812
  if (!entry.startsWith(`.${name}-`)) continue;
21323
- fs9.rmSync(path21.join(scopeDir, entry), { recursive: true, force: true });
21324
- appendUpgradeLog(`Removed stale scoped staging dir: ${path21.join(scopeDir, entry)}`);
21813
+ fs9.rmSync(path22.join(scopeDir, entry), { recursive: true, force: true });
21814
+ appendUpgradeLog(`Removed stale scoped staging dir: ${path22.join(scopeDir, entry)}`);
21325
21815
  }
21326
21816
  } else {
21327
21817
  for (const entry of fs9.readdirSync(npmRoot)) {
21328
21818
  if (!entry.startsWith(`.${pkgName}-`)) continue;
21329
- fs9.rmSync(path21.join(npmRoot, entry), { recursive: true, force: true });
21330
- appendUpgradeLog(`Removed stale staging dir: ${path21.join(npmRoot, entry)}`);
21819
+ fs9.rmSync(path22.join(npmRoot, entry), { recursive: true, force: true });
21820
+ appendUpgradeLog(`Removed stale staging dir: ${path22.join(npmRoot, entry)}`);
21331
21821
  }
21332
21822
  }
21333
21823
  if (fs9.existsSync(binDir)) {
21334
21824
  for (const entry of fs9.readdirSync(binDir)) {
21335
21825
  if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
21336
- fs9.rmSync(path21.join(binDir, entry), { recursive: true, force: true });
21337
- appendUpgradeLog(`Removed stale bin staging entry: ${path21.join(binDir, entry)}`);
21826
+ fs9.rmSync(path22.join(binDir, entry), { recursive: true, force: true });
21827
+ appendUpgradeLog(`Removed stale bin staging entry: ${path22.join(binDir, entry)}`);
21338
21828
  }
21339
21829
  }
21340
21830
  }
@@ -22706,7 +23196,7 @@ var DaemonCommandRouter = class {
22706
23196
  workspace
22707
23197
  };
22708
23198
  }
22709
- const { existsSync: existsSync23, readFileSync: readFileSync15, writeFileSync: writeFileSync13, copyFileSync: copyFileSync3, mkdirSync: mkdirSync15 } = await import("fs");
23199
+ const { existsSync: existsSync23, readFileSync: readFileSync15, writeFileSync: writeFileSync14, copyFileSync: copyFileSync3, mkdirSync: mkdirSync16 } = await import("fs");
22710
23200
  const { dirname: dirname9 } = await import("path");
22711
23201
  const mcpConfigPath = coordinatorSetup.configPath;
22712
23202
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
@@ -22730,7 +23220,7 @@ var DaemonCommandRouter = class {
22730
23220
  };
22731
23221
  }
22732
23222
  try {
22733
- mkdirSync15(dirname9(mcpConfigPath), { recursive: true });
23223
+ mkdirSync16(dirname9(mcpConfigPath), { recursive: true });
22734
23224
  } catch (error) {
22735
23225
  const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
22736
23226
  LOG.error("MeshCoordinator", message);
@@ -22762,7 +23252,7 @@ var DaemonCommandRouter = class {
22762
23252
  }
22763
23253
  };
22764
23254
  try {
22765
- writeFileSync13(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
23255
+ writeFileSync14(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
22766
23256
  } catch (error) {
22767
23257
  const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
22768
23258
  LOG.error("MeshCoordinator", message);
@@ -22772,6 +23262,10 @@ var DaemonCommandRouter = class {
22772
23262
  LOG.info("MeshCoordinator", `Wrote ${mcpConfigPath} with ${coordinatorSetup.serverName} server`);
22773
23263
  const cliArgs = [];
22774
23264
  const launchEnv = {};
23265
+ if (configFormat === "hermes_config_yaml") {
23266
+ launchEnv.HERMES_HOME = dirname9(mcpConfigPath);
23267
+ launchEnv.HERMES_IGNORE_USER_CONFIG = "";
23268
+ }
22775
23269
  if (systemPrompt) {
22776
23270
  if (configFormat === "hermes_config_yaml") {
22777
23271
  launchEnv.HERMES_EPHEMERAL_SYSTEM_PROMPT = systemPrompt;
@@ -23193,7 +23687,8 @@ function prepareSessionChatTailUpdate(input) {
23193
23687
  update: null
23194
23688
  };
23195
23689
  }
23196
- const messages = Array.isArray(result.messages) ? result.messages : [];
23690
+ const fullMessages = normalizeChatMessages(Array.isArray(result.messages) ? result.messages : []);
23691
+ const messages = filterUserFacingChatMessages(fullMessages);
23197
23692
  const title = typeof result.title === "string" ? result.title : void 0;
23198
23693
  const activeModal = normalizeChatTailActiveModal(result.activeModal);
23199
23694
  const status = typeof result.status === "string" ? result.status : "idle";
@@ -24467,11 +24962,11 @@ var ProviderInstanceManager = class {
24467
24962
 
24468
24963
  // src/providers/version-archive.ts
24469
24964
  var fs11 = __toESM(require("fs"));
24470
- var path22 = __toESM(require("path"));
24965
+ var path23 = __toESM(require("path"));
24471
24966
  var os20 = __toESM(require("os"));
24472
24967
  var import_child_process10 = require("child_process");
24473
24968
  var import_os3 = require("os");
24474
- var ARCHIVE_PATH = path22.join(os20.homedir(), ".adhdev", "version-history.json");
24969
+ var ARCHIVE_PATH = path23.join(os20.homedir(), ".adhdev", "version-history.json");
24475
24970
  var MAX_ENTRIES_PER_PROVIDER = 20;
24476
24971
  var VersionArchive = class {
24477
24972
  history = {};
@@ -24518,7 +25013,7 @@ var VersionArchive = class {
24518
25013
  }
24519
25014
  save() {
24520
25015
  try {
24521
- fs11.mkdirSync(path22.dirname(ARCHIVE_PATH), { recursive: true });
25016
+ fs11.mkdirSync(path23.dirname(ARCHIVE_PATH), { recursive: true });
24522
25017
  fs11.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
24523
25018
  } catch {
24524
25019
  }
@@ -24575,7 +25070,7 @@ function checkPathExists2(paths) {
24575
25070
  for (const p of paths) {
24576
25071
  if (p.includes("*")) {
24577
25072
  const home = os20.homedir();
24578
- const resolved = p.replace(/\*/g, home.split(path22.sep).pop() || "");
25073
+ const resolved = p.replace(/\*/g, home.split(path23.sep).pop() || "");
24579
25074
  if (fs11.existsSync(resolved)) return resolved;
24580
25075
  } else {
24581
25076
  if (fs11.existsSync(p)) return p;
@@ -24585,7 +25080,7 @@ function checkPathExists2(paths) {
24585
25080
  }
24586
25081
  function getMacAppVersion(appPath) {
24587
25082
  if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
24588
- const plistPath = path22.join(appPath, "Contents", "Info.plist");
25083
+ const plistPath = path23.join(appPath, "Contents", "Info.plist");
24589
25084
  if (!fs11.existsSync(plistPath)) return null;
24590
25085
  const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
24591
25086
  return raw || null;
@@ -24611,7 +25106,7 @@ async function detectAllVersions(loader, archive) {
24611
25106
  const cliBin = provider.cli ? findBinary2(provider.cli) : null;
24612
25107
  let resolvedBin = cliBin;
24613
25108
  if (!resolvedBin && appPath && currentOs === "darwin") {
24614
- const bundled = path22.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
25109
+ const bundled = path23.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
24615
25110
  if (provider.cli && fs11.existsSync(bundled)) resolvedBin = bundled;
24616
25111
  }
24617
25112
  info.installed = !!(appPath || resolvedBin);
@@ -24652,7 +25147,7 @@ async function detectAllVersions(loader, archive) {
24652
25147
  // src/daemon/dev-server.ts
24653
25148
  var http2 = __toESM(require("http"));
24654
25149
  var fs15 = __toESM(require("fs"));
24655
- var path26 = __toESM(require("path"));
25150
+ var path27 = __toESM(require("path"));
24656
25151
  init_config();
24657
25152
 
24658
25153
  // src/daemon/scaffold-template.ts
@@ -25003,7 +25498,7 @@ init_logger();
25003
25498
 
25004
25499
  // src/daemon/dev-cdp-handlers.ts
25005
25500
  var fs12 = __toESM(require("fs"));
25006
- var path23 = __toESM(require("path"));
25501
+ var path24 = __toESM(require("path"));
25007
25502
  init_logger();
25008
25503
  async function handleCdpEvaluate(ctx, req, res) {
25009
25504
  const body = await ctx.readBody(req);
@@ -25182,17 +25677,17 @@ async function handleScriptHints(ctx, type, _req, res) {
25182
25677
  return;
25183
25678
  }
25184
25679
  let scriptsPath = "";
25185
- const directScripts = path23.join(dir, "scripts.js");
25680
+ const directScripts = path24.join(dir, "scripts.js");
25186
25681
  if (fs12.existsSync(directScripts)) {
25187
25682
  scriptsPath = directScripts;
25188
25683
  } else {
25189
- const scriptsDir = path23.join(dir, "scripts");
25684
+ const scriptsDir = path24.join(dir, "scripts");
25190
25685
  if (fs12.existsSync(scriptsDir)) {
25191
25686
  const versions = fs12.readdirSync(scriptsDir).filter((d) => {
25192
- return fs12.statSync(path23.join(scriptsDir, d)).isDirectory();
25687
+ return fs12.statSync(path24.join(scriptsDir, d)).isDirectory();
25193
25688
  }).sort().reverse();
25194
25689
  for (const ver of versions) {
25195
- const p = path23.join(scriptsDir, ver, "scripts.js");
25690
+ const p = path24.join(scriptsDir, ver, "scripts.js");
25196
25691
  if (fs12.existsSync(p)) {
25197
25692
  scriptsPath = p;
25198
25693
  break;
@@ -26021,7 +26516,7 @@ async function handleDomContext(ctx, type, req, res) {
26021
26516
 
26022
26517
  // src/daemon/dev-cli-debug.ts
26023
26518
  var fs13 = __toESM(require("fs"));
26024
- var path24 = __toESM(require("path"));
26519
+ var path25 = __toESM(require("path"));
26025
26520
  function slugifyFixtureName(value) {
26026
26521
  const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
26027
26522
  return normalized || `fixture-${Date.now()}`;
@@ -26031,11 +26526,11 @@ function getCliFixtureDir(ctx, type) {
26031
26526
  if (!providerDir) {
26032
26527
  throw new Error(`Provider directory not found for '${type}'`);
26033
26528
  }
26034
- return path24.join(providerDir, "fixtures");
26529
+ return path25.join(providerDir, "fixtures");
26035
26530
  }
26036
26531
  function readCliFixture(ctx, type, name) {
26037
26532
  const fixtureDir = getCliFixtureDir(ctx, type);
26038
- const filePath = path24.join(fixtureDir, `${name}.json`);
26533
+ const filePath = path25.join(fixtureDir, `${name}.json`);
26039
26534
  if (!fs13.existsSync(filePath)) {
26040
26535
  throw new Error(`Fixture not found: ${filePath}`);
26041
26536
  }
@@ -26802,7 +27297,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
26802
27297
  },
26803
27298
  notes: typeof body?.notes === "string" ? body.notes : void 0
26804
27299
  };
26805
- const filePath = path24.join(fixtureDir, `${name}.json`);
27300
+ const filePath = path25.join(fixtureDir, `${name}.json`);
26806
27301
  fs13.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
26807
27302
  ctx.json(res, 200, {
26808
27303
  saved: true,
@@ -26826,7 +27321,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
26826
27321
  return;
26827
27322
  }
26828
27323
  const fixtures = fs13.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
26829
- const fullPath = path24.join(fixtureDir, file);
27324
+ const fullPath = path25.join(fixtureDir, file);
26830
27325
  try {
26831
27326
  const raw = JSON.parse(fs13.readFileSync(fullPath, "utf-8"));
26832
27327
  return {
@@ -26962,7 +27457,7 @@ async function handleCliRaw(ctx, req, res) {
26962
27457
 
26963
27458
  // src/daemon/dev-auto-implement.ts
26964
27459
  var fs14 = __toESM(require("fs"));
26965
- var path25 = __toESM(require("path"));
27460
+ var path26 = __toESM(require("path"));
26966
27461
  var os21 = __toESM(require("os"));
26967
27462
  function getAutoImplPid(ctx) {
26968
27463
  const pid = ctx.autoImplProcess?.pid;
@@ -27012,22 +27507,22 @@ function getLatestScriptVersionDir(scriptsDir) {
27012
27507
  if (!fs14.existsSync(scriptsDir)) return null;
27013
27508
  const versions = fs14.readdirSync(scriptsDir).filter((d) => {
27014
27509
  try {
27015
- return fs14.statSync(path25.join(scriptsDir, d)).isDirectory();
27510
+ return fs14.statSync(path26.join(scriptsDir, d)).isDirectory();
27016
27511
  } catch {
27017
27512
  return false;
27018
27513
  }
27019
27514
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
27020
27515
  if (versions.length === 0) return null;
27021
- return path25.join(scriptsDir, versions[0]);
27516
+ return path26.join(scriptsDir, versions[0]);
27022
27517
  }
27023
27518
  function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
27024
- const canonicalUserDir = path25.resolve(ctx.providerLoader.getUserProviderDir(category, type));
27025
- const desiredDir = requestedDir ? path25.resolve(requestedDir) : canonicalUserDir;
27026
- const upstreamRoot = path25.resolve(ctx.providerLoader.getUpstreamDir());
27027
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path25.sep}`)) {
27519
+ const canonicalUserDir = path26.resolve(ctx.providerLoader.getUserProviderDir(category, type));
27520
+ const desiredDir = requestedDir ? path26.resolve(requestedDir) : canonicalUserDir;
27521
+ const upstreamRoot = path26.resolve(ctx.providerLoader.getUpstreamDir());
27522
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path26.sep}`)) {
27028
27523
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
27029
27524
  }
27030
- if (path25.basename(desiredDir) !== type) {
27525
+ if (path26.basename(desiredDir) !== type) {
27031
27526
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
27032
27527
  }
27033
27528
  const sourceDir = ctx.findProviderDir(type);
@@ -27035,11 +27530,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
27035
27530
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
27036
27531
  }
27037
27532
  if (!fs14.existsSync(desiredDir)) {
27038
- fs14.mkdirSync(path25.dirname(desiredDir), { recursive: true });
27533
+ fs14.mkdirSync(path26.dirname(desiredDir), { recursive: true });
27039
27534
  fs14.cpSync(sourceDir, desiredDir, { recursive: true });
27040
27535
  ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
27041
27536
  }
27042
- const providerJson = path25.join(desiredDir, "provider.json");
27537
+ const providerJson = path26.join(desiredDir, "provider.json");
27043
27538
  if (!fs14.existsSync(providerJson)) {
27044
27539
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
27045
27540
  }
@@ -27050,13 +27545,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
27050
27545
  const refDir = ctx.findProviderDir(referenceType);
27051
27546
  if (!refDir || !fs14.existsSync(refDir)) return {};
27052
27547
  const referenceScripts = {};
27053
- const scriptsDir = path25.join(refDir, "scripts");
27548
+ const scriptsDir = path26.join(refDir, "scripts");
27054
27549
  const latestDir = getLatestScriptVersionDir(scriptsDir);
27055
27550
  if (!latestDir) return referenceScripts;
27056
27551
  for (const file of fs14.readdirSync(latestDir)) {
27057
27552
  if (!file.endsWith(".js")) continue;
27058
27553
  try {
27059
- referenceScripts[file] = fs14.readFileSync(path25.join(latestDir, file), "utf-8");
27554
+ referenceScripts[file] = fs14.readFileSync(path26.join(latestDir, file), "utf-8");
27060
27555
  } catch {
27061
27556
  }
27062
27557
  }
@@ -27164,9 +27659,9 @@ async function handleAutoImplement(ctx, type, req, res) {
27164
27659
  });
27165
27660
  const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
27166
27661
  const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
27167
- const tmpDir = path25.join(os21.tmpdir(), "adhdev-autoimpl");
27662
+ const tmpDir = path26.join(os21.tmpdir(), "adhdev-autoimpl");
27168
27663
  if (!fs14.existsSync(tmpDir)) fs14.mkdirSync(tmpDir, { recursive: true });
27169
- const promptFile = path25.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
27664
+ const promptFile = path26.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
27170
27665
  fs14.writeFileSync(promptFile, prompt, "utf-8");
27171
27666
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
27172
27667
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
@@ -27598,7 +28093,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
27598
28093
  setMode: "set_mode.js"
27599
28094
  };
27600
28095
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
27601
- const scriptsDir = path25.join(providerDir, "scripts");
28096
+ const scriptsDir = path26.join(providerDir, "scripts");
27602
28097
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
27603
28098
  if (latestScriptsDir) {
27604
28099
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -27609,7 +28104,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
27609
28104
  for (const file of fs14.readdirSync(latestScriptsDir)) {
27610
28105
  if (file.endsWith(".js") && targetFileNames.has(file)) {
27611
28106
  try {
27612
- const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
28107
+ const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
27613
28108
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
27614
28109
  lines.push("```javascript");
27615
28110
  lines.push(content);
@@ -27626,7 +28121,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
27626
28121
  lines.push("");
27627
28122
  for (const file of refFiles) {
27628
28123
  try {
27629
- const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
28124
+ const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
27630
28125
  lines.push(`### \`${file}\` \u{1F512}`);
27631
28126
  lines.push("```javascript");
27632
28127
  lines.push(content);
@@ -27667,10 +28162,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
27667
28162
  lines.push("");
27668
28163
  }
27669
28164
  }
27670
- const docsDir = path25.join(providerDir, "../../docs");
28165
+ const docsDir = path26.join(providerDir, "../../docs");
27671
28166
  const loadGuide = (name) => {
27672
28167
  try {
27673
- const p = path25.join(docsDir, name);
28168
+ const p = path26.join(docsDir, name);
27674
28169
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
27675
28170
  } catch {
27676
28171
  }
@@ -27907,7 +28402,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
27907
28402
  parseApproval: "parse_approval.js"
27908
28403
  };
27909
28404
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
27910
- const scriptsDir = path25.join(providerDir, "scripts");
28405
+ const scriptsDir = path26.join(providerDir, "scripts");
27911
28406
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
27912
28407
  if (latestScriptsDir) {
27913
28408
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -27919,7 +28414,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
27919
28414
  if (!file.endsWith(".js")) continue;
27920
28415
  if (!targetFileNames.has(file)) continue;
27921
28416
  try {
27922
- const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
28417
+ const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
27923
28418
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
27924
28419
  lines.push("```javascript");
27925
28420
  lines.push(content);
@@ -27935,7 +28430,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
27935
28430
  lines.push("");
27936
28431
  for (const file of refFiles) {
27937
28432
  try {
27938
- const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
28433
+ const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
27939
28434
  lines.push(`### \`${file}\` \u{1F512}`);
27940
28435
  lines.push("```javascript");
27941
28436
  lines.push(content);
@@ -27968,10 +28463,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
27968
28463
  lines.push("");
27969
28464
  }
27970
28465
  }
27971
- const docsDir = path25.join(providerDir, "../../docs");
28466
+ const docsDir = path26.join(providerDir, "../../docs");
27972
28467
  const loadGuide = (name) => {
27973
28468
  try {
27974
- const p = path25.join(docsDir, name);
28469
+ const p = path26.join(docsDir, name);
27975
28470
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
27976
28471
  } catch {
27977
28472
  }
@@ -28418,8 +28913,8 @@ var DevServer = class _DevServer {
28418
28913
  }
28419
28914
  getEndpointList() {
28420
28915
  return this.routes.map((r) => {
28421
- const path27 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
28422
- return `${r.method.padEnd(5)} ${path27}`;
28916
+ const path28 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
28917
+ return `${r.method.padEnd(5)} ${path28}`;
28423
28918
  });
28424
28919
  }
28425
28920
  async start(port = DEV_SERVER_PORT) {
@@ -28707,12 +29202,12 @@ var DevServer = class _DevServer {
28707
29202
  // ─── DevConsole SPA ───
28708
29203
  getConsoleDistDir() {
28709
29204
  const candidates = [
28710
- path26.resolve(__dirname, "../../web-devconsole/dist"),
28711
- path26.resolve(__dirname, "../../../web-devconsole/dist"),
28712
- path26.join(process.cwd(), "packages/web-devconsole/dist")
29205
+ path27.resolve(__dirname, "../../web-devconsole/dist"),
29206
+ path27.resolve(__dirname, "../../../web-devconsole/dist"),
29207
+ path27.join(process.cwd(), "packages/web-devconsole/dist")
28713
29208
  ];
28714
29209
  for (const dir of candidates) {
28715
- if (fs15.existsSync(path26.join(dir, "index.html"))) return dir;
29210
+ if (fs15.existsSync(path27.join(dir, "index.html"))) return dir;
28716
29211
  }
28717
29212
  return null;
28718
29213
  }
@@ -28722,7 +29217,7 @@ var DevServer = class _DevServer {
28722
29217
  this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
28723
29218
  return;
28724
29219
  }
28725
- const htmlPath = path26.join(distDir, "index.html");
29220
+ const htmlPath = path27.join(distDir, "index.html");
28726
29221
  try {
28727
29222
  const html = fs15.readFileSync(htmlPath, "utf-8");
28728
29223
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
@@ -28747,15 +29242,15 @@ var DevServer = class _DevServer {
28747
29242
  this.json(res, 404, { error: "Not found" });
28748
29243
  return;
28749
29244
  }
28750
- const safePath = path26.normalize(pathname).replace(/^\.\.\//, "");
28751
- const filePath = path26.join(distDir, safePath);
29245
+ const safePath = path27.normalize(pathname).replace(/^\.\.\//, "");
29246
+ const filePath = path27.join(distDir, safePath);
28752
29247
  if (!filePath.startsWith(distDir)) {
28753
29248
  this.json(res, 403, { error: "Forbidden" });
28754
29249
  return;
28755
29250
  }
28756
29251
  try {
28757
29252
  const content = fs15.readFileSync(filePath);
28758
- const ext = path26.extname(filePath);
29253
+ const ext = path27.extname(filePath);
28759
29254
  const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
28760
29255
  res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
28761
29256
  res.end(content);
@@ -28868,9 +29363,9 @@ var DevServer = class _DevServer {
28868
29363
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
28869
29364
  if (entry.isDirectory()) {
28870
29365
  files.push({ path: rel, size: 0, type: "dir" });
28871
- scan(path26.join(d, entry.name), rel);
29366
+ scan(path27.join(d, entry.name), rel);
28872
29367
  } else {
28873
- const stat2 = fs15.statSync(path26.join(d, entry.name));
29368
+ const stat2 = fs15.statSync(path27.join(d, entry.name));
28874
29369
  files.push({ path: rel, size: stat2.size, type: "file" });
28875
29370
  }
28876
29371
  }
@@ -28893,7 +29388,7 @@ var DevServer = class _DevServer {
28893
29388
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
28894
29389
  return;
28895
29390
  }
28896
- const fullPath = path26.resolve(dir, path26.normalize(filePath));
29391
+ const fullPath = path27.resolve(dir, path27.normalize(filePath));
28897
29392
  if (!fullPath.startsWith(dir)) {
28898
29393
  this.json(res, 403, { error: "Forbidden" });
28899
29394
  return;
@@ -28918,14 +29413,14 @@ var DevServer = class _DevServer {
28918
29413
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
28919
29414
  return;
28920
29415
  }
28921
- const fullPath = path26.resolve(dir, path26.normalize(filePath));
29416
+ const fullPath = path27.resolve(dir, path27.normalize(filePath));
28922
29417
  if (!fullPath.startsWith(dir)) {
28923
29418
  this.json(res, 403, { error: "Forbidden" });
28924
29419
  return;
28925
29420
  }
28926
29421
  try {
28927
29422
  if (fs15.existsSync(fullPath)) fs15.copyFileSync(fullPath, fullPath + ".bak");
28928
- fs15.mkdirSync(path26.dirname(fullPath), { recursive: true });
29423
+ fs15.mkdirSync(path27.dirname(fullPath), { recursive: true });
28929
29424
  fs15.writeFileSync(fullPath, content, "utf-8");
28930
29425
  this.log(`File saved: ${fullPath} (${content.length} chars)`);
28931
29426
  this.providerLoader.reload();
@@ -28942,7 +29437,7 @@ var DevServer = class _DevServer {
28942
29437
  return;
28943
29438
  }
28944
29439
  for (const name of ["scripts.js", "provider.json"]) {
28945
- const p = path26.join(dir, name);
29440
+ const p = path27.join(dir, name);
28946
29441
  if (fs15.existsSync(p)) {
28947
29442
  const source = fs15.readFileSync(p, "utf-8");
28948
29443
  this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
@@ -28963,8 +29458,8 @@ var DevServer = class _DevServer {
28963
29458
  this.json(res, 404, { error: `Provider not found: ${type}` });
28964
29459
  return;
28965
29460
  }
28966
- const target = fs15.existsSync(path26.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
28967
- const targetPath = path26.join(dir, target);
29461
+ const target = fs15.existsSync(path27.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
29462
+ const targetPath = path27.join(dir, target);
28968
29463
  try {
28969
29464
  if (fs15.existsSync(targetPath)) fs15.copyFileSync(targetPath, targetPath + ".bak");
28970
29465
  fs15.writeFileSync(targetPath, source, "utf-8");
@@ -29111,7 +29606,7 @@ var DevServer = class _DevServer {
29111
29606
  }
29112
29607
  let targetDir;
29113
29608
  targetDir = this.providerLoader.getUserProviderDir(category, type);
29114
- const jsonPath = path26.join(targetDir, "provider.json");
29609
+ const jsonPath = path27.join(targetDir, "provider.json");
29115
29610
  if (fs15.existsSync(jsonPath)) {
29116
29611
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
29117
29612
  return;
@@ -29123,8 +29618,8 @@ var DevServer = class _DevServer {
29123
29618
  const createdFiles = ["provider.json"];
29124
29619
  if (result.files) {
29125
29620
  for (const [relPath, content] of Object.entries(result.files)) {
29126
- const fullPath = path26.join(targetDir, relPath);
29127
- fs15.mkdirSync(path26.dirname(fullPath), { recursive: true });
29621
+ const fullPath = path27.join(targetDir, relPath);
29622
+ fs15.mkdirSync(path27.dirname(fullPath), { recursive: true });
29128
29623
  fs15.writeFileSync(fullPath, content, "utf-8");
29129
29624
  createdFiles.push(relPath);
29130
29625
  }
@@ -29177,22 +29672,22 @@ var DevServer = class _DevServer {
29177
29672
  if (!fs15.existsSync(scriptsDir)) return null;
29178
29673
  const versions = fs15.readdirSync(scriptsDir).filter((d) => {
29179
29674
  try {
29180
- return fs15.statSync(path26.join(scriptsDir, d)).isDirectory();
29675
+ return fs15.statSync(path27.join(scriptsDir, d)).isDirectory();
29181
29676
  } catch {
29182
29677
  return false;
29183
29678
  }
29184
29679
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
29185
29680
  if (versions.length === 0) return null;
29186
- return path26.join(scriptsDir, versions[0]);
29681
+ return path27.join(scriptsDir, versions[0]);
29187
29682
  }
29188
29683
  resolveAutoImplWritableProviderDir(category, type, requestedDir) {
29189
- const canonicalUserDir = path26.resolve(this.providerLoader.getUserProviderDir(category, type));
29190
- const desiredDir = requestedDir ? path26.resolve(requestedDir) : canonicalUserDir;
29191
- const upstreamRoot = path26.resolve(this.providerLoader.getUpstreamDir());
29192
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path26.sep}`)) {
29684
+ const canonicalUserDir = path27.resolve(this.providerLoader.getUserProviderDir(category, type));
29685
+ const desiredDir = requestedDir ? path27.resolve(requestedDir) : canonicalUserDir;
29686
+ const upstreamRoot = path27.resolve(this.providerLoader.getUpstreamDir());
29687
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path27.sep}`)) {
29193
29688
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
29194
29689
  }
29195
- if (path26.basename(desiredDir) !== type) {
29690
+ if (path27.basename(desiredDir) !== type) {
29196
29691
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
29197
29692
  }
29198
29693
  const sourceDir = this.findProviderDir(type);
@@ -29200,11 +29695,11 @@ var DevServer = class _DevServer {
29200
29695
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
29201
29696
  }
29202
29697
  if (!fs15.existsSync(desiredDir)) {
29203
- fs15.mkdirSync(path26.dirname(desiredDir), { recursive: true });
29698
+ fs15.mkdirSync(path27.dirname(desiredDir), { recursive: true });
29204
29699
  fs15.cpSync(sourceDir, desiredDir, { recursive: true });
29205
29700
  this.log(`Auto-implement writable copy created: ${desiredDir}`);
29206
29701
  }
29207
- const providerJson = path26.join(desiredDir, "provider.json");
29702
+ const providerJson = path27.join(desiredDir, "provider.json");
29208
29703
  if (!fs15.existsSync(providerJson)) {
29209
29704
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
29210
29705
  }
@@ -29240,7 +29735,7 @@ var DevServer = class _DevServer {
29240
29735
  setMode: "set_mode.js"
29241
29736
  };
29242
29737
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
29243
- const scriptsDir = path26.join(providerDir, "scripts");
29738
+ const scriptsDir = path27.join(providerDir, "scripts");
29244
29739
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
29245
29740
  if (latestScriptsDir) {
29246
29741
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -29251,7 +29746,7 @@ var DevServer = class _DevServer {
29251
29746
  for (const file of fs15.readdirSync(latestScriptsDir)) {
29252
29747
  if (file.endsWith(".js") && targetFileNames.has(file)) {
29253
29748
  try {
29254
- const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
29749
+ const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
29255
29750
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
29256
29751
  lines.push("```javascript");
29257
29752
  lines.push(content);
@@ -29268,7 +29763,7 @@ var DevServer = class _DevServer {
29268
29763
  lines.push("");
29269
29764
  for (const file of refFiles) {
29270
29765
  try {
29271
- const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
29766
+ const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
29272
29767
  lines.push(`### \`${file}\` \u{1F512}`);
29273
29768
  lines.push("```javascript");
29274
29769
  lines.push(content);
@@ -29309,10 +29804,10 @@ var DevServer = class _DevServer {
29309
29804
  lines.push("");
29310
29805
  }
29311
29806
  }
29312
- const docsDir = path26.join(providerDir, "../../docs");
29807
+ const docsDir = path27.join(providerDir, "../../docs");
29313
29808
  const loadGuide = (name) => {
29314
29809
  try {
29315
- const p = path26.join(docsDir, name);
29810
+ const p = path27.join(docsDir, name);
29316
29811
  if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
29317
29812
  } catch {
29318
29813
  }
@@ -29486,7 +29981,7 @@ var DevServer = class _DevServer {
29486
29981
  parseApproval: "parse_approval.js"
29487
29982
  };
29488
29983
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
29489
- const scriptsDir = path26.join(providerDir, "scripts");
29984
+ const scriptsDir = path27.join(providerDir, "scripts");
29490
29985
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
29491
29986
  if (latestScriptsDir) {
29492
29987
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -29498,7 +29993,7 @@ var DevServer = class _DevServer {
29498
29993
  if (!file.endsWith(".js")) continue;
29499
29994
  if (!targetFileNames.has(file)) continue;
29500
29995
  try {
29501
- const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
29996
+ const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
29502
29997
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
29503
29998
  lines.push("```javascript");
29504
29999
  lines.push(content);
@@ -29514,7 +30009,7 @@ var DevServer = class _DevServer {
29514
30009
  lines.push("");
29515
30010
  for (const file of refFiles) {
29516
30011
  try {
29517
- const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
30012
+ const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
29518
30013
  lines.push(`### \`${file}\` \u{1F512}`);
29519
30014
  lines.push("```javascript");
29520
30015
  lines.push(content);
@@ -29547,10 +30042,10 @@ var DevServer = class _DevServer {
29547
30042
  lines.push("");
29548
30043
  }
29549
30044
  }
29550
- const docsDir = path26.join(providerDir, "../../docs");
30045
+ const docsDir = path27.join(providerDir, "../../docs");
29551
30046
  const loadGuide = (name) => {
29552
30047
  try {
29553
- const p = path26.join(docsDir, name);
30048
+ const p = path27.join(docsDir, name);
29554
30049
  if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
29555
30050
  } catch {
29556
30051
  }
@@ -30811,6 +31306,12 @@ async function shutdownDaemonComponents(components) {
30811
31306
  AcpProviderInstance,
30812
31307
  AgentStreamPoller,
30813
31308
  BUILTIN_CHAT_MESSAGE_KINDS,
31309
+ CHAT_MESSAGE_ACTIVITY_SOURCES,
31310
+ CHAT_MESSAGE_AUDIENCES,
31311
+ CHAT_MESSAGE_INTERNAL_SOURCES,
31312
+ CHAT_MESSAGE_SOURCES,
31313
+ CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES,
31314
+ CHAT_MESSAGE_VISIBILITIES,
30814
31315
  CdpDomHandlers,
30815
31316
  CliProviderInstance,
30816
31317
  DAEMON_WS_PATH,
@@ -30873,6 +31374,7 @@ async function shutdownDaemonComponents(components) {
30873
31374
  buildThoughtChatMessage,
30874
31375
  buildToolChatMessage,
30875
31376
  buildUserChatMessage,
31377
+ classifyChatMessageVisibility,
30876
31378
  classifyHotChatSessionsForSubscriptionFlush,
30877
31379
  clearDebugTrace,
30878
31380
  compareGitSnapshots,
@@ -30892,6 +31394,9 @@ async function shutdownDaemonComponents(components) {
30892
31394
  detectIDEs,
30893
31395
  ensureSessionHostReady,
30894
31396
  execNpmCommandSync,
31397
+ filterActivityChatMessages,
31398
+ filterChatMessagesByVisibility,
31399
+ filterInternalChatMessages,
30895
31400
  filterUserFacingChatMessages,
30896
31401
  findCdpManager,
30897
31402
  flattenMessageParts,
@@ -30923,11 +31428,13 @@ async function shutdownDaemonComponents(components) {
30923
31428
  initDaemonComponents,
30924
31429
  installExtensions,
30925
31430
  installGlobalInterceptor,
31431
+ isActivityChatMessage,
30926
31432
  isBuiltinChatMessageKind,
30927
31433
  isCdpConnected,
30928
31434
  isExtensionInstalled,
30929
31435
  isGitCommandName,
30930
31436
  isIdeRunning,
31437
+ isInternalChatMessage,
30931
31438
  isManagedStatusWaiting,
30932
31439
  isManagedStatusWorking,
30933
31440
  isPathInside,