@adhdev/daemon-core 0.9.82-rc.165 → 0.9.82-rc.166

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.mjs CHANGED
@@ -106,8 +106,8 @@ function normalizeGitOutput(value) {
106
106
  return String(value).replace(/\r\n/g, "\n");
107
107
  }
108
108
  function isPathInside(parent, child) {
109
- const relative4 = path.relative(path.resolve(parent), path.resolve(child));
110
- return relative4 === "" || !relative4.startsWith("..") && !path.isAbsolute(relative4);
109
+ const relative5 = path.relative(path.resolve(parent), path.resolve(child));
110
+ return relative5 === "" || !relative5.startsWith("..") && !path.isAbsolute(relative5);
111
111
  }
112
112
  async function validateWorkspace(workspace) {
113
113
  if (typeof workspace !== "string" || workspace.length === 0 || workspace.includes("\0")) {
@@ -768,10 +768,10 @@ function getMeshConfigPath() {
768
768
  return join4(getConfigDir(), "meshes.json");
769
769
  }
770
770
  function loadMeshConfig() {
771
- const path39 = getMeshConfigPath();
772
- if (!existsSync4(path39)) return { meshes: [] };
771
+ const path40 = getMeshConfigPath();
772
+ if (!existsSync4(path40)) return { meshes: [] };
773
773
  try {
774
- const raw = JSON.parse(readFileSync2(path39, "utf-8"));
774
+ const raw = JSON.parse(readFileSync2(path40, "utf-8"));
775
775
  if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
776
776
  return raw;
777
777
  } catch {
@@ -779,16 +779,16 @@ function loadMeshConfig() {
779
779
  }
780
780
  }
781
781
  function saveMeshConfig(config) {
782
- const path39 = getMeshConfigPath();
783
- writeFileSync2(path39, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
782
+ const path40 = getMeshConfigPath();
783
+ writeFileSync2(path40, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
784
784
  }
785
785
  function normalizeRepoIdentity(remoteUrl) {
786
786
  let identity = remoteUrl.trim();
787
787
  if (identity.startsWith("http://") || identity.startsWith("https://")) {
788
788
  try {
789
789
  const url = new URL(identity);
790
- const path39 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
791
- return `${url.hostname}/${path39}`;
790
+ const path40 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
791
+ return `${url.hostname}/${path40}`;
792
792
  } catch {
793
793
  }
794
794
  }
@@ -1717,8 +1717,8 @@ function resolveMeshCoordinatorSetup(options) {
1717
1717
  }
1718
1718
  const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
1719
1719
  if (mcpConfig.mode === "auto_import") {
1720
- const path39 = mcpConfig.path?.trim();
1721
- if (!path39) {
1720
+ const path40 = mcpConfig.path?.trim();
1721
+ if (!path40) {
1722
1722
  return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
1723
1723
  }
1724
1724
  const mcpServer = resolveAdhdevMcpServerLaunch({
@@ -1736,7 +1736,7 @@ function resolveMeshCoordinatorSetup(options) {
1736
1736
  return {
1737
1737
  kind: "auto_import",
1738
1738
  serverName,
1739
- configPath: resolveMcpConfigPath(path39, workspace),
1739
+ configPath: resolveMcpConfigPath(path40, workspace),
1740
1740
  configFormat: mcpConfig.format,
1741
1741
  mcpServer
1742
1742
  };
@@ -1893,8 +1893,8 @@ function stripCoordinatorWrapperFile(filePath) {
1893
1893
  const remaining = (existing.slice(0, openIdx) + existing.slice(closeIdx + CLOSE.length)).replace(/^\s*\n+/, "").replace(/\n+\s*$/, "");
1894
1894
  if (!remaining.trim()) {
1895
1895
  try {
1896
- const fs27 = __require("fs");
1897
- fs27.unlinkSync(filePath);
1896
+ const fs28 = __require("fs");
1897
+ fs28.unlinkSync(filePath);
1898
1898
  } catch {
1899
1899
  }
1900
1900
  } else {
@@ -2032,10 +2032,10 @@ function rotateArchiveFile(meshId, archivePath) {
2032
2032
  }
2033
2033
  }
2034
2034
  function readArchivedCounts(meshId) {
2035
- const path39 = getArchivedCountsPath(meshId);
2036
- if (!existsSync10(path39)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
2035
+ const path40 = getArchivedCountsPath(meshId);
2036
+ if (!existsSync10(path40)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
2037
2037
  try {
2038
- return JSON.parse(readFileSync8(path39, "utf-8"));
2038
+ return JSON.parse(readFileSync8(path40, "utf-8"));
2039
2039
  } catch {
2040
2040
  return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
2041
2041
  }
@@ -2685,10 +2685,10 @@ var init_beads_db = __esm({
2685
2685
  this.migratedMeshIds.add(meshId);
2686
2686
  const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
2687
2687
  if (count.count > 0) return;
2688
- const path39 = legacyQueuePath(meshId);
2689
- if (!existsSync11(path39)) return;
2688
+ const path40 = legacyQueuePath(meshId);
2689
+ if (!existsSync11(path40)) return;
2690
2690
  try {
2691
- const entries = JSON.parse(readFileSync9(path39, "utf-8"));
2691
+ const entries = JSON.parse(readFileSync9(path40, "utf-8"));
2692
2692
  if (!Array.isArray(entries)) return;
2693
2693
  const insert = this.db.prepare(`
2694
2694
  INSERT OR REPLACE INTO mesh_queue (
@@ -3399,10 +3399,10 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
3399
3399
  if (!meshId) return [];
3400
3400
  const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
3401
3401
  const events = [];
3402
- for (const path39 of paths) {
3403
- if (!existsSync13(path39)) continue;
3402
+ for (const path40 of paths) {
3403
+ if (!existsSync13(path40)) continue;
3404
3404
  try {
3405
- const raw = readFileSync10(path39, "utf-8");
3405
+ const raw = readFileSync10(path40, "utf-8");
3406
3406
  const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
3407
3407
  try {
3408
3408
  return [JSON.parse(line)];
@@ -3410,7 +3410,7 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
3410
3410
  return [];
3411
3411
  }
3412
3412
  });
3413
- const filtered = coordinatorDaemonId && path39 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
3413
+ const filtered = coordinatorDaemonId && path40 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
3414
3414
  events.push(...filtered);
3415
3415
  } catch {
3416
3416
  }
@@ -3479,13 +3479,13 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
3479
3479
  ...backfilled
3480
3480
  ];
3481
3481
  }
3482
- function trimPendingEventsIfNeeded(path39) {
3482
+ function trimPendingEventsIfNeeded(path40) {
3483
3483
  try {
3484
- if (!existsSync13(path39)) return;
3485
- if (statSync5(path39).size <= MAX_PENDING_EVENTS_BYTES) return;
3486
- const lines = readFileSync10(path39, "utf-8").split("\n").filter(Boolean);
3484
+ if (!existsSync13(path40)) return;
3485
+ if (statSync5(path40).size <= MAX_PENDING_EVENTS_BYTES) return;
3486
+ const lines = readFileSync10(path40, "utf-8").split("\n").filter(Boolean);
3487
3487
  if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
3488
- writeFileSync6(path39, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
3488
+ writeFileSync6(path40, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
3489
3489
  } catch {
3490
3490
  }
3491
3491
  }
@@ -3499,19 +3499,19 @@ function queuePendingMeshCoordinatorEvent(event) {
3499
3499
  LOG.info("MeshEvents", `Suppressed duplicate pending ${event.event} for mesh ${event.meshId}`);
3500
3500
  return true;
3501
3501
  }
3502
- const path39 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
3503
- trimPendingEventsIfNeeded(path39);
3504
- appendFileSync2(path39, JSON.stringify(event) + "\n", "utf-8");
3502
+ const path40 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
3503
+ trimPendingEventsIfNeeded(path40);
3504
+ appendFileSync2(path40, JSON.stringify(event) + "\n", "utf-8");
3505
3505
  return true;
3506
3506
  } catch (e) {
3507
3507
  LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
3508
3508
  return false;
3509
3509
  }
3510
3510
  }
3511
- function atomicDrainFile(path39) {
3512
- const tmpPath = `${path39}.draining`;
3511
+ function atomicDrainFile(path40) {
3512
+ const tmpPath = `${path40}.draining`;
3513
3513
  try {
3514
- renameSync3(path39, tmpPath);
3514
+ renameSync3(path40, tmpPath);
3515
3515
  } catch {
3516
3516
  return null;
3517
3517
  }
@@ -3534,8 +3534,8 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
3534
3534
  if (!meshId) return [];
3535
3535
  const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
3536
3536
  const all = [];
3537
- for (const path39 of paths) {
3538
- const content = atomicDrainFile(path39);
3537
+ for (const path40 of paths) {
3538
+ const content = atomicDrainFile(path40);
3539
3539
  if (!content) continue;
3540
3540
  const parsed = content.split("\n").filter(Boolean).flatMap((line) => {
3541
3541
  try {
@@ -3544,7 +3544,7 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
3544
3544
  return [];
3545
3545
  }
3546
3546
  });
3547
- const filtered = coordinatorDaemonId && path39 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
3547
+ const filtered = coordinatorDaemonId && path40 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
3548
3548
  all.push(...filtered);
3549
3549
  }
3550
3550
  if (all.length === 0) return [];
@@ -3557,9 +3557,9 @@ function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
3557
3557
  function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
3558
3558
  if (!meshId) return;
3559
3559
  const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
3560
- for (const path39 of paths) {
3561
- if (existsSync13(path39)) try {
3562
- unlinkSync2(path39);
3560
+ for (const path40 of paths) {
3561
+ if (existsSync13(path40)) try {
3562
+ unlinkSync2(path40);
3563
3563
  } catch {
3564
3564
  }
3565
3565
  }
@@ -4683,6 +4683,56 @@ var init_debug_config = __esm({
4683
4683
  }
4684
4684
  });
4685
4685
 
4686
+ // src/providers/provider-trust.ts
4687
+ var provider_trust_exports = {};
4688
+ __export(provider_trust_exports, {
4689
+ classifyTrust: () => classifyTrust,
4690
+ describeTrust: () => describeTrust,
4691
+ inspectManifestShape: () => inspectManifestShape,
4692
+ requiresConfirmation: () => requiresConfirmation
4693
+ });
4694
+ function inspectManifestShape(manifest) {
4695
+ const hasTui = !!manifest.tui && typeof manifest.tui === "object" && Object.keys(manifest.tui).length > 0;
4696
+ const hasOverrides = !!manifest.overrides && typeof manifest.overrides === "object" && !Array.isArray(manifest.overrides) && Object.keys(manifest.overrides).length > 0;
4697
+ const compat = Array.isArray(manifest.compatibility) ? manifest.compatibility : [];
4698
+ const compatHasScriptDir = compat.some((entry) => typeof entry?.scriptDir === "string");
4699
+ const hasScriptDir = compatHasScriptDir || typeof manifest.defaultScriptDir === "string";
4700
+ return { hasTui, hasOverrides, hasScriptDir };
4701
+ }
4702
+ function classifyTrust(layer, shape) {
4703
+ const isSpecOnly = !shape.hasTui && !shape.hasOverrides && !shape.hasScriptDir;
4704
+ switch (layer) {
4705
+ case "user":
4706
+ return "user-custom";
4707
+ case "upstream":
4708
+ return isSpecOnly ? "trusted" : "trusted-with-scripts";
4709
+ case "external":
4710
+ return isSpecOnly ? "external-safe" : "external-untrusted";
4711
+ }
4712
+ }
4713
+ function requiresConfirmation(trust) {
4714
+ return trust === "external-untrusted";
4715
+ }
4716
+ function describeTrust(trust) {
4717
+ switch (trust) {
4718
+ case "user-custom":
4719
+ return "Hand-authored in ~/.adhdev/providers/. Runs your own code.";
4720
+ case "trusted":
4721
+ return "Official, declarative-only manifest from the ADHDev registry.";
4722
+ case "trusted-with-scripts":
4723
+ return "Official manifest from the ADHDev registry. Ships JavaScript hooks executed by the daemon.";
4724
+ case "external-safe":
4725
+ return "Manifest from a 3rd-party git source you added. Declarative-only \u2014 the daemon never runs JS from this source.";
4726
+ case "external-untrusted":
4727
+ return "Manifest from a 3rd-party git source you added. Ships JavaScript that the daemon will execute. Treat as untrusted code \u2014 review the source before enabling.";
4728
+ }
4729
+ }
4730
+ var init_provider_trust = __esm({
4731
+ "src/providers/provider-trust.ts"() {
4732
+ "use strict";
4733
+ }
4734
+ });
4735
+
4686
4736
  // src/providers/sdk/v1/schemas/cli/provider.schema.json
4687
4737
  var provider_schema_default;
4688
4738
  var init_provider_schema = __esm({
@@ -5188,7 +5238,7 @@ function getCliValidator() {
5188
5238
  return _cliValidator;
5189
5239
  }
5190
5240
  function formatIssue(err) {
5191
- const path39 = err.instancePath || "";
5241
+ const path40 = err.instancePath || "";
5192
5242
  const params = err.params;
5193
5243
  let message = err.message || "validation failed";
5194
5244
  let allowed;
@@ -5206,7 +5256,7 @@ function formatIssue(err) {
5206
5256
  } else if (err.keyword === "type") {
5207
5257
  message = `must be ${params.type}`;
5208
5258
  }
5209
- return { path: path39, keyword: err.keyword, message, ...allowed !== void 0 ? { allowed } : {} };
5259
+ return { path: path40, keyword: err.keyword, message, ...allowed !== void 0 ? { allowed } : {} };
5210
5260
  }
5211
5261
  function validateCliProviderManifest(manifest) {
5212
5262
  const validator = getCliValidator();
@@ -5231,6 +5281,156 @@ var init_manifest = __esm({
5231
5281
  }
5232
5282
  });
5233
5283
 
5284
+ // src/providers/external-sources.ts
5285
+ var external_sources_exports = {};
5286
+ __export(external_sources_exports, {
5287
+ activeFilePath: () => activeFilePath,
5288
+ deriveSourceName: () => deriveSourceName,
5289
+ externalRoot: () => externalRoot,
5290
+ inventoryExternalSources: () => inventoryExternalSources,
5291
+ loadExternalSources: () => loadExternalSources,
5292
+ loadProvidersActive: () => loadProvidersActive,
5293
+ resolveActiveSource: () => resolveActiveSource,
5294
+ saveExternalSources: () => saveExternalSources,
5295
+ saveProvidersActive: () => saveProvidersActive,
5296
+ sourcesFilePath: () => sourcesFilePath,
5297
+ sourcesProviding: () => sourcesProviding
5298
+ });
5299
+ import * as fs8 from "fs";
5300
+ import * as os10 from "os";
5301
+ import * as path15 from "path";
5302
+ function adhdevDir() {
5303
+ return path15.join(os10.homedir(), ".adhdev");
5304
+ }
5305
+ function externalRoot() {
5306
+ return path15.join(adhdevDir(), "external");
5307
+ }
5308
+ function sourcesFilePath() {
5309
+ return path15.join(adhdevDir(), SOURCES_FILENAME);
5310
+ }
5311
+ function activeFilePath() {
5312
+ return path15.join(adhdevDir(), ACTIVE_FILENAME);
5313
+ }
5314
+ function ensureAdhdevDir() {
5315
+ const d = adhdevDir();
5316
+ if (!fs8.existsSync(d)) fs8.mkdirSync(d, { recursive: true });
5317
+ }
5318
+ function loadExternalSources() {
5319
+ const p = sourcesFilePath();
5320
+ if (!fs8.existsSync(p)) return { schema: 1, sources: [] };
5321
+ try {
5322
+ const raw = JSON.parse(fs8.readFileSync(p, "utf-8"));
5323
+ if (!raw || typeof raw !== "object") return { schema: 1, sources: [] };
5324
+ const sources = Array.isArray(raw.sources) ? raw.sources.filter(isValidSource) : [];
5325
+ return { schema: 1, sources };
5326
+ } catch {
5327
+ return { schema: 1, sources: [] };
5328
+ }
5329
+ }
5330
+ function saveExternalSources(file) {
5331
+ ensureAdhdevDir();
5332
+ const tmp = sourcesFilePath() + ".tmp";
5333
+ fs8.writeFileSync(tmp, JSON.stringify(file, null, 2) + "\n", "utf-8");
5334
+ fs8.renameSync(tmp, sourcesFilePath());
5335
+ }
5336
+ function loadProvidersActive() {
5337
+ const p = activeFilePath();
5338
+ if (!fs8.existsSync(p)) return { schema: 1, active: {} };
5339
+ try {
5340
+ const raw = JSON.parse(fs8.readFileSync(p, "utf-8"));
5341
+ if (!raw || typeof raw !== "object") return { schema: 1, active: {} };
5342
+ const active = raw.active && typeof raw.active === "object" ? raw.active : {};
5343
+ return { schema: 1, active };
5344
+ } catch {
5345
+ return { schema: 1, active: {} };
5346
+ }
5347
+ }
5348
+ function saveProvidersActive(file) {
5349
+ ensureAdhdevDir();
5350
+ const tmp = activeFilePath() + ".tmp";
5351
+ fs8.writeFileSync(tmp, JSON.stringify(file, null, 2) + "\n", "utf-8");
5352
+ fs8.renameSync(tmp, activeFilePath());
5353
+ }
5354
+ function isValidSource(x) {
5355
+ if (!x || typeof x !== "object") return false;
5356
+ const s = x;
5357
+ return typeof s.name === "string" && s.name.length > 0 && typeof s.url === "string" && s.url.length > 0 && typeof s.ref === "string" && s.ref.length > 0 && typeof s.addedAt === "string";
5358
+ }
5359
+ function deriveSourceName(url) {
5360
+ const m = url.match(/[/:]([^/:]+)\/([^/]+?)(?:\.git)?$/);
5361
+ if (!m) return "@source";
5362
+ const owner = m[1].toLowerCase().replace(/[^a-z0-9_-]/g, "-");
5363
+ const repo = m[2].toLowerCase().replace(/[^a-z0-9_-]/g, "-");
5364
+ return `@${owner}-${repo}`;
5365
+ }
5366
+ function inventoryExternalSources() {
5367
+ const root = externalRoot();
5368
+ if (!fs8.existsSync(root)) return [];
5369
+ const out = [];
5370
+ let entries;
5371
+ try {
5372
+ entries = fs8.readdirSync(root, { withFileTypes: true });
5373
+ } catch {
5374
+ return [];
5375
+ }
5376
+ for (const sourceEntry of entries) {
5377
+ if (!sourceEntry.isDirectory()) continue;
5378
+ const sourceName = sourceEntry.name;
5379
+ const sourceDir = path15.join(root, sourceName);
5380
+ const providers = {};
5381
+ let categoryEntries;
5382
+ try {
5383
+ categoryEntries = fs8.readdirSync(sourceDir, { withFileTypes: true });
5384
+ } catch {
5385
+ continue;
5386
+ }
5387
+ for (const categoryEntry of categoryEntries) {
5388
+ if (!categoryEntry.isDirectory()) continue;
5389
+ const category = categoryEntry.name;
5390
+ const categoryDir = path15.join(sourceDir, category);
5391
+ let typeEntries;
5392
+ try {
5393
+ typeEntries = fs8.readdirSync(categoryDir, { withFileTypes: true });
5394
+ } catch {
5395
+ continue;
5396
+ }
5397
+ const types = [];
5398
+ for (const typeEntry of typeEntries) {
5399
+ if (!typeEntry.isDirectory()) continue;
5400
+ const typeDir = path15.join(categoryDir, typeEntry.name);
5401
+ const hasV1 = fs8.existsSync(path15.join(typeDir, "provider.v1.json"));
5402
+ const hasV0 = fs8.existsSync(path15.join(typeDir, "provider.json"));
5403
+ if (hasV1 || hasV0) types.push(typeEntry.name);
5404
+ }
5405
+ if (types.length > 0) providers[category] = types;
5406
+ }
5407
+ out.push({ sourceName, providers });
5408
+ }
5409
+ return out;
5410
+ }
5411
+ function sourcesProviding(category, type) {
5412
+ const inventory = inventoryExternalSources();
5413
+ return inventory.filter((s) => (s.providers[category] || []).includes(type)).map((s) => s.sourceName);
5414
+ }
5415
+ function resolveActiveSource(category, type, activeFile) {
5416
+ const candidates = sourcesProviding(category, type);
5417
+ if (candidates.length === 0) return { source: null, ambiguous: false, candidates };
5418
+ if (candidates.length === 1) return { source: candidates[0], ambiguous: false, candidates };
5419
+ const explicit = (activeFile ?? loadProvidersActive()).active[type];
5420
+ if (explicit && candidates.includes(explicit)) {
5421
+ return { source: explicit, ambiguous: false, candidates };
5422
+ }
5423
+ return { source: candidates[0], ambiguous: true, candidates };
5424
+ }
5425
+ var SOURCES_FILENAME, ACTIVE_FILENAME;
5426
+ var init_external_sources = __esm({
5427
+ "src/providers/external-sources.ts"() {
5428
+ "use strict";
5429
+ SOURCES_FILENAME = "providers-sources.json";
5430
+ ACTIVE_FILENAME = "providers-active.json";
5431
+ }
5432
+ });
5433
+
5234
5434
  // src/cli-adapters/terminal-backends/ghostty-vt-backend.ts
5235
5435
  function isModuleNotFoundError(error, ref) {
5236
5436
  if (!(error instanceof Error)) return false;
@@ -5519,7 +5719,7 @@ var init_spawn_env = __esm({
5519
5719
  });
5520
5720
 
5521
5721
  // src/cli-adapters/pty-transport.ts
5522
- import * as os10 from "os";
5722
+ import * as os11 from "os";
5523
5723
  function loadNodePty() {
5524
5724
  if (cachedPty !== void 0) return cachedPty;
5525
5725
  try {
@@ -5570,11 +5770,11 @@ var init_pty_transport = __esm({
5570
5770
  let cwd = options.cwd;
5571
5771
  if (cwd) {
5572
5772
  try {
5573
- const fs27 = __require("fs");
5574
- const stat2 = fs27.statSync(cwd);
5575
- if (!stat2.isDirectory()) cwd = os10.homedir();
5773
+ const fs28 = __require("fs");
5774
+ const stat2 = fs28.statSync(cwd);
5775
+ if (!stat2.isDirectory()) cwd = os11.homedir();
5576
5776
  } catch {
5577
- cwd = os10.homedir();
5777
+ cwd = os11.homedir();
5578
5778
  }
5579
5779
  }
5580
5780
  const handle = pty.spawn(command, args, {
@@ -5591,8 +5791,8 @@ var init_pty_transport = __esm({
5591
5791
  });
5592
5792
 
5593
5793
  // src/cli-adapters/provider-cli-shared.ts
5594
- import * as os11 from "os";
5595
- import * as path15 from "path";
5794
+ import * as os12 from "os";
5795
+ import * as path16 from "path";
5596
5796
  function stripAnsi(str) {
5597
5797
  return str.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
5598
5798
  }
@@ -5668,21 +5868,21 @@ function buildCliScreenSnapshot(text) {
5668
5868
  function findBinary(name) {
5669
5869
  const trimmed = String(name || "").trim();
5670
5870
  if (!trimmed) return trimmed;
5671
- const expanded = trimmed.startsWith("~") ? path15.join(os11.homedir(), trimmed.slice(1)) : trimmed;
5672
- if (path15.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
5673
- return path15.isAbsolute(expanded) ? expanded : path15.resolve(expanded);
5871
+ const expanded = trimmed.startsWith("~") ? path16.join(os12.homedir(), trimmed.slice(1)) : trimmed;
5872
+ if (path16.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
5873
+ return path16.isAbsolute(expanded) ? expanded : path16.resolve(expanded);
5674
5874
  }
5675
- const isWin = os11.platform() === "win32";
5676
- const paths = (process.env.PATH || "").split(path15.delimiter);
5875
+ const isWin = os12.platform() === "win32";
5876
+ const paths = (process.env.PATH || "").split(path16.delimiter);
5677
5877
  const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
5678
5878
  for (const p of paths) {
5679
5879
  if (!p) continue;
5680
5880
  for (const ext of exes) {
5681
- const fullPath = path15.join(p, trimmed + ext);
5881
+ const fullPath = path16.join(p, trimmed + ext);
5682
5882
  try {
5683
- const fs27 = __require("fs");
5684
- if (fs27.existsSync(fullPath)) {
5685
- const stat2 = fs27.statSync(fullPath);
5883
+ const fs28 = __require("fs");
5884
+ if (fs28.existsSync(fullPath)) {
5885
+ const stat2 = fs28.statSync(fullPath);
5686
5886
  if (stat2.isFile() && (isWin || stat2.mode & 73)) {
5687
5887
  return fullPath;
5688
5888
  }
@@ -5694,14 +5894,14 @@ function findBinary(name) {
5694
5894
  return isWin ? `${trimmed}.cmd` : trimmed;
5695
5895
  }
5696
5896
  function isScriptBinary(binaryPath) {
5697
- if (!path15.isAbsolute(binaryPath)) return false;
5897
+ if (!path16.isAbsolute(binaryPath)) return false;
5698
5898
  try {
5699
- const fs27 = __require("fs");
5700
- const resolved = fs27.realpathSync(binaryPath);
5899
+ const fs28 = __require("fs");
5900
+ const resolved = fs28.realpathSync(binaryPath);
5701
5901
  const head = Buffer.alloc(8);
5702
- const fd = fs27.openSync(resolved, "r");
5703
- fs27.readSync(fd, head, 0, 8, 0);
5704
- fs27.closeSync(fd);
5902
+ const fd = fs28.openSync(resolved, "r");
5903
+ fs28.readSync(fd, head, 0, 8, 0);
5904
+ fs28.closeSync(fd);
5705
5905
  let i = 0;
5706
5906
  if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
5707
5907
  return head[i] === 35 && head[i + 1] === 33;
@@ -5710,14 +5910,14 @@ function isScriptBinary(binaryPath) {
5710
5910
  }
5711
5911
  }
5712
5912
  function looksLikeMachOOrElf(filePath) {
5713
- if (!path15.isAbsolute(filePath)) return false;
5913
+ if (!path16.isAbsolute(filePath)) return false;
5714
5914
  try {
5715
- const fs27 = __require("fs");
5716
- const resolved = fs27.realpathSync(filePath);
5915
+ const fs28 = __require("fs");
5916
+ const resolved = fs28.realpathSync(filePath);
5717
5917
  const buf = Buffer.alloc(8);
5718
- const fd = fs27.openSync(resolved, "r");
5719
- fs27.readSync(fd, buf, 0, 8, 0);
5720
- fs27.closeSync(fd);
5918
+ const fd = fs28.openSync(resolved, "r");
5919
+ fs28.readSync(fd, buf, 0, 8, 0);
5920
+ fs28.closeSync(fd);
5721
5921
  let i = 0;
5722
5922
  if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
5723
5923
  const b = buf.subarray(i);
@@ -5733,7 +5933,7 @@ function looksLikeMachOOrElf(filePath) {
5733
5933
  }
5734
5934
  function shSingleQuote(arg) {
5735
5935
  if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
5736
- if (os11.platform() === "win32") {
5936
+ if (os12.platform() === "win32") {
5737
5937
  return `"${arg.replace(/"/g, '""')}"`;
5738
5938
  }
5739
5939
  return `'${arg.replace(/'/g, `'\\''`)}'`;
@@ -7686,23 +7886,23 @@ var init_provider_cli_config = __esm({
7686
7886
  });
7687
7887
 
7688
7888
  // src/cli-adapters/provider-cli-runtime.ts
7689
- import * as os12 from "os";
7690
- import * as path16 from "path";
7889
+ import * as os13 from "os";
7890
+ import * as path17 from "path";
7691
7891
  import { DEFAULT_SESSION_HOST_COLS, DEFAULT_SESSION_HOST_ROWS } from "@adhdev/session-host-core";
7692
7892
  function resolveCliSpawnPlan(options) {
7693
7893
  const { provider, runtimeSettings, workingDir, extraArgs, extraEnv } = options;
7694
7894
  const { spawn: spawnConfig } = provider;
7695
7895
  const configuredCommand = typeof runtimeSettings.executablePath === "string" && runtimeSettings.executablePath.trim() ? runtimeSettings.executablePath.trim() : spawnConfig.command;
7696
7896
  const binaryPath = findBinary(configuredCommand);
7697
- const isWin = os12.platform() === "win32";
7897
+ const isWin = os13.platform() === "win32";
7698
7898
  const allArgs = [...spawnConfig.args, ...extraArgs].map(
7699
7899
  (arg) => typeof arg === "string" ? arg.replace(/\{\{workingDir\}\}/g, workingDir) : arg
7700
7900
  );
7701
7901
  let shellCmd;
7702
7902
  let shellArgs;
7703
- const useShellUnix = !isWin && (!!spawnConfig.shell || !path16.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
7903
+ const useShellUnix = !isWin && (!!spawnConfig.shell || !path17.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
7704
7904
  const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
7705
- const useShellWin = !!spawnConfig.shell || isCmdShim || !path16.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
7905
+ const useShellWin = !!spawnConfig.shell || isCmdShim || !path17.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
7706
7906
  const useShell = isWin ? useShellWin : useShellUnix;
7707
7907
  if (useShell) {
7708
7908
  shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
@@ -7792,7 +7992,7 @@ __export(provider_cli_adapter_exports, {
7792
7992
  appendBoundedText: () => appendBoundedText,
7793
7993
  normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
7794
7994
  });
7795
- import * as os13 from "os";
7995
+ import * as os14 from "os";
7796
7996
  function appendBoundedText(current, chunk, maxChars) {
7797
7997
  if (!chunk) return current.length <= maxChars ? current : current.slice(-maxChars);
7798
7998
  if (maxChars <= 0) return "";
@@ -7825,7 +8025,7 @@ var init_provider_cli_adapter = __esm({
7825
8025
  this.transportFactory = transportFactory;
7826
8026
  this.cliType = provider.type;
7827
8027
  this.cliName = provider.name;
7828
- this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os13.homedir()) : workingDir;
8028
+ this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os14.homedir()) : workingDir;
7829
8029
  const resolvedConfig = resolveCliAdapterConfig(provider);
7830
8030
  this.timeouts = resolvedConfig.timeouts;
7831
8031
  this.approvalKeys = resolvedConfig.approvalKeys;
@@ -9969,13 +10169,13 @@ __export(loader_exports, {
9969
10169
  loadSpec: () => loadSpec,
9970
10170
  resolveSpecPath: () => resolveSpecPath
9971
10171
  });
9972
- import * as fs8 from "fs";
9973
- import * as path17 from "path";
10172
+ import * as fs9 from "fs";
10173
+ import * as path18 from "path";
9974
10174
  import Ajv from "ajv";
9975
10175
  function loadSpec(sourcePath) {
9976
10176
  let raw;
9977
10177
  try {
9978
- const text = fs8.readFileSync(sourcePath, "utf8");
10178
+ const text = fs9.readFileSync(sourcePath, "utf8");
9979
10179
  raw = JSON.parse(text);
9980
10180
  } catch (err) {
9981
10181
  return { ok: false, errors: [`Failed to read spec: ${err.message}`], sourcePath };
@@ -10051,7 +10251,7 @@ function compileRegex2(source, flags, where, errs) {
10051
10251
  }
10052
10252
  }
10053
10253
  function resolveSpecPath(providerDir) {
10054
- return path17.join(providerDir, "spec.json");
10254
+ return path18.join(providerDir, "spec.json");
10055
10255
  }
10056
10256
  var ajv, validate;
10057
10257
  var init_loader = __esm({
@@ -10074,7 +10274,7 @@ __export(require_whitelist_exports, {
10074
10274
  registerProviderScriptRoot: () => registerProviderScriptRoot,
10075
10275
  unregisterProviderScriptRoot: () => unregisterProviderScriptRoot
10076
10276
  });
10077
- import * as path23 from "path";
10277
+ import * as path24 from "path";
10078
10278
  import { createRequire as createRequire3 } from "module";
10079
10279
  import * as nodeFs from "fs";
10080
10280
  import * as nodeChildProcess from "child_process";
@@ -10215,7 +10415,7 @@ function _getRegisteredRoots() {
10215
10415
  }
10216
10416
  function canonicalize(p) {
10217
10417
  try {
10218
- const resolved = path23.resolve(p);
10418
+ const resolved = path24.resolve(p);
10219
10419
  try {
10220
10420
  return nodeFs.realpathSync.native ? nodeFs.realpathSync.native(resolved) : nodeFs.realpathSync(resolved);
10221
10421
  } catch {
@@ -10235,7 +10435,7 @@ function isCallerInsideGatedRoot(callerFilename) {
10235
10435
  }
10236
10436
  for (const root of _gatedRoots) {
10237
10437
  if (normalized === root.rootPath) return root;
10238
- if (normalized.startsWith(root.rootPath + path23.sep)) return root;
10438
+ if (normalized.startsWith(root.rootPath + path24.sep)) return root;
10239
10439
  }
10240
10440
  return null;
10241
10441
  }
@@ -10254,16 +10454,16 @@ function ensureInstalled() {
10254
10454
  };
10255
10455
  }
10256
10456
  function gatedRequire(request, parent, isMain, gated, originalLoad) {
10257
- if (request.startsWith("./") || request.startsWith("../") || path23.isAbsolute(request)) {
10457
+ if (request.startsWith("./") || request.startsWith("../") || path24.isAbsolute(request)) {
10258
10458
  let resolved;
10259
10459
  try {
10260
- const callerRequire = parent?.filename ? createRequire3(parent.filename) : createRequire3(path23.join(gated.rootPath, "__entry__.js"));
10460
+ const callerRequire = parent?.filename ? createRequire3(parent.filename) : createRequire3(path24.join(gated.rootPath, "__entry__.js"));
10261
10461
  resolved = callerRequire.resolve(request);
10262
10462
  } catch {
10263
10463
  return originalLoad.call(this, request, parent, isMain);
10264
10464
  }
10265
10465
  const resolvedCanon = canonicalize(resolved) || resolved;
10266
- if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath + path23.sep))) {
10466
+ if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath + path24.sep))) {
10267
10467
  denyRequire(request, parent, `relative path escapes provider root (resolved to ${resolvedCanon})`);
10268
10468
  }
10269
10469
  return originalLoad.call(this, request, parent, isMain);
@@ -10379,9 +10579,9 @@ var native_history_executor_exports = {};
10379
10579
  __export(native_history_executor_exports, {
10380
10580
  executeNativeHistory: () => executeNativeHistory
10381
10581
  });
10382
- import * as fs12 from "fs";
10383
- import * as os17 from "os";
10384
- import * as path24 from "path";
10582
+ import * as fs13 from "fs";
10583
+ import * as os18 from "os";
10584
+ import * as path25 from "path";
10385
10585
  function executeNativeHistory(cfg, input) {
10386
10586
  if (!cfg?.source) return null;
10387
10587
  if (cfg.source.kind === "jsonl") return executeJsonl(cfg.source, input);
@@ -10400,7 +10600,7 @@ function executeJsonl(src, input) {
10400
10600
  } else {
10401
10601
  let stat2 = null;
10402
10602
  try {
10403
- stat2 = fs12.statSync(resolved);
10603
+ stat2 = fs13.statSync(resolved);
10404
10604
  } catch {
10405
10605
  return null;
10406
10606
  }
@@ -10419,7 +10619,7 @@ function executeJsonl(src, input) {
10419
10619
  const v = jsonPathGet(lines[0], src.session_id_path);
10420
10620
  if (typeof v === "string" && v) providerSessionId = v;
10421
10621
  } else if (src.session_id_from === "filename_uuid" || !src.session_id_from) {
10422
- const m = path24.basename(sourcePath).match(UUID_RE);
10622
+ const m = path25.basename(sourcePath).match(UUID_RE);
10423
10623
  if (m) providerSessionId = m[1];
10424
10624
  }
10425
10625
  const requested = input.providerSessionId || "";
@@ -10444,7 +10644,7 @@ function executeJsonl(src, input) {
10444
10644
  function readJsonlLines(p) {
10445
10645
  let text;
10446
10646
  try {
10447
- text = fs12.readFileSync(p, "utf8");
10647
+ text = fs13.readFileSync(p, "utf8");
10448
10648
  } catch {
10449
10649
  return [];
10450
10650
  }
@@ -10461,7 +10661,7 @@ function readJsonlLines(p) {
10461
10661
  }
10462
10662
  function executeSqlite(src, input) {
10463
10663
  const resolved = expandPath2(src.path, input);
10464
- if (!resolved || !fs12.existsSync(resolved)) return null;
10664
+ if (!resolved || !fs13.existsSync(resolved)) return null;
10465
10665
  let Database;
10466
10666
  try {
10467
10667
  Database = __require("better-sqlite3");
@@ -10520,19 +10720,19 @@ function expandPath2(template, input) {
10520
10720
  if (!template) return null;
10521
10721
  let out = template;
10522
10722
  if (out.startsWith("~/") || out === "~") {
10523
- out = path24.join(os17.homedir(), out.slice(2));
10723
+ out = path25.join(os18.homedir(), out.slice(2));
10524
10724
  }
10525
10725
  out = out.replace(/\$\{([A-Z_][A-Z0-9_]*)(?::-(.*?))?\}/g, (_m, name, fallback) => {
10526
10726
  const v = input.envOverrides?.[name] ?? process.env[name];
10527
10727
  return v != null && v !== "" ? v : fallback ?? "";
10528
10728
  });
10529
- if (out.startsWith("~/")) out = path24.join(os17.homedir(), out.slice(2));
10729
+ if (out.startsWith("~/")) out = path25.join(os18.homedir(), out.slice(2));
10530
10730
  const now = /* @__PURE__ */ new Date();
10531
10731
  const workspaceRaw = input.workspace ?? "";
10532
10732
  let workspaceResolved = workspaceRaw;
10533
10733
  if (workspaceRaw) {
10534
10734
  try {
10535
- workspaceResolved = fs12.realpathSync(workspaceRaw);
10735
+ workspaceResolved = fs13.realpathSync(workspaceRaw);
10536
10736
  } catch {
10537
10737
  }
10538
10738
  }
@@ -10574,20 +10774,20 @@ function expandDirGlob(template) {
10574
10774
  for (const d of dirs) {
10575
10775
  let entries;
10576
10776
  try {
10577
- entries = fs12.readdirSync(d, { withFileTypes: true });
10777
+ entries = fs13.readdirSync(d, { withFileTypes: true });
10578
10778
  } catch {
10579
10779
  continue;
10580
10780
  }
10581
10781
  for (const e of entries) {
10582
- if (e.isDirectory() && re.test(e.name)) next.push(path24.join(d, e.name));
10782
+ if (e.isDirectory() && re.test(e.name)) next.push(path25.join(d, e.name));
10583
10783
  }
10584
10784
  }
10585
10785
  } else {
10586
10786
  for (const d of dirs) {
10587
- const candidate = path24.join(d, seg);
10787
+ const candidate = path25.join(d, seg);
10588
10788
  let stat2 = null;
10589
10789
  try {
10590
- stat2 = fs12.statSync(candidate);
10790
+ stat2 = fs13.statSync(candidate);
10591
10791
  } catch {
10592
10792
  continue;
10593
10793
  }
@@ -10601,13 +10801,13 @@ function expandDirGlob(template) {
10601
10801
  function walkAllDirs(root, out) {
10602
10802
  let entries;
10603
10803
  try {
10604
- entries = fs12.readdirSync(root, { withFileTypes: true });
10804
+ entries = fs13.readdirSync(root, { withFileTypes: true });
10605
10805
  } catch {
10606
10806
  return;
10607
10807
  }
10608
10808
  out.push(root);
10609
10809
  for (const e of entries) {
10610
- if (e.isDirectory()) walkAllDirs(path24.join(root, e.name), out);
10810
+ if (e.isDirectory()) walkAllDirs(path25.join(root, e.name), out);
10611
10811
  }
10612
10812
  }
10613
10813
  function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs = 0) {
@@ -10617,13 +10817,13 @@ function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs
10617
10817
  for (const d of dirs) {
10618
10818
  let entries;
10619
10819
  try {
10620
- entries = fs12.readdirSync(d, { withFileTypes: true });
10820
+ entries = fs13.readdirSync(d, { withFileTypes: true });
10621
10821
  } catch {
10622
10822
  continue;
10623
10823
  }
10624
10824
  for (const e of entries) {
10625
10825
  if (!e.isFile() || !pattern.test(e.name)) continue;
10626
- const p = path24.join(d, e.name);
10826
+ const p = path25.join(d, e.name);
10627
10827
  const mtime = safeMtimeMs(p);
10628
10828
  if (mtime < cutoff) continue;
10629
10829
  if (!best || mtime > best.mtime) best = { p, mtime };
@@ -10634,7 +10834,7 @@ function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs
10634
10834
  function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
10635
10835
  let entries;
10636
10836
  try {
10637
- entries = fs12.readdirSync(dir, { withFileTypes: true });
10837
+ entries = fs13.readdirSync(dir, { withFileTypes: true });
10638
10838
  } catch {
10639
10839
  return null;
10640
10840
  }
@@ -10642,7 +10842,7 @@ function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
10642
10842
  let best = null;
10643
10843
  for (const e of entries) {
10644
10844
  if (!e.isFile() || !pattern.test(e.name)) continue;
10645
- const p = path24.join(dir, e.name);
10845
+ const p = path25.join(dir, e.name);
10646
10846
  const mtime = safeMtimeMs(p);
10647
10847
  if (mtime < cutoff) continue;
10648
10848
  if (!best || mtime > best.mtime) best = { p, mtime };
@@ -10651,7 +10851,7 @@ function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
10651
10851
  }
10652
10852
  function safeMtimeMs(p) {
10653
10853
  try {
10654
- return Math.floor(fs12.statSync(p).mtimeMs);
10854
+ return Math.floor(fs13.statSync(p).mtimeMs);
10655
10855
  } catch {
10656
10856
  return 0;
10657
10857
  }
@@ -10864,8 +11064,8 @@ var init_native_history_executor = __esm({
10864
11064
  });
10865
11065
 
10866
11066
  // src/providers/native-history/claude-cli-transcript.ts
10867
- import * as fs13 from "fs";
10868
- import * as path25 from "path";
11067
+ import * as fs14 from "fs";
11068
+ import * as path26 from "path";
10869
11069
  function extractTimestampValue(value) {
10870
11070
  if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
10871
11071
  if (typeof value === "string") {
@@ -10878,7 +11078,7 @@ function extractTimestampValue(value) {
10878
11078
  }
10879
11079
  function statMtimeMs(filePath) {
10880
11080
  try {
10881
- return fs13.statSync(filePath).mtimeMs;
11081
+ return fs14.statSync(filePath).mtimeMs;
10882
11082
  } catch {
10883
11083
  return 0;
10884
11084
  }
@@ -10948,7 +11148,7 @@ function extractUserContentParts(content) {
10948
11148
  function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
10949
11149
  let raw;
10950
11150
  try {
10951
- raw = fs13.readFileSync(filePath, "utf-8");
11151
+ raw = fs14.readFileSync(filePath, "utf-8");
10952
11152
  } catch {
10953
11153
  return [];
10954
11154
  }
@@ -11021,10 +11221,10 @@ function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
11021
11221
  return records;
11022
11222
  }
11023
11223
  function readSession(sessionPath) {
11024
- if (!sessionPath || !path25.isAbsolute(sessionPath)) return null;
11025
- const basename12 = path25.basename(sessionPath, ".jsonl");
11224
+ if (!sessionPath || !path26.isAbsolute(sessionPath)) return null;
11225
+ const basename12 = path26.basename(sessionPath, ".jsonl");
11026
11226
  if (!isSafeSessionId(basename12)) return null;
11027
- if (!fs13.existsSync(sessionPath)) return null;
11227
+ if (!fs14.existsSync(sessionPath)) return null;
11028
11228
  const sourceMtimeMs = statMtimeMs(sessionPath);
11029
11229
  const messages = parseTranscriptFile(sessionPath, basename12);
11030
11230
  if (messages.length === 0) return null;
@@ -11047,8 +11247,8 @@ var init_claude_cli_transcript = __esm({
11047
11247
  });
11048
11248
 
11049
11249
  // src/providers/native-history/codex-cli-transcript.ts
11050
- import * as fs14 from "fs";
11051
- import * as path26 from "path";
11250
+ import * as fs15 from "fs";
11251
+ import * as path27 from "path";
11052
11252
  function extractTimestampValue2(value) {
11053
11253
  if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
11054
11254
  if (typeof value === "string") {
@@ -11061,7 +11261,7 @@ function extractTimestampValue2(value) {
11061
11261
  }
11062
11262
  function statMtimeMs2(filePath) {
11063
11263
  try {
11064
- return fs14.statSync(filePath).mtimeMs;
11264
+ return fs15.statSync(filePath).mtimeMs;
11065
11265
  } catch {
11066
11266
  return 0;
11067
11267
  }
@@ -11129,7 +11329,7 @@ function extractToolOutputContent(payload) {
11129
11329
  }
11130
11330
  function readSessionMeta(filePath) {
11131
11331
  try {
11132
- const firstLine = fs14.readFileSync(filePath, "utf-8").split("\n").find(Boolean);
11332
+ const firstLine = fs15.readFileSync(filePath, "utf-8").split("\n").find(Boolean);
11133
11333
  if (!firstLine) return null;
11134
11334
  const parsed = JSON.parse(firstLine);
11135
11335
  if (String(parsed.type ?? "") !== "session_meta") return null;
@@ -11141,7 +11341,7 @@ function readSessionMeta(filePath) {
11141
11341
  function parseSessionFile(filePath, sessionId, workspaceFallback) {
11142
11342
  let raw;
11143
11343
  try {
11144
- raw = fs14.readFileSync(filePath, "utf-8");
11344
+ raw = fs15.readFileSync(filePath, "utf-8");
11145
11345
  } catch {
11146
11346
  return [];
11147
11347
  }
@@ -11235,11 +11435,11 @@ function parseSessionFile(filePath, sessionId, workspaceFallback) {
11235
11435
  return records;
11236
11436
  }
11237
11437
  function readSession2(sessionPath) {
11238
- if (!sessionPath || !path26.isAbsolute(sessionPath)) return null;
11239
- if (!fs14.existsSync(sessionPath)) return null;
11438
+ if (!sessionPath || !path27.isAbsolute(sessionPath)) return null;
11439
+ if (!fs15.existsSync(sessionPath)) return null;
11240
11440
  const meta = readSessionMeta(sessionPath);
11241
11441
  const metaId = String(meta?.id ?? "").trim();
11242
- const basename12 = path26.basename(sessionPath, ".jsonl");
11442
+ const basename12 = path27.basename(sessionPath, ".jsonl");
11243
11443
  const uuidMatch = basename12.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);
11244
11444
  const filenameUuid = uuidMatch ? uuidMatch[1] : "";
11245
11445
  if (metaId && filenameUuid && metaId !== filenameUuid) return null;
@@ -11268,9 +11468,9 @@ var init_codex_cli_transcript = __esm({
11268
11468
  });
11269
11469
 
11270
11470
  // src/providers/native-history/antigravity-cli-transcript.ts
11271
- import * as fs15 from "fs";
11272
- import * as path27 from "path";
11273
- import * as os18 from "os";
11471
+ import * as fs16 from "fs";
11472
+ import * as path28 from "path";
11473
+ import * as os19 from "os";
11274
11474
  function extractTimestampValue3(value) {
11275
11475
  if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
11276
11476
  if (typeof value === "string") {
@@ -11283,7 +11483,7 @@ function extractTimestampValue3(value) {
11283
11483
  }
11284
11484
  function statMtimeMs3(filePath) {
11285
11485
  try {
11286
- return fs15.statSync(filePath).mtimeMs;
11486
+ return fs16.statSync(filePath).mtimeMs;
11287
11487
  } catch {
11288
11488
  return 0;
11289
11489
  }
@@ -11292,13 +11492,13 @@ function isUuidLike(value) {
11292
11492
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
11293
11493
  }
11294
11494
  function antigravityRoot() {
11295
- return path27.join(os18.homedir(), ".gemini", "antigravity-cli");
11495
+ return path28.join(os19.homedir(), ".gemini", "antigravity-cli");
11296
11496
  }
11297
11497
  function historyJsonlPath() {
11298
- return path27.join(antigravityRoot(), "history.jsonl");
11498
+ return path28.join(antigravityRoot(), "history.jsonl");
11299
11499
  }
11300
11500
  function brainRoot() {
11301
- return path27.join(antigravityRoot(), "brain");
11501
+ return path28.join(antigravityRoot(), "brain");
11302
11502
  }
11303
11503
  function extractUserRequestContent(content) {
11304
11504
  const raw = content.trim();
@@ -11314,7 +11514,7 @@ function antigravityRowKind(rowType) {
11314
11514
  function parseBrainTranscript(filePath, sessionId, workspace) {
11315
11515
  let raw;
11316
11516
  try {
11317
- raw = fs15.readFileSync(filePath, "utf-8");
11517
+ raw = fs16.readFileSync(filePath, "utf-8");
11318
11518
  } catch {
11319
11519
  return null;
11320
11520
  }
@@ -11374,7 +11574,7 @@ function readHistoryRows() {
11374
11574
  const sourcePath = historyJsonlPath();
11375
11575
  let lines = [];
11376
11576
  try {
11377
- lines = fs15.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
11577
+ lines = fs16.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
11378
11578
  } catch {
11379
11579
  return [];
11380
11580
  }
@@ -11421,7 +11621,7 @@ function extractStringsFromBuffer(buf) {
11421
11621
  function parsePbFile(filePath, sessionId) {
11422
11622
  let buf;
11423
11623
  try {
11424
- buf = fs15.readFileSync(filePath);
11624
+ buf = fs16.readFileSync(filePath);
11425
11625
  } catch {
11426
11626
  return null;
11427
11627
  }
@@ -11444,13 +11644,13 @@ function parsePbFile(filePath, sessionId) {
11444
11644
  ];
11445
11645
  }
11446
11646
  function readSession3(sessionPath, sessionId, workspace) {
11447
- if (!sessionPath || !path27.isAbsolute(sessionPath)) return null;
11448
- if (!fs15.existsSync(sessionPath)) return null;
11647
+ if (!sessionPath || !path28.isAbsolute(sessionPath)) return null;
11648
+ if (!fs16.existsSync(sessionPath)) return null;
11449
11649
  const sourceMtimeMs = statMtimeMs3(sessionPath);
11450
11650
  const brainRootPath = brainRoot();
11451
- if (sessionPath.startsWith(brainRootPath + path27.sep) && sessionPath.endsWith(".jsonl")) {
11452
- const relative4 = sessionPath.slice(brainRootPath.length + 1);
11453
- const uuidFromPath = relative4.split(path27.sep)[0];
11651
+ if (sessionPath.startsWith(brainRootPath + path28.sep) && sessionPath.endsWith(".jsonl")) {
11652
+ const relative5 = sessionPath.slice(brainRootPath.length + 1);
11653
+ const uuidFromPath = relative5.split(path28.sep)[0];
11454
11654
  const resolvedSessionId = sessionId || (isUuidLike(uuidFromPath) ? uuidFromPath : "");
11455
11655
  if (!resolvedSessionId) return null;
11456
11656
  const messages = parseBrainTranscript(sessionPath, resolvedSessionId, workspace);
@@ -11466,7 +11666,7 @@ function readSession3(sessionPath, sessionId, workspace) {
11466
11666
  };
11467
11667
  }
11468
11668
  if (sessionPath.endsWith(".pb")) {
11469
- const pbSessionId = sessionId || path27.basename(sessionPath, ".pb");
11669
+ const pbSessionId = sessionId || path28.basename(sessionPath, ".pb");
11470
11670
  if (!isUuidLike(pbSessionId)) return null;
11471
11671
  const messages = parsePbFile(sessionPath, pbSessionId);
11472
11672
  if (!messages || messages.length === 0) return null;
@@ -11480,7 +11680,7 @@ function readSession3(sessionPath, sessionId, workspace) {
11480
11680
  partialReason: "antigravity_cli_pb_raw_text_extraction"
11481
11681
  };
11482
11682
  }
11483
- if (path27.basename(sessionPath) === "history.jsonl") {
11683
+ if (path28.basename(sessionPath) === "history.jsonl") {
11484
11684
  const resolvedSessionId = sessionId || "";
11485
11685
  if (!resolvedSessionId || !isUuidLike(resolvedSessionId)) return null;
11486
11686
  const rows = readHistoryRows().filter((r) => r.conversationId === resolvedSessionId);
@@ -11534,18 +11734,18 @@ var init_antigravity_cli_transcript = __esm({
11534
11734
  });
11535
11735
 
11536
11736
  // src/providers/native-history/hermes-cli-transcript.ts
11537
- import * as fs16 from "fs";
11538
- import * as path28 from "path";
11539
- import * as os19 from "os";
11737
+ import * as fs17 from "fs";
11738
+ import * as path29 from "path";
11739
+ import * as os20 from "os";
11540
11740
  function statMtimeMs4(p) {
11541
11741
  try {
11542
- return Math.floor(fs16.statSync(p).mtimeMs);
11742
+ return Math.floor(fs17.statSync(p).mtimeMs);
11543
11743
  } catch {
11544
11744
  return 0;
11545
11745
  }
11546
11746
  }
11547
11747
  function openDb() {
11548
- if (!fs16.existsSync(HERMES_STATE_DB)) return null;
11748
+ if (!fs17.existsSync(HERMES_STATE_DB)) return null;
11549
11749
  try {
11550
11750
  const Database = __require("better-sqlite3");
11551
11751
  return new Database(HERMES_STATE_DB, { readonly: true, fileMustExist: true });
@@ -11602,10 +11802,10 @@ function readSession4(sessionPath) {
11602
11802
  }
11603
11803
  }
11604
11804
  }
11605
- if (!path28.isAbsolute(sessionPath) || !fs16.existsSync(sessionPath)) return null;
11805
+ if (!path29.isAbsolute(sessionPath) || !fs17.existsSync(sessionPath)) return null;
11606
11806
  let raw;
11607
11807
  try {
11608
- raw = JSON.parse(fs16.readFileSync(sessionPath, "utf8"));
11808
+ raw = JSON.parse(fs17.readFileSync(sessionPath, "utf8"));
11609
11809
  } catch {
11610
11810
  return null;
11611
11811
  }
@@ -11628,7 +11828,7 @@ function readSession4(sessionPath) {
11628
11828
  });
11629
11829
  }
11630
11830
  if (messages.length === 0) return null;
11631
- const sessionId = typeof raw.session_id === "string" && raw.session_id ? raw.session_id : path28.basename(sessionPath, ".json").replace(/^session_/, "");
11831
+ const sessionId = typeof raw.session_id === "string" && raw.session_id ? raw.session_id : path29.basename(sessionPath, ".json").replace(/^session_/, "");
11632
11832
  return {
11633
11833
  messages,
11634
11834
  providerSessionId: sessionId,
@@ -11649,8 +11849,8 @@ var HERMES_STATE_DB, HERMES_LEGACY_SESSIONS_DIR;
11649
11849
  var init_hermes_cli_transcript = __esm({
11650
11850
  "src/providers/native-history/hermes-cli-transcript.ts"() {
11651
11851
  "use strict";
11652
- HERMES_STATE_DB = path28.join(os19.homedir(), ".hermes", "state.db");
11653
- HERMES_LEGACY_SESSIONS_DIR = path28.join(os19.homedir(), ".hermes", "sessions");
11852
+ HERMES_STATE_DB = path29.join(os20.homedir(), ".hermes", "state.db");
11853
+ HERMES_LEGACY_SESSIONS_DIR = path29.join(os20.homedir(), ".hermes", "sessions");
11654
11854
  }
11655
11855
  });
11656
11856
 
@@ -11659,9 +11859,9 @@ var dispatcher_exports = {};
11659
11859
  __export(dispatcher_exports, {
11660
11860
  createNativeHistoryDispatcher: () => createNativeHistoryDispatcher
11661
11861
  });
11662
- import * as fs17 from "fs";
11663
- import * as os20 from "os";
11664
- import * as path29 from "path";
11862
+ import * as fs18 from "fs";
11863
+ import * as os21 from "os";
11864
+ import * as path30 from "path";
11665
11865
  function createNativeHistoryDispatcher(reader) {
11666
11866
  return (input) => {
11667
11867
  const workspace = input.workspace || "";
@@ -11701,26 +11901,26 @@ function resolveSourcePath(reader, workspace, sessionId) {
11701
11901
  }
11702
11902
  }
11703
11903
  function resolveClaudePath(workspace, sessionId) {
11704
- const dir = path29.join(os20.homedir(), ".claude", "projects", cwdAsDashes(workspace));
11705
- if (!fs17.existsSync(dir)) return null;
11904
+ const dir = path30.join(os21.homedir(), ".claude", "projects", cwdAsDashes(workspace));
11905
+ if (!fs18.existsSync(dir)) return null;
11706
11906
  if (sessionId) {
11707
- const candidate = path29.join(dir, `${sessionId}.jsonl`);
11708
- if (fs17.existsSync(candidate)) return candidate;
11907
+ const candidate = path30.join(dir, `${sessionId}.jsonl`);
11908
+ if (fs18.existsSync(candidate)) return candidate;
11709
11909
  }
11710
11910
  return null;
11711
11911
  }
11712
11912
  function resolveCodexPath(workspace) {
11713
11913
  void workspace;
11714
11914
  const now = /* @__PURE__ */ new Date();
11715
- const dir = path29.join(
11716
- os20.homedir(),
11915
+ const dir = path30.join(
11916
+ os21.homedir(),
11717
11917
  ".codex",
11718
11918
  "sessions",
11719
11919
  String(now.getUTCFullYear()),
11720
11920
  String(now.getUTCMonth() + 1).padStart(2, "0"),
11721
11921
  String(now.getUTCDate()).padStart(2, "0")
11722
11922
  );
11723
- if (fs17.existsSync(dir)) {
11923
+ if (fs18.existsSync(dir)) {
11724
11924
  const f = newestRecentFile2(dir, /\.jsonl$/);
11725
11925
  if (f) return f;
11726
11926
  }
@@ -11728,23 +11928,23 @@ function resolveCodexPath(workspace) {
11728
11928
  }
11729
11929
  function resolveAntigravityPath(workspace) {
11730
11930
  void workspace;
11731
- const brainRoot2 = path29.join(os20.homedir(), ".gemini", "antigravity-cli", "brain");
11732
- if (!fs17.existsSync(brainRoot2)) return null;
11931
+ const brainRoot2 = path30.join(os21.homedir(), ".gemini", "antigravity-cli", "brain");
11932
+ if (!fs18.existsSync(brainRoot2)) return null;
11733
11933
  const cutoff = Date.now() - RECENT_WINDOW_MS;
11734
- const entries = fs17.readdirSync(brainRoot2, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => ({ p: path29.join(brainRoot2, e.name), mtime: safeMtime(path29.join(brainRoot2, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
11934
+ const entries = fs18.readdirSync(brainRoot2, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => ({ p: path30.join(brainRoot2, e.name), mtime: safeMtime(path30.join(brainRoot2, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
11735
11935
  for (const e of entries) {
11736
- const t = path29.join(e.p, ".system_generated", "logs", "transcript.jsonl");
11737
- if (fs17.existsSync(t)) return t;
11936
+ const t = path30.join(e.p, ".system_generated", "logs", "transcript.jsonl");
11937
+ if (fs18.existsSync(t)) return t;
11738
11938
  }
11739
11939
  return null;
11740
11940
  }
11741
11941
  function resolveHermesPath(workspace, sessionId) {
11742
11942
  void workspace;
11743
11943
  void sessionId;
11744
- const dbPath = path29.join(os20.homedir(), ".hermes", "state.db");
11745
- if (fs17.existsSync(dbPath)) return dbPath;
11746
- const dir = path29.join(os20.homedir(), ".hermes", "sessions");
11747
- if (!fs17.existsSync(dir)) return null;
11944
+ const dbPath = path30.join(os21.homedir(), ".hermes", "state.db");
11945
+ if (fs18.existsSync(dbPath)) return dbPath;
11946
+ const dir = path30.join(os21.homedir(), ".hermes", "sessions");
11947
+ if (!fs18.existsSync(dir)) return null;
11748
11948
  return newestRecentFile2(dir, /^session_.*\.json$/);
11749
11949
  }
11750
11950
  function readByReader(reader, sourcePath, sessionId, workspace) {
@@ -11766,7 +11966,7 @@ function cwdAsDashes(cwd) {
11766
11966
  function newestRecentFile2(dir, pattern) {
11767
11967
  try {
11768
11968
  const cutoff = Date.now() - RECENT_WINDOW_MS;
11769
- const entries = fs17.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && pattern.test(e.name)).map((e) => ({ p: path29.join(dir, e.name), mtime: safeMtime(path29.join(dir, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
11969
+ const entries = fs18.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && pattern.test(e.name)).map((e) => ({ p: path30.join(dir, e.name), mtime: safeMtime(path30.join(dir, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
11770
11970
  return entries[0]?.p ?? null;
11771
11971
  } catch {
11772
11972
  return null;
@@ -11774,7 +11974,7 @@ function newestRecentFile2(dir, pattern) {
11774
11974
  }
11775
11975
  function safeMtime(p) {
11776
11976
  try {
11777
- return Math.floor(fs17.statSync(p).mtimeMs);
11977
+ return Math.floor(fs18.statSync(p).mtimeMs);
11778
11978
  } catch {
11779
11979
  return 0;
11780
11980
  }
@@ -12042,12 +12242,12 @@ function parseSubmoduleStatusOutput(output, repoRoot, ignorePaths) {
12042
12242
  if (!match) continue;
12043
12243
  const prefix = match[1];
12044
12244
  const commit = match[2];
12045
- const path39 = match[3];
12046
- if (ignoreSet.has(path39)) continue;
12245
+ const path40 = match[3];
12246
+ if (ignoreSet.has(path40)) continue;
12047
12247
  submodules.push({
12048
- path: path39,
12248
+ path: path40,
12049
12249
  commit,
12050
- repoPath: repoRoot + "/" + path39,
12250
+ repoPath: repoRoot + "/" + path40,
12051
12251
  dirty: prefix === "+",
12052
12252
  outOfSync: prefix === "-",
12053
12253
  lastCheckedAt: Date.now()
@@ -13551,10 +13751,10 @@ function getRegistryPath() {
13551
13751
  return join8(getDaemonDataDir(), "mesh-coordinators.json");
13552
13752
  }
13553
13753
  function loadMeshCoordinatorRegistry() {
13554
- const path39 = getRegistryPath();
13555
- if (!existsSync7(path39)) return;
13754
+ const path40 = getRegistryPath();
13755
+ if (!existsSync7(path40)) return;
13556
13756
  try {
13557
- const raw = JSON.parse(readFileSync5(path39, "utf-8"));
13757
+ const raw = JSON.parse(readFileSync5(path40, "utf-8"));
13558
13758
  if (!Array.isArray(raw)) return;
13559
13759
  _registry.clear();
13560
13760
  for (const entry of raw) {
@@ -13773,8 +13973,8 @@ function validateMeshRefineConfig(config, source = "inline") {
13773
13973
  if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
13774
13974
  return { valid: errors.length === 0, errors, bootstrapCommands, commands, rejectedCommands };
13775
13975
  }
13776
- function parseConfigText(path39, text) {
13777
- if (/\.json$/i.test(path39)) return JSON.parse(text);
13976
+ function parseConfigText(path40, text) {
13977
+ if (/\.json$/i.test(path40)) return JSON.parse(text);
13778
13978
  return yaml.load(text);
13779
13979
  }
13780
13980
  function loadMeshRefineConfig(mesh, workspace) {
@@ -13785,16 +13985,16 @@ function loadMeshRefineConfig(mesh, workspace) {
13785
13985
  if (!validation.valid) return { source: "mesh.policy.refineConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
13786
13986
  return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
13787
13987
  }
13788
- for (const relative4 of MESH_REFINE_CONFIG_LOCATIONS) {
13789
- const configPath = join9(workspace, relative4);
13988
+ for (const relative5 of MESH_REFINE_CONFIG_LOCATIONS) {
13989
+ const configPath = join9(workspace, relative5);
13790
13990
  if (!existsSync8(configPath)) continue;
13791
13991
  try {
13792
13992
  const parsed = parseConfigText(configPath, readFileSync6(configPath, "utf-8"));
13793
- const validation = validateMeshRefineConfig(parsed, relative4);
13794
- if (!validation.valid) return { source: relative4, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
13795
- return { config: parsed, source: relative4, sourceType: "repo_file", path: configPath };
13993
+ const validation = validateMeshRefineConfig(parsed, relative5);
13994
+ if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
13995
+ return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
13796
13996
  } catch (error) {
13797
- return { source: relative4, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
13997
+ return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
13798
13998
  }
13799
13999
  }
13800
14000
  return {
@@ -13927,8 +14127,8 @@ var MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA = {
13927
14127
  var DEFAULT_TIMEOUT_MS2 = 12e4;
13928
14128
  var DEFAULT_OUTPUT_LIMIT_BYTES = 128 * 1024;
13929
14129
  var OUTPUT_SUMMARY_CHARS = 2e3;
13930
- function parseConfigText2(path39, text) {
13931
- if (/\.json$/i.test(path39)) return JSON.parse(text);
14130
+ function parseConfigText2(path40, text) {
14131
+ if (/\.json$/i.test(path40)) return JSON.parse(text);
13932
14132
  return yaml2.load(text);
13933
14133
  }
13934
14134
  function truncateOutput(value) {
@@ -13968,16 +14168,16 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
13968
14168
  if (!validation.valid) return { source: "mesh.policy.worktreeBootstrapConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
13969
14169
  return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
13970
14170
  }
13971
- for (const relative4 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
13972
- const configPath = join10(workspace, relative4);
14171
+ for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
14172
+ const configPath = join10(workspace, relative5);
13973
14173
  if (!existsSync9(configPath)) continue;
13974
14174
  try {
13975
14175
  const parsed = parseConfigText2(configPath, readFileSync7(configPath, "utf-8"));
13976
- const validation = validateMeshWorktreeBootstrapConfig(parsed, relative4);
13977
- if (!validation.valid) return { source: relative4, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
13978
- return { config: parsed, source: relative4, sourceType: "repo_file", path: configPath };
14176
+ const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
14177
+ if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
14178
+ return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
13979
14179
  } catch (error) {
13980
- return { source: relative4, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
14180
+ return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
13981
14181
  }
13982
14182
  }
13983
14183
  return { source: "unavailable", sourceType: "unavailable", error: `No worktree bootstrap config found. Checked: ${MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS.join(", ")}` };
@@ -15218,17 +15418,17 @@ function checkPathExists(paths) {
15218
15418
  return null;
15219
15419
  }
15220
15420
  async function detectIDEs(providerLoader) {
15221
- const os28 = platform2();
15421
+ const os29 = platform2();
15222
15422
  const results = [];
15223
15423
  for (const def of getMergedDefinitions()) {
15224
15424
  const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
15225
- const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os28] || []) || []);
15425
+ const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os29] || []) || []);
15226
15426
  let resolvedCli = cliPath;
15227
- if (!resolvedCli && appPath && os28 === "darwin") {
15427
+ if (!resolvedCli && appPath && os29 === "darwin") {
15228
15428
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
15229
15429
  if (existsSync15(bundledCli)) resolvedCli = bundledCli;
15230
15430
  }
15231
- if (!resolvedCli && appPath && os28 === "win32") {
15431
+ if (!resolvedCli && appPath && os29 === "win32") {
15232
15432
  const { dirname: dirname11 } = await import("path");
15233
15433
  const appDir = dirname11(appPath);
15234
15434
  const candidates = [
@@ -15245,7 +15445,7 @@ async function detectIDEs(providerLoader) {
15245
15445
  }
15246
15446
  }
15247
15447
  }
15248
- const installed = os28 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
15448
+ const installed = os29 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
15249
15449
  const version = resolvedCli ? await getIdeVersion(resolvedCli) : null;
15250
15450
  results.push({
15251
15451
  id: def.id,
@@ -25627,6 +25827,14 @@ var DaemonCommandHandler = class {
25627
25827
  return this.handleCheckProviderUpdates(args);
25628
25828
  case "list_installed_providers":
25629
25829
  return this.handleListInstalledProviders(args);
25830
+ case "add_provider_source":
25831
+ return this.handleAddProviderSource(args);
25832
+ case "remove_provider_source":
25833
+ return this.handleRemoveProviderSource(args);
25834
+ case "list_provider_sources":
25835
+ return this.handleListProviderSources(args);
25836
+ case "set_active_provider_source":
25837
+ return this.handleSetActiveProviderSource(args);
25630
25838
  // ─── Stream commands (stream-commands.ts) ───────────
25631
25839
  case "select_session":
25632
25840
  return handleSelectSession(this, args);
@@ -25690,49 +25898,62 @@ var DaemonCommandHandler = class {
25690
25898
  return { success: false, error: "ProviderLoader not initialized" };
25691
25899
  }
25692
25900
  /**
25693
- * Return per-provider availability so a Marketplace UI can show
25694
- * "Installed" badges. Reuses the existing detection state from
25901
+ * Return per-provider availability so the dashboard's provider catalog
25902
+ * can show "Installed" badges. Reuses the existing detection state from
25695
25903
  * ProviderLoader.getMachineProviderStatus() — no probing is triggered.
25696
25904
  */
25697
25905
  handleListProviderAvailability(_args) {
25698
25906
  if (!this._ctx.providerLoader) {
25699
25907
  return { success: false, error: "ProviderLoader not initialized" };
25700
25908
  }
25909
+ const { describeTrust: describeTrust2, requiresConfirmation: requiresConfirmation2 } = (init_provider_trust(), __toCommonJS(provider_trust_exports));
25701
25910
  const loader = this._ctx.providerLoader;
25702
25911
  const items = loader.getAll().map((provider) => {
25703
25912
  const machineConfig = loader.getMachineProviderConfig(provider.type);
25704
25913
  const lastDetection = machineConfig.lastDetection;
25914
+ const trust = provider._sourceTrust ?? "trusted";
25915
+ const layer = provider._sourceLayer ?? "upstream";
25916
+ const sourceName = provider._sourceName ?? null;
25705
25917
  return {
25706
25918
  type: provider.type,
25707
25919
  category: provider.category,
25708
25920
  status: loader.getMachineProviderStatus(provider.type),
25709
25921
  installed: lastDetection?.ok === true,
25710
25922
  detectedPath: lastDetection?.path ?? null,
25711
- checkedAt: lastDetection?.checkedAt ?? null
25923
+ checkedAt: lastDetection?.checkedAt ?? null,
25924
+ trust,
25925
+ trustDescription: describeTrust2(trust),
25926
+ requiresConfirmation: requiresConfirmation2(trust),
25927
+ sourceLayer: layer,
25928
+ sourceName
25712
25929
  };
25713
25930
  });
25714
25931
  return { success: true, providers: items };
25715
25932
  }
25716
25933
  /**
25717
- * Compute the *Marketplace install root*. This is always
25718
- * `~/.adhdev/marketplace/` regardless of how ProviderLoader resolved its
25719
- * userDir (which can point to a sibling adhdev-providers git checkout in
25720
- * dev). Marketplace-installed manifests must never overwrite files in a
25721
- * developer checkout, and they should be isolated from upstream/registry
25722
- * sync so they survive `refresh_scripts`.
25934
+ * Compute the *upstream cache root*. install_provider_manifest writes
25935
+ * official-registry manifests here so the daemon's standard upstream
25936
+ * layer picks them up no special handling needed at load time, and
25937
+ * the manifests inherit the official-trust badge instead of the
25938
+ * untrusted-external one.
25939
+ *
25940
+ * Path matches ProviderLoader.upstreamDir but we recompute it from
25941
+ * homedir() so this method stays usable in dev where userDir can
25942
+ * point at a sibling git checkout.
25723
25943
  */
25724
- getMarketplaceInstallRoot() {
25725
- const os28 = __require("os");
25726
- const path39 = __require("path");
25727
- return path39.join(os28.homedir(), ".adhdev", "marketplace");
25944
+ getUpstreamInstallRoot() {
25945
+ const os29 = __require("os");
25946
+ const path40 = __require("path");
25947
+ return path40.join(os29.homedir(), ".adhdev", "providers", ".upstream");
25728
25948
  }
25729
25949
  /**
25730
25950
  * Download a single provider manifest from the registry and write it to
25731
- * ~/.adhdev/marketplace/{category}/{type}/provider.json.
25951
+ * ~/.adhdev/providers/.upstream/{category}/{type}/provider.json.
25732
25952
  *
25733
- * Used by the Marketplace UI's Install button. Verifies SHA-256 checksum
25734
- * against the registry meta before persisting. Refuses to write outside
25735
- * the marketplace root.
25953
+ * Used by standalone onboarding to seed the upstream cache with the
25954
+ * default provider set on first launch. Verifies SHA-256 checksum
25955
+ * against the registry meta before persisting. Refuses to write
25956
+ * outside the upstream root.
25736
25957
  *
25737
25958
  * Args: { type: string, category?: string, version?: string }
25738
25959
  * If category/version are omitted, looks up the latest from the registry.
@@ -25747,8 +25968,8 @@ var DaemonCommandHandler = class {
25747
25968
  return { success: false, error: "invalid type" };
25748
25969
  }
25749
25970
  const https = __require("https");
25750
- const fs27 = __require("fs");
25751
- const path39 = __require("path");
25971
+ const fs28 = __require("fs");
25972
+ const path40 = __require("path");
25752
25973
  const crypto6 = __require("crypto");
25753
25974
  const REGISTRY = "https://api.adhf.dev/api/v1/registry";
25754
25975
  function fetchText(url, timeoutMs) {
@@ -25785,13 +26006,13 @@ var DaemonCommandHandler = class {
25785
26006
  if (actualChecksum !== meta.checksum) {
25786
26007
  return { success: false, error: `checksum mismatch: expected ${meta.checksum}, got ${actualChecksum}` };
25787
26008
  }
25788
- const installRoot = this.getMarketplaceInstallRoot();
25789
- const installRootResolved = path39.resolve(installRoot);
25790
- const targetDir = path39.resolve(path39.join(installRoot, category, type));
25791
- if (!targetDir.startsWith(installRootResolved + path39.sep)) {
25792
- return { success: false, error: "install path escaped marketplace root" };
26009
+ const installRoot = this.getUpstreamInstallRoot();
26010
+ const installRootResolved = path40.resolve(installRoot);
26011
+ const targetDir = path40.resolve(path40.join(installRoot, category, type));
26012
+ if (!targetDir.startsWith(installRootResolved + path40.sep)) {
26013
+ return { success: false, error: "install path escaped upstream root" };
25793
26014
  }
25794
- fs27.mkdirSync(targetDir, { recursive: true });
26015
+ fs28.mkdirSync(targetDir, { recursive: true });
25795
26016
  let manifestProbe = {};
25796
26017
  try {
25797
26018
  manifestProbe = JSON.parse(manifestBody);
@@ -25815,8 +26036,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
25815
26036
  }
25816
26037
  }
25817
26038
  const targetFile = isV1 ? "provider.v1.json" : "provider.json";
25818
- const targetPath = path39.join(targetDir, targetFile);
25819
- fs27.writeFileSync(targetPath, manifestBody, "utf-8");
26039
+ const targetPath = path40.join(targetDir, targetFile);
26040
+ fs28.writeFileSync(targetPath, manifestBody, "utf-8");
25820
26041
  const manifestJson = JSON.parse(manifestBody);
25821
26042
  const scriptFetch = await this.fetchProviderSources(
25822
26043
  manifestJson,
@@ -25864,6 +26085,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
25864
26085
  if (Array.isArray(manifest.compatibility)) {
25865
26086
  for (const c of manifest.compatibility) {
25866
26087
  if (typeof c?.scriptDir === "string") scriptDirs.add(c.scriptDir);
26088
+ if (typeof c?.spec === "string" && c.spec.includes("/")) {
26089
+ const dir = c.spec.substring(0, c.spec.lastIndexOf("/"));
26090
+ if (dir) scriptDirs.add(dir);
26091
+ }
25867
26092
  }
25868
26093
  }
25869
26094
  if (manifest.overrides && typeof manifest.overrides === "object" && !Array.isArray(manifest.overrides)) {
@@ -25882,8 +26107,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
25882
26107
  const repo = source.repo;
25883
26108
  const ref = source.ref;
25884
26109
  const https = __require("https");
25885
- const fs27 = __require("fs");
25886
- const path39 = __require("path");
26110
+ const fs28 = __require("fs");
26111
+ const path40 = __require("path");
25887
26112
  function fetchJson(url, timeoutMs) {
25888
26113
  return new Promise((resolve23, reject) => {
25889
26114
  const req = https.get(url, {
@@ -25939,9 +26164,9 @@ ${formatManifestValidationIssues2(validation.issues)}`,
25939
26164
  }
25940
26165
  let fetchedCount = 0;
25941
26166
  const sharedDirRel = `${category}/_shared`;
25942
- const sharedTargetDir = path39.resolve(path39.join(targetDir, "../_shared"));
25943
- const installRootResolved = path39.resolve(path39.join(targetDir, "../.."));
25944
- if (sharedTargetDir.startsWith(installRootResolved + path39.sep)) {
26167
+ const sharedTargetDir = path40.resolve(path40.join(targetDir, "../_shared"));
26168
+ const installRootResolved = path40.resolve(path40.join(targetDir, "../.."));
26169
+ if (sharedTargetDir.startsWith(installRootResolved + path40.sep)) {
25945
26170
  const sharedStack = [sharedDirRel];
25946
26171
  while (sharedStack.length) {
25947
26172
  const relDir = sharedStack.pop();
@@ -25964,10 +26189,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
25964
26189
  try {
25965
26190
  const body = await fetchBinary(entry.download_url, 3e4);
25966
26191
  const relInside = entry.path.startsWith(sharedDirRel + "/") ? entry.path.slice(sharedDirRel.length + 1) : entry.path;
25967
- const outPath = path39.resolve(path39.join(sharedTargetDir, relInside));
25968
- if (!outPath.startsWith(path39.resolve(sharedTargetDir) + path39.sep)) continue;
25969
- fs27.mkdirSync(path39.dirname(outPath), { recursive: true });
25970
- fs27.writeFileSync(outPath, body);
26192
+ const outPath = path40.resolve(path40.join(sharedTargetDir, relInside));
26193
+ if (!outPath.startsWith(path40.resolve(sharedTargetDir) + path40.sep)) continue;
26194
+ fs28.mkdirSync(path40.dirname(outPath), { recursive: true });
26195
+ fs28.writeFileSync(outPath, body);
25971
26196
  fetchedCount++;
25972
26197
  } catch (e) {
25973
26198
  errors.push(`fetch shared ${entry.path}: ${e?.message ?? e}`);
@@ -26000,13 +26225,13 @@ ${formatManifestValidationIssues2(validation.issues)}`,
26000
26225
  try {
26001
26226
  const body = await fetchBinary(entry.download_url, 3e4);
26002
26227
  const relInsideProvider = entry.path.startsWith(subdir + "/") ? entry.path.slice(subdir.length + 1) : entry.path;
26003
- const outPath = path39.resolve(path39.join(targetDir, relInsideProvider));
26004
- if (!outPath.startsWith(path39.resolve(targetDir) + path39.sep)) {
26228
+ const outPath = path40.resolve(path40.join(targetDir, relInsideProvider));
26229
+ if (!outPath.startsWith(path40.resolve(targetDir) + path40.sep)) {
26005
26230
  errors.push(`refusing to write outside targetDir: ${entry.path}`);
26006
26231
  continue;
26007
26232
  }
26008
- fs27.mkdirSync(path39.dirname(outPath), { recursive: true });
26009
- fs27.writeFileSync(outPath, body);
26233
+ fs28.mkdirSync(path40.dirname(outPath), { recursive: true });
26234
+ fs28.writeFileSync(outPath, body);
26010
26235
  fetchedCount++;
26011
26236
  } catch (e) {
26012
26237
  errors.push(`fetch ${entry.path}: ${e?.message ?? e}`);
@@ -26017,9 +26242,12 @@ ${formatManifestValidationIssues2(validation.issues)}`,
26017
26242
  return { fetchedCount, source: `${repo}@${ref}`, errors };
26018
26243
  }
26019
26244
  /**
26020
- * Remove a provider manifest from the marketplace install root
26021
- * (~/.adhdev/marketplace/{category}/{type}/). Refuses to touch anything
26022
- * outside that root.
26245
+ * Remove a provider manifest from the upstream cache root
26246
+ * (~/.adhdev/providers/.upstream/{category}/{type}/). Refuses to touch
26247
+ * anything outside that root. Used by onboarding to opt out of a
26248
+ * provider the user doesn't want; the dashboard no longer exposes a
26249
+ * per-provider uninstall button (external sources are removed as a
26250
+ * whole via remove_provider_source).
26023
26251
  */
26024
26252
  async handleUninstallProviderManifest(args) {
26025
26253
  const type = typeof args?.type === "string" ? args.type : "";
@@ -26031,19 +26259,19 @@ ${formatManifestValidationIssues2(validation.issues)}`,
26031
26259
  if (!["cli", "ide", "extension", "acp"].includes(category)) {
26032
26260
  return { success: false, error: `unknown category: ${category}` };
26033
26261
  }
26034
- const fs27 = __require("fs");
26035
- const path39 = __require("path");
26262
+ const fs28 = __require("fs");
26263
+ const path40 = __require("path");
26036
26264
  try {
26037
- const installRoot = this.getMarketplaceInstallRoot();
26038
- const installRootResolved = path39.resolve(installRoot);
26039
- const targetDir = path39.resolve(path39.join(installRoot, category, type));
26040
- if (!targetDir.startsWith(installRootResolved + path39.sep)) {
26041
- return { success: false, error: "refusing to delete outside marketplace root" };
26265
+ const installRoot = this.getUpstreamInstallRoot();
26266
+ const installRootResolved = path40.resolve(installRoot);
26267
+ const targetDir = path40.resolve(path40.join(installRoot, category, type));
26268
+ if (!targetDir.startsWith(installRootResolved + path40.sep)) {
26269
+ return { success: false, error: "refusing to delete outside upstream root" };
26042
26270
  }
26043
- if (!fs27.existsSync(targetDir)) {
26271
+ if (!fs28.existsSync(targetDir)) {
26044
26272
  return { success: false, error: "not installed" };
26045
26273
  }
26046
- fs27.rmSync(targetDir, { recursive: true, force: true });
26274
+ fs28.rmSync(targetDir, { recursive: true, force: true });
26047
26275
  if (this._ctx.providerLoader) {
26048
26276
  this._ctx.providerLoader.reload();
26049
26277
  this._ctx.providerLoader.registerToDetector();
@@ -26054,33 +26282,33 @@ ${formatManifestValidationIssues2(validation.issues)}`,
26054
26282
  }
26055
26283
  }
26056
26284
  /**
26057
- * Return everything currently installed in ~/.adhdev/marketplace/ with its
26285
+ * Return everything currently installed in the upstream cache with its
26058
26286
  * version. This is the "what does this daemon have" answer used both by
26059
26287
  * the UI and by the update checker.
26060
26288
  */
26061
26289
  handleListInstalledProviders(_args) {
26062
- const fs27 = __require("fs");
26063
- const path39 = __require("path");
26064
- const installRoot = this.getMarketplaceInstallRoot();
26065
- if (!fs27.existsSync(installRoot)) return { success: true, providers: [] };
26290
+ const fs28 = __require("fs");
26291
+ const path40 = __require("path");
26292
+ const installRoot = this.getUpstreamInstallRoot();
26293
+ if (!fs28.existsSync(installRoot)) return { success: true, providers: [] };
26066
26294
  const CATEGORIES = ["cli", "ide", "extension", "acp"];
26067
26295
  const items = [];
26068
26296
  for (const category of CATEGORIES) {
26069
- const categoryDir = path39.join(installRoot, category);
26070
- if (!fs27.existsSync(categoryDir)) continue;
26297
+ const categoryDir = path40.join(installRoot, category);
26298
+ if (!fs28.existsSync(categoryDir)) continue;
26071
26299
  let entries;
26072
26300
  try {
26073
- entries = fs27.readdirSync(categoryDir);
26301
+ entries = fs28.readdirSync(categoryDir);
26074
26302
  } catch {
26075
26303
  continue;
26076
26304
  }
26077
26305
  for (const type of entries) {
26078
- const v1Path = path39.join(categoryDir, type, "provider.v1.json");
26079
- const v0Path = path39.join(categoryDir, type, "provider.json");
26080
- const manifestPath = fs27.existsSync(v1Path) ? v1Path : fs27.existsSync(v0Path) ? v0Path : null;
26306
+ const v1Path = path40.join(categoryDir, type, "provider.v1.json");
26307
+ const v0Path = path40.join(categoryDir, type, "provider.json");
26308
+ const manifestPath = fs28.existsSync(v1Path) ? v1Path : fs28.existsSync(v0Path) ? v0Path : null;
26081
26309
  if (!manifestPath) continue;
26082
26310
  try {
26083
- const m = JSON.parse(fs27.readFileSync(manifestPath, "utf-8"));
26311
+ const m = JSON.parse(fs28.readFileSync(manifestPath, "utf-8"));
26084
26312
  items.push({
26085
26313
  type,
26086
26314
  category,
@@ -26157,6 +26385,196 @@ ${formatManifestValidationIssues2(validation.issues)}`,
26157
26385
  );
26158
26386
  return { success: true, providers: checks };
26159
26387
  }
26388
+ // ─── External provider sources (3rd-party git URLs) ──────────────
26389
+ /**
26390
+ * Register a new external provider source. The daemon clones the repo
26391
+ * to ~/.adhdev/external/<name>/, walks it once to detect provided
26392
+ * types, and surfaces any conflicts with already-installed types so
26393
+ * the dashboard can ask the user how to resolve them.
26394
+ *
26395
+ * Args: { url: string, ref?: string, name?: string }
26396
+ * - url: https://, git@, or any git-cloneable URL
26397
+ * - ref: branch/tag/commit (default "main")
26398
+ * - name: short identifier (default derived from URL)
26399
+ *
26400
+ * Returns: { source, providers, conflicts }
26401
+ * - conflicts: list of types this new source provides that another
26402
+ * source already exposes. UI uses this to prompt for active-source
26403
+ * selection before the load takes effect.
26404
+ */
26405
+ async handleAddProviderSource(args) {
26406
+ const url = typeof args?.url === "string" ? args.url.trim() : "";
26407
+ if (!url) return { success: false, error: "url is required" };
26408
+ const ref = typeof args?.ref === "string" && args.ref.trim() ? args.ref.trim() : "main";
26409
+ if (url.startsWith("-")) return { success: false, error: 'url must not start with "-"' };
26410
+ if (ref.startsWith("-")) return { success: false, error: 'ref must not start with "-"' };
26411
+ if (!/^(https?:\/\/|git@[a-z0-9._-]+:)[a-z0-9._@:/~\-]+$/i.test(url)) {
26412
+ return { success: false, error: "url must be https://\u2026 or git@host:\u2026 and contain only URL-safe characters" };
26413
+ }
26414
+ if (!/^[A-Za-z0-9._/-]+$/.test(ref)) {
26415
+ return { success: false, error: "ref must contain only [A-Za-z0-9._/-]" };
26416
+ }
26417
+ const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
26418
+ const requestedName = typeof args?.name === "string" && args.name.trim() ? args.name.trim() : ext.deriveSourceName(url);
26419
+ if (!/^@[a-z0-9_-]+$/i.test(requestedName)) {
26420
+ return { success: false, error: "name must match @[a-z0-9_-]+" };
26421
+ }
26422
+ const fs28 = __require("fs");
26423
+ const path40 = __require("path");
26424
+ const { spawnSync: spawnSync2 } = __require("child_process");
26425
+ const file = ext.loadExternalSources();
26426
+ if (file.sources.some((s) => s.name === requestedName)) {
26427
+ return { success: false, error: `source name "${requestedName}" is already registered` };
26428
+ }
26429
+ if (file.sources.some((s) => s.url === url && s.ref === ref)) {
26430
+ return { success: false, error: `source url+ref already registered (use a different name to track another ref)` };
26431
+ }
26432
+ const sourceDir = path40.join(ext.externalRoot(), requestedName);
26433
+ if (!fs28.existsSync(ext.externalRoot())) fs28.mkdirSync(ext.externalRoot(), { recursive: true });
26434
+ if (fs28.existsSync(sourceDir)) {
26435
+ return { success: false, error: `directory already exists: ${sourceDir} (rename or remove first)` };
26436
+ }
26437
+ const clone = spawnSync2("git", ["clone", "--depth=1", "--branch", ref, "--", url, sourceDir], {
26438
+ encoding: "utf-8",
26439
+ stdio: ["ignore", "pipe", "pipe"],
26440
+ timeout: 6e4
26441
+ });
26442
+ if (clone.status !== 0) {
26443
+ try {
26444
+ fs28.rmSync(sourceDir, { recursive: true, force: true });
26445
+ } catch {
26446
+ }
26447
+ return { success: false, error: `git clone failed: ${(clone.stderr || clone.stdout || "").trim() || "unknown error"}` };
26448
+ }
26449
+ const source = {
26450
+ name: requestedName,
26451
+ url,
26452
+ ref,
26453
+ addedAt: (/* @__PURE__ */ new Date()).toISOString()
26454
+ };
26455
+ ext.saveExternalSources({ schema: 1, sources: [...file.sources, source] });
26456
+ const inventory = ext.inventoryExternalSources();
26457
+ const conflicts = [];
26458
+ const newEntry = inventory.find((e) => e.sourceName === requestedName);
26459
+ if (newEntry) {
26460
+ for (const [category, types] of Object.entries(newEntry.providers)) {
26461
+ for (const type of types) {
26462
+ const sources = ext.sourcesProviding(category, type);
26463
+ if (sources.length > 1) conflicts.push({ category, type, sources });
26464
+ }
26465
+ }
26466
+ }
26467
+ if (this._ctx.providerLoader) {
26468
+ this._ctx.providerLoader.reload();
26469
+ this._ctx.providerLoader.registerToDetector();
26470
+ }
26471
+ return {
26472
+ success: true,
26473
+ source,
26474
+ providers: newEntry?.providers ?? {},
26475
+ conflicts
26476
+ };
26477
+ }
26478
+ /**
26479
+ * Remove a registered external source. Deletes the clone directory and
26480
+ * any active-source entry pointing to it.
26481
+ *
26482
+ * Args: { name: string }
26483
+ */
26484
+ async handleRemoveProviderSource(args) {
26485
+ const name = typeof args?.name === "string" ? args.name.trim() : "";
26486
+ if (!name) return { success: false, error: "name is required" };
26487
+ const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
26488
+ const fs28 = __require("fs");
26489
+ const path40 = __require("path");
26490
+ const file = ext.loadExternalSources();
26491
+ const match = file.sources.find((s) => s.name === name);
26492
+ if (!match) return { success: false, error: `source "${name}" not registered` };
26493
+ const sourceDir = path40.join(ext.externalRoot(), name);
26494
+ if (fs28.existsSync(sourceDir)) {
26495
+ try {
26496
+ fs28.rmSync(sourceDir, { recursive: true, force: true });
26497
+ } catch (e) {
26498
+ return { success: false, error: `failed to delete ${sourceDir}: ${e?.message || e}` };
26499
+ }
26500
+ }
26501
+ ext.saveExternalSources({
26502
+ schema: 1,
26503
+ sources: file.sources.filter((s) => s.name !== name)
26504
+ });
26505
+ const active = ext.loadProvidersActive();
26506
+ const filteredActive = {};
26507
+ for (const [type, src] of Object.entries(active.active)) {
26508
+ if (src !== name) filteredActive[type] = src;
26509
+ }
26510
+ ext.saveProvidersActive({ schema: 1, active: filteredActive });
26511
+ if (this._ctx.providerLoader) {
26512
+ this._ctx.providerLoader.reload();
26513
+ this._ctx.providerLoader.registerToDetector();
26514
+ }
26515
+ return { success: true, removed: { name } };
26516
+ }
26517
+ /**
26518
+ * List registered external sources + each source's currently installed
26519
+ * providers + the active selection for any conflicting types. Used by
26520
+ * the dashboard's "Sources" tab.
26521
+ */
26522
+ handleListProviderSources(_args) {
26523
+ const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
26524
+ const file = ext.loadExternalSources();
26525
+ const inventory = ext.inventoryExternalSources();
26526
+ const active = ext.loadProvidersActive();
26527
+ const sources = file.sources.map((s) => {
26528
+ const inv = inventory.find((e) => e.sourceName === s.name);
26529
+ return {
26530
+ ...s,
26531
+ providers: inv?.providers ?? {}
26532
+ };
26533
+ });
26534
+ const conflictMap = /* @__PURE__ */ new Map();
26535
+ for (const inv of inventory) {
26536
+ for (const [category, types] of Object.entries(inv.providers)) {
26537
+ for (const type of types) {
26538
+ const candidates = ext.sourcesProviding(category, type);
26539
+ if (candidates.length > 1 && !conflictMap.has(type)) {
26540
+ conflictMap.set(type, { category, sources: candidates });
26541
+ }
26542
+ }
26543
+ }
26544
+ }
26545
+ const conflicts = [...conflictMap.entries()].map(([type, info]) => ({
26546
+ type,
26547
+ category: info.category,
26548
+ candidates: info.sources,
26549
+ active: active.active[type] ?? null
26550
+ }));
26551
+ return { success: true, sources, conflicts };
26552
+ }
26553
+ /**
26554
+ * Pick which source's copy of a conflicting provider type is active.
26555
+ * Other sources' copies stay on disk but the loader ignores them.
26556
+ *
26557
+ * Args: { type: string, sourceName: string }
26558
+ */
26559
+ handleSetActiveProviderSource(args) {
26560
+ const type = typeof args?.type === "string" ? args.type.trim() : "";
26561
+ const sourceName = typeof args?.sourceName === "string" ? args.sourceName.trim() : "";
26562
+ if (!type || !sourceName) return { success: false, error: "type and sourceName are required" };
26563
+ const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
26564
+ const inventory = ext.inventoryExternalSources();
26565
+ const entry = inventory.find((e) => e.sourceName === sourceName);
26566
+ if (!entry) return { success: false, error: `source "${sourceName}" not found` };
26567
+ const provided = Object.values(entry.providers).some((types) => types.includes(type));
26568
+ if (!provided) return { success: false, error: `source "${sourceName}" does not provide type "${type}"` };
26569
+ const active = ext.loadProvidersActive();
26570
+ active.active[type] = sourceName;
26571
+ ext.saveProvidersActive(active);
26572
+ if (this._ctx.providerLoader) {
26573
+ this._ctx.providerLoader.reload();
26574
+ this._ctx.providerLoader.registerToDetector();
26575
+ }
26576
+ return { success: true, type, sourceName };
26577
+ }
26160
26578
  // ─── DevServer HTTP proxy helpers ─────────────────
26161
26579
  // These bridge WS commands to the DevServer REST API (localhost:19280)
26162
26580
  async proxyDevServerPost(args, endpoint) {
@@ -26252,29 +26670,29 @@ ${formatManifestValidationIssues2(validation.issues)}`,
26252
26670
  init_provider_cli_adapter();
26253
26671
  init_cli_detector();
26254
26672
  init_config();
26255
- import * as os16 from "os";
26256
- import * as path22 from "path";
26673
+ import * as os17 from "os";
26674
+ import * as path23 from "path";
26257
26675
  import * as crypto5 from "crypto";
26258
- import { existsSync as existsSync20, mkdirSync as mkdirSync10, writeFileSync as writeFileSync13 } from "fs";
26676
+ import { existsSync as existsSync21, mkdirSync as mkdirSync11, writeFileSync as writeFileSync14 } from "fs";
26259
26677
  import { execFileSync } from "child_process";
26260
26678
  import chalk from "chalk";
26261
26679
 
26262
26680
  // src/providers/cli-provider-instance.ts
26263
- import * as os15 from "os";
26264
- import * as path20 from "path";
26681
+ import * as os16 from "os";
26682
+ import * as path21 from "path";
26265
26683
  import * as crypto4 from "crypto";
26266
- import * as fs11 from "fs";
26684
+ import * as fs12 from "fs";
26267
26685
  import { createRequire as createRequire2 } from "module";
26268
26686
 
26269
26687
  // src/providers/spec/route.ts
26270
26688
  init_provider_cli_adapter();
26271
- import * as fs10 from "fs";
26272
- import * as path19 from "path";
26689
+ import * as fs11 from "fs";
26690
+ import * as path20 from "path";
26273
26691
 
26274
26692
  // src/providers/spec/driver.ts
26275
- import * as fs9 from "fs";
26276
- import * as os14 from "os";
26277
- import * as path18 from "path";
26693
+ import * as fs10 from "fs";
26694
+ import * as os15 from "os";
26695
+ import * as path19 from "path";
26278
26696
 
26279
26697
  // src/providers/spec/adapter.ts
26280
26698
  init_pty_transport();
@@ -26651,7 +27069,7 @@ var SpecDriver = class {
26651
27069
  }
26652
27070
  armSpecWatcher() {
26653
27071
  try {
26654
- this.specWatcher = fs9.watch(this.opts.specPath, { persistent: false }, () => {
27072
+ this.specWatcher = fs10.watch(this.opts.specPath, { persistent: false }, () => {
26655
27073
  const res = loadSpec(this.opts.specPath);
26656
27074
  if (!res.ok) {
26657
27075
  this.emit({ kind: "spec_error", errors: res.errors });
@@ -26744,7 +27162,7 @@ var SpecDriver = class {
26744
27162
  }
26745
27163
  fireDelegate(d) {
26746
27164
  const ev = this.currentEval;
26747
- const task = d.task_template.replace(/\{node\}/g, os14.hostname()).replace(/\{state\.label\}/g, ev?.state.label ?? "").replace(/\{state\.title\}/g, ev?.state.title ?? "").replace(/\{duration_ms\}/g, String(d.after_duration_ms ?? 0));
27165
+ const task = d.task_template.replace(/\{node\}/g, os15.hostname()).replace(/\{state\.label\}/g, ev?.state.label ?? "").replace(/\{state\.title\}/g, ev?.state.title ?? "").replace(/\{duration_ms\}/g, String(d.after_duration_ms ?? 0));
26748
27166
  this.emit({ kind: "delegate", id: d.id, task });
26749
27167
  }
26750
27168
  // ────────────────────────────────────────────────────────────────────
@@ -26813,9 +27231,9 @@ var SpecDriver = class {
26813
27231
  const ctl = (this.spec.control_bar ?? []).find((c) => c.action.type === "attach_image");
26814
27232
  if (!ctl || ctl.action.type !== "attach_image") return;
26815
27233
  const ext = guessExt(mime);
26816
- const tmp = path18.join(os14.tmpdir(), `adhdev-attach-${Date.now()}${ext}`);
27234
+ const tmp = path19.join(os15.tmpdir(), `adhdev-attach-${Date.now()}${ext}`);
26817
27235
  try {
26818
- fs9.writeFileSync(tmp, Buffer.from(blob, "base64"));
27236
+ fs10.writeFileSync(tmp, Buffer.from(blob, "base64"));
26819
27237
  } catch {
26820
27238
  return;
26821
27239
  }
@@ -27143,14 +27561,14 @@ init_logger();
27143
27561
  function createCliAdapter(provider, workingDir, cliArgs, extraEnv, transportFactory) {
27144
27562
  const resolvedSpecPath = provider._resolvedSpecPath;
27145
27563
  const dir = provider._resolvedProviderDir;
27146
- let specPath = resolvedSpecPath && fs10.existsSync(resolvedSpecPath) ? resolvedSpecPath : void 0;
27564
+ let specPath = resolvedSpecPath && fs11.existsSync(resolvedSpecPath) ? resolvedSpecPath : void 0;
27147
27565
  if (!specPath && dir) {
27148
- const legacy = path19.join(dir, "spec.json");
27149
- if (fs10.existsSync(legacy)) specPath = legacy;
27566
+ const legacy = path20.join(dir, "spec.json");
27567
+ if (fs11.existsSync(legacy)) specPath = legacy;
27150
27568
  }
27151
27569
  if (specPath) {
27152
27570
  try {
27153
- LOG.info("spec-route", `[${provider.type}] routing through SpecCliAdapter (${path19.relative(dir || "", specPath) || specPath})`);
27571
+ LOG.info("spec-route", `[${provider.type}] routing through SpecCliAdapter (${path20.relative(dir || "", specPath) || specPath})`);
27154
27572
  return new SpecCliAdapter(specPath, workingDir, cliArgs, extraEnv, transportFactory);
27155
27573
  } catch (err) {
27156
27574
  LOG.warn("spec-route", `[${provider.type}] spec invalid, falling back to ProviderCliAdapter: ${err.message}`);
@@ -27211,7 +27629,7 @@ function filePathFromUri(uri) {
27211
27629
  return uri.slice("file://".length);
27212
27630
  }
27213
27631
  }
27214
- if (path20.isAbsolute(uri)) return uri;
27632
+ if (path21.isAbsolute(uri)) return uri;
27215
27633
  return null;
27216
27634
  }
27217
27635
  function extensionForImageMime(mimeType) {
@@ -27226,9 +27644,9 @@ function materializeImageDataPart(part, index, dir) {
27226
27644
  if (!part.data) return null;
27227
27645
  const rawData = part.data.includes(",") ? part.data.split(",").pop() || "" : part.data;
27228
27646
  if (!rawData) return null;
27229
- fs11.mkdirSync(dir, { recursive: true });
27230
- const filePath = path20.join(dir, safeInputImageBasename(index, part.mimeType));
27231
- fs11.writeFileSync(filePath, Buffer.from(rawData, "base64"));
27647
+ fs12.mkdirSync(dir, { recursive: true });
27648
+ const filePath = path21.join(dir, safeInputImageBasename(index, part.mimeType));
27649
+ fs12.writeFileSync(filePath, Buffer.from(rawData, "base64"));
27232
27650
  cleanupStaleMaterializedImages(dir);
27233
27651
  return filePath;
27234
27652
  }
@@ -27240,14 +27658,14 @@ function cleanupStaleMaterializedImages(dir) {
27240
27658
  if (now - lastMaterializedImageCleanupAt < MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS) return;
27241
27659
  lastMaterializedImageCleanupAt = now;
27242
27660
  try {
27243
- const entries = fs11.readdirSync(dir);
27661
+ const entries = fs12.readdirSync(dir);
27244
27662
  for (const entry of entries) {
27245
27663
  if (!entry.startsWith("adhdev-input-image-")) continue;
27246
- const fullPath = path20.join(dir, entry);
27664
+ const fullPath = path21.join(dir, entry);
27247
27665
  try {
27248
- const stat2 = fs11.statSync(fullPath);
27666
+ const stat2 = fs12.statSync(fullPath);
27249
27667
  if (now - stat2.mtimeMs > MATERIALIZED_IMAGE_MAX_AGE_MS) {
27250
- fs11.unlinkSync(fullPath);
27668
+ fs12.unlinkSync(fullPath);
27251
27669
  }
27252
27670
  } catch {
27253
27671
  }
@@ -27266,7 +27684,7 @@ function buildCliStructuredInputPrompt(input, options = {}) {
27266
27684
  const promptParts = [];
27267
27685
  const imageRefs = [];
27268
27686
  const resourceRefs = [];
27269
- const materializeDir = options.materializeDir || path20.join(os15.tmpdir(), "adhdev-input-media");
27687
+ const materializeDir = options.materializeDir || path21.join(os16.tmpdir(), "adhdev-input-media");
27270
27688
  input.parts.forEach((part, index) => {
27271
27689
  if (part.type === "text" && part.text.trim()) {
27272
27690
  promptParts.push(part.text.trim());
@@ -27333,7 +27751,7 @@ function buildIncrementalHistoryAppendMessages(previousMessages, currentMessages
27333
27751
  var CachedDatabaseSync = null;
27334
27752
  function getDatabaseSync() {
27335
27753
  if (CachedDatabaseSync) return CachedDatabaseSync;
27336
- const requireFn = typeof __require === "function" ? __require : createRequire2(path20.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
27754
+ const requireFn = typeof __require === "function" ? __require : createRequire2(path21.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
27337
27755
  const sqliteModule = requireFn(`node:${"sqlite"}`);
27338
27756
  CachedDatabaseSync = sqliteModule.DatabaseSync;
27339
27757
  if (!CachedDatabaseSync) {
@@ -27487,10 +27905,10 @@ var CliProviderInstance = class {
27487
27905
  * Replaces the previously duplicated probeOpenCode/Codex/Goose functions.
27488
27906
  */
27489
27907
  probeSessionIdFromConfig(probe) {
27490
- const resolvedDbPath = probe.dbPath.replace(/^~/, os15.homedir());
27908
+ const resolvedDbPath = probe.dbPath.replace(/^~/, os16.homedir());
27491
27909
  const now = Date.now();
27492
27910
  if (this.cachedSqliteDbMissingUntil > now) return null;
27493
- if (!fs11.existsSync(resolvedDbPath)) {
27911
+ if (!fs12.existsSync(resolvedDbPath)) {
27494
27912
  this.cachedSqliteDbMissingUntil = now + 1e4;
27495
27913
  return null;
27496
27914
  }
@@ -28592,7 +29010,7 @@ ${effect.notification.body || ""}`.trim();
28592
29010
  };
28593
29011
  addDir(this.workingDir);
28594
29012
  try {
28595
- addDir(fs11.realpathSync.native(this.workingDir));
29013
+ addDir(fs12.realpathSync.native(this.workingDir));
28596
29014
  } catch {
28597
29015
  }
28598
29016
  return Array.from(dirs);
@@ -28629,7 +29047,7 @@ ${effect.notification.body || ""}`.trim();
28629
29047
  };
28630
29048
 
28631
29049
  // src/providers/acp-provider-instance.ts
28632
- import * as path21 from "path";
29050
+ import * as path22 from "path";
28633
29051
  import { Readable, Writable } from "stream";
28634
29052
  import { spawn } from "child_process";
28635
29053
  import {
@@ -29409,7 +29827,7 @@ var AcpProviderInstance = class {
29409
29827
  return b.uri ? {
29410
29828
  type: "resource_link",
29411
29829
  uri: b.uri,
29412
- name: path21.basename(b.uri),
29830
+ name: path22.basename(b.uri),
29413
29831
  mimeType: b.mimeType,
29414
29832
  ...b.transcript ? { description: b.transcript } : {}
29415
29833
  } : { type: "text", text: b.transcript || `[Video attachment: ${b.mimeType}]` };
@@ -29867,17 +30285,17 @@ function shouldRestoreHostedRuntime(record, managerTag) {
29867
30285
  // src/commands/cli-manager.ts
29868
30286
  function isExplicitCommand(command) {
29869
30287
  const trimmed = command.trim();
29870
- return path22.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
30288
+ return path23.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
29871
30289
  }
29872
30290
  function expandExecutable(command) {
29873
30291
  const trimmed = command.trim();
29874
- return trimmed.startsWith("~") ? path22.join(os16.homedir(), trimmed.slice(1)) : trimmed;
30292
+ return trimmed.startsWith("~") ? path23.join(os17.homedir(), trimmed.slice(1)) : trimmed;
29875
30293
  }
29876
30294
  function commandExists(command) {
29877
30295
  const trimmed = command.trim();
29878
30296
  if (!trimmed) return false;
29879
30297
  if (isExplicitCommand(trimmed)) {
29880
- return existsSync20(expandExecutable(trimmed));
30298
+ return existsSync21(expandExecutable(trimmed));
29881
30299
  }
29882
30300
  try {
29883
30301
  execFileSync(process.platform === "win32" ? "where" : "which", [trimmed], {
@@ -29998,11 +30416,11 @@ function hasCliArg(args, flag) {
29998
30416
  return args.some((arg) => arg === flag || arg.startsWith(`${flag}=`));
29999
30417
  }
30000
30418
  function ensureEmptyDelegatedMcpConfig(workspace) {
30001
- const baseDir = path22.join(os16.tmpdir(), "adhdev-delegated-agent-empty-mcp");
30002
- mkdirSync10(baseDir, { recursive: true });
30003
- const workspaceHash = crypto5.createHash("sha256").update(path22.resolve(workspace || os16.tmpdir())).digest("hex").slice(0, 16);
30004
- const filePath = path22.join(baseDir, `${workspaceHash}.json`);
30005
- writeFileSync13(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
30419
+ const baseDir = path23.join(os17.tmpdir(), "adhdev-delegated-agent-empty-mcp");
30420
+ mkdirSync11(baseDir, { recursive: true });
30421
+ const workspaceHash = crypto5.createHash("sha256").update(path23.resolve(workspace || os17.tmpdir())).digest("hex").slice(0, 16);
30422
+ const filePath = path23.join(baseDir, `${workspaceHash}.json`);
30423
+ writeFileSync14(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
30006
30424
  return filePath;
30007
30425
  }
30008
30426
  function buildCoordinatorDelegatedCliLaunchOptions(input) {
@@ -30295,7 +30713,7 @@ var DaemonCliManager = class {
30295
30713
  async startSession(cliType, workingDir, cliArgs, initialModel, options) {
30296
30714
  const trimmed = (workingDir || "").trim();
30297
30715
  if (!trimmed) throw new Error("working directory required");
30298
- const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os16.homedir()) : path22.resolve(trimmed);
30716
+ const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os17.homedir()) : path23.resolve(trimmed);
30299
30717
  const normalizedType = this.providerLoader.resolveAlias(cliType);
30300
30718
  const rawProvider = this.providerLoader.getByAlias(cliType);
30301
30719
  const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
@@ -30680,6 +31098,20 @@ Run 'adhdev doctor' for detailed diagnostics.`
30680
31098
  cliArgs: args?.cliArgs,
30681
31099
  env: args?.env
30682
31100
  }) : null;
31101
+ const provLookup = this.providerLoader.getMeta(this.providerLoader.resolveAlias(cliType));
31102
+ const provTrust = provLookup?._sourceTrust;
31103
+ if (provTrust === "external-untrusted" && args?.confirmExternalUntrusted !== true) {
31104
+ return {
31105
+ success: false,
31106
+ error: "untrusted_external_provider",
31107
+ provider: {
31108
+ type: provLookup?.type ?? cliType,
31109
+ sourceName: provLookup?._sourceName ?? null,
31110
+ trust: provTrust
31111
+ },
31112
+ hint: "Resend launch_cli with confirmExternalUntrusted=true after the user explicitly approves running JavaScript from this 3rd-party source."
31113
+ };
31114
+ }
30683
31115
  const started = await this.startSession(
30684
31116
  cliType,
30685
31117
  dir,
@@ -30866,13 +31298,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
30866
31298
  // src/launch.ts
30867
31299
  import { exec as exec4, spawn as spawn2 } from "child_process";
30868
31300
  import * as net from "net";
30869
- import * as os22 from "os";
30870
- import * as path31 from "path";
31301
+ import * as os23 from "os";
31302
+ import * as path32 from "path";
30871
31303
 
30872
31304
  // src/providers/provider-loader.ts
30873
- import * as fs18 from "fs";
30874
- import * as path30 from "path";
30875
- import * as os21 from "os";
31305
+ import * as fs19 from "fs";
31306
+ import * as path31 from "path";
31307
+ import * as os22 from "os";
30876
31308
  import * as chokidar from "chokidar";
30877
31309
  init_logger();
30878
31310
 
@@ -31245,9 +31677,9 @@ var ProviderLoader = class _ProviderLoader {
31245
31677
  static siblingStderrLogged = /* @__PURE__ */ new Set();
31246
31678
  static looksLikeProviderRoot(candidate) {
31247
31679
  try {
31248
- if (!fs18.existsSync(candidate) || !fs18.statSync(candidate).isDirectory()) return false;
31680
+ if (!fs19.existsSync(candidate) || !fs19.statSync(candidate).isDirectory()) return false;
31249
31681
  return ["ide", "extension", "cli", "acp"].some(
31250
- (category) => fs18.existsSync(path30.join(candidate, category))
31682
+ (category) => fs19.existsSync(path31.join(candidate, category))
31251
31683
  );
31252
31684
  } catch {
31253
31685
  return false;
@@ -31255,20 +31687,20 @@ var ProviderLoader = class _ProviderLoader {
31255
31687
  }
31256
31688
  static hasProviderRootMarker(candidate) {
31257
31689
  try {
31258
- return fs18.existsSync(path30.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
31690
+ return fs19.existsSync(path31.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
31259
31691
  } catch {
31260
31692
  return false;
31261
31693
  }
31262
31694
  }
31263
31695
  detectDefaultUserDir() {
31264
- const fallback = path30.join(os21.homedir(), ".adhdev", "providers");
31696
+ const fallback = path31.join(os22.homedir(), ".adhdev", "providers");
31265
31697
  const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
31266
31698
  const visited = /* @__PURE__ */ new Set();
31267
31699
  for (const start of this.probeStarts) {
31268
- let current = path30.resolve(start);
31700
+ let current = path31.resolve(start);
31269
31701
  while (!visited.has(current)) {
31270
31702
  visited.add(current);
31271
- const siblingCandidate = path30.join(path30.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
31703
+ const siblingCandidate = path31.join(path31.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
31272
31704
  if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
31273
31705
  const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
31274
31706
  if (envOptIn || hasMarker) {
@@ -31290,7 +31722,7 @@ var ProviderLoader = class _ProviderLoader {
31290
31722
  return { path: siblingCandidate, source };
31291
31723
  }
31292
31724
  }
31293
- const parent = path30.dirname(current);
31725
+ const parent = path31.dirname(current);
31294
31726
  if (parent === current) break;
31295
31727
  current = parent;
31296
31728
  }
@@ -31300,17 +31732,34 @@ var ProviderLoader = class _ProviderLoader {
31300
31732
  constructor(options) {
31301
31733
  this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
31302
31734
  this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
31303
- this.defaultProvidersDir = path30.join(os21.homedir(), ".adhdev", "providers");
31735
+ this.defaultProvidersDir = path31.join(os22.homedir(), ".adhdev", "providers");
31304
31736
  const detected = this.detectDefaultUserDir();
31305
31737
  this.userDir = detected.path;
31306
31738
  this.userDirSource = detected.source;
31307
- this.upstreamDir = path30.join(this.defaultProvidersDir, ".upstream");
31739
+ this.upstreamDir = path31.join(this.defaultProvidersDir, ".upstream");
31308
31740
  this.disableUpstream = false;
31309
31741
  this.applySourceConfig({
31310
31742
  userDir: options?.userDir,
31311
31743
  sourceMode: options?.sourceMode,
31312
31744
  disableUpstream: options?.disableUpstream
31313
31745
  });
31746
+ this.migrateMarketplaceDirToExternal();
31747
+ }
31748
+ migrateMarketplaceDirToExternal() {
31749
+ try {
31750
+ const home = os22.homedir();
31751
+ const oldDir = path31.join(home, ".adhdev", "marketplace");
31752
+ const newDir = path31.join(home, ".adhdev", "external");
31753
+ if (!fs19.existsSync(oldDir)) return;
31754
+ if (fs19.existsSync(newDir)) {
31755
+ this.log(`Migration skipped: both ~/.adhdev/marketplace and ~/.adhdev/external exist (marketplace dir is now inert and can be removed manually).`);
31756
+ return;
31757
+ }
31758
+ fs19.renameSync(oldDir, newDir);
31759
+ this.log(`Migrated ~/.adhdev/marketplace \u2192 ~/.adhdev/external (one-time rename after provider source-layer cleanup).`);
31760
+ } catch (e) {
31761
+ this.log(`Marketplace\u2192external migration failed: ${e?.message || e}`);
31762
+ }
31314
31763
  }
31315
31764
  log(msg) {
31316
31765
  this.logFn(`[ProviderLoader] ${msg}`);
@@ -31336,8 +31785,8 @@ var ProviderLoader = class _ProviderLoader {
31336
31785
  * Highest-priority editable overrides come first.
31337
31786
  */
31338
31787
  getProviderRoots() {
31339
- const marketplaceDir = path30.join(os21.homedir(), ".adhdev", "marketplace");
31340
- return [this.userDir, marketplaceDir, this.upstreamDir];
31788
+ const externalDir = path31.join(os22.homedir(), ".adhdev", "external");
31789
+ return [this.userDir, externalDir, this.upstreamDir];
31341
31790
  }
31342
31791
  getSourceConfig() {
31343
31792
  return {
@@ -31364,7 +31813,7 @@ var ProviderLoader = class _ProviderLoader {
31364
31813
  this.userDir = detected.path;
31365
31814
  this.userDirSource = detected.source;
31366
31815
  }
31367
- this.upstreamDir = path30.join(this.defaultProvidersDir, ".upstream");
31816
+ this.upstreamDir = path31.join(this.defaultProvidersDir, ".upstream");
31368
31817
  this.disableUpstream = this.sourceMode === "no-upstream";
31369
31818
  if (this.explicitProviderDir) {
31370
31819
  this.log(`Config 'providerDir' applied: ${this.userDir}`);
@@ -31378,7 +31827,7 @@ var ProviderLoader = class _ProviderLoader {
31378
31827
  * Canonical provider directory shape for a given root.
31379
31828
  */
31380
31829
  getProviderDir(root, category, type) {
31381
- return path30.join(root, category, type);
31830
+ return path31.join(root, category, type);
31382
31831
  }
31383
31832
  /**
31384
31833
  * Canonical user override directory for a provider.
@@ -31405,20 +31854,23 @@ var ProviderLoader = class _ProviderLoader {
31405
31854
  resolveProviderFile(type, ...segments) {
31406
31855
  const dir = this.findProviderDirInternal(type);
31407
31856
  if (!dir) return null;
31408
- return path30.join(dir, ...segments);
31857
+ return path31.join(dir, ...segments);
31409
31858
  }
31410
31859
  /**
31411
31860
  * Load all providers (3-tier priority)
31412
- * 1. .upstream/ (GitHub auto-download — primary source)
31413
- * 2. User custom (~/.adhdev/providers/ excluding .upstream)
31414
- * User custom always wins (highest priority).
31861
+ * 1. ~/.adhdev/providers/.upstream/ official git, auto-synced
31862
+ * 2. ~/.adhdev/external/ 3rd-party git sources, user-added,
31863
+ * bundled providers may include arbitrary JS (untrusted by default)
31864
+ * 3. ~/.adhdev/providers/ (excluding .upstream) — user-authored customs,
31865
+ * always wins
31866
+ * Highest priority listed last (overwrites earlier loads).
31415
31867
  * If .upstream/ is empty, call fetchLatest() before loadAll().
31416
31868
  */
31417
31869
  loadAll() {
31418
31870
  this.providers.clear();
31419
31871
  this.providerAvailability.clear();
31420
31872
  let upstreamCount = 0;
31421
- if (!this.disableUpstream && fs18.existsSync(this.upstreamDir)) {
31873
+ if (!this.disableUpstream && fs19.existsSync(this.upstreamDir)) {
31422
31874
  upstreamCount = this.loadDir(this.upstreamDir);
31423
31875
  if (upstreamCount > 0) {
31424
31876
  this.log(`Loaded ${upstreamCount} upstream providers (auto-updated)`);
@@ -31426,14 +31878,64 @@ var ProviderLoader = class _ProviderLoader {
31426
31878
  } else if (this.disableUpstream) {
31427
31879
  this.log("Upstream loading disabled (sourceMode=no-upstream)");
31428
31880
  }
31429
- const marketplaceDir = path30.join(os21.homedir(), ".adhdev", "marketplace");
31430
- if (fs18.existsSync(marketplaceDir)) {
31431
- const marketplaceCount = this.loadDir(marketplaceDir);
31432
- if (marketplaceCount > 0) {
31433
- this.log(`Loaded ${marketplaceCount} marketplace-installed providers`);
31881
+ const externalDir = path31.join(os22.homedir(), ".adhdev", "external");
31882
+ if (fs19.existsSync(externalDir)) {
31883
+ const rootEntries = (() => {
31884
+ try {
31885
+ return fs19.readdirSync(externalDir, { withFileTypes: true });
31886
+ } catch {
31887
+ return [];
31888
+ }
31889
+ })();
31890
+ const KNOWN_CATEGORIES = /* @__PURE__ */ new Set(["cli", "ide", "extension", "acp"]);
31891
+ const looksLegacy = rootEntries.some((e) => e.isDirectory() && KNOWN_CATEGORIES.has(e.name));
31892
+ if (looksLegacy) {
31893
+ const externalCount = this.loadDir(externalDir);
31894
+ if (externalCount > 0) {
31895
+ this.log(`Loaded ${externalCount} external providers (legacy unnamed source)`);
31896
+ }
31897
+ } else {
31898
+ const {
31899
+ loadProvidersActive: loadProvidersActive2,
31900
+ resolveActiveSource: resolveActiveSource2
31901
+ } = (init_external_sources(), __toCommonJS(external_sources_exports));
31902
+ const activeFile = loadProvidersActive2();
31903
+ let totalLoaded = 0;
31904
+ const ambiguousTypes = [];
31905
+ for (const sourceEntry of rootEntries) {
31906
+ if (!sourceEntry.isDirectory()) continue;
31907
+ const sourceDir = path31.join(externalDir, sourceEntry.name);
31908
+ const sourceLoaded = this.loadDir(sourceDir);
31909
+ if (sourceLoaded > 0) {
31910
+ totalLoaded += sourceLoaded;
31911
+ this.log(`Loaded ${sourceLoaded} providers from external source "${sourceEntry.name}"`);
31912
+ }
31913
+ }
31914
+ for (const [type] of this.providers) {
31915
+ const prov = this.providers.get(type);
31916
+ if (!prov) continue;
31917
+ const resolved = resolveActiveSource2(prov.category, type, activeFile);
31918
+ if (resolved.candidates.length <= 1) continue;
31919
+ if (resolved.ambiguous) {
31920
+ ambiguousTypes.push({ type, chosen: resolved.source ?? "?", candidates: resolved.candidates });
31921
+ }
31922
+ if (resolved.source && resolved.source !== "?") {
31923
+ const sourceDir = path31.join(externalDir, resolved.source);
31924
+ const reloadCount = this.loadDir(sourceDir);
31925
+ if (reloadCount === 0) {
31926
+ this.log(`Active source "${resolved.source}" no longer provides ${type}`);
31927
+ }
31928
+ }
31929
+ }
31930
+ if (totalLoaded > 0) {
31931
+ this.log(`Loaded ${totalLoaded} external providers (3rd-party sources)`);
31932
+ }
31933
+ for (const a of ambiguousTypes) {
31934
+ this.log(`Ambiguous provider "${a.type}" \u2014 provided by [${a.candidates.join(", ")}], defaulted to "${a.chosen}". Set the active source from the dashboard to silence this warning.`);
31935
+ }
31434
31936
  }
31435
31937
  }
31436
- if (fs18.existsSync(this.userDir)) {
31938
+ if (fs19.existsSync(this.userDir)) {
31437
31939
  const userCount = this.loadDir(this.userDir, [".upstream"]);
31438
31940
  if (userCount > 0) {
31439
31941
  this.log(`Loaded ${userCount} user custom providers (never auto-updated)`);
@@ -31448,10 +31950,10 @@ var ProviderLoader = class _ProviderLoader {
31448
31950
  * Check if upstream directory exists and has providers.
31449
31951
  */
31450
31952
  hasUpstream() {
31451
- if (!fs18.existsSync(this.upstreamDir)) return false;
31953
+ if (!fs19.existsSync(this.upstreamDir)) return false;
31452
31954
  try {
31453
- return fs18.readdirSync(this.upstreamDir).some(
31454
- (d) => fs18.statSync(path30.join(this.upstreamDir, d)).isDirectory()
31955
+ return fs19.readdirSync(this.upstreamDir).some(
31956
+ (d) => fs19.statSync(path31.join(this.upstreamDir, d)).isDirectory()
31455
31957
  );
31456
31958
  } catch {
31457
31959
  return false;
@@ -31949,8 +32451,8 @@ var ProviderLoader = class _ProviderLoader {
31949
32451
  resolved._resolvedScriptDir = entry.scriptDir;
31950
32452
  resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
31951
32453
  if (providerDir) {
31952
- const fullDir = path30.join(providerDir, entry.scriptDir);
31953
- resolved._resolvedScriptsPath = fs18.existsSync(path30.join(fullDir, "scripts.js")) ? path30.join(fullDir, "scripts.js") : fullDir;
32454
+ const fullDir = path31.join(providerDir, entry.scriptDir);
32455
+ resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
31954
32456
  }
31955
32457
  matched = true;
31956
32458
  }
@@ -31968,8 +32470,8 @@ var ProviderLoader = class _ProviderLoader {
31968
32470
  resolved._resolvedScriptDir = base.defaultScriptDir;
31969
32471
  resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
31970
32472
  if (providerDir) {
31971
- const fullDir = path30.join(providerDir, base.defaultScriptDir);
31972
- resolved._resolvedScriptsPath = fs18.existsSync(path30.join(fullDir, "scripts.js")) ? path30.join(fullDir, "scripts.js") : fullDir;
32473
+ const fullDir = path31.join(providerDir, base.defaultScriptDir);
32474
+ resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
31973
32475
  }
31974
32476
  }
31975
32477
  resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
@@ -31986,8 +32488,8 @@ var ProviderLoader = class _ProviderLoader {
31986
32488
  resolved._resolvedScriptDir = dirOverride;
31987
32489
  resolved._resolvedScriptsSource = `versions:${range}`;
31988
32490
  if (providerDir) {
31989
- const fullDir = path30.join(providerDir, dirOverride);
31990
- resolved._resolvedScriptsPath = fs18.existsSync(path30.join(fullDir, "scripts.js")) ? path30.join(fullDir, "scripts.js") : fullDir;
32491
+ const fullDir = path31.join(providerDir, dirOverride);
32492
+ resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
31991
32493
  }
31992
32494
  }
31993
32495
  } else if (override.scripts) {
@@ -32003,8 +32505,8 @@ var ProviderLoader = class _ProviderLoader {
32003
32505
  resolved._resolvedScriptDir = base.defaultScriptDir;
32004
32506
  resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
32005
32507
  if (providerDir) {
32006
- const fullDir = path30.join(providerDir, base.defaultScriptDir);
32007
- resolved._resolvedScriptsPath = fs18.existsSync(path30.join(fullDir, "scripts.js")) ? path30.join(fullDir, "scripts.js") : fullDir;
32508
+ const fullDir = path31.join(providerDir, base.defaultScriptDir);
32509
+ resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
32008
32510
  }
32009
32511
  }
32010
32512
  }
@@ -32021,13 +32523,13 @@ var ProviderLoader = class _ProviderLoader {
32021
32523
  if (providerDir2) {
32022
32524
  for (const [scriptName, override] of Object.entries(base.overrides)) {
32023
32525
  if (!override || typeof override.path !== "string") continue;
32024
- const fullPath = path30.join(providerDir2, override.path);
32025
- if (!fs18.existsSync(fullPath)) {
32526
+ const fullPath = path31.join(providerDir2, override.path);
32527
+ if (!fs19.existsSync(fullPath)) {
32026
32528
  this.log(` [overrides] ${base.type}: ${scriptName} path not found: ${fullPath}`);
32027
32529
  continue;
32028
32530
  }
32029
32531
  try {
32030
- registerProviderScriptRootSafely(path30.dirname(path30.dirname(providerDir2)));
32532
+ registerProviderScriptRootSafely(path31.dirname(path31.dirname(providerDir2)));
32031
32533
  delete __require.cache[__require.resolve(fullPath)];
32032
32534
  const fn = __require(fullPath);
32033
32535
  const target = typeof fn === "function" ? fn : fn && fn[scriptName];
@@ -32052,19 +32554,19 @@ var ProviderLoader = class _ProviderLoader {
32052
32554
  }
32053
32555
  if (providerDir) {
32054
32556
  try {
32055
- const fs27 = __require("fs");
32056
- const path39 = __require("path");
32557
+ const fs28 = __require("fs");
32558
+ const path40 = __require("path");
32057
32559
  const candidates = [];
32058
32560
  if (Array.isArray(base.compatibility)) {
32059
32561
  for (const entry of base.compatibility) {
32060
32562
  if (typeof entry?.spec !== "string") continue;
32061
32563
  const matches = !entry.ideVersion || currentVersion && this.matchesVersion(currentVersion, entry.ideVersion) || !currentVersion;
32062
- if (matches) candidates.push(path39.join(providerDir, entry.spec));
32564
+ if (matches) candidates.push(path40.join(providerDir, entry.spec));
32063
32565
  }
32064
32566
  }
32065
- candidates.push(path39.join(providerDir, "specs", "default.json"));
32066
- candidates.push(path39.join(providerDir, "spec.json"));
32067
- const specPath = candidates.find((p) => fs27.existsSync(p));
32567
+ candidates.push(path40.join(providerDir, "specs", "default.json"));
32568
+ candidates.push(path40.join(providerDir, "spec.json"));
32569
+ const specPath = candidates.find((p) => fs28.existsSync(p));
32068
32570
  if (specPath) {
32069
32571
  resolved._resolvedSpecPath = specPath;
32070
32572
  const { loadSpec: loadSpec2 } = (init_loader(), __toCommonJS(loader_exports));
@@ -32093,10 +32595,10 @@ var ProviderLoader = class _ProviderLoader {
32093
32595
  format = `spec-${nh.source.kind}`;
32094
32596
  reader = (input) => executeNativeHistory2(nh, input);
32095
32597
  } else if (nh.override_path) {
32096
- const overrideFile = path39.resolve(providerDir, nh.override_path);
32097
- if (fs27.existsSync(overrideFile)) {
32598
+ const overrideFile = path40.resolve(providerDir, nh.override_path);
32599
+ if (fs28.existsSync(overrideFile)) {
32098
32600
  try {
32099
- registerProviderScriptRootSafely(path39.dirname(path39.dirname(providerDir)));
32601
+ registerProviderScriptRootSafely(path40.dirname(path40.dirname(providerDir)));
32100
32602
  delete __require.cache[__require.resolve(overrideFile)];
32101
32603
  const mod = __require(overrideFile);
32102
32604
  const fn = typeof mod === "function" ? mod : mod && typeof mod.default === "function" ? mod.default : null;
@@ -32140,16 +32642,16 @@ var ProviderLoader = class _ProviderLoader {
32140
32642
  this.debugLog(`[loadScriptsFromDir] ${type}: providerDir not found`);
32141
32643
  return null;
32142
32644
  }
32143
- const dir = path30.join(providerDir, scriptDir);
32144
- if (!fs18.existsSync(dir)) {
32645
+ const dir = path31.join(providerDir, scriptDir);
32646
+ if (!fs19.existsSync(dir)) {
32145
32647
  this.debugLog(`[loadScriptsFromDir] ${type}: dir not found: ${dir}`);
32146
32648
  return null;
32147
32649
  }
32148
- registerProviderScriptRootSafely(path30.dirname(path30.dirname(providerDir)));
32650
+ registerProviderScriptRootSafely(path31.dirname(path31.dirname(providerDir)));
32149
32651
  const cached = this.scriptsCache.get(dir);
32150
32652
  if (cached) return cached;
32151
- const scriptsJs = path30.join(dir, "scripts.js");
32152
- if (fs18.existsSync(scriptsJs)) {
32653
+ const scriptsJs = path31.join(dir, "scripts.js");
32654
+ if (fs19.existsSync(scriptsJs)) {
32153
32655
  try {
32154
32656
  delete __require.cache[__require.resolve(scriptsJs)];
32155
32657
  const loaded = __require(scriptsJs);
@@ -32170,9 +32672,9 @@ var ProviderLoader = class _ProviderLoader {
32170
32672
  watch() {
32171
32673
  this.stopWatch();
32172
32674
  const watchDir = (dir) => {
32173
- if (!fs18.existsSync(dir)) {
32675
+ if (!fs19.existsSync(dir)) {
32174
32676
  try {
32175
- fs18.mkdirSync(dir, { recursive: true });
32677
+ fs19.mkdirSync(dir, { recursive: true });
32176
32678
  } catch {
32177
32679
  return;
32178
32680
  }
@@ -32193,7 +32695,7 @@ var ProviderLoader = class _ProviderLoader {
32193
32695
  if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
32194
32696
  if (reloadTimer) clearTimeout(reloadTimer);
32195
32697
  reloadTimer = setTimeout(() => {
32196
- this.log(`File changed: ${path30.basename(filePath)}, reloading...`);
32698
+ this.log(`File changed: ${path31.basename(filePath)}, reloading...`);
32197
32699
  this.reload();
32198
32700
  }, 300);
32199
32701
  }
@@ -32261,11 +32763,11 @@ var ProviderLoader = class _ProviderLoader {
32261
32763
  }
32262
32764
  this.log(`Registry sync starting (${_ProviderLoader.REGISTRY_BASE_URL})...`);
32263
32765
  const https = __require("https");
32264
- const regMetaPath = path30.join(this.upstreamDir, _ProviderLoader.REGISTRY_META_FILE);
32766
+ const regMetaPath = path31.join(this.upstreamDir, _ProviderLoader.REGISTRY_META_FILE);
32265
32767
  let cachedChecksums = {};
32266
32768
  try {
32267
- if (fs18.existsSync(regMetaPath)) {
32268
- cachedChecksums = JSON.parse(fs18.readFileSync(regMetaPath, "utf-8")).checksums ?? {};
32769
+ if (fs19.existsSync(regMetaPath)) {
32770
+ cachedChecksums = JSON.parse(fs19.readFileSync(regMetaPath, "utf-8")).checksums ?? {};
32269
32771
  }
32270
32772
  } catch {
32271
32773
  }
@@ -32319,15 +32821,15 @@ var ProviderLoader = class _ProviderLoader {
32319
32821
  this.log(`\u26A0 Registry checksum mismatch for ${type}@${version} \u2014 skipping`);
32320
32822
  continue;
32321
32823
  }
32322
- const providerDir = path30.join(this.upstreamDir, category, type);
32323
- fs18.mkdirSync(providerDir, { recursive: true });
32324
- fs18.writeFileSync(path30.join(providerDir, "provider.json"), manifestBody, "utf-8");
32824
+ const providerDir = path31.join(this.upstreamDir, category, type);
32825
+ fs19.mkdirSync(providerDir, { recursive: true });
32826
+ fs19.writeFileSync(path31.join(providerDir, "provider.json"), manifestBody, "utf-8");
32325
32827
  cachedChecksums[cacheKey] = checksum;
32326
32828
  updatedCount++;
32327
32829
  this.log(`\u2713 Registry updated: ${category}/${type}@${version}`);
32328
32830
  }
32329
- fs18.mkdirSync(this.upstreamDir, { recursive: true });
32330
- fs18.writeFileSync(regMetaPath, JSON.stringify({
32831
+ fs19.mkdirSync(this.upstreamDir, { recursive: true });
32832
+ fs19.writeFileSync(regMetaPath, JSON.stringify({
32331
32833
  checksums: cachedChecksums,
32332
32834
  syncedAt: (/* @__PURE__ */ new Date()).toISOString(),
32333
32835
  providerCount: list.providers.length
@@ -32348,12 +32850,12 @@ var ProviderLoader = class _ProviderLoader {
32348
32850
  const { exec: exec7 } = __require("child_process");
32349
32851
  const { promisify: promisify7 } = __require("util");
32350
32852
  const execAsync5 = promisify7(exec7);
32351
- const metaPath = path30.join(this.upstreamDir, _ProviderLoader.META_FILE);
32853
+ const metaPath = path31.join(this.upstreamDir, _ProviderLoader.META_FILE);
32352
32854
  let prevEtag = "";
32353
32855
  let prevTimestamp = 0;
32354
32856
  try {
32355
- if (fs18.existsSync(metaPath)) {
32356
- const meta = JSON.parse(fs18.readFileSync(metaPath, "utf-8"));
32857
+ if (fs19.existsSync(metaPath)) {
32858
+ const meta = JSON.parse(fs19.readFileSync(metaPath, "utf-8"));
32357
32859
  prevEtag = meta.etag || "";
32358
32860
  prevTimestamp = meta.timestamp || 0;
32359
32861
  }
@@ -32408,39 +32910,39 @@ var ProviderLoader = class _ProviderLoader {
32408
32910
  return { updated: false };
32409
32911
  }
32410
32912
  this.log("Downloading latest providers from GitHub...");
32411
- const tmpTar = path30.join(os21.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
32412
- const tmpExtract = path30.join(os21.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
32913
+ const tmpTar = path31.join(os22.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
32914
+ const tmpExtract = path31.join(os22.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
32413
32915
  await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
32414
- fs18.mkdirSync(tmpExtract, { recursive: true });
32916
+ fs19.mkdirSync(tmpExtract, { recursive: true });
32415
32917
  await execAsync5(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
32416
- const extracted = fs18.readdirSync(tmpExtract);
32918
+ const extracted = fs19.readdirSync(tmpExtract);
32417
32919
  const rootDir = extracted.find(
32418
- (d) => fs18.statSync(path30.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
32920
+ (d) => fs19.statSync(path31.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
32419
32921
  );
32420
32922
  if (!rootDir) throw new Error("Unexpected tarball structure");
32421
- const sourceDir = path30.join(tmpExtract, rootDir);
32923
+ const sourceDir = path31.join(tmpExtract, rootDir);
32422
32924
  const backupDir = this.upstreamDir + ".bak";
32423
- if (fs18.existsSync(this.upstreamDir)) {
32424
- if (fs18.existsSync(backupDir)) fs18.rmSync(backupDir, { recursive: true, force: true });
32425
- fs18.renameSync(this.upstreamDir, backupDir);
32925
+ if (fs19.existsSync(this.upstreamDir)) {
32926
+ if (fs19.existsSync(backupDir)) fs19.rmSync(backupDir, { recursive: true, force: true });
32927
+ fs19.renameSync(this.upstreamDir, backupDir);
32426
32928
  }
32427
32929
  try {
32428
32930
  this.copyDirRecursive(sourceDir, this.upstreamDir);
32429
32931
  this.writeMeta(metaPath, etag || `ts-${Date.now()}`, Date.now());
32430
- if (fs18.existsSync(backupDir)) fs18.rmSync(backupDir, { recursive: true, force: true });
32932
+ if (fs19.existsSync(backupDir)) fs19.rmSync(backupDir, { recursive: true, force: true });
32431
32933
  } catch (e) {
32432
- if (fs18.existsSync(backupDir)) {
32433
- if (fs18.existsSync(this.upstreamDir)) fs18.rmSync(this.upstreamDir, { recursive: true, force: true });
32434
- fs18.renameSync(backupDir, this.upstreamDir);
32934
+ if (fs19.existsSync(backupDir)) {
32935
+ if (fs19.existsSync(this.upstreamDir)) fs19.rmSync(this.upstreamDir, { recursive: true, force: true });
32936
+ fs19.renameSync(backupDir, this.upstreamDir);
32435
32937
  }
32436
32938
  throw e;
32437
32939
  }
32438
32940
  try {
32439
- fs18.rmSync(tmpTar, { force: true });
32941
+ fs19.rmSync(tmpTar, { force: true });
32440
32942
  } catch {
32441
32943
  }
32442
32944
  try {
32443
- fs18.rmSync(tmpExtract, { recursive: true, force: true });
32945
+ fs19.rmSync(tmpExtract, { recursive: true, force: true });
32444
32946
  } catch {
32445
32947
  }
32446
32948
  const upstreamCount = this.countProviders(this.upstreamDir);
@@ -32472,7 +32974,7 @@ var ProviderLoader = class _ProviderLoader {
32472
32974
  reject(new Error(`HTTP ${res.statusCode}`));
32473
32975
  return;
32474
32976
  }
32475
- const ws = fs18.createWriteStream(destPath);
32977
+ const ws = fs19.createWriteStream(destPath);
32476
32978
  res.pipe(ws);
32477
32979
  ws.on("finish", () => {
32478
32980
  ws.close();
@@ -32491,22 +32993,22 @@ var ProviderLoader = class _ProviderLoader {
32491
32993
  }
32492
32994
  /** Recursive directory copy */
32493
32995
  copyDirRecursive(src, dest) {
32494
- fs18.mkdirSync(dest, { recursive: true });
32495
- for (const entry of fs18.readdirSync(src, { withFileTypes: true })) {
32496
- const srcPath = path30.join(src, entry.name);
32497
- const destPath = path30.join(dest, entry.name);
32996
+ fs19.mkdirSync(dest, { recursive: true });
32997
+ for (const entry of fs19.readdirSync(src, { withFileTypes: true })) {
32998
+ const srcPath = path31.join(src, entry.name);
32999
+ const destPath = path31.join(dest, entry.name);
32498
33000
  if (entry.isDirectory()) {
32499
33001
  this.copyDirRecursive(srcPath, destPath);
32500
33002
  } else {
32501
- fs18.copyFileSync(srcPath, destPath);
33003
+ fs19.copyFileSync(srcPath, destPath);
32502
33004
  }
32503
33005
  }
32504
33006
  }
32505
33007
  /** .meta.json save */
32506
33008
  writeMeta(metaPath, etag, timestamp) {
32507
33009
  try {
32508
- fs18.mkdirSync(path30.dirname(metaPath), { recursive: true });
32509
- fs18.writeFileSync(metaPath, JSON.stringify({
33010
+ fs19.mkdirSync(path31.dirname(metaPath), { recursive: true });
33011
+ fs19.writeFileSync(metaPath, JSON.stringify({
32510
33012
  etag,
32511
33013
  timestamp,
32512
33014
  lastCheck: new Date(timestamp).toISOString(),
@@ -32517,15 +33019,15 @@ var ProviderLoader = class _ProviderLoader {
32517
33019
  }
32518
33020
  /** Count provider files (provider.v1.json or provider.json — at most one per dir). */
32519
33021
  countProviders(dir) {
32520
- if (!fs18.existsSync(dir)) return 0;
33022
+ if (!fs19.existsSync(dir)) return 0;
32521
33023
  let count = 0;
32522
33024
  const scan = (d) => {
32523
33025
  try {
32524
- const entries = fs18.readdirSync(d, { withFileTypes: true });
33026
+ const entries = fs19.readdirSync(d, { withFileTypes: true });
32525
33027
  const hasManifest = entries.some((e) => e.name === "provider.v1.json" || e.name === "provider.json");
32526
33028
  if (hasManifest) count++;
32527
33029
  for (const entry of entries) {
32528
- if (entry.isDirectory()) scan(path30.join(d, entry.name));
33030
+ if (entry.isDirectory()) scan(path31.join(d, entry.name));
32529
33031
  }
32530
33032
  } catch {
32531
33033
  }
@@ -32751,13 +33253,13 @@ var ProviderLoader = class _ProviderLoader {
32751
33253
  if (!provider) return null;
32752
33254
  const cat = provider.category;
32753
33255
  const searchRoots = this.getProviderRoots();
32754
- const hasManifest = (dir) => fs18.existsSync(path30.join(dir, "provider.v1.json")) || fs18.existsSync(path30.join(dir, "provider.json"));
33256
+ const hasManifest = (dir) => fs19.existsSync(path31.join(dir, "provider.v1.json")) || fs19.existsSync(path31.join(dir, "provider.json"));
32755
33257
  const readManifestType = (dir) => {
32756
33258
  for (const file of ["provider.v1.json", "provider.json"]) {
32757
- const p = path30.join(dir, file);
32758
- if (!fs18.existsSync(p)) continue;
33259
+ const p = path31.join(dir, file);
33260
+ if (!fs19.existsSync(p)) continue;
32759
33261
  try {
32760
- const data = JSON.parse(fs18.readFileSync(p, "utf-8"));
33262
+ const data = JSON.parse(fs19.readFileSync(p, "utf-8"));
32761
33263
  if (typeof data?.type === "string") return data.type;
32762
33264
  } catch {
32763
33265
  }
@@ -32765,15 +33267,15 @@ var ProviderLoader = class _ProviderLoader {
32765
33267
  return null;
32766
33268
  };
32767
33269
  for (const root of searchRoots) {
32768
- if (!fs18.existsSync(root)) continue;
33270
+ if (!fs19.existsSync(root)) continue;
32769
33271
  const candidate = this.getProviderDir(root, cat, type);
32770
33272
  if (hasManifest(candidate)) return candidate;
32771
- const catDir = path30.join(root, cat);
32772
- if (fs18.existsSync(catDir)) {
33273
+ const catDir = path31.join(root, cat);
33274
+ if (fs19.existsSync(catDir)) {
32773
33275
  try {
32774
- for (const entry of fs18.readdirSync(catDir, { withFileTypes: true })) {
33276
+ for (const entry of fs19.readdirSync(catDir, { withFileTypes: true })) {
32775
33277
  if (!entry.isDirectory()) continue;
32776
- const entryDir = path30.join(catDir, entry.name);
33278
+ const entryDir = path31.join(catDir, entry.name);
32777
33279
  const manifestType = readManifestType(entryDir);
32778
33280
  if (manifestType === type) return entryDir;
32779
33281
  }
@@ -32789,8 +33291,8 @@ var ProviderLoader = class _ProviderLoader {
32789
33291
  * (template substitution is NOT applied here — scripts.js handles that)
32790
33292
  */
32791
33293
  buildScriptWrappersFromDir(dir) {
32792
- const scriptsJs = path30.join(dir, "scripts.js");
32793
- if (fs18.existsSync(scriptsJs)) {
33294
+ const scriptsJs = path31.join(dir, "scripts.js");
33295
+ if (fs19.existsSync(scriptsJs)) {
32794
33296
  try {
32795
33297
  delete __require.cache[__require.resolve(scriptsJs)];
32796
33298
  return __require(scriptsJs);
@@ -32800,13 +33302,13 @@ var ProviderLoader = class _ProviderLoader {
32800
33302
  const toCamel = (name) => name.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
32801
33303
  const result = {};
32802
33304
  try {
32803
- for (const file of fs18.readdirSync(dir)) {
33305
+ for (const file of fs19.readdirSync(dir)) {
32804
33306
  if (!file.endsWith(".js")) continue;
32805
33307
  const scriptName = toCamel(file.replace(".js", ""));
32806
- const filePath = path30.join(dir, file);
33308
+ const filePath = path31.join(dir, file);
32807
33309
  result[scriptName] = (...args) => {
32808
33310
  try {
32809
- let content = fs18.readFileSync(filePath, "utf-8");
33311
+ let content = fs19.readFileSync(filePath, "utf-8");
32810
33312
  if (args[0] && typeof args[0] === "object") {
32811
33313
  for (const [key, val] of Object.entries(args[0])) {
32812
33314
  let v = val;
@@ -32852,12 +33354,12 @@ var ProviderLoader = class _ProviderLoader {
32852
33354
  * Structure: dir/category/agent-name/provider.{json,js}
32853
33355
  */
32854
33356
  loadDir(dir, excludeDirs) {
32855
- if (!fs18.existsSync(dir)) return 0;
33357
+ if (!fs19.existsSync(dir)) return 0;
32856
33358
  let count = 0;
32857
33359
  const scan = (d) => {
32858
33360
  let entries;
32859
33361
  try {
32860
- entries = fs18.readdirSync(d, { withFileTypes: true });
33362
+ entries = fs19.readdirSync(d, { withFileTypes: true });
32861
33363
  } catch {
32862
33364
  return;
32863
33365
  }
@@ -32865,9 +33367,9 @@ var ProviderLoader = class _ProviderLoader {
32865
33367
  const hasJson = entries.some((e) => e.name === "provider.json");
32866
33368
  if (hasV1 || hasJson) {
32867
33369
  const manifestFile = hasV1 ? "provider.v1.json" : "provider.json";
32868
- const jsonPath = path30.join(d, manifestFile);
33370
+ const jsonPath = path31.join(d, manifestFile);
32869
33371
  try {
32870
- const raw = fs18.readFileSync(jsonPath, "utf-8");
33372
+ const raw = fs19.readFileSync(jsonPath, "utf-8");
32871
33373
  const mod = JSON.parse(raw);
32872
33374
  if (hasV1 && mod?.category === "cli") {
32873
33375
  try {
@@ -32905,10 +33407,10 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
32905
33407
  this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
32906
33408
  } else {
32907
33409
  const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
32908
- const scriptsPath = path30.join(d, "scripts.js");
32909
- if (!hasCompatibility && fs18.existsSync(scriptsPath)) {
33410
+ const scriptsPath = path31.join(d, "scripts.js");
33411
+ if (!hasCompatibility && fs19.existsSync(scriptsPath)) {
32910
33412
  try {
32911
- registerProviderScriptRootSafely(path30.dirname(path30.dirname(d)));
33413
+ registerProviderScriptRootSafely(path31.dirname(path31.dirname(d)));
32912
33414
  delete __require.cache[__require.resolve(scriptsPath)];
32913
33415
  const scripts = __require(scriptsPath);
32914
33416
  normalizedProvider.scripts = scripts;
@@ -32916,12 +33418,30 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
32916
33418
  this.log(`\u26A0 Failed to load scripts: ${scriptsPath}: ${e.message}`);
32917
33419
  }
32918
33420
  }
33421
+ const externalDirAbs = path31.join(os22.homedir(), ".adhdev", "external");
33422
+ const layer = d.startsWith(externalDirAbs) ? "external" : d.startsWith(this.userDir) && !d.includes(".upstream") ? "user" : "upstream";
33423
+ try {
33424
+ const { inspectManifestShape: inspectManifestShape2, classifyTrust: classifyTrust2 } = (init_provider_trust(), __toCommonJS(provider_trust_exports));
33425
+ const shape = inspectManifestShape2(mod);
33426
+ const trust = classifyTrust2(layer, shape);
33427
+ normalizedProvider._sourceLayer = layer;
33428
+ normalizedProvider._sourceTrust = trust;
33429
+ normalizedProvider._manifestShape = shape;
33430
+ if (layer === "external") {
33431
+ const rel = path31.relative(externalDirAbs, d);
33432
+ const firstSeg = rel.split(path31.sep)[0];
33433
+ if (firstSeg && firstSeg !== "..") normalizedProvider._sourceName = firstSeg;
33434
+ }
33435
+ } catch {
33436
+ }
32919
33437
  const existed = this.providers.has(normalizedProvider.type);
32920
33438
  this.providers.set(normalizedProvider.type, normalizedProvider);
32921
33439
  count++;
32922
- const source = d.startsWith(this.userDir) && !d.includes(".upstream") ? "user" : "upstream";
33440
+ const source = normalizedProvider._sourceLayer ?? "upstream";
32923
33441
  const overrideWarning = existed && source === "user" ? " \u26A0 OVERRIDES upstream" : "";
32924
- this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${normalizedProvider.type} (${normalizedProvider.category}) \u2014 ${normalizedProvider.name} [${source}]${overrideWarning}`);
33442
+ const sourceName = normalizedProvider._sourceName;
33443
+ const sourceLabel = sourceName ? `${source}/${sourceName}` : source;
33444
+ this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${normalizedProvider.type} (${normalizedProvider.category}) \u2014 ${normalizedProvider.name} [${sourceLabel}]${overrideWarning}`);
32925
33445
  }
32926
33446
  } catch (e) {
32927
33447
  this.log(`\u26A0 Failed to load ${jsonPath}: ${e.message}`);
@@ -32931,8 +33451,9 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
32931
33451
  for (const entry of entries) {
32932
33452
  if (!entry.isDirectory()) continue;
32933
33453
  if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
33454
+ if (d === dir && entry.name === "examples") continue;
32934
33455
  if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
32935
- scan(path30.join(d, entry.name));
33456
+ scan(path31.join(d, entry.name));
32936
33457
  }
32937
33458
  }
32938
33459
  };
@@ -33130,7 +33651,7 @@ async function isCdpActive(port) {
33130
33651
  });
33131
33652
  }
33132
33653
  async function killIdeProcess(ideId) {
33133
- const plat = os22.platform();
33654
+ const plat = os23.platform();
33134
33655
  const appName = getMacAppIdentifiers()[ideId];
33135
33656
  const winProcesses = getWinProcessNames()[ideId];
33136
33657
  try {
@@ -33191,7 +33712,7 @@ async function killIdeProcess(ideId) {
33191
33712
  }
33192
33713
  }
33193
33714
  async function isIdeRunning(ideId) {
33194
- const plat = os22.platform();
33715
+ const plat = os23.platform();
33195
33716
  try {
33196
33717
  if (plat === "darwin") {
33197
33718
  const appName = getMacAppIdentifiers()[ideId];
@@ -33246,7 +33767,7 @@ async function isIdeRunning(ideId) {
33246
33767
  }
33247
33768
  }
33248
33769
  async function detectCurrentWorkspace(ideId) {
33249
- const plat = os22.platform();
33770
+ const plat = os23.platform();
33250
33771
  if (plat === "darwin") {
33251
33772
  try {
33252
33773
  const appName = getMacAppIdentifiers()[ideId];
@@ -33261,17 +33782,17 @@ async function detectCurrentWorkspace(ideId) {
33261
33782
  }
33262
33783
  } else if (plat === "win32") {
33263
33784
  try {
33264
- const fs27 = __require("fs");
33785
+ const fs28 = __require("fs");
33265
33786
  const appNameMap = getMacAppIdentifiers();
33266
33787
  const appName = appNameMap[ideId];
33267
33788
  if (appName) {
33268
- const storagePath = path31.join(
33269
- process.env.APPDATA || path31.join(os22.homedir(), "AppData", "Roaming"),
33789
+ const storagePath = path32.join(
33790
+ process.env.APPDATA || path32.join(os23.homedir(), "AppData", "Roaming"),
33270
33791
  appName,
33271
33792
  "storage.json"
33272
33793
  );
33273
- if (fs27.existsSync(storagePath)) {
33274
- const data = JSON.parse(fs27.readFileSync(storagePath, "utf-8"));
33794
+ if (fs28.existsSync(storagePath)) {
33795
+ const data = JSON.parse(fs28.readFileSync(storagePath, "utf-8"));
33275
33796
  const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
33276
33797
  if (workspaces.length > 0) {
33277
33798
  const recent = workspaces[0];
@@ -33288,7 +33809,7 @@ async function detectCurrentWorkspace(ideId) {
33288
33809
  return void 0;
33289
33810
  }
33290
33811
  async function launchWithCdp(options = {}) {
33291
- const platform10 = os22.platform();
33812
+ const platform10 = os23.platform();
33292
33813
  let targetIde;
33293
33814
  const ides = await detectIDEs(getProviderLoader());
33294
33815
  if (options.ideId) {
@@ -33455,14 +33976,14 @@ init_cli_detector();
33455
33976
  init_logger();
33456
33977
 
33457
33978
  // src/logging/command-log.ts
33458
- import * as fs19 from "fs";
33459
- import * as path32 from "path";
33460
- import * as os23 from "os";
33461
- var LOG_DIR2 = process.platform === "win32" ? path32.join(process.env.LOCALAPPDATA || process.env.APPDATA || path32.join(os23.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path32.join(os23.homedir(), "Library", "Logs", "adhdev") : path32.join(os23.homedir(), ".local", "share", "adhdev", "logs");
33979
+ import * as fs20 from "fs";
33980
+ import * as path33 from "path";
33981
+ import * as os24 from "os";
33982
+ var LOG_DIR2 = process.platform === "win32" ? path33.join(process.env.LOCALAPPDATA || process.env.APPDATA || path33.join(os24.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path33.join(os24.homedir(), "Library", "Logs", "adhdev") : path33.join(os24.homedir(), ".local", "share", "adhdev", "logs");
33462
33983
  var MAX_FILE_SIZE = 5 * 1024 * 1024;
33463
33984
  var MAX_DAYS = 7;
33464
33985
  try {
33465
- fs19.mkdirSync(LOG_DIR2, { recursive: true });
33986
+ fs20.mkdirSync(LOG_DIR2, { recursive: true });
33466
33987
  } catch {
33467
33988
  }
33468
33989
  var SENSITIVE_KEYS = /* @__PURE__ */ new Set([
@@ -33496,19 +34017,19 @@ function getDateStr2() {
33496
34017
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
33497
34018
  }
33498
34019
  var currentDate2 = getDateStr2();
33499
- var currentFile = path32.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
34020
+ var currentFile = path33.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
33500
34021
  var writeCount2 = 0;
33501
34022
  function checkRotation() {
33502
34023
  const today = getDateStr2();
33503
34024
  if (today !== currentDate2) {
33504
34025
  currentDate2 = today;
33505
- currentFile = path32.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
34026
+ currentFile = path33.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
33506
34027
  cleanOldFiles();
33507
34028
  }
33508
34029
  }
33509
34030
  function cleanOldFiles() {
33510
34031
  try {
33511
- const files = fs19.readdirSync(LOG_DIR2).filter((f) => f.startsWith("commands-") && f.endsWith(".jsonl"));
34032
+ const files = fs20.readdirSync(LOG_DIR2).filter((f) => f.startsWith("commands-") && f.endsWith(".jsonl"));
33512
34033
  const cutoff = /* @__PURE__ */ new Date();
33513
34034
  cutoff.setDate(cutoff.getDate() - MAX_DAYS);
33514
34035
  const cutoffStr = cutoff.toISOString().slice(0, 10);
@@ -33516,7 +34037,7 @@ function cleanOldFiles() {
33516
34037
  const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
33517
34038
  if (dateMatch && dateMatch[1] < cutoffStr) {
33518
34039
  try {
33519
- fs19.unlinkSync(path32.join(LOG_DIR2, file));
34040
+ fs20.unlinkSync(path33.join(LOG_DIR2, file));
33520
34041
  } catch {
33521
34042
  }
33522
34043
  }
@@ -33526,14 +34047,14 @@ function cleanOldFiles() {
33526
34047
  }
33527
34048
  function checkSize() {
33528
34049
  try {
33529
- const stat2 = fs19.statSync(currentFile);
34050
+ const stat2 = fs20.statSync(currentFile);
33530
34051
  if (stat2.size > MAX_FILE_SIZE) {
33531
34052
  const backup = currentFile.replace(".jsonl", ".1.jsonl");
33532
34053
  try {
33533
- fs19.unlinkSync(backup);
34054
+ fs20.unlinkSync(backup);
33534
34055
  } catch {
33535
34056
  }
33536
- fs19.renameSync(currentFile, backup);
34057
+ fs20.renameSync(currentFile, backup);
33537
34058
  }
33538
34059
  } catch {
33539
34060
  }
@@ -33566,14 +34087,14 @@ function logCommand(entry) {
33566
34087
  ...entry.error ? { err: entry.error } : {},
33567
34088
  ...entry.durationMs !== void 0 ? { ms: entry.durationMs } : {}
33568
34089
  });
33569
- fs19.appendFileSync(currentFile, line + "\n");
34090
+ fs20.appendFileSync(currentFile, line + "\n");
33570
34091
  } catch {
33571
34092
  }
33572
34093
  }
33573
34094
  function getRecentCommands(count = 50) {
33574
34095
  try {
33575
- if (!fs19.existsSync(currentFile)) return [];
33576
- const content = fs19.readFileSync(currentFile, "utf-8");
34096
+ if (!fs20.existsSync(currentFile)) return [];
34097
+ const content = fs20.readFileSync(currentFile, "utf-8");
33577
34098
  const lines = content.trim().split("\n").filter(Boolean);
33578
34099
  return lines.slice(-count).map((line) => {
33579
34100
  try {
@@ -33607,7 +34128,7 @@ init_mesh_host_ownership();
33607
34128
 
33608
34129
  // src/mesh/preview-freshness.ts
33609
34130
  import { execFileSync as execFileSync3 } from "child_process";
33610
- import { existsSync as existsSync29, readFileSync as readFileSync22 } from "fs";
34131
+ import { existsSync as existsSync30, readFileSync as readFileSync23 } from "fs";
33611
34132
  import { resolve as resolve18 } from "path";
33612
34133
  var PREVIEW_DEPLOY_RECORD = ".adhdev/preview-deploy.json";
33613
34134
  function runGit2(repoRoot, args) {
@@ -33623,10 +34144,10 @@ function runGit2(repoRoot, args) {
33623
34144
  }
33624
34145
  }
33625
34146
  function readRecord3(repoRoot) {
33626
- const path39 = resolve18(repoRoot, PREVIEW_DEPLOY_RECORD);
33627
- if (!existsSync29(path39)) return null;
34147
+ const path40 = resolve18(repoRoot, PREVIEW_DEPLOY_RECORD);
34148
+ if (!existsSync30(path40)) return null;
33628
34149
  try {
33629
- const parsed = JSON.parse(readFileSync22(path39, "utf8"));
34150
+ const parsed = JSON.parse(readFileSync23(path40, "utf8"));
33630
34151
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
33631
34152
  } catch {
33632
34153
  return null;
@@ -33689,7 +34210,7 @@ function buildPreviewFreshness(repoRoot) {
33689
34210
 
33690
34211
  // src/status/snapshot.ts
33691
34212
  init_config();
33692
- import * as os24 from "os";
34213
+ import * as os25 from "os";
33693
34214
  init_terminal_screen();
33694
34215
  init_logger();
33695
34216
  var READ_DEBUG_ENABLED = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
@@ -33727,25 +34248,50 @@ function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
33727
34248
  }
33728
34249
  function buildAvailableProviders(providerLoader) {
33729
34250
  const providers = providerLoader.getAvailableProviderInfos?.() || providerLoader.getAll();
33730
- return providers.map((provider) => ({
33731
- type: provider.type,
33732
- name: provider.displayName || provider.type,
33733
- displayName: provider.displayName || provider.type,
33734
- icon: provider.icon || "\u{1F4BB}",
33735
- category: provider.category,
33736
- ...provider.installed !== void 0 ? { installed: provider.installed } : {},
33737
- ...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {},
33738
- ...provider.enabled !== void 0 ? { enabled: provider.enabled } : {},
33739
- ...provider.machineStatus !== void 0 ? { machineStatus: provider.machineStatus } : {},
33740
- ...provider.lastDetection !== void 0 ? { lastDetection: provider.lastDetection } : {},
33741
- ...provider.lastVerification !== void 0 ? { lastVerification: provider.lastVerification } : {},
33742
- ...provider.meshCoordinator !== void 0 ? { meshCoordinator: provider.meshCoordinator } : {}
33743
- }));
34251
+ let describeTrust2 = () => "";
34252
+ let requiresConfirmation2 = () => false;
34253
+ try {
34254
+ const mod = (init_provider_trust(), __toCommonJS(provider_trust_exports));
34255
+ describeTrust2 = mod.describeTrust;
34256
+ requiresConfirmation2 = mod.requiresConfirmation;
34257
+ } catch {
34258
+ }
34259
+ return providers.map((provider) => {
34260
+ const trust = provider._sourceTrust;
34261
+ const sourceLayer = provider._sourceLayer;
34262
+ const sourceName = provider._sourceName;
34263
+ return {
34264
+ type: provider.type,
34265
+ name: provider.displayName || provider.type,
34266
+ displayName: provider.displayName || provider.type,
34267
+ icon: provider.icon || "\u{1F4BB}",
34268
+ category: provider.category,
34269
+ ...provider.installed !== void 0 ? { installed: provider.installed } : {},
34270
+ ...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {},
34271
+ ...provider.enabled !== void 0 ? { enabled: provider.enabled } : {},
34272
+ ...provider.machineStatus !== void 0 ? { machineStatus: provider.machineStatus } : {},
34273
+ ...provider.lastDetection !== void 0 ? { lastDetection: provider.lastDetection } : {},
34274
+ ...provider.lastVerification !== void 0 ? { lastVerification: provider.lastVerification } : {},
34275
+ ...provider.meshCoordinator !== void 0 ? { meshCoordinator: provider.meshCoordinator } : {},
34276
+ ...trust ? {
34277
+ trust,
34278
+ trustDescription: describeTrust2(trust),
34279
+ requiresConfirmation: requiresConfirmation2(trust)
34280
+ } : {},
34281
+ ...sourceLayer ? { sourceLayer } : {},
34282
+ ...sourceName ? { sourceName } : {},
34283
+ ...provider.providerVersion ? { providerVersion: provider.providerVersion } : {},
34284
+ ...provider.binary ? { binary: provider.binary } : {},
34285
+ ...provider.status ? { status: provider.status } : {},
34286
+ ...provider.details ? { details: provider.details } : {},
34287
+ ...provider.links ? { links: provider.links } : {}
34288
+ };
34289
+ });
33744
34290
  }
33745
34291
  function buildMachineInfo(profile = "full") {
33746
34292
  const base = {
33747
- hostname: os24.hostname(),
33748
- platform: os24.platform()
34293
+ hostname: os25.hostname(),
34294
+ platform: os25.platform()
33749
34295
  };
33750
34296
  if (profile === "live") {
33751
34297
  return base;
@@ -33754,23 +34300,23 @@ function buildMachineInfo(profile = "full") {
33754
34300
  const memSnap2 = getHostMemorySnapshot();
33755
34301
  return {
33756
34302
  ...base,
33757
- arch: os24.arch(),
33758
- cpus: os24.cpus().length,
34303
+ arch: os25.arch(),
34304
+ cpus: os25.cpus().length,
33759
34305
  totalMem: memSnap2.totalMem,
33760
- release: os24.release()
34306
+ release: os25.release()
33761
34307
  };
33762
34308
  }
33763
34309
  const memSnap = getHostMemorySnapshot();
33764
34310
  return {
33765
34311
  ...base,
33766
- arch: os24.arch(),
33767
- cpus: os24.cpus().length,
34312
+ arch: os25.arch(),
34313
+ cpus: os25.cpus().length,
33768
34314
  totalMem: memSnap.totalMem,
33769
34315
  freeMem: memSnap.freeMem,
33770
34316
  availableMem: memSnap.availableMem,
33771
- loadavg: os24.loadavg(),
33772
- uptime: os24.uptime(),
33773
- release: os24.release()
34317
+ loadavg: os25.loadavg(),
34318
+ uptime: os25.uptime(),
34319
+ release: os25.release()
33774
34320
  };
33775
34321
  }
33776
34322
  function parseMessageTime(value) {
@@ -34011,42 +34557,42 @@ function buildStatusSnapshot(options) {
34011
34557
  // src/commands/upgrade-helper.ts
34012
34558
  import { execFileSync as execFileSync4 } from "child_process";
34013
34559
  import { spawn as spawn3 } from "child_process";
34014
- import * as fs20 from "fs";
34015
- import * as os25 from "os";
34016
- import * as path33 from "path";
34560
+ import * as fs21 from "fs";
34561
+ import * as os26 from "os";
34562
+ import * as path34 from "path";
34017
34563
  var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
34018
34564
  function getUpgradeLogPath() {
34019
- const home = os25.homedir();
34020
- const dir = path33.join(home, ".adhdev");
34021
- fs20.mkdirSync(dir, { recursive: true });
34022
- return path33.join(dir, "daemon-upgrade.log");
34565
+ const home = os26.homedir();
34566
+ const dir = path34.join(home, ".adhdev");
34567
+ fs21.mkdirSync(dir, { recursive: true });
34568
+ return path34.join(dir, "daemon-upgrade.log");
34023
34569
  }
34024
34570
  function appendUpgradeLog(message) {
34025
34571
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
34026
34572
  `;
34027
34573
  try {
34028
- fs20.appendFileSync(getUpgradeLogPath(), line, "utf8");
34574
+ fs21.appendFileSync(getUpgradeLogPath(), line, "utf8");
34029
34575
  } catch {
34030
34576
  }
34031
34577
  }
34032
34578
  function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
34033
- const binDir = path33.dirname(nodeExecutable);
34579
+ const binDir = path34.dirname(nodeExecutable);
34034
34580
  if (platform10 === "win32") {
34035
- const npmCliPath = path33.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
34036
- if (fs20.existsSync(npmCliPath)) {
34581
+ const npmCliPath = path34.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
34582
+ if (fs21.existsSync(npmCliPath)) {
34037
34583
  return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
34038
34584
  }
34039
34585
  for (const candidate of ["npm.exe", "npm"]) {
34040
- const candidatePath = path33.join(binDir, candidate);
34041
- if (fs20.existsSync(candidatePath)) {
34586
+ const candidatePath = path34.join(binDir, candidate);
34587
+ if (fs21.existsSync(candidatePath)) {
34042
34588
  return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
34043
34589
  }
34044
34590
  }
34045
34591
  return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
34046
34592
  }
34047
34593
  for (const candidate of ["npm"]) {
34048
- const candidatePath = path33.join(binDir, candidate);
34049
- if (fs20.existsSync(candidatePath)) {
34594
+ const candidatePath = path34.join(binDir, candidate);
34595
+ if (fs21.existsSync(candidatePath)) {
34050
34596
  return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
34051
34597
  }
34052
34598
  }
@@ -34056,22 +34602,22 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
34056
34602
  if (!currentCliPath) return null;
34057
34603
  let resolvedPath = currentCliPath;
34058
34604
  try {
34059
- resolvedPath = fs20.realpathSync.native(currentCliPath);
34605
+ resolvedPath = fs21.realpathSync.native(currentCliPath);
34060
34606
  } catch {
34061
34607
  }
34062
34608
  let currentDir = resolvedPath;
34063
34609
  try {
34064
- if (fs20.statSync(resolvedPath).isFile()) {
34065
- currentDir = path33.dirname(resolvedPath);
34610
+ if (fs21.statSync(resolvedPath).isFile()) {
34611
+ currentDir = path34.dirname(resolvedPath);
34066
34612
  }
34067
34613
  } catch {
34068
- currentDir = path33.dirname(resolvedPath);
34614
+ currentDir = path34.dirname(resolvedPath);
34069
34615
  }
34070
34616
  while (true) {
34071
- const packageJsonPath = path33.join(currentDir, "package.json");
34617
+ const packageJsonPath = path34.join(currentDir, "package.json");
34072
34618
  try {
34073
- if (fs20.existsSync(packageJsonPath)) {
34074
- const parsed = JSON.parse(fs20.readFileSync(packageJsonPath, "utf8"));
34619
+ if (fs21.existsSync(packageJsonPath)) {
34620
+ const parsed = JSON.parse(fs21.readFileSync(packageJsonPath, "utf8"));
34075
34621
  if (parsed?.name === packageName) {
34076
34622
  const normalized = currentDir.replace(/\\/g, "/");
34077
34623
  return normalized.includes("/node_modules/") ? currentDir : null;
@@ -34079,7 +34625,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
34079
34625
  }
34080
34626
  } catch {
34081
34627
  }
34082
- const parentDir = path33.dirname(currentDir);
34628
+ const parentDir = path34.dirname(currentDir);
34083
34629
  if (parentDir === currentDir) {
34084
34630
  return null;
34085
34631
  }
@@ -34087,13 +34633,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
34087
34633
  }
34088
34634
  }
34089
34635
  function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
34090
- const nodeModulesDir = packageName.startsWith("@") ? path33.dirname(path33.dirname(packageRoot)) : path33.dirname(packageRoot);
34091
- if (path33.basename(nodeModulesDir) !== "node_modules") {
34636
+ const nodeModulesDir = packageName.startsWith("@") ? path34.dirname(path34.dirname(packageRoot)) : path34.dirname(packageRoot);
34637
+ if (path34.basename(nodeModulesDir) !== "node_modules") {
34092
34638
  return null;
34093
34639
  }
34094
- const maybeLibDir = path33.dirname(nodeModulesDir);
34095
- if (path33.basename(maybeLibDir) === "lib") {
34096
- return path33.dirname(maybeLibDir);
34640
+ const maybeLibDir = path34.dirname(nodeModulesDir);
34641
+ if (path34.basename(maybeLibDir) === "lib") {
34642
+ return path34.dirname(maybeLibDir);
34097
34643
  }
34098
34644
  return maybeLibDir;
34099
34645
  }
@@ -34208,10 +34754,10 @@ async function waitForPidExit(pid, timeoutMs) {
34208
34754
  }
34209
34755
  }
34210
34756
  function stopSessionHostProcesses(appName) {
34211
- const pidFile = path33.join(os25.homedir(), ".adhdev", `${appName}-session-host.pid`);
34757
+ const pidFile = path34.join(os26.homedir(), ".adhdev", `${appName}-session-host.pid`);
34212
34758
  try {
34213
- if (fs20.existsSync(pidFile)) {
34214
- const pid = Number.parseInt(fs20.readFileSync(pidFile, "utf8").trim(), 10);
34759
+ if (fs21.existsSync(pidFile)) {
34760
+ const pid = Number.parseInt(fs21.readFileSync(pidFile, "utf8").trim(), 10);
34215
34761
  if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
34216
34762
  killPid(pid);
34217
34763
  }
@@ -34219,15 +34765,15 @@ function stopSessionHostProcesses(appName) {
34219
34765
  } catch {
34220
34766
  } finally {
34221
34767
  try {
34222
- fs20.unlinkSync(pidFile);
34768
+ fs21.unlinkSync(pidFile);
34223
34769
  } catch {
34224
34770
  }
34225
34771
  }
34226
34772
  }
34227
34773
  function removeDaemonPidFile() {
34228
- const pidFile = path33.join(os25.homedir(), ".adhdev", "daemon.pid");
34774
+ const pidFile = path34.join(os26.homedir(), ".adhdev", "daemon.pid");
34229
34775
  try {
34230
- fs20.unlinkSync(pidFile);
34776
+ fs21.unlinkSync(pidFile);
34231
34777
  } catch {
34232
34778
  }
34233
34779
  }
@@ -34236,7 +34782,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
34236
34782
  const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
34237
34783
  if (!npmRoot) return;
34238
34784
  const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
34239
- const binDir = process.platform === "win32" ? npmPrefix : path33.join(npmPrefix, "bin");
34785
+ const binDir = process.platform === "win32" ? npmPrefix : path34.join(npmPrefix, "bin");
34240
34786
  const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
34241
34787
  const binNames = /* @__PURE__ */ new Set([packageBaseName]);
34242
34788
  if (pkgName === "@adhdev/daemon-standalone") {
@@ -34244,25 +34790,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
34244
34790
  }
34245
34791
  if (pkgName.startsWith("@")) {
34246
34792
  const [scope, name] = pkgName.split("/");
34247
- const scopeDir = path33.join(npmRoot, scope);
34248
- if (!fs20.existsSync(scopeDir)) return;
34249
- for (const entry of fs20.readdirSync(scopeDir)) {
34793
+ const scopeDir = path34.join(npmRoot, scope);
34794
+ if (!fs21.existsSync(scopeDir)) return;
34795
+ for (const entry of fs21.readdirSync(scopeDir)) {
34250
34796
  if (!entry.startsWith(`.${name}-`)) continue;
34251
- fs20.rmSync(path33.join(scopeDir, entry), { recursive: true, force: true });
34252
- appendUpgradeLog(`Removed stale scoped staging dir: ${path33.join(scopeDir, entry)}`);
34797
+ fs21.rmSync(path34.join(scopeDir, entry), { recursive: true, force: true });
34798
+ appendUpgradeLog(`Removed stale scoped staging dir: ${path34.join(scopeDir, entry)}`);
34253
34799
  }
34254
34800
  } else {
34255
- for (const entry of fs20.readdirSync(npmRoot)) {
34801
+ for (const entry of fs21.readdirSync(npmRoot)) {
34256
34802
  if (!entry.startsWith(`.${pkgName}-`)) continue;
34257
- fs20.rmSync(path33.join(npmRoot, entry), { recursive: true, force: true });
34258
- appendUpgradeLog(`Removed stale staging dir: ${path33.join(npmRoot, entry)}`);
34803
+ fs21.rmSync(path34.join(npmRoot, entry), { recursive: true, force: true });
34804
+ appendUpgradeLog(`Removed stale staging dir: ${path34.join(npmRoot, entry)}`);
34259
34805
  }
34260
34806
  }
34261
- if (fs20.existsSync(binDir)) {
34262
- for (const entry of fs20.readdirSync(binDir)) {
34807
+ if (fs21.existsSync(binDir)) {
34808
+ for (const entry of fs21.readdirSync(binDir)) {
34263
34809
  if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
34264
- fs20.rmSync(path33.join(binDir, entry), { recursive: true, force: true });
34265
- appendUpgradeLog(`Removed stale bin staging entry: ${path33.join(binDir, entry)}`);
34810
+ fs21.rmSync(path34.join(binDir, entry), { recursive: true, force: true });
34811
+ appendUpgradeLog(`Removed stale bin staging entry: ${path34.join(binDir, entry)}`);
34266
34812
  }
34267
34813
  }
34268
34814
  }
@@ -34348,9 +34894,9 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
34348
34894
 
34349
34895
  // src/commands/router.ts
34350
34896
  init_mesh_work_queue();
34351
- import { homedir as homedir24, hostname as osHostname } from "os";
34897
+ import { homedir as homedir25, hostname as osHostname } from "os";
34352
34898
  import { basename as pathBasename, join as pathJoin, resolve as pathResolve2 } from "path";
34353
- import * as fs21 from "fs";
34899
+ import * as fs22 from "fs";
34354
34900
  import { execFileSync as execFileSync5 } from "child_process";
34355
34901
  var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
34356
34902
  var CHANNEL_SERVER_URL = {
@@ -34477,12 +35023,12 @@ function readGitSubmodules(value, parentRepoRoot) {
34477
35023
  if (!Array.isArray(value)) return void 0;
34478
35024
  const submodules = value.map((entry) => {
34479
35025
  const submodule = readObjectRecord(entry);
34480
- const path39 = readStringValue(submodule.path);
35026
+ const path40 = readStringValue(submodule.path);
34481
35027
  const commit = readStringValue(submodule.commit);
34482
- const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path39);
34483
- if (!path39 || !commit || !repoPath) return null;
35028
+ const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path40);
35029
+ if (!path40 || !commit || !repoPath) return null;
34484
35030
  return {
34485
- path: path39,
35031
+ path: path40,
34486
35032
  commit,
34487
35033
  repoPath,
34488
35034
  dirty: readBooleanValue(submodule.dirty) ?? false,
@@ -35124,7 +35670,7 @@ async function hydrateInlineMeshDirectTruth(args) {
35124
35670
  if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
35125
35671
  continue;
35126
35672
  }
35127
- if (fs21.existsSync(workspace)) {
35673
+ if (fs22.existsSync(workspace)) {
35128
35674
  try {
35129
35675
  const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
35130
35676
  if (localGit?.isGitRepo) {
@@ -35209,7 +35755,7 @@ function readLiveMeshNodeWorkspace(args) {
35209
35755
  }
35210
35756
  function collectLiveMeshSessionRecords(args) {
35211
35757
  const nodeWorkspace = readStringValue(args.node?.workspace);
35212
- const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs21.existsSync(nodeWorkspace);
35758
+ const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs22.existsSync(nodeWorkspace);
35213
35759
  const matches = args.liveSessionRecords.filter((record) => {
35214
35760
  const recordNodeId = readStringValue(record?.meta?.meshNodeId);
35215
35761
  if (recordNodeId && recordNodeId !== args.nodeId) return false;
@@ -35236,7 +35782,7 @@ function buildHistoricalMeshSessions(args) {
35236
35782
  const workspace = readStringValue(node?.workspace);
35237
35783
  if (nodeId) liveNodeIds.add(nodeId);
35238
35784
  if (workspace) liveWorkspaces.add(workspace);
35239
- if (nodeId && node?.isLocalWorktree === true && workspace && !fs21.existsSync(workspace)) {
35785
+ if (nodeId && node?.isLocalWorktree === true && workspace && !fs22.existsSync(workspace)) {
35240
35786
  missingLocalWorktreeNodeIds.add(nodeId);
35241
35787
  }
35242
35788
  }
@@ -35435,10 +35981,10 @@ ${e?.stderr || ""}`
35435
35981
  }
35436
35982
  function buildPatchEquivalenceSubmoduleConflictHint(repoRoot, baseHead, branchHead, output) {
35437
35983
  if (!/(submodule|160000)/i.test(output) || !/(conflict|failed to merge)/i.test(output)) return void 0;
35438
- const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path39) => ({
35439
- path: path39,
35440
- baseCommit: readTreeObject(repoRoot, baseHead, path39),
35441
- branchCommit: readTreeObject(repoRoot, branchHead, path39)
35984
+ const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path40) => ({
35985
+ path: path40,
35986
+ baseCommit: readTreeObject(repoRoot, baseHead, path40),
35987
+ branchCommit: readTreeObject(repoRoot, branchHead, path40)
35442
35988
  }));
35443
35989
  if (conflicts.length === 0) return void 0;
35444
35990
  return {
@@ -35464,11 +36010,11 @@ function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
35464
36010
  if (!line.trim()) continue;
35465
36011
  const metaAndPath = line.split(" ");
35466
36012
  const meta = metaAndPath[0] || "";
35467
- const path39 = metaAndPath[metaAndPath.length - 1]?.trim();
35468
- if (!path39) continue;
36013
+ const path40 = metaAndPath[metaAndPath.length - 1]?.trim();
36014
+ if (!path40) continue;
35469
36015
  const parts = meta.split(/\s+/);
35470
36016
  if (parts[0]?.includes("160000") || parts[1]?.includes("160000")) {
35471
- paths.add(path39);
36017
+ paths.add(path40);
35472
36018
  }
35473
36019
  }
35474
36020
  return [...paths].sort();
@@ -35476,9 +36022,9 @@ function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
35476
36022
  return [];
35477
36023
  }
35478
36024
  }
35479
- function readTreeObject(repoRoot, ref, path39) {
36025
+ function readTreeObject(repoRoot, ref, path40) {
35480
36026
  try {
35481
- const output = execFileSync5("git", ["ls-tree", ref, "--", path39], {
36027
+ const output = execFileSync5("git", ["ls-tree", ref, "--", path40], {
35482
36028
  cwd: repoRoot,
35483
36029
  encoding: "utf8",
35484
36030
  maxBuffer: 1024 * 1024
@@ -35491,7 +36037,7 @@ function readTreeObject(repoRoot, ref, path39) {
35491
36037
  }
35492
36038
  async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, currentHead, options = {}) {
35493
36039
  const startedAt = Date.now();
35494
- const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((path39) => !(options.submoduleIgnorePaths || []).includes(path39));
36040
+ const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((path40) => !(options.submoduleIgnorePaths || []).includes(path40));
35495
36041
  const preStatus = await getGitRepoStatus(repoRoot, {
35496
36042
  includeSubmodules: true,
35497
36043
  submoduleIgnorePaths: options.submoduleIgnorePaths,
@@ -35532,7 +36078,7 @@ async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, cur
35532
36078
  changedGitlinkPaths,
35533
36079
  outOfSyncPaths,
35534
36080
  updatedPaths: updatePaths,
35535
- verifiedPaths: updatePaths.filter((path39) => !remaining.some((submodule) => submodule.path === path39)),
36081
+ verifiedPaths: updatePaths.filter((path40) => !remaining.some((submodule) => submodule.path === path40)),
35536
36082
  durationMs: Date.now() - startedAt,
35537
36083
  command: `git ${commandArgs.join(" ")}`,
35538
36084
  stdout: truncateValidationOutput(result.stdout),
@@ -35587,7 +36133,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
35587
36133
  return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
35588
36134
  };
35589
36135
  const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
35590
- if (!fs21.existsSync(worktreeSubmodulePath)) return false;
36136
+ if (!fs22.existsSync(worktreeSubmodulePath)) return false;
35591
36137
  try {
35592
36138
  await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
35593
36139
  } catch {
@@ -35610,7 +36156,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
35610
36156
  reachable: false
35611
36157
  };
35612
36158
  try {
35613
- if (!fs21.existsSync(submodulePath)) {
36159
+ if (!fs22.existsSync(submodulePath)) {
35614
36160
  entry.error = `Submodule checkout missing at ${gitlink.path}`;
35615
36161
  entry.publishRequired = true;
35616
36162
  if (options.allowAutoPublishSubmoduleMainCommits === true) {
@@ -35802,9 +36348,9 @@ async function runMeshRefineValidationGate(mesh, workspace) {
35802
36348
  return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
35803
36349
  };
35804
36350
  const dependenciesLikelyMissing = (cwd) => {
35805
- if (!fs21.existsSync(pathJoin(cwd, "package.json"))) return false;
35806
- if (fs21.existsSync(pathJoin(cwd, "node_modules"))) return false;
35807
- return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs21.existsSync(pathJoin(cwd, lock)));
36351
+ if (!fs22.existsSync(pathJoin(cwd, "package.json"))) return false;
36352
+ if (fs22.existsSync(pathJoin(cwd, "node_modules"))) return false;
36353
+ return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs22.existsSync(pathJoin(cwd, lock)));
35808
36354
  };
35809
36355
  for (const candidate of selection.bootstrapCommands) {
35810
36356
  const startedAt = Date.now();
@@ -35896,14 +36442,14 @@ function serializeMeshCoordinatorMcpConfig(config, format) {
35896
36442
  }
35897
36443
  function resolveHermesUserHome() {
35898
36444
  const explicitHome = process.env.HERMES_HOME?.trim();
35899
- return explicitHome || pathJoin(homedir24(), ".hermes");
36445
+ return explicitHome || pathJoin(homedir25(), ".hermes");
35900
36446
  }
35901
36447
  function loadHermesCoordinatorBaseConfig(targetConfigPath) {
35902
36448
  const sourceHome = resolveHermesUserHome();
35903
36449
  const sourceConfigPath = pathJoin(sourceHome, "config.yaml");
35904
- if (!fs21.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
36450
+ if (!fs22.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
35905
36451
  if (pathResolve2(sourceConfigPath) === pathResolve2(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
35906
- const parsed = parseMeshCoordinatorMcpConfig(fs21.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
36452
+ const parsed = parseMeshCoordinatorMcpConfig(fs22.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
35907
36453
  const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
35908
36454
  return { config: baseConfig, sourceHome, sourceConfigPath };
35909
36455
  }
@@ -35940,9 +36486,9 @@ function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
35940
36486
  for (const fileName of [".env", "auth.json"]) {
35941
36487
  const sourcePath = pathJoin(sourceHome, fileName);
35942
36488
  const targetPath = pathJoin(targetHome, fileName);
35943
- if (!fs21.existsSync(sourcePath)) continue;
36489
+ if (!fs22.existsSync(sourcePath)) continue;
35944
36490
  try {
35945
- fs21.copyFileSync(sourcePath, targetPath);
36491
+ fs22.copyFileSync(sourcePath, targetPath);
35946
36492
  } catch (error) {
35947
36493
  LOG.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error?.message || error}`);
35948
36494
  }
@@ -36297,13 +36843,13 @@ var DaemonCommandRouter = class {
36297
36843
  recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
36298
36844
  };
36299
36845
  }
36300
- const worktreeExists = fs21.existsSync(workspace);
36846
+ const worktreeExists = fs22.existsSync(workspace);
36301
36847
  const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => n.id === args.node.clonedFromNodeId || n.nodeId === args.node.clonedFromNodeId) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
36302
36848
  const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
36303
36849
  if (!worktreeExists) {
36304
36850
  return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
36305
36851
  }
36306
- if (!repoRoot || !fs21.existsSync(repoRoot)) {
36852
+ if (!repoRoot || !fs22.existsSync(repoRoot)) {
36307
36853
  return {
36308
36854
  success: false,
36309
36855
  code: "mesh_worktree_cleanup_missing_source_repo",
@@ -36323,7 +36869,7 @@ var DaemonCommandRouter = class {
36323
36869
  const normalizePath = (value) => {
36324
36870
  const resolved = pathResolve2(value);
36325
36871
  try {
36326
- return fs21.realpathSync(resolved);
36872
+ return fs22.realpathSync(resolved);
36327
36873
  } catch {
36328
36874
  return resolved;
36329
36875
  }
@@ -37262,8 +37808,8 @@ var DaemonCommandRouter = class {
37262
37808
  if (sinceTs > 0) {
37263
37809
  return { success: true, logs: [], totalBuffered: 0 };
37264
37810
  }
37265
- if (fs21.existsSync(LOG_PATH)) {
37266
- const content = fs21.readFileSync(LOG_PATH, "utf-8");
37811
+ if (fs22.existsSync(LOG_PATH)) {
37812
+ const content = fs22.readFileSync(LOG_PATH, "utf-8");
37267
37813
  const allLines = content.split("\n");
37268
37814
  const recent = allLines.slice(-count).join("\n");
37269
37815
  return { success: true, logs: recent, totalLines: allLines.length };
@@ -37653,24 +38199,24 @@ var DaemonCommandRouter = class {
37653
38199
  // Settings page in the dashboard reads/writes via these two
37654
38200
  // commands instead of going through fs from the browser.
37655
38201
  case "list_coordinator_prompts": {
37656
- const fs27 = await import("fs");
37657
- const path39 = await import("path");
37658
- const os28 = await import("os");
37659
- const dir = path39.join(os28.homedir(), ".adhdev", "coordinator-prompts");
38202
+ const fs28 = await import("fs");
38203
+ const path40 = await import("path");
38204
+ const os29 = await import("os");
38205
+ const dir = path40.join(os29.homedir(), ".adhdev", "coordinator-prompts");
37660
38206
  const entries = {};
37661
38207
  try {
37662
- if (fs27.existsSync(dir)) {
37663
- for (const name of fs27.readdirSync(dir)) {
38208
+ if (fs28.existsSync(dir)) {
38209
+ for (const name of fs28.readdirSync(dir)) {
37664
38210
  const matchOverride = name.match(/^([a-zA-Z0-9_.-]+)\.md$/);
37665
38211
  const matchAppend = name.match(/^([a-zA-Z0-9_.-]+)\.append\.md$/);
37666
38212
  const m = matchAppend || matchOverride;
37667
38213
  if (!m) continue;
37668
38214
  const isAppend = !!matchAppend;
37669
38215
  const key = m[1];
37670
- const full = path39.join(dir, name);
38216
+ const full = path40.join(dir, name);
37671
38217
  let content = "";
37672
38218
  try {
37673
- content = fs27.readFileSync(full, "utf8");
38219
+ content = fs28.readFileSync(full, "utf8");
37674
38220
  } catch {
37675
38221
  }
37676
38222
  if (!entries[key]) entries[key] = { override: "", append: "" };
@@ -37684,24 +38230,24 @@ var DaemonCommandRouter = class {
37684
38230
  return { success: true, dir, entries };
37685
38231
  }
37686
38232
  case "write_coordinator_prompt": {
37687
- const fs27 = await import("fs");
37688
- const path39 = await import("path");
37689
- const os28 = await import("os");
38233
+ const fs28 = await import("fs");
38234
+ const path40 = await import("path");
38235
+ const os29 = await import("os");
37690
38236
  const key = typeof args?.key === "string" ? args.key.trim() : "";
37691
38237
  const kind = args?.kind === "append" ? "append" : "override";
37692
38238
  const content = typeof args?.content === "string" ? args.content : "";
37693
38239
  if (!key || !/^[a-zA-Z0-9_.-]+$/.test(key)) {
37694
38240
  return { success: false, error: "key must match [a-zA-Z0-9_.-]+" };
37695
38241
  }
37696
- const dir = path39.join(os28.homedir(), ".adhdev", "coordinator-prompts");
38242
+ const dir = path40.join(os29.homedir(), ".adhdev", "coordinator-prompts");
37697
38243
  const filename = kind === "append" ? `${key}.append.md` : `${key}.md`;
37698
- const full = path39.join(dir, filename);
38244
+ const full = path40.join(dir, filename);
37699
38245
  try {
37700
- fs27.mkdirSync(dir, { recursive: true });
38246
+ fs28.mkdirSync(dir, { recursive: true });
37701
38247
  if (content.trim()) {
37702
- fs27.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
37703
- } else if (fs27.existsSync(full)) {
37704
- fs27.unlinkSync(full);
38248
+ fs28.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
38249
+ } else if (fs28.existsSync(full)) {
38250
+ fs28.unlinkSync(full);
37705
38251
  }
37706
38252
  return { success: true, path: full, kind, key };
37707
38253
  } catch (error) {
@@ -38910,7 +39456,7 @@ ${ptyResult.output.slice(-2e3)}`);
38910
39456
  workspace
38911
39457
  };
38912
39458
  }
38913
- const { existsSync: existsSync38, readFileSync: readFileSync32, writeFileSync: writeFileSync19, copyFileSync: copyFileSync4, mkdirSync: mkdirSync18 } = await import("fs");
39459
+ const { existsSync: existsSync39, readFileSync: readFileSync33, writeFileSync: writeFileSync20, copyFileSync: copyFileSync4, mkdirSync: mkdirSync19 } = await import("fs");
38914
39460
  const { dirname: dirname11 } = await import("path");
38915
39461
  const mcpConfigPath = coordinatorSetup.configPath;
38916
39462
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
@@ -38946,21 +39492,21 @@ ${ptyResult.output.slice(-2e3)}`);
38946
39492
  };
38947
39493
  }
38948
39494
  try {
38949
- mkdirSync18(dirname11(mcpConfigPath), { recursive: true });
39495
+ mkdirSync19(dirname11(mcpConfigPath), { recursive: true });
38950
39496
  } catch (error) {
38951
39497
  const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
38952
39498
  LOG.error("MeshCoordinator", message);
38953
39499
  if (hermesManualFallback) return returnManualFallback(message);
38954
39500
  return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
38955
39501
  }
38956
- const hadExistingMcpConfig = existsSync38(mcpConfigPath);
39502
+ const hadExistingMcpConfig = existsSync39(mcpConfigPath);
38957
39503
  let existingMcpConfig = hermesBaseConfig?.config || {};
38958
39504
  if (hermesBaseConfig) {
38959
39505
  copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname11(mcpConfigPath));
38960
39506
  }
38961
39507
  if (hadExistingMcpConfig) {
38962
39508
  try {
38963
- const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync32(mcpConfigPath, "utf-8"), configFormat);
39509
+ const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync33(mcpConfigPath, "utf-8"), configFormat);
38964
39510
  const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
38965
39511
  existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
38966
39512
  copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
@@ -38983,7 +39529,7 @@ ${ptyResult.output.slice(-2e3)}`);
38983
39529
  }
38984
39530
  };
38985
39531
  try {
38986
- writeFileSync19(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
39532
+ writeFileSync20(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
38987
39533
  } catch (error) {
38988
39534
  const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
38989
39535
  LOG.error("MeshCoordinator", message);
@@ -39262,7 +39808,7 @@ ${ptyResult.output.slice(-2e3)}`);
39262
39808
  }
39263
39809
  }
39264
39810
  if (workspace) {
39265
- if (!fs21.existsSync(workspace)) {
39811
+ if (!fs22.existsSync(workspace)) {
39266
39812
  const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
39267
39813
  let remoteProbeApplied = false;
39268
39814
  if (inlineTransitGit) {
@@ -39375,7 +39921,7 @@ ${ptyResult.output.slice(-2e3)}`);
39375
39921
  const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
39376
39922
  const pendingCoordinatorEvents = drainPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
39377
39923
  const previewFreshness = (() => {
39378
- const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs21.existsSync(candidate));
39924
+ const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs22.existsSync(candidate));
39379
39925
  return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
39380
39926
  })();
39381
39927
  const asyncRefineJobs = buildMeshAsyncRefineJobs({
@@ -41122,12 +41668,12 @@ var ProviderInstanceManager = class {
41122
41668
  };
41123
41669
 
41124
41670
  // src/providers/version-archive.ts
41125
- import * as fs22 from "fs";
41126
- import * as path34 from "path";
41127
- import * as os26 from "os";
41671
+ import * as fs23 from "fs";
41672
+ import * as path35 from "path";
41673
+ import * as os27 from "os";
41128
41674
  import { platform as platform8 } from "os";
41129
41675
  import { exec as exec5 } from "child_process";
41130
- var ARCHIVE_PATH = path34.join(os26.homedir(), ".adhdev", "version-history.json");
41676
+ var ARCHIVE_PATH = path35.join(os27.homedir(), ".adhdev", "version-history.json");
41131
41677
  var MAX_ENTRIES_PER_PROVIDER = 20;
41132
41678
  var VersionArchive = class {
41133
41679
  history = {};
@@ -41136,8 +41682,8 @@ var VersionArchive = class {
41136
41682
  }
41137
41683
  load() {
41138
41684
  try {
41139
- if (fs22.existsSync(ARCHIVE_PATH)) {
41140
- this.history = JSON.parse(fs22.readFileSync(ARCHIVE_PATH, "utf-8"));
41685
+ if (fs23.existsSync(ARCHIVE_PATH)) {
41686
+ this.history = JSON.parse(fs23.readFileSync(ARCHIVE_PATH, "utf-8"));
41141
41687
  }
41142
41688
  } catch {
41143
41689
  this.history = {};
@@ -41174,8 +41720,8 @@ var VersionArchive = class {
41174
41720
  }
41175
41721
  save() {
41176
41722
  try {
41177
- fs22.mkdirSync(path34.dirname(ARCHIVE_PATH), { recursive: true });
41178
- fs22.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
41723
+ fs23.mkdirSync(path35.dirname(ARCHIVE_PATH), { recursive: true });
41724
+ fs23.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
41179
41725
  } catch {
41180
41726
  }
41181
41727
  }
@@ -41198,10 +41744,10 @@ function findBinary2(name) {
41198
41744
  for (const p of paths) {
41199
41745
  if (!p) continue;
41200
41746
  for (const ext of exes) {
41201
- const fullPath = path34.join(p, name + ext);
41747
+ const fullPath = path35.join(p, name + ext);
41202
41748
  try {
41203
- if (fs22.existsSync(fullPath)) {
41204
- const stat2 = fs22.statSync(fullPath);
41749
+ if (fs23.existsSync(fullPath)) {
41750
+ const stat2 = fs23.statSync(fullPath);
41205
41751
  if (stat2.isFile() && (isWin || stat2.mode & 73)) {
41206
41752
  return fullPath;
41207
41753
  }
@@ -41246,19 +41792,19 @@ async function getVersion(binary, versionCommand) {
41246
41792
  function checkPathExists2(paths) {
41247
41793
  for (const p of paths) {
41248
41794
  if (p.includes("*")) {
41249
- const home = os26.homedir();
41250
- const resolved = p.replace(/\*/g, home.split(path34.sep).pop() || "");
41251
- if (fs22.existsSync(resolved)) return resolved;
41795
+ const home = os27.homedir();
41796
+ const resolved = p.replace(/\*/g, home.split(path35.sep).pop() || "");
41797
+ if (fs23.existsSync(resolved)) return resolved;
41252
41798
  } else {
41253
- if (fs22.existsSync(p)) return p;
41799
+ if (fs23.existsSync(p)) return p;
41254
41800
  }
41255
41801
  }
41256
41802
  return null;
41257
41803
  }
41258
41804
  async function getMacAppVersion(appPath) {
41259
41805
  if (platform8() !== "darwin" || !appPath.endsWith(".app")) return null;
41260
- const plistPath = path34.join(appPath, "Contents", "Info.plist");
41261
- if (!fs22.existsSync(plistPath)) return null;
41806
+ const plistPath = path35.join(appPath, "Contents", "Info.plist");
41807
+ if (!fs23.existsSync(plistPath)) return null;
41262
41808
  const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
41263
41809
  return raw || null;
41264
41810
  }
@@ -41283,8 +41829,8 @@ async function detectAllVersions(loader, archive) {
41283
41829
  const cliBin = provider.cli ? findBinary2(provider.cli) : null;
41284
41830
  let resolvedBin = cliBin;
41285
41831
  if (!resolvedBin && appPath && currentOs === "darwin") {
41286
- const bundled = path34.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
41287
- if (provider.cli && fs22.existsSync(bundled)) resolvedBin = bundled;
41832
+ const bundled = path35.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
41833
+ if (provider.cli && fs23.existsSync(bundled)) resolvedBin = bundled;
41288
41834
  }
41289
41835
  info.installed = !!(appPath || resolvedBin);
41290
41836
  info.path = appPath || null;
@@ -41323,8 +41869,8 @@ async function detectAllVersions(loader, archive) {
41323
41869
 
41324
41870
  // src/daemon/dev-server.ts
41325
41871
  import * as http2 from "http";
41326
- import * as fs26 from "fs";
41327
- import * as path38 from "path";
41872
+ import * as fs27 from "fs";
41873
+ import * as path39 from "path";
41328
41874
  init_config();
41329
41875
 
41330
41876
  // src/daemon/scaffold-template.ts
@@ -41675,8 +42221,8 @@ init_logger();
41675
42221
 
41676
42222
  // src/daemon/dev-cdp-handlers.ts
41677
42223
  init_logger();
41678
- import * as fs23 from "fs";
41679
- import * as path35 from "path";
42224
+ import * as fs24 from "fs";
42225
+ import * as path36 from "path";
41680
42226
  async function handleCdpEvaluate(ctx, req, res) {
41681
42227
  const body = await ctx.readBody(req);
41682
42228
  const { expression, timeout, ideType } = body;
@@ -41854,18 +42400,18 @@ async function handleScriptHints(ctx, type, _req, res) {
41854
42400
  return;
41855
42401
  }
41856
42402
  let scriptsPath = "";
41857
- const directScripts = path35.join(dir, "scripts.js");
41858
- if (fs23.existsSync(directScripts)) {
42403
+ const directScripts = path36.join(dir, "scripts.js");
42404
+ if (fs24.existsSync(directScripts)) {
41859
42405
  scriptsPath = directScripts;
41860
42406
  } else {
41861
- const scriptsDir = path35.join(dir, "scripts");
41862
- if (fs23.existsSync(scriptsDir)) {
41863
- const versions = fs23.readdirSync(scriptsDir).filter((d) => {
41864
- return fs23.statSync(path35.join(scriptsDir, d)).isDirectory();
42407
+ const scriptsDir = path36.join(dir, "scripts");
42408
+ if (fs24.existsSync(scriptsDir)) {
42409
+ const versions = fs24.readdirSync(scriptsDir).filter((d) => {
42410
+ return fs24.statSync(path36.join(scriptsDir, d)).isDirectory();
41865
42411
  }).sort().reverse();
41866
42412
  for (const ver of versions) {
41867
- const p = path35.join(scriptsDir, ver, "scripts.js");
41868
- if (fs23.existsSync(p)) {
42413
+ const p = path36.join(scriptsDir, ver, "scripts.js");
42414
+ if (fs24.existsSync(p)) {
41869
42415
  scriptsPath = p;
41870
42416
  break;
41871
42417
  }
@@ -41877,7 +42423,7 @@ async function handleScriptHints(ctx, type, _req, res) {
41877
42423
  return;
41878
42424
  }
41879
42425
  try {
41880
- const source = fs23.readFileSync(scriptsPath, "utf-8");
42426
+ const source = fs24.readFileSync(scriptsPath, "utf-8");
41881
42427
  const hints = {};
41882
42428
  const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
41883
42429
  let match;
@@ -42692,8 +43238,8 @@ async function handleDomContext(ctx, type, req, res) {
42692
43238
  }
42693
43239
 
42694
43240
  // src/daemon/dev-cli-debug.ts
42695
- import * as fs24 from "fs";
42696
- import * as path36 from "path";
43241
+ import * as fs25 from "fs";
43242
+ import * as path37 from "path";
42697
43243
  function slugifyFixtureName(value) {
42698
43244
  const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
42699
43245
  return normalized || `fixture-${Date.now()}`;
@@ -42703,15 +43249,15 @@ function getCliFixtureDir(ctx, type) {
42703
43249
  if (!providerDir) {
42704
43250
  throw new Error(`Provider directory not found for '${type}'`);
42705
43251
  }
42706
- return path36.join(providerDir, "fixtures");
43252
+ return path37.join(providerDir, "fixtures");
42707
43253
  }
42708
43254
  function readCliFixture(ctx, type, name) {
42709
43255
  const fixtureDir = getCliFixtureDir(ctx, type);
42710
- const filePath = path36.join(fixtureDir, `${name}.json`);
42711
- if (!fs24.existsSync(filePath)) {
43256
+ const filePath = path37.join(fixtureDir, `${name}.json`);
43257
+ if (!fs25.existsSync(filePath)) {
42712
43258
  throw new Error(`Fixture not found: ${filePath}`);
42713
43259
  }
42714
- return JSON.parse(fs24.readFileSync(filePath, "utf-8"));
43260
+ return JSON.parse(fs25.readFileSync(filePath, "utf-8"));
42715
43261
  }
42716
43262
  function getExerciseTranscriptText(result) {
42717
43263
  const parts = [];
@@ -43456,7 +44002,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
43456
44002
  return;
43457
44003
  }
43458
44004
  const fixtureDir = getCliFixtureDir(ctx, type);
43459
- fs24.mkdirSync(fixtureDir, { recursive: true });
44005
+ fs25.mkdirSync(fixtureDir, { recursive: true });
43460
44006
  const name = slugifyFixtureName(String(body?.name || `${type}-${Date.now()}`));
43461
44007
  const result = await runCliExerciseInternal(ctx, { ...request, type });
43462
44008
  const fixture = {
@@ -43483,8 +44029,8 @@ async function handleCliFixtureCapture(ctx, req, res) {
43483
44029
  },
43484
44030
  notes: typeof body?.notes === "string" ? body.notes : void 0
43485
44031
  };
43486
- const filePath = path36.join(fixtureDir, `${name}.json`);
43487
- fs24.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
44032
+ const filePath = path37.join(fixtureDir, `${name}.json`);
44033
+ fs25.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
43488
44034
  ctx.json(res, 200, {
43489
44035
  saved: true,
43490
44036
  name,
@@ -43502,14 +44048,14 @@ async function handleCliFixtureCapture(ctx, req, res) {
43502
44048
  async function handleCliFixtureList(ctx, type, _req, res) {
43503
44049
  try {
43504
44050
  const fixtureDir = getCliFixtureDir(ctx, type);
43505
- if (!fs24.existsSync(fixtureDir)) {
44051
+ if (!fs25.existsSync(fixtureDir)) {
43506
44052
  ctx.json(res, 200, { fixtures: [], count: 0 });
43507
44053
  return;
43508
44054
  }
43509
- const fixtures = fs24.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
43510
- const fullPath = path36.join(fixtureDir, file);
44055
+ const fixtures = fs25.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
44056
+ const fullPath = path37.join(fixtureDir, file);
43511
44057
  try {
43512
- const raw = JSON.parse(fs24.readFileSync(fullPath, "utf-8"));
44058
+ const raw = JSON.parse(fs25.readFileSync(fullPath, "utf-8"));
43513
44059
  return {
43514
44060
  name: raw.name || file.replace(/\.json$/i, ""),
43515
44061
  path: fullPath,
@@ -43642,9 +44188,9 @@ async function handleCliRaw(ctx, req, res) {
43642
44188
  }
43643
44189
 
43644
44190
  // src/daemon/dev-auto-implement.ts
43645
- import * as fs25 from "fs";
43646
- import * as path37 from "path";
43647
- import * as os27 from "os";
44191
+ import * as fs26 from "fs";
44192
+ import * as path38 from "path";
44193
+ import * as os28 from "os";
43648
44194
  function getAutoImplPid(ctx) {
43649
44195
  const pid = ctx.autoImplProcess?.pid;
43650
44196
  return typeof pid === "number" && pid > 0 ? pid : null;
@@ -43690,38 +44236,38 @@ function resolveAutoImplReference(ctx, category, requestedReference, targetType)
43690
44236
  return fallback?.type || null;
43691
44237
  }
43692
44238
  function getLatestScriptVersionDir(scriptsDir) {
43693
- if (!fs25.existsSync(scriptsDir)) return null;
43694
- const versions = fs25.readdirSync(scriptsDir).filter((d) => {
44239
+ if (!fs26.existsSync(scriptsDir)) return null;
44240
+ const versions = fs26.readdirSync(scriptsDir).filter((d) => {
43695
44241
  try {
43696
- return fs25.statSync(path37.join(scriptsDir, d)).isDirectory();
44242
+ return fs26.statSync(path38.join(scriptsDir, d)).isDirectory();
43697
44243
  } catch {
43698
44244
  return false;
43699
44245
  }
43700
44246
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
43701
44247
  if (versions.length === 0) return null;
43702
- return path37.join(scriptsDir, versions[0]);
44248
+ return path38.join(scriptsDir, versions[0]);
43703
44249
  }
43704
44250
  function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
43705
- const canonicalUserDir = path37.resolve(ctx.providerLoader.getUserProviderDir(category, type));
43706
- const desiredDir = requestedDir ? path37.resolve(requestedDir) : canonicalUserDir;
43707
- const upstreamRoot = path37.resolve(ctx.providerLoader.getUpstreamDir());
43708
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path37.sep}`)) {
44251
+ const canonicalUserDir = path38.resolve(ctx.providerLoader.getUserProviderDir(category, type));
44252
+ const desiredDir = requestedDir ? path38.resolve(requestedDir) : canonicalUserDir;
44253
+ const upstreamRoot = path38.resolve(ctx.providerLoader.getUpstreamDir());
44254
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path38.sep}`)) {
43709
44255
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
43710
44256
  }
43711
- if (path37.basename(desiredDir) !== type) {
44257
+ if (path38.basename(desiredDir) !== type) {
43712
44258
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
43713
44259
  }
43714
44260
  const sourceDir = ctx.findProviderDir(type);
43715
44261
  if (!sourceDir) {
43716
44262
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
43717
44263
  }
43718
- if (!fs25.existsSync(desiredDir)) {
43719
- fs25.mkdirSync(path37.dirname(desiredDir), { recursive: true });
43720
- fs25.cpSync(sourceDir, desiredDir, { recursive: true });
44264
+ if (!fs26.existsSync(desiredDir)) {
44265
+ fs26.mkdirSync(path38.dirname(desiredDir), { recursive: true });
44266
+ fs26.cpSync(sourceDir, desiredDir, { recursive: true });
43721
44267
  ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
43722
44268
  }
43723
- const providerJson = path37.join(desiredDir, "provider.json");
43724
- if (!fs25.existsSync(providerJson)) {
44269
+ const providerJson = path38.join(desiredDir, "provider.json");
44270
+ if (!fs26.existsSync(providerJson)) {
43725
44271
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
43726
44272
  }
43727
44273
  return { dir: desiredDir };
@@ -43729,15 +44275,15 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
43729
44275
  function loadAutoImplReferenceScripts(ctx, referenceType) {
43730
44276
  if (!referenceType) return {};
43731
44277
  const refDir = ctx.findProviderDir(referenceType);
43732
- if (!refDir || !fs25.existsSync(refDir)) return {};
44278
+ if (!refDir || !fs26.existsSync(refDir)) return {};
43733
44279
  const referenceScripts = {};
43734
- const scriptsDir = path37.join(refDir, "scripts");
44280
+ const scriptsDir = path38.join(refDir, "scripts");
43735
44281
  const latestDir = getLatestScriptVersionDir(scriptsDir);
43736
44282
  if (!latestDir) return referenceScripts;
43737
- for (const file of fs25.readdirSync(latestDir)) {
44283
+ for (const file of fs26.readdirSync(latestDir)) {
43738
44284
  if (!file.endsWith(".js")) continue;
43739
44285
  try {
43740
- referenceScripts[file] = fs25.readFileSync(path37.join(latestDir, file), "utf-8");
44286
+ referenceScripts[file] = fs26.readFileSync(path38.join(latestDir, file), "utf-8");
43741
44287
  } catch {
43742
44288
  }
43743
44289
  }
@@ -43845,16 +44391,16 @@ async function handleAutoImplement(ctx, type, req, res) {
43845
44391
  });
43846
44392
  const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
43847
44393
  const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
43848
- const tmpDir = path37.join(os27.tmpdir(), "adhdev-autoimpl");
43849
- if (!fs25.existsSync(tmpDir)) fs25.mkdirSync(tmpDir, { recursive: true });
43850
- const promptFile = path37.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
43851
- fs25.writeFileSync(promptFile, prompt, "utf-8");
44394
+ const tmpDir = path38.join(os28.tmpdir(), "adhdev-autoimpl");
44395
+ if (!fs26.existsSync(tmpDir)) fs26.mkdirSync(tmpDir, { recursive: true });
44396
+ const promptFile = path38.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
44397
+ fs26.writeFileSync(promptFile, prompt, "utf-8");
43852
44398
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
43853
44399
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
43854
44400
  const spawn4 = agentProvider?.spawn;
43855
44401
  if (!spawn4?.command) {
43856
44402
  try {
43857
- fs25.unlinkSync(promptFile);
44403
+ fs26.unlinkSync(promptFile);
43858
44404
  } catch {
43859
44405
  }
43860
44406
  ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
@@ -43956,7 +44502,7 @@ async function handleAutoImplement(ctx, type, req, res) {
43956
44502
  } catch {
43957
44503
  }
43958
44504
  try {
43959
- fs25.unlinkSync(promptFile);
44505
+ fs26.unlinkSync(promptFile);
43960
44506
  } catch {
43961
44507
  }
43962
44508
  ctx.log(`Auto-implement (ACP) ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
@@ -44000,7 +44546,7 @@ async function handleAutoImplement(ctx, type, req, res) {
44000
44546
  const interactiveFlags = ["--yolo", "--interactive", "-i"];
44001
44547
  const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
44002
44548
  let shellCmd;
44003
- const isWin = os27.platform() === "win32";
44549
+ const isWin = os28.platform() === "win32";
44004
44550
  const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
44005
44551
  const promptMode = autoImpl?.promptMode ?? "stdin";
44006
44552
  const extraArgs = autoImpl?.extraArgs ?? [];
@@ -44039,7 +44585,7 @@ async function handleAutoImplement(ctx, type, req, res) {
44039
44585
  try {
44040
44586
  const pty = __require("node-pty");
44041
44587
  ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
44042
- const isWin2 = os27.platform() === "win32";
44588
+ const isWin2 = os28.platform() === "win32";
44043
44589
  child = pty.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
44044
44590
  name: "xterm-256color",
44045
44591
  cols: 120,
@@ -44182,7 +44728,7 @@ async function handleAutoImplement(ctx, type, req, res) {
44182
44728
  }
44183
44729
  });
44184
44730
  try {
44185
- fs25.unlinkSync(promptFile);
44731
+ fs26.unlinkSync(promptFile);
44186
44732
  } catch {
44187
44733
  }
44188
44734
  ctx.log(`Auto-implement ${success ? "completed" : "failed"}: ${type} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
@@ -44279,7 +44825,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
44279
44825
  setMode: "set_mode.js"
44280
44826
  };
44281
44827
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
44282
- const scriptsDir = path37.join(providerDir, "scripts");
44828
+ const scriptsDir = path38.join(providerDir, "scripts");
44283
44829
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
44284
44830
  if (latestScriptsDir) {
44285
44831
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -44287,10 +44833,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
44287
44833
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
44288
44834
  lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
44289
44835
  lines.push("");
44290
- for (const file of fs25.readdirSync(latestScriptsDir)) {
44836
+ for (const file of fs26.readdirSync(latestScriptsDir)) {
44291
44837
  if (file.endsWith(".js") && targetFileNames.has(file)) {
44292
44838
  try {
44293
- const content = fs25.readFileSync(path37.join(latestScriptsDir, file), "utf-8");
44839
+ const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
44294
44840
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
44295
44841
  lines.push("```javascript");
44296
44842
  lines.push(content);
@@ -44300,14 +44846,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
44300
44846
  }
44301
44847
  }
44302
44848
  }
44303
- const refFiles = fs25.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
44849
+ const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
44304
44850
  if (refFiles.length > 0) {
44305
44851
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
44306
44852
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
44307
44853
  lines.push("");
44308
44854
  for (const file of refFiles) {
44309
44855
  try {
44310
- const content = fs25.readFileSync(path37.join(latestScriptsDir, file), "utf-8");
44856
+ const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
44311
44857
  lines.push(`### \`${file}\` \u{1F512}`);
44312
44858
  lines.push("```javascript");
44313
44859
  lines.push(content);
@@ -44348,11 +44894,11 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
44348
44894
  lines.push("");
44349
44895
  }
44350
44896
  }
44351
- const docsDir = path37.join(providerDir, "../../docs");
44897
+ const docsDir = path38.join(providerDir, "../../docs");
44352
44898
  const loadGuide = (name) => {
44353
44899
  try {
44354
- const p = path37.join(docsDir, name);
44355
- if (fs25.existsSync(p)) return fs25.readFileSync(p, "utf-8");
44900
+ const p = path38.join(docsDir, name);
44901
+ if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
44356
44902
  } catch {
44357
44903
  }
44358
44904
  return null;
@@ -44588,7 +45134,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
44588
45134
  parseApproval: "parse_approval.js"
44589
45135
  };
44590
45136
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
44591
- const scriptsDir = path37.join(providerDir, "scripts");
45137
+ const scriptsDir = path38.join(providerDir, "scripts");
44592
45138
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
44593
45139
  if (latestScriptsDir) {
44594
45140
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -44596,11 +45142,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
44596
45142
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
44597
45143
  lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
44598
45144
  lines.push("");
44599
- for (const file of fs25.readdirSync(latestScriptsDir)) {
45145
+ for (const file of fs26.readdirSync(latestScriptsDir)) {
44600
45146
  if (!file.endsWith(".js")) continue;
44601
45147
  if (!targetFileNames.has(file)) continue;
44602
45148
  try {
44603
- const content = fs25.readFileSync(path37.join(latestScriptsDir, file), "utf-8");
45149
+ const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
44604
45150
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
44605
45151
  lines.push("```javascript");
44606
45152
  lines.push(content);
@@ -44609,14 +45155,14 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
44609
45155
  } catch {
44610
45156
  }
44611
45157
  }
44612
- const refFiles = fs25.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
45158
+ const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
44613
45159
  if (refFiles.length > 0) {
44614
45160
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
44615
45161
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
44616
45162
  lines.push("");
44617
45163
  for (const file of refFiles) {
44618
45164
  try {
44619
- const content = fs25.readFileSync(path37.join(latestScriptsDir, file), "utf-8");
45165
+ const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
44620
45166
  lines.push(`### \`${file}\` \u{1F512}`);
44621
45167
  lines.push("```javascript");
44622
45168
  lines.push(content);
@@ -44649,11 +45195,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
44649
45195
  lines.push("");
44650
45196
  }
44651
45197
  }
44652
- const docsDir = path37.join(providerDir, "../../docs");
45198
+ const docsDir = path38.join(providerDir, "../../docs");
44653
45199
  const loadGuide = (name) => {
44654
45200
  try {
44655
- const p = path37.join(docsDir, name);
44656
- if (fs25.existsSync(p)) return fs25.readFileSync(p, "utf-8");
45201
+ const p = path38.join(docsDir, name);
45202
+ if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
44657
45203
  } catch {
44658
45204
  }
44659
45205
  return null;
@@ -45099,8 +45645,8 @@ var DevServer = class _DevServer {
45099
45645
  }
45100
45646
  getEndpointList() {
45101
45647
  return this.routes.map((r) => {
45102
- const path39 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
45103
- return `${r.method.padEnd(5)} ${path39}`;
45648
+ const path40 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
45649
+ return `${r.method.padEnd(5)} ${path40}`;
45104
45650
  });
45105
45651
  }
45106
45652
  async start(port = DEV_SERVER_PORT) {
@@ -45388,12 +45934,12 @@ var DevServer = class _DevServer {
45388
45934
  // ─── DevConsole SPA ───
45389
45935
  getConsoleDistDir() {
45390
45936
  const candidates = [
45391
- path38.resolve(__dirname, "../../web-devconsole/dist"),
45392
- path38.resolve(__dirname, "../../../web-devconsole/dist"),
45393
- path38.join(process.cwd(), "packages/web-devconsole/dist")
45937
+ path39.resolve(__dirname, "../../web-devconsole/dist"),
45938
+ path39.resolve(__dirname, "../../../web-devconsole/dist"),
45939
+ path39.join(process.cwd(), "packages/web-devconsole/dist")
45394
45940
  ];
45395
45941
  for (const dir of candidates) {
45396
- if (fs26.existsSync(path38.join(dir, "index.html"))) return dir;
45942
+ if (fs27.existsSync(path39.join(dir, "index.html"))) return dir;
45397
45943
  }
45398
45944
  return null;
45399
45945
  }
@@ -45403,9 +45949,9 @@ var DevServer = class _DevServer {
45403
45949
  this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
45404
45950
  return;
45405
45951
  }
45406
- const htmlPath = path38.join(distDir, "index.html");
45952
+ const htmlPath = path39.join(distDir, "index.html");
45407
45953
  try {
45408
- const html = fs26.readFileSync(htmlPath, "utf-8");
45954
+ const html = fs27.readFileSync(htmlPath, "utf-8");
45409
45955
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
45410
45956
  res.end(html);
45411
45957
  } catch (e) {
@@ -45428,15 +45974,15 @@ var DevServer = class _DevServer {
45428
45974
  this.json(res, 404, { error: "Not found" });
45429
45975
  return;
45430
45976
  }
45431
- const safePath = path38.normalize(pathname).replace(/^\.\.\//, "");
45432
- const filePath = path38.join(distDir, safePath);
45977
+ const safePath = path39.normalize(pathname).replace(/^\.\.\//, "");
45978
+ const filePath = path39.join(distDir, safePath);
45433
45979
  if (!filePath.startsWith(distDir)) {
45434
45980
  this.json(res, 403, { error: "Forbidden" });
45435
45981
  return;
45436
45982
  }
45437
45983
  try {
45438
- const content = fs26.readFileSync(filePath);
45439
- const ext = path38.extname(filePath);
45984
+ const content = fs27.readFileSync(filePath);
45985
+ const ext = path39.extname(filePath);
45440
45986
  const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
45441
45987
  res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
45442
45988
  res.end(content);
@@ -45544,14 +46090,14 @@ var DevServer = class _DevServer {
45544
46090
  const files = [];
45545
46091
  const scan = (d, prefix) => {
45546
46092
  try {
45547
- for (const entry of fs26.readdirSync(d, { withFileTypes: true })) {
46093
+ for (const entry of fs27.readdirSync(d, { withFileTypes: true })) {
45548
46094
  if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
45549
46095
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
45550
46096
  if (entry.isDirectory()) {
45551
46097
  files.push({ path: rel, size: 0, type: "dir" });
45552
- scan(path38.join(d, entry.name), rel);
46098
+ scan(path39.join(d, entry.name), rel);
45553
46099
  } else {
45554
- const stat2 = fs26.statSync(path38.join(d, entry.name));
46100
+ const stat2 = fs27.statSync(path39.join(d, entry.name));
45555
46101
  files.push({ path: rel, size: stat2.size, type: "file" });
45556
46102
  }
45557
46103
  }
@@ -45574,16 +46120,16 @@ var DevServer = class _DevServer {
45574
46120
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
45575
46121
  return;
45576
46122
  }
45577
- const fullPath = path38.resolve(dir, path38.normalize(filePath));
46123
+ const fullPath = path39.resolve(dir, path39.normalize(filePath));
45578
46124
  if (!fullPath.startsWith(dir)) {
45579
46125
  this.json(res, 403, { error: "Forbidden" });
45580
46126
  return;
45581
46127
  }
45582
- if (!fs26.existsSync(fullPath) || fs26.statSync(fullPath).isDirectory()) {
46128
+ if (!fs27.existsSync(fullPath) || fs27.statSync(fullPath).isDirectory()) {
45583
46129
  this.json(res, 404, { error: `File not found: ${filePath}` });
45584
46130
  return;
45585
46131
  }
45586
- const content = fs26.readFileSync(fullPath, "utf-8");
46132
+ const content = fs27.readFileSync(fullPath, "utf-8");
45587
46133
  this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
45588
46134
  }
45589
46135
  /** POST /api/providers/:type/file — write a file { path, content } */
@@ -45599,15 +46145,15 @@ var DevServer = class _DevServer {
45599
46145
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
45600
46146
  return;
45601
46147
  }
45602
- const fullPath = path38.resolve(dir, path38.normalize(filePath));
46148
+ const fullPath = path39.resolve(dir, path39.normalize(filePath));
45603
46149
  if (!fullPath.startsWith(dir)) {
45604
46150
  this.json(res, 403, { error: "Forbidden" });
45605
46151
  return;
45606
46152
  }
45607
46153
  try {
45608
- if (fs26.existsSync(fullPath)) fs26.copyFileSync(fullPath, fullPath + ".bak");
45609
- fs26.mkdirSync(path38.dirname(fullPath), { recursive: true });
45610
- fs26.writeFileSync(fullPath, content, "utf-8");
46154
+ if (fs27.existsSync(fullPath)) fs27.copyFileSync(fullPath, fullPath + ".bak");
46155
+ fs27.mkdirSync(path39.dirname(fullPath), { recursive: true });
46156
+ fs27.writeFileSync(fullPath, content, "utf-8");
45611
46157
  this.log(`File saved: ${fullPath} (${content.length} chars)`);
45612
46158
  this.providerLoader.reload();
45613
46159
  this.json(res, 200, { saved: true, path: filePath, chars: content.length });
@@ -45623,9 +46169,9 @@ var DevServer = class _DevServer {
45623
46169
  return;
45624
46170
  }
45625
46171
  for (const name of ["scripts.js", "provider.json"]) {
45626
- const p = path38.join(dir, name);
45627
- if (fs26.existsSync(p)) {
45628
- const source = fs26.readFileSync(p, "utf-8");
46172
+ const p = path39.join(dir, name);
46173
+ if (fs27.existsSync(p)) {
46174
+ const source = fs27.readFileSync(p, "utf-8");
45629
46175
  this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
45630
46176
  return;
45631
46177
  }
@@ -45644,11 +46190,11 @@ var DevServer = class _DevServer {
45644
46190
  this.json(res, 404, { error: `Provider not found: ${type}` });
45645
46191
  return;
45646
46192
  }
45647
- const target = fs26.existsSync(path38.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
45648
- const targetPath = path38.join(dir, target);
46193
+ const target = fs27.existsSync(path39.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
46194
+ const targetPath = path39.join(dir, target);
45649
46195
  try {
45650
- if (fs26.existsSync(targetPath)) fs26.copyFileSync(targetPath, targetPath + ".bak");
45651
- fs26.writeFileSync(targetPath, source, "utf-8");
46196
+ if (fs27.existsSync(targetPath)) fs27.copyFileSync(targetPath, targetPath + ".bak");
46197
+ fs27.writeFileSync(targetPath, source, "utf-8");
45652
46198
  this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
45653
46199
  this.providerLoader.reload();
45654
46200
  this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
@@ -45792,21 +46338,21 @@ var DevServer = class _DevServer {
45792
46338
  }
45793
46339
  let targetDir;
45794
46340
  targetDir = this.providerLoader.getUserProviderDir(category, type);
45795
- const jsonPath = path38.join(targetDir, "provider.json");
45796
- if (fs26.existsSync(jsonPath)) {
46341
+ const jsonPath = path39.join(targetDir, "provider.json");
46342
+ if (fs27.existsSync(jsonPath)) {
45797
46343
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
45798
46344
  return;
45799
46345
  }
45800
46346
  try {
45801
46347
  const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version, osPaths, processNames });
45802
- fs26.mkdirSync(targetDir, { recursive: true });
45803
- fs26.writeFileSync(jsonPath, result["provider.json"], "utf-8");
46348
+ fs27.mkdirSync(targetDir, { recursive: true });
46349
+ fs27.writeFileSync(jsonPath, result["provider.json"], "utf-8");
45804
46350
  const createdFiles = ["provider.json"];
45805
46351
  if (result.files) {
45806
46352
  for (const [relPath, content] of Object.entries(result.files)) {
45807
- const fullPath = path38.join(targetDir, relPath);
45808
- fs26.mkdirSync(path38.dirname(fullPath), { recursive: true });
45809
- fs26.writeFileSync(fullPath, content, "utf-8");
46353
+ const fullPath = path39.join(targetDir, relPath);
46354
+ fs27.mkdirSync(path39.dirname(fullPath), { recursive: true });
46355
+ fs27.writeFileSync(fullPath, content, "utf-8");
45810
46356
  createdFiles.push(relPath);
45811
46357
  }
45812
46358
  }
@@ -45855,38 +46401,38 @@ var DevServer = class _DevServer {
45855
46401
  }
45856
46402
  // ─── Phase 2: Auto-Implement Backend ───
45857
46403
  getLatestScriptVersionDir(scriptsDir) {
45858
- if (!fs26.existsSync(scriptsDir)) return null;
45859
- const versions = fs26.readdirSync(scriptsDir).filter((d) => {
46404
+ if (!fs27.existsSync(scriptsDir)) return null;
46405
+ const versions = fs27.readdirSync(scriptsDir).filter((d) => {
45860
46406
  try {
45861
- return fs26.statSync(path38.join(scriptsDir, d)).isDirectory();
46407
+ return fs27.statSync(path39.join(scriptsDir, d)).isDirectory();
45862
46408
  } catch {
45863
46409
  return false;
45864
46410
  }
45865
46411
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
45866
46412
  if (versions.length === 0) return null;
45867
- return path38.join(scriptsDir, versions[0]);
46413
+ return path39.join(scriptsDir, versions[0]);
45868
46414
  }
45869
46415
  resolveAutoImplWritableProviderDir(category, type, requestedDir) {
45870
- const canonicalUserDir = path38.resolve(this.providerLoader.getUserProviderDir(category, type));
45871
- const desiredDir = requestedDir ? path38.resolve(requestedDir) : canonicalUserDir;
45872
- const upstreamRoot = path38.resolve(this.providerLoader.getUpstreamDir());
45873
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path38.sep}`)) {
46416
+ const canonicalUserDir = path39.resolve(this.providerLoader.getUserProviderDir(category, type));
46417
+ const desiredDir = requestedDir ? path39.resolve(requestedDir) : canonicalUserDir;
46418
+ const upstreamRoot = path39.resolve(this.providerLoader.getUpstreamDir());
46419
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path39.sep}`)) {
45874
46420
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
45875
46421
  }
45876
- if (path38.basename(desiredDir) !== type) {
46422
+ if (path39.basename(desiredDir) !== type) {
45877
46423
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
45878
46424
  }
45879
46425
  const sourceDir = this.findProviderDir(type);
45880
46426
  if (!sourceDir) {
45881
46427
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
45882
46428
  }
45883
- if (!fs26.existsSync(desiredDir)) {
45884
- fs26.mkdirSync(path38.dirname(desiredDir), { recursive: true });
45885
- fs26.cpSync(sourceDir, desiredDir, { recursive: true });
46429
+ if (!fs27.existsSync(desiredDir)) {
46430
+ fs27.mkdirSync(path39.dirname(desiredDir), { recursive: true });
46431
+ fs27.cpSync(sourceDir, desiredDir, { recursive: true });
45886
46432
  this.log(`Auto-implement writable copy created: ${desiredDir}`);
45887
46433
  }
45888
- const providerJson = path38.join(desiredDir, "provider.json");
45889
- if (!fs26.existsSync(providerJson)) {
46434
+ const providerJson = path39.join(desiredDir, "provider.json");
46435
+ if (!fs27.existsSync(providerJson)) {
45890
46436
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
45891
46437
  }
45892
46438
  return { dir: desiredDir };
@@ -45921,7 +46467,7 @@ var DevServer = class _DevServer {
45921
46467
  setMode: "set_mode.js"
45922
46468
  };
45923
46469
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
45924
- const scriptsDir = path38.join(providerDir, "scripts");
46470
+ const scriptsDir = path39.join(providerDir, "scripts");
45925
46471
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
45926
46472
  if (latestScriptsDir) {
45927
46473
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -45929,10 +46475,10 @@ var DevServer = class _DevServer {
45929
46475
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
45930
46476
  lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
45931
46477
  lines.push("");
45932
- for (const file of fs26.readdirSync(latestScriptsDir)) {
46478
+ for (const file of fs27.readdirSync(latestScriptsDir)) {
45933
46479
  if (file.endsWith(".js") && targetFileNames.has(file)) {
45934
46480
  try {
45935
- const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
46481
+ const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
45936
46482
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
45937
46483
  lines.push("```javascript");
45938
46484
  lines.push(content);
@@ -45942,14 +46488,14 @@ var DevServer = class _DevServer {
45942
46488
  }
45943
46489
  }
45944
46490
  }
45945
- const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
46491
+ const refFiles = fs27.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
45946
46492
  if (refFiles.length > 0) {
45947
46493
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
45948
46494
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
45949
46495
  lines.push("");
45950
46496
  for (const file of refFiles) {
45951
46497
  try {
45952
- const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
46498
+ const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
45953
46499
  lines.push(`### \`${file}\` \u{1F512}`);
45954
46500
  lines.push("```javascript");
45955
46501
  lines.push(content);
@@ -45990,11 +46536,11 @@ var DevServer = class _DevServer {
45990
46536
  lines.push("");
45991
46537
  }
45992
46538
  }
45993
- const docsDir = path38.join(providerDir, "../../docs");
46539
+ const docsDir = path39.join(providerDir, "../../docs");
45994
46540
  const loadGuide = (name) => {
45995
46541
  try {
45996
- const p = path38.join(docsDir, name);
45997
- if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
46542
+ const p = path39.join(docsDir, name);
46543
+ if (fs27.existsSync(p)) return fs27.readFileSync(p, "utf-8");
45998
46544
  } catch {
45999
46545
  }
46000
46546
  return null;
@@ -46167,7 +46713,7 @@ var DevServer = class _DevServer {
46167
46713
  parseApproval: "parse_approval.js"
46168
46714
  };
46169
46715
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
46170
- const scriptsDir = path38.join(providerDir, "scripts");
46716
+ const scriptsDir = path39.join(providerDir, "scripts");
46171
46717
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
46172
46718
  if (latestScriptsDir) {
46173
46719
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -46175,11 +46721,11 @@ var DevServer = class _DevServer {
46175
46721
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
46176
46722
  lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
46177
46723
  lines.push("");
46178
- for (const file of fs26.readdirSync(latestScriptsDir)) {
46724
+ for (const file of fs27.readdirSync(latestScriptsDir)) {
46179
46725
  if (!file.endsWith(".js")) continue;
46180
46726
  if (!targetFileNames.has(file)) continue;
46181
46727
  try {
46182
- const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
46728
+ const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
46183
46729
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
46184
46730
  lines.push("```javascript");
46185
46731
  lines.push(content);
@@ -46188,14 +46734,14 @@ var DevServer = class _DevServer {
46188
46734
  } catch {
46189
46735
  }
46190
46736
  }
46191
- const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
46737
+ const refFiles = fs27.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
46192
46738
  if (refFiles.length > 0) {
46193
46739
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
46194
46740
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
46195
46741
  lines.push("");
46196
46742
  for (const file of refFiles) {
46197
46743
  try {
46198
- const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
46744
+ const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
46199
46745
  lines.push(`### \`${file}\` \u{1F512}`);
46200
46746
  lines.push("```javascript");
46201
46747
  lines.push(content);
@@ -46228,11 +46774,11 @@ var DevServer = class _DevServer {
46228
46774
  lines.push("");
46229
46775
  }
46230
46776
  }
46231
- const docsDir = path38.join(providerDir, "../../docs");
46777
+ const docsDir = path39.join(providerDir, "../../docs");
46232
46778
  const loadGuide = (name) => {
46233
46779
  try {
46234
- const p = path38.join(docsDir, name);
46235
- if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
46780
+ const p = path39.join(docsDir, name);
46781
+ if (fs27.existsSync(p)) return fs27.readFileSync(p, "utf-8");
46236
46782
  } catch {
46237
46783
  }
46238
46784
  return null;
@@ -47142,8 +47688,8 @@ async function installExtension(ide, extension) {
47142
47688
  const res = await fetch(extension.vsixUrl);
47143
47689
  if (res.ok) {
47144
47690
  const buffer = Buffer.from(await res.arrayBuffer());
47145
- const fs27 = await import("fs");
47146
- fs27.writeFileSync(vsixPath, buffer);
47691
+ const fs28 = await import("fs");
47692
+ fs28.writeFileSync(vsixPath, buffer);
47147
47693
  return new Promise((resolve23) => {
47148
47694
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
47149
47695
  exec6(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
@@ -47714,12 +48260,12 @@ init_parse_session();
47714
48260
 
47715
48261
  // src/providers/sdk/v1/fixture-tooling/replay.ts
47716
48262
  init_provider_cli_shared();
47717
- import { readFileSync as readFileSync30 } from "fs";
48263
+ import { readFileSync as readFileSync31 } from "fs";
47718
48264
  import { dirname as dirname9, resolve as resolve21 } from "path";
47719
48265
 
47720
48266
  // src/providers/sdk/v1/validators/taint.ts
47721
- import { readFileSync as readFileSync31, existsSync as existsSync37 } from "fs";
47722
- import { resolve as resolve22, dirname as dirname10, join as join42 } from "path";
48267
+ import { readFileSync as readFileSync32, existsSync as existsSync38 } from "fs";
48268
+ import { resolve as resolve22, dirname as dirname10, join as join43 } from "path";
47723
48269
 
47724
48270
  // src/providers/sdk/v1/validators/index.ts
47725
48271
  init_manifest();