adhdev 0.8.52 → 0.8.54

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.
Files changed (29) hide show
  1. package/dist/cli/index.js +2086 -849
  2. package/dist/cli/index.js.map +1 -1
  3. package/dist/index.js +1362 -609
  4. package/dist/index.js.map +1 -1
  5. package/package.json +1 -1
  6. package/vendor/session-host-daemon/index.d.mts +3 -0
  7. package/vendor/session-host-daemon/index.d.ts +3 -0
  8. package/vendor/session-host-daemon/index.js +33 -2
  9. package/vendor/session-host-daemon/index.js.map +1 -1
  10. package/vendor/session-host-daemon/index.mjs +34 -2
  11. package/vendor/session-host-daemon/index.mjs.map +1 -1
  12. package/vendor/session-host-daemon/node_modules/@adhdev/session-host-core/index.d.mts +16 -1
  13. package/vendor/session-host-daemon/node_modules/@adhdev/session-host-core/index.d.ts +16 -1
  14. package/vendor/session-host-daemon/node_modules/@adhdev/session-host-core/index.js +59 -0
  15. package/vendor/session-host-daemon/node_modules/@adhdev/session-host-core/index.js.map +1 -1
  16. package/vendor/session-host-daemon/node_modules/@adhdev/session-host-core/index.mjs +54 -0
  17. package/vendor/session-host-daemon/node_modules/@adhdev/session-host-core/index.mjs.map +1 -1
  18. package/vendor/terminal-mux-cli/index.js +24 -10
  19. package/vendor/terminal-mux-cli/index.mjs +24 -10
  20. package/vendor/terminal-mux-cli/node_modules/@adhdev/session-host-core/index.d.mts +16 -1
  21. package/vendor/terminal-mux-cli/node_modules/@adhdev/session-host-core/index.d.ts +16 -1
  22. package/vendor/terminal-mux-cli/node_modules/@adhdev/session-host-core/index.js +59 -0
  23. package/vendor/terminal-mux-cli/node_modules/@adhdev/session-host-core/index.js.map +1 -1
  24. package/vendor/terminal-mux-cli/node_modules/@adhdev/session-host-core/index.mjs +54 -0
  25. package/vendor/terminal-mux-cli/node_modules/@adhdev/session-host-core/index.mjs.map +1 -1
  26. package/vendor/terminal-mux-cli/node_modules/@adhdev/terminal-mux-core/index.d.mts +3 -1
  27. package/vendor/terminal-mux-cli/node_modules/@adhdev/terminal-mux-core/index.d.ts +3 -1
  28. package/vendor/terminal-mux-cli/node_modules/@adhdev/terminal-mux-core/index.js +13 -5
  29. package/vendor/terminal-mux-cli/node_modules/@adhdev/terminal-mux-core/index.mjs +10 -1
package/dist/index.js CHANGED
@@ -649,17 +649,17 @@ function checkPathExists(paths) {
649
649
  return null;
650
650
  }
651
651
  async function detectIDEs(providerLoader) {
652
- const os24 = (0, import_os2.platform)();
652
+ const os25 = (0, import_os2.platform)();
653
653
  const results = [];
654
654
  for (const def of getMergedDefinitions()) {
655
655
  const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
656
- const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os24] || []) || []);
656
+ const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os25] || []) || []);
657
657
  let resolvedCli = cliPath;
658
- if (!resolvedCli && appPath && os24 === "darwin") {
658
+ if (!resolvedCli && appPath && os25 === "darwin") {
659
659
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
660
660
  if ((0, import_fs3.existsSync)(bundledCli)) resolvedCli = bundledCli;
661
661
  }
662
- if (!resolvedCli && appPath && os24 === "win32") {
662
+ if (!resolvedCli && appPath && os25 === "win32") {
663
663
  const { dirname: dirname9 } = await import("path");
664
664
  const appDir = dirname9(appPath);
665
665
  const candidates = [
@@ -676,7 +676,7 @@ async function detectIDEs(providerLoader) {
676
676
  }
677
677
  }
678
678
  }
679
- const installed = os24 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
679
+ const installed = os25 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
680
680
  const version2 = resolvedCli ? getIdeVersion(resolvedCli) : null;
681
681
  results.push({
682
682
  id: def.id,
@@ -2599,6 +2599,61 @@ function normalizeProviderEffects(data) {
2599
2599
  }
2600
2600
  return effects;
2601
2601
  }
2602
+ function normalizeControlListResult(data) {
2603
+ if (data && typeof data === "object" && Array.isArray(data.options)) {
2604
+ return {
2605
+ options: normalizeControlOptions(data.options),
2606
+ ...isScalarControlValue(data.currentValue) ? { currentValue: data.currentValue } : {},
2607
+ ...typeof data.error === "string" ? { error: data.error } : {}
2608
+ };
2609
+ }
2610
+ const rawOptions = Array.isArray(data?.models) ? data.models : Array.isArray(data?.modes) ? data.modes : Array.isArray(data?.options) ? data.options : [];
2611
+ const options = normalizeControlOptions(rawOptions);
2612
+ return {
2613
+ options,
2614
+ ...isScalarControlValue(data?.current) ? { currentValue: data.current } : {},
2615
+ ...isScalarControlValue(data?.currentValue) ? { currentValue: data.currentValue } : {},
2616
+ ...typeof data?.error === "string" ? { error: data.error } : {}
2617
+ };
2618
+ }
2619
+ function normalizeControlSetResult(data) {
2620
+ const currentValue = isScalarControlValue(data?.currentValue) ? data.currentValue : isScalarControlValue(data?.value) ? data.value : void 0;
2621
+ return {
2622
+ ok: data?.ok === true || data?.success === true,
2623
+ ...currentValue !== void 0 ? { currentValue } : {},
2624
+ ...Array.isArray(data?.effects) ? { effects: normalizeProviderEffects(data) } : {},
2625
+ ...typeof data?.error === "string" ? { error: data.error } : {}
2626
+ };
2627
+ }
2628
+ function normalizeControlInvokeResult(data) {
2629
+ const currentValue = isScalarControlValue(data?.currentValue) ? data.currentValue : isScalarControlValue(data?.value) ? data.value : void 0;
2630
+ return {
2631
+ ok: data?.ok === true || data?.success === true,
2632
+ ...currentValue !== void 0 ? { currentValue } : {},
2633
+ ...Array.isArray(data?.effects) ? { effects: normalizeProviderEffects(data) } : {},
2634
+ ...typeof data?.error === "string" ? { error: data.error } : {}
2635
+ };
2636
+ }
2637
+ function normalizeControlOptions(options) {
2638
+ return options.map((option) => normalizeControlOption(option)).filter((option) => !!option);
2639
+ }
2640
+ function normalizeControlOption(option) {
2641
+ if (typeof option === "string") {
2642
+ return { value: option, label: option };
2643
+ }
2644
+ if (!option || typeof option !== "object") return null;
2645
+ const record2 = option;
2646
+ const value = typeof record2.value === "string" ? record2.value : typeof record2.id === "string" ? record2.id : null;
2647
+ if (!value) return null;
2648
+ const label = typeof record2.label === "string" ? record2.label : typeof record2.name === "string" ? record2.name : value;
2649
+ const normalized = { value, label };
2650
+ if (typeof record2.description === "string") normalized.description = record2.description;
2651
+ if (typeof record2.group === "string") normalized.group = record2.group;
2652
+ return normalized;
2653
+ }
2654
+ function isScalarControlValue(value) {
2655
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
2656
+ }
2602
2657
  function normalizeControlValue(value) {
2603
2658
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
2604
2659
  return value;
@@ -4656,50 +4711,6 @@ function isCdpConnected(cdpManagers, key) {
4656
4711
  }
4657
4712
  return false;
4658
4713
  }
4659
- function buildFallbackControls(providerControls, serverModel, serverMode, acpConfigOptions, acpModes) {
4660
- if (providerControls && providerControls.length > 0) return providerControls;
4661
- const controls = [];
4662
- const isAcp = !!(acpConfigOptions || acpModes);
4663
- const modelFromAcp = acpConfigOptions?.find((c) => c.category === "model");
4664
- if (!isAcp || modelFromAcp) {
4665
- controls.push({
4666
- id: "model",
4667
- type: "select",
4668
- label: "Model",
4669
- icon: "\u{1F916}",
4670
- placement: "bar",
4671
- dynamic: !modelFromAcp,
4672
- listScript: "listModels",
4673
- setScript: "setModel",
4674
- readFrom: "model",
4675
- ...modelFromAcp && {
4676
- options: modelFromAcp.options.map((o) => ({ value: o.value, label: o.name || o.value }))
4677
- }
4678
- });
4679
- }
4680
- const modeFromAcp = acpModes && acpModes.length > 0;
4681
- const thoughtFromAcp = !modeFromAcp && acpConfigOptions?.find((c) => c.category !== "model");
4682
- if (!isAcp || modeFromAcp || thoughtFromAcp) {
4683
- controls.push({
4684
- id: "mode",
4685
- type: thoughtFromAcp ? "cycle" : "select",
4686
- label: thoughtFromAcp ? "Thinking" : "Mode",
4687
- icon: thoughtFromAcp ? "\u{1F9E0}" : "\u26A1",
4688
- placement: "bar",
4689
- dynamic: !modeFromAcp && !thoughtFromAcp,
4690
- listScript: "listModes",
4691
- setScript: thoughtFromAcp ? "setThinkingLevel" : "setMode",
4692
- readFrom: "mode",
4693
- ...modeFromAcp && {
4694
- options: acpModes.map((m) => ({ value: m.id, label: m.name || m.id }))
4695
- },
4696
- ...thoughtFromAcp && {
4697
- options: thoughtFromAcp.options.map((o) => ({ value: o.value, label: o.name || o.value }))
4698
- }
4699
- });
4700
- }
4701
- return controls;
4702
- }
4703
4714
  function buildIdeWorkspaceSession(state, cdpManagers, options) {
4704
4715
  const profile = options.profile || "full";
4705
4716
  const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
@@ -4726,11 +4737,7 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
4726
4737
  currentAutoApprove: state.currentAutoApprove,
4727
4738
  ...includeSessionControls && {
4728
4739
  controlValues: state.controlValues,
4729
- providerControls: buildFallbackControls(
4730
- state.providerControls,
4731
- state.currentModel,
4732
- state.currentPlan
4733
- )
4740
+ providerControls: state.providerControls
4734
4741
  },
4735
4742
  errorMessage: state.errorMessage,
4736
4743
  errorReason: state.errorReason,
@@ -4760,11 +4767,7 @@ function buildExtensionAgentSession(parent, ext, options) {
4760
4767
  currentPlan: ext.currentPlan,
4761
4768
  ...includeSessionControls && {
4762
4769
  controlValues: ext.controlValues,
4763
- providerControls: buildFallbackControls(
4764
- ext.providerControls,
4765
- ext.currentModel,
4766
- ext.currentPlan
4767
- )
4770
+ providerControls: ext.providerControls
4768
4771
  },
4769
4772
  errorMessage: ext.errorMessage,
4770
4773
  errorReason: ext.errorReason,
@@ -4805,9 +4808,7 @@ function buildCliSession(state, options) {
4805
4808
  },
4806
4809
  ...includeSessionControls && {
4807
4810
  controlValues: state.controlValues,
4808
- providerControls: buildFallbackControls(
4809
- state.providerControls
4810
- )
4811
+ providerControls: state.providerControls
4811
4812
  },
4812
4813
  errorMessage: state.errorMessage,
4813
4814
  errorReason: state.errorReason,
@@ -4839,13 +4840,7 @@ function buildAcpSession(state, options) {
4839
4840
  acpConfigOptions: state.acpConfigOptions,
4840
4841
  acpModes: state.acpModes,
4841
4842
  controlValues: state.controlValues,
4842
- providerControls: buildFallbackControls(
4843
- state.providerControls,
4844
- state.currentModel,
4845
- state.currentPlan,
4846
- state.acpConfigOptions,
4847
- state.acpModes
4848
- )
4843
+ providerControls: state.providerControls
4849
4844
  },
4850
4845
  errorMessage: state.errorMessage,
4851
4846
  errorReason: state.errorReason,
@@ -4979,14 +4974,228 @@ var init_reconcile = __esm({
4979
4974
  }
4980
4975
  });
4981
4976
 
4977
+ // ../../oss/packages/daemon-core/src/providers/io-contracts.ts
4978
+ function normalizeInputEnvelope(input) {
4979
+ const normalized = normalizeInputEnvelopePayload(input);
4980
+ const textFallback = normalized.textFallback ?? flattenInputParts(normalized.parts);
4981
+ return {
4982
+ parts: normalized.parts,
4983
+ textFallback,
4984
+ ...normalized.metadata ? { metadata: normalized.metadata } : {}
4985
+ };
4986
+ }
4987
+ function normalizeMessageParts(content) {
4988
+ if (typeof content === "string") return [{ type: "text", text: content }];
4989
+ if (!Array.isArray(content)) {
4990
+ if (content && typeof content === "object" && typeof content.text === "string") {
4991
+ return [{ type: "text", text: String(content.text) }];
4992
+ }
4993
+ return [];
4994
+ }
4995
+ const parts = [];
4996
+ for (const raw of content) {
4997
+ if (typeof raw === "string") {
4998
+ parts.push({ type: "text", text: raw });
4999
+ continue;
5000
+ }
5001
+ if (!raw || typeof raw !== "object") continue;
5002
+ const part = normalizeMessagePartObject(raw);
5003
+ if (part) parts.push(part);
5004
+ }
5005
+ return parts;
5006
+ }
5007
+ function flattenMessageParts(parts) {
5008
+ return parts.map((part) => {
5009
+ if (part.type === "text") return part.text;
5010
+ if (part.type === "resource") return part.resource.text || "";
5011
+ return "";
5012
+ }).filter((value) => value.length > 0).join("\n");
5013
+ }
5014
+ function normalizeInputEnvelopePayload(input) {
5015
+ if (typeof input === "string") {
5016
+ return { parts: [{ type: "text", text: input }], textFallback: input };
5017
+ }
5018
+ if (!input || typeof input !== "object") {
5019
+ return { parts: [], textFallback: "" };
5020
+ }
5021
+ const record2 = input;
5022
+ const nestedInput = record2.input;
5023
+ if (nestedInput && typeof nestedInput === "object") {
5024
+ const nested = nestedInput;
5025
+ return {
5026
+ parts: normalizeInputParts(nested.parts ?? nested.prompt),
5027
+ textFallback: typeof nested.textFallback === "string" ? nested.textFallback : void 0,
5028
+ metadata: normalizeInputMetadata(nested.metadata)
5029
+ };
5030
+ }
5031
+ const directText = typeof record2.text === "string" ? record2.text : typeof record2.message === "string" ? record2.message : void 0;
5032
+ if (directText !== void 0) {
5033
+ return { parts: [{ type: "text", text: directText }], textFallback: directText };
5034
+ }
5035
+ const directParts = normalizeInputParts(record2.parts ?? record2.prompt);
5036
+ return {
5037
+ parts: directParts,
5038
+ textFallback: typeof record2.textFallback === "string" ? record2.textFallback : void 0,
5039
+ metadata: normalizeInputMetadata(record2.metadata)
5040
+ };
5041
+ }
5042
+ function normalizeInputMetadata(value) {
5043
+ if (!value || typeof value !== "object") return void 0;
5044
+ const record2 = value;
5045
+ const metadata = {};
5046
+ if (record2.source === "dashboard" || record2.source === "shortcut_api" || record2.source === "provider_script" || record2.source === "session_replay") {
5047
+ metadata.source = record2.source;
5048
+ }
5049
+ if (typeof record2.clientTimestamp === "number" && Number.isFinite(record2.clientTimestamp)) {
5050
+ metadata.clientTimestamp = record2.clientTimestamp;
5051
+ }
5052
+ return Object.keys(metadata).length > 0 ? metadata : void 0;
5053
+ }
5054
+ function normalizeInputParts(value) {
5055
+ if (!Array.isArray(value)) return [];
5056
+ const parts = [];
5057
+ for (const raw of value) {
5058
+ if (typeof raw === "string") {
5059
+ parts.push({ type: "text", text: raw });
5060
+ continue;
5061
+ }
5062
+ if (!raw || typeof raw !== "object") continue;
5063
+ const part = normalizeInputPartObject(raw);
5064
+ if (part) parts.push(part);
5065
+ }
5066
+ return parts;
5067
+ }
5068
+ function normalizeInputPartObject(raw) {
5069
+ const type = raw.type;
5070
+ if (type === "text" && typeof raw.text === "string") {
5071
+ return { type, text: raw.text };
5072
+ }
5073
+ if (type === "image" && typeof raw.mimeType === "string") {
5074
+ return {
5075
+ type,
5076
+ mimeType: raw.mimeType,
5077
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
5078
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
5079
+ ...typeof raw.alt === "string" ? { alt: raw.alt } : {}
5080
+ };
5081
+ }
5082
+ if (type === "audio" && typeof raw.mimeType === "string") {
5083
+ return {
5084
+ type,
5085
+ mimeType: raw.mimeType,
5086
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
5087
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
5088
+ ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
5089
+ };
5090
+ }
5091
+ if (type === "video" && typeof raw.mimeType === "string") {
5092
+ return {
5093
+ type,
5094
+ mimeType: raw.mimeType,
5095
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
5096
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
5097
+ ...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
5098
+ };
5099
+ }
5100
+ if (type === "resource" && typeof raw.uri === "string") {
5101
+ return {
5102
+ type,
5103
+ uri: raw.uri,
5104
+ ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
5105
+ ...typeof raw.name === "string" ? { name: raw.name } : {},
5106
+ ...typeof raw.text === "string" ? { text: raw.text } : {},
5107
+ ...typeof raw.data === "string" ? { data: raw.data } : {}
5108
+ };
5109
+ }
5110
+ if (type === "resource_link" && typeof raw.uri === "string") {
5111
+ return {
5112
+ type: "resource",
5113
+ uri: raw.uri,
5114
+ ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
5115
+ ...typeof raw.name === "string" ? { name: raw.name } : {}
5116
+ };
5117
+ }
5118
+ return null;
5119
+ }
5120
+ function normalizeMessagePartObject(raw) {
5121
+ const type = raw.type;
5122
+ if (type === "text" && typeof raw.text === "string") {
5123
+ return { type, text: raw.text };
5124
+ }
5125
+ if (type === "image" && typeof raw.mimeType === "string") {
5126
+ return {
5127
+ type,
5128
+ mimeType: raw.mimeType,
5129
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
5130
+ ...typeof raw.data === "string" ? { data: raw.data } : {}
5131
+ };
5132
+ }
5133
+ if (type === "audio" && typeof raw.mimeType === "string") {
5134
+ return {
5135
+ type,
5136
+ mimeType: raw.mimeType,
5137
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
5138
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
5139
+ ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
5140
+ };
5141
+ }
5142
+ if (type === "video" && typeof raw.mimeType === "string") {
5143
+ return {
5144
+ type,
5145
+ mimeType: raw.mimeType,
5146
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
5147
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
5148
+ ...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
5149
+ };
5150
+ }
5151
+ if (type === "resource_link" && typeof raw.uri === "string" && typeof raw.name === "string") {
5152
+ return {
5153
+ type,
5154
+ uri: raw.uri,
5155
+ name: raw.name,
5156
+ ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
5157
+ ...typeof raw.size === "number" ? { size: raw.size } : {}
5158
+ };
5159
+ }
5160
+ if (type === "resource" && raw.resource && typeof raw.resource === "object") {
5161
+ const resource = raw.resource;
5162
+ if (typeof resource.uri !== "string") return null;
5163
+ return {
5164
+ type,
5165
+ resource: {
5166
+ uri: resource.uri,
5167
+ ...typeof resource.mimeType === "string" || resource.mimeType === null ? { mimeType: resource.mimeType } : {},
5168
+ ...typeof resource.text === "string" ? { text: resource.text } : {},
5169
+ ...typeof resource.blob === "string" ? { blob: resource.blob } : {}
5170
+ }
5171
+ };
5172
+ }
5173
+ return null;
5174
+ }
5175
+ function flattenInputParts(parts) {
5176
+ return parts.map((part) => {
5177
+ if (part.type === "text") return part.text;
5178
+ if (part.type === "audio") return part.transcript || "";
5179
+ if (part.type === "resource") return part.text || "";
5180
+ return "";
5181
+ }).filter((value) => value.length > 0).join("\n");
5182
+ }
5183
+ var init_io_contracts = __esm({
5184
+ "../../oss/packages/daemon-core/src/providers/io-contracts.ts"() {
5185
+ "use strict";
5186
+ }
5187
+ });
5188
+
4982
5189
  // ../../oss/packages/daemon-core/src/providers/contracts.ts
4983
5190
  function flattenContent(content) {
4984
5191
  if (typeof content === "string") return content;
4985
- return content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
5192
+ return flattenMessageParts(normalizeMessageParts(content));
4986
5193
  }
4987
5194
  var init_contracts = __esm({
4988
5195
  "../../oss/packages/daemon-core/src/providers/contracts.ts"() {
4989
5196
  "use strict";
5197
+ init_io_contracts();
5198
+ init_io_contracts();
4990
5199
  }
4991
5200
  });
4992
5201
 
@@ -5184,6 +5393,9 @@ function buildRecentSendKey(h, args, provider, text) {
5184
5393
  const target = args?.targetSessionId || args?.agentType || h.currentSession?.providerType || h.currentProviderType || h.currentManagerKey || "unknown";
5185
5394
  return `${transport}:${target}:${text.trim()}`;
5186
5395
  }
5396
+ function getSendChatInputEnvelope(args) {
5397
+ return normalizeInputEnvelope(args?.input ? { input: args.input } : args);
5398
+ }
5187
5399
  function getHistorySessionId(h, args) {
5188
5400
  const explicit = typeof args?.historySessionId === "string" ? args.historySessionId.trim() : "";
5189
5401
  if (explicit) return explicit;
@@ -5588,7 +5800,8 @@ async function handleReadChat(h, args) {
5588
5800
  return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
5589
5801
  }
5590
5802
  async function handleSendChat(h, args) {
5591
- const text = args?.text || args?.message;
5803
+ const input = getSendChatInputEnvelope(args);
5804
+ const text = input.textFallback;
5592
5805
  if (!text) return { success: false, error: "text required" };
5593
5806
  const _log = (msg) => LOG.debug("Command", `[send_chat] ${msg}`);
5594
5807
  const provider = h.getProvider(args?.agentType);
@@ -6502,6 +6715,21 @@ function listDirectoryEntriesSafe(dirPath) {
6502
6715
  }
6503
6716
  return files;
6504
6717
  }
6718
+ function listWindowsDriveEntries(excludePath) {
6719
+ const excluded = typeof excludePath === "string" ? excludePath.toLowerCase() : "";
6720
+ const drives = [];
6721
+ for (let code = 65; code <= 90; code += 1) {
6722
+ const letter = String.fromCharCode(code);
6723
+ const root = `${letter}:\\`;
6724
+ try {
6725
+ if (!fs4.existsSync(root)) continue;
6726
+ if (excluded && root.toLowerCase() === excluded) continue;
6727
+ drives.push({ name: `${letter}:`, type: "directory", path: root });
6728
+ } catch {
6729
+ }
6730
+ }
6731
+ return drives;
6732
+ }
6505
6733
  async function handleFileRead(h, args) {
6506
6734
  try {
6507
6735
  const filePath = resolveSafePath(args?.path);
@@ -6534,6 +6762,14 @@ async function handleFileListBrowse(h, args) {
6534
6762
  try {
6535
6763
  const dirPath = resolveSafePath(args?.path || ".");
6536
6764
  const files = listDirectoryEntriesSafe(dirPath).filter((entry) => entry.type === "directory").sort((a, b) => a.name.localeCompare(b.name));
6765
+ if (process.platform === "win32" && /^[A-Za-z]:\\?$/.test(dirPath)) {
6766
+ const driveEntries = listWindowsDriveEntries(dirPath);
6767
+ return {
6768
+ success: true,
6769
+ files: [...driveEntries, ...files],
6770
+ path: dirPath
6771
+ };
6772
+ }
6537
6773
  return { success: true, files, path: dirPath };
6538
6774
  } catch (e) {
6539
6775
  return { success: false, error: e.message };
@@ -6584,6 +6820,42 @@ var init_cdp_commands = __esm({
6584
6820
  }
6585
6821
  });
6586
6822
 
6823
+ // ../../oss/packages/daemon-core/src/providers/cli-script-results.ts
6824
+ function parseCliScriptResult(result) {
6825
+ if (typeof result === "string") {
6826
+ try {
6827
+ const parsed = JSON.parse(result);
6828
+ if (parsed && typeof parsed === "object" && parsed.success === false) {
6829
+ return { success: false, payload: parsed };
6830
+ }
6831
+ return { success: true, payload: parsed };
6832
+ } catch {
6833
+ return { success: true, payload: { result } };
6834
+ }
6835
+ }
6836
+ if (result && typeof result === "object" && "success" in result && result.success === false) {
6837
+ return { success: false, payload: result };
6838
+ }
6839
+ return { success: true, payload: result };
6840
+ }
6841
+ function getCliScriptCommand(payload) {
6842
+ if (!payload || typeof payload !== "object") return null;
6843
+ if (typeof payload.sendMessage === "string" && payload.sendMessage.trim()) {
6844
+ return { type: "send_message", text: payload.sendMessage.trim() };
6845
+ }
6846
+ const command = payload.command;
6847
+ if (!command || typeof command !== "object") return null;
6848
+ if (command.type !== "send_message" && command.type !== "pty_write") return null;
6849
+ const text = typeof command.text === "string" ? command.text.trim() : typeof command.message === "string" ? command.message.trim() : "";
6850
+ if (!text) return null;
6851
+ return { type: command.type, text };
6852
+ }
6853
+ var init_cli_script_results = __esm({
6854
+ "../../oss/packages/daemon-core/src/providers/cli-script-results.ts"() {
6855
+ "use strict";
6856
+ }
6857
+ });
6858
+
6587
6859
  // ../../oss/packages/daemon-core/src/commands/stream-commands.ts
6588
6860
  function getCliPresentationMode(h, targetSessionId) {
6589
6861
  if (!targetSessionId) return null;
@@ -6673,34 +6945,19 @@ function normalizeProviderScriptArgs(args) {
6673
6945
  }
6674
6946
  return normalizedArgs;
6675
6947
  }
6676
- function parseScriptResult(result) {
6677
- if (typeof result === "string") {
6678
- try {
6679
- const parsed = JSON.parse(result);
6680
- if (parsed && typeof parsed === "object" && parsed.success === false) {
6681
- return { success: false, payload: parsed };
6682
- }
6683
- return { success: true, payload: parsed };
6684
- } catch {
6685
- return { success: true, payload: { result } };
6686
- }
6948
+ function buildControlScriptResult(scriptName, payload) {
6949
+ if (!payload || typeof payload !== "object") return {};
6950
+ if (Array.isArray(payload.options) || Array.isArray(payload.models) || Array.isArray(payload.modes)) {
6951
+ return { controlResult: normalizeControlListResult(payload) };
6687
6952
  }
6688
- if (result && typeof result === "object" && "success" in result && result.success === false) {
6689
- return { success: false, payload: result };
6953
+ const looksLikeValueMutation = /^set|^change/i.test(scriptName) || payload.currentValue !== void 0 || payload.value !== void 0;
6954
+ if (looksLikeValueMutation) {
6955
+ return { controlResult: normalizeControlSetResult(payload) };
6690
6956
  }
6691
- return { success: true, payload: result };
6692
- }
6693
- function getCliScriptCommand(payload) {
6694
- if (!payload || typeof payload !== "object") return null;
6695
- if (typeof payload.sendMessage === "string" && payload.sendMessage.trim()) {
6696
- return { type: "send_message", text: payload.sendMessage.trim() };
6957
+ if (payload.ok !== void 0 || payload.success !== void 0 || Array.isArray(payload.effects)) {
6958
+ return { controlResult: normalizeControlInvokeResult(payload) };
6697
6959
  }
6698
- const command = payload.command;
6699
- if (!command || typeof command !== "object") return null;
6700
- if (command.type !== "send_message" && command.type !== "pty_write") return null;
6701
- const text = typeof command.text === "string" ? command.text.trim() : typeof command.message === "string" ? command.message.trim() : "";
6702
- if (!text) return null;
6703
- return { type: command.type, text };
6960
+ return {};
6704
6961
  }
6705
6962
  function applyProviderPatch(h, args, payload) {
6706
6963
  if (!payload || typeof payload !== "object") return;
@@ -6734,7 +6991,7 @@ async function executeProviderScript(h, args, scriptName) {
6734
6991
  }
6735
6992
  try {
6736
6993
  const raw = await adapter.invokeScript(actualScriptName, normalizedArgs);
6737
- const parsed = parseScriptResult(raw);
6994
+ const parsed = parseCliScriptResult(raw);
6738
6995
  if (!parsed.success) {
6739
6996
  return { success: false, ...parsed.payload || {} };
6740
6997
  }
@@ -6745,7 +7002,11 @@ async function executeProviderScript(h, args, scriptName) {
6745
7002
  adapter.writeRaw(cliCommand.text + "\r");
6746
7003
  }
6747
7004
  applyProviderPatch(h, args, parsed.payload);
6748
- return { success: true, ...parsed.payload && typeof parsed.payload === "object" ? parsed.payload : { result: parsed.payload } };
7005
+ return {
7006
+ success: true,
7007
+ ...parsed.payload && typeof parsed.payload === "object" ? parsed.payload : { result: parsed.payload },
7008
+ ...buildControlScriptResult(scriptName, parsed.payload)
7009
+ };
6749
7010
  } catch (e) {
6750
7011
  return { success: false, error: `Script execution failed: ${e.message}` };
6751
7012
  }
@@ -6808,7 +7069,7 @@ async function executeProviderScript(h, args, scriptName) {
6808
7069
  if (parsed && typeof parsed === "object" && parsed.success === false) {
6809
7070
  return { success: false, ...parsed };
6810
7071
  }
6811
- return { success: true, ...parsed };
7072
+ return { success: true, ...parsed, ...buildControlScriptResult(scriptName, parsed) };
6812
7073
  } catch {
6813
7074
  return { success: true, result };
6814
7075
  }
@@ -6819,9 +7080,6 @@ async function executeProviderScript(h, args, scriptName) {
6819
7080
  return { success: false, error: `Script execution failed: ${e.message}` };
6820
7081
  }
6821
7082
  }
6822
- async function handleExtensionScript(h, args, scriptName) {
6823
- return executeProviderScript(h, args, scriptName);
6824
- }
6825
7083
  async function handleProviderScript(h, args) {
6826
7084
  const scriptName = typeof args?.scriptName === "string" ? args.scriptName.trim() : "";
6827
7085
  if (!scriptName) return { success: false, error: "scriptName is required" };
@@ -6871,6 +7129,8 @@ function handleSetIdeExtension(h, args) {
6871
7129
  var init_stream_commands = __esm({
6872
7130
  "../../oss/packages/daemon-core/src/commands/stream-commands.ts"() {
6873
7131
  "use strict";
7132
+ init_cli_script_results();
7133
+ init_control_effects();
6874
7134
  init_logger();
6875
7135
  }
6876
7136
  });
@@ -7289,11 +7549,7 @@ var init_handler = __esm({
7289
7549
  "focus_session",
7290
7550
  "pty_input",
7291
7551
  "pty_resize",
7292
- "invoke_provider_script",
7293
- "list_extension_models",
7294
- "set_extension_model",
7295
- "list_extension_modes",
7296
- "set_extension_mode"
7552
+ "invoke_provider_script"
7297
7553
  ]);
7298
7554
  if (this._currentRoute.sessionLookupFailed && sessionScopedCommands.has(cmd)) {
7299
7555
  const result2 = {
@@ -7405,17 +7661,9 @@ var init_handler = __esm({
7405
7661
  return handleGetIdeExtensions(this, args);
7406
7662
  case "set_ide_extension":
7407
7663
  return handleSetIdeExtension(this, args);
7408
- // ─── Extension Model / Mode Control (stream-commands.ts) ──────────
7664
+ // ─── Provider control execution (stream-commands.ts) ──────────
7409
7665
  case "invoke_provider_script":
7410
7666
  return handleProviderScript(this, args);
7411
- case "list_extension_models":
7412
- return handleExtensionScript(this, args, "listModels");
7413
- case "set_extension_model":
7414
- return handleExtensionScript(this, args, "setModel");
7415
- case "list_extension_modes":
7416
- return handleExtensionScript(this, args, "listModes");
7417
- case "set_extension_mode":
7418
- return handleExtensionScript(this, args, "setMode");
7419
7667
  // ─── Provider Auto-Fix / Clone (DevServer proxy) ──────────
7420
7668
  case "provider_auto_fix":
7421
7669
  return this.proxyDevServerPost(args, "auto-implement");
@@ -7860,14 +8108,14 @@ function applyTerminalColorEnv(env) {
7860
8108
  function ensureNodePtySpawnHelperPermissions(logFn) {
7861
8109
  if (os22.platform() === "win32") return;
7862
8110
  try {
7863
- const fs18 = __require("fs");
8111
+ const fs19 = __require("fs");
7864
8112
  const ptyDir = path32.resolve(path32.dirname(__require.resolve("node-pty")), "..");
7865
8113
  const platformArch = `${os22.platform()}-${os22.arch()}`;
7866
8114
  const helper = path32.join(ptyDir, "prebuilds", platformArch, "spawn-helper");
7867
- if (fs18.existsSync(helper)) {
7868
- const stat4 = fs18.statSync(helper);
8115
+ if (fs19.existsSync(helper)) {
8116
+ const stat4 = fs19.statSync(helper);
7869
8117
  if (!(stat4.mode & 73)) {
7870
- fs18.chmodSync(helper, stat4.mode | 493);
8118
+ fs19.chmodSync(helper, stat4.mode | 493);
7871
8119
  logFn?.(`Fixed spawn-helper permissions: ${helper}`);
7872
8120
  }
7873
8121
  }
@@ -8059,8 +8307,8 @@ var init_pty_transport = __esm({
8059
8307
  let cwd = options.cwd;
8060
8308
  if (cwd) {
8061
8309
  try {
8062
- const fs18 = require("fs");
8063
- const stat4 = fs18.statSync(cwd);
8310
+ const fs19 = require("fs");
8311
+ const stat4 = fs19.statSync(cwd);
8064
8312
  if (!stat4.isDirectory()) cwd = os8.homedir();
8065
8313
  } catch {
8066
8314
  cwd = os8.homedir();
@@ -8158,12 +8406,12 @@ function findBinary(name) {
8158
8406
  function isScriptBinary(binaryPath) {
8159
8407
  if (!path9.isAbsolute(binaryPath)) return false;
8160
8408
  try {
8161
- const fs18 = require("fs");
8162
- const resolved = fs18.realpathSync(binaryPath);
8409
+ const fs19 = require("fs");
8410
+ const resolved = fs19.realpathSync(binaryPath);
8163
8411
  const head = Buffer.alloc(8);
8164
- const fd = fs18.openSync(resolved, "r");
8165
- fs18.readSync(fd, head, 0, 8, 0);
8166
- fs18.closeSync(fd);
8412
+ const fd = fs19.openSync(resolved, "r");
8413
+ fs19.readSync(fd, head, 0, 8, 0);
8414
+ fs19.closeSync(fd);
8167
8415
  let i = 0;
8168
8416
  if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
8169
8417
  return head[i] === 35 && head[i + 1] === 33;
@@ -8174,12 +8422,12 @@ function isScriptBinary(binaryPath) {
8174
8422
  function looksLikeMachOOrElf(filePath) {
8175
8423
  if (!path9.isAbsolute(filePath)) return false;
8176
8424
  try {
8177
- const fs18 = require("fs");
8178
- const resolved = fs18.realpathSync(filePath);
8425
+ const fs19 = require("fs");
8426
+ const resolved = fs19.realpathSync(filePath);
8179
8427
  const buf = Buffer.alloc(8);
8180
- const fd = fs18.openSync(resolved, "r");
8181
- fs18.readSync(fd, buf, 0, 8, 0);
8182
- fs18.closeSync(fd);
8428
+ const fd = fs19.openSync(resolved, "r");
8429
+ fs19.readSync(fd, buf, 0, 8, 0);
8430
+ fs19.closeSync(fd);
8183
8431
  let i = 0;
8184
8432
  if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
8185
8433
  const b = buf.subarray(i);
@@ -10293,6 +10541,23 @@ function getDatabaseSync() {
10293
10541
  }
10294
10542
  return CachedDatabaseSync;
10295
10543
  }
10544
+ function getForcedNewSessionScriptName(provider, launchMode) {
10545
+ if (!provider || launchMode !== "new") return null;
10546
+ const resume = provider.resume;
10547
+ if (!resume?.supported) return null;
10548
+ if (Array.isArray(resume.newSessionArgs) && resume.newSessionArgs.length > 0) return null;
10549
+ const controls = Array.isArray(provider.controls) ? provider.controls : [];
10550
+ for (const control of controls) {
10551
+ if (control?.type !== "action") continue;
10552
+ const invokeScript = typeof control?.invokeScript === "string" ? control.invokeScript.trim() : "";
10553
+ if (!invokeScript) continue;
10554
+ const controlId = typeof control?.id === "string" ? control.id.trim() : "";
10555
+ if (controlId === "new_session" || /^new.?session$/i.test(invokeScript)) {
10556
+ return invokeScript;
10557
+ }
10558
+ }
10559
+ return null;
10560
+ }
10296
10561
  var os12, path11, crypto3, fs5, import_node_module, CachedDatabaseSync, CliProviderInstance;
10297
10562
  var init_cli_provider_instance = __esm({
10298
10563
  "../../oss/packages/daemon-core/src/providers/cli-provider-instance.ts"() {
@@ -10302,12 +10567,14 @@ var init_cli_provider_instance = __esm({
10302
10567
  crypto3 = __toESM(require("crypto"));
10303
10568
  fs5 = __toESM(require("fs"));
10304
10569
  import_node_module = require("module");
10570
+ init_contracts();
10305
10571
  init_provider_cli_adapter();
10306
10572
  init_status_monitor();
10307
10573
  init_chat_history();
10308
10574
  init_logger();
10309
10575
  init_control_effects();
10310
10576
  init_approval_utils();
10577
+ init_cli_script_results();
10311
10578
  CachedDatabaseSync = null;
10312
10579
  CliProviderInstance = class {
10313
10580
  constructor(provider, workingDir, cliArgs = [], instanceId, transportFactory, options) {
@@ -10367,6 +10634,7 @@ var init_cli_provider_instance = __esm({
10367
10634
  this.detectStatusTransition();
10368
10635
  });
10369
10636
  await this.adapter.spawn();
10637
+ await this.enforceFreshSessionLaunchIfNeeded();
10370
10638
  this.maybeAppendRuntimeRecoveryMessage(this.adapter.getRuntimeMetadata());
10371
10639
  if (this.providerSessionId) {
10372
10640
  this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
@@ -10558,10 +10826,13 @@ var init_cli_provider_instance = __esm({
10558
10826
  });
10559
10827
  }
10560
10828
  onEvent(event, data) {
10561
- if (event === "send_message" && data?.text) {
10562
- void this.adapter.sendMessage(data.text).catch((e) => {
10563
- LOG.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
10564
- });
10829
+ if (event === "send_message") {
10830
+ const input = normalizeInputEnvelope(data);
10831
+ if (input.textFallback) {
10832
+ void this.adapter.sendMessage(input.textFallback).catch((e) => {
10833
+ LOG.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
10834
+ });
10835
+ }
10565
10836
  } else if (event === "server_connected" && data?.serverConn) {
10566
10837
  this.adapter.setServerConn(data.serverConn);
10567
10838
  } else if (event === "resolve_action" && data) {
@@ -10579,6 +10850,23 @@ var init_cli_provider_instance = __esm({
10579
10850
  }
10580
10851
  completedDebounceTimer = null;
10581
10852
  completedDebouncePending = null;
10853
+ async enforceFreshSessionLaunchIfNeeded() {
10854
+ const scriptName = getForcedNewSessionScriptName(this.provider, this.launchMode);
10855
+ if (!scriptName) return;
10856
+ LOG.info("CLI", `[${this.type}] forcing fresh session launch via script: ${scriptName}`);
10857
+ const raw = await this.adapter.invokeScript(scriptName, {});
10858
+ const parsed = parseCliScriptResult(raw);
10859
+ if (!parsed.success) {
10860
+ throw new Error(parsed.payload?.error || `Failed to invoke fresh-session script '${scriptName}'`);
10861
+ }
10862
+ const cliCommand = getCliScriptCommand(parsed.payload);
10863
+ if (cliCommand?.type === "send_message" && cliCommand.text) {
10864
+ await this.adapter.sendMessage(cliCommand.text);
10865
+ } else if (cliCommand?.type === "pty_write" && cliCommand.text) {
10866
+ this.adapter.writeRaw(cliCommand.text + "\r");
10867
+ }
10868
+ this.applyProviderResponse(parsed.payload, { phase: "immediate" });
10869
+ }
10582
10870
  detectStatusTransition() {
10583
10871
  const now = Date.now();
10584
10872
  const adapterStatus = this.adapter.getStatus();
@@ -11216,10 +11504,10 @@ function mergeDefs(...defs) {
11216
11504
  function cloneDef(schema) {
11217
11505
  return mergeDefs(schema._zod.def);
11218
11506
  }
11219
- function getElementAtPath(obj, path26) {
11220
- if (!path26)
11507
+ function getElementAtPath(obj, path28) {
11508
+ if (!path28)
11221
11509
  return obj;
11222
- return path26.reduce((acc, key) => acc?.[key], obj);
11510
+ return path28.reduce((acc, key) => acc?.[key], obj);
11223
11511
  }
11224
11512
  function promiseAllObject(promisesObj) {
11225
11513
  const keys = Object.keys(promisesObj);
@@ -11531,11 +11819,11 @@ function aborted(x, startIndex = 0) {
11531
11819
  }
11532
11820
  return false;
11533
11821
  }
11534
- function prefixIssues(path26, issues) {
11822
+ function prefixIssues(path28, issues) {
11535
11823
  return issues.map((iss) => {
11536
11824
  var _a2;
11537
11825
  (_a2 = iss).path ?? (_a2.path = []);
11538
- iss.path.unshift(path26);
11826
+ iss.path.unshift(path28);
11539
11827
  return iss;
11540
11828
  });
11541
11829
  }
@@ -11778,7 +12066,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
11778
12066
  }
11779
12067
  function treeifyError(error48, mapper = (issue2) => issue2.message) {
11780
12068
  const result = { errors: [] };
11781
- const processError = (error49, path26 = []) => {
12069
+ const processError = (error49, path28 = []) => {
11782
12070
  var _a2, _b;
11783
12071
  for (const issue2 of error49.issues) {
11784
12072
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -11788,7 +12076,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
11788
12076
  } else if (issue2.code === "invalid_element") {
11789
12077
  processError({ issues: issue2.issues }, issue2.path);
11790
12078
  } else {
11791
- const fullpath = [...path26, ...issue2.path];
12079
+ const fullpath = [...path28, ...issue2.path];
11792
12080
  if (fullpath.length === 0) {
11793
12081
  result.errors.push(mapper(issue2));
11794
12082
  continue;
@@ -11820,8 +12108,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
11820
12108
  }
11821
12109
  function toDotPath(_path) {
11822
12110
  const segs = [];
11823
- const path26 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
11824
- for (const seg of path26) {
12111
+ const path28 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
12112
+ for (const seg of path28) {
11825
12113
  if (typeof seg === "number")
11826
12114
  segs.push(`[${seg}]`);
11827
12115
  else if (typeof seg === "symbol")
@@ -24585,13 +24873,13 @@ function resolveRef(ref, ctx) {
24585
24873
  if (!ref.startsWith("#")) {
24586
24874
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
24587
24875
  }
24588
- const path26 = ref.slice(1).split("/").filter(Boolean);
24589
- if (path26.length === 0) {
24876
+ const path28 = ref.slice(1).split("/").filter(Boolean);
24877
+ if (path28.length === 0) {
24590
24878
  return ctx.rootSchema;
24591
24879
  }
24592
24880
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
24593
- if (path26[0] === defsKey) {
24594
- const key = path26[1];
24881
+ if (path28[0] === defsKey) {
24882
+ const key = path28[1];
24595
24883
  if (!key || !ctx.defs[key]) {
24596
24884
  throw new Error(`Reference not found: ${ref}`);
24597
24885
  }
@@ -27265,10 +27553,106 @@ var init_acp = __esm({
27265
27553
  });
27266
27554
 
27267
27555
  // ../../oss/packages/daemon-core/src/providers/acp-provider-instance.ts
27268
- var import_stream, import_child_process5, AcpProviderInstance;
27556
+ function getPromptCapabilityFlags(agentCapabilities) {
27557
+ const prompt = agentCapabilities?.promptCapabilities || {};
27558
+ return {
27559
+ image: prompt.image === true,
27560
+ audio: prompt.audio === true,
27561
+ embeddedContext: prompt.embeddedContext === true
27562
+ };
27563
+ }
27564
+ function getResourceNameFromUri(uri, fallback) {
27565
+ try {
27566
+ if (uri.startsWith("file://")) {
27567
+ return path12.basename(new URL(uri).pathname) || fallback;
27568
+ }
27569
+ return path12.basename(uri) || fallback;
27570
+ } catch {
27571
+ return fallback;
27572
+ }
27573
+ }
27574
+ function inputPartToResourceLink(part, fallbackName) {
27575
+ if (!part.uri) return null;
27576
+ return {
27577
+ type: "resource_link",
27578
+ uri: part.uri,
27579
+ name: getResourceNameFromUri(part.uri, fallbackName),
27580
+ ...part.mimeType ? { mimeType: part.mimeType } : {}
27581
+ };
27582
+ }
27583
+ function appendPromptText(promptParts, text) {
27584
+ const normalized = typeof text === "string" ? text.trim() : "";
27585
+ if (!normalized) return;
27586
+ const last = promptParts[promptParts.length - 1];
27587
+ if (last?.type === "text" && last.text === normalized) return;
27588
+ promptParts.push({ type: "text", text: normalized });
27589
+ }
27590
+ function buildAcpPromptParts(input, agentCapabilities) {
27591
+ const caps = getPromptCapabilityFlags(agentCapabilities);
27592
+ const promptParts = [];
27593
+ for (const part of input.parts) {
27594
+ if (part.type === "text") {
27595
+ promptParts.push({ type: "text", text: part.text });
27596
+ continue;
27597
+ }
27598
+ if (part.type === "image") {
27599
+ if (caps.image && part.data) {
27600
+ promptParts.push({
27601
+ type: "image",
27602
+ data: part.data,
27603
+ mimeType: part.mimeType,
27604
+ ...part.uri ? { uri: part.uri } : {}
27605
+ });
27606
+ continue;
27607
+ }
27608
+ const fallback = inputPartToResourceLink(part, "image");
27609
+ if (fallback) promptParts.push(fallback);
27610
+ appendPromptText(promptParts, part.alt || (!part.uri ? `Attached image (${part.mimeType})` : void 0));
27611
+ continue;
27612
+ }
27613
+ if (part.type === "audio") {
27614
+ if (caps.audio && part.data) {
27615
+ promptParts.push({
27616
+ type: "audio",
27617
+ data: part.data,
27618
+ mimeType: part.mimeType
27619
+ });
27620
+ continue;
27621
+ }
27622
+ const fallback = inputPartToResourceLink(part, "audio");
27623
+ if (fallback) promptParts.push(fallback);
27624
+ appendPromptText(promptParts, part.transcript || (!part.uri ? `Attached audio (${part.mimeType})` : void 0));
27625
+ continue;
27626
+ }
27627
+ if (part.type === "resource") {
27628
+ if (caps.embeddedContext && (part.text || part.data)) {
27629
+ promptParts.push({
27630
+ type: "resource",
27631
+ resource: part.text ? { uri: part.uri, text: part.text, mimeType: part.mimeType ?? null } : { uri: part.uri, blob: part.data || "", mimeType: part.mimeType ?? null }
27632
+ });
27633
+ continue;
27634
+ }
27635
+ const fallback = inputPartToResourceLink(part, part.name || "resource");
27636
+ if (fallback) promptParts.push(fallback);
27637
+ appendPromptText(promptParts, part.text || (!part.uri && part.name ? part.name : void 0));
27638
+ continue;
27639
+ }
27640
+ if (part.type === "video") {
27641
+ const fallback = inputPartToResourceLink(part, "video");
27642
+ if (fallback) promptParts.push(fallback);
27643
+ appendPromptText(promptParts, !part.uri ? `Attached video (${part.mimeType})` : void 0);
27644
+ }
27645
+ }
27646
+ if (!promptParts.some((part) => part.type === "text") && input.textFallback) {
27647
+ promptParts.unshift({ type: "text", text: input.textFallback });
27648
+ }
27649
+ return promptParts;
27650
+ }
27651
+ var path12, import_stream, import_child_process5, AcpProviderInstance;
27269
27652
  var init_acp_provider_instance = __esm({
27270
27653
  "../../oss/packages/daemon-core/src/providers/acp-provider-instance.ts"() {
27271
27654
  "use strict";
27655
+ path12 = __toESM(require("path"));
27272
27656
  import_stream = require("stream");
27273
27657
  import_child_process5 = require("child_process");
27274
27658
  init_acp();
@@ -27403,8 +27787,10 @@ var init_acp_provider_instance = __esm({
27403
27787
  };
27404
27788
  }
27405
27789
  onEvent(event, data) {
27406
- if (event === "send_message" && data?.text) {
27407
- this.sendPrompt(data.text).catch(
27790
+ if (event === "send_message") {
27791
+ const input = normalizeInputEnvelope(data);
27792
+ const promptParts = buildAcpPromptParts(input, this.agentCapabilities);
27793
+ this.sendPrompt(input.textFallback, promptParts.length > 0 ? promptParts : void 0).catch(
27408
27794
  (e) => this.log.warn(`[${this.type}] sendPrompt error: ${e?.message}`)
27409
27795
  );
27410
27796
  } else if (event === "resolve_action") {
@@ -27829,18 +28215,34 @@ var init_acp_provider_instance = __esm({
27829
28215
  this.log.warn(`[${this.type}] Cannot send prompt: no active connection/session`);
27830
28216
  return;
27831
28217
  }
27832
- let promptParts;
27833
- if (contentBlocks && contentBlocks.length > 0) {
27834
- promptParts = contentBlocks.map((b) => {
27835
- if (b.type === "text") return { type: "text", text: b.text };
27836
- if (b.type === "image") return { type: "image", data: b.data, mimeType: b.mimeType };
27837
- if (b.type === "resource_link") return { type: "resource_link", uri: b.uri, name: b.name };
27838
- if (b.type === "resource") return { type: "resource", resource: b.resource };
27839
- return { type: "text", text: flattenContent([b]) };
27840
- });
27841
- } else {
27842
- promptParts = [{ type: "text", text }];
27843
- }
28218
+ const promptParts = contentBlocks && contentBlocks.length > 0 ? contentBlocks.map((b) => {
28219
+ if (b.type === "text") return { type: "text", text: b.text };
28220
+ if (b.type === "image") {
28221
+ return {
28222
+ type: "image",
28223
+ data: b.data,
28224
+ mimeType: b.mimeType,
28225
+ ...b.uri ? { uri: b.uri } : {}
28226
+ };
28227
+ }
28228
+ if (b.type === "audio") {
28229
+ return {
28230
+ type: "audio",
28231
+ data: b.data,
28232
+ mimeType: b.mimeType
28233
+ };
28234
+ }
28235
+ if (b.type === "resource_link") {
28236
+ return {
28237
+ type: "resource_link",
28238
+ uri: b.uri,
28239
+ name: b.name,
28240
+ ...b.mimeType ? { mimeType: b.mimeType } : {}
28241
+ };
28242
+ }
28243
+ if (b.type === "resource") return { type: "resource", resource: b.resource };
28244
+ return { type: "text", text: flattenContent([b]) };
28245
+ }) : [{ type: "text", text }];
27844
28246
  this.messages.push({
27845
28247
  role: "user",
27846
28248
  content: contentBlocks && contentBlocks.length > 0 ? contentBlocks : text,
@@ -27904,6 +28306,13 @@ var init_acp_provider_instance = __esm({
27904
28306
  this.partialBlocks.push({
27905
28307
  type: "image",
27906
28308
  data: content.data,
28309
+ mimeType: content.mimeType,
28310
+ ...content.uri ? { uri: content.uri } : {}
28311
+ });
28312
+ } else if (content.type === "audio") {
28313
+ this.partialBlocks.push({
28314
+ type: "audio",
28315
+ data: content.data,
27907
28316
  mimeType: content.mimeType
27908
28317
  });
27909
28318
  } else if (content.type === "resource_link") {
@@ -28297,7 +28706,7 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
28297
28706
  };
28298
28707
  }
28299
28708
  if (!supportsExplicitSessionStart(resume)) {
28300
- return { cliArgs: baseArgs, launchMode: "manual" };
28709
+ return { cliArgs: baseArgs, launchMode: "new" };
28301
28710
  }
28302
28711
  const providerSessionId = crypto4.randomUUID();
28303
28712
  const newSessionArgs = expandResumeArgs(resume.newSessionArgs, providerSessionId);
@@ -28307,12 +28716,12 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
28307
28716
  launchMode: "new"
28308
28717
  };
28309
28718
  }
28310
- var os13, path12, crypto4, import_chalk, chalkModule, chalkApi, DaemonCliManager;
28719
+ var os13, path13, crypto4, import_chalk, chalkModule, chalkApi, DaemonCliManager;
28311
28720
  var init_cli_manager = __esm({
28312
28721
  "../../oss/packages/daemon-core/src/commands/cli-manager.ts"() {
28313
28722
  "use strict";
28314
28723
  os13 = __toESM(require("os"));
28315
- path12 = __toESM(require("path"));
28724
+ path13 = __toESM(require("path"));
28316
28725
  crypto4 = __toESM(require("crypto"));
28317
28726
  import_chalk = __toESM(require("chalk"));
28318
28727
  init_provider_cli_adapter();
@@ -28324,6 +28733,7 @@ var init_cli_manager = __esm({
28324
28733
  init_saved_sessions();
28325
28734
  init_cli_provider_instance();
28326
28735
  init_acp_provider_instance();
28736
+ init_contracts();
28327
28737
  init_logger();
28328
28738
  init_hosted_runtime_restore();
28329
28739
  chalkModule = import_chalk.default;
@@ -28466,7 +28876,7 @@ var init_cli_manager = __esm({
28466
28876
  async startSession(cliType, workingDir, cliArgs, initialModel, options) {
28467
28877
  const trimmed = (workingDir || "").trim();
28468
28878
  if (!trimmed) throw new Error("working directory required");
28469
- const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path12.resolve(trimmed);
28879
+ const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path13.resolve(trimmed);
28470
28880
  const normalizedType = this.providerLoader.resolveAlias(cliType);
28471
28881
  const provider = this.providerLoader.getByAlias(cliType);
28472
28882
  const key = crypto4.randomUUID();
@@ -28514,7 +28924,8 @@ ${installInfo}`
28514
28924
  instanceManager2.removeInstance(key);
28515
28925
  },
28516
28926
  sendMessage: async (text) => {
28517
- acpInstance.onEvent("send_message", { text });
28927
+ const input = normalizeInputEnvelope(text);
28928
+ acpInstance.onEvent("send_message", { input });
28518
28929
  },
28519
28930
  getStatus: () => {
28520
28931
  const state = acpInstance.getState();
@@ -28923,7 +29334,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
28923
29334
  if (!found) throw new Error(`CLI agent not running: ${agentType}`);
28924
29335
  const { adapter, key } = found;
28925
29336
  if (action === "send_chat") {
28926
- const message = args.message || args.text;
29337
+ const input = normalizeInputEnvelope(args?.input ? { input: args.input } : args);
29338
+ const message = input.textFallback;
28927
29339
  if (!message) throw new Error("message required for send_chat");
28928
29340
  await adapter.sendMessage(message);
28929
29341
  return { success: true, status: "generating" };
@@ -29047,7 +29459,7 @@ var init_readdirp = __esm({
29047
29459
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
29048
29460
  const statMethod = opts.lstat ? import_promises.lstat : import_promises.stat;
29049
29461
  if (wantBigintFsStats) {
29050
- this._stat = (path26) => statMethod(path26, { bigint: true });
29462
+ this._stat = (path28) => statMethod(path28, { bigint: true });
29051
29463
  } else {
29052
29464
  this._stat = statMethod;
29053
29465
  }
@@ -29072,8 +29484,8 @@ var init_readdirp = __esm({
29072
29484
  const par = this.parent;
29073
29485
  const fil = par && par.files;
29074
29486
  if (fil && fil.length > 0) {
29075
- const { path: path26, depth } = par;
29076
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path26));
29487
+ const { path: path28, depth } = par;
29488
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path28));
29077
29489
  const awaited = await Promise.all(slice);
29078
29490
  for (const entry of awaited) {
29079
29491
  if (!entry)
@@ -29113,21 +29525,21 @@ var init_readdirp = __esm({
29113
29525
  this.reading = false;
29114
29526
  }
29115
29527
  }
29116
- async _exploreDir(path26, depth) {
29528
+ async _exploreDir(path28, depth) {
29117
29529
  let files;
29118
29530
  try {
29119
- files = await (0, import_promises.readdir)(path26, this._rdOptions);
29531
+ files = await (0, import_promises.readdir)(path28, this._rdOptions);
29120
29532
  } catch (error48) {
29121
29533
  this._onError(error48);
29122
29534
  }
29123
- return { files, depth, path: path26 };
29535
+ return { files, depth, path: path28 };
29124
29536
  }
29125
- async _formatEntry(dirent, path26) {
29537
+ async _formatEntry(dirent, path28) {
29126
29538
  let entry;
29127
- const basename7 = this._isDirent ? dirent.name : dirent;
29539
+ const basename9 = this._isDirent ? dirent.name : dirent;
29128
29540
  try {
29129
- const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path26, basename7));
29130
- entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename7 };
29541
+ const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path28, basename9));
29542
+ entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename9 };
29131
29543
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
29132
29544
  } catch (err) {
29133
29545
  this._onError(err);
@@ -29183,16 +29595,16 @@ var init_readdirp = __esm({
29183
29595
  });
29184
29596
 
29185
29597
  // ../../oss/packages/daemon-core/node_modules/chokidar/handler.js
29186
- function createFsWatchInstance(path26, options, listener, errHandler, emitRaw) {
29598
+ function createFsWatchInstance(path28, options, listener, errHandler, emitRaw) {
29187
29599
  const handleEvent = (rawEvent, evPath) => {
29188
- listener(path26);
29189
- emitRaw(rawEvent, evPath, { watchedPath: path26 });
29190
- if (evPath && path26 !== evPath) {
29191
- fsWatchBroadcast(sp.resolve(path26, evPath), KEY_LISTENERS, sp.join(path26, evPath));
29600
+ listener(path28);
29601
+ emitRaw(rawEvent, evPath, { watchedPath: path28 });
29602
+ if (evPath && path28 !== evPath) {
29603
+ fsWatchBroadcast(sp.resolve(path28, evPath), KEY_LISTENERS, sp.join(path28, evPath));
29192
29604
  }
29193
29605
  };
29194
29606
  try {
29195
- return (0, import_node_fs.watch)(path26, {
29607
+ return (0, import_node_fs.watch)(path28, {
29196
29608
  persistent: options.persistent
29197
29609
  }, handleEvent);
29198
29610
  } catch (error48) {
@@ -29541,12 +29953,12 @@ var init_handler2 = __esm({
29541
29953
  listener(val1, val2, val3);
29542
29954
  });
29543
29955
  };
29544
- setFsWatchListener = (path26, fullPath, options, handlers) => {
29956
+ setFsWatchListener = (path28, fullPath, options, handlers) => {
29545
29957
  const { listener, errHandler, rawEmitter } = handlers;
29546
29958
  let cont = FsWatchInstances.get(fullPath);
29547
29959
  let watcher;
29548
29960
  if (!options.persistent) {
29549
- watcher = createFsWatchInstance(path26, options, listener, errHandler, rawEmitter);
29961
+ watcher = createFsWatchInstance(path28, options, listener, errHandler, rawEmitter);
29550
29962
  if (!watcher)
29551
29963
  return;
29552
29964
  return watcher.close.bind(watcher);
@@ -29557,7 +29969,7 @@ var init_handler2 = __esm({
29557
29969
  addAndConvert(cont, KEY_RAW, rawEmitter);
29558
29970
  } else {
29559
29971
  watcher = createFsWatchInstance(
29560
- path26,
29972
+ path28,
29561
29973
  options,
29562
29974
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
29563
29975
  errHandler,
@@ -29572,7 +29984,7 @@ var init_handler2 = __esm({
29572
29984
  cont.watcherUnusable = true;
29573
29985
  if (isWindows && error48.code === "EPERM") {
29574
29986
  try {
29575
- const fd = await (0, import_promises2.open)(path26, "r");
29987
+ const fd = await (0, import_promises2.open)(path28, "r");
29576
29988
  await fd.close();
29577
29989
  broadcastErr(error48);
29578
29990
  } catch (err) {
@@ -29603,7 +30015,7 @@ var init_handler2 = __esm({
29603
30015
  };
29604
30016
  };
29605
30017
  FsWatchFileInstances = /* @__PURE__ */ new Map();
29606
- setFsWatchFileListener = (path26, fullPath, options, handlers) => {
30018
+ setFsWatchFileListener = (path28, fullPath, options, handlers) => {
29607
30019
  const { listener, rawEmitter } = handlers;
29608
30020
  let cont = FsWatchFileInstances.get(fullPath);
29609
30021
  const copts = cont && cont.options;
@@ -29625,7 +30037,7 @@ var init_handler2 = __esm({
29625
30037
  });
29626
30038
  const currmtime = curr.mtimeMs;
29627
30039
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
29628
- foreach(cont.listeners, (listener2) => listener2(path26, curr));
30040
+ foreach(cont.listeners, (listener2) => listener2(path28, curr));
29629
30041
  }
29630
30042
  })
29631
30043
  };
@@ -29655,13 +30067,13 @@ var init_handler2 = __esm({
29655
30067
  * @param listener on fs change
29656
30068
  * @returns closer for the watcher instance
29657
30069
  */
29658
- _watchWithNodeFs(path26, listener) {
30070
+ _watchWithNodeFs(path28, listener) {
29659
30071
  const opts = this.fsw.options;
29660
- const directory = sp.dirname(path26);
29661
- const basename7 = sp.basename(path26);
30072
+ const directory = sp.dirname(path28);
30073
+ const basename9 = sp.basename(path28);
29662
30074
  const parent = this.fsw._getWatchedDir(directory);
29663
- parent.add(basename7);
29664
- const absolutePath = sp.resolve(path26);
30075
+ parent.add(basename9);
30076
+ const absolutePath = sp.resolve(path28);
29665
30077
  const options = {
29666
30078
  persistent: opts.persistent
29667
30079
  };
@@ -29670,13 +30082,13 @@ var init_handler2 = __esm({
29670
30082
  let closer;
29671
30083
  if (opts.usePolling) {
29672
30084
  const enableBin = opts.interval !== opts.binaryInterval;
29673
- options.interval = enableBin && isBinaryPath(basename7) ? opts.binaryInterval : opts.interval;
29674
- closer = setFsWatchFileListener(path26, absolutePath, options, {
30085
+ options.interval = enableBin && isBinaryPath(basename9) ? opts.binaryInterval : opts.interval;
30086
+ closer = setFsWatchFileListener(path28, absolutePath, options, {
29675
30087
  listener,
29676
30088
  rawEmitter: this.fsw._emitRaw
29677
30089
  });
29678
30090
  } else {
29679
- closer = setFsWatchListener(path26, absolutePath, options, {
30091
+ closer = setFsWatchListener(path28, absolutePath, options, {
29680
30092
  listener,
29681
30093
  errHandler: this._boundHandleError,
29682
30094
  rawEmitter: this.fsw._emitRaw
@@ -29693,12 +30105,12 @@ var init_handler2 = __esm({
29693
30105
  return;
29694
30106
  }
29695
30107
  const dirname9 = sp.dirname(file2);
29696
- const basename7 = sp.basename(file2);
30108
+ const basename9 = sp.basename(file2);
29697
30109
  const parent = this.fsw._getWatchedDir(dirname9);
29698
30110
  let prevStats = stats;
29699
- if (parent.has(basename7))
30111
+ if (parent.has(basename9))
29700
30112
  return;
29701
- const listener = async (path26, newStats) => {
30113
+ const listener = async (path28, newStats) => {
29702
30114
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file2, 5))
29703
30115
  return;
29704
30116
  if (!newStats || newStats.mtimeMs === 0) {
@@ -29712,18 +30124,18 @@ var init_handler2 = __esm({
29712
30124
  this.fsw._emit(EV.CHANGE, file2, newStats2);
29713
30125
  }
29714
30126
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
29715
- this.fsw._closeFile(path26);
30127
+ this.fsw._closeFile(path28);
29716
30128
  prevStats = newStats2;
29717
30129
  const closer2 = this._watchWithNodeFs(file2, listener);
29718
30130
  if (closer2)
29719
- this.fsw._addPathCloser(path26, closer2);
30131
+ this.fsw._addPathCloser(path28, closer2);
29720
30132
  } else {
29721
30133
  prevStats = newStats2;
29722
30134
  }
29723
30135
  } catch (error48) {
29724
- this.fsw._remove(dirname9, basename7);
30136
+ this.fsw._remove(dirname9, basename9);
29725
30137
  }
29726
- } else if (parent.has(basename7)) {
30138
+ } else if (parent.has(basename9)) {
29727
30139
  const at = newStats.atimeMs;
29728
30140
  const mt = newStats.mtimeMs;
29729
30141
  if (!at || at <= mt || mt !== prevStats.mtimeMs) {
@@ -29748,7 +30160,7 @@ var init_handler2 = __esm({
29748
30160
  * @param item basename of this item
29749
30161
  * @returns true if no more processing is needed for this entry.
29750
30162
  */
29751
- async _handleSymlink(entry, directory, path26, item) {
30163
+ async _handleSymlink(entry, directory, path28, item) {
29752
30164
  if (this.fsw.closed) {
29753
30165
  return;
29754
30166
  }
@@ -29758,7 +30170,7 @@ var init_handler2 = __esm({
29758
30170
  this.fsw._incrReadyCount();
29759
30171
  let linkPath;
29760
30172
  try {
29761
- linkPath = await (0, import_promises2.realpath)(path26);
30173
+ linkPath = await (0, import_promises2.realpath)(path28);
29762
30174
  } catch (e) {
29763
30175
  this.fsw._emitReady();
29764
30176
  return true;
@@ -29768,12 +30180,12 @@ var init_handler2 = __esm({
29768
30180
  if (dir.has(item)) {
29769
30181
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
29770
30182
  this.fsw._symlinkPaths.set(full, linkPath);
29771
- this.fsw._emit(EV.CHANGE, path26, entry.stats);
30183
+ this.fsw._emit(EV.CHANGE, path28, entry.stats);
29772
30184
  }
29773
30185
  } else {
29774
30186
  dir.add(item);
29775
30187
  this.fsw._symlinkPaths.set(full, linkPath);
29776
- this.fsw._emit(EV.ADD, path26, entry.stats);
30188
+ this.fsw._emit(EV.ADD, path28, entry.stats);
29777
30189
  }
29778
30190
  this.fsw._emitReady();
29779
30191
  return true;
@@ -29803,9 +30215,9 @@ var init_handler2 = __esm({
29803
30215
  return;
29804
30216
  }
29805
30217
  const item = entry.path;
29806
- let path26 = sp.join(directory, item);
30218
+ let path28 = sp.join(directory, item);
29807
30219
  current.add(item);
29808
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path26, item)) {
30220
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path28, item)) {
29809
30221
  return;
29810
30222
  }
29811
30223
  if (this.fsw.closed) {
@@ -29814,8 +30226,8 @@ var init_handler2 = __esm({
29814
30226
  }
29815
30227
  if (item === target || !target && !previous.has(item)) {
29816
30228
  this.fsw._incrReadyCount();
29817
- path26 = sp.join(dir, sp.relative(dir, path26));
29818
- this._addToNodeFs(path26, initialAdd, wh, depth + 1);
30229
+ path28 = sp.join(dir, sp.relative(dir, path28));
30230
+ this._addToNodeFs(path28, initialAdd, wh, depth + 1);
29819
30231
  }
29820
30232
  }).on(EV.ERROR, this._boundHandleError);
29821
30233
  return new Promise((resolve16, reject) => {
@@ -29884,13 +30296,13 @@ var init_handler2 = __esm({
29884
30296
  * @param depth Child path actually targeted for watch
29885
30297
  * @param target Child path actually targeted for watch
29886
30298
  */
29887
- async _addToNodeFs(path26, initialAdd, priorWh, depth, target) {
30299
+ async _addToNodeFs(path28, initialAdd, priorWh, depth, target) {
29888
30300
  const ready = this.fsw._emitReady;
29889
- if (this.fsw._isIgnored(path26) || this.fsw.closed) {
30301
+ if (this.fsw._isIgnored(path28) || this.fsw.closed) {
29890
30302
  ready();
29891
30303
  return false;
29892
30304
  }
29893
- const wh = this.fsw._getWatchHelpers(path26);
30305
+ const wh = this.fsw._getWatchHelpers(path28);
29894
30306
  if (priorWh) {
29895
30307
  wh.filterPath = (entry) => priorWh.filterPath(entry);
29896
30308
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -29906,8 +30318,8 @@ var init_handler2 = __esm({
29906
30318
  const follow = this.fsw.options.followSymlinks;
29907
30319
  let closer;
29908
30320
  if (stats.isDirectory()) {
29909
- const absPath = sp.resolve(path26);
29910
- const targetPath = follow ? await (0, import_promises2.realpath)(path26) : path26;
30321
+ const absPath = sp.resolve(path28);
30322
+ const targetPath = follow ? await (0, import_promises2.realpath)(path28) : path28;
29911
30323
  if (this.fsw.closed)
29912
30324
  return;
29913
30325
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -29917,29 +30329,29 @@ var init_handler2 = __esm({
29917
30329
  this.fsw._symlinkPaths.set(absPath, targetPath);
29918
30330
  }
29919
30331
  } else if (stats.isSymbolicLink()) {
29920
- const targetPath = follow ? await (0, import_promises2.realpath)(path26) : path26;
30332
+ const targetPath = follow ? await (0, import_promises2.realpath)(path28) : path28;
29921
30333
  if (this.fsw.closed)
29922
30334
  return;
29923
30335
  const parent = sp.dirname(wh.watchPath);
29924
30336
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
29925
30337
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
29926
- closer = await this._handleDir(parent, stats, initialAdd, depth, path26, wh, targetPath);
30338
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path28, wh, targetPath);
29927
30339
  if (this.fsw.closed)
29928
30340
  return;
29929
30341
  if (targetPath !== void 0) {
29930
- this.fsw._symlinkPaths.set(sp.resolve(path26), targetPath);
30342
+ this.fsw._symlinkPaths.set(sp.resolve(path28), targetPath);
29931
30343
  }
29932
30344
  } else {
29933
30345
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
29934
30346
  }
29935
30347
  ready();
29936
30348
  if (closer)
29937
- this.fsw._addPathCloser(path26, closer);
30349
+ this.fsw._addPathCloser(path28, closer);
29938
30350
  return false;
29939
30351
  } catch (error48) {
29940
30352
  if (this.fsw._handleError(error48)) {
29941
30353
  ready();
29942
- return path26;
30354
+ return path28;
29943
30355
  }
29944
30356
  }
29945
30357
  }
@@ -29974,24 +30386,24 @@ function createPattern(matcher) {
29974
30386
  }
29975
30387
  return () => false;
29976
30388
  }
29977
- function normalizePath(path26) {
29978
- if (typeof path26 !== "string")
30389
+ function normalizePath(path28) {
30390
+ if (typeof path28 !== "string")
29979
30391
  throw new Error("string expected");
29980
- path26 = sp2.normalize(path26);
29981
- path26 = path26.replace(/\\/g, "/");
30392
+ path28 = sp2.normalize(path28);
30393
+ path28 = path28.replace(/\\/g, "/");
29982
30394
  let prepend = false;
29983
- if (path26.startsWith("//"))
30395
+ if (path28.startsWith("//"))
29984
30396
  prepend = true;
29985
- path26 = path26.replace(DOUBLE_SLASH_RE, "/");
30397
+ path28 = path28.replace(DOUBLE_SLASH_RE, "/");
29986
30398
  if (prepend)
29987
- path26 = "/" + path26;
29988
- return path26;
30399
+ path28 = "/" + path28;
30400
+ return path28;
29989
30401
  }
29990
30402
  function matchPatterns(patterns, testString, stats) {
29991
- const path26 = normalizePath(testString);
30403
+ const path28 = normalizePath(testString);
29992
30404
  for (let index = 0; index < patterns.length; index++) {
29993
30405
  const pattern = patterns[index];
29994
- if (pattern(path26, stats)) {
30406
+ if (pattern(path28, stats)) {
29995
30407
  return true;
29996
30408
  }
29997
30409
  }
@@ -30054,19 +30466,19 @@ var init_chokidar = __esm({
30054
30466
  }
30055
30467
  return str;
30056
30468
  };
30057
- normalizePathToUnix = (path26) => toUnix(sp2.normalize(toUnix(path26)));
30058
- normalizeIgnored = (cwd = "") => (path26) => {
30059
- if (typeof path26 === "string") {
30060
- return normalizePathToUnix(sp2.isAbsolute(path26) ? path26 : sp2.join(cwd, path26));
30469
+ normalizePathToUnix = (path28) => toUnix(sp2.normalize(toUnix(path28)));
30470
+ normalizeIgnored = (cwd = "") => (path28) => {
30471
+ if (typeof path28 === "string") {
30472
+ return normalizePathToUnix(sp2.isAbsolute(path28) ? path28 : sp2.join(cwd, path28));
30061
30473
  } else {
30062
- return path26;
30474
+ return path28;
30063
30475
  }
30064
30476
  };
30065
- getAbsolutePath = (path26, cwd) => {
30066
- if (sp2.isAbsolute(path26)) {
30067
- return path26;
30477
+ getAbsolutePath = (path28, cwd) => {
30478
+ if (sp2.isAbsolute(path28)) {
30479
+ return path28;
30068
30480
  }
30069
- return sp2.join(cwd, path26);
30481
+ return sp2.join(cwd, path28);
30070
30482
  };
30071
30483
  EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
30072
30484
  DirEntry = class {
@@ -30131,10 +30543,10 @@ var init_chokidar = __esm({
30131
30543
  dirParts;
30132
30544
  followSymlinks;
30133
30545
  statMethod;
30134
- constructor(path26, follow, fsw) {
30546
+ constructor(path28, follow, fsw) {
30135
30547
  this.fsw = fsw;
30136
- const watchPath = path26;
30137
- this.path = path26 = path26.replace(REPLACER_RE, "");
30548
+ const watchPath = path28;
30549
+ this.path = path28 = path28.replace(REPLACER_RE, "");
30138
30550
  this.watchPath = watchPath;
30139
30551
  this.fullWatchPath = sp2.resolve(watchPath);
30140
30552
  this.dirParts = [];
@@ -30274,20 +30686,20 @@ var init_chokidar = __esm({
30274
30686
  this._closePromise = void 0;
30275
30687
  let paths = unifyPaths(paths_);
30276
30688
  if (cwd) {
30277
- paths = paths.map((path26) => {
30278
- const absPath = getAbsolutePath(path26, cwd);
30689
+ paths = paths.map((path28) => {
30690
+ const absPath = getAbsolutePath(path28, cwd);
30279
30691
  return absPath;
30280
30692
  });
30281
30693
  }
30282
- paths.forEach((path26) => {
30283
- this._removeIgnoredPath(path26);
30694
+ paths.forEach((path28) => {
30695
+ this._removeIgnoredPath(path28);
30284
30696
  });
30285
30697
  this._userIgnored = void 0;
30286
30698
  if (!this._readyCount)
30287
30699
  this._readyCount = 0;
30288
30700
  this._readyCount += paths.length;
30289
- Promise.all(paths.map(async (path26) => {
30290
- const res = await this._nodeFsHandler._addToNodeFs(path26, !_internal, void 0, 0, _origAdd);
30701
+ Promise.all(paths.map(async (path28) => {
30702
+ const res = await this._nodeFsHandler._addToNodeFs(path28, !_internal, void 0, 0, _origAdd);
30291
30703
  if (res)
30292
30704
  this._emitReady();
30293
30705
  return res;
@@ -30309,17 +30721,17 @@ var init_chokidar = __esm({
30309
30721
  return this;
30310
30722
  const paths = unifyPaths(paths_);
30311
30723
  const { cwd } = this.options;
30312
- paths.forEach((path26) => {
30313
- if (!sp2.isAbsolute(path26) && !this._closers.has(path26)) {
30724
+ paths.forEach((path28) => {
30725
+ if (!sp2.isAbsolute(path28) && !this._closers.has(path28)) {
30314
30726
  if (cwd)
30315
- path26 = sp2.join(cwd, path26);
30316
- path26 = sp2.resolve(path26);
30727
+ path28 = sp2.join(cwd, path28);
30728
+ path28 = sp2.resolve(path28);
30317
30729
  }
30318
- this._closePath(path26);
30319
- this._addIgnoredPath(path26);
30320
- if (this._watched.has(path26)) {
30730
+ this._closePath(path28);
30731
+ this._addIgnoredPath(path28);
30732
+ if (this._watched.has(path28)) {
30321
30733
  this._addIgnoredPath({
30322
- path: path26,
30734
+ path: path28,
30323
30735
  recursive: true
30324
30736
  });
30325
30737
  }
@@ -30383,38 +30795,38 @@ var init_chokidar = __esm({
30383
30795
  * @param stats arguments to be passed with event
30384
30796
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
30385
30797
  */
30386
- async _emit(event, path26, stats) {
30798
+ async _emit(event, path28, stats) {
30387
30799
  if (this.closed)
30388
30800
  return;
30389
30801
  const opts = this.options;
30390
30802
  if (isWindows)
30391
- path26 = sp2.normalize(path26);
30803
+ path28 = sp2.normalize(path28);
30392
30804
  if (opts.cwd)
30393
- path26 = sp2.relative(opts.cwd, path26);
30394
- const args = [path26];
30805
+ path28 = sp2.relative(opts.cwd, path28);
30806
+ const args = [path28];
30395
30807
  if (stats != null)
30396
30808
  args.push(stats);
30397
30809
  const awf = opts.awaitWriteFinish;
30398
30810
  let pw;
30399
- if (awf && (pw = this._pendingWrites.get(path26))) {
30811
+ if (awf && (pw = this._pendingWrites.get(path28))) {
30400
30812
  pw.lastChange = /* @__PURE__ */ new Date();
30401
30813
  return this;
30402
30814
  }
30403
30815
  if (opts.atomic) {
30404
30816
  if (event === EVENTS.UNLINK) {
30405
- this._pendingUnlinks.set(path26, [event, ...args]);
30817
+ this._pendingUnlinks.set(path28, [event, ...args]);
30406
30818
  setTimeout(() => {
30407
- this._pendingUnlinks.forEach((entry, path27) => {
30819
+ this._pendingUnlinks.forEach((entry, path29) => {
30408
30820
  this.emit(...entry);
30409
30821
  this.emit(EVENTS.ALL, ...entry);
30410
- this._pendingUnlinks.delete(path27);
30822
+ this._pendingUnlinks.delete(path29);
30411
30823
  });
30412
30824
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
30413
30825
  return this;
30414
30826
  }
30415
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path26)) {
30827
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path28)) {
30416
30828
  event = EVENTS.CHANGE;
30417
- this._pendingUnlinks.delete(path26);
30829
+ this._pendingUnlinks.delete(path28);
30418
30830
  }
30419
30831
  }
30420
30832
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -30432,16 +30844,16 @@ var init_chokidar = __esm({
30432
30844
  this.emitWithAll(event, args);
30433
30845
  }
30434
30846
  };
30435
- this._awaitWriteFinish(path26, awf.stabilityThreshold, event, awfEmit);
30847
+ this._awaitWriteFinish(path28, awf.stabilityThreshold, event, awfEmit);
30436
30848
  return this;
30437
30849
  }
30438
30850
  if (event === EVENTS.CHANGE) {
30439
- const isThrottled = !this._throttle(EVENTS.CHANGE, path26, 50);
30851
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path28, 50);
30440
30852
  if (isThrottled)
30441
30853
  return this;
30442
30854
  }
30443
30855
  if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
30444
- const fullPath = opts.cwd ? sp2.join(opts.cwd, path26) : path26;
30856
+ const fullPath = opts.cwd ? sp2.join(opts.cwd, path28) : path28;
30445
30857
  let stats2;
30446
30858
  try {
30447
30859
  stats2 = await (0, import_promises3.stat)(fullPath);
@@ -30472,23 +30884,23 @@ var init_chokidar = __esm({
30472
30884
  * @param timeout duration of time to suppress duplicate actions
30473
30885
  * @returns tracking object or false if action should be suppressed
30474
30886
  */
30475
- _throttle(actionType, path26, timeout) {
30887
+ _throttle(actionType, path28, timeout) {
30476
30888
  if (!this._throttled.has(actionType)) {
30477
30889
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
30478
30890
  }
30479
30891
  const action = this._throttled.get(actionType);
30480
30892
  if (!action)
30481
30893
  throw new Error("invalid throttle");
30482
- const actionPath = action.get(path26);
30894
+ const actionPath = action.get(path28);
30483
30895
  if (actionPath) {
30484
30896
  actionPath.count++;
30485
30897
  return false;
30486
30898
  }
30487
30899
  let timeoutObject;
30488
30900
  const clear = () => {
30489
- const item = action.get(path26);
30901
+ const item = action.get(path28);
30490
30902
  const count = item ? item.count : 0;
30491
- action.delete(path26);
30903
+ action.delete(path28);
30492
30904
  clearTimeout(timeoutObject);
30493
30905
  if (item)
30494
30906
  clearTimeout(item.timeoutObject);
@@ -30496,7 +30908,7 @@ var init_chokidar = __esm({
30496
30908
  };
30497
30909
  timeoutObject = setTimeout(clear, timeout);
30498
30910
  const thr = { timeoutObject, clear, count: 0 };
30499
- action.set(path26, thr);
30911
+ action.set(path28, thr);
30500
30912
  return thr;
30501
30913
  }
30502
30914
  _incrReadyCount() {
@@ -30510,44 +30922,44 @@ var init_chokidar = __esm({
30510
30922
  * @param event
30511
30923
  * @param awfEmit Callback to be called when ready for event to be emitted.
30512
30924
  */
30513
- _awaitWriteFinish(path26, threshold, event, awfEmit) {
30925
+ _awaitWriteFinish(path28, threshold, event, awfEmit) {
30514
30926
  const awf = this.options.awaitWriteFinish;
30515
30927
  if (typeof awf !== "object")
30516
30928
  return;
30517
30929
  const pollInterval = awf.pollInterval;
30518
30930
  let timeoutHandler;
30519
- let fullPath = path26;
30520
- if (this.options.cwd && !sp2.isAbsolute(path26)) {
30521
- fullPath = sp2.join(this.options.cwd, path26);
30931
+ let fullPath = path28;
30932
+ if (this.options.cwd && !sp2.isAbsolute(path28)) {
30933
+ fullPath = sp2.join(this.options.cwd, path28);
30522
30934
  }
30523
30935
  const now = /* @__PURE__ */ new Date();
30524
30936
  const writes = this._pendingWrites;
30525
30937
  function awaitWriteFinishFn(prevStat) {
30526
30938
  (0, import_node_fs2.stat)(fullPath, (err, curStat) => {
30527
- if (err || !writes.has(path26)) {
30939
+ if (err || !writes.has(path28)) {
30528
30940
  if (err && err.code !== "ENOENT")
30529
30941
  awfEmit(err);
30530
30942
  return;
30531
30943
  }
30532
30944
  const now2 = Number(/* @__PURE__ */ new Date());
30533
30945
  if (prevStat && curStat.size !== prevStat.size) {
30534
- writes.get(path26).lastChange = now2;
30946
+ writes.get(path28).lastChange = now2;
30535
30947
  }
30536
- const pw = writes.get(path26);
30948
+ const pw = writes.get(path28);
30537
30949
  const df = now2 - pw.lastChange;
30538
30950
  if (df >= threshold) {
30539
- writes.delete(path26);
30951
+ writes.delete(path28);
30540
30952
  awfEmit(void 0, curStat);
30541
30953
  } else {
30542
30954
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
30543
30955
  }
30544
30956
  });
30545
30957
  }
30546
- if (!writes.has(path26)) {
30547
- writes.set(path26, {
30958
+ if (!writes.has(path28)) {
30959
+ writes.set(path28, {
30548
30960
  lastChange: now,
30549
30961
  cancelWait: () => {
30550
- writes.delete(path26);
30962
+ writes.delete(path28);
30551
30963
  clearTimeout(timeoutHandler);
30552
30964
  return event;
30553
30965
  }
@@ -30558,8 +30970,8 @@ var init_chokidar = __esm({
30558
30970
  /**
30559
30971
  * Determines whether user has asked to ignore this path.
30560
30972
  */
30561
- _isIgnored(path26, stats) {
30562
- if (this.options.atomic && DOT_RE.test(path26))
30973
+ _isIgnored(path28, stats) {
30974
+ if (this.options.atomic && DOT_RE.test(path28))
30563
30975
  return true;
30564
30976
  if (!this._userIgnored) {
30565
30977
  const { cwd } = this.options;
@@ -30569,17 +30981,17 @@ var init_chokidar = __esm({
30569
30981
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
30570
30982
  this._userIgnored = anymatch(list, void 0);
30571
30983
  }
30572
- return this._userIgnored(path26, stats);
30984
+ return this._userIgnored(path28, stats);
30573
30985
  }
30574
- _isntIgnored(path26, stat4) {
30575
- return !this._isIgnored(path26, stat4);
30986
+ _isntIgnored(path28, stat4) {
30987
+ return !this._isIgnored(path28, stat4);
30576
30988
  }
30577
30989
  /**
30578
30990
  * Provides a set of common helpers and properties relating to symlink handling.
30579
30991
  * @param path file or directory pattern being watched
30580
30992
  */
30581
- _getWatchHelpers(path26) {
30582
- return new WatchHelper(path26, this.options.followSymlinks, this);
30993
+ _getWatchHelpers(path28) {
30994
+ return new WatchHelper(path28, this.options.followSymlinks, this);
30583
30995
  }
30584
30996
  // Directory helpers
30585
30997
  // -----------------
@@ -30611,63 +31023,63 @@ var init_chokidar = __esm({
30611
31023
  * @param item base path of item/directory
30612
31024
  */
30613
31025
  _remove(directory, item, isDirectory) {
30614
- const path26 = sp2.join(directory, item);
30615
- const fullPath = sp2.resolve(path26);
30616
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path26) || this._watched.has(fullPath);
30617
- if (!this._throttle("remove", path26, 100))
31026
+ const path28 = sp2.join(directory, item);
31027
+ const fullPath = sp2.resolve(path28);
31028
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path28) || this._watched.has(fullPath);
31029
+ if (!this._throttle("remove", path28, 100))
30618
31030
  return;
30619
31031
  if (!isDirectory && this._watched.size === 1) {
30620
31032
  this.add(directory, item, true);
30621
31033
  }
30622
- const wp = this._getWatchedDir(path26);
31034
+ const wp = this._getWatchedDir(path28);
30623
31035
  const nestedDirectoryChildren = wp.getChildren();
30624
- nestedDirectoryChildren.forEach((nested) => this._remove(path26, nested));
31036
+ nestedDirectoryChildren.forEach((nested) => this._remove(path28, nested));
30625
31037
  const parent = this._getWatchedDir(directory);
30626
31038
  const wasTracked = parent.has(item);
30627
31039
  parent.remove(item);
30628
31040
  if (this._symlinkPaths.has(fullPath)) {
30629
31041
  this._symlinkPaths.delete(fullPath);
30630
31042
  }
30631
- let relPath = path26;
31043
+ let relPath = path28;
30632
31044
  if (this.options.cwd)
30633
- relPath = sp2.relative(this.options.cwd, path26);
31045
+ relPath = sp2.relative(this.options.cwd, path28);
30634
31046
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
30635
31047
  const event = this._pendingWrites.get(relPath).cancelWait();
30636
31048
  if (event === EVENTS.ADD)
30637
31049
  return;
30638
31050
  }
30639
- this._watched.delete(path26);
31051
+ this._watched.delete(path28);
30640
31052
  this._watched.delete(fullPath);
30641
31053
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
30642
- if (wasTracked && !this._isIgnored(path26))
30643
- this._emit(eventName, path26);
30644
- this._closePath(path26);
31054
+ if (wasTracked && !this._isIgnored(path28))
31055
+ this._emit(eventName, path28);
31056
+ this._closePath(path28);
30645
31057
  }
30646
31058
  /**
30647
31059
  * Closes all watchers for a path
30648
31060
  */
30649
- _closePath(path26) {
30650
- this._closeFile(path26);
30651
- const dir = sp2.dirname(path26);
30652
- this._getWatchedDir(dir).remove(sp2.basename(path26));
31061
+ _closePath(path28) {
31062
+ this._closeFile(path28);
31063
+ const dir = sp2.dirname(path28);
31064
+ this._getWatchedDir(dir).remove(sp2.basename(path28));
30653
31065
  }
30654
31066
  /**
30655
31067
  * Closes only file-specific watchers
30656
31068
  */
30657
- _closeFile(path26) {
30658
- const closers = this._closers.get(path26);
31069
+ _closeFile(path28) {
31070
+ const closers = this._closers.get(path28);
30659
31071
  if (!closers)
30660
31072
  return;
30661
31073
  closers.forEach((closer) => closer());
30662
- this._closers.delete(path26);
31074
+ this._closers.delete(path28);
30663
31075
  }
30664
- _addPathCloser(path26, closer) {
31076
+ _addPathCloser(path28, closer) {
30665
31077
  if (!closer)
30666
31078
  return;
30667
- let list = this._closers.get(path26);
31079
+ let list = this._closers.get(path28);
30668
31080
  if (!list) {
30669
31081
  list = [];
30670
- this._closers.set(path26, list);
31082
+ this._closers.set(path28, list);
30671
31083
  }
30672
31084
  list.push(closer);
30673
31085
  }
@@ -30692,17 +31104,152 @@ var init_chokidar = __esm({
30692
31104
  }
30693
31105
  });
30694
31106
 
31107
+ // ../../oss/packages/daemon-core/src/providers/provider-schema.ts
31108
+ function validateProviderDefinition(raw) {
31109
+ const errors = [];
31110
+ const warnings = [];
31111
+ if (!raw || typeof raw !== "object") {
31112
+ return { errors: ["Provider definition must be an object"], warnings };
31113
+ }
31114
+ const provider = raw;
31115
+ if (!provider.type) errors.push("Missing required field: type");
31116
+ if (!provider.name) errors.push("Missing required field: name");
31117
+ if (!provider.category) {
31118
+ errors.push("Missing required field: category");
31119
+ } else if (!["ide", "extension", "cli", "acp"].includes(String(provider.category))) {
31120
+ errors.push(`Invalid category: ${String(provider.category)}`);
31121
+ }
31122
+ for (const key of Object.keys(provider)) {
31123
+ if (!KNOWN_PROVIDER_FIELDS.has(key)) {
31124
+ warnings.push(`Unknown provider field: ${key}`);
31125
+ }
31126
+ }
31127
+ const category = provider.category;
31128
+ if (category === "cli" || category === "acp") {
31129
+ const spawn5 = provider.spawn;
31130
+ const command = spawn5 && typeof spawn5 === "object" ? spawn5.command : void 0;
31131
+ if (!spawn5 || typeof spawn5 !== "object") {
31132
+ errors.push(`${String(category).toUpperCase()}/CLI providers must have spawn config`);
31133
+ } else if (typeof command !== "string" || !command.trim()) {
31134
+ errors.push("spawn.command is required");
31135
+ }
31136
+ }
31137
+ if ((category === "ide" || category === "extension") && provider.cdpPorts !== void 0) {
31138
+ if (!Array.isArray(provider.cdpPorts) || provider.cdpPorts.length === 0) {
31139
+ warnings.push("IDE/Extension providers should have cdpPorts");
31140
+ }
31141
+ }
31142
+ if (category === "extension" && !provider.extensionId) {
31143
+ warnings.push("Extension providers should have extensionId");
31144
+ }
31145
+ for (const control of Array.isArray(provider.controls) ? provider.controls : []) {
31146
+ validateControl(control, errors);
31147
+ }
31148
+ return { errors, warnings };
31149
+ }
31150
+ function validateControl(control, errors) {
31151
+ if (!control || typeof control !== "object") {
31152
+ errors.push("controls: each control must be an object");
31153
+ return;
31154
+ }
31155
+ const id = typeof control.id === "string" && control.id.trim() ? control.id.trim() : "unknown";
31156
+ const prefix = `controls.${id}`;
31157
+ if (!control.id || !String(control.id).trim()) errors.push(`${prefix}: id is required`);
31158
+ if (!control.type) errors.push(`${prefix}: type is required`);
31159
+ if (!control.label || !String(control.label).trim()) errors.push(`${prefix}: label is required`);
31160
+ if (!control.placement) errors.push(`${prefix}: placement is required`);
31161
+ if (control.dynamic && !control.listScript) {
31162
+ errors.push(`${prefix}: dynamic controls require listScript`);
31163
+ }
31164
+ if (VALUE_CONTROL_TYPES.has(control.type) && !control.setScript) {
31165
+ errors.push(`${prefix}: ${control.type} controls require setScript`);
31166
+ }
31167
+ if (control.type === "action" && !control.invokeScript) {
31168
+ errors.push(`${prefix}: action controls require invokeScript`);
31169
+ }
31170
+ if (control.type === "slider") {
31171
+ if (typeof control.min !== "number" || typeof control.max !== "number") {
31172
+ errors.push(`${prefix}: slider controls require numeric min and max`);
31173
+ } else if (control.min > control.max) {
31174
+ errors.push(`${prefix}: slider min cannot exceed max`);
31175
+ }
31176
+ }
31177
+ if (control.readFrom !== void 0 && (typeof control.readFrom !== "string" || !control.readFrom.trim())) {
31178
+ errors.push(`${prefix}: readFrom must be a non-empty string when provided`);
31179
+ }
31180
+ }
31181
+ var KNOWN_PROVIDER_FIELDS, VALUE_CONTROL_TYPES;
31182
+ var init_provider_schema = __esm({
31183
+ "../../oss/packages/daemon-core/src/providers/provider-schema.ts"() {
31184
+ "use strict";
31185
+ KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
31186
+ "type",
31187
+ "name",
31188
+ "category",
31189
+ "aliases",
31190
+ "cdpPorts",
31191
+ "targetFilter",
31192
+ "cli",
31193
+ "icon",
31194
+ "displayName",
31195
+ "install",
31196
+ "versionCommand",
31197
+ "testedVersions",
31198
+ "processNames",
31199
+ "launch",
31200
+ "paths",
31201
+ "extensionId",
31202
+ "extensionIdPattern",
31203
+ "extensionIdPattern_flags",
31204
+ "compatibility",
31205
+ "defaultScriptDir",
31206
+ "binary",
31207
+ "spawn",
31208
+ "approvalKeys",
31209
+ "patterns",
31210
+ "cleanOutput",
31211
+ "resume",
31212
+ "sessionProbe",
31213
+ "approvalPositiveHints",
31214
+ "scripts",
31215
+ "vscodeCommands",
31216
+ "inputMethod",
31217
+ "inputSelector",
31218
+ "webviewMatchText",
31219
+ "os",
31220
+ "versions",
31221
+ "overrides",
31222
+ "settings",
31223
+ "controls",
31224
+ "staticConfigOptions",
31225
+ "spawnArgBuilder",
31226
+ "auth",
31227
+ "contractVersion",
31228
+ "capabilities",
31229
+ "providerVersion",
31230
+ "status",
31231
+ "details",
31232
+ "sendDelayMs",
31233
+ "sendKey",
31234
+ "submitStrategy",
31235
+ "disableUpstream"
31236
+ ]);
31237
+ VALUE_CONTROL_TYPES = /* @__PURE__ */ new Set(["select", "toggle", "cycle", "slider"]);
31238
+ }
31239
+ });
31240
+
30695
31241
  // ../../oss/packages/daemon-core/src/providers/provider-loader.ts
30696
- var fs6, path13, os14, ProviderLoader;
31242
+ var fs6, path14, os14, ProviderLoader;
30697
31243
  var init_provider_loader = __esm({
30698
31244
  "../../oss/packages/daemon-core/src/providers/provider-loader.ts"() {
30699
31245
  "use strict";
30700
31246
  fs6 = __toESM(require("fs"));
30701
- path13 = __toESM(require("path"));
31247
+ path14 = __toESM(require("path"));
30702
31248
  os14 = __toESM(require("os"));
30703
31249
  init_chokidar();
30704
31250
  init_ide_detector();
30705
31251
  init_logger();
31252
+ init_provider_schema();
30706
31253
  ProviderLoader = class _ProviderLoader {
30707
31254
  providers = /* @__PURE__ */ new Map();
30708
31255
  providerAvailability = /* @__PURE__ */ new Map();
@@ -30721,12 +31268,12 @@ var init_provider_loader = __esm({
30721
31268
  static META_FILE = ".meta.json";
30722
31269
  constructor(options) {
30723
31270
  this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
30724
- const defaultProvidersDir = path13.join(os14.homedir(), ".adhdev", "providers");
31271
+ const defaultProvidersDir = path14.join(os14.homedir(), ".adhdev", "providers");
30725
31272
  if (options?.userDir) {
30726
31273
  this.userDir = options.userDir;
30727
31274
  this.log(`Config 'providerDir' applied: ${this.userDir}`);
30728
31275
  } else {
30729
- const localRepoPath = path13.resolve(__dirname, "../../../../../adhdev-providers");
31276
+ const localRepoPath = path14.resolve(__dirname, "../../../../../adhdev-providers");
30730
31277
  if (fs6.existsSync(localRepoPath)) {
30731
31278
  this.userDir = localRepoPath;
30732
31279
  this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
@@ -30735,7 +31282,7 @@ var init_provider_loader = __esm({
30735
31282
  this.log(`Using default user providers directory: ${this.userDir}`);
30736
31283
  }
30737
31284
  }
30738
- this.upstreamDir = path13.join(defaultProvidersDir, ".upstream");
31285
+ this.upstreamDir = path14.join(defaultProvidersDir, ".upstream");
30739
31286
  this.disableUpstream = options?.disableUpstream ?? false;
30740
31287
  }
30741
31288
  log(msg) {
@@ -30765,7 +31312,7 @@ var init_provider_loader = __esm({
30765
31312
  * Canonical provider directory shape for a given root.
30766
31313
  */
30767
31314
  getProviderDir(root, category, type) {
30768
- return path13.join(root, category, type);
31315
+ return path14.join(root, category, type);
30769
31316
  }
30770
31317
  /**
30771
31318
  * Canonical user override directory for a provider.
@@ -30792,7 +31339,7 @@ var init_provider_loader = __esm({
30792
31339
  resolveProviderFile(type, ...segments) {
30793
31340
  const dir = this.findProviderDirInternal(type);
30794
31341
  if (!dir) return null;
30795
- return path13.join(dir, ...segments);
31342
+ return path14.join(dir, ...segments);
30796
31343
  }
30797
31344
  /**
30798
31345
  * Load all providers (3-tier priority)
@@ -30831,7 +31378,7 @@ var init_provider_loader = __esm({
30831
31378
  if (!fs6.existsSync(this.upstreamDir)) return false;
30832
31379
  try {
30833
31380
  return fs6.readdirSync(this.upstreamDir).some(
30834
- (d) => fs6.statSync(path13.join(this.upstreamDir, d)).isDirectory()
31381
+ (d) => fs6.statSync(path14.join(this.upstreamDir, d)).isDirectory()
30835
31382
  );
30836
31383
  } catch {
30837
31384
  return false;
@@ -31146,8 +31693,8 @@ var init_provider_loader = __esm({
31146
31693
  resolved._resolvedScriptDir = entry.scriptDir;
31147
31694
  resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
31148
31695
  if (providerDir) {
31149
- const fullDir = path13.join(providerDir, entry.scriptDir);
31150
- resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
31696
+ const fullDir = path14.join(providerDir, entry.scriptDir);
31697
+ resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
31151
31698
  }
31152
31699
  matched = true;
31153
31700
  }
@@ -31162,8 +31709,8 @@ var init_provider_loader = __esm({
31162
31709
  resolved._resolvedScriptDir = base.defaultScriptDir;
31163
31710
  resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
31164
31711
  if (providerDir) {
31165
- const fullDir = path13.join(providerDir, base.defaultScriptDir);
31166
- resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
31712
+ const fullDir = path14.join(providerDir, base.defaultScriptDir);
31713
+ resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
31167
31714
  }
31168
31715
  }
31169
31716
  resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
@@ -31180,8 +31727,8 @@ var init_provider_loader = __esm({
31180
31727
  resolved._resolvedScriptDir = dirOverride;
31181
31728
  resolved._resolvedScriptsSource = `versions:${range}`;
31182
31729
  if (providerDir) {
31183
- const fullDir = path13.join(providerDir, dirOverride);
31184
- resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
31730
+ const fullDir = path14.join(providerDir, dirOverride);
31731
+ resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
31185
31732
  }
31186
31733
  }
31187
31734
  } else if (override.scripts) {
@@ -31197,8 +31744,8 @@ var init_provider_loader = __esm({
31197
31744
  resolved._resolvedScriptDir = base.defaultScriptDir;
31198
31745
  resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
31199
31746
  if (providerDir) {
31200
- const fullDir = path13.join(providerDir, base.defaultScriptDir);
31201
- resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
31747
+ const fullDir = path14.join(providerDir, base.defaultScriptDir);
31748
+ resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
31202
31749
  }
31203
31750
  }
31204
31751
  }
@@ -31223,14 +31770,14 @@ var init_provider_loader = __esm({
31223
31770
  this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
31224
31771
  return null;
31225
31772
  }
31226
- const dir = path13.join(providerDir, scriptDir);
31773
+ const dir = path14.join(providerDir, scriptDir);
31227
31774
  if (!fs6.existsSync(dir)) {
31228
31775
  this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
31229
31776
  return null;
31230
31777
  }
31231
31778
  const cached2 = this.scriptsCache.get(dir);
31232
31779
  if (cached2) return cached2;
31233
- const scriptsJs = path13.join(dir, "scripts.js");
31780
+ const scriptsJs = path14.join(dir, "scripts.js");
31234
31781
  if (fs6.existsSync(scriptsJs)) {
31235
31782
  try {
31236
31783
  delete require.cache[require.resolve(scriptsJs)];
@@ -31272,7 +31819,7 @@ var init_provider_loader = __esm({
31272
31819
  return;
31273
31820
  }
31274
31821
  if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
31275
- this.log(`File changed: ${path13.basename(filePath)}, reloading...`);
31822
+ this.log(`File changed: ${path14.basename(filePath)}, reloading...`);
31276
31823
  this.reload();
31277
31824
  }
31278
31825
  };
@@ -31327,7 +31874,7 @@ var init_provider_loader = __esm({
31327
31874
  }
31328
31875
  const https = require("https");
31329
31876
  const { execSync: execSync7 } = require("child_process");
31330
- const metaPath = path13.join(this.upstreamDir, _ProviderLoader.META_FILE);
31877
+ const metaPath = path14.join(this.upstreamDir, _ProviderLoader.META_FILE);
31331
31878
  let prevEtag = "";
31332
31879
  let prevTimestamp = 0;
31333
31880
  try {
@@ -31387,17 +31934,17 @@ var init_provider_loader = __esm({
31387
31934
  return { updated: false };
31388
31935
  }
31389
31936
  this.log("Downloading latest providers from GitHub...");
31390
- const tmpTar = path13.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
31391
- const tmpExtract = path13.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
31937
+ const tmpTar = path14.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
31938
+ const tmpExtract = path14.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
31392
31939
  await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
31393
31940
  fs6.mkdirSync(tmpExtract, { recursive: true });
31394
31941
  execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
31395
31942
  const extracted = fs6.readdirSync(tmpExtract);
31396
31943
  const rootDir = extracted.find(
31397
- (d) => fs6.statSync(path13.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
31944
+ (d) => fs6.statSync(path14.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
31398
31945
  );
31399
31946
  if (!rootDir) throw new Error("Unexpected tarball structure");
31400
- const sourceDir = path13.join(tmpExtract, rootDir);
31947
+ const sourceDir = path14.join(tmpExtract, rootDir);
31401
31948
  const backupDir = this.upstreamDir + ".bak";
31402
31949
  if (fs6.existsSync(this.upstreamDir)) {
31403
31950
  if (fs6.existsSync(backupDir)) fs6.rmSync(backupDir, { recursive: true, force: true });
@@ -31472,8 +32019,8 @@ var init_provider_loader = __esm({
31472
32019
  copyDirRecursive(src, dest) {
31473
32020
  fs6.mkdirSync(dest, { recursive: true });
31474
32021
  for (const entry of fs6.readdirSync(src, { withFileTypes: true })) {
31475
- const srcPath = path13.join(src, entry.name);
31476
- const destPath = path13.join(dest, entry.name);
32022
+ const srcPath = path14.join(src, entry.name);
32023
+ const destPath = path14.join(dest, entry.name);
31477
32024
  if (entry.isDirectory()) {
31478
32025
  this.copyDirRecursive(srcPath, destPath);
31479
32026
  } else {
@@ -31484,7 +32031,7 @@ var init_provider_loader = __esm({
31484
32031
  /** .meta.json save */
31485
32032
  writeMeta(metaPath, etag, timestamp) {
31486
32033
  try {
31487
- fs6.mkdirSync(path13.dirname(metaPath), { recursive: true });
32034
+ fs6.mkdirSync(path14.dirname(metaPath), { recursive: true });
31488
32035
  fs6.writeFileSync(metaPath, JSON.stringify({
31489
32036
  etag,
31490
32037
  timestamp,
@@ -31501,7 +32048,7 @@ var init_provider_loader = __esm({
31501
32048
  const scan = (d) => {
31502
32049
  try {
31503
32050
  for (const entry of fs6.readdirSync(d, { withFileTypes: true })) {
31504
- if (entry.isDirectory()) scan(path13.join(d, entry.name));
32051
+ if (entry.isDirectory()) scan(path14.join(d, entry.name));
31505
32052
  else if (entry.name === "provider.json") count++;
31506
32053
  }
31507
32054
  } catch {
@@ -31686,17 +32233,17 @@ var init_provider_loader = __esm({
31686
32233
  for (const root of searchRoots) {
31687
32234
  if (!fs6.existsSync(root)) continue;
31688
32235
  const candidate = this.getProviderDir(root, cat, type);
31689
- if (fs6.existsSync(path13.join(candidate, "provider.json"))) return candidate;
31690
- const catDir = path13.join(root, cat);
32236
+ if (fs6.existsSync(path14.join(candidate, "provider.json"))) return candidate;
32237
+ const catDir = path14.join(root, cat);
31691
32238
  if (fs6.existsSync(catDir)) {
31692
32239
  try {
31693
32240
  for (const entry of fs6.readdirSync(catDir, { withFileTypes: true })) {
31694
32241
  if (!entry.isDirectory()) continue;
31695
- const jsonPath = path13.join(catDir, entry.name, "provider.json");
32242
+ const jsonPath = path14.join(catDir, entry.name, "provider.json");
31696
32243
  if (fs6.existsSync(jsonPath)) {
31697
32244
  try {
31698
32245
  const data = JSON.parse(fs6.readFileSync(jsonPath, "utf-8"));
31699
- if (data.type === type) return path13.join(catDir, entry.name);
32246
+ if (data.type === type) return path14.join(catDir, entry.name);
31700
32247
  } catch {
31701
32248
  }
31702
32249
  }
@@ -31713,7 +32260,7 @@ var init_provider_loader = __esm({
31713
32260
  * (template substitution is NOT applied here — scripts.js handles that)
31714
32261
  */
31715
32262
  buildScriptWrappersFromDir(dir) {
31716
- const scriptsJs = path13.join(dir, "scripts.js");
32263
+ const scriptsJs = path14.join(dir, "scripts.js");
31717
32264
  if (fs6.existsSync(scriptsJs)) {
31718
32265
  try {
31719
32266
  delete require.cache[require.resolve(scriptsJs)];
@@ -31727,7 +32274,7 @@ var init_provider_loader = __esm({
31727
32274
  for (const file2 of fs6.readdirSync(dir)) {
31728
32275
  if (!file2.endsWith(".js")) continue;
31729
32276
  const scriptName = toCamel(file2.replace(".js", ""));
31730
- const filePath = path13.join(dir, file2);
32277
+ const filePath = path14.join(dir, file2);
31731
32278
  result[scriptName] = (...args) => {
31732
32279
  try {
31733
32280
  let content = fs6.readFileSync(filePath, "utf-8");
@@ -31787,24 +32334,28 @@ var init_provider_loader = __esm({
31787
32334
  }
31788
32335
  const hasJson = entries.some((e) => e.name === "provider.json");
31789
32336
  if (hasJson) {
31790
- const jsonPath = path13.join(d, "provider.json");
32337
+ const jsonPath = path14.join(d, "provider.json");
31791
32338
  try {
31792
32339
  const raw = fs6.readFileSync(jsonPath, "utf-8");
31793
32340
  const mod = JSON.parse(raw);
31794
- if (!mod.type || !mod.name || !mod.category) {
31795
- this.log(`\u26A0 Invalid provider at ${jsonPath}: missing type/name/category`);
32341
+ if (typeof mod.extensionIdPattern === "string") {
32342
+ const flags = mod.extensionIdPattern_flags || "";
32343
+ mod.extensionIdPattern = new RegExp(mod.extensionIdPattern, flags);
32344
+ }
32345
+ const { extensionIdPattern_flags, extensionIdPattern, ...providerFields } = mod;
32346
+ const normalizedProvider = {
32347
+ ...providerFields,
32348
+ ...extensionIdPattern instanceof RegExp ? { extensionIdPattern } : {}
32349
+ };
32350
+ const validation = validateProviderDefinition(normalizedProvider);
32351
+ for (const warning of validation.warnings) {
32352
+ this.log(`\u26A0 ${jsonPath}: ${warning}`);
32353
+ }
32354
+ if (validation.errors.length > 0) {
32355
+ this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
31796
32356
  } else {
31797
- if (typeof mod.extensionIdPattern === "string") {
31798
- const flags = mod.extensionIdPattern_flags || "";
31799
- mod.extensionIdPattern = new RegExp(mod.extensionIdPattern, flags);
31800
- }
31801
- const { extensionIdPattern_flags, extensionIdPattern, ...providerFields } = mod;
31802
- const normalizedProvider = {
31803
- ...providerFields,
31804
- ...extensionIdPattern instanceof RegExp ? { extensionIdPattern } : {}
31805
- };
31806
32357
  const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
31807
- const scriptsPath = path13.join(d, "scripts.js");
32358
+ const scriptsPath = path14.join(d, "scripts.js");
31808
32359
  if (!hasCompatibility && fs6.existsSync(scriptsPath)) {
31809
32360
  try {
31810
32361
  delete require.cache[require.resolve(scriptsPath)];
@@ -31830,7 +32381,7 @@ var init_provider_loader = __esm({
31830
32381
  if (!entry.isDirectory()) continue;
31831
32382
  if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
31832
32383
  if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
31833
- scan(path13.join(d, entry.name));
32384
+ scan(path14.join(d, entry.name));
31834
32385
  }
31835
32386
  }
31836
32387
  };
@@ -32085,17 +32636,17 @@ function detectCurrentWorkspace(ideId) {
32085
32636
  }
32086
32637
  } else if (plat === "win32") {
32087
32638
  try {
32088
- const fs18 = require("fs");
32639
+ const fs19 = require("fs");
32089
32640
  const appNameMap = getMacAppIdentifiers();
32090
32641
  const appName = appNameMap[ideId];
32091
32642
  if (appName) {
32092
- const storagePath = path14.join(
32093
- process.env.APPDATA || path14.join(os15.homedir(), "AppData", "Roaming"),
32643
+ const storagePath = path15.join(
32644
+ process.env.APPDATA || path15.join(os15.homedir(), "AppData", "Roaming"),
32094
32645
  appName,
32095
32646
  "storage.json"
32096
32647
  );
32097
- if (fs18.existsSync(storagePath)) {
32098
- const data = JSON.parse(fs18.readFileSync(storagePath, "utf-8"));
32648
+ if (fs19.existsSync(storagePath)) {
32649
+ const data = JSON.parse(fs19.readFileSync(storagePath, "utf-8"));
32099
32650
  const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
32100
32651
  if (workspaces.length > 0) {
32101
32652
  const recent = workspaces[0];
@@ -32261,14 +32812,14 @@ async function launchLinux(ide, port, workspace, newWindow) {
32261
32812
  function getAvailableIdeIds() {
32262
32813
  return getProviderLoader().getAvailableIdeTypes();
32263
32814
  }
32264
- var import_child_process6, net2, os15, path14, _providerLoader;
32815
+ var import_child_process6, net2, os15, path15, _providerLoader;
32265
32816
  var init_launch = __esm({
32266
32817
  "../../oss/packages/daemon-core/src/launch.ts"() {
32267
32818
  "use strict";
32268
32819
  import_child_process6 = require("child_process");
32269
32820
  net2 = __toESM(require("net"));
32270
32821
  os15 = __toESM(require("os"));
32271
- path14 = __toESM(require("path"));
32822
+ path15 = __toESM(require("path"));
32272
32823
  init_ide_detector();
32273
32824
  init_provider_loader();
32274
32825
  _providerLoader = null;
@@ -32299,7 +32850,7 @@ function checkRotation() {
32299
32850
  const today = getDateStr2();
32300
32851
  if (today !== currentDate2) {
32301
32852
  currentDate2 = today;
32302
- currentFile = path15.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
32853
+ currentFile = path16.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
32303
32854
  cleanOldFiles();
32304
32855
  }
32305
32856
  }
@@ -32313,7 +32864,7 @@ function cleanOldFiles() {
32313
32864
  const dateMatch = file2.match(/commands-(\d{4}-\d{2}-\d{2})/);
32314
32865
  if (dateMatch && dateMatch[1] < cutoffStr) {
32315
32866
  try {
32316
- fs7.unlinkSync(path15.join(LOG_DIR2, file2));
32867
+ fs7.unlinkSync(path16.join(LOG_DIR2, file2));
32317
32868
  } catch {
32318
32869
  }
32319
32870
  }
@@ -32382,14 +32933,14 @@ function getRecentCommands(count = 50) {
32382
32933
  return [];
32383
32934
  }
32384
32935
  }
32385
- var fs7, path15, os16, LOG_DIR2, MAX_FILE_SIZE, MAX_DAYS, SENSITIVE_KEYS, currentDate2, currentFile, writeCount2, SKIP_COMMANDS;
32936
+ var fs7, path16, os16, LOG_DIR2, MAX_FILE_SIZE, MAX_DAYS, SENSITIVE_KEYS, currentDate2, currentFile, writeCount2, SKIP_COMMANDS;
32386
32937
  var init_command_log = __esm({
32387
32938
  "../../oss/packages/daemon-core/src/logging/command-log.ts"() {
32388
32939
  "use strict";
32389
32940
  fs7 = __toESM(require("fs"));
32390
- path15 = __toESM(require("path"));
32941
+ path16 = __toESM(require("path"));
32391
32942
  os16 = __toESM(require("os"));
32392
- LOG_DIR2 = process.platform === "win32" ? path15.join(process.env.LOCALAPPDATA || process.env.APPDATA || path15.join(os16.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path15.join(os16.homedir(), "Library", "Logs", "adhdev") : path15.join(os16.homedir(), ".local", "share", "adhdev", "logs");
32943
+ LOG_DIR2 = process.platform === "win32" ? path16.join(process.env.LOCALAPPDATA || process.env.APPDATA || path16.join(os16.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path16.join(os16.homedir(), "Library", "Logs", "adhdev") : path16.join(os16.homedir(), ".local", "share", "adhdev", "logs");
32393
32944
  MAX_FILE_SIZE = 5 * 1024 * 1024;
32394
32945
  MAX_DAYS = 7;
32395
32946
  try {
@@ -32408,7 +32959,7 @@ var init_command_log = __esm({
32408
32959
  "text"
32409
32960
  ]);
32410
32961
  currentDate2 = getDateStr2();
32411
- currentFile = path15.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
32962
+ currentFile = path16.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
32412
32963
  writeCount2 = 0;
32413
32964
  SKIP_COMMANDS = /* @__PURE__ */ new Set([
32414
32965
  "heartbeat",
@@ -32666,9 +33217,9 @@ var init_snapshot = __esm({
32666
33217
  // ../../oss/packages/daemon-core/src/commands/upgrade-helper.ts
32667
33218
  function getUpgradeLogPath() {
32668
33219
  const home = os18.homedir();
32669
- const dir = path16.join(home, ".adhdev");
33220
+ const dir = path17.join(home, ".adhdev");
32670
33221
  fs8.mkdirSync(dir, { recursive: true });
32671
- return path16.join(dir, "daemon-upgrade.log");
33222
+ return path17.join(dir, "daemon-upgrade.log");
32672
33223
  }
32673
33224
  function appendUpgradeLog(message) {
32674
33225
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
@@ -32708,7 +33259,7 @@ async function waitForPidExit(pid, timeoutMs) {
32708
33259
  }
32709
33260
  }
32710
33261
  function stopSessionHostProcesses(appName) {
32711
- const pidFile = path16.join(os18.homedir(), ".adhdev", `${appName}-session-host.pid`);
33262
+ const pidFile = path17.join(os18.homedir(), ".adhdev", `${appName}-session-host.pid`);
32712
33263
  try {
32713
33264
  if (fs8.existsSync(pidFile)) {
32714
33265
  const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
@@ -32737,7 +33288,7 @@ function stopSessionHostProcesses(appName) {
32737
33288
  }
32738
33289
  }
32739
33290
  function removeDaemonPidFile() {
32740
- const pidFile = path16.join(os18.homedir(), ".adhdev", "daemon.pid");
33291
+ const pidFile = path17.join(os18.homedir(), ".adhdev", "daemon.pid");
32741
33292
  try {
32742
33293
  fs8.unlinkSync(pidFile);
32743
33294
  } catch {
@@ -32748,7 +33299,7 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
32748
33299
  const npmRoot = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["root", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
32749
33300
  if (!npmRoot) return;
32750
33301
  const npmPrefix = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["prefix", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
32751
- const binDir = process.platform === "win32" ? npmPrefix : path16.join(npmPrefix, "bin");
33302
+ const binDir = process.platform === "win32" ? npmPrefix : path17.join(npmPrefix, "bin");
32752
33303
  const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
32753
33304
  const binNames = /* @__PURE__ */ new Set([packageBaseName]);
32754
33305
  if (pkgName === "@adhdev/daemon-standalone") {
@@ -32756,25 +33307,25 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
32756
33307
  }
32757
33308
  if (pkgName.startsWith("@")) {
32758
33309
  const [scope, name] = pkgName.split("/");
32759
- const scopeDir = path16.join(npmRoot, scope);
33310
+ const scopeDir = path17.join(npmRoot, scope);
32760
33311
  if (!fs8.existsSync(scopeDir)) return;
32761
33312
  for (const entry of fs8.readdirSync(scopeDir)) {
32762
33313
  if (!entry.startsWith(`.${name}-`)) continue;
32763
- fs8.rmSync(path16.join(scopeDir, entry), { recursive: true, force: true });
32764
- appendUpgradeLog(`Removed stale scoped staging dir: ${path16.join(scopeDir, entry)}`);
33314
+ fs8.rmSync(path17.join(scopeDir, entry), { recursive: true, force: true });
33315
+ appendUpgradeLog(`Removed stale scoped staging dir: ${path17.join(scopeDir, entry)}`);
32765
33316
  }
32766
33317
  } else {
32767
33318
  for (const entry of fs8.readdirSync(npmRoot)) {
32768
33319
  if (!entry.startsWith(`.${pkgName}-`)) continue;
32769
- fs8.rmSync(path16.join(npmRoot, entry), { recursive: true, force: true });
32770
- appendUpgradeLog(`Removed stale staging dir: ${path16.join(npmRoot, entry)}`);
33320
+ fs8.rmSync(path17.join(npmRoot, entry), { recursive: true, force: true });
33321
+ appendUpgradeLog(`Removed stale staging dir: ${path17.join(npmRoot, entry)}`);
32771
33322
  }
32772
33323
  }
32773
33324
  if (fs8.existsSync(binDir)) {
32774
33325
  for (const entry of fs8.readdirSync(binDir)) {
32775
33326
  if (![...binNames].some((name) => entry.startsWith(`.${name}-`))) continue;
32776
- fs8.rmSync(path16.join(binDir, entry), { recursive: true, force: true });
32777
- appendUpgradeLog(`Removed stale bin staging entry: ${path16.join(binDir, entry)}`);
33327
+ fs8.rmSync(path17.join(binDir, entry), { recursive: true, force: true });
33328
+ appendUpgradeLog(`Removed stale bin staging entry: ${path17.join(binDir, entry)}`);
32778
33329
  }
32779
33330
  }
32780
33331
  }
@@ -32849,7 +33400,7 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
32849
33400
  process.exit(1);
32850
33401
  }
32851
33402
  }
32852
- var import_child_process7, import_child_process8, fs8, os18, path16, UPGRADE_HELPER_ENV;
33403
+ var import_child_process7, import_child_process8, fs8, os18, path17, UPGRADE_HELPER_ENV;
32853
33404
  var init_upgrade_helper = __esm({
32854
33405
  "../../oss/packages/daemon-core/src/commands/upgrade-helper.ts"() {
32855
33406
  "use strict";
@@ -32857,7 +33408,7 @@ var init_upgrade_helper = __esm({
32857
33408
  import_child_process8 = require("child_process");
32858
33409
  fs8 = __toESM(require("fs"));
32859
33410
  os18 = __toESM(require("os"));
32860
- path16 = __toESM(require("path"));
33411
+ path17 = __toESM(require("path"));
32861
33412
  UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
32862
33413
  }
32863
33414
  });
@@ -34802,7 +35353,7 @@ function checkPathExists2(paths) {
34802
35353
  for (const p of paths) {
34803
35354
  if (p.includes("*")) {
34804
35355
  const home = os19.homedir();
34805
- const resolved = p.replace(/\*/g, home.split(path17.sep).pop() || "");
35356
+ const resolved = p.replace(/\*/g, home.split(path18.sep).pop() || "");
34806
35357
  if (fs10.existsSync(resolved)) return resolved;
34807
35358
  } else {
34808
35359
  if (fs10.existsSync(p)) return p;
@@ -34812,7 +35363,7 @@ function checkPathExists2(paths) {
34812
35363
  }
34813
35364
  function getMacAppVersion(appPath) {
34814
35365
  if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
34815
- const plistPath = path17.join(appPath, "Contents", "Info.plist");
35366
+ const plistPath = path18.join(appPath, "Contents", "Info.plist");
34816
35367
  if (!fs10.existsSync(plistPath)) return null;
34817
35368
  const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
34818
35369
  return raw || null;
@@ -34838,7 +35389,7 @@ async function detectAllVersions(loader, archive) {
34838
35389
  const cliBin = provider.cli ? findBinary2(provider.cli) : null;
34839
35390
  let resolvedBin = cliBin;
34840
35391
  if (!resolvedBin && appPath && currentOs === "darwin") {
34841
- const bundled = path17.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
35392
+ const bundled = path18.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
34842
35393
  if (provider.cli && fs10.existsSync(bundled)) resolvedBin = bundled;
34843
35394
  }
34844
35395
  info.installed = !!(appPath || resolvedBin);
@@ -34875,16 +35426,16 @@ async function detectAllVersions(loader, archive) {
34875
35426
  }
34876
35427
  return results;
34877
35428
  }
34878
- var fs10, path17, os19, import_child_process9, import_os3, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive;
35429
+ var fs10, path18, os19, import_child_process9, import_os3, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive;
34879
35430
  var init_version_archive = __esm({
34880
35431
  "../../oss/packages/daemon-core/src/providers/version-archive.ts"() {
34881
35432
  "use strict";
34882
35433
  fs10 = __toESM(require("fs"));
34883
- path17 = __toESM(require("path"));
35434
+ path18 = __toESM(require("path"));
34884
35435
  os19 = __toESM(require("os"));
34885
35436
  import_child_process9 = require("child_process");
34886
35437
  import_os3 = require("os");
34887
- ARCHIVE_PATH = path17.join(os19.homedir(), ".adhdev", "version-history.json");
35438
+ ARCHIVE_PATH = path18.join(os19.homedir(), ".adhdev", "version-history.json");
34888
35439
  MAX_ENTRIES_PER_PROVIDER = 20;
34889
35440
  VersionArchive = class {
34890
35441
  history = {};
@@ -34931,7 +35482,7 @@ var init_version_archive = __esm({
34931
35482
  }
34932
35483
  save() {
34933
35484
  try {
34934
- fs10.mkdirSync(path17.dirname(ARCHIVE_PATH), { recursive: true });
35485
+ fs10.mkdirSync(path18.dirname(ARCHIVE_PATH), { recursive: true });
34935
35486
  fs10.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
34936
35487
  } catch {
34937
35488
  }
@@ -35452,17 +36003,17 @@ async function handleScriptHints(ctx, type, _req, res) {
35452
36003
  return;
35453
36004
  }
35454
36005
  let scriptsPath = "";
35455
- const directScripts = path18.join(dir, "scripts.js");
36006
+ const directScripts = path19.join(dir, "scripts.js");
35456
36007
  if (fs11.existsSync(directScripts)) {
35457
36008
  scriptsPath = directScripts;
35458
36009
  } else {
35459
- const scriptsDir = path18.join(dir, "scripts");
36010
+ const scriptsDir = path19.join(dir, "scripts");
35460
36011
  if (fs11.existsSync(scriptsDir)) {
35461
36012
  const versions = fs11.readdirSync(scriptsDir).filter((d) => {
35462
- return fs11.statSync(path18.join(scriptsDir, d)).isDirectory();
36013
+ return fs11.statSync(path19.join(scriptsDir, d)).isDirectory();
35463
36014
  }).sort().reverse();
35464
36015
  for (const ver of versions) {
35465
- const p = path18.join(scriptsDir, ver, "scripts.js");
36016
+ const p = path19.join(scriptsDir, ver, "scripts.js");
35466
36017
  if (fs11.existsSync(p)) {
35467
36018
  scriptsPath = p;
35468
36019
  break;
@@ -36288,12 +36839,12 @@ async function handleDomContext(ctx, type, req, res) {
36288
36839
  ctx.json(res, 500, { error: `DOM context collection failed: ${e.message}` });
36289
36840
  }
36290
36841
  }
36291
- var fs11, path18;
36842
+ var fs11, path19;
36292
36843
  var init_dev_cdp_handlers = __esm({
36293
36844
  "../../oss/packages/daemon-core/src/daemon/dev-cdp-handlers.ts"() {
36294
36845
  "use strict";
36295
36846
  fs11 = __toESM(require("fs"));
36296
- path18 = __toESM(require("path"));
36847
+ path19 = __toESM(require("path"));
36297
36848
  init_logger();
36298
36849
  }
36299
36850
  });
@@ -36308,11 +36859,11 @@ function getCliFixtureDir(ctx, type) {
36308
36859
  if (!providerDir) {
36309
36860
  throw new Error(`Provider directory not found for '${type}'`);
36310
36861
  }
36311
- return path19.join(providerDir, "fixtures");
36862
+ return path20.join(providerDir, "fixtures");
36312
36863
  }
36313
36864
  function readCliFixture(ctx, type, name) {
36314
36865
  const fixtureDir = getCliFixtureDir(ctx, type);
36315
- const filePath = path19.join(fixtureDir, `${name}.json`);
36866
+ const filePath = path20.join(fixtureDir, `${name}.json`);
36316
36867
  if (!fs12.existsSync(filePath)) {
36317
36868
  throw new Error(`Fixture not found: ${filePath}`);
36318
36869
  }
@@ -37080,7 +37631,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
37080
37631
  },
37081
37632
  notes: typeof body?.notes === "string" ? body.notes : void 0
37082
37633
  };
37083
- const filePath = path19.join(fixtureDir, `${name}.json`);
37634
+ const filePath = path20.join(fixtureDir, `${name}.json`);
37084
37635
  fs12.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
37085
37636
  ctx.json(res, 200, {
37086
37637
  saved: true,
@@ -37104,7 +37655,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
37104
37655
  return;
37105
37656
  }
37106
37657
  const fixtures = fs12.readdirSync(fixtureDir).filter((file2) => file2.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file2) => {
37107
- const fullPath = path19.join(fixtureDir, file2);
37658
+ const fullPath = path20.join(fixtureDir, file2);
37108
37659
  try {
37109
37660
  const raw = JSON.parse(fs12.readFileSync(fullPath, "utf-8"));
37110
37661
  return {
@@ -37237,12 +37788,12 @@ async function handleCliRaw(ctx, req, res) {
37237
37788
  ctx.json(res, 500, { error: `Raw send failed: ${e.message}` });
37238
37789
  }
37239
37790
  }
37240
- var fs12, path19;
37791
+ var fs12, path20;
37241
37792
  var init_dev_cli_debug = __esm({
37242
37793
  "../../oss/packages/daemon-core/src/daemon/dev-cli-debug.ts"() {
37243
37794
  "use strict";
37244
37795
  fs12 = __toESM(require("fs"));
37245
- path19 = __toESM(require("path"));
37796
+ path20 = __toESM(require("path"));
37246
37797
  }
37247
37798
  });
37248
37799
 
@@ -37302,22 +37853,22 @@ function getLatestScriptVersionDir(scriptsDir) {
37302
37853
  if (!fs13.existsSync(scriptsDir)) return null;
37303
37854
  const versions = fs13.readdirSync(scriptsDir).filter((d) => {
37304
37855
  try {
37305
- return fs13.statSync(path20.join(scriptsDir, d)).isDirectory();
37856
+ return fs13.statSync(path21.join(scriptsDir, d)).isDirectory();
37306
37857
  } catch {
37307
37858
  return false;
37308
37859
  }
37309
37860
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
37310
37861
  if (versions.length === 0) return null;
37311
- return path20.join(scriptsDir, versions[0]);
37862
+ return path21.join(scriptsDir, versions[0]);
37312
37863
  }
37313
37864
  function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
37314
- const canonicalUserDir = path20.resolve(ctx.providerLoader.getUserProviderDir(category, type));
37315
- const desiredDir = requestedDir ? path20.resolve(requestedDir) : canonicalUserDir;
37316
- const upstreamRoot = path20.resolve(ctx.providerLoader.getUpstreamDir());
37317
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path20.sep}`)) {
37865
+ const canonicalUserDir = path21.resolve(ctx.providerLoader.getUserProviderDir(category, type));
37866
+ const desiredDir = requestedDir ? path21.resolve(requestedDir) : canonicalUserDir;
37867
+ const upstreamRoot = path21.resolve(ctx.providerLoader.getUpstreamDir());
37868
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path21.sep}`)) {
37318
37869
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
37319
37870
  }
37320
- if (path20.basename(desiredDir) !== type) {
37871
+ if (path21.basename(desiredDir) !== type) {
37321
37872
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
37322
37873
  }
37323
37874
  const sourceDir = ctx.findProviderDir(type);
@@ -37325,11 +37876,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
37325
37876
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
37326
37877
  }
37327
37878
  if (!fs13.existsSync(desiredDir)) {
37328
- fs13.mkdirSync(path20.dirname(desiredDir), { recursive: true });
37879
+ fs13.mkdirSync(path21.dirname(desiredDir), { recursive: true });
37329
37880
  fs13.cpSync(sourceDir, desiredDir, { recursive: true });
37330
37881
  ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
37331
37882
  }
37332
- const providerJson = path20.join(desiredDir, "provider.json");
37883
+ const providerJson = path21.join(desiredDir, "provider.json");
37333
37884
  if (!fs13.existsSync(providerJson)) {
37334
37885
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
37335
37886
  }
@@ -37352,13 +37903,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
37352
37903
  const refDir = ctx.findProviderDir(referenceType);
37353
37904
  if (!refDir || !fs13.existsSync(refDir)) return {};
37354
37905
  const referenceScripts = {};
37355
- const scriptsDir = path20.join(refDir, "scripts");
37906
+ const scriptsDir = path21.join(refDir, "scripts");
37356
37907
  const latestDir = getLatestScriptVersionDir(scriptsDir);
37357
37908
  if (!latestDir) return referenceScripts;
37358
37909
  for (const file2 of fs13.readdirSync(latestDir)) {
37359
37910
  if (!file2.endsWith(".js")) continue;
37360
37911
  try {
37361
- referenceScripts[file2] = fs13.readFileSync(path20.join(latestDir, file2), "utf-8");
37912
+ referenceScripts[file2] = fs13.readFileSync(path21.join(latestDir, file2), "utf-8");
37362
37913
  } catch {
37363
37914
  }
37364
37915
  }
@@ -37466,9 +38017,9 @@ async function handleAutoImplement(ctx, type, req, res) {
37466
38017
  });
37467
38018
  const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
37468
38019
  const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
37469
- const tmpDir = path20.join(os20.tmpdir(), "adhdev-autoimpl");
38020
+ const tmpDir = path21.join(os20.tmpdir(), "adhdev-autoimpl");
37470
38021
  if (!fs13.existsSync(tmpDir)) fs13.mkdirSync(tmpDir, { recursive: true });
37471
- const promptFile = path20.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
38022
+ const promptFile = path21.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
37472
38023
  fs13.writeFileSync(promptFile, prompt, "utf-8");
37473
38024
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
37474
38025
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
@@ -37905,7 +38456,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
37905
38456
  setMode: "set_mode.js"
37906
38457
  };
37907
38458
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
37908
- const scriptsDir = path20.join(providerDir, "scripts");
38459
+ const scriptsDir = path21.join(providerDir, "scripts");
37909
38460
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
37910
38461
  if (latestScriptsDir) {
37911
38462
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -37916,7 +38467,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
37916
38467
  for (const file2 of fs13.readdirSync(latestScriptsDir)) {
37917
38468
  if (file2.endsWith(".js") && targetFileNames.has(file2)) {
37918
38469
  try {
37919
- const content = fs13.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
38470
+ const content = fs13.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
37920
38471
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
37921
38472
  lines.push("```javascript");
37922
38473
  lines.push(content);
@@ -37933,7 +38484,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
37933
38484
  lines.push("");
37934
38485
  for (const file2 of refFiles) {
37935
38486
  try {
37936
- const content = fs13.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
38487
+ const content = fs13.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
37937
38488
  lines.push(`### \`${file2}\` \u{1F512}`);
37938
38489
  lines.push("```javascript");
37939
38490
  lines.push(content);
@@ -37974,10 +38525,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
37974
38525
  lines.push("");
37975
38526
  }
37976
38527
  }
37977
- const docsDir = path20.join(providerDir, "../../docs");
38528
+ const docsDir = path21.join(providerDir, "../../docs");
37978
38529
  const loadGuide = (name) => {
37979
38530
  try {
37980
- const p = path20.join(docsDir, name);
38531
+ const p = path21.join(docsDir, name);
37981
38532
  if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
37982
38533
  } catch {
37983
38534
  }
@@ -38214,7 +38765,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
38214
38765
  parseApproval: "parse_approval.js"
38215
38766
  };
38216
38767
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
38217
- const scriptsDir = path20.join(providerDir, "scripts");
38768
+ const scriptsDir = path21.join(providerDir, "scripts");
38218
38769
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
38219
38770
  if (latestScriptsDir) {
38220
38771
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -38226,7 +38777,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
38226
38777
  if (!file2.endsWith(".js")) continue;
38227
38778
  if (!targetFileNames.has(file2)) continue;
38228
38779
  try {
38229
- const content = fs13.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
38780
+ const content = fs13.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
38230
38781
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
38231
38782
  lines.push("```javascript");
38232
38783
  lines.push(content);
@@ -38242,7 +38793,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
38242
38793
  lines.push("");
38243
38794
  for (const file2 of refFiles) {
38244
38795
  try {
38245
- const content = fs13.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
38796
+ const content = fs13.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
38246
38797
  lines.push(`### \`${file2}\` \u{1F512}`);
38247
38798
  lines.push("```javascript");
38248
38799
  lines.push(content);
@@ -38275,10 +38826,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
38275
38826
  lines.push("");
38276
38827
  }
38277
38828
  }
38278
- const docsDir = path20.join(providerDir, "../../docs");
38829
+ const docsDir = path21.join(providerDir, "../../docs");
38279
38830
  const loadGuide = (name) => {
38280
38831
  try {
38281
- const p = path20.join(docsDir, name);
38832
+ const p = path21.join(docsDir, name);
38282
38833
  if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
38283
38834
  } catch {
38284
38835
  }
@@ -38590,12 +39141,12 @@ data: ${JSON.stringify(msg.data)}
38590
39141
  }
38591
39142
  }
38592
39143
  }
38593
- var fs13, path20, os20;
39144
+ var fs13, path21, os20;
38594
39145
  var init_dev_auto_implement = __esm({
38595
39146
  "../../oss/packages/daemon-core/src/daemon/dev-auto-implement.ts"() {
38596
39147
  "use strict";
38597
39148
  fs13 = __toESM(require("fs"));
38598
- path20 = __toESM(require("path"));
39149
+ path21 = __toESM(require("path"));
38599
39150
  os20 = __toESM(require("os"));
38600
39151
  init_dev_server();
38601
39152
  init_dev_cli_debug();
@@ -38635,13 +39186,14 @@ function toProviderListEntry(provider) {
38635
39186
  }
38636
39187
  return base;
38637
39188
  }
38638
- var http2, fs14, path21, DEV_SERVER_PORT, DevServer;
39189
+ var http2, fs14, path23, DEV_SERVER_PORT, DevServer;
38639
39190
  var init_dev_server = __esm({
38640
39191
  "../../oss/packages/daemon-core/src/daemon/dev-server.ts"() {
38641
39192
  "use strict";
38642
39193
  http2 = __toESM(require("http"));
38643
39194
  fs14 = __toESM(require("fs"));
38644
- path21 = __toESM(require("path"));
39195
+ path23 = __toESM(require("path"));
39196
+ init_provider_schema();
38645
39197
  init_scaffold_template();
38646
39198
  init_version_archive();
38647
39199
  init_logger();
@@ -38746,8 +39298,8 @@ var init_dev_server = __esm({
38746
39298
  }
38747
39299
  getEndpointList() {
38748
39300
  return this.routes.map((r) => {
38749
- const path26 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
38750
- return `${r.method.padEnd(5)} ${path26}`;
39301
+ const path28 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
39302
+ return `${r.method.padEnd(5)} ${path28}`;
38751
39303
  });
38752
39304
  }
38753
39305
  async start(port = DEV_SERVER_PORT) {
@@ -39002,12 +39554,12 @@ var init_dev_server = __esm({
39002
39554
  // ─── DevConsole SPA ───
39003
39555
  getConsoleDistDir() {
39004
39556
  const candidates = [
39005
- path21.resolve(__dirname, "../../web-devconsole/dist"),
39006
- path21.resolve(__dirname, "../../../web-devconsole/dist"),
39007
- path21.join(process.cwd(), "packages/web-devconsole/dist")
39557
+ path23.resolve(__dirname, "../../web-devconsole/dist"),
39558
+ path23.resolve(__dirname, "../../../web-devconsole/dist"),
39559
+ path23.join(process.cwd(), "packages/web-devconsole/dist")
39008
39560
  ];
39009
39561
  for (const dir of candidates) {
39010
- if (fs14.existsSync(path21.join(dir, "index.html"))) return dir;
39562
+ if (fs14.existsSync(path23.join(dir, "index.html"))) return dir;
39011
39563
  }
39012
39564
  return null;
39013
39565
  }
@@ -39017,7 +39569,7 @@ var init_dev_server = __esm({
39017
39569
  this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
39018
39570
  return;
39019
39571
  }
39020
- const htmlPath = path21.join(distDir, "index.html");
39572
+ const htmlPath = path23.join(distDir, "index.html");
39021
39573
  try {
39022
39574
  const html = fs14.readFileSync(htmlPath, "utf-8");
39023
39575
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
@@ -39042,15 +39594,15 @@ var init_dev_server = __esm({
39042
39594
  this.json(res, 404, { error: "Not found" });
39043
39595
  return;
39044
39596
  }
39045
- const safePath = path21.normalize(pathname).replace(/^\.\.\//, "");
39046
- const filePath = path21.join(distDir, safePath);
39597
+ const safePath = path23.normalize(pathname).replace(/^\.\.\//, "");
39598
+ const filePath = path23.join(distDir, safePath);
39047
39599
  if (!filePath.startsWith(distDir)) {
39048
39600
  this.json(res, 403, { error: "Forbidden" });
39049
39601
  return;
39050
39602
  }
39051
39603
  try {
39052
39604
  const content = fs14.readFileSync(filePath);
39053
- const ext = path21.extname(filePath);
39605
+ const ext = path23.extname(filePath);
39054
39606
  const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
39055
39607
  res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
39056
39608
  res.end(content);
@@ -39163,9 +39715,9 @@ var init_dev_server = __esm({
39163
39715
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
39164
39716
  if (entry.isDirectory()) {
39165
39717
  files.push({ path: rel, size: 0, type: "dir" });
39166
- scan(path21.join(d, entry.name), rel);
39718
+ scan(path23.join(d, entry.name), rel);
39167
39719
  } else {
39168
- const stat4 = fs14.statSync(path21.join(d, entry.name));
39720
+ const stat4 = fs14.statSync(path23.join(d, entry.name));
39169
39721
  files.push({ path: rel, size: stat4.size, type: "file" });
39170
39722
  }
39171
39723
  }
@@ -39188,7 +39740,7 @@ var init_dev_server = __esm({
39188
39740
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
39189
39741
  return;
39190
39742
  }
39191
- const fullPath = path21.resolve(dir, path21.normalize(filePath));
39743
+ const fullPath = path23.resolve(dir, path23.normalize(filePath));
39192
39744
  if (!fullPath.startsWith(dir)) {
39193
39745
  this.json(res, 403, { error: "Forbidden" });
39194
39746
  return;
@@ -39213,14 +39765,14 @@ var init_dev_server = __esm({
39213
39765
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
39214
39766
  return;
39215
39767
  }
39216
- const fullPath = path21.resolve(dir, path21.normalize(filePath));
39768
+ const fullPath = path23.resolve(dir, path23.normalize(filePath));
39217
39769
  if (!fullPath.startsWith(dir)) {
39218
39770
  this.json(res, 403, { error: "Forbidden" });
39219
39771
  return;
39220
39772
  }
39221
39773
  try {
39222
39774
  if (fs14.existsSync(fullPath)) fs14.copyFileSync(fullPath, fullPath + ".bak");
39223
- fs14.mkdirSync(path21.dirname(fullPath), { recursive: true });
39775
+ fs14.mkdirSync(path23.dirname(fullPath), { recursive: true });
39224
39776
  fs14.writeFileSync(fullPath, content, "utf-8");
39225
39777
  this.log(`File saved: ${fullPath} (${content.length} chars)`);
39226
39778
  this.providerLoader.reload();
@@ -39237,7 +39789,7 @@ var init_dev_server = __esm({
39237
39789
  return;
39238
39790
  }
39239
39791
  for (const name of ["scripts.js", "provider.json"]) {
39240
- const p = path21.join(dir, name);
39792
+ const p = path23.join(dir, name);
39241
39793
  if (fs14.existsSync(p)) {
39242
39794
  const source = fs14.readFileSync(p, "utf-8");
39243
39795
  this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
@@ -39258,8 +39810,8 @@ var init_dev_server = __esm({
39258
39810
  this.json(res, 404, { error: `Provider not found: ${type}` });
39259
39811
  return;
39260
39812
  }
39261
- const target = fs14.existsSync(path21.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
39262
- const targetPath = path21.join(dir, target);
39813
+ const target = fs14.existsSync(path23.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
39814
+ const targetPath = path23.join(dir, target);
39263
39815
  try {
39264
39816
  if (fs14.existsSync(targetPath)) fs14.copyFileSync(targetPath, targetPath + ".bak");
39265
39817
  fs14.writeFileSync(targetPath, source, "utf-8");
@@ -39287,22 +39839,9 @@ var init_dev_server = __esm({
39287
39839
  const warnings = [];
39288
39840
  try {
39289
39841
  const config2 = typeof content === "string" ? JSON.parse(content) : content;
39290
- if (!config2.type) errors.push("Missing required field: type");
39291
- if (!config2.name) errors.push("Missing required field: name");
39292
- if (!config2.category) errors.push("Missing required field: category");
39293
- else if (!["ide", "extension", "cli", "acp"].includes(config2.category)) errors.push(`Invalid category: ${config2.category}`);
39294
- if (config2.category === "ide" || config2.category === "extension") {
39295
- if (!config2.cdpPorts || !Array.isArray(config2.cdpPorts) || config2.cdpPorts.length === 0)
39296
- warnings.push("IDE/Extension providers should have cdpPorts");
39297
- if (config2.category === "extension" && !config2.extensionId)
39298
- warnings.push("Extension providers should have extensionId");
39299
- }
39300
- if (config2.category === "acp" || config2.category === "cli") {
39301
- if (!config2.spawn) errors.push("ACP/CLI providers must have spawn config");
39302
- else {
39303
- if (!config2.spawn.command) errors.push("spawn.command is required");
39304
- }
39305
- }
39842
+ const validation = validateProviderDefinition(config2);
39843
+ errors.push(...validation.errors);
39844
+ warnings.push(...validation.warnings);
39306
39845
  if (config2.settings) {
39307
39846
  for (const [key, val] of Object.entries(config2.settings)) {
39308
39847
  const s = val;
@@ -39419,7 +39958,7 @@ var init_dev_server = __esm({
39419
39958
  }
39420
39959
  let targetDir;
39421
39960
  targetDir = this.providerLoader.getUserProviderDir(category, type);
39422
- const jsonPath = path21.join(targetDir, "provider.json");
39961
+ const jsonPath = path23.join(targetDir, "provider.json");
39423
39962
  if (fs14.existsSync(jsonPath)) {
39424
39963
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
39425
39964
  return;
@@ -39431,8 +39970,8 @@ var init_dev_server = __esm({
39431
39970
  const createdFiles = ["provider.json"];
39432
39971
  if (result.files) {
39433
39972
  for (const [relPath, content] of Object.entries(result.files)) {
39434
- const fullPath = path21.join(targetDir, relPath);
39435
- fs14.mkdirSync(path21.dirname(fullPath), { recursive: true });
39973
+ const fullPath = path23.join(targetDir, relPath);
39974
+ fs14.mkdirSync(path23.dirname(fullPath), { recursive: true });
39436
39975
  fs14.writeFileSync(fullPath, content, "utf-8");
39437
39976
  createdFiles.push(relPath);
39438
39977
  }
@@ -39485,22 +40024,22 @@ var init_dev_server = __esm({
39485
40024
  if (!fs14.existsSync(scriptsDir)) return null;
39486
40025
  const versions = fs14.readdirSync(scriptsDir).filter((d) => {
39487
40026
  try {
39488
- return fs14.statSync(path21.join(scriptsDir, d)).isDirectory();
40027
+ return fs14.statSync(path23.join(scriptsDir, d)).isDirectory();
39489
40028
  } catch {
39490
40029
  return false;
39491
40030
  }
39492
40031
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
39493
40032
  if (versions.length === 0) return null;
39494
- return path21.join(scriptsDir, versions[0]);
40033
+ return path23.join(scriptsDir, versions[0]);
39495
40034
  }
39496
40035
  resolveAutoImplWritableProviderDir(category, type, requestedDir) {
39497
- const canonicalUserDir = path21.resolve(this.providerLoader.getUserProviderDir(category, type));
39498
- const desiredDir = requestedDir ? path21.resolve(requestedDir) : canonicalUserDir;
39499
- const upstreamRoot = path21.resolve(this.providerLoader.getUpstreamDir());
39500
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path21.sep}`)) {
40036
+ const canonicalUserDir = path23.resolve(this.providerLoader.getUserProviderDir(category, type));
40037
+ const desiredDir = requestedDir ? path23.resolve(requestedDir) : canonicalUserDir;
40038
+ const upstreamRoot = path23.resolve(this.providerLoader.getUpstreamDir());
40039
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path23.sep}`)) {
39501
40040
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
39502
40041
  }
39503
- if (path21.basename(desiredDir) !== type) {
40042
+ if (path23.basename(desiredDir) !== type) {
39504
40043
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
39505
40044
  }
39506
40045
  const sourceDir = this.findProviderDir(type);
@@ -39508,11 +40047,11 @@ var init_dev_server = __esm({
39508
40047
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
39509
40048
  }
39510
40049
  if (!fs14.existsSync(desiredDir)) {
39511
- fs14.mkdirSync(path21.dirname(desiredDir), { recursive: true });
40050
+ fs14.mkdirSync(path23.dirname(desiredDir), { recursive: true });
39512
40051
  fs14.cpSync(sourceDir, desiredDir, { recursive: true });
39513
40052
  this.log(`Auto-implement writable copy created: ${desiredDir}`);
39514
40053
  }
39515
- const providerJson = path21.join(desiredDir, "provider.json");
40054
+ const providerJson = path23.join(desiredDir, "provider.json");
39516
40055
  if (!fs14.existsSync(providerJson)) {
39517
40056
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
39518
40057
  }
@@ -39560,7 +40099,7 @@ var init_dev_server = __esm({
39560
40099
  setMode: "set_mode.js"
39561
40100
  };
39562
40101
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
39563
- const scriptsDir = path21.join(providerDir, "scripts");
40102
+ const scriptsDir = path23.join(providerDir, "scripts");
39564
40103
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
39565
40104
  if (latestScriptsDir) {
39566
40105
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -39571,7 +40110,7 @@ var init_dev_server = __esm({
39571
40110
  for (const file2 of fs14.readdirSync(latestScriptsDir)) {
39572
40111
  if (file2.endsWith(".js") && targetFileNames.has(file2)) {
39573
40112
  try {
39574
- const content = fs14.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
40113
+ const content = fs14.readFileSync(path23.join(latestScriptsDir, file2), "utf-8");
39575
40114
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
39576
40115
  lines.push("```javascript");
39577
40116
  lines.push(content);
@@ -39588,7 +40127,7 @@ var init_dev_server = __esm({
39588
40127
  lines.push("");
39589
40128
  for (const file2 of refFiles) {
39590
40129
  try {
39591
- const content = fs14.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
40130
+ const content = fs14.readFileSync(path23.join(latestScriptsDir, file2), "utf-8");
39592
40131
  lines.push(`### \`${file2}\` \u{1F512}`);
39593
40132
  lines.push("```javascript");
39594
40133
  lines.push(content);
@@ -39629,10 +40168,10 @@ var init_dev_server = __esm({
39629
40168
  lines.push("");
39630
40169
  }
39631
40170
  }
39632
- const docsDir = path21.join(providerDir, "../../docs");
40171
+ const docsDir = path23.join(providerDir, "../../docs");
39633
40172
  const loadGuide = (name) => {
39634
40173
  try {
39635
- const p = path21.join(docsDir, name);
40174
+ const p = path23.join(docsDir, name);
39636
40175
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
39637
40176
  } catch {
39638
40177
  }
@@ -39806,7 +40345,7 @@ var init_dev_server = __esm({
39806
40345
  parseApproval: "parse_approval.js"
39807
40346
  };
39808
40347
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
39809
- const scriptsDir = path21.join(providerDir, "scripts");
40348
+ const scriptsDir = path23.join(providerDir, "scripts");
39810
40349
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
39811
40350
  if (latestScriptsDir) {
39812
40351
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -39818,7 +40357,7 @@ var init_dev_server = __esm({
39818
40357
  if (!file2.endsWith(".js")) continue;
39819
40358
  if (!targetFileNames.has(file2)) continue;
39820
40359
  try {
39821
- const content = fs14.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
40360
+ const content = fs14.readFileSync(path23.join(latestScriptsDir, file2), "utf-8");
39822
40361
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
39823
40362
  lines.push("```javascript");
39824
40363
  lines.push(content);
@@ -39834,7 +40373,7 @@ var init_dev_server = __esm({
39834
40373
  lines.push("");
39835
40374
  for (const file2 of refFiles) {
39836
40375
  try {
39837
- const content = fs14.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
40376
+ const content = fs14.readFileSync(path23.join(latestScriptsDir, file2), "utf-8");
39838
40377
  lines.push(`### \`${file2}\` \u{1F512}`);
39839
40378
  lines.push("```javascript");
39840
40379
  lines.push(content);
@@ -39867,10 +40406,10 @@ var init_dev_server = __esm({
39867
40406
  lines.push("");
39868
40407
  }
39869
40408
  }
39870
- const docsDir = path21.join(providerDir, "../../docs");
40409
+ const docsDir = path23.join(providerDir, "../../docs");
39871
40410
  const loadGuide = (name) => {
39872
40411
  try {
39873
- const p = path21.join(docsDir, name);
40412
+ const p = path23.join(docsDir, name);
39874
40413
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
39875
40414
  } catch {
39876
40415
  }
@@ -40594,6 +41133,78 @@ var init_runtime_support = __esm({
40594
41133
  }
40595
41134
  });
40596
41135
 
41136
+ // ../../oss/packages/daemon-core/src/session-host/runtime-surface.ts
41137
+ function isSessionHostLiveRuntime(record2) {
41138
+ const lifecycle = String(record2?.lifecycle || "").trim();
41139
+ return LIVE_LIFECYCLES.has(lifecycle);
41140
+ }
41141
+ function getSessionHostRecoveryLabel(meta3) {
41142
+ const recoveryState = typeof meta3?.runtimeRecoveryState === "string" ? String(meta3.runtimeRecoveryState).trim() : "";
41143
+ if (!recoveryState) return null;
41144
+ if (recoveryState === "auto_resumed") return "restored after restart";
41145
+ if (recoveryState === "resume_failed") return "restore failed";
41146
+ if (recoveryState === "host_restart_interrupted") return "host restart interrupted";
41147
+ if (recoveryState === "orphan_snapshot") return "snapshot recovered";
41148
+ return recoveryState.replace(/_/g, " ");
41149
+ }
41150
+ function isSessionHostRecoverySnapshot(record2) {
41151
+ if (!record2) return false;
41152
+ if (isSessionHostLiveRuntime(record2)) return false;
41153
+ const lifecycle = String(record2.lifecycle || "").trim();
41154
+ if (lifecycle && lifecycle !== "stopped" && lifecycle !== "failed") {
41155
+ return false;
41156
+ }
41157
+ const meta3 = record2.meta || void 0;
41158
+ if (meta3?.restoredFromStorage === true) return true;
41159
+ return getSessionHostRecoveryLabel(meta3) !== null;
41160
+ }
41161
+ function getSessionHostSurfaceKind(record2) {
41162
+ if (isSessionHostLiveRuntime(record2)) return "live_runtime";
41163
+ if (isSessionHostRecoverySnapshot(record2)) return "recovery_snapshot";
41164
+ return "inactive_record";
41165
+ }
41166
+ function partitionSessionHostRecords(records) {
41167
+ const liveRuntimes = [];
41168
+ const recoverySnapshots = [];
41169
+ const inactiveRecords = [];
41170
+ for (const record2 of records) {
41171
+ const kind = getSessionHostSurfaceKind(record2);
41172
+ if (kind === "live_runtime") {
41173
+ liveRuntimes.push(record2);
41174
+ } else if (kind === "recovery_snapshot") {
41175
+ recoverySnapshots.push(record2);
41176
+ } else {
41177
+ inactiveRecords.push(record2);
41178
+ }
41179
+ }
41180
+ return {
41181
+ liveRuntimes,
41182
+ recoverySnapshots,
41183
+ inactiveRecords
41184
+ };
41185
+ }
41186
+ function partitionSessionHostDiagnosticsSessions(records) {
41187
+ return partitionSessionHostRecords(records || []);
41188
+ }
41189
+ var LIVE_LIFECYCLES;
41190
+ var init_runtime_surface = __esm({
41191
+ "../../oss/packages/daemon-core/src/session-host/runtime-surface.ts"() {
41192
+ "use strict";
41193
+ LIVE_LIFECYCLES = /* @__PURE__ */ new Set(["starting", "running", "stopping", "interrupted"]);
41194
+ }
41195
+ });
41196
+
41197
+ // ../../oss/packages/daemon-core/src/session-host/startup-restore-policy.js
41198
+ function shouldAutoRestoreHostedSessionsOnStartup(env = process.env) {
41199
+ const raw = typeof env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP === "string" ? env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP.trim().toLowerCase() : "";
41200
+ return raw === "1" || raw === "true" || raw === "yes";
41201
+ }
41202
+ var init_startup_restore_policy = __esm({
41203
+ "../../oss/packages/daemon-core/src/session-host/startup-restore-policy.js"() {
41204
+ "use strict";
41205
+ }
41206
+ });
41207
+
40597
41208
  // ../../oss/packages/daemon-core/src/installer.ts
40598
41209
  function isExtensionInstalled(ide, marketplaceId) {
40599
41210
  if (!ide.cliCommand) return false;
@@ -40635,8 +41246,8 @@ async function installExtension(ide, extension) {
40635
41246
  const res = await fetch(extension.vsixUrl);
40636
41247
  if (res.ok) {
40637
41248
  const buffer = Buffer.from(await res.arrayBuffer());
40638
- const fs18 = await import("fs");
40639
- fs18.writeFileSync(vsixPath, buffer);
41249
+ const fs19 = await import("fs");
41250
+ fs19.writeFileSync(vsixPath, buffer);
40640
41251
  return new Promise((resolve16) => {
40641
41252
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
40642
41253
  (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
@@ -41133,6 +41744,7 @@ __export(src_exports, {
41133
41744
  detectIDEs: () => detectIDEs,
41134
41745
  ensureSessionHostReady: () => ensureSessionHostReady,
41135
41746
  findCdpManager: () => findCdpManager,
41747
+ flattenMessageParts: () => flattenMessageParts,
41136
41748
  forwardAgentStreamsToIdeInstance: () => forwardAgentStreamsToIdeInstance,
41137
41749
  getAIExtensions: () => getAIExtensions,
41138
41750
  getAvailableIdeIds: () => getAvailableIdeIds,
@@ -41146,6 +41758,8 @@ __export(src_exports, {
41146
41758
  getRecentDebugTrace: () => getRecentDebugTrace,
41147
41759
  getRecentLogs: () => getRecentLogs,
41148
41760
  getSavedProviderSessions: () => getSavedProviderSessions,
41761
+ getSessionHostRecoveryLabel: () => getSessionHostRecoveryLabel,
41762
+ getSessionHostSurfaceKind: () => getSessionHostSurfaceKind,
41149
41763
  getWorkspaceState: () => getWorkspaceState,
41150
41764
  hasCdpManager: () => hasCdpManager,
41151
41765
  initDaemonComponents: () => initDaemonComponents,
@@ -41156,6 +41770,8 @@ __export(src_exports, {
41156
41770
  isIdeRunning: () => isIdeRunning,
41157
41771
  isManagedStatusWaiting: () => isManagedStatusWaiting,
41158
41772
  isManagedStatusWorking: () => isManagedStatusWorking,
41773
+ isSessionHostLiveRuntime: () => isSessionHostLiveRuntime,
41774
+ isSessionHostRecoverySnapshot: () => isSessionHostRecoverySnapshot,
41159
41775
  isSetupComplete: () => isSetupComplete,
41160
41776
  killIdeProcess: () => killIdeProcess,
41161
41777
  launchIDE: () => launchIDE,
@@ -41167,7 +41783,11 @@ __export(src_exports, {
41167
41783
  markSetupComplete: () => markSetupComplete,
41168
41784
  maybeRunDaemonUpgradeHelperFromEnv: () => maybeRunDaemonUpgradeHelperFromEnv,
41169
41785
  normalizeActiveChatData: () => normalizeActiveChatData,
41786
+ normalizeInputEnvelope: () => normalizeInputEnvelope,
41170
41787
  normalizeManagedStatus: () => normalizeManagedStatus,
41788
+ normalizeMessageParts: () => normalizeMessageParts,
41789
+ partitionSessionHostDiagnosticsSessions: () => partitionSessionHostDiagnosticsSessions,
41790
+ partitionSessionHostRecords: () => partitionSessionHostRecords,
41171
41791
  probeCdpPort: () => probeCdpPort,
41172
41792
  readChatHistory: () => readChatHistory,
41173
41793
  recordDebugTrace: () => recordDebugTrace,
@@ -41182,6 +41802,7 @@ __export(src_exports, {
41182
41802
  setDebugRuntimeConfig: () => setDebugRuntimeConfig,
41183
41803
  setLogLevel: () => setLogLevel,
41184
41804
  setupIdeInstance: () => setupIdeInstance,
41805
+ shouldAutoRestoreHostedSessionsOnStartup: () => shouldAutoRestoreHostedSessionsOnStartup,
41185
41806
  shouldCollectTraceCategory: () => shouldCollectTraceCategory,
41186
41807
  shutdownDaemonComponents: () => shutdownDaemonComponents,
41187
41808
  spawnDetachedDaemonUpgradeHelper: () => spawnDetachedDaemonUpgradeHelper,
@@ -41228,6 +41849,7 @@ var init_src = __esm({
41228
41849
  init_ide_provider_instance();
41229
41850
  init_cli_provider_instance();
41230
41851
  init_acp_provider_instance();
41852
+ init_io_contracts();
41231
41853
  init_version_archive();
41232
41854
  init_dev_server();
41233
41855
  init_provider_cli_adapter();
@@ -41235,6 +41857,8 @@ var init_src = __esm({
41235
41857
  init_session_host_transport();
41236
41858
  init_app_name();
41237
41859
  init_runtime_support();
41860
+ init_runtime_surface();
41861
+ init_startup_restore_policy();
41238
41862
  init_installer();
41239
41863
  init_daemon_lifecycle();
41240
41864
  }
@@ -42278,12 +42902,12 @@ var init_peer_connection_manager = __esm({
42278
42902
  });
42279
42903
 
42280
42904
  // src/daemon-p2p/index.ts
42281
- var fs15, path23, import_node_module2, esmRequire, DaemonP2PSender;
42905
+ var fs15, path24, import_node_module2, esmRequire, DaemonP2PSender;
42282
42906
  var init_daemon_p2p = __esm({
42283
42907
  "src/daemon-p2p/index.ts"() {
42284
42908
  "use strict";
42285
42909
  fs15 = __toESM(require("fs"));
42286
- path23 = __toESM(require("path"));
42910
+ path24 = __toESM(require("path"));
42287
42911
  import_node_module2 = require("module");
42288
42912
  init_data_channel_router();
42289
42913
  init_screenshot_sender();
@@ -42356,15 +42980,15 @@ ${e?.stack || ""}`);
42356
42980
  const prebuildKey = `${platform12}-${arch3}`;
42357
42981
  try {
42358
42982
  const candidates = [
42359
- path23.join(__dirname, "node_modules", "node-datachannel"),
42360
- path23.join(__dirname, "..", "node_modules", "node-datachannel"),
42361
- path23.join(__dirname, "..", "..", "node_modules", "node-datachannel")
42983
+ path24.join(__dirname, "node_modules", "node-datachannel"),
42984
+ path24.join(__dirname, "..", "node_modules", "node-datachannel"),
42985
+ path24.join(__dirname, "..", "..", "node_modules", "node-datachannel")
42362
42986
  ];
42363
42987
  for (const candidate of candidates) {
42364
- const prebuildPath = path23.join(candidate, "prebuilds", prebuildKey, "node_datachannel.node");
42988
+ const prebuildPath = path24.join(candidate, "prebuilds", prebuildKey, "node_datachannel.node");
42365
42989
  if (fs15.existsSync(prebuildPath)) {
42366
- const targetDir = path23.join(candidate, "build", "Release");
42367
- const targetPath = path23.join(targetDir, "node_datachannel.node");
42990
+ const targetDir = path24.join(candidate, "build", "Release");
42991
+ const targetPath = path24.join(targetDir, "node_datachannel.node");
42368
42992
  fs15.mkdirSync(targetDir, { recursive: true });
42369
42993
  fs15.copyFileSync(prebuildPath, targetPath);
42370
42994
  try {
@@ -42682,27 +43306,27 @@ var require_process = __commonJS({
42682
43306
  var require_filesystem = __commonJS({
42683
43307
  "../../node_modules/detect-libc/lib/filesystem.js"(exports2, module2) {
42684
43308
  "use strict";
42685
- var fs18 = require("fs");
43309
+ var fs19 = require("fs");
42686
43310
  var LDD_PATH = "/usr/bin/ldd";
42687
43311
  var SELF_PATH = "/proc/self/exe";
42688
43312
  var MAX_LENGTH = 2048;
42689
- var readFileSync17 = (path26) => {
42690
- const fd = fs18.openSync(path26, "r");
43313
+ var readFileSync18 = (path28) => {
43314
+ const fd = fs19.openSync(path28, "r");
42691
43315
  const buffer = Buffer.alloc(MAX_LENGTH);
42692
- const bytesRead = fs18.readSync(fd, buffer, 0, MAX_LENGTH, 0);
42693
- fs18.close(fd, () => {
43316
+ const bytesRead = fs19.readSync(fd, buffer, 0, MAX_LENGTH, 0);
43317
+ fs19.close(fd, () => {
42694
43318
  });
42695
43319
  return buffer.subarray(0, bytesRead);
42696
43320
  };
42697
- var readFile = (path26) => new Promise((resolve16, reject) => {
42698
- fs18.open(path26, "r", (err, fd) => {
43321
+ var readFile = (path28) => new Promise((resolve16, reject) => {
43322
+ fs19.open(path28, "r", (err, fd) => {
42699
43323
  if (err) {
42700
43324
  reject(err);
42701
43325
  } else {
42702
43326
  const buffer = Buffer.alloc(MAX_LENGTH);
42703
- fs18.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
43327
+ fs19.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
42704
43328
  resolve16(buffer.subarray(0, bytesRead));
42705
- fs18.close(fd, () => {
43329
+ fs19.close(fd, () => {
42706
43330
  });
42707
43331
  });
42708
43332
  }
@@ -42711,7 +43335,7 @@ var require_filesystem = __commonJS({
42711
43335
  module2.exports = {
42712
43336
  LDD_PATH,
42713
43337
  SELF_PATH,
42714
- readFileSync: readFileSync17,
43338
+ readFileSync: readFileSync18,
42715
43339
  readFile
42716
43340
  };
42717
43341
  }
@@ -42760,7 +43384,7 @@ var require_detect_libc = __commonJS({
42760
43384
  "use strict";
42761
43385
  var childProcess = require("child_process");
42762
43386
  var { isLinux: isLinux2, getReport } = require_process();
42763
- var { LDD_PATH, SELF_PATH, readFile, readFileSync: readFileSync17 } = require_filesystem();
43387
+ var { LDD_PATH, SELF_PATH, readFile, readFileSync: readFileSync18 } = require_filesystem();
42764
43388
  var { interpreterPath } = require_elf();
42765
43389
  var cachedFamilyInterpreter;
42766
43390
  var cachedFamilyFilesystem;
@@ -42814,11 +43438,11 @@ var require_detect_libc = __commonJS({
42814
43438
  }
42815
43439
  return null;
42816
43440
  };
42817
- var familyFromInterpreterPath = (path26) => {
42818
- if (path26) {
42819
- if (path26.includes("/ld-musl-")) {
43441
+ var familyFromInterpreterPath = (path28) => {
43442
+ if (path28) {
43443
+ if (path28.includes("/ld-musl-")) {
42820
43444
  return MUSL;
42821
- } else if (path26.includes("/ld-linux-")) {
43445
+ } else if (path28.includes("/ld-linux-")) {
42822
43446
  return GLIBC;
42823
43447
  }
42824
43448
  }
@@ -42852,7 +43476,7 @@ var require_detect_libc = __commonJS({
42852
43476
  }
42853
43477
  cachedFamilyFilesystem = null;
42854
43478
  try {
42855
- const lddContent = readFileSync17(LDD_PATH);
43479
+ const lddContent = readFileSync18(LDD_PATH);
42856
43480
  cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
42857
43481
  } catch (e) {
42858
43482
  }
@@ -42865,8 +43489,8 @@ var require_detect_libc = __commonJS({
42865
43489
  cachedFamilyInterpreter = null;
42866
43490
  try {
42867
43491
  const selfContent = await readFile(SELF_PATH);
42868
- const path26 = interpreterPath(selfContent);
42869
- cachedFamilyInterpreter = familyFromInterpreterPath(path26);
43492
+ const path28 = interpreterPath(selfContent);
43493
+ cachedFamilyInterpreter = familyFromInterpreterPath(path28);
42870
43494
  } catch (e) {
42871
43495
  }
42872
43496
  return cachedFamilyInterpreter;
@@ -42877,9 +43501,9 @@ var require_detect_libc = __commonJS({
42877
43501
  }
42878
43502
  cachedFamilyInterpreter = null;
42879
43503
  try {
42880
- const selfContent = readFileSync17(SELF_PATH);
42881
- const path26 = interpreterPath(selfContent);
42882
- cachedFamilyInterpreter = familyFromInterpreterPath(path26);
43504
+ const selfContent = readFileSync18(SELF_PATH);
43505
+ const path28 = interpreterPath(selfContent);
43506
+ cachedFamilyInterpreter = familyFromInterpreterPath(path28);
42883
43507
  } catch (e) {
42884
43508
  }
42885
43509
  return cachedFamilyInterpreter;
@@ -42941,7 +43565,7 @@ var require_detect_libc = __commonJS({
42941
43565
  }
42942
43566
  cachedVersionFilesystem = null;
42943
43567
  try {
42944
- const lddContent = readFileSync17(LDD_PATH);
43568
+ const lddContent = readFileSync18(LDD_PATH);
42945
43569
  const versionMatch = lddContent.match(RE_GLIBC_VERSION);
42946
43570
  if (versionMatch) {
42947
43571
  cachedVersionFilesystem = versionMatch[1];
@@ -44598,18 +45222,18 @@ var require_sharp = __commonJS({
44598
45222
  `@img/sharp-${runtimePlatform}/sharp.node`,
44599
45223
  "@img/sharp-wasm32/sharp.node"
44600
45224
  ];
44601
- var path26;
45225
+ var path28;
44602
45226
  var sharp;
44603
45227
  var errors = [];
44604
- for (path26 of paths) {
45228
+ for (path28 of paths) {
44605
45229
  try {
44606
- sharp = require(path26);
45230
+ sharp = require(path28);
44607
45231
  break;
44608
45232
  } catch (err) {
44609
45233
  errors.push(err);
44610
45234
  }
44611
45235
  }
44612
- if (sharp && path26.startsWith("@img/sharp-linux-x64") && !sharp._isUsingX64V2()) {
45236
+ if (sharp && path28.startsWith("@img/sharp-linux-x64") && !sharp._isUsingX64V2()) {
44613
45237
  const err = new Error("Prebuilt binaries for linux-x64 require v2 microarchitecture");
44614
45238
  err.code = "Unsupported CPU";
44615
45239
  errors.push(err);
@@ -44618,7 +45242,7 @@ var require_sharp = __commonJS({
44618
45242
  if (sharp) {
44619
45243
  module2.exports = sharp;
44620
45244
  } else {
44621
- const [isLinux2, isMacOs, isWindows2] = ["linux", "darwin", "win32"].map((os24) => runtimePlatform.startsWith(os24));
45245
+ const [isLinux2, isMacOs, isWindows2] = ["linux", "darwin", "win32"].map((os25) => runtimePlatform.startsWith(os25));
44622
45246
  const help = [`Could not load the "sharp" module using the ${runtimePlatform} runtime`];
44623
45247
  errors.forEach((err) => {
44624
45248
  if (err.code !== "MODULE_NOT_FOUND") {
@@ -44635,15 +45259,15 @@ var require_sharp = __commonJS({
44635
45259
  ` Requires ${expected}`
44636
45260
  );
44637
45261
  } else if (prebuiltPlatforms.includes(runtimePlatform)) {
44638
- const [os24, cpu] = runtimePlatform.split("-");
44639
- const libc = os24.endsWith("musl") ? " --libc=musl" : "";
45262
+ const [os25, cpu] = runtimePlatform.split("-");
45263
+ const libc = os25.endsWith("musl") ? " --libc=musl" : "";
44640
45264
  help.push(
44641
45265
  "- Ensure optional dependencies can be installed:",
44642
45266
  " npm install --include=optional sharp",
44643
45267
  "- Ensure your package manager supports multi-platform installation:",
44644
45268
  " See https://sharp.pixelplumbing.com/install#cross-platform",
44645
45269
  "- Add platform-specific dependencies:",
44646
- ` npm install --os=${os24.replace("musl", "")}${libc} --cpu=${cpu} sharp`
45270
+ ` npm install --os=${os25.replace("musl", "")}${libc} --cpu=${cpu} sharp`
44647
45271
  );
44648
45272
  } else {
44649
45273
  help.push(
@@ -47518,15 +48142,15 @@ var require_color = __commonJS({
47518
48142
  };
47519
48143
  }
47520
48144
  function wrapConversion(toModel, graph) {
47521
- const path26 = [graph[toModel].parent, toModel];
48145
+ const path28 = [graph[toModel].parent, toModel];
47522
48146
  let fn = conversions_default[graph[toModel].parent][toModel];
47523
48147
  let cur = graph[toModel].parent;
47524
48148
  while (graph[cur].parent) {
47525
- path26.unshift(graph[cur].parent);
48149
+ path28.unshift(graph[cur].parent);
47526
48150
  fn = link(conversions_default[graph[cur].parent][cur], fn);
47527
48151
  cur = graph[cur].parent;
47528
48152
  }
47529
- fn.conversion = path26;
48153
+ fn.conversion = path28;
47530
48154
  return fn;
47531
48155
  }
47532
48156
  function route(fromModel) {
@@ -48143,7 +48767,7 @@ var require_channel = __commonJS({
48143
48767
  var require_output = __commonJS({
48144
48768
  "../../node_modules/sharp/lib/output.js"(exports2, module2) {
48145
48769
  "use strict";
48146
- var path26 = require("path");
48770
+ var path28 = require("path");
48147
48771
  var is = require_is();
48148
48772
  var sharp = require_sharp();
48149
48773
  var formats = /* @__PURE__ */ new Map([
@@ -48174,9 +48798,9 @@ var require_output = __commonJS({
48174
48798
  let err;
48175
48799
  if (!is.string(fileOut)) {
48176
48800
  err = new Error("Missing output file path");
48177
- } else if (is.string(this.options.input.file) && path26.resolve(this.options.input.file) === path26.resolve(fileOut)) {
48801
+ } else if (is.string(this.options.input.file) && path28.resolve(this.options.input.file) === path28.resolve(fileOut)) {
48178
48802
  err = new Error("Cannot use same file for input and output");
48179
- } else if (jp2Regex.test(path26.extname(fileOut)) && !this.constructor.format.jp2k.output.file) {
48803
+ } else if (jp2Regex.test(path28.extname(fileOut)) && !this.constructor.format.jp2k.output.file) {
48180
48804
  err = errJp2Save();
48181
48805
  }
48182
48806
  if (err) {
@@ -49373,6 +49997,98 @@ var init_screenshot_controller = __esm({
49373
49997
  }
49374
49998
  });
49375
49999
 
50000
+ // src/session-host-hygiene.ts
50001
+ function formatTimestamp(date5) {
50002
+ const pad = (value) => String(value).padStart(2, "0");
50003
+ return [
50004
+ date5.getUTCFullYear(),
50005
+ pad(date5.getUTCMonth() + 1),
50006
+ pad(date5.getUTCDate()),
50007
+ "-",
50008
+ pad(date5.getUTCHours()),
50009
+ pad(date5.getUTCMinutes()),
50010
+ pad(date5.getUTCSeconds())
50011
+ ].join("");
50012
+ }
50013
+ function defaultPidRunning(pid) {
50014
+ try {
50015
+ process.kill(pid, 0);
50016
+ return true;
50017
+ } catch {
50018
+ return false;
50019
+ }
50020
+ }
50021
+ function shouldSkipForExplicitOverride(env) {
50022
+ const explicit = typeof env?.ADHDEV_SESSION_HOST_NAME === "string" ? env.ADHDEV_SESSION_HOST_NAME.trim() : "";
50023
+ return explicit.length > 0;
50024
+ }
50025
+ function isActiveStandaloneRecord(record2, isPidRunning) {
50026
+ const managerTag = typeof record2?.meta?.managedBy === "string" ? record2.meta.managedBy.trim() : "";
50027
+ if (managerTag !== LEGACY_STANDALONE_MANAGER_TAG) return false;
50028
+ const lifecycle = typeof record2?.lifecycle === "string" ? record2.lifecycle.trim() : "";
50029
+ const pid = Number(record2?.osPid);
50030
+ if (!Number.isFinite(pid) || pid <= 0) return false;
50031
+ if (lifecycle !== "running" && lifecycle !== "starting" && lifecycle !== "interrupted") return false;
50032
+ return isPidRunning(pid);
50033
+ }
50034
+ function quarantineLegacyStandaloneSessions(options) {
50035
+ const env = options.env || process.env;
50036
+ if (options.appName !== DEFAULT_SESSION_HOST_APP_NAME) {
50037
+ return { movedCount: 0, skippedActiveCount: 0, backupDir: null };
50038
+ }
50039
+ if (shouldSkipForExplicitOverride(env)) {
50040
+ return { movedCount: 0, skippedActiveCount: 0, backupDir: null };
50041
+ }
50042
+ const homeDir = options.homeDir || os21.homedir();
50043
+ const now = options.now || (() => /* @__PURE__ */ new Date());
50044
+ const isPidRunning = options.isPidRunning || defaultPidRunning;
50045
+ const runtimesDir = path25.join(homeDir, ".adhdev", "session-host", options.appName, "runtimes");
50046
+ if (!fs16.existsSync(runtimesDir)) {
50047
+ return { movedCount: 0, skippedActiveCount: 0, backupDir: null };
50048
+ }
50049
+ const candidates = fs16.readdirSync(runtimesDir).filter((name) => name.endsWith(".json")).map((name) => path25.join(runtimesDir, name));
50050
+ let movedCount = 0;
50051
+ let skippedActiveCount = 0;
50052
+ let backupDir = null;
50053
+ for (const sourcePath of candidates) {
50054
+ let parsed;
50055
+ try {
50056
+ parsed = JSON.parse(fs16.readFileSync(sourcePath, "utf8"));
50057
+ } catch {
50058
+ continue;
50059
+ }
50060
+ const managerTag = typeof parsed?.meta?.managedBy === "string" ? parsed.meta.managedBy.trim() : "";
50061
+ if (managerTag !== LEGACY_STANDALONE_MANAGER_TAG) continue;
50062
+ if (isActiveStandaloneRecord(parsed, isPidRunning)) {
50063
+ skippedActiveCount += 1;
50064
+ continue;
50065
+ }
50066
+ if (!backupDir) {
50067
+ backupDir = path25.join(
50068
+ homeDir,
50069
+ ".adhdev",
50070
+ "session-host-backups",
50071
+ `legacy-standalone-${options.appName}-${formatTimestamp(now())}`
50072
+ );
50073
+ fs16.mkdirSync(path25.join(backupDir, "runtimes"), { recursive: true });
50074
+ }
50075
+ fs16.renameSync(sourcePath, path25.join(backupDir, "runtimes", path25.basename(sourcePath)));
50076
+ movedCount += 1;
50077
+ }
50078
+ return { movedCount, skippedActiveCount, backupDir };
50079
+ }
50080
+ var fs16, os21, path25, LEGACY_STANDALONE_MANAGER_TAG;
50081
+ var init_session_host_hygiene = __esm({
50082
+ "src/session-host-hygiene.ts"() {
50083
+ "use strict";
50084
+ fs16 = __toESM(require("fs"));
50085
+ os21 = __toESM(require("os"));
50086
+ path25 = __toESM(require("path"));
50087
+ init_src();
50088
+ LEGACY_STANDALONE_MANAGER_TAG = "adhdev-standalone";
50089
+ }
50090
+ });
50091
+
49376
50092
  // src/session-host.ts
49377
50093
  function buildSessionHostEnv(baseEnv) {
49378
50094
  const env = sanitizeSpawnEnv(baseEnv);
@@ -49381,18 +50097,18 @@ function buildSessionHostEnv(baseEnv) {
49381
50097
  }
49382
50098
  function resolveSessionHostEntry() {
49383
50099
  const packagedCandidates = [
49384
- path24.resolve(__dirname, "../vendor/session-host-daemon/index.js"),
49385
- path24.resolve(__dirname, "../../vendor/session-host-daemon/index.js")
50100
+ path26.resolve(__dirname, "../vendor/session-host-daemon/index.js"),
50101
+ path26.resolve(__dirname, "../../vendor/session-host-daemon/index.js")
49386
50102
  ];
49387
50103
  for (const candidate of packagedCandidates) {
49388
- if (fs16.existsSync(candidate)) {
50104
+ if (fs17.existsSync(candidate)) {
49389
50105
  return candidate;
49390
50106
  }
49391
50107
  }
49392
50108
  return require.resolve("@adhdev/session-host-daemon");
49393
50109
  }
49394
50110
  function getSessionHostPidFile() {
49395
- return path24.join(os21.homedir(), ".adhdev", `${SESSION_HOST_APP_NAME}-session-host.pid`);
50111
+ return path26.join(os23.homedir(), ".adhdev", `${SESSION_HOST_APP_NAME}-session-host.pid`);
49396
50112
  }
49397
50113
  function killPid2(pid) {
49398
50114
  try {
@@ -49435,12 +50151,12 @@ function getWindowsProcessCommandLine(pid) {
49435
50151
  }
49436
50152
  return null;
49437
50153
  }
49438
- function stopSessionHost() {
50154
+ function stopManagedSessionHostProcess() {
49439
50155
  let stopped = false;
49440
50156
  const pidFile = getSessionHostPidFile();
49441
50157
  try {
49442
- if (fs16.existsSync(pidFile)) {
49443
- const pid = Number.parseInt(fs16.readFileSync(pidFile, "utf8").trim(), 10);
50158
+ if (fs17.existsSync(pidFile)) {
50159
+ const pid = Number.parseInt(fs17.readFileSync(pidFile, "utf8").trim(), 10);
49444
50160
  if (Number.isFinite(pid) && pid !== process.pid) {
49445
50161
  stopped = killPid2(pid) || stopped;
49446
50162
  }
@@ -49448,10 +50164,14 @@ function stopSessionHost() {
49448
50164
  } catch {
49449
50165
  } finally {
49450
50166
  try {
49451
- fs16.unlinkSync(pidFile);
50167
+ fs17.unlinkSync(pidFile);
49452
50168
  } catch {
49453
50169
  }
49454
50170
  }
50171
+ return stopped;
50172
+ }
50173
+ function stopSessionHost() {
50174
+ let stopped = stopManagedSessionHostProcess();
49455
50175
  if (process.platform === "win32") {
49456
50176
  try {
49457
50177
  const raw = (0, import_child_process11.execFileSync)("tasklist", ["/FO", "CSV", "/NH", "/FI", "IMAGENAME eq node.exe"], {
@@ -49487,11 +50207,27 @@ function stopSessionHost() {
49487
50207
  return stopped;
49488
50208
  }
49489
50209
  async function ensureSessionHostReady2() {
50210
+ const quarantine = quarantineLegacyStandaloneSessions({
50211
+ appName: SESSION_HOST_APP_NAME,
50212
+ env: process.env
50213
+ });
50214
+ if (quarantine.movedCount > 0) {
50215
+ LOG.warn(
50216
+ "SessionHost",
50217
+ `quarantined ${quarantine.movedCount} legacy standalone runtime file(s) from ${SESSION_HOST_APP_NAME}` + (quarantine.backupDir ? ` \u2192 ${quarantine.backupDir}` : "")
50218
+ );
50219
+ }
50220
+ if (quarantine.skippedActiveCount > 0) {
50221
+ LOG.warn(
50222
+ "SessionHost",
50223
+ `detected ${quarantine.skippedActiveCount} active standalone runtime(s) still using the ${SESSION_HOST_APP_NAME} namespace; leaving them untouched`
50224
+ );
50225
+ }
49490
50226
  const spawnHost = () => {
49491
50227
  const entry = resolveSessionHostEntry();
49492
- const logDir = path24.join(os21.homedir(), ".adhdev", "logs");
49493
- fs16.mkdirSync(logDir, { recursive: true });
49494
- const logFd = fs16.openSync(path24.join(logDir, "session-host.log"), "a");
50228
+ const logDir = path26.join(os23.homedir(), ".adhdev", "logs");
50229
+ fs17.mkdirSync(logDir, { recursive: true });
50230
+ const logFd = fs17.openSync(path26.join(logDir, "session-host.log"), "a");
49495
50231
  const child = (0, import_child_process11.spawn)(process.execPath, [entry], {
49496
50232
  detached: true,
49497
50233
  stdio: ["ignore", logFd, logFd],
@@ -49500,7 +50236,7 @@ async function ensureSessionHostReady2() {
49500
50236
  });
49501
50237
  child.unref();
49502
50238
  try {
49503
- fs16.closeSync(logFd);
50239
+ fs17.closeSync(logFd);
49504
50240
  } catch {
49505
50241
  }
49506
50242
  };
@@ -49526,17 +50262,18 @@ async function ensureSessionHostReady2() {
49526
50262
  async function listHostedCliRuntimes2(endpoint) {
49527
50263
  return listHostedCliRuntimes(endpoint);
49528
50264
  }
49529
- var import_child_process11, fs16, os21, path24, SESSION_HOST_APP_NAME, SESSION_HOST_START_TIMEOUT_MS;
50265
+ var import_child_process11, fs17, os23, path26, SESSION_HOST_APP_NAME, SESSION_HOST_START_TIMEOUT_MS;
49530
50266
  var init_session_host = __esm({
49531
50267
  "src/session-host.ts"() {
49532
50268
  "use strict";
49533
50269
  import_child_process11 = require("child_process");
49534
- fs16 = __toESM(require("fs"));
49535
- os21 = __toESM(require("os"));
49536
- path24 = __toESM(require("path"));
50270
+ fs17 = __toESM(require("fs"));
50271
+ os23 = __toESM(require("os"));
50272
+ path26 = __toESM(require("path"));
49537
50273
  init_src();
49538
50274
  init_dist();
49539
- SESSION_HOST_APP_NAME = process.env.ADHDEV_SESSION_HOST_NAME || "adhdev";
50275
+ init_session_host_hygiene();
50276
+ SESSION_HOST_APP_NAME = process.env.ADHDEV_SESSION_HOST_NAME || DEFAULT_SESSION_HOST_APP_NAME;
49540
50277
  SESSION_HOST_START_TIMEOUT_MS = 15e3;
49541
50278
  }
49542
50279
  });
@@ -49769,31 +50506,36 @@ function buildSessionModalDeliverySignature(payload) {
49769
50506
  Array.isArray(payload.modalButtons) ? payload.modalButtons.join("") : ""
49770
50507
  ]);
49771
50508
  }
49772
- function getDaemonPidFile() {
49773
- const dir = path25.join(os23.homedir(), ".adhdev");
49774
- if (!fs17.existsSync(dir)) fs17.mkdirSync(dir, { recursive: true });
49775
- return path25.join(dir, "daemon.pid");
50509
+ function resolveDaemonPort(ref = {}) {
50510
+ return Number.isFinite(ref.port) && Number(ref.port) > 0 ? Number(ref.port) : DEFAULT_DAEMON_PORT;
50511
+ }
50512
+ function getDaemonPidFile(ref = {}) {
50513
+ const dir = path27.join(ref.homeDir || os24.homedir(), ".adhdev");
50514
+ if (!fs18.existsSync(dir)) fs18.mkdirSync(dir, { recursive: true });
50515
+ const port = resolveDaemonPort(ref);
50516
+ return path27.join(dir, port === DEFAULT_DAEMON_PORT ? "daemon.pid" : `daemon-${port}.pid`);
49776
50517
  }
49777
- function writeDaemonPid(pid) {
49778
- const pidFile = getDaemonPidFile();
50518
+ function writeDaemonPid(pid, ref = {}) {
50519
+ const pidFile = getDaemonPidFile(ref);
49779
50520
  try {
49780
- fs17.writeFileSync(pidFile, String(pid), { encoding: "utf-8", flag: "wx" });
50521
+ fs18.writeFileSync(pidFile, String(pid), { encoding: "utf-8", flag: "wx" });
49781
50522
  } catch {
49782
- fs17.writeFileSync(pidFile, String(pid), "utf-8");
50523
+ fs18.writeFileSync(pidFile, String(pid), "utf-8");
49783
50524
  }
49784
50525
  }
49785
- function removeDaemonPid() {
50526
+ function removeDaemonPid(ref = {}) {
49786
50527
  try {
49787
- fs17.unlinkSync(getDaemonPidFile());
50528
+ fs18.unlinkSync(getDaemonPidFile(ref));
49788
50529
  } catch (e) {
49789
50530
  }
49790
50531
  }
49791
- function isDaemonRunning() {
50532
+ function isDaemonRunning(ref = {}) {
50533
+ const port = resolveDaemonPort(ref);
49792
50534
  try {
49793
50535
  const { execFileSync: execFileSync3 } = require("child_process");
49794
50536
  const probe = `
49795
50537
  const http = require('http');
49796
- const req = http.get('http://127.0.0.1:${DEFAULT_DAEMON_PORT}/health', { timeout: 1500 }, (res) => {
50538
+ const req = http.get('http://127.0.0.1:${port}/health', { timeout: 1500 }, (res) => {
49797
50539
  process.stdout.write(String(res.statusCode));
49798
50540
  res.resume();
49799
50541
  });
@@ -49808,18 +50550,18 @@ function isDaemonRunning() {
49808
50550
  if (result === "200") return true;
49809
50551
  } catch {
49810
50552
  }
49811
- const pidFile = getDaemonPidFile();
50553
+ const pidFile = getDaemonPidFile(ref);
49812
50554
  try {
49813
- if (!fs17.existsSync(pidFile)) return false;
49814
- const pid = parseInt(fs17.readFileSync(pidFile, "utf-8").trim());
50555
+ if (!fs18.existsSync(pidFile)) return false;
50556
+ const pid = parseInt(fs18.readFileSync(pidFile, "utf-8").trim());
49815
50557
  process.kill(pid, 0);
49816
50558
  if (!isAdhdevProcess(pid)) {
49817
- removeDaemonPid();
50559
+ removeDaemonPid(ref);
49818
50560
  return false;
49819
50561
  }
49820
50562
  return true;
49821
50563
  } catch {
49822
- removeDaemonPid();
50564
+ removeDaemonPid(ref);
49823
50565
  return false;
49824
50566
  }
49825
50567
  }
@@ -49853,30 +50595,30 @@ function isAdhdevProcess(pid) {
49853
50595
  return true;
49854
50596
  }
49855
50597
  }
49856
- function getDaemonPid() {
49857
- const pidFile = getDaemonPidFile();
50598
+ function getDaemonPid(ref = {}) {
50599
+ const pidFile = getDaemonPidFile(ref);
49858
50600
  try {
49859
- if (!fs17.existsSync(pidFile)) return null;
49860
- const pid = parseInt(fs17.readFileSync(pidFile, "utf-8").trim(), 10);
50601
+ if (!fs18.existsSync(pidFile)) return null;
50602
+ const pid = parseInt(fs18.readFileSync(pidFile, "utf-8").trim(), 10);
49861
50603
  return Number.isFinite(pid) ? pid : null;
49862
50604
  } catch {
49863
50605
  return null;
49864
50606
  }
49865
50607
  }
49866
- function stopDaemon() {
49867
- const pidFile = getDaemonPidFile();
50608
+ function stopDaemon(ref = {}) {
50609
+ const pidFile = getDaemonPidFile(ref);
49868
50610
  try {
49869
- if (!fs17.existsSync(pidFile)) return false;
49870
- const pid = parseInt(fs17.readFileSync(pidFile, "utf-8").trim());
50611
+ if (!fs18.existsSync(pidFile)) return false;
50612
+ const pid = parseInt(fs18.readFileSync(pidFile, "utf-8").trim());
49871
50613
  process.kill(pid, "SIGTERM");
49872
- removeDaemonPid();
50614
+ removeDaemonPid(ref);
49873
50615
  return true;
49874
50616
  } catch {
49875
- removeDaemonPid();
50617
+ removeDaemonPid(ref);
49876
50618
  return false;
49877
50619
  }
49878
50620
  }
49879
- var os23, fs17, path25, import_http, import_ws3, import_chalk2, pkgVersion, ACTIVE_CHAT_POLL_STATUSES, AdhdevDaemon;
50621
+ var os24, fs18, path27, import_http, import_ws3, import_chalk2, pkgVersion, ACTIVE_CHAT_POLL_STATUSES, AdhdevDaemon;
49880
50622
  var init_adhdev_daemon = __esm({
49881
50623
  "src/adhdev-daemon.ts"() {
49882
50624
  "use strict";
@@ -49885,16 +50627,17 @@ var init_adhdev_daemon = __esm({
49885
50627
  init_daemon_p2p2();
49886
50628
  init_screenshot_controller();
49887
50629
  init_session_host();
50630
+ init_startup_restore_policy();
49888
50631
  init_dist();
49889
50632
  init_session_host_controller();
49890
- os23 = __toESM(require("os"));
49891
- fs17 = __toESM(require("fs"));
49892
- path25 = __toESM(require("path"));
50633
+ os24 = __toESM(require("os"));
50634
+ fs18 = __toESM(require("fs"));
50635
+ path27 = __toESM(require("path"));
49893
50636
  import_http = require("http");
49894
50637
  import_ws3 = require("ws");
49895
50638
  import_chalk2 = __toESM(require("chalk"));
49896
50639
  init_version();
49897
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.52" });
50640
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.54" });
49898
50641
  ACTIVE_CHAT_POLL_STATUSES = /* @__PURE__ */ new Set([
49899
50642
  "generating",
49900
50643
  "waiting_approval",
@@ -50323,13 +51066,13 @@ ${err?.stack || ""}`);
50323
51066
  const workingDir = options.workingDir || process.cwd();
50324
51067
  let pidWritten = false;
50325
51068
  try {
50326
- if (isDaemonRunning()) {
51069
+ if (isDaemonRunning({ port: this.localPort })) {
50327
51070
  console.log(import_chalk2.default.yellow("\n\u26A0 ADHDev Daemon is already running."));
50328
51071
  console.log(import_chalk2.default.gray(` Stop with: adhdev daemon:stop
50329
51072
  `));
50330
51073
  return;
50331
51074
  }
50332
- writeDaemonPid(process.pid);
51075
+ writeDaemonPid(process.pid, { port: this.localPort });
50333
51076
  pidWritten = true;
50334
51077
  const config2 = loadConfig();
50335
51078
  const authToken = config2.machineSecret;
@@ -50402,7 +51145,9 @@ ${err?.stack || ""}`);
50402
51145
  forwardAgentStreamsToIdeInstance(this.components.instanceManager, ideType, streams);
50403
51146
  }
50404
51147
  });
50405
- await this.components.cliManager.restoreHostedSessions();
51148
+ if (shouldAutoRestoreHostedSessionsOnStartup(process.env)) {
51149
+ await this.components.cliManager.restoreHostedSessions();
51150
+ }
50406
51151
  this.components.providerLoader.fetchLatest().then(({ updated }) => {
50407
51152
  if (updated) {
50408
51153
  this.components.providerLoader.reload();
@@ -50418,8 +51163,8 @@ ${err?.stack || ""}`);
50418
51163
  cliInfo: {
50419
51164
  type: "adhdev-daemon",
50420
51165
  version: pkgVersion,
50421
- platform: os23.platform(),
50422
- hostname: os23.hostname(),
51166
+ platform: os24.platform(),
51167
+ hostname: os24.hostname(),
50423
51168
  machineId: config2.machineId,
50424
51169
  instanceId
50425
51170
  }
@@ -50572,7 +51317,7 @@ ${err?.stack || ""}`);
50572
51317
  }
50573
51318
  } catch (error48) {
50574
51319
  if (!this.running && pidWritten) {
50575
- removeDaemonPid();
51320
+ removeDaemonPid({ port: this.localPort });
50576
51321
  }
50577
51322
  throw error48;
50578
51323
  }
@@ -50882,6 +51627,18 @@ ${err?.stack || ""}`);
50882
51627
  * Daemon cleanup (release all resources)
50883
51628
  * @param exitProcess If true, exit after cleanup process.exit(0), if false, cleanup only
50884
51629
  */
51630
+ async stopManagedSessionHost() {
51631
+ try {
51632
+ await this.sessionHostController?.stop();
51633
+ } catch {
51634
+ } finally {
51635
+ this.sessionHostController = null;
51636
+ }
51637
+ try {
51638
+ stopManagedSessionHostProcess();
51639
+ } catch {
51640
+ }
51641
+ }
50885
51642
  async stop(exitProcess = true) {
50886
51643
  if (!this.running) return;
50887
51644
  this.running = false;
@@ -50909,11 +51666,7 @@ ${err?.stack || ""}`);
50909
51666
  this.serverConn?.disconnect();
50910
51667
  } catch {
50911
51668
  }
50912
- try {
50913
- await this.sessionHostController?.stop();
50914
- this.sessionHostController = null;
50915
- } catch {
50916
- }
51669
+ await this.stopManagedSessionHost();
50917
51670
  try {
50918
51671
  for (const client of this.localClients) {
50919
51672
  client.close();
@@ -50931,7 +51684,7 @@ ${err?.stack || ""}`);
50931
51684
  });
50932
51685
  } catch {
50933
51686
  }
50934
- removeDaemonPid();
51687
+ removeDaemonPid({ port: this.localPort });
50935
51688
  console.log(import_chalk2.default.green(" \u2713 ADHDev Daemon stopped.\n"));
50936
51689
  if (exitProcess) {
50937
51690
  process.exit(0);
@@ -51123,15 +51876,15 @@ async function loginFlow() {
51123
51876
  let verificationUrl;
51124
51877
  try {
51125
51878
  const config2 = loadConfig();
51126
- const os24 = await import("os");
51879
+ const os25 = await import("os");
51127
51880
  const res = await fetch(`${SERVER_URL}/auth/cli/init`, {
51128
51881
  method: "POST",
51129
51882
  headers: { "Content-Type": "application/json" },
51130
51883
  body: JSON.stringify({
51131
51884
  clientMachineId: config2.machineId,
51132
- hostname: os24.hostname(),
51133
- platform: os24.platform(),
51134
- arch: os24.arch()
51885
+ hostname: os25.hostname(),
51886
+ platform: os25.platform(),
51887
+ arch: os25.arch()
51135
51888
  })
51136
51889
  });
51137
51890
  if (!res.ok) {
@@ -51236,8 +51989,8 @@ async function startDaemonFlow() {
51236
51989
  const { execSync: execSync7 } = await import("child_process");
51237
51990
  const { getCurrentDaemonLogPath: getCurrentDaemonLogPath2 } = await Promise.resolve().then(() => (init_src(), src_exports));
51238
51991
  const logPath = getCurrentDaemonLogPath2();
51239
- const os24 = await import("os");
51240
- const platform12 = os24.platform();
51992
+ const os25 = await import("os");
51993
+ const platform12 = os25.platform();
51241
51994
  try {
51242
51995
  if (platform12 === "win32") {
51243
51996
  execSync7("start /B adhdev daemon >NUL 2>&1", {