@adhdev/daemon-standalone 0.8.51 → 0.8.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -9173,7 +9173,12 @@ var require_dist = __commonJS({
9173
9173
  ensureNodePtySpawnHelperPermissions: () => ensureNodePtySpawnHelperPermissions,
9174
9174
  formatRuntimeOwner: () => formatRuntimeOwner,
9175
9175
  getDefaultSessionHostEndpoint: () => getDefaultSessionHostEndpoint2,
9176
+ getSessionHostRecoveryLabel: () => getSessionHostRecoveryLabel,
9177
+ getSessionHostSurfaceKind: () => getSessionHostSurfaceKind,
9176
9178
  getWorkspaceLabel: () => getWorkspaceLabel,
9179
+ isSessionHostLiveRuntime: () => isSessionHostLiveRuntime,
9180
+ isSessionHostRecoverySnapshot: () => isSessionHostRecoverySnapshot,
9181
+ resolveAttachableRuntimeRecord: () => resolveAttachableRuntimeRecord,
9177
9182
  resolveRuntimeRecord: () => resolveRuntimeRecord,
9178
9183
  sanitizeSpawnEnv: () => sanitizeSpawnEnv,
9179
9184
  writeEnvelope: () => writeEnvelope
@@ -9275,6 +9280,55 @@ var require_dist = __commonJS({
9275
9280
  }
9276
9281
  return candidate;
9277
9282
  }
9283
+ var LIVE_LIFECYCLES = /* @__PURE__ */ new Set(["starting", "running", "stopping", "interrupted"]);
9284
+ function isSessionHostLiveRuntime(record2) {
9285
+ if (!record2) return false;
9286
+ if (record2.surfaceKind === "live_runtime") return true;
9287
+ if (record2.surfaceKind === "recovery_snapshot" || record2.surfaceKind === "inactive_record") return false;
9288
+ const lifecycle = String(record2.lifecycle || "").trim();
9289
+ return LIVE_LIFECYCLES.has(lifecycle);
9290
+ }
9291
+ function getSessionHostRecoveryLabel(meta3) {
9292
+ const recoveryState = typeof meta3?.runtimeRecoveryState === "string" ? String(meta3.runtimeRecoveryState).trim() : "";
9293
+ if (!recoveryState) return null;
9294
+ if (recoveryState === "auto_resumed") return "restored after restart";
9295
+ if (recoveryState === "resume_failed") return "restore failed";
9296
+ if (recoveryState === "host_restart_interrupted") return "host restart interrupted";
9297
+ if (recoveryState === "orphan_snapshot") return "snapshot recovered";
9298
+ return recoveryState.replace(/_/g, " ");
9299
+ }
9300
+ function isSessionHostRecoverySnapshot(record2) {
9301
+ if (!record2) return false;
9302
+ if (record2.surfaceKind === "recovery_snapshot") return true;
9303
+ if (record2.surfaceKind === "live_runtime" || record2.surfaceKind === "inactive_record") return false;
9304
+ if (isSessionHostLiveRuntime(record2)) return false;
9305
+ const lifecycle = String(record2.lifecycle || "").trim();
9306
+ if (lifecycle && lifecycle !== "stopped" && lifecycle !== "failed") {
9307
+ return false;
9308
+ }
9309
+ const meta3 = record2.meta || void 0;
9310
+ if (meta3?.restoredFromStorage === true) return true;
9311
+ return getSessionHostRecoveryLabel(meta3) !== null;
9312
+ }
9313
+ function getSessionHostSurfaceKind(record2) {
9314
+ if (record2?.surfaceKind === "live_runtime" || record2?.surfaceKind === "recovery_snapshot" || record2?.surfaceKind === "inactive_record") {
9315
+ return record2.surfaceKind;
9316
+ }
9317
+ if (isSessionHostLiveRuntime(record2)) return "live_runtime";
9318
+ if (isSessionHostRecoverySnapshot(record2)) return "recovery_snapshot";
9319
+ return "inactive_record";
9320
+ }
9321
+ function resolveAttachableRuntimeRecord(records, identifier) {
9322
+ const record2 = resolveRuntimeRecord(records, identifier);
9323
+ const surfaceKind = getSessionHostSurfaceKind(record2);
9324
+ if (surfaceKind === "live_runtime") {
9325
+ return record2;
9326
+ }
9327
+ if (surfaceKind === "recovery_snapshot") {
9328
+ throw new Error(`Runtime ${record2.runtimeKey} is a recovery snapshot, not a live attach target. Resume or recover it first.`);
9329
+ }
9330
+ throw new Error(`Runtime ${record2.runtimeKey} is ${record2.lifecycle}, not a live attach target.`);
9331
+ }
9278
9332
  function uniqueMatch(records, predicate) {
9279
9333
  const matches = records.filter(predicate);
9280
9334
  if (matches.length === 1) return matches[0] || null;
@@ -30836,6 +30890,7 @@ ${data.message || ""}`.trim();
30836
30890
  detectIDEs: () => detectIDEs,
30837
30891
  ensureSessionHostReady: () => ensureSessionHostReady2,
30838
30892
  findCdpManager: () => findCdpManager,
30893
+ flattenMessageParts: () => flattenMessageParts,
30839
30894
  forwardAgentStreamsToIdeInstance: () => forwardAgentStreamsToIdeInstance2,
30840
30895
  getAIExtensions: () => getAIExtensions,
30841
30896
  getAvailableIdeIds: () => getAvailableIdeIds,
@@ -30849,6 +30904,8 @@ ${data.message || ""}`.trim();
30849
30904
  getRecentDebugTrace: () => getRecentDebugTrace,
30850
30905
  getRecentLogs: () => getRecentLogs,
30851
30906
  getSavedProviderSessions: () => getSavedProviderSessions,
30907
+ getSessionHostRecoveryLabel: () => getSessionHostRecoveryLabel,
30908
+ getSessionHostSurfaceKind: () => getSessionHostSurfaceKind,
30852
30909
  getWorkspaceState: () => getWorkspaceState2,
30853
30910
  hasCdpManager: () => hasCdpManager,
30854
30911
  initDaemonComponents: () => initDaemonComponents2,
@@ -30859,6 +30916,8 @@ ${data.message || ""}`.trim();
30859
30916
  isIdeRunning: () => isIdeRunning,
30860
30917
  isManagedStatusWaiting: () => isManagedStatusWaiting,
30861
30918
  isManagedStatusWorking: () => isManagedStatusWorking,
30919
+ isSessionHostLiveRuntime: () => isSessionHostLiveRuntime,
30920
+ isSessionHostRecoverySnapshot: () => isSessionHostRecoverySnapshot,
30862
30921
  isSetupComplete: () => isSetupComplete,
30863
30922
  killIdeProcess: () => killIdeProcess,
30864
30923
  launchIDE: () => launchIDE,
@@ -30870,7 +30929,11 @@ ${data.message || ""}`.trim();
30870
30929
  markSetupComplete: () => markSetupComplete,
30871
30930
  maybeRunDaemonUpgradeHelperFromEnv: () => maybeRunDaemonUpgradeHelperFromEnv2,
30872
30931
  normalizeActiveChatData: () => normalizeActiveChatData,
30932
+ normalizeInputEnvelope: () => normalizeInputEnvelope,
30873
30933
  normalizeManagedStatus: () => normalizeManagedStatus,
30934
+ normalizeMessageParts: () => normalizeMessageParts,
30935
+ partitionSessionHostDiagnosticsSessions: () => partitionSessionHostDiagnosticsSessions,
30936
+ partitionSessionHostRecords: () => partitionSessionHostRecords,
30874
30937
  probeCdpPort: () => probeCdpPort,
30875
30938
  readChatHistory: () => readChatHistory,
30876
30939
  recordDebugTrace: () => recordDebugTrace,
@@ -30885,6 +30948,7 @@ ${data.message || ""}`.trim();
30885
30948
  setDebugRuntimeConfig: () => setDebugRuntimeConfig,
30886
30949
  setLogLevel: () => setLogLevel,
30887
30950
  setupIdeInstance: () => setupIdeInstance,
30951
+ shouldAutoRestoreHostedSessionsOnStartup: () => shouldAutoRestoreHostedSessionsOnStartup2,
30888
30952
  shouldCollectTraceCategory: () => shouldCollectTraceCategory,
30889
30953
  shutdownDaemonComponents: () => shutdownDaemonComponents2,
30890
30954
  spawnDetachedDaemonUpgradeHelper: () => spawnDetachedDaemonUpgradeHelper,
@@ -32956,6 +33020,61 @@ ${data.message || ""}`.trim();
32956
33020
  }
32957
33021
  return effects;
32958
33022
  }
33023
+ function normalizeControlListResult(data) {
33024
+ if (data && typeof data === "object" && Array.isArray(data.options)) {
33025
+ return {
33026
+ options: normalizeControlOptions(data.options),
33027
+ ...isScalarControlValue(data.currentValue) ? { currentValue: data.currentValue } : {},
33028
+ ...typeof data.error === "string" ? { error: data.error } : {}
33029
+ };
33030
+ }
33031
+ const rawOptions = Array.isArray(data?.models) ? data.models : Array.isArray(data?.modes) ? data.modes : Array.isArray(data?.options) ? data.options : [];
33032
+ const options = normalizeControlOptions(rawOptions);
33033
+ return {
33034
+ options,
33035
+ ...isScalarControlValue(data?.current) ? { currentValue: data.current } : {},
33036
+ ...isScalarControlValue(data?.currentValue) ? { currentValue: data.currentValue } : {},
33037
+ ...typeof data?.error === "string" ? { error: data.error } : {}
33038
+ };
33039
+ }
33040
+ function normalizeControlSetResult(data) {
33041
+ const currentValue = isScalarControlValue(data?.currentValue) ? data.currentValue : isScalarControlValue(data?.value) ? data.value : void 0;
33042
+ return {
33043
+ ok: data?.ok === true || data?.success === true,
33044
+ ...currentValue !== void 0 ? { currentValue } : {},
33045
+ ...Array.isArray(data?.effects) ? { effects: normalizeProviderEffects(data) } : {},
33046
+ ...typeof data?.error === "string" ? { error: data.error } : {}
33047
+ };
33048
+ }
33049
+ function normalizeControlInvokeResult(data) {
33050
+ const currentValue = isScalarControlValue(data?.currentValue) ? data.currentValue : isScalarControlValue(data?.value) ? data.value : void 0;
33051
+ return {
33052
+ ok: data?.ok === true || data?.success === true,
33053
+ ...currentValue !== void 0 ? { currentValue } : {},
33054
+ ...Array.isArray(data?.effects) ? { effects: normalizeProviderEffects(data) } : {},
33055
+ ...typeof data?.error === "string" ? { error: data.error } : {}
33056
+ };
33057
+ }
33058
+ function normalizeControlOptions(options) {
33059
+ return options.map((option) => normalizeControlOption(option)).filter((option) => !!option);
33060
+ }
33061
+ function normalizeControlOption(option) {
33062
+ if (typeof option === "string") {
33063
+ return { value: option, label: option };
33064
+ }
33065
+ if (!option || typeof option !== "object") return null;
33066
+ const record2 = option;
33067
+ const value = typeof record2.value === "string" ? record2.value : typeof record2.id === "string" ? record2.id : null;
33068
+ if (!value) return null;
33069
+ const label = typeof record2.label === "string" ? record2.label : typeof record2.name === "string" ? record2.name : value;
33070
+ const normalized = { value, label };
33071
+ if (typeof record2.description === "string") normalized.description = record2.description;
33072
+ if (typeof record2.group === "string") normalized.group = record2.group;
33073
+ return normalized;
33074
+ }
33075
+ function isScalarControlValue(value) {
33076
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
33077
+ }
32959
33078
  function normalizeControlValue(value) {
32960
33079
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
32961
33080
  return value;
@@ -34927,50 +35046,6 @@ ${effect.notification.body || ""}`.trim();
34927
35046
  }
34928
35047
  return false;
34929
35048
  }
34930
- function buildFallbackControls(providerControls, serverModel, serverMode, acpConfigOptions, acpModes) {
34931
- if (providerControls && providerControls.length > 0) return providerControls;
34932
- const controls = [];
34933
- const isAcp = !!(acpConfigOptions || acpModes);
34934
- const modelFromAcp = acpConfigOptions?.find((c) => c.category === "model");
34935
- if (!isAcp || modelFromAcp) {
34936
- controls.push({
34937
- id: "model",
34938
- type: "select",
34939
- label: "Model",
34940
- icon: "\u{1F916}",
34941
- placement: "bar",
34942
- dynamic: !modelFromAcp,
34943
- listScript: "listModels",
34944
- setScript: "setModel",
34945
- readFrom: "model",
34946
- ...modelFromAcp && {
34947
- options: modelFromAcp.options.map((o) => ({ value: o.value, label: o.name || o.value }))
34948
- }
34949
- });
34950
- }
34951
- const modeFromAcp = acpModes && acpModes.length > 0;
34952
- const thoughtFromAcp = !modeFromAcp && acpConfigOptions?.find((c) => c.category !== "model");
34953
- if (!isAcp || modeFromAcp || thoughtFromAcp) {
34954
- controls.push({
34955
- id: "mode",
34956
- type: thoughtFromAcp ? "cycle" : "select",
34957
- label: thoughtFromAcp ? "Thinking" : "Mode",
34958
- icon: thoughtFromAcp ? "\u{1F9E0}" : "\u26A1",
34959
- placement: "bar",
34960
- dynamic: !modeFromAcp && !thoughtFromAcp,
34961
- listScript: "listModes",
34962
- setScript: thoughtFromAcp ? "setThinkingLevel" : "setMode",
34963
- readFrom: "mode",
34964
- ...modeFromAcp && {
34965
- options: acpModes.map((m) => ({ value: m.id, label: m.name || m.id }))
34966
- },
34967
- ...thoughtFromAcp && {
34968
- options: thoughtFromAcp.options.map((o) => ({ value: o.value, label: o.name || o.value }))
34969
- }
34970
- });
34971
- }
34972
- return controls;
34973
- }
34974
35049
  var IDE_SESSION_CAPABILITIES = [
34975
35050
  "read_chat",
34976
35051
  "send_message",
@@ -35039,11 +35114,7 @@ ${effect.notification.body || ""}`.trim();
35039
35114
  currentAutoApprove: state.currentAutoApprove,
35040
35115
  ...includeSessionControls && {
35041
35116
  controlValues: state.controlValues,
35042
- providerControls: buildFallbackControls(
35043
- state.providerControls,
35044
- state.currentModel,
35045
- state.currentPlan
35046
- )
35117
+ providerControls: state.providerControls
35047
35118
  },
35048
35119
  errorMessage: state.errorMessage,
35049
35120
  errorReason: state.errorReason,
@@ -35073,11 +35144,7 @@ ${effect.notification.body || ""}`.trim();
35073
35144
  currentPlan: ext.currentPlan,
35074
35145
  ...includeSessionControls && {
35075
35146
  controlValues: ext.controlValues,
35076
- providerControls: buildFallbackControls(
35077
- ext.providerControls,
35078
- ext.currentModel,
35079
- ext.currentPlan
35080
- )
35147
+ providerControls: ext.providerControls
35081
35148
  },
35082
35149
  errorMessage: ext.errorMessage,
35083
35150
  errorReason: ext.errorReason,
@@ -35118,9 +35185,7 @@ ${effect.notification.body || ""}`.trim();
35118
35185
  },
35119
35186
  ...includeSessionControls && {
35120
35187
  controlValues: state.controlValues,
35121
- providerControls: buildFallbackControls(
35122
- state.providerControls
35123
- )
35188
+ providerControls: state.providerControls
35124
35189
  },
35125
35190
  errorMessage: state.errorMessage,
35126
35191
  errorReason: state.errorReason,
@@ -35152,13 +35217,7 @@ ${effect.notification.body || ""}`.trim();
35152
35217
  acpConfigOptions: state.acpConfigOptions,
35153
35218
  acpModes: state.acpModes,
35154
35219
  controlValues: state.controlValues,
35155
- providerControls: buildFallbackControls(
35156
- state.providerControls,
35157
- state.currentModel,
35158
- state.currentPlan,
35159
- state.acpConfigOptions,
35160
- state.acpModes
35161
- )
35220
+ providerControls: state.providerControls
35162
35221
  },
35163
35222
  errorMessage: state.errorMessage,
35164
35223
  errorReason: state.errorReason,
@@ -35236,9 +35295,214 @@ ${effect.notification.body || ""}`.trim();
35236
35295
  }
35237
35296
  }
35238
35297
  init_logger();
35298
+ function normalizeInputEnvelope(input) {
35299
+ const normalized = normalizeInputEnvelopePayload(input);
35300
+ const textFallback = normalized.textFallback ?? flattenInputParts(normalized.parts);
35301
+ return {
35302
+ parts: normalized.parts,
35303
+ textFallback,
35304
+ ...normalized.metadata ? { metadata: normalized.metadata } : {}
35305
+ };
35306
+ }
35307
+ function normalizeMessageParts(content) {
35308
+ if (typeof content === "string") return [{ type: "text", text: content }];
35309
+ if (!Array.isArray(content)) {
35310
+ if (content && typeof content === "object" && typeof content.text === "string") {
35311
+ return [{ type: "text", text: String(content.text) }];
35312
+ }
35313
+ return [];
35314
+ }
35315
+ const parts = [];
35316
+ for (const raw of content) {
35317
+ if (typeof raw === "string") {
35318
+ parts.push({ type: "text", text: raw });
35319
+ continue;
35320
+ }
35321
+ if (!raw || typeof raw !== "object") continue;
35322
+ const part = normalizeMessagePartObject(raw);
35323
+ if (part) parts.push(part);
35324
+ }
35325
+ return parts;
35326
+ }
35327
+ function flattenMessageParts(parts) {
35328
+ return parts.map((part) => {
35329
+ if (part.type === "text") return part.text;
35330
+ if (part.type === "resource") return part.resource.text || "";
35331
+ return "";
35332
+ }).filter((value) => value.length > 0).join("\n");
35333
+ }
35334
+ function normalizeInputEnvelopePayload(input) {
35335
+ if (typeof input === "string") {
35336
+ return { parts: [{ type: "text", text: input }], textFallback: input };
35337
+ }
35338
+ if (!input || typeof input !== "object") {
35339
+ return { parts: [], textFallback: "" };
35340
+ }
35341
+ const record2 = input;
35342
+ const nestedInput = record2.input;
35343
+ if (nestedInput && typeof nestedInput === "object") {
35344
+ const nested = nestedInput;
35345
+ return {
35346
+ parts: normalizeInputParts(nested.parts ?? nested.prompt),
35347
+ textFallback: typeof nested.textFallback === "string" ? nested.textFallback : void 0,
35348
+ metadata: normalizeInputMetadata(nested.metadata)
35349
+ };
35350
+ }
35351
+ const directText = typeof record2.text === "string" ? record2.text : typeof record2.message === "string" ? record2.message : void 0;
35352
+ if (directText !== void 0) {
35353
+ return { parts: [{ type: "text", text: directText }], textFallback: directText };
35354
+ }
35355
+ const directParts = normalizeInputParts(record2.parts ?? record2.prompt);
35356
+ return {
35357
+ parts: directParts,
35358
+ textFallback: typeof record2.textFallback === "string" ? record2.textFallback : void 0,
35359
+ metadata: normalizeInputMetadata(record2.metadata)
35360
+ };
35361
+ }
35362
+ function normalizeInputMetadata(value) {
35363
+ if (!value || typeof value !== "object") return void 0;
35364
+ const record2 = value;
35365
+ const metadata = {};
35366
+ if (record2.source === "dashboard" || record2.source === "shortcut_api" || record2.source === "provider_script" || record2.source === "session_replay") {
35367
+ metadata.source = record2.source;
35368
+ }
35369
+ if (typeof record2.clientTimestamp === "number" && Number.isFinite(record2.clientTimestamp)) {
35370
+ metadata.clientTimestamp = record2.clientTimestamp;
35371
+ }
35372
+ return Object.keys(metadata).length > 0 ? metadata : void 0;
35373
+ }
35374
+ function normalizeInputParts(value) {
35375
+ if (!Array.isArray(value)) return [];
35376
+ const parts = [];
35377
+ for (const raw of value) {
35378
+ if (typeof raw === "string") {
35379
+ parts.push({ type: "text", text: raw });
35380
+ continue;
35381
+ }
35382
+ if (!raw || typeof raw !== "object") continue;
35383
+ const part = normalizeInputPartObject(raw);
35384
+ if (part) parts.push(part);
35385
+ }
35386
+ return parts;
35387
+ }
35388
+ function normalizeInputPartObject(raw) {
35389
+ const type = raw.type;
35390
+ if (type === "text" && typeof raw.text === "string") {
35391
+ return { type, text: raw.text };
35392
+ }
35393
+ if (type === "image" && typeof raw.mimeType === "string") {
35394
+ return {
35395
+ type,
35396
+ mimeType: raw.mimeType,
35397
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
35398
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
35399
+ ...typeof raw.alt === "string" ? { alt: raw.alt } : {}
35400
+ };
35401
+ }
35402
+ if (type === "audio" && typeof raw.mimeType === "string") {
35403
+ return {
35404
+ type,
35405
+ mimeType: raw.mimeType,
35406
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
35407
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
35408
+ ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
35409
+ };
35410
+ }
35411
+ if (type === "video" && typeof raw.mimeType === "string") {
35412
+ return {
35413
+ type,
35414
+ mimeType: raw.mimeType,
35415
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
35416
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
35417
+ ...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
35418
+ };
35419
+ }
35420
+ if (type === "resource" && typeof raw.uri === "string") {
35421
+ return {
35422
+ type,
35423
+ uri: raw.uri,
35424
+ ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
35425
+ ...typeof raw.name === "string" ? { name: raw.name } : {},
35426
+ ...typeof raw.text === "string" ? { text: raw.text } : {},
35427
+ ...typeof raw.data === "string" ? { data: raw.data } : {}
35428
+ };
35429
+ }
35430
+ if (type === "resource_link" && typeof raw.uri === "string") {
35431
+ return {
35432
+ type: "resource",
35433
+ uri: raw.uri,
35434
+ ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
35435
+ ...typeof raw.name === "string" ? { name: raw.name } : {}
35436
+ };
35437
+ }
35438
+ return null;
35439
+ }
35440
+ function normalizeMessagePartObject(raw) {
35441
+ const type = raw.type;
35442
+ if (type === "text" && typeof raw.text === "string") {
35443
+ return { type, text: raw.text };
35444
+ }
35445
+ if (type === "image" && typeof raw.mimeType === "string") {
35446
+ return {
35447
+ type,
35448
+ mimeType: raw.mimeType,
35449
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
35450
+ ...typeof raw.data === "string" ? { data: raw.data } : {}
35451
+ };
35452
+ }
35453
+ if (type === "audio" && typeof raw.mimeType === "string") {
35454
+ return {
35455
+ type,
35456
+ mimeType: raw.mimeType,
35457
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
35458
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
35459
+ ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
35460
+ };
35461
+ }
35462
+ if (type === "video" && typeof raw.mimeType === "string") {
35463
+ return {
35464
+ type,
35465
+ mimeType: raw.mimeType,
35466
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
35467
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
35468
+ ...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
35469
+ };
35470
+ }
35471
+ if (type === "resource_link" && typeof raw.uri === "string" && typeof raw.name === "string") {
35472
+ return {
35473
+ type,
35474
+ uri: raw.uri,
35475
+ name: raw.name,
35476
+ ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
35477
+ ...typeof raw.size === "number" ? { size: raw.size } : {}
35478
+ };
35479
+ }
35480
+ if (type === "resource" && raw.resource && typeof raw.resource === "object") {
35481
+ const resource = raw.resource;
35482
+ if (typeof resource.uri !== "string") return null;
35483
+ return {
35484
+ type,
35485
+ resource: {
35486
+ uri: resource.uri,
35487
+ ...typeof resource.mimeType === "string" || resource.mimeType === null ? { mimeType: resource.mimeType } : {},
35488
+ ...typeof resource.text === "string" ? { text: resource.text } : {},
35489
+ ...typeof resource.blob === "string" ? { blob: resource.blob } : {}
35490
+ }
35491
+ };
35492
+ }
35493
+ return null;
35494
+ }
35495
+ function flattenInputParts(parts) {
35496
+ return parts.map((part) => {
35497
+ if (part.type === "text") return part.text;
35498
+ if (part.type === "audio") return part.transcript || "";
35499
+ if (part.type === "resource") return part.text || "";
35500
+ return "";
35501
+ }).filter((value) => value.length > 0).join("\n");
35502
+ }
35239
35503
  function flattenContent(content) {
35240
35504
  if (typeof content === "string") return content;
35241
- return content.filter((b2) => b2.type === "text").map((b2) => b2.text).join("\n");
35505
+ return flattenMessageParts(normalizeMessageParts(content));
35242
35506
  }
35243
35507
  init_logger();
35244
35508
  var NORMAL_TRACE_BUFFER_SIZE = 200;
@@ -35419,6 +35683,9 @@ ${effect.notification.body || ""}`.trim();
35419
35683
  const target = args?.targetSessionId || args?.agentType || h.currentSession?.providerType || h.currentProviderType || h.currentManagerKey || "unknown";
35420
35684
  return `${transport}:${target}:${text.trim()}`;
35421
35685
  }
35686
+ function getSendChatInputEnvelope(args) {
35687
+ return normalizeInputEnvelope(args?.input ? { input: args.input } : args);
35688
+ }
35422
35689
  function getHistorySessionId(h, args) {
35423
35690
  const explicit = typeof args?.historySessionId === "string" ? args.historySessionId.trim() : "";
35424
35691
  if (explicit) return explicit;
@@ -35823,7 +36090,8 @@ ${effect.notification.body || ""}`.trim();
35823
36090
  return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
35824
36091
  }
35825
36092
  async function handleSendChat(h, args) {
35826
- const text = args?.text || args?.message;
36093
+ const input = getSendChatInputEnvelope(args);
36094
+ const text = input.textFallback;
35827
36095
  if (!text) return { success: false, error: "text required" };
35828
36096
  const _log = (msg) => LOG2.debug("Command", `[send_chat] ${msg}`);
35829
36097
  const provider = h.getProvider(args?.agentType);
@@ -36761,6 +37029,21 @@ ${effect.notification.body || ""}`.trim();
36761
37029
  }
36762
37030
  return files;
36763
37031
  }
37032
+ function listWindowsDriveEntries(excludePath) {
37033
+ const excluded = typeof excludePath === "string" ? excludePath.toLowerCase() : "";
37034
+ const drives = [];
37035
+ for (let code = 65; code <= 90; code += 1) {
37036
+ const letter = String.fromCharCode(code);
37037
+ const root = `${letter}:\\`;
37038
+ try {
37039
+ if (!fs42.existsSync(root)) continue;
37040
+ if (excluded && root.toLowerCase() === excluded) continue;
37041
+ drives.push({ name: `${letter}:`, type: "directory", path: root });
37042
+ } catch {
37043
+ }
37044
+ }
37045
+ return drives;
37046
+ }
36764
37047
  async function handleFileRead(h, args) {
36765
37048
  try {
36766
37049
  const filePath = resolveSafePath(args?.path);
@@ -36793,11 +37076,48 @@ ${effect.notification.body || ""}`.trim();
36793
37076
  try {
36794
37077
  const dirPath = resolveSafePath(args?.path || ".");
36795
37078
  const files = listDirectoryEntriesSafe(dirPath).filter((entry) => entry.type === "directory").sort((a, b2) => a.name.localeCompare(b2.name));
37079
+ if (process.platform === "win32" && /^[A-Za-z]:\\?$/.test(dirPath)) {
37080
+ const driveEntries = listWindowsDriveEntries(dirPath);
37081
+ return {
37082
+ success: true,
37083
+ files: [...driveEntries, ...files],
37084
+ path: dirPath
37085
+ };
37086
+ }
36796
37087
  return { success: true, files, path: dirPath };
36797
37088
  } catch (e) {
36798
37089
  return { success: false, error: e.message };
36799
37090
  }
36800
37091
  }
37092
+ function parseCliScriptResult(result) {
37093
+ if (typeof result === "string") {
37094
+ try {
37095
+ const parsed = JSON.parse(result);
37096
+ if (parsed && typeof parsed === "object" && parsed.success === false) {
37097
+ return { success: false, payload: parsed };
37098
+ }
37099
+ return { success: true, payload: parsed };
37100
+ } catch {
37101
+ return { success: true, payload: { result } };
37102
+ }
37103
+ }
37104
+ if (result && typeof result === "object" && "success" in result && result.success === false) {
37105
+ return { success: false, payload: result };
37106
+ }
37107
+ return { success: true, payload: result };
37108
+ }
37109
+ function getCliScriptCommand(payload) {
37110
+ if (!payload || typeof payload !== "object") return null;
37111
+ if (typeof payload.sendMessage === "string" && payload.sendMessage.trim()) {
37112
+ return { type: "send_message", text: payload.sendMessage.trim() };
37113
+ }
37114
+ const command = payload.command;
37115
+ if (!command || typeof command !== "object") return null;
37116
+ if (command.type !== "send_message" && command.type !== "pty_write") return null;
37117
+ const text = typeof command.text === "string" ? command.text.trim() : typeof command.message === "string" ? command.message.trim() : "";
37118
+ if (!text) return null;
37119
+ return { type: command.type, text };
37120
+ }
36801
37121
  init_logger();
36802
37122
  function getCliPresentationMode(h, targetSessionId) {
36803
37123
  if (!targetSessionId) return null;
@@ -36887,34 +37207,19 @@ ${effect.notification.body || ""}`.trim();
36887
37207
  }
36888
37208
  return normalizedArgs;
36889
37209
  }
36890
- function parseScriptResult(result) {
36891
- if (typeof result === "string") {
36892
- try {
36893
- const parsed = JSON.parse(result);
36894
- if (parsed && typeof parsed === "object" && parsed.success === false) {
36895
- return { success: false, payload: parsed };
36896
- }
36897
- return { success: true, payload: parsed };
36898
- } catch {
36899
- return { success: true, payload: { result } };
36900
- }
37210
+ function buildControlScriptResult(scriptName, payload) {
37211
+ if (!payload || typeof payload !== "object") return {};
37212
+ if (Array.isArray(payload.options) || Array.isArray(payload.models) || Array.isArray(payload.modes)) {
37213
+ return { controlResult: normalizeControlListResult(payload) };
36901
37214
  }
36902
- if (result && typeof result === "object" && "success" in result && result.success === false) {
36903
- return { success: false, payload: result };
37215
+ const looksLikeValueMutation = /^set|^change/i.test(scriptName) || payload.currentValue !== void 0 || payload.value !== void 0;
37216
+ if (looksLikeValueMutation) {
37217
+ return { controlResult: normalizeControlSetResult(payload) };
36904
37218
  }
36905
- return { success: true, payload: result };
36906
- }
36907
- function getCliScriptCommand(payload) {
36908
- if (!payload || typeof payload !== "object") return null;
36909
- if (typeof payload.sendMessage === "string" && payload.sendMessage.trim()) {
36910
- return { type: "send_message", text: payload.sendMessage.trim() };
37219
+ if (payload.ok !== void 0 || payload.success !== void 0 || Array.isArray(payload.effects)) {
37220
+ return { controlResult: normalizeControlInvokeResult(payload) };
36911
37221
  }
36912
- const command = payload.command;
36913
- if (!command || typeof command !== "object") return null;
36914
- if (command.type !== "send_message" && command.type !== "pty_write") return null;
36915
- const text = typeof command.text === "string" ? command.text.trim() : typeof command.message === "string" ? command.message.trim() : "";
36916
- if (!text) return null;
36917
- return { type: command.type, text };
37222
+ return {};
36918
37223
  }
36919
37224
  function applyProviderPatch(h, args, payload) {
36920
37225
  if (!payload || typeof payload !== "object") return;
@@ -36948,7 +37253,7 @@ ${effect.notification.body || ""}`.trim();
36948
37253
  }
36949
37254
  try {
36950
37255
  const raw = await adapter.invokeScript(actualScriptName, normalizedArgs);
36951
- const parsed = parseScriptResult(raw);
37256
+ const parsed = parseCliScriptResult(raw);
36952
37257
  if (!parsed.success) {
36953
37258
  return { success: false, ...parsed.payload || {} };
36954
37259
  }
@@ -36959,7 +37264,11 @@ ${effect.notification.body || ""}`.trim();
36959
37264
  adapter.writeRaw(cliCommand.text + "\r");
36960
37265
  }
36961
37266
  applyProviderPatch(h, args, parsed.payload);
36962
- return { success: true, ...parsed.payload && typeof parsed.payload === "object" ? parsed.payload : { result: parsed.payload } };
37267
+ return {
37268
+ success: true,
37269
+ ...parsed.payload && typeof parsed.payload === "object" ? parsed.payload : { result: parsed.payload },
37270
+ ...buildControlScriptResult(scriptName, parsed.payload)
37271
+ };
36963
37272
  } catch (e) {
36964
37273
  return { success: false, error: `Script execution failed: ${e.message}` };
36965
37274
  }
@@ -37022,7 +37331,7 @@ ${effect.notification.body || ""}`.trim();
37022
37331
  if (parsed && typeof parsed === "object" && parsed.success === false) {
37023
37332
  return { success: false, ...parsed };
37024
37333
  }
37025
- return { success: true, ...parsed };
37334
+ return { success: true, ...parsed, ...buildControlScriptResult(scriptName, parsed) };
37026
37335
  } catch {
37027
37336
  return { success: true, result };
37028
37337
  }
@@ -37033,9 +37342,6 @@ ${effect.notification.body || ""}`.trim();
37033
37342
  return { success: false, error: `Script execution failed: ${e.message}` };
37034
37343
  }
37035
37344
  }
37036
- async function handleExtensionScript(h, args, scriptName) {
37037
- return executeProviderScript(h, args, scriptName);
37038
- }
37039
37345
  async function handleProviderScript(h, args) {
37040
37346
  const scriptName = typeof args?.scriptName === "string" ? args.scriptName.trim() : "";
37041
37347
  if (!scriptName) return { success: false, error: "scriptName is required" };
@@ -37474,11 +37780,7 @@ ${effect.notification.body || ""}`.trim();
37474
37780
  "focus_session",
37475
37781
  "pty_input",
37476
37782
  "pty_resize",
37477
- "invoke_provider_script",
37478
- "list_extension_models",
37479
- "set_extension_model",
37480
- "list_extension_modes",
37481
- "set_extension_mode"
37783
+ "invoke_provider_script"
37482
37784
  ]);
37483
37785
  if (this._currentRoute.sessionLookupFailed && sessionScopedCommands.has(cmd)) {
37484
37786
  const result2 = {
@@ -37590,17 +37892,9 @@ ${effect.notification.body || ""}`.trim();
37590
37892
  return handleGetIdeExtensions(this, args);
37591
37893
  case "set_ide_extension":
37592
37894
  return handleSetIdeExtension(this, args);
37593
- // ─── Extension Model / Mode Control (stream-commands.ts) ──────────
37895
+ // ─── Provider control execution (stream-commands.ts) ──────────
37594
37896
  case "invoke_provider_script":
37595
37897
  return handleProviderScript(this, args);
37596
- case "list_extension_models":
37597
- return handleExtensionScript(this, args, "listModels");
37598
- case "set_extension_model":
37599
- return handleExtensionScript(this, args, "setModel");
37600
- case "list_extension_modes":
37601
- return handleExtensionScript(this, args, "listModes");
37602
- case "set_extension_mode":
37603
- return handleExtensionScript(this, args, "setMode");
37604
37898
  // ─── Provider Auto-Fix / Clone (DevServer proxy) ──────────
37605
37899
  case "provider_auto_fix":
37606
37900
  return this.proxyDevServerPost(args, "auto-implement");
@@ -37715,7 +38009,7 @@ ${effect.notification.body || ""}`.trim();
37715
38009
  }
37716
38010
  };
37717
38011
  var os12 = __toESM2(require("os"));
37718
- var path12 = __toESM2(require("path"));
38012
+ var path13 = __toESM2(require("path"));
37719
38013
  var crypto4 = __toESM2(require("crypto"));
37720
38014
  var import_chalk = __toESM2(require("chalk"));
37721
38015
  init_provider_cli_adapter();
@@ -37738,6 +38032,23 @@ ${effect.notification.body || ""}`.trim();
37738
38032
  }
37739
38033
  return CachedDatabaseSync;
37740
38034
  }
38035
+ function getForcedNewSessionScriptName(provider, launchMode) {
38036
+ if (!provider || launchMode !== "new") return null;
38037
+ const resume = provider.resume;
38038
+ if (!resume?.supported) return null;
38039
+ if (Array.isArray(resume.newSessionArgs) && resume.newSessionArgs.length > 0) return null;
38040
+ const controls = Array.isArray(provider.controls) ? provider.controls : [];
38041
+ for (const control of controls) {
38042
+ if (control?.type !== "action") continue;
38043
+ const invokeScript = typeof control?.invokeScript === "string" ? control.invokeScript.trim() : "";
38044
+ if (!invokeScript) continue;
38045
+ const controlId = typeof control?.id === "string" ? control.id.trim() : "";
38046
+ if (controlId === "new_session" || /^new.?session$/i.test(invokeScript)) {
38047
+ return invokeScript;
38048
+ }
38049
+ }
38050
+ return null;
38051
+ }
37741
38052
  var CliProviderInstance = class {
37742
38053
  constructor(provider, workingDir, cliArgs = [], instanceId, transportFactory, options) {
37743
38054
  this.provider = provider;
@@ -37796,6 +38107,7 @@ ${effect.notification.body || ""}`.trim();
37796
38107
  this.detectStatusTransition();
37797
38108
  });
37798
38109
  await this.adapter.spawn();
38110
+ await this.enforceFreshSessionLaunchIfNeeded();
37799
38111
  this.maybeAppendRuntimeRecoveryMessage(this.adapter.getRuntimeMetadata());
37800
38112
  if (this.providerSessionId) {
37801
38113
  this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
@@ -37987,10 +38299,13 @@ ${effect.notification.body || ""}`.trim();
37987
38299
  });
37988
38300
  }
37989
38301
  onEvent(event, data) {
37990
- if (event === "send_message" && data?.text) {
37991
- void this.adapter.sendMessage(data.text).catch((e) => {
37992
- LOG2.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
37993
- });
38302
+ if (event === "send_message") {
38303
+ const input = normalizeInputEnvelope(data);
38304
+ if (input.textFallback) {
38305
+ void this.adapter.sendMessage(input.textFallback).catch((e) => {
38306
+ LOG2.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
38307
+ });
38308
+ }
37994
38309
  } else if (event === "server_connected" && data?.serverConn) {
37995
38310
  this.adapter.setServerConn(data.serverConn);
37996
38311
  } else if (event === "resolve_action" && data) {
@@ -38008,6 +38323,23 @@ ${effect.notification.body || ""}`.trim();
38008
38323
  }
38009
38324
  completedDebounceTimer = null;
38010
38325
  completedDebouncePending = null;
38326
+ async enforceFreshSessionLaunchIfNeeded() {
38327
+ const scriptName = getForcedNewSessionScriptName(this.provider, this.launchMode);
38328
+ if (!scriptName) return;
38329
+ LOG2.info("CLI", `[${this.type}] forcing fresh session launch via script: ${scriptName}`);
38330
+ const raw = await this.adapter.invokeScript(scriptName, {});
38331
+ const parsed = parseCliScriptResult(raw);
38332
+ if (!parsed.success) {
38333
+ throw new Error(parsed.payload?.error || `Failed to invoke fresh-session script '${scriptName}'`);
38334
+ }
38335
+ const cliCommand = getCliScriptCommand(parsed.payload);
38336
+ if (cliCommand?.type === "send_message" && cliCommand.text) {
38337
+ await this.adapter.sendMessage(cliCommand.text);
38338
+ } else if (cliCommand?.type === "pty_write" && cliCommand.text) {
38339
+ this.adapter.writeRaw(cliCommand.text + "\r");
38340
+ }
38341
+ this.applyProviderResponse(parsed.payload, { phase: "immediate" });
38342
+ }
38011
38343
  detectStatusTransition() {
38012
38344
  const now = Date.now();
38013
38345
  const adapterStatus = this.adapter.getStatus();
@@ -38389,10 +38721,106 @@ ${effect.notification.body || ""}`.trim();
38389
38721
  }
38390
38722
  }
38391
38723
  };
38724
+ var path12 = __toESM2(require("path"));
38392
38725
  var import_stream = require("stream");
38393
38726
  var import_child_process5 = require("child_process");
38394
38727
  var import_sdk = (init_acp(), __toCommonJS(acp_exports));
38395
38728
  init_logger();
38729
+ function getPromptCapabilityFlags(agentCapabilities) {
38730
+ const prompt = agentCapabilities?.promptCapabilities || {};
38731
+ return {
38732
+ image: prompt.image === true,
38733
+ audio: prompt.audio === true,
38734
+ embeddedContext: prompt.embeddedContext === true
38735
+ };
38736
+ }
38737
+ function getResourceNameFromUri(uri, fallback) {
38738
+ try {
38739
+ if (uri.startsWith("file://")) {
38740
+ return path12.basename(new URL(uri).pathname) || fallback;
38741
+ }
38742
+ return path12.basename(uri) || fallback;
38743
+ } catch {
38744
+ return fallback;
38745
+ }
38746
+ }
38747
+ function inputPartToResourceLink(part, fallbackName) {
38748
+ if (!part.uri) return null;
38749
+ return {
38750
+ type: "resource_link",
38751
+ uri: part.uri,
38752
+ name: getResourceNameFromUri(part.uri, fallbackName),
38753
+ ...part.mimeType ? { mimeType: part.mimeType } : {}
38754
+ };
38755
+ }
38756
+ function appendPromptText(promptParts, text) {
38757
+ const normalized = typeof text === "string" ? text.trim() : "";
38758
+ if (!normalized) return;
38759
+ const last = promptParts[promptParts.length - 1];
38760
+ if (last?.type === "text" && last.text === normalized) return;
38761
+ promptParts.push({ type: "text", text: normalized });
38762
+ }
38763
+ function buildAcpPromptParts(input, agentCapabilities) {
38764
+ const caps = getPromptCapabilityFlags(agentCapabilities);
38765
+ const promptParts = [];
38766
+ for (const part of input.parts) {
38767
+ if (part.type === "text") {
38768
+ promptParts.push({ type: "text", text: part.text });
38769
+ continue;
38770
+ }
38771
+ if (part.type === "image") {
38772
+ if (caps.image && part.data) {
38773
+ promptParts.push({
38774
+ type: "image",
38775
+ data: part.data,
38776
+ mimeType: part.mimeType,
38777
+ ...part.uri ? { uri: part.uri } : {}
38778
+ });
38779
+ continue;
38780
+ }
38781
+ const fallback = inputPartToResourceLink(part, "image");
38782
+ if (fallback) promptParts.push(fallback);
38783
+ appendPromptText(promptParts, part.alt || (!part.uri ? `Attached image (${part.mimeType})` : void 0));
38784
+ continue;
38785
+ }
38786
+ if (part.type === "audio") {
38787
+ if (caps.audio && part.data) {
38788
+ promptParts.push({
38789
+ type: "audio",
38790
+ data: part.data,
38791
+ mimeType: part.mimeType
38792
+ });
38793
+ continue;
38794
+ }
38795
+ const fallback = inputPartToResourceLink(part, "audio");
38796
+ if (fallback) promptParts.push(fallback);
38797
+ appendPromptText(promptParts, part.transcript || (!part.uri ? `Attached audio (${part.mimeType})` : void 0));
38798
+ continue;
38799
+ }
38800
+ if (part.type === "resource") {
38801
+ if (caps.embeddedContext && (part.text || part.data)) {
38802
+ promptParts.push({
38803
+ type: "resource",
38804
+ resource: part.text ? { uri: part.uri, text: part.text, mimeType: part.mimeType ?? null } : { uri: part.uri, blob: part.data || "", mimeType: part.mimeType ?? null }
38805
+ });
38806
+ continue;
38807
+ }
38808
+ const fallback = inputPartToResourceLink(part, part.name || "resource");
38809
+ if (fallback) promptParts.push(fallback);
38810
+ appendPromptText(promptParts, part.text || (!part.uri && part.name ? part.name : void 0));
38811
+ continue;
38812
+ }
38813
+ if (part.type === "video") {
38814
+ const fallback = inputPartToResourceLink(part, "video");
38815
+ if (fallback) promptParts.push(fallback);
38816
+ appendPromptText(promptParts, !part.uri ? `Attached video (${part.mimeType})` : void 0);
38817
+ }
38818
+ }
38819
+ if (!promptParts.some((part) => part.type === "text") && input.textFallback) {
38820
+ promptParts.unshift({ type: "text", text: input.textFallback });
38821
+ }
38822
+ return promptParts;
38823
+ }
38396
38824
  var AcpProviderInstance = class {
38397
38825
  constructor(provider, workingDir, cliArgs = []) {
38398
38826
  this.cliArgs = cliArgs;
@@ -38521,8 +38949,10 @@ ${effect.notification.body || ""}`.trim();
38521
38949
  };
38522
38950
  }
38523
38951
  onEvent(event, data) {
38524
- if (event === "send_message" && data?.text) {
38525
- this.sendPrompt(data.text).catch(
38952
+ if (event === "send_message") {
38953
+ const input = normalizeInputEnvelope(data);
38954
+ const promptParts = buildAcpPromptParts(input, this.agentCapabilities);
38955
+ this.sendPrompt(input.textFallback, promptParts.length > 0 ? promptParts : void 0).catch(
38526
38956
  (e) => this.log.warn(`[${this.type}] sendPrompt error: ${e?.message}`)
38527
38957
  );
38528
38958
  } else if (event === "resolve_action") {
@@ -38947,18 +39377,34 @@ ${effect.notification.body || ""}`.trim();
38947
39377
  this.log.warn(`[${this.type}] Cannot send prompt: no active connection/session`);
38948
39378
  return;
38949
39379
  }
38950
- let promptParts;
38951
- if (contentBlocks && contentBlocks.length > 0) {
38952
- promptParts = contentBlocks.map((b2) => {
38953
- if (b2.type === "text") return { type: "text", text: b2.text };
38954
- if (b2.type === "image") return { type: "image", data: b2.data, mimeType: b2.mimeType };
38955
- if (b2.type === "resource_link") return { type: "resource_link", uri: b2.uri, name: b2.name };
38956
- if (b2.type === "resource") return { type: "resource", resource: b2.resource };
38957
- return { type: "text", text: flattenContent([b2]) };
38958
- });
38959
- } else {
38960
- promptParts = [{ type: "text", text }];
38961
- }
39380
+ const promptParts = contentBlocks && contentBlocks.length > 0 ? contentBlocks.map((b2) => {
39381
+ if (b2.type === "text") return { type: "text", text: b2.text };
39382
+ if (b2.type === "image") {
39383
+ return {
39384
+ type: "image",
39385
+ data: b2.data,
39386
+ mimeType: b2.mimeType,
39387
+ ...b2.uri ? { uri: b2.uri } : {}
39388
+ };
39389
+ }
39390
+ if (b2.type === "audio") {
39391
+ return {
39392
+ type: "audio",
39393
+ data: b2.data,
39394
+ mimeType: b2.mimeType
39395
+ };
39396
+ }
39397
+ if (b2.type === "resource_link") {
39398
+ return {
39399
+ type: "resource_link",
39400
+ uri: b2.uri,
39401
+ name: b2.name,
39402
+ ...b2.mimeType ? { mimeType: b2.mimeType } : {}
39403
+ };
39404
+ }
39405
+ if (b2.type === "resource") return { type: "resource", resource: b2.resource };
39406
+ return { type: "text", text: flattenContent([b2]) };
39407
+ }) : [{ type: "text", text }];
38962
39408
  this.messages.push({
38963
39409
  role: "user",
38964
39410
  content: contentBlocks && contentBlocks.length > 0 ? contentBlocks : text,
@@ -39022,6 +39468,13 @@ ${effect.notification.body || ""}`.trim();
39022
39468
  this.partialBlocks.push({
39023
39469
  type: "image",
39024
39470
  data: content.data,
39471
+ mimeType: content.mimeType,
39472
+ ...content.uri ? { uri: content.uri } : {}
39473
+ });
39474
+ } else if (content.type === "audio") {
39475
+ this.partialBlocks.push({
39476
+ type: "audio",
39477
+ data: content.data,
39025
39478
  mimeType: content.mimeType
39026
39479
  });
39027
39480
  } else if (content.type === "resource_link") {
@@ -39407,7 +39860,7 @@ ${effect.notification.body || ""}`.trim();
39407
39860
  };
39408
39861
  }
39409
39862
  if (!supportsExplicitSessionStart(resume)) {
39410
- return { cliArgs: baseArgs, launchMode: "manual" };
39863
+ return { cliArgs: baseArgs, launchMode: "new" };
39411
39864
  }
39412
39865
  const providerSessionId = crypto4.randomUUID();
39413
39866
  const newSessionArgs = expandResumeArgs(resume.newSessionArgs, providerSessionId);
@@ -39555,7 +40008,7 @@ ${effect.notification.body || ""}`.trim();
39555
40008
  async startSession(cliType, workingDir, cliArgs, initialModel, options) {
39556
40009
  const trimmed = (workingDir || "").trim();
39557
40010
  if (!trimmed) throw new Error("working directory required");
39558
- const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os12.homedir()) : path12.resolve(trimmed);
40011
+ const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os12.homedir()) : path13.resolve(trimmed);
39559
40012
  const normalizedType = this.providerLoader.resolveAlias(cliType);
39560
40013
  const provider = this.providerLoader.getByAlias(cliType);
39561
40014
  const key = crypto4.randomUUID();
@@ -39603,7 +40056,8 @@ ${installInfo}`
39603
40056
  instanceManager2.removeInstance(key);
39604
40057
  },
39605
40058
  sendMessage: async (text) => {
39606
- acpInstance.onEvent("send_message", { text });
40059
+ const input = normalizeInputEnvelope(text);
40060
+ acpInstance.onEvent("send_message", { input });
39607
40061
  },
39608
40062
  getStatus: () => {
39609
40063
  const state = acpInstance.getState();
@@ -40012,7 +40466,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
40012
40466
  if (!found) throw new Error(`CLI agent not running: ${agentType}`);
40013
40467
  const { adapter, key } = found;
40014
40468
  if (action === "send_chat") {
40015
- const message = args.message || args.text;
40469
+ const input = normalizeInputEnvelope(args?.input ? { input: args.input } : args);
40470
+ const message = input.textFallback;
40016
40471
  if (!message) throw new Error("message required for send_chat");
40017
40472
  await adapter.sendMessage(message);
40018
40473
  return { success: true, status: "generating" };
@@ -40032,12 +40487,138 @@ Run 'adhdev doctor' for detailed diagnostics.`
40032
40487
  var import_child_process6 = require("child_process");
40033
40488
  var net3 = __toESM2(require("net"));
40034
40489
  var os14 = __toESM2(require("os"));
40035
- var path14 = __toESM2(require("path"));
40490
+ var path15 = __toESM2(require("path"));
40036
40491
  var fs6 = __toESM2(require("fs"));
40037
- var path13 = __toESM2(require("path"));
40492
+ var path14 = __toESM2(require("path"));
40038
40493
  var os13 = __toESM2(require("os"));
40039
40494
  var chokidar = __toESM2((init_chokidar(), __toCommonJS(chokidar_exports)));
40040
40495
  init_logger();
40496
+ var KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
40497
+ "type",
40498
+ "name",
40499
+ "category",
40500
+ "aliases",
40501
+ "cdpPorts",
40502
+ "targetFilter",
40503
+ "cli",
40504
+ "icon",
40505
+ "displayName",
40506
+ "install",
40507
+ "versionCommand",
40508
+ "testedVersions",
40509
+ "processNames",
40510
+ "launch",
40511
+ "paths",
40512
+ "extensionId",
40513
+ "extensionIdPattern",
40514
+ "extensionIdPattern_flags",
40515
+ "compatibility",
40516
+ "defaultScriptDir",
40517
+ "binary",
40518
+ "spawn",
40519
+ "approvalKeys",
40520
+ "patterns",
40521
+ "cleanOutput",
40522
+ "resume",
40523
+ "sessionProbe",
40524
+ "approvalPositiveHints",
40525
+ "scripts",
40526
+ "vscodeCommands",
40527
+ "inputMethod",
40528
+ "inputSelector",
40529
+ "webviewMatchText",
40530
+ "os",
40531
+ "versions",
40532
+ "overrides",
40533
+ "settings",
40534
+ "controls",
40535
+ "staticConfigOptions",
40536
+ "spawnArgBuilder",
40537
+ "auth",
40538
+ "contractVersion",
40539
+ "capabilities",
40540
+ "providerVersion",
40541
+ "status",
40542
+ "details",
40543
+ "sendDelayMs",
40544
+ "sendKey",
40545
+ "submitStrategy",
40546
+ "disableUpstream"
40547
+ ]);
40548
+ var VALUE_CONTROL_TYPES = /* @__PURE__ */ new Set(["select", "toggle", "cycle", "slider"]);
40549
+ function validateProviderDefinition(raw) {
40550
+ const errors = [];
40551
+ const warnings = [];
40552
+ if (!raw || typeof raw !== "object") {
40553
+ return { errors: ["Provider definition must be an object"], warnings };
40554
+ }
40555
+ const provider = raw;
40556
+ if (!provider.type) errors.push("Missing required field: type");
40557
+ if (!provider.name) errors.push("Missing required field: name");
40558
+ if (!provider.category) {
40559
+ errors.push("Missing required field: category");
40560
+ } else if (!["ide", "extension", "cli", "acp"].includes(String(provider.category))) {
40561
+ errors.push(`Invalid category: ${String(provider.category)}`);
40562
+ }
40563
+ for (const key of Object.keys(provider)) {
40564
+ if (!KNOWN_PROVIDER_FIELDS.has(key)) {
40565
+ warnings.push(`Unknown provider field: ${key}`);
40566
+ }
40567
+ }
40568
+ const category = provider.category;
40569
+ if (category === "cli" || category === "acp") {
40570
+ const spawn4 = provider.spawn;
40571
+ const command = spawn4 && typeof spawn4 === "object" ? spawn4.command : void 0;
40572
+ if (!spawn4 || typeof spawn4 !== "object") {
40573
+ errors.push(`${String(category).toUpperCase()}/CLI providers must have spawn config`);
40574
+ } else if (typeof command !== "string" || !command.trim()) {
40575
+ errors.push("spawn.command is required");
40576
+ }
40577
+ }
40578
+ if ((category === "ide" || category === "extension") && provider.cdpPorts !== void 0) {
40579
+ if (!Array.isArray(provider.cdpPorts) || provider.cdpPorts.length === 0) {
40580
+ warnings.push("IDE/Extension providers should have cdpPorts");
40581
+ }
40582
+ }
40583
+ if (category === "extension" && !provider.extensionId) {
40584
+ warnings.push("Extension providers should have extensionId");
40585
+ }
40586
+ for (const control of Array.isArray(provider.controls) ? provider.controls : []) {
40587
+ validateControl(control, errors);
40588
+ }
40589
+ return { errors, warnings };
40590
+ }
40591
+ function validateControl(control, errors) {
40592
+ if (!control || typeof control !== "object") {
40593
+ errors.push("controls: each control must be an object");
40594
+ return;
40595
+ }
40596
+ const id = typeof control.id === "string" && control.id.trim() ? control.id.trim() : "unknown";
40597
+ const prefix = `controls.${id}`;
40598
+ if (!control.id || !String(control.id).trim()) errors.push(`${prefix}: id is required`);
40599
+ if (!control.type) errors.push(`${prefix}: type is required`);
40600
+ if (!control.label || !String(control.label).trim()) errors.push(`${prefix}: label is required`);
40601
+ if (!control.placement) errors.push(`${prefix}: placement is required`);
40602
+ if (control.dynamic && !control.listScript) {
40603
+ errors.push(`${prefix}: dynamic controls require listScript`);
40604
+ }
40605
+ if (VALUE_CONTROL_TYPES.has(control.type) && !control.setScript) {
40606
+ errors.push(`${prefix}: ${control.type} controls require setScript`);
40607
+ }
40608
+ if (control.type === "action" && !control.invokeScript) {
40609
+ errors.push(`${prefix}: action controls require invokeScript`);
40610
+ }
40611
+ if (control.type === "slider") {
40612
+ if (typeof control.min !== "number" || typeof control.max !== "number") {
40613
+ errors.push(`${prefix}: slider controls require numeric min and max`);
40614
+ } else if (control.min > control.max) {
40615
+ errors.push(`${prefix}: slider min cannot exceed max`);
40616
+ }
40617
+ }
40618
+ if (control.readFrom !== void 0 && (typeof control.readFrom !== "string" || !control.readFrom.trim())) {
40619
+ errors.push(`${prefix}: readFrom must be a non-empty string when provided`);
40620
+ }
40621
+ }
40041
40622
  var ProviderLoader = class _ProviderLoader {
40042
40623
  providers = /* @__PURE__ */ new Map();
40043
40624
  providerAvailability = /* @__PURE__ */ new Map();
@@ -40056,12 +40637,12 @@ Run 'adhdev doctor' for detailed diagnostics.`
40056
40637
  static META_FILE = ".meta.json";
40057
40638
  constructor(options) {
40058
40639
  this.logFn = options?.logFn || LOG2.forComponent("Provider").asLogFn();
40059
- const defaultProvidersDir = path13.join(os13.homedir(), ".adhdev", "providers");
40640
+ const defaultProvidersDir = path14.join(os13.homedir(), ".adhdev", "providers");
40060
40641
  if (options?.userDir) {
40061
40642
  this.userDir = options.userDir;
40062
40643
  this.log(`Config 'providerDir' applied: ${this.userDir}`);
40063
40644
  } else {
40064
- const localRepoPath = path13.resolve(__dirname, "../../../../../adhdev-providers");
40645
+ const localRepoPath = path14.resolve(__dirname, "../../../../../adhdev-providers");
40065
40646
  if (fs6.existsSync(localRepoPath)) {
40066
40647
  this.userDir = localRepoPath;
40067
40648
  this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
@@ -40070,7 +40651,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
40070
40651
  this.log(`Using default user providers directory: ${this.userDir}`);
40071
40652
  }
40072
40653
  }
40073
- this.upstreamDir = path13.join(defaultProvidersDir, ".upstream");
40654
+ this.upstreamDir = path14.join(defaultProvidersDir, ".upstream");
40074
40655
  this.disableUpstream = options?.disableUpstream ?? false;
40075
40656
  }
40076
40657
  log(msg) {
@@ -40100,7 +40681,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
40100
40681
  * Canonical provider directory shape for a given root.
40101
40682
  */
40102
40683
  getProviderDir(root, category, type) {
40103
- return path13.join(root, category, type);
40684
+ return path14.join(root, category, type);
40104
40685
  }
40105
40686
  /**
40106
40687
  * Canonical user override directory for a provider.
@@ -40127,7 +40708,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
40127
40708
  resolveProviderFile(type, ...segments) {
40128
40709
  const dir = this.findProviderDirInternal(type);
40129
40710
  if (!dir) return null;
40130
- return path13.join(dir, ...segments);
40711
+ return path14.join(dir, ...segments);
40131
40712
  }
40132
40713
  /**
40133
40714
  * Load all providers (3-tier priority)
@@ -40166,7 +40747,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
40166
40747
  if (!fs6.existsSync(this.upstreamDir)) return false;
40167
40748
  try {
40168
40749
  return fs6.readdirSync(this.upstreamDir).some(
40169
- (d) => fs6.statSync(path13.join(this.upstreamDir, d)).isDirectory()
40750
+ (d) => fs6.statSync(path14.join(this.upstreamDir, d)).isDirectory()
40170
40751
  );
40171
40752
  } catch {
40172
40753
  return false;
@@ -40481,8 +41062,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
40481
41062
  resolved._resolvedScriptDir = entry.scriptDir;
40482
41063
  resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
40483
41064
  if (providerDir) {
40484
- const fullDir = path13.join(providerDir, entry.scriptDir);
40485
- resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
41065
+ const fullDir = path14.join(providerDir, entry.scriptDir);
41066
+ resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
40486
41067
  }
40487
41068
  matched = true;
40488
41069
  }
@@ -40497,8 +41078,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
40497
41078
  resolved._resolvedScriptDir = base.defaultScriptDir;
40498
41079
  resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
40499
41080
  if (providerDir) {
40500
- const fullDir = path13.join(providerDir, base.defaultScriptDir);
40501
- resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
41081
+ const fullDir = path14.join(providerDir, base.defaultScriptDir);
41082
+ resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
40502
41083
  }
40503
41084
  }
40504
41085
  resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
@@ -40515,8 +41096,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
40515
41096
  resolved._resolvedScriptDir = dirOverride;
40516
41097
  resolved._resolvedScriptsSource = `versions:${range}`;
40517
41098
  if (providerDir) {
40518
- const fullDir = path13.join(providerDir, dirOverride);
40519
- resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
41099
+ const fullDir = path14.join(providerDir, dirOverride);
41100
+ resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
40520
41101
  }
40521
41102
  }
40522
41103
  } else if (override.scripts) {
@@ -40532,8 +41113,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
40532
41113
  resolved._resolvedScriptDir = base.defaultScriptDir;
40533
41114
  resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
40534
41115
  if (providerDir) {
40535
- const fullDir = path13.join(providerDir, base.defaultScriptDir);
40536
- resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
41116
+ const fullDir = path14.join(providerDir, base.defaultScriptDir);
41117
+ resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
40537
41118
  }
40538
41119
  }
40539
41120
  }
@@ -40558,14 +41139,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
40558
41139
  this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
40559
41140
  return null;
40560
41141
  }
40561
- const dir = path13.join(providerDir, scriptDir);
41142
+ const dir = path14.join(providerDir, scriptDir);
40562
41143
  if (!fs6.existsSync(dir)) {
40563
41144
  this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
40564
41145
  return null;
40565
41146
  }
40566
41147
  const cached2 = this.scriptsCache.get(dir);
40567
41148
  if (cached2) return cached2;
40568
- const scriptsJs = path13.join(dir, "scripts.js");
41149
+ const scriptsJs = path14.join(dir, "scripts.js");
40569
41150
  if (fs6.existsSync(scriptsJs)) {
40570
41151
  try {
40571
41152
  delete require.cache[require.resolve(scriptsJs)];
@@ -40607,7 +41188,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
40607
41188
  return;
40608
41189
  }
40609
41190
  if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
40610
- this.log(`File changed: ${path13.basename(filePath)}, reloading...`);
41191
+ this.log(`File changed: ${path14.basename(filePath)}, reloading...`);
40611
41192
  this.reload();
40612
41193
  }
40613
41194
  };
@@ -40662,7 +41243,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
40662
41243
  }
40663
41244
  const https = require("https");
40664
41245
  const { execSync: execSync7 } = require("child_process");
40665
- const metaPath = path13.join(this.upstreamDir, _ProviderLoader.META_FILE);
41246
+ const metaPath = path14.join(this.upstreamDir, _ProviderLoader.META_FILE);
40666
41247
  let prevEtag = "";
40667
41248
  let prevTimestamp = 0;
40668
41249
  try {
@@ -40722,17 +41303,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
40722
41303
  return { updated: false };
40723
41304
  }
40724
41305
  this.log("Downloading latest providers from GitHub...");
40725
- const tmpTar = path13.join(os13.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
40726
- const tmpExtract = path13.join(os13.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
41306
+ const tmpTar = path14.join(os13.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
41307
+ const tmpExtract = path14.join(os13.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
40727
41308
  await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
40728
41309
  fs6.mkdirSync(tmpExtract, { recursive: true });
40729
41310
  execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
40730
41311
  const extracted = fs6.readdirSync(tmpExtract);
40731
41312
  const rootDir = extracted.find(
40732
- (d) => fs6.statSync(path13.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
41313
+ (d) => fs6.statSync(path14.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
40733
41314
  );
40734
41315
  if (!rootDir) throw new Error("Unexpected tarball structure");
40735
- const sourceDir = path13.join(tmpExtract, rootDir);
41316
+ const sourceDir = path14.join(tmpExtract, rootDir);
40736
41317
  const backupDir = this.upstreamDir + ".bak";
40737
41318
  if (fs6.existsSync(this.upstreamDir)) {
40738
41319
  if (fs6.existsSync(backupDir)) fs6.rmSync(backupDir, { recursive: true, force: true });
@@ -40807,8 +41388,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
40807
41388
  copyDirRecursive(src, dest) {
40808
41389
  fs6.mkdirSync(dest, { recursive: true });
40809
41390
  for (const entry of fs6.readdirSync(src, { withFileTypes: true })) {
40810
- const srcPath = path13.join(src, entry.name);
40811
- const destPath = path13.join(dest, entry.name);
41391
+ const srcPath = path14.join(src, entry.name);
41392
+ const destPath = path14.join(dest, entry.name);
40812
41393
  if (entry.isDirectory()) {
40813
41394
  this.copyDirRecursive(srcPath, destPath);
40814
41395
  } else {
@@ -40819,7 +41400,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
40819
41400
  /** .meta.json save */
40820
41401
  writeMeta(metaPath, etag, timestamp) {
40821
41402
  try {
40822
- fs6.mkdirSync(path13.dirname(metaPath), { recursive: true });
41403
+ fs6.mkdirSync(path14.dirname(metaPath), { recursive: true });
40823
41404
  fs6.writeFileSync(metaPath, JSON.stringify({
40824
41405
  etag,
40825
41406
  timestamp,
@@ -40836,7 +41417,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
40836
41417
  const scan = (d) => {
40837
41418
  try {
40838
41419
  for (const entry of fs6.readdirSync(d, { withFileTypes: true })) {
40839
- if (entry.isDirectory()) scan(path13.join(d, entry.name));
41420
+ if (entry.isDirectory()) scan(path14.join(d, entry.name));
40840
41421
  else if (entry.name === "provider.json") count++;
40841
41422
  }
40842
41423
  } catch {
@@ -41021,17 +41602,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
41021
41602
  for (const root of searchRoots) {
41022
41603
  if (!fs6.existsSync(root)) continue;
41023
41604
  const candidate = this.getProviderDir(root, cat, type);
41024
- if (fs6.existsSync(path13.join(candidate, "provider.json"))) return candidate;
41025
- const catDir = path13.join(root, cat);
41605
+ if (fs6.existsSync(path14.join(candidate, "provider.json"))) return candidate;
41606
+ const catDir = path14.join(root, cat);
41026
41607
  if (fs6.existsSync(catDir)) {
41027
41608
  try {
41028
41609
  for (const entry of fs6.readdirSync(catDir, { withFileTypes: true })) {
41029
41610
  if (!entry.isDirectory()) continue;
41030
- const jsonPath = path13.join(catDir, entry.name, "provider.json");
41611
+ const jsonPath = path14.join(catDir, entry.name, "provider.json");
41031
41612
  if (fs6.existsSync(jsonPath)) {
41032
41613
  try {
41033
41614
  const data = JSON.parse(fs6.readFileSync(jsonPath, "utf-8"));
41034
- if (data.type === type) return path13.join(catDir, entry.name);
41615
+ if (data.type === type) return path14.join(catDir, entry.name);
41035
41616
  } catch {
41036
41617
  }
41037
41618
  }
@@ -41048,7 +41629,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
41048
41629
  * (template substitution is NOT applied here — scripts.js handles that)
41049
41630
  */
41050
41631
  buildScriptWrappersFromDir(dir) {
41051
- const scriptsJs = path13.join(dir, "scripts.js");
41632
+ const scriptsJs = path14.join(dir, "scripts.js");
41052
41633
  if (fs6.existsSync(scriptsJs)) {
41053
41634
  try {
41054
41635
  delete require.cache[require.resolve(scriptsJs)];
@@ -41062,7 +41643,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
41062
41643
  for (const file2 of fs6.readdirSync(dir)) {
41063
41644
  if (!file2.endsWith(".js")) continue;
41064
41645
  const scriptName = toCamel(file2.replace(".js", ""));
41065
- const filePath = path13.join(dir, file2);
41646
+ const filePath = path14.join(dir, file2);
41066
41647
  result[scriptName] = (...args) => {
41067
41648
  try {
41068
41649
  let content = fs6.readFileSync(filePath, "utf-8");
@@ -41122,24 +41703,28 @@ Run 'adhdev doctor' for detailed diagnostics.`
41122
41703
  }
41123
41704
  const hasJson = entries.some((e) => e.name === "provider.json");
41124
41705
  if (hasJson) {
41125
- const jsonPath = path13.join(d, "provider.json");
41706
+ const jsonPath = path14.join(d, "provider.json");
41126
41707
  try {
41127
41708
  const raw = fs6.readFileSync(jsonPath, "utf-8");
41128
41709
  const mod = JSON.parse(raw);
41129
- if (!mod.type || !mod.name || !mod.category) {
41130
- this.log(`\u26A0 Invalid provider at ${jsonPath}: missing type/name/category`);
41710
+ if (typeof mod.extensionIdPattern === "string") {
41711
+ const flags = mod.extensionIdPattern_flags || "";
41712
+ mod.extensionIdPattern = new RegExp(mod.extensionIdPattern, flags);
41713
+ }
41714
+ const { extensionIdPattern_flags, extensionIdPattern, ...providerFields } = mod;
41715
+ const normalizedProvider = {
41716
+ ...providerFields,
41717
+ ...extensionIdPattern instanceof RegExp ? { extensionIdPattern } : {}
41718
+ };
41719
+ const validation = validateProviderDefinition(normalizedProvider);
41720
+ for (const warning of validation.warnings) {
41721
+ this.log(`\u26A0 ${jsonPath}: ${warning}`);
41722
+ }
41723
+ if (validation.errors.length > 0) {
41724
+ this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
41131
41725
  } else {
41132
- if (typeof mod.extensionIdPattern === "string") {
41133
- const flags = mod.extensionIdPattern_flags || "";
41134
- mod.extensionIdPattern = new RegExp(mod.extensionIdPattern, flags);
41135
- }
41136
- const { extensionIdPattern_flags, extensionIdPattern, ...providerFields } = mod;
41137
- const normalizedProvider = {
41138
- ...providerFields,
41139
- ...extensionIdPattern instanceof RegExp ? { extensionIdPattern } : {}
41140
- };
41141
41726
  const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
41142
- const scriptsPath = path13.join(d, "scripts.js");
41727
+ const scriptsPath = path14.join(d, "scripts.js");
41143
41728
  if (!hasCompatibility && fs6.existsSync(scriptsPath)) {
41144
41729
  try {
41145
41730
  delete require.cache[require.resolve(scriptsPath)];
@@ -41165,7 +41750,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
41165
41750
  if (!entry.isDirectory()) continue;
41166
41751
  if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
41167
41752
  if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
41168
- scan(path13.join(d, entry.name));
41753
+ scan(path14.join(d, entry.name));
41169
41754
  }
41170
41755
  }
41171
41756
  };
@@ -41421,8 +42006,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
41421
42006
  const appNameMap = getMacAppIdentifiers();
41422
42007
  const appName = appNameMap[ideId];
41423
42008
  if (appName) {
41424
- const storagePath = path14.join(
41425
- process.env.APPDATA || path14.join(os14.homedir(), "AppData", "Roaming"),
42009
+ const storagePath = path15.join(
42010
+ process.env.APPDATA || path15.join(os14.homedir(), "AppData", "Roaming"),
41426
42011
  appName,
41427
42012
  "storage.json"
41428
42013
  );
@@ -41596,9 +42181,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
41596
42181
  init_config();
41597
42182
  init_logger();
41598
42183
  var fs7 = __toESM2(require("fs"));
41599
- var path15 = __toESM2(require("path"));
42184
+ var path16 = __toESM2(require("path"));
41600
42185
  var os15 = __toESM2(require("os"));
41601
- var LOG_DIR2 = process.platform === "win32" ? path15.join(process.env.LOCALAPPDATA || process.env.APPDATA || path15.join(os15.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path15.join(os15.homedir(), "Library", "Logs", "adhdev") : path15.join(os15.homedir(), ".local", "share", "adhdev", "logs");
42186
+ var LOG_DIR2 = process.platform === "win32" ? path16.join(process.env.LOCALAPPDATA || process.env.APPDATA || path16.join(os15.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path16.join(os15.homedir(), "Library", "Logs", "adhdev") : path16.join(os15.homedir(), ".local", "share", "adhdev", "logs");
41602
42187
  var MAX_FILE_SIZE = 5 * 1024 * 1024;
41603
42188
  var MAX_DAYS = 7;
41604
42189
  try {
@@ -41636,13 +42221,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
41636
42221
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
41637
42222
  }
41638
42223
  var currentDate2 = getDateStr2();
41639
- var currentFile = path15.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
42224
+ var currentFile = path16.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
41640
42225
  var writeCount2 = 0;
41641
42226
  function checkRotation() {
41642
42227
  const today = getDateStr2();
41643
42228
  if (today !== currentDate2) {
41644
42229
  currentDate2 = today;
41645
- currentFile = path15.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
42230
+ currentFile = path16.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
41646
42231
  cleanOldFiles();
41647
42232
  }
41648
42233
  }
@@ -41656,7 +42241,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
41656
42241
  const dateMatch = file2.match(/commands-(\d{4}-\d{2}-\d{2})/);
41657
42242
  if (dateMatch && dateMatch[1] < cutoffStr) {
41658
42243
  try {
41659
- fs7.unlinkSync(path15.join(LOG_DIR2, file2));
42244
+ fs7.unlinkSync(path16.join(LOG_DIR2, file2));
41660
42245
  } catch {
41661
42246
  }
41662
42247
  }
@@ -41967,13 +42552,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
41967
42552
  var import_child_process8 = require("child_process");
41968
42553
  var fs8 = __toESM2(require("fs"));
41969
42554
  var os17 = __toESM2(require("os"));
41970
- var path16 = __toESM2(require("path"));
42555
+ var path17 = __toESM2(require("path"));
41971
42556
  var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
41972
42557
  function getUpgradeLogPath() {
41973
42558
  const home = os17.homedir();
41974
- const dir = path16.join(home, ".adhdev");
42559
+ const dir = path17.join(home, ".adhdev");
41975
42560
  fs8.mkdirSync(dir, { recursive: true });
41976
- return path16.join(dir, "daemon-upgrade.log");
42561
+ return path17.join(dir, "daemon-upgrade.log");
41977
42562
  }
41978
42563
  function appendUpgradeLog(message) {
41979
42564
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
@@ -42013,7 +42598,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
42013
42598
  }
42014
42599
  }
42015
42600
  function stopSessionHostProcesses(appName) {
42016
- const pidFile = path16.join(os17.homedir(), ".adhdev", `${appName}-session-host.pid`);
42601
+ const pidFile = path17.join(os17.homedir(), ".adhdev", `${appName}-session-host.pid`);
42017
42602
  try {
42018
42603
  if (fs8.existsSync(pidFile)) {
42019
42604
  const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
@@ -42042,7 +42627,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
42042
42627
  }
42043
42628
  }
42044
42629
  function removeDaemonPidFile() {
42045
- const pidFile = path16.join(os17.homedir(), ".adhdev", "daemon.pid");
42630
+ const pidFile = path17.join(os17.homedir(), ".adhdev", "daemon.pid");
42046
42631
  try {
42047
42632
  fs8.unlinkSync(pidFile);
42048
42633
  } catch {
@@ -42053,7 +42638,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
42053
42638
  const npmRoot = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["root", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
42054
42639
  if (!npmRoot) return;
42055
42640
  const npmPrefix = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["prefix", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
42056
- const binDir = process.platform === "win32" ? npmPrefix : path16.join(npmPrefix, "bin");
42641
+ const binDir = process.platform === "win32" ? npmPrefix : path17.join(npmPrefix, "bin");
42057
42642
  const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
42058
42643
  const binNames = /* @__PURE__ */ new Set([packageBaseName]);
42059
42644
  if (pkgName === "@adhdev/daemon-standalone") {
@@ -42061,25 +42646,25 @@ Run 'adhdev doctor' for detailed diagnostics.`
42061
42646
  }
42062
42647
  if (pkgName.startsWith("@")) {
42063
42648
  const [scope, name] = pkgName.split("/");
42064
- const scopeDir = path16.join(npmRoot, scope);
42649
+ const scopeDir = path17.join(npmRoot, scope);
42065
42650
  if (!fs8.existsSync(scopeDir)) return;
42066
42651
  for (const entry of fs8.readdirSync(scopeDir)) {
42067
42652
  if (!entry.startsWith(`.${name}-`)) continue;
42068
- fs8.rmSync(path16.join(scopeDir, entry), { recursive: true, force: true });
42069
- appendUpgradeLog(`Removed stale scoped staging dir: ${path16.join(scopeDir, entry)}`);
42653
+ fs8.rmSync(path17.join(scopeDir, entry), { recursive: true, force: true });
42654
+ appendUpgradeLog(`Removed stale scoped staging dir: ${path17.join(scopeDir, entry)}`);
42070
42655
  }
42071
42656
  } else {
42072
42657
  for (const entry of fs8.readdirSync(npmRoot)) {
42073
42658
  if (!entry.startsWith(`.${pkgName}-`)) continue;
42074
- fs8.rmSync(path16.join(npmRoot, entry), { recursive: true, force: true });
42075
- appendUpgradeLog(`Removed stale staging dir: ${path16.join(npmRoot, entry)}`);
42659
+ fs8.rmSync(path17.join(npmRoot, entry), { recursive: true, force: true });
42660
+ appendUpgradeLog(`Removed stale staging dir: ${path17.join(npmRoot, entry)}`);
42076
42661
  }
42077
42662
  }
42078
42663
  if (fs8.existsSync(binDir)) {
42079
42664
  for (const entry of fs8.readdirSync(binDir)) {
42080
42665
  if (![...binNames].some((name) => entry.startsWith(`.${name}-`))) continue;
42081
- fs8.rmSync(path16.join(binDir, entry), { recursive: true, force: true });
42082
- appendUpgradeLog(`Removed stale bin staging entry: ${path16.join(binDir, entry)}`);
42666
+ fs8.rmSync(path17.join(binDir, entry), { recursive: true, force: true });
42667
+ appendUpgradeLog(`Removed stale bin staging entry: ${path17.join(binDir, entry)}`);
42083
42668
  }
42084
42669
  }
42085
42670
  }
@@ -43937,11 +44522,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
43937
44522
  }
43938
44523
  };
43939
44524
  var fs10 = __toESM2(require("fs"));
43940
- var path17 = __toESM2(require("path"));
44525
+ var path18 = __toESM2(require("path"));
43941
44526
  var os18 = __toESM2(require("os"));
43942
44527
  var import_child_process9 = require("child_process");
43943
44528
  var import_os3 = require("os");
43944
- var ARCHIVE_PATH = path17.join(os18.homedir(), ".adhdev", "version-history.json");
44529
+ var ARCHIVE_PATH = path18.join(os18.homedir(), ".adhdev", "version-history.json");
43945
44530
  var MAX_ENTRIES_PER_PROVIDER = 20;
43946
44531
  var VersionArchive = class {
43947
44532
  history = {};
@@ -43988,7 +44573,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
43988
44573
  }
43989
44574
  save() {
43990
44575
  try {
43991
- fs10.mkdirSync(path17.dirname(ARCHIVE_PATH), { recursive: true });
44576
+ fs10.mkdirSync(path18.dirname(ARCHIVE_PATH), { recursive: true });
43992
44577
  fs10.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
43993
44578
  } catch {
43994
44579
  }
@@ -44045,7 +44630,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
44045
44630
  for (const p of paths) {
44046
44631
  if (p.includes("*")) {
44047
44632
  const home = os18.homedir();
44048
- const resolved = p.replace(/\*/g, home.split(path17.sep).pop() || "");
44633
+ const resolved = p.replace(/\*/g, home.split(path18.sep).pop() || "");
44049
44634
  if (fs10.existsSync(resolved)) return resolved;
44050
44635
  } else {
44051
44636
  if (fs10.existsSync(p)) return p;
@@ -44055,7 +44640,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
44055
44640
  }
44056
44641
  function getMacAppVersion(appPath) {
44057
44642
  if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
44058
- const plistPath = path17.join(appPath, "Contents", "Info.plist");
44643
+ const plistPath = path18.join(appPath, "Contents", "Info.plist");
44059
44644
  if (!fs10.existsSync(plistPath)) return null;
44060
44645
  const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
44061
44646
  return raw || null;
@@ -44081,7 +44666,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
44081
44666
  const cliBin = provider.cli ? findBinary2(provider.cli) : null;
44082
44667
  let resolvedBin = cliBin;
44083
44668
  if (!resolvedBin && appPath && currentOs === "darwin") {
44084
- const bundled = path17.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
44669
+ const bundled = path18.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
44085
44670
  if (provider.cli && fs10.existsSync(bundled)) resolvedBin = bundled;
44086
44671
  }
44087
44672
  info.installed = !!(appPath || resolvedBin);
@@ -44120,7 +44705,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
44120
44705
  }
44121
44706
  var http2 = __toESM2(require("http"));
44122
44707
  var fs14 = __toESM2(require("fs"));
44123
- var path21 = __toESM2(require("path"));
44708
+ var path222 = __toESM2(require("path"));
44124
44709
  function generateFiles(type, name, category, opts = {}) {
44125
44710
  const { cdpPorts, cli, processName, installPath, binary, extensionId, version: version2 = "0.1" } = opts;
44126
44711
  if (category === "cli" || category === "acp") {
@@ -44450,7 +45035,7 @@ async (params) => {
44450
45035
  }
44451
45036
  init_logger();
44452
45037
  var fs11 = __toESM2(require("fs"));
44453
- var path18 = __toESM2(require("path"));
45038
+ var path19 = __toESM2(require("path"));
44454
45039
  init_logger();
44455
45040
  async function handleCdpEvaluate(ctx, req, res) {
44456
45041
  const body = await ctx.readBody(req);
@@ -44629,17 +45214,17 @@ async (params) => {
44629
45214
  return;
44630
45215
  }
44631
45216
  let scriptsPath = "";
44632
- const directScripts = path18.join(dir, "scripts.js");
45217
+ const directScripts = path19.join(dir, "scripts.js");
44633
45218
  if (fs11.existsSync(directScripts)) {
44634
45219
  scriptsPath = directScripts;
44635
45220
  } else {
44636
- const scriptsDir = path18.join(dir, "scripts");
45221
+ const scriptsDir = path19.join(dir, "scripts");
44637
45222
  if (fs11.existsSync(scriptsDir)) {
44638
45223
  const versions = fs11.readdirSync(scriptsDir).filter((d) => {
44639
- return fs11.statSync(path18.join(scriptsDir, d)).isDirectory();
45224
+ return fs11.statSync(path19.join(scriptsDir, d)).isDirectory();
44640
45225
  }).sort().reverse();
44641
45226
  for (const ver of versions) {
44642
- const p = path18.join(scriptsDir, ver, "scripts.js");
45227
+ const p = path19.join(scriptsDir, ver, "scripts.js");
44643
45228
  if (fs11.existsSync(p)) {
44644
45229
  scriptsPath = p;
44645
45230
  break;
@@ -45466,7 +46051,7 @@ async (params) => {
45466
46051
  }
45467
46052
  }
45468
46053
  var fs12 = __toESM2(require("fs"));
45469
- var path19 = __toESM2(require("path"));
46054
+ var path20 = __toESM2(require("path"));
45470
46055
  function slugifyFixtureName(value) {
45471
46056
  const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
45472
46057
  return normalized || `fixture-${Date.now()}`;
@@ -45476,11 +46061,11 @@ async (params) => {
45476
46061
  if (!providerDir) {
45477
46062
  throw new Error(`Provider directory not found for '${type}'`);
45478
46063
  }
45479
- return path19.join(providerDir, "fixtures");
46064
+ return path20.join(providerDir, "fixtures");
45480
46065
  }
45481
46066
  function readCliFixture(ctx, type, name) {
45482
46067
  const fixtureDir = getCliFixtureDir(ctx, type);
45483
- const filePath = path19.join(fixtureDir, `${name}.json`);
46068
+ const filePath = path20.join(fixtureDir, `${name}.json`);
45484
46069
  if (!fs12.existsSync(filePath)) {
45485
46070
  throw new Error(`Fixture not found: ${filePath}`);
45486
46071
  }
@@ -46248,7 +46833,7 @@ async (params) => {
46248
46833
  },
46249
46834
  notes: typeof body?.notes === "string" ? body.notes : void 0
46250
46835
  };
46251
- const filePath = path19.join(fixtureDir, `${name}.json`);
46836
+ const filePath = path20.join(fixtureDir, `${name}.json`);
46252
46837
  fs12.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
46253
46838
  ctx.json(res, 200, {
46254
46839
  saved: true,
@@ -46272,7 +46857,7 @@ async (params) => {
46272
46857
  return;
46273
46858
  }
46274
46859
  const fixtures = fs12.readdirSync(fixtureDir).filter((file2) => file2.endsWith(".json")).sort((a, b2) => b2.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file2) => {
46275
- const fullPath = path19.join(fixtureDir, file2);
46860
+ const fullPath = path20.join(fixtureDir, file2);
46276
46861
  try {
46277
46862
  const raw = JSON.parse(fs12.readFileSync(fullPath, "utf-8"));
46278
46863
  return {
@@ -46406,7 +46991,7 @@ async (params) => {
46406
46991
  }
46407
46992
  }
46408
46993
  var fs13 = __toESM2(require("fs"));
46409
- var path20 = __toESM2(require("path"));
46994
+ var path21 = __toESM2(require("path"));
46410
46995
  var os19 = __toESM2(require("os"));
46411
46996
  function getAutoImplPid(ctx) {
46412
46997
  const pid = ctx.autoImplProcess?.pid;
@@ -46463,22 +47048,22 @@ async (params) => {
46463
47048
  if (!fs13.existsSync(scriptsDir)) return null;
46464
47049
  const versions = fs13.readdirSync(scriptsDir).filter((d) => {
46465
47050
  try {
46466
- return fs13.statSync(path20.join(scriptsDir, d)).isDirectory();
47051
+ return fs13.statSync(path21.join(scriptsDir, d)).isDirectory();
46467
47052
  } catch {
46468
47053
  return false;
46469
47054
  }
46470
47055
  }).sort((a, b2) => b2.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
46471
47056
  if (versions.length === 0) return null;
46472
- return path20.join(scriptsDir, versions[0]);
47057
+ return path21.join(scriptsDir, versions[0]);
46473
47058
  }
46474
47059
  function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
46475
- const canonicalUserDir = path20.resolve(ctx.providerLoader.getUserProviderDir(category, type));
46476
- const desiredDir = requestedDir ? path20.resolve(requestedDir) : canonicalUserDir;
46477
- const upstreamRoot = path20.resolve(ctx.providerLoader.getUpstreamDir());
46478
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path20.sep}`)) {
47060
+ const canonicalUserDir = path21.resolve(ctx.providerLoader.getUserProviderDir(category, type));
47061
+ const desiredDir = requestedDir ? path21.resolve(requestedDir) : canonicalUserDir;
47062
+ const upstreamRoot = path21.resolve(ctx.providerLoader.getUpstreamDir());
47063
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path21.sep}`)) {
46479
47064
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
46480
47065
  }
46481
- if (path20.basename(desiredDir) !== type) {
47066
+ if (path21.basename(desiredDir) !== type) {
46482
47067
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
46483
47068
  }
46484
47069
  const sourceDir = ctx.findProviderDir(type);
@@ -46486,11 +47071,11 @@ async (params) => {
46486
47071
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
46487
47072
  }
46488
47073
  if (!fs13.existsSync(desiredDir)) {
46489
- fs13.mkdirSync(path20.dirname(desiredDir), { recursive: true });
47074
+ fs13.mkdirSync(path21.dirname(desiredDir), { recursive: true });
46490
47075
  fs13.cpSync(sourceDir, desiredDir, { recursive: true });
46491
47076
  ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
46492
47077
  }
46493
- const providerJson = path20.join(desiredDir, "provider.json");
47078
+ const providerJson = path21.join(desiredDir, "provider.json");
46494
47079
  if (!fs13.existsSync(providerJson)) {
46495
47080
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
46496
47081
  }
@@ -46513,13 +47098,13 @@ async (params) => {
46513
47098
  const refDir = ctx.findProviderDir(referenceType);
46514
47099
  if (!refDir || !fs13.existsSync(refDir)) return {};
46515
47100
  const referenceScripts = {};
46516
- const scriptsDir = path20.join(refDir, "scripts");
47101
+ const scriptsDir = path21.join(refDir, "scripts");
46517
47102
  const latestDir = getLatestScriptVersionDir(scriptsDir);
46518
47103
  if (!latestDir) return referenceScripts;
46519
47104
  for (const file2 of fs13.readdirSync(latestDir)) {
46520
47105
  if (!file2.endsWith(".js")) continue;
46521
47106
  try {
46522
- referenceScripts[file2] = fs13.readFileSync(path20.join(latestDir, file2), "utf-8");
47107
+ referenceScripts[file2] = fs13.readFileSync(path21.join(latestDir, file2), "utf-8");
46523
47108
  } catch {
46524
47109
  }
46525
47110
  }
@@ -46627,9 +47212,9 @@ async (params) => {
46627
47212
  });
46628
47213
  const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
46629
47214
  const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
46630
- const tmpDir = path20.join(os19.tmpdir(), "adhdev-autoimpl");
47215
+ const tmpDir = path21.join(os19.tmpdir(), "adhdev-autoimpl");
46631
47216
  if (!fs13.existsSync(tmpDir)) fs13.mkdirSync(tmpDir, { recursive: true });
46632
- const promptFile = path20.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
47217
+ const promptFile = path21.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
46633
47218
  fs13.writeFileSync(promptFile, prompt, "utf-8");
46634
47219
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
46635
47220
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
@@ -47066,7 +47651,7 @@ async (params) => {
47066
47651
  setMode: "set_mode.js"
47067
47652
  };
47068
47653
  const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
47069
- const scriptsDir = path20.join(providerDir, "scripts");
47654
+ const scriptsDir = path21.join(providerDir, "scripts");
47070
47655
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
47071
47656
  if (latestScriptsDir) {
47072
47657
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -47077,7 +47662,7 @@ async (params) => {
47077
47662
  for (const file2 of fs13.readdirSync(latestScriptsDir)) {
47078
47663
  if (file2.endsWith(".js") && targetFileNames.has(file2)) {
47079
47664
  try {
47080
- const content = fs13.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
47665
+ const content = fs13.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
47081
47666
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
47082
47667
  lines.push("```javascript");
47083
47668
  lines.push(content);
@@ -47094,7 +47679,7 @@ async (params) => {
47094
47679
  lines.push("");
47095
47680
  for (const file2 of refFiles) {
47096
47681
  try {
47097
- const content = fs13.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
47682
+ const content = fs13.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
47098
47683
  lines.push(`### \`${file2}\` \u{1F512}`);
47099
47684
  lines.push("```javascript");
47100
47685
  lines.push(content);
@@ -47135,10 +47720,10 @@ async (params) => {
47135
47720
  lines.push("");
47136
47721
  }
47137
47722
  }
47138
- const docsDir = path20.join(providerDir, "../../docs");
47723
+ const docsDir = path21.join(providerDir, "../../docs");
47139
47724
  const loadGuide = (name) => {
47140
47725
  try {
47141
- const p = path20.join(docsDir, name);
47726
+ const p = path21.join(docsDir, name);
47142
47727
  if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
47143
47728
  } catch {
47144
47729
  }
@@ -47375,7 +47960,7 @@ async (params) => {
47375
47960
  parseApproval: "parse_approval.js"
47376
47961
  };
47377
47962
  const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
47378
- const scriptsDir = path20.join(providerDir, "scripts");
47963
+ const scriptsDir = path21.join(providerDir, "scripts");
47379
47964
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
47380
47965
  if (latestScriptsDir) {
47381
47966
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -47387,7 +47972,7 @@ async (params) => {
47387
47972
  if (!file2.endsWith(".js")) continue;
47388
47973
  if (!targetFileNames.has(file2)) continue;
47389
47974
  try {
47390
- const content = fs13.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
47975
+ const content = fs13.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
47391
47976
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
47392
47977
  lines.push("```javascript");
47393
47978
  lines.push(content);
@@ -47403,7 +47988,7 @@ async (params) => {
47403
47988
  lines.push("");
47404
47989
  for (const file2 of refFiles) {
47405
47990
  try {
47406
- const content = fs13.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
47991
+ const content = fs13.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
47407
47992
  lines.push(`### \`${file2}\` \u{1F512}`);
47408
47993
  lines.push("```javascript");
47409
47994
  lines.push(content);
@@ -47436,10 +48021,10 @@ async (params) => {
47436
48021
  lines.push("");
47437
48022
  }
47438
48023
  }
47439
- const docsDir = path20.join(providerDir, "../../docs");
48024
+ const docsDir = path21.join(providerDir, "../../docs");
47440
48025
  const loadGuide = (name) => {
47441
48026
  try {
47442
- const p = path20.join(docsDir, name);
48027
+ const p = path21.join(docsDir, name);
47443
48028
  if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
47444
48029
  } catch {
47445
48030
  }
@@ -47880,8 +48465,8 @@ data: ${JSON.stringify(msg.data)}
47880
48465
  }
47881
48466
  getEndpointList() {
47882
48467
  return this.routes.map((r) => {
47883
- const path222 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
47884
- return `${r.method.padEnd(5)} ${path222}`;
48468
+ const path23 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
48469
+ return `${r.method.padEnd(5)} ${path23}`;
47885
48470
  });
47886
48471
  }
47887
48472
  async start(port = DEV_SERVER_PORT) {
@@ -48136,12 +48721,12 @@ data: ${JSON.stringify(msg.data)}
48136
48721
  // ─── DevConsole SPA ───
48137
48722
  getConsoleDistDir() {
48138
48723
  const candidates = [
48139
- path21.resolve(__dirname, "../../web-devconsole/dist"),
48140
- path21.resolve(__dirname, "../../../web-devconsole/dist"),
48141
- path21.join(process.cwd(), "packages/web-devconsole/dist")
48724
+ path222.resolve(__dirname, "../../web-devconsole/dist"),
48725
+ path222.resolve(__dirname, "../../../web-devconsole/dist"),
48726
+ path222.join(process.cwd(), "packages/web-devconsole/dist")
48142
48727
  ];
48143
48728
  for (const dir of candidates) {
48144
- if (fs14.existsSync(path21.join(dir, "index.html"))) return dir;
48729
+ if (fs14.existsSync(path222.join(dir, "index.html"))) return dir;
48145
48730
  }
48146
48731
  return null;
48147
48732
  }
@@ -48151,7 +48736,7 @@ data: ${JSON.stringify(msg.data)}
48151
48736
  this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
48152
48737
  return;
48153
48738
  }
48154
- const htmlPath = path21.join(distDir, "index.html");
48739
+ const htmlPath = path222.join(distDir, "index.html");
48155
48740
  try {
48156
48741
  const html = fs14.readFileSync(htmlPath, "utf-8");
48157
48742
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
@@ -48176,15 +48761,15 @@ data: ${JSON.stringify(msg.data)}
48176
48761
  this.json(res, 404, { error: "Not found" });
48177
48762
  return;
48178
48763
  }
48179
- const safePath = path21.normalize(pathname).replace(/^\.\.\//, "");
48180
- const filePath = path21.join(distDir, safePath);
48764
+ const safePath = path222.normalize(pathname).replace(/^\.\.\//, "");
48765
+ const filePath = path222.join(distDir, safePath);
48181
48766
  if (!filePath.startsWith(distDir)) {
48182
48767
  this.json(res, 403, { error: "Forbidden" });
48183
48768
  return;
48184
48769
  }
48185
48770
  try {
48186
48771
  const content = fs14.readFileSync(filePath);
48187
- const ext = path21.extname(filePath);
48772
+ const ext = path222.extname(filePath);
48188
48773
  const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
48189
48774
  res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
48190
48775
  res.end(content);
@@ -48297,9 +48882,9 @@ data: ${JSON.stringify(msg.data)}
48297
48882
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
48298
48883
  if (entry.isDirectory()) {
48299
48884
  files.push({ path: rel, size: 0, type: "dir" });
48300
- scan(path21.join(d, entry.name), rel);
48885
+ scan(path222.join(d, entry.name), rel);
48301
48886
  } else {
48302
- const stat4 = fs14.statSync(path21.join(d, entry.name));
48887
+ const stat4 = fs14.statSync(path222.join(d, entry.name));
48303
48888
  files.push({ path: rel, size: stat4.size, type: "file" });
48304
48889
  }
48305
48890
  }
@@ -48322,7 +48907,7 @@ data: ${JSON.stringify(msg.data)}
48322
48907
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
48323
48908
  return;
48324
48909
  }
48325
- const fullPath = path21.resolve(dir, path21.normalize(filePath));
48910
+ const fullPath = path222.resolve(dir, path222.normalize(filePath));
48326
48911
  if (!fullPath.startsWith(dir)) {
48327
48912
  this.json(res, 403, { error: "Forbidden" });
48328
48913
  return;
@@ -48347,14 +48932,14 @@ data: ${JSON.stringify(msg.data)}
48347
48932
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
48348
48933
  return;
48349
48934
  }
48350
- const fullPath = path21.resolve(dir, path21.normalize(filePath));
48935
+ const fullPath = path222.resolve(dir, path222.normalize(filePath));
48351
48936
  if (!fullPath.startsWith(dir)) {
48352
48937
  this.json(res, 403, { error: "Forbidden" });
48353
48938
  return;
48354
48939
  }
48355
48940
  try {
48356
48941
  if (fs14.existsSync(fullPath)) fs14.copyFileSync(fullPath, fullPath + ".bak");
48357
- fs14.mkdirSync(path21.dirname(fullPath), { recursive: true });
48942
+ fs14.mkdirSync(path222.dirname(fullPath), { recursive: true });
48358
48943
  fs14.writeFileSync(fullPath, content, "utf-8");
48359
48944
  this.log(`File saved: ${fullPath} (${content.length} chars)`);
48360
48945
  this.providerLoader.reload();
@@ -48371,7 +48956,7 @@ data: ${JSON.stringify(msg.data)}
48371
48956
  return;
48372
48957
  }
48373
48958
  for (const name of ["scripts.js", "provider.json"]) {
48374
- const p = path21.join(dir, name);
48959
+ const p = path222.join(dir, name);
48375
48960
  if (fs14.existsSync(p)) {
48376
48961
  const source = fs14.readFileSync(p, "utf-8");
48377
48962
  this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
@@ -48392,8 +48977,8 @@ data: ${JSON.stringify(msg.data)}
48392
48977
  this.json(res, 404, { error: `Provider not found: ${type}` });
48393
48978
  return;
48394
48979
  }
48395
- const target = fs14.existsSync(path21.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
48396
- const targetPath = path21.join(dir, target);
48980
+ const target = fs14.existsSync(path222.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
48981
+ const targetPath = path222.join(dir, target);
48397
48982
  try {
48398
48983
  if (fs14.existsSync(targetPath)) fs14.copyFileSync(targetPath, targetPath + ".bak");
48399
48984
  fs14.writeFileSync(targetPath, source, "utf-8");
@@ -48421,22 +49006,9 @@ data: ${JSON.stringify(msg.data)}
48421
49006
  const warnings = [];
48422
49007
  try {
48423
49008
  const config2 = typeof content === "string" ? JSON.parse(content) : content;
48424
- if (!config2.type) errors.push("Missing required field: type");
48425
- if (!config2.name) errors.push("Missing required field: name");
48426
- if (!config2.category) errors.push("Missing required field: category");
48427
- else if (!["ide", "extension", "cli", "acp"].includes(config2.category)) errors.push(`Invalid category: ${config2.category}`);
48428
- if (config2.category === "ide" || config2.category === "extension") {
48429
- if (!config2.cdpPorts || !Array.isArray(config2.cdpPorts) || config2.cdpPorts.length === 0)
48430
- warnings.push("IDE/Extension providers should have cdpPorts");
48431
- if (config2.category === "extension" && !config2.extensionId)
48432
- warnings.push("Extension providers should have extensionId");
48433
- }
48434
- if (config2.category === "acp" || config2.category === "cli") {
48435
- if (!config2.spawn) errors.push("ACP/CLI providers must have spawn config");
48436
- else {
48437
- if (!config2.spawn.command) errors.push("spawn.command is required");
48438
- }
48439
- }
49009
+ const validation = validateProviderDefinition(config2);
49010
+ errors.push(...validation.errors);
49011
+ warnings.push(...validation.warnings);
48440
49012
  if (config2.settings) {
48441
49013
  for (const [key, val] of Object.entries(config2.settings)) {
48442
49014
  const s15 = val;
@@ -48553,7 +49125,7 @@ data: ${JSON.stringify(msg.data)}
48553
49125
  }
48554
49126
  let targetDir;
48555
49127
  targetDir = this.providerLoader.getUserProviderDir(category, type);
48556
- const jsonPath = path21.join(targetDir, "provider.json");
49128
+ const jsonPath = path222.join(targetDir, "provider.json");
48557
49129
  if (fs14.existsSync(jsonPath)) {
48558
49130
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
48559
49131
  return;
@@ -48565,8 +49137,8 @@ data: ${JSON.stringify(msg.data)}
48565
49137
  const createdFiles = ["provider.json"];
48566
49138
  if (result.files) {
48567
49139
  for (const [relPath, content] of Object.entries(result.files)) {
48568
- const fullPath = path21.join(targetDir, relPath);
48569
- fs14.mkdirSync(path21.dirname(fullPath), { recursive: true });
49140
+ const fullPath = path222.join(targetDir, relPath);
49141
+ fs14.mkdirSync(path222.dirname(fullPath), { recursive: true });
48570
49142
  fs14.writeFileSync(fullPath, content, "utf-8");
48571
49143
  createdFiles.push(relPath);
48572
49144
  }
@@ -48619,22 +49191,22 @@ data: ${JSON.stringify(msg.data)}
48619
49191
  if (!fs14.existsSync(scriptsDir)) return null;
48620
49192
  const versions = fs14.readdirSync(scriptsDir).filter((d) => {
48621
49193
  try {
48622
- return fs14.statSync(path21.join(scriptsDir, d)).isDirectory();
49194
+ return fs14.statSync(path222.join(scriptsDir, d)).isDirectory();
48623
49195
  } catch {
48624
49196
  return false;
48625
49197
  }
48626
49198
  }).sort((a, b2) => b2.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
48627
49199
  if (versions.length === 0) return null;
48628
- return path21.join(scriptsDir, versions[0]);
49200
+ return path222.join(scriptsDir, versions[0]);
48629
49201
  }
48630
49202
  resolveAutoImplWritableProviderDir(category, type, requestedDir) {
48631
- const canonicalUserDir = path21.resolve(this.providerLoader.getUserProviderDir(category, type));
48632
- const desiredDir = requestedDir ? path21.resolve(requestedDir) : canonicalUserDir;
48633
- const upstreamRoot = path21.resolve(this.providerLoader.getUpstreamDir());
48634
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path21.sep}`)) {
49203
+ const canonicalUserDir = path222.resolve(this.providerLoader.getUserProviderDir(category, type));
49204
+ const desiredDir = requestedDir ? path222.resolve(requestedDir) : canonicalUserDir;
49205
+ const upstreamRoot = path222.resolve(this.providerLoader.getUpstreamDir());
49206
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path222.sep}`)) {
48635
49207
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
48636
49208
  }
48637
- if (path21.basename(desiredDir) !== type) {
49209
+ if (path222.basename(desiredDir) !== type) {
48638
49210
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
48639
49211
  }
48640
49212
  const sourceDir = this.findProviderDir(type);
@@ -48642,11 +49214,11 @@ data: ${JSON.stringify(msg.data)}
48642
49214
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
48643
49215
  }
48644
49216
  if (!fs14.existsSync(desiredDir)) {
48645
- fs14.mkdirSync(path21.dirname(desiredDir), { recursive: true });
49217
+ fs14.mkdirSync(path222.dirname(desiredDir), { recursive: true });
48646
49218
  fs14.cpSync(sourceDir, desiredDir, { recursive: true });
48647
49219
  this.log(`Auto-implement writable copy created: ${desiredDir}`);
48648
49220
  }
48649
- const providerJson = path21.join(desiredDir, "provider.json");
49221
+ const providerJson = path222.join(desiredDir, "provider.json");
48650
49222
  if (!fs14.existsSync(providerJson)) {
48651
49223
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
48652
49224
  }
@@ -48694,7 +49266,7 @@ data: ${JSON.stringify(msg.data)}
48694
49266
  setMode: "set_mode.js"
48695
49267
  };
48696
49268
  const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
48697
- const scriptsDir = path21.join(providerDir, "scripts");
49269
+ const scriptsDir = path222.join(providerDir, "scripts");
48698
49270
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
48699
49271
  if (latestScriptsDir) {
48700
49272
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -48705,7 +49277,7 @@ data: ${JSON.stringify(msg.data)}
48705
49277
  for (const file2 of fs14.readdirSync(latestScriptsDir)) {
48706
49278
  if (file2.endsWith(".js") && targetFileNames.has(file2)) {
48707
49279
  try {
48708
- const content = fs14.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
49280
+ const content = fs14.readFileSync(path222.join(latestScriptsDir, file2), "utf-8");
48709
49281
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
48710
49282
  lines.push("```javascript");
48711
49283
  lines.push(content);
@@ -48722,7 +49294,7 @@ data: ${JSON.stringify(msg.data)}
48722
49294
  lines.push("");
48723
49295
  for (const file2 of refFiles) {
48724
49296
  try {
48725
- const content = fs14.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
49297
+ const content = fs14.readFileSync(path222.join(latestScriptsDir, file2), "utf-8");
48726
49298
  lines.push(`### \`${file2}\` \u{1F512}`);
48727
49299
  lines.push("```javascript");
48728
49300
  lines.push(content);
@@ -48763,10 +49335,10 @@ data: ${JSON.stringify(msg.data)}
48763
49335
  lines.push("");
48764
49336
  }
48765
49337
  }
48766
- const docsDir = path21.join(providerDir, "../../docs");
49338
+ const docsDir = path222.join(providerDir, "../../docs");
48767
49339
  const loadGuide = (name) => {
48768
49340
  try {
48769
- const p = path21.join(docsDir, name);
49341
+ const p = path222.join(docsDir, name);
48770
49342
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
48771
49343
  } catch {
48772
49344
  }
@@ -48940,7 +49512,7 @@ data: ${JSON.stringify(msg.data)}
48940
49512
  parseApproval: "parse_approval.js"
48941
49513
  };
48942
49514
  const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
48943
- const scriptsDir = path21.join(providerDir, "scripts");
49515
+ const scriptsDir = path222.join(providerDir, "scripts");
48944
49516
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
48945
49517
  if (latestScriptsDir) {
48946
49518
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -48952,7 +49524,7 @@ data: ${JSON.stringify(msg.data)}
48952
49524
  if (!file2.endsWith(".js")) continue;
48953
49525
  if (!targetFileNames.has(file2)) continue;
48954
49526
  try {
48955
- const content = fs14.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
49527
+ const content = fs14.readFileSync(path222.join(latestScriptsDir, file2), "utf-8");
48956
49528
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
48957
49529
  lines.push("```javascript");
48958
49530
  lines.push(content);
@@ -48968,7 +49540,7 @@ data: ${JSON.stringify(msg.data)}
48968
49540
  lines.push("");
48969
49541
  for (const file2 of refFiles) {
48970
49542
  try {
48971
- const content = fs14.readFileSync(path21.join(latestScriptsDir, file2), "utf-8");
49543
+ const content = fs14.readFileSync(path222.join(latestScriptsDir, file2), "utf-8");
48972
49544
  lines.push(`### \`${file2}\` \u{1F512}`);
48973
49545
  lines.push("```javascript");
48974
49546
  lines.push(content);
@@ -49001,10 +49573,10 @@ data: ${JSON.stringify(msg.data)}
49001
49573
  lines.push("");
49002
49574
  }
49003
49575
  }
49004
- const docsDir = path21.join(providerDir, "../../docs");
49576
+ const docsDir = path222.join(providerDir, "../../docs");
49005
49577
  const loadGuide = (name) => {
49006
49578
  try {
49007
- const p = path21.join(docsDir, name);
49579
+ const p = path222.join(docsDir, name);
49008
49580
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
49009
49581
  } catch {
49010
49582
  }
@@ -49703,6 +50275,63 @@ data: ${JSON.stringify(msg.data)}
49703
50275
  });
49704
50276
  }
49705
50277
  }
50278
+ var LIVE_LIFECYCLES = /* @__PURE__ */ new Set(["starting", "running", "stopping", "interrupted"]);
50279
+ function isSessionHostLiveRuntime(record2) {
50280
+ const lifecycle = String(record2?.lifecycle || "").trim();
50281
+ return LIVE_LIFECYCLES.has(lifecycle);
50282
+ }
50283
+ function getSessionHostRecoveryLabel(meta3) {
50284
+ const recoveryState = typeof meta3?.runtimeRecoveryState === "string" ? String(meta3.runtimeRecoveryState).trim() : "";
50285
+ if (!recoveryState) return null;
50286
+ if (recoveryState === "auto_resumed") return "restored after restart";
50287
+ if (recoveryState === "resume_failed") return "restore failed";
50288
+ if (recoveryState === "host_restart_interrupted") return "host restart interrupted";
50289
+ if (recoveryState === "orphan_snapshot") return "snapshot recovered";
50290
+ return recoveryState.replace(/_/g, " ");
50291
+ }
50292
+ function isSessionHostRecoverySnapshot(record2) {
50293
+ if (!record2) return false;
50294
+ if (isSessionHostLiveRuntime(record2)) return false;
50295
+ const lifecycle = String(record2.lifecycle || "").trim();
50296
+ if (lifecycle && lifecycle !== "stopped" && lifecycle !== "failed") {
50297
+ return false;
50298
+ }
50299
+ const meta3 = record2.meta || void 0;
50300
+ if (meta3?.restoredFromStorage === true) return true;
50301
+ return getSessionHostRecoveryLabel(meta3) !== null;
50302
+ }
50303
+ function getSessionHostSurfaceKind(record2) {
50304
+ if (isSessionHostLiveRuntime(record2)) return "live_runtime";
50305
+ if (isSessionHostRecoverySnapshot(record2)) return "recovery_snapshot";
50306
+ return "inactive_record";
50307
+ }
50308
+ function partitionSessionHostRecords(records) {
50309
+ const liveRuntimes = [];
50310
+ const recoverySnapshots = [];
50311
+ const inactiveRecords = [];
50312
+ for (const record2 of records) {
50313
+ const kind = getSessionHostSurfaceKind(record2);
50314
+ if (kind === "live_runtime") {
50315
+ liveRuntimes.push(record2);
50316
+ } else if (kind === "recovery_snapshot") {
50317
+ recoverySnapshots.push(record2);
50318
+ } else {
50319
+ inactiveRecords.push(record2);
50320
+ }
50321
+ }
50322
+ return {
50323
+ liveRuntimes,
50324
+ recoverySnapshots,
50325
+ inactiveRecords
50326
+ };
50327
+ }
50328
+ function partitionSessionHostDiagnosticsSessions(records) {
50329
+ return partitionSessionHostRecords(records || []);
50330
+ }
50331
+ function shouldAutoRestoreHostedSessionsOnStartup2(env = process.env) {
50332
+ const raw = typeof env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP === "string" ? env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP.trim().toLowerCase() : "";
50333
+ return raw === "1" || raw === "true" || raw === "yes";
50334
+ }
49706
50335
  var import_child_process10 = require("child_process");
49707
50336
  var EXTENSION_CATALOG = [
49708
50337
  // AI Agent extensions
@@ -50321,6 +50950,12 @@ async function proxySessionHostAttach(target, options = {}) {
50321
50950
  return runSessionHostCli(args);
50322
50951
  }
50323
50952
 
50953
+ // src/startup-restore-policy.ts
50954
+ function shouldAutoRestoreHostedSessionsOnStartup(env = process.env) {
50955
+ const raw = typeof env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP === "string" ? env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP.trim().toLowerCase() : "";
50956
+ return raw === "1" || raw === "true" || raw === "yes";
50957
+ }
50958
+
50324
50959
  // ../session-host-core/dist/index.mjs
50325
50960
  var os3 = __toESM(require("os"), 1);
50326
50961
  var path2 = __toESM(require("path"), 1);
@@ -50892,7 +51527,9 @@ var StandaloneServer = class {
50892
51527
  tickIntervalMs: 3e3,
50893
51528
  cdpScanIntervalMs: 15e3
50894
51529
  });
50895
- await this.components.cliManager.restoreHostedSessions();
51530
+ if (shouldAutoRestoreHostedSessionsOnStartup(process.env)) {
51531
+ await this.components.cliManager.restoreHostedSessions();
51532
+ }
50896
51533
  if (options.dev) {
50897
51534
  this.devServer = await (0, import_daemon_core2.startDaemonDevSupport)({
50898
51535
  components: this.components,
@@ -51913,7 +52550,7 @@ async function main() {
51913
52550
  if (primaryCommand === "attach") {
51914
52551
  const target = args[1];
51915
52552
  if (!target) {
51916
- console.error("Usage: adhdev attach <sessionId> [--read-only|--takeover]");
52553
+ console.error("Usage: adhdev-standalone attach <sessionId> [--read-only|--takeover]");
51917
52554
  process.exit(1);
51918
52555
  }
51919
52556
  const readOnly = args.includes("--read-only");