@adhdev/daemon-core 0.9.82-rc.328 → 0.9.82-rc.329

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -313,10 +313,10 @@ function readInjected(value) {
313
313
  }
314
314
  function getDaemonBuildInfo() {
315
315
  if (cached) return cached;
316
- const commit = readInjected(true ? "38ede5a48ea8a2e21b5ea014880b9af37c6e3537" : void 0) ?? "unknown";
317
- const commitShort = readInjected(true ? "38ede5a4" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
318
- const version = readInjected(true ? "0.9.82-rc.328" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
319
- const builtAt = readInjected(true ? "2026-06-19T13:57:32.496Z" : void 0);
316
+ const commit = readInjected(true ? "9277ba79593a0feae0e17de0204856825a199ebe" : void 0) ?? "unknown";
317
+ const commitShort = readInjected(true ? "9277ba79" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
318
+ const version = readInjected(true ? "0.9.82-rc.329" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
319
+ const builtAt = readInjected(true ? "2026-06-19T15:56:44.269Z" : void 0);
320
320
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
321
321
  return cached;
322
322
  }
@@ -327,6 +327,247 @@ var init_build_info = __esm({
327
327
  }
328
328
  });
329
329
 
330
+ // src/git/change-impact-config.ts
331
+ function isRecord(value) {
332
+ return !!value && typeof value === "object" && !Array.isArray(value);
333
+ }
334
+ function isStringArray(value) {
335
+ return Array.isArray(value) && value.every((v) => typeof v === "string" && v.length > 0);
336
+ }
337
+ function validateTarget(value, key, errors) {
338
+ if (!isRecord(value)) {
339
+ errors.push(`impactTargets.${key} must be an object`);
340
+ return void 0;
341
+ }
342
+ const { recommendedCommand } = value;
343
+ if (typeof recommendedCommand !== "string" || !recommendedCommand.length) {
344
+ errors.push(`impactTargets.${key}.recommendedCommand must be a non-empty string`);
345
+ return void 0;
346
+ }
347
+ for (const k of Object.keys(value)) {
348
+ if (k !== "recommendedCommand") errors.push(`impactTargets.${key}.${k} is not a recognized field (only recommendedCommand)`);
349
+ }
350
+ return { recommendedCommand };
351
+ }
352
+ function validateChangeImpactConfig(raw, source = "inline") {
353
+ const errors = [];
354
+ if (!isRecord(raw)) {
355
+ return { valid: false, errors: [`${source}: config must be an object`] };
356
+ }
357
+ const config = {};
358
+ if (raw.daemonRuntimePackages !== void 0) {
359
+ if (isStringArray(raw.daemonRuntimePackages)) config.daemonRuntimePackages = [...raw.daemonRuntimePackages];
360
+ else errors.push("daemonRuntimePackages must be an array of non-empty strings");
361
+ }
362
+ if (raw.webOnlyPackages !== void 0) {
363
+ if (isStringArray(raw.webOnlyPackages)) config.webOnlyPackages = [...raw.webOnlyPackages];
364
+ else errors.push("webOnlyPackages must be an array of non-empty strings");
365
+ }
366
+ if (raw.nonRuntimeRootFilePatterns !== void 0) {
367
+ if (isStringArray(raw.nonRuntimeRootFilePatterns)) config.nonRuntimeRootFilePatterns = [...raw.nonRuntimeRootFilePatterns];
368
+ else errors.push("nonRuntimeRootFilePatterns must be an array of non-empty strings");
369
+ }
370
+ if (raw.impactTargets !== void 0) {
371
+ if (!isRecord(raw.impactTargets)) {
372
+ errors.push("impactTargets must be an object");
373
+ } else {
374
+ const targets = {};
375
+ for (const key of Object.keys(raw.impactTargets)) {
376
+ if (key !== "daemon" && key !== "web" && key !== "none") {
377
+ errors.push(`impactTargets.${key} is not a recognized impact kind (daemon|web|none)`);
378
+ continue;
379
+ }
380
+ const target = validateTarget(raw.impactTargets[key], key, errors);
381
+ if (target) targets[key] = target;
382
+ }
383
+ if (Object.keys(targets).length) config.impactTargets = targets;
384
+ }
385
+ }
386
+ for (const key of Object.keys(raw)) {
387
+ if (!["daemonRuntimePackages", "webOnlyPackages", "nonRuntimeRootFilePatterns", "impactTargets"].includes(key)) {
388
+ errors.push(`unknown config key '${key}'`);
389
+ }
390
+ }
391
+ return { valid: errors.length === 0, errors, config: errors.length === 0 ? config : void 0 };
392
+ }
393
+ function parseConfigText(path42, text) {
394
+ if (/\.json$/i.test(path42)) return JSON.parse(text);
395
+ return yaml.load(text);
396
+ }
397
+ function loadChangeImpactConfig(repoRoot) {
398
+ for (const relative5 of CHANGE_IMPACT_CONFIG_LOCATIONS) {
399
+ const configPath = (0, import_path.join)(repoRoot, relative5);
400
+ if (!(0, import_fs.existsSync)(configPath)) continue;
401
+ try {
402
+ const text = (0, import_fs.readFileSync)(configPath, "utf-8");
403
+ let mtimeMs = 0;
404
+ try {
405
+ mtimeMs = (0, import_fs.statSync)(configPath).mtimeMs;
406
+ } catch {
407
+ mtimeMs = text.length;
408
+ }
409
+ const parsed = parseConfigText(configPath, text);
410
+ const validation = validateChangeImpactConfig(parsed, relative5);
411
+ if (!validation.valid) {
412
+ return {
413
+ source: relative5,
414
+ sourceType: "invalid",
415
+ path: configPath,
416
+ error: validation.errors.join("; "),
417
+ sourceKey: `invalid:${configPath}:${mtimeMs}`
418
+ };
419
+ }
420
+ return {
421
+ config: validation.config,
422
+ source: relative5,
423
+ sourceType: "repo_file",
424
+ path: configPath,
425
+ sourceKey: `file:${configPath}:${mtimeMs}`
426
+ };
427
+ } catch (error) {
428
+ return {
429
+ source: relative5,
430
+ sourceType: "invalid",
431
+ path: configPath,
432
+ error: error?.message || String(error),
433
+ sourceKey: `error:${configPath}`
434
+ };
435
+ }
436
+ }
437
+ return {
438
+ source: "unavailable",
439
+ sourceType: "unavailable",
440
+ error: `No change-impact config found. Checked: ${CHANGE_IMPACT_CONFIG_LOCATIONS.join(", ")}`,
441
+ sourceKey: "unavailable"
442
+ };
443
+ }
444
+ function globToRegExp(pattern) {
445
+ let out = "";
446
+ for (let i = 0; i < pattern.length; i++) {
447
+ const ch = pattern[i];
448
+ if (ch === "*") {
449
+ if (pattern[i + 1] === "*") {
450
+ out += ".*";
451
+ i++;
452
+ if (pattern[i + 1] === "/") i++;
453
+ } else {
454
+ out += "[^/]*";
455
+ }
456
+ } else if (ch === "?") {
457
+ out += "[^/]";
458
+ } else if (".+^${}()|[]\\".includes(ch)) {
459
+ out += "\\" + ch;
460
+ } else {
461
+ out += ch;
462
+ }
463
+ }
464
+ return new RegExp(`^${out}$`);
465
+ }
466
+ function listPackageDirs(packagesRoot) {
467
+ try {
468
+ return (0, import_fs.readdirSync)(packagesRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
469
+ } catch {
470
+ return [];
471
+ }
472
+ }
473
+ function suggestChangeImpactConfig(repoRoot) {
474
+ const notes = [];
475
+ const daemon = /* @__PURE__ */ new Set();
476
+ const web = /* @__PURE__ */ new Set();
477
+ const unclassified = [];
478
+ const roots = ["packages", (0, import_path.join)("oss", "packages")];
479
+ for (const rel of roots) {
480
+ const packagesRoot = (0, import_path.join)(repoRoot, rel);
481
+ if (!(0, import_fs.existsSync)(packagesRoot)) continue;
482
+ for (const name of listPackageDirs(packagesRoot)) {
483
+ if (/(^web[-.]|[-.]web$)/i.test(name) || /dashboard|frontend|ui$/i.test(name)) {
484
+ web.add(name);
485
+ } else {
486
+ daemon.add(name);
487
+ }
488
+ }
489
+ }
490
+ const daemonRuntimePackages = [...daemon].sort();
491
+ const webOnlyPackages = [...web].sort();
492
+ if (!daemonRuntimePackages.length && !webOnlyPackages.length) {
493
+ notes.push("No packages/ or oss/packages/ directories found \u2014 defaulting to an empty draft you should fill in by hand.");
494
+ } else {
495
+ if (daemonRuntimePackages.length) notes.push(`Classified ${daemonRuntimePackages.length} package(s) as daemon-runtime (change \u2192 rebuild/redeploy + restart).`);
496
+ if (webOnlyPackages.length) notes.push(`Classified ${webOnlyPackages.length} web-* package(s) as web-only (change \u2192 web redeploy, no daemon restart).`);
497
+ notes.push("Heuristic only: confirm each package actually matches its bucket before saving.");
498
+ }
499
+ const nonRuntimeRootFilePatterns = [
500
+ "*.md",
501
+ "docs/**",
502
+ "LICENSE",
503
+ "LICENSE.*",
504
+ ".gitignore"
505
+ ];
506
+ notes.push("nonRuntimeRootFilePatterns lists root files that demonstrably cannot change daemon runtime behavior; extend with your repo markers.");
507
+ const suggestedConfig = {
508
+ ...daemonRuntimePackages.length ? { daemonRuntimePackages } : {},
509
+ ...webOnlyPackages.length ? { webOnlyPackages } : {},
510
+ nonRuntimeRootFilePatterns,
511
+ impactTargets: {
512
+ daemon: { recommendedCommand: "rebuild + redeploy the daemon, then restart it" },
513
+ web: { recommendedCommand: "redeploy the web app (no daemon restart required)" },
514
+ none: { recommendedCommand: "no action required" }
515
+ }
516
+ };
517
+ return {
518
+ suggestedConfig,
519
+ notes,
520
+ discoveredPackages: { daemon: daemonRuntimePackages, web: webOnlyPackages, unclassified }
521
+ };
522
+ }
523
+ var import_fs, import_path, yaml, CHANGE_IMPACT_CONFIG_LOCATIONS, CHANGE_IMPACT_CONFIG_SCHEMA;
524
+ var init_change_impact_config = __esm({
525
+ "src/git/change-impact-config.ts"() {
526
+ "use strict";
527
+ import_fs = require("fs");
528
+ import_path = require("path");
529
+ yaml = __toESM(require("js-yaml"));
530
+ CHANGE_IMPACT_CONFIG_LOCATIONS = [
531
+ ".adhdev/change-impact.json",
532
+ ".adhdev/change-impact.yaml",
533
+ ".adhdev/change-impact.yml",
534
+ ".adhdev/repo-mesh-change-impact.json",
535
+ ".adhdev/repo-mesh-change-impact.yaml",
536
+ ".adhdev/repo-mesh-change-impact.yml"
537
+ ];
538
+ CHANGE_IMPACT_CONFIG_SCHEMA = {
539
+ $schema: "https://json-schema.org/draft/2020-12/schema",
540
+ title: "ADHDev Change Impact Config",
541
+ type: "object",
542
+ additionalProperties: false,
543
+ properties: {
544
+ daemonRuntimePackages: { type: "array", items: { type: "string", minLength: 1 } },
545
+ webOnlyPackages: { type: "array", items: { type: "string", minLength: 1 } },
546
+ nonRuntimeRootFilePatterns: { type: "array", items: { type: "string", minLength: 1 } },
547
+ impactTargets: {
548
+ type: "object",
549
+ additionalProperties: false,
550
+ properties: {
551
+ daemon: { $ref: "#/$defs/target" },
552
+ web: { $ref: "#/$defs/target" },
553
+ none: { $ref: "#/$defs/target" }
554
+ }
555
+ }
556
+ },
557
+ $defs: {
558
+ target: {
559
+ type: "object",
560
+ additionalProperties: false,
561
+ required: ["recommendedCommand"],
562
+ properties: {
563
+ recommendedCommand: { type: "string", minLength: 1 }
564
+ }
565
+ }
566
+ }
567
+ };
568
+ }
569
+ });
570
+
330
571
  // src/git/git-status.ts
331
572
  function isTransientGitFailure(error) {
332
573
  return error.reason === "timeout" || error.reason === "git_command_failed";
@@ -402,16 +643,34 @@ async function collectGitRepoStatus(repo, includeSubmodules, lastCheckedAt, opti
402
643
  ...daemonBuildBehind ? { daemonBuildBehind } : {}
403
644
  };
404
645
  }
405
- function isNonRuntimeRootFile(file) {
646
+ function resolveChangeImpactPolicy(config) {
647
+ const daemonRuntimePackages = new Set(
648
+ config?.daemonRuntimePackages && config.daemonRuntimePackages.length ? config.daemonRuntimePackages : DEFAULT_DAEMON_RUNTIME_PACKAGES
649
+ );
650
+ const webOnlyPackages = new Set(
651
+ config?.webOnlyPackages && config.webOnlyPackages.length ? config.webOnlyPackages : DEFAULT_WEB_ONLY_PACKAGES
652
+ );
653
+ const nonRuntimeRootFilePatterns = (config?.nonRuntimeRootFilePatterns || []).map(globToRegExp);
654
+ const impactTargets = {
655
+ daemon: config?.impactTargets?.daemon ?? DEFAULT_IMPACT_TARGETS.daemon,
656
+ web: config?.impactTargets?.web ?? DEFAULT_IMPACT_TARGETS.web,
657
+ none: config?.impactTargets?.none ?? DEFAULT_IMPACT_TARGETS.none
658
+ };
659
+ return { daemonRuntimePackages, webOnlyPackages, nonRuntimeRootFilePatterns, impactTargets };
660
+ }
661
+ function isNonRuntimeRootFile(file, policy) {
406
662
  const base = file.slice(file.lastIndexOf("/") + 1);
407
663
  if (/^\.(?:verify|marker|converge|ff-verify|patch-equiv|live-verify)\b/i.test(base)) return true;
408
664
  if (/(?:^|\/)docs\//i.test(file)) return true;
409
665
  if (/^(?:README|CHANGELOG|LICENSE|NOTICE|AUTHORS|CONTRIBUTING|CODEOWNERS)(?:\.[A-Za-z0-9]+)?$/i.test(base)) {
410
666
  return true;
411
667
  }
668
+ for (const re of policy.nonRuntimeRootFilePatterns) {
669
+ if (re.test(file)) return true;
670
+ }
412
671
  return false;
413
672
  }
414
- async function classifyDaemonBuildChange(repoPath, buildCommit, options) {
673
+ async function classifyDaemonBuildChange(repoPath, buildCommit, options, policy) {
415
674
  try {
416
675
  const diff = await runGit(repoPath, ["diff", "--name-only", `${buildCommit}..HEAD`], options);
417
676
  const files = diff.stdout.split("\n").map((line) => line.trim()).filter(Boolean);
@@ -423,21 +682,47 @@ async function classifyDaemonBuildChange(repoPath, buildCommit, options) {
423
682
  for (const file of files) {
424
683
  const match = file.match(/(?:^|\/)packages\/([^/]+)\//);
425
684
  if (!match) {
426
- if (!isNonRuntimeRootFile(file)) sawRuntimeAmbiguousNonPackage = true;
685
+ if (!isNonRuntimeRootFile(file, policy)) sawRuntimeAmbiguousNonPackage = true;
427
686
  continue;
428
687
  }
429
688
  pkgs.add(match[1]);
430
689
  }
431
690
  const affectedPackages = [...pkgs].sort();
432
- const allBenign = !sawRuntimeAmbiguousNonPackage && affectedPackages.every((p) => WEB_ONLY_PACKAGES.has(p) && !DAEMON_RUNTIME_PACKAGES.has(p));
691
+ const allBenign = !sawRuntimeAmbiguousNonPackage && affectedPackages.every((p) => policy.webOnlyPackages.has(p) && !policy.daemonRuntimePackages.has(p));
433
692
  return { isDaemonAffecting: !allBenign, affectedPackages };
434
693
  } catch {
435
694
  return { isDaemonAffecting: true, affectedPackages: [] };
436
695
  }
437
696
  }
697
+ function resolveChangeImpactConfigForRepo(repoRoot, options) {
698
+ if (options.changeImpactConfig === null) {
699
+ return { config: null, sourceKey: "forced-default" };
700
+ }
701
+ if (options.changeImpactConfig !== void 0) {
702
+ let key = "injected";
703
+ try {
704
+ key = `injected:${JSON.stringify(options.changeImpactConfig)}`;
705
+ } catch {
706
+ }
707
+ return { config: options.changeImpactConfig, sourceKey: key };
708
+ }
709
+ if (!repoRoot) {
710
+ return { config: null, sourceKey: "no-repo-root" };
711
+ }
712
+ const loaded = loadChangeImpactConfig(repoRoot);
713
+ const cached2 = changeImpactConfigCache.get(repoRoot);
714
+ if (cached2 && cached2.sourceKey === loaded.sourceKey) {
715
+ return { config: cached2.config, sourceKey: loaded.sourceKey };
716
+ }
717
+ const config = loaded.sourceType === "repo_file" ? loaded.config ?? null : null;
718
+ changeImpactConfigCache.set(repoRoot, { sourceKey: loaded.sourceKey, config });
719
+ return { config, sourceKey: loaded.sourceKey };
720
+ }
438
721
  async function detectDaemonBuildBehind(repo, submodules, options) {
439
722
  const build = options.daemonBuildInfo ?? getDaemonBuildInfo();
440
723
  if (!build.commit || build.commit === "unknown") return void 0;
724
+ const { config, sourceKey: configKey } = resolveChangeImpactConfigForRepo(repo.repoRoot, options);
725
+ const policy = resolveChangeImpactPolicy(config);
441
726
  const scopes = [
442
727
  { scope: "root", repoPath: repo.repoRoot || repo.workspace }
443
728
  ];
@@ -451,11 +736,15 @@ async function detectDaemonBuildBehind(repo, submodules, options) {
451
736
  const head = headResult.stdout.trim();
452
737
  if (!head || head === build.commit) continue;
453
738
  await runGit(repoPath, ["merge-base", "--is-ancestor", build.commit, "HEAD"], options);
454
- const { isDaemonAffecting, affectedPackages } = await classifyDaemonBuildChange(
455
- repoPath,
456
- build.commit,
457
- options
458
- );
739
+ const evalKey = `${repoPath}\0${build.commit}\0${head}\0${configKey}`;
740
+ let evaluated = changeImpactEvalCache.get(evalKey);
741
+ if (!evaluated) {
742
+ evaluated = await classifyDaemonBuildChange(repoPath, build.commit, options, policy);
743
+ changeImpactEvalCache.set(evalKey, evaluated);
744
+ }
745
+ const { isDaemonAffecting, affectedPackages } = evaluated;
746
+ const kind = isDaemonAffecting ? "daemon" : affectedPackages.length > 0 ? "web" : "none";
747
+ const target = policy.impactTargets[kind];
459
748
  const scopeLabel = scope === "root" ? "workspace" : scope;
460
749
  const benignDetail = affectedPackages.length > 0 ? `only web packages changed (${affectedPackages.join(", ")})` : "only non-runtime files changed (markers/docs)";
461
750
  const warning = isDaemonAffecting ? `Live daemon was built from ${build.commitShort} which is behind ${scopeLabel} HEAD ${head.slice(0, 7)}. Merged code is NOT live until the daemon is rebuilt/redeployed and restarted \u2014 a local dist rebuild alone does not update a cloud daemon.` : `Live daemon was built from ${build.commitShort} which is behind ${scopeLabel} HEAD ${head.slice(0, 7)}, but ${benignDetail}. Daemon restart NOT required \u2014 redeploy the web app to reflect the change.`;
@@ -466,6 +755,8 @@ async function detectDaemonBuildBehind(repo, submodules, options) {
466
755
  scope,
467
756
  isDaemonAffecting,
468
757
  ...affectedPackages && affectedPackages.length > 0 ? { affectedPackages } : {},
758
+ recommendedAction: kind,
759
+ recommendedCommand: target.recommendedCommand,
469
760
  warning
470
761
  };
471
762
  } catch {
@@ -729,14 +1020,17 @@ async function enrichSubmoduleWorktreeStatus(repo, submodule, options) {
729
1020
  submodule.error = formatGitError(error);
730
1021
  }
731
1022
  }
732
- var lastKnownGoodStatus, DAEMON_RUNTIME_PACKAGES, WEB_ONLY_PACKAGES;
1023
+ var lastKnownGoodStatus, changeImpactEvalCache, changeImpactConfigCache, DEFAULT_DAEMON_RUNTIME_PACKAGES, DEFAULT_WEB_ONLY_PACKAGES, DEFAULT_IMPACT_TARGETS;
733
1024
  var init_git_status = __esm({
734
1025
  "src/git/git-status.ts"() {
735
1026
  "use strict";
736
1027
  init_git_executor();
737
1028
  init_build_info();
1029
+ init_change_impact_config();
738
1030
  lastKnownGoodStatus = /* @__PURE__ */ new Map();
739
- DAEMON_RUNTIME_PACKAGES = /* @__PURE__ */ new Set([
1031
+ changeImpactEvalCache = /* @__PURE__ */ new Map();
1032
+ changeImpactConfigCache = /* @__PURE__ */ new Map();
1033
+ DEFAULT_DAEMON_RUNTIME_PACKAGES = [
740
1034
  "daemon-core",
741
1035
  "daemon-standalone",
742
1036
  "session-host-core",
@@ -746,13 +1040,24 @@ var init_git_status = __esm({
746
1040
  "terminal-mux-cli",
747
1041
  "ghostty-vt-node",
748
1042
  "mcp-server"
749
- ]);
750
- WEB_ONLY_PACKAGES = /* @__PURE__ */ new Set([
1043
+ ];
1044
+ DEFAULT_WEB_ONLY_PACKAGES = [
751
1045
  "web-core",
752
1046
  "web-standalone",
753
1047
  "web-devconsole",
754
1048
  "terminal-render-web"
755
- ]);
1049
+ ];
1050
+ DEFAULT_IMPACT_TARGETS = {
1051
+ daemon: {
1052
+ recommendedCommand: "Redeploy + restart the daemon (a local dist rebuild alone does not update a cloud daemon)."
1053
+ },
1054
+ web: {
1055
+ recommendedCommand: "Redeploy the web app (no daemon restart required)."
1056
+ },
1057
+ none: {
1058
+ recommendedCommand: "No action required."
1059
+ }
1060
+ };
756
1061
  }
757
1062
  });
758
1063
 
@@ -1311,25 +1616,25 @@ function ensureMachineId(config) {
1311
1616
  }
1312
1617
  function getConfigDir() {
1313
1618
  const override = process.env.ADHDEV_CONFIG_DIR;
1314
- const dir = override && override.trim() ? override.trim() : (0, import_path.join)((0, import_os.homedir)(), ".adhdev");
1315
- if (!(0, import_fs.existsSync)(dir)) {
1316
- (0, import_fs.mkdirSync)(dir, { recursive: true });
1619
+ const dir = override && override.trim() ? override.trim() : (0, import_path2.join)((0, import_os.homedir)(), ".adhdev");
1620
+ if (!(0, import_fs2.existsSync)(dir)) {
1621
+ (0, import_fs2.mkdirSync)(dir, { recursive: true });
1317
1622
  }
1318
1623
  return dir;
1319
1624
  }
1320
1625
  function getDaemonDataDir() {
1321
- const dir = (0, import_path.join)(getConfigDir(), "daemon");
1322
- if (!(0, import_fs.existsSync)(dir)) {
1323
- (0, import_fs.mkdirSync)(dir, { recursive: true });
1626
+ const dir = (0, import_path2.join)(getConfigDir(), "daemon");
1627
+ if (!(0, import_fs2.existsSync)(dir)) {
1628
+ (0, import_fs2.mkdirSync)(dir, { recursive: true });
1324
1629
  }
1325
1630
  return dir;
1326
1631
  }
1327
1632
  function getConfigPath() {
1328
- return (0, import_path.join)(getConfigDir(), "config.json");
1633
+ return (0, import_path2.join)(getConfigDir(), "config.json");
1329
1634
  }
1330
1635
  function migrateStateToStateFile(raw) {
1331
- const statePath = (0, import_path.join)(getConfigDir(), "state.json");
1332
- if ((0, import_fs.existsSync)(statePath)) return;
1636
+ const statePath = (0, import_path2.join)(getConfigDir(), "state.json");
1637
+ if ((0, import_fs2.existsSync)(statePath)) return;
1333
1638
  const recentActivity = Array.isArray(raw.recentActivity) ? raw.recentActivity : [];
1334
1639
  const savedProviderSessions = Array.isArray(raw.savedProviderSessions) ? raw.savedProviderSessions : [];
1335
1640
  const legacySessionReads = isPlainObject(raw.recentSessionReads) ? raw.recentSessionReads : {};
@@ -1349,11 +1654,11 @@ function migrateStateToStateFile(raw) {
1349
1654
  sessionReads: mergedReads,
1350
1655
  sessionReadMarkers: cleanedMarkers
1351
1656
  };
1352
- (0, import_fs.writeFileSync)(statePath, JSON.stringify(state, null, 2), { encoding: "utf-8", mode: 384 });
1657
+ (0, import_fs2.writeFileSync)(statePath, JSON.stringify(state, null, 2), { encoding: "utf-8", mode: 384 });
1353
1658
  }
1354
1659
  function loadConfig() {
1355
1660
  const configPath = getConfigPath();
1356
- if (!(0, import_fs.existsSync)(configPath)) {
1661
+ if (!(0, import_fs2.existsSync)(configPath)) {
1357
1662
  const initialized = ensureMachineId({ ...DEFAULT_CONFIG });
1358
1663
  try {
1359
1664
  saveConfig(initialized.config);
@@ -1362,7 +1667,7 @@ function loadConfig() {
1362
1667
  return initialized.config;
1363
1668
  }
1364
1669
  try {
1365
- const raw = (0, import_fs.readFileSync)(configPath, "utf-8");
1670
+ const raw = (0, import_fs2.readFileSync)(configPath, "utf-8");
1366
1671
  const parsed = JSON.parse(raw);
1367
1672
  migrateStateToStateFile(parsed);
1368
1673
  const normalizedInput = normalizeConfig(parsed);
@@ -1384,12 +1689,12 @@ function saveConfig(config) {
1384
1689
  const configPath = getConfigPath();
1385
1690
  const dir = getConfigDir();
1386
1691
  const normalized = normalizeConfig(config);
1387
- if (!(0, import_fs.existsSync)(dir)) {
1388
- (0, import_fs.mkdirSync)(dir, { recursive: true, mode: 448 });
1692
+ if (!(0, import_fs2.existsSync)(dir)) {
1693
+ (0, import_fs2.mkdirSync)(dir, { recursive: true, mode: 448 });
1389
1694
  }
1390
- (0, import_fs.writeFileSync)(configPath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
1695
+ (0, import_fs2.writeFileSync)(configPath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
1391
1696
  try {
1392
- (0, import_fs.chmodSync)(configPath, 384);
1697
+ (0, import_fs2.chmodSync)(configPath, 384);
1393
1698
  } catch {
1394
1699
  }
1395
1700
  }
@@ -1416,13 +1721,13 @@ function isSetupComplete() {
1416
1721
  function resetConfig() {
1417
1722
  saveConfig({ ...DEFAULT_CONFIG });
1418
1723
  }
1419
- var import_os, import_path, import_fs, import_crypto, DEFAULT_CONFIG, MACHINE_ID_PREFIX;
1724
+ var import_os, import_path2, import_fs2, import_crypto, DEFAULT_CONFIG, MACHINE_ID_PREFIX;
1420
1725
  var init_config = __esm({
1421
1726
  "src/config/config.ts"() {
1422
1727
  "use strict";
1423
1728
  import_os = require("os");
1424
- import_path = require("path");
1425
- import_fs = require("fs");
1729
+ import_path2 = require("path");
1730
+ import_fs2 = require("fs");
1426
1731
  import_crypto = require("crypto");
1427
1732
  DEFAULT_CONFIG = {
1428
1733
  serverUrl: "https://api.adhf.dev",
@@ -1541,13 +1846,13 @@ __export(mesh_config_exports, {
1541
1846
  updateNode: () => updateNode
1542
1847
  });
1543
1848
  function getMeshConfigPath() {
1544
- return (0, import_path2.join)(getConfigDir(), "meshes.json");
1849
+ return (0, import_path3.join)(getConfigDir(), "meshes.json");
1545
1850
  }
1546
1851
  function loadMeshConfig() {
1547
1852
  const path42 = getMeshConfigPath();
1548
- if (!(0, import_fs2.existsSync)(path42)) return { meshes: [] };
1853
+ if (!(0, import_fs3.existsSync)(path42)) return { meshes: [] };
1549
1854
  try {
1550
- const raw = JSON.parse((0, import_fs2.readFileSync)(path42, "utf-8"));
1855
+ const raw = JSON.parse((0, import_fs3.readFileSync)(path42, "utf-8"));
1551
1856
  if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
1552
1857
  const config = raw;
1553
1858
  const migrated = migrateLoadedMeshConfig(config);
@@ -1597,7 +1902,7 @@ function normalizeCapabilityTags(value) {
1597
1902
  }
1598
1903
  function saveMeshConfig(config) {
1599
1904
  const path42 = getMeshConfigPath();
1600
- (0, import_fs2.writeFileSync)(path42, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
1905
+ (0, import_fs3.writeFileSync)(path42, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
1601
1906
  }
1602
1907
  function normalizeRepoIdentity(remoteUrl) {
1603
1908
  let identity = remoteUrl.trim();
@@ -1957,12 +2262,12 @@ function updateNode(meshId, nodeId, opts) {
1957
2262
  saveMeshConfig(config);
1958
2263
  return node;
1959
2264
  }
1960
- var import_fs2, import_path2, import_crypto3, SESSION_CLEANUP_MODES, SPAWNED_SESSION_VISIBILITY_MODES;
2265
+ var import_fs3, import_path3, import_crypto3, SESSION_CLEANUP_MODES, SPAWNED_SESSION_VISIBILITY_MODES;
1961
2266
  var init_mesh_config = __esm({
1962
2267
  "src/config/mesh-config.ts"() {
1963
2268
  "use strict";
1964
- import_fs2 = require("fs");
1965
- import_path2 = require("path");
2269
+ import_fs3 = require("fs");
2270
+ import_path3 = require("path");
1966
2271
  import_crypto3 = require("crypto");
1967
2272
  init_config();
1968
2273
  init_repo_mesh_types();
@@ -2259,41 +2564,41 @@ function isIntentionalCleanupStopEntry(entry) {
2259
2564
  return payload.intentional === true && (payload.reason === "operator_cleanup" || payload.intentionalStopReason === "operator_cleanup" || payload.source === "mesh_cleanup_sessions" || payload.source === "mesh_remove_node");
2260
2565
  }
2261
2566
  function getLedgerDir() {
2262
- const dir = (0, import_path3.join)(getConfigDir(), LEDGER_DIR_NAME);
2263
- if (!(0, import_fs3.existsSync)(dir)) {
2264
- (0, import_fs3.mkdirSync)(dir, { recursive: true, mode: 448 });
2567
+ const dir = (0, import_path4.join)(getConfigDir(), LEDGER_DIR_NAME);
2568
+ if (!(0, import_fs4.existsSync)(dir)) {
2569
+ (0, import_fs4.mkdirSync)(dir, { recursive: true, mode: 448 });
2265
2570
  }
2266
2571
  return dir;
2267
2572
  }
2268
2573
  function getLedgerPath(meshId) {
2269
2574
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
2270
- return (0, import_path3.join)(getLedgerDir(), `${safe}.jsonl`);
2575
+ return (0, import_path4.join)(getLedgerDir(), `${safe}.jsonl`);
2271
2576
  }
2272
2577
  function getRotatedPath(meshId, index) {
2273
2578
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
2274
- return (0, import_path3.join)(getLedgerDir(), `${safe}.${index}.jsonl`);
2579
+ return (0, import_path4.join)(getLedgerDir(), `${safe}.${index}.jsonl`);
2275
2580
  }
2276
2581
  function getArchivePath(meshId) {
2277
2582
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
2278
- return (0, import_path3.join)(getLedgerDir(), `${safe}.archive.jsonl`);
2583
+ return (0, import_path4.join)(getLedgerDir(), `${safe}.archive.jsonl`);
2279
2584
  }
2280
2585
  function getRotatedArchivePath(meshId, index) {
2281
2586
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
2282
- return (0, import_path3.join)(getLedgerDir(), `${safe}.archive.${index}.jsonl`);
2587
+ return (0, import_path4.join)(getLedgerDir(), `${safe}.archive.${index}.jsonl`);
2283
2588
  }
2284
2589
  function getArchivedCountsPath(meshId) {
2285
2590
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
2286
- return (0, import_path3.join)(getLedgerDir(), `${safe}.archived-counts.json`);
2591
+ return (0, import_path4.join)(getLedgerDir(), `${safe}.archived-counts.json`);
2287
2592
  }
2288
2593
  function rotateArchiveFile(meshId, archivePath) {
2289
2594
  let index = 1;
2290
- while ((0, import_fs3.existsSync)(getRotatedArchivePath(meshId, index))) {
2595
+ while ((0, import_fs4.existsSync)(getRotatedArchivePath(meshId, index))) {
2291
2596
  index++;
2292
2597
  if (index > 5) break;
2293
2598
  }
2294
2599
  if (index > 5) index = 5;
2295
2600
  try {
2296
- (0, import_fs3.renameSync)(archivePath, getRotatedArchivePath(meshId, index));
2601
+ (0, import_fs4.renameSync)(archivePath, getRotatedArchivePath(meshId, index));
2297
2602
  } catch (e) {
2298
2603
  process.stderr.write(`[adhdev-mesh] Archive rotation failed for mesh ${meshId}: ${e?.message || e}
2299
2604
  `);
@@ -2301,9 +2606,9 @@ function rotateArchiveFile(meshId, archivePath) {
2301
2606
  }
2302
2607
  function readArchivedCounts(meshId) {
2303
2608
  const path42 = getArchivedCountsPath(meshId);
2304
- if (!(0, import_fs3.existsSync)(path42)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
2609
+ if (!(0, import_fs4.existsSync)(path42)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
2305
2610
  try {
2306
- return JSON.parse((0, import_fs3.readFileSync)(path42, "utf-8"));
2611
+ return JSON.parse((0, import_fs4.readFileSync)(path42, "utf-8"));
2307
2612
  } catch {
2308
2613
  return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
2309
2614
  }
@@ -2319,7 +2624,7 @@ function updateArchivedCounts(meshId, archived) {
2319
2624
  counts.totalArchived += archived.length;
2320
2625
  counts.lastArchivedAt = (/* @__PURE__ */ new Date()).toISOString();
2321
2626
  try {
2322
- (0, import_fs3.writeFileSync)(getArchivedCountsPath(meshId), JSON.stringify(counts), { encoding: "utf-8", mode: 384 });
2627
+ (0, import_fs4.writeFileSync)(getArchivedCountsPath(meshId), JSON.stringify(counts), { encoding: "utf-8", mode: 384 });
2323
2628
  } catch {
2324
2629
  }
2325
2630
  }
@@ -2342,7 +2647,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
2342
2647
  }
2343
2648
  function compactLedger(meshId) {
2344
2649
  const filePath = getLedgerPath(meshId);
2345
- if (!(0, import_fs3.existsSync)(filePath)) return { archivedCount: 0, retainedCount: 0 };
2650
+ if (!(0, import_fs4.existsSync)(filePath)) return { archivedCount: 0, retainedCount: 0 };
2346
2651
  const cutoff = Date.now() - ARCHIVE_TERMINAL_OLDER_THAN_MS;
2347
2652
  const entries = readLedgerEntries(meshId);
2348
2653
  const keep = [];
@@ -2357,11 +2662,11 @@ function compactLedger(meshId) {
2357
2662
  if (archive.length === 0) return { archivedCount: 0, retainedCount: keep.length };
2358
2663
  const archivePath = getArchivePath(meshId);
2359
2664
  try {
2360
- if ((0, import_fs3.existsSync)(archivePath) && (0, import_fs3.statSync)(archivePath).size > 50 * 1024 * 1024) {
2665
+ if ((0, import_fs4.existsSync)(archivePath) && (0, import_fs4.statSync)(archivePath).size > 50 * 1024 * 1024) {
2361
2666
  rotateArchiveFile(meshId, archivePath);
2362
2667
  }
2363
2668
  const archiveLines = archive.map((e) => JSON.stringify(e)).join("\n") + "\n";
2364
- (0, import_fs3.appendFileSync)(archivePath, archiveLines, { encoding: "utf-8", mode: 384 });
2669
+ (0, import_fs4.appendFileSync)(archivePath, archiveLines, { encoding: "utf-8", mode: 384 });
2365
2670
  updateArchivedCounts(meshId, archive);
2366
2671
  } catch (e) {
2367
2672
  process.stderr.write(`[adhdev-mesh] Ledger archive write failed for mesh ${meshId}: ${e?.message || e}
@@ -2370,7 +2675,7 @@ function compactLedger(meshId) {
2370
2675
  }
2371
2676
  try {
2372
2677
  const keepLines = keep.length ? keep.map((e) => JSON.stringify(e)).join("\n") + "\n" : "";
2373
- (0, import_fs3.writeFileSync)(filePath, keepLines, { encoding: "utf-8", mode: 384 });
2678
+ (0, import_fs4.writeFileSync)(filePath, keepLines, { encoding: "utf-8", mode: 384 });
2374
2679
  invalidateLedgerCache(meshId);
2375
2680
  } catch (e) {
2376
2681
  process.stderr.write(`[adhdev-mesh] Ledger compaction rewrite failed for mesh ${meshId}: ${e?.message || e}
@@ -2507,9 +2812,9 @@ function appendLedgerEntry(meshId, partial) {
2507
2812
  ...partial
2508
2813
  };
2509
2814
  const filePath = getLedgerPath(meshId);
2510
- if ((0, import_fs3.existsSync)(filePath)) {
2815
+ if ((0, import_fs4.existsSync)(filePath)) {
2511
2816
  try {
2512
- const stat2 = (0, import_fs3.statSync)(filePath);
2817
+ const stat2 = (0, import_fs4.statSync)(filePath);
2513
2818
  if (stat2.size >= MAX_FILE_SIZE_BYTES) {
2514
2819
  rotateLedgerFile(meshId, filePath);
2515
2820
  } else if (stat2.size >= COMPACT_THRESHOLD_BYTES) {
@@ -2534,7 +2839,7 @@ function appendLedgerEntry(meshId, partial) {
2534
2839
  }
2535
2840
  try {
2536
2841
  const line = JSON.stringify(entry) + "\n";
2537
- (0, import_fs3.appendFileSync)(filePath, line, { encoding: "utf-8", mode: 384 });
2842
+ (0, import_fs4.appendFileSync)(filePath, line, { encoding: "utf-8", mode: 384 });
2538
2843
  invalidateLedgerCache(meshId);
2539
2844
  meshLedgerEvents.emit("append", meshId, entry);
2540
2845
  return entry;
@@ -2593,7 +2898,7 @@ function appendRemoteLedgerEntries(meshId, entries) {
2593
2898
  }
2594
2899
  try {
2595
2900
  const lines = validEntries.map((e) => JSON.stringify(e)).join("\n") + "\n";
2596
- (0, import_fs3.appendFileSync)(ledgerPath, lines, { encoding: "utf-8", mode: 384 });
2901
+ (0, import_fs4.appendFileSync)(ledgerPath, lines, { encoding: "utf-8", mode: 384 });
2597
2902
  invalidateLedgerCache(meshId);
2598
2903
  for (const entry of validEntries) {
2599
2904
  meshLedgerEvents.emit("append", meshId, entry);
@@ -2605,10 +2910,10 @@ function appendRemoteLedgerEntries(meshId, entries) {
2605
2910
  }
2606
2911
  function readLedgerFile(meshId) {
2607
2912
  const filePath = getLedgerPath(meshId);
2608
- if (!(0, import_fs3.existsSync)(filePath)) return [];
2913
+ if (!(0, import_fs4.existsSync)(filePath)) return [];
2609
2914
  let content;
2610
2915
  try {
2611
- content = (0, import_fs3.readFileSync)(filePath, "utf-8");
2916
+ content = (0, import_fs4.readFileSync)(filePath, "utf-8");
2612
2917
  } catch {
2613
2918
  return [];
2614
2919
  }
@@ -2869,24 +3174,24 @@ function getSessionRecoveryContext(meshId, opts) {
2869
3174
  }
2870
3175
  function rotateLedgerFile(meshId, currentPath) {
2871
3176
  let index = 1;
2872
- while ((0, import_fs3.existsSync)(getRotatedPath(meshId, index))) {
3177
+ while ((0, import_fs4.existsSync)(getRotatedPath(meshId, index))) {
2873
3178
  index++;
2874
3179
  if (index > 10) break;
2875
3180
  }
2876
3181
  if (index > 10) index = 10;
2877
3182
  try {
2878
- (0, import_fs3.renameSync)(currentPath, getRotatedPath(meshId, index));
3183
+ (0, import_fs4.renameSync)(currentPath, getRotatedPath(meshId, index));
2879
3184
  } catch (e) {
2880
3185
  process.stderr.write(`[adhdev-mesh] Ledger rotation failed for mesh ${meshId}: ${e?.message || e}. File will continue to grow.
2881
3186
  `);
2882
3187
  }
2883
3188
  }
2884
- var import_fs3, import_path3, import_crypto4, import_events, LEDGER_DIR_NAME, MAX_FILE_SIZE_BYTES, COMPACT_THRESHOLD_BYTES, ARCHIVE_TERMINAL_OLDER_THAN_MS, RECENT_FAILURE_WINDOW_MS, ARCHIVABLE_KINDS, DEFAULT_LEDGER_SLICE_LIMIT, MAX_LEDGER_SLICE_LIMIT, meshLedgerEvents, ledgerReadCache, LEDGER_CACHE_TTL_MS, ledgerImportStoreRef, ledgerImportDone;
3189
+ var import_fs4, import_path4, import_crypto4, import_events, LEDGER_DIR_NAME, MAX_FILE_SIZE_BYTES, COMPACT_THRESHOLD_BYTES, ARCHIVE_TERMINAL_OLDER_THAN_MS, RECENT_FAILURE_WINDOW_MS, ARCHIVABLE_KINDS, DEFAULT_LEDGER_SLICE_LIMIT, MAX_LEDGER_SLICE_LIMIT, meshLedgerEvents, ledgerReadCache, LEDGER_CACHE_TTL_MS, ledgerImportStoreRef, ledgerImportDone;
2885
3190
  var init_mesh_ledger = __esm({
2886
3191
  "src/mesh/mesh-ledger.ts"() {
2887
3192
  "use strict";
2888
- import_fs3 = require("fs");
2889
- import_path3 = require("path");
3193
+ import_fs4 = require("fs");
3194
+ import_path4 = require("path");
2890
3195
  import_crypto4 = require("crypto");
2891
3196
  init_config();
2892
3197
  import_events = require("events");
@@ -3554,32 +3859,32 @@ function safeMeshId(meshId) {
3554
3859
  return meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
3555
3860
  }
3556
3861
  function legacyQueuePath(meshId) {
3557
- return (0, import_path4.join)(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
3862
+ return (0, import_path5.join)(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
3558
3863
  }
3559
3864
  function meshRuntimeStorePath() {
3560
3865
  const dir = getLedgerDir();
3561
- const nextPath = (0, import_path4.join)(dir, "mesh-runtime.db");
3562
- if ((0, import_fs4.existsSync)(nextPath)) return nextPath;
3563
- const legacyPath = (0, import_path4.join)(dir, "beads.db");
3564
- if (!(0, import_fs4.existsSync)(legacyPath)) return nextPath;
3866
+ const nextPath = (0, import_path5.join)(dir, "mesh-runtime.db");
3867
+ if ((0, import_fs5.existsSync)(nextPath)) return nextPath;
3868
+ const legacyPath = (0, import_path5.join)(dir, "beads.db");
3869
+ if (!(0, import_fs5.existsSync)(legacyPath)) return nextPath;
3565
3870
  try {
3566
- (0, import_fs4.renameSync)(legacyPath, nextPath);
3871
+ (0, import_fs5.renameSync)(legacyPath, nextPath);
3567
3872
  for (const suffix of ["-wal", "-shm"]) {
3568
3873
  const legacyCompanion = `${legacyPath}${suffix}`;
3569
- if ((0, import_fs4.existsSync)(legacyCompanion)) {
3570
- (0, import_fs4.renameSync)(legacyCompanion, `${nextPath}${suffix}`);
3874
+ if ((0, import_fs5.existsSync)(legacyCompanion)) {
3875
+ (0, import_fs5.renameSync)(legacyCompanion, `${nextPath}${suffix}`);
3571
3876
  }
3572
3877
  }
3573
3878
  } catch {
3574
3879
  }
3575
3880
  return nextPath;
3576
3881
  }
3577
- var import_fs4, import_path4, import_module, import_meta, DatabaseCtor, MeshRuntimeStore;
3882
+ var import_fs5, import_path5, import_module, import_meta, DatabaseCtor, MeshRuntimeStore;
3578
3883
  var init_mesh_runtime_store = __esm({
3579
3884
  "src/mesh/mesh-runtime-store.ts"() {
3580
3885
  "use strict";
3581
- import_fs4 = require("fs");
3582
- import_path4 = require("path");
3886
+ import_fs5 = require("fs");
3887
+ import_path5 = require("path");
3583
3888
  import_module = require("module");
3584
3889
  init_mesh_ledger();
3585
3890
  init_mesh_work_queue();
@@ -3595,8 +3900,8 @@ var init_mesh_runtime_store = __esm({
3595
3900
  static WAL_MAX_BYTES = 50 * 1024 * 1024;
3596
3901
  // 50 MB
3597
3902
  constructor(dbPath) {
3598
- const dir = (0, import_path4.dirname)(dbPath);
3599
- if (!(0, import_fs4.existsSync)(dir)) (0, import_fs4.mkdirSync)(dir, { recursive: true });
3903
+ const dir = (0, import_path5.dirname)(dbPath);
3904
+ if (!(0, import_fs5.existsSync)(dir)) (0, import_fs5.mkdirSync)(dir, { recursive: true });
3600
3905
  this.dbPath = dbPath;
3601
3906
  this.db = new (loadDatabaseCtor())(dbPath);
3602
3907
  this.db.pragma("journal_mode = WAL");
@@ -3851,8 +4156,8 @@ var init_mesh_runtime_store = __esm({
3851
4156
  this.walWriteCounter = 0;
3852
4157
  try {
3853
4158
  const walPath = `${this.dbPath}-wal`;
3854
- if (!(0, import_fs4.existsSync)(walPath)) return;
3855
- const size = (0, import_fs4.statSync)(walPath).size;
4159
+ if (!(0, import_fs5.existsSync)(walPath)) return;
4160
+ const size = (0, import_fs5.statSync)(walPath).size;
3856
4161
  if (size < _MeshRuntimeStore.WAL_MAX_BYTES) return;
3857
4162
  process.stderr.write(
3858
4163
  `[adhdev-mesh] WAL file ${Math.round(size / 1024 / 1024)}MB exceeds threshold; forcing checkpoint
@@ -3868,9 +4173,9 @@ var init_mesh_runtime_store = __esm({
3868
4173
  const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
3869
4174
  if (count.count > 0) return;
3870
4175
  const path42 = legacyQueuePath(meshId);
3871
- if (!(0, import_fs4.existsSync)(path42)) return;
4176
+ if (!(0, import_fs5.existsSync)(path42)) return;
3872
4177
  try {
3873
- const entries = JSON.parse((0, import_fs4.readFileSync)(path42, "utf-8"));
4178
+ const entries = JSON.parse((0, import_fs5.readFileSync)(path42, "utf-8"));
3874
4179
  if (!Array.isArray(entries)) return;
3875
4180
  const insert = this.db.prepare(`
3876
4181
  INSERT OR REPLACE INTO mesh_queue (
@@ -7434,8 +7739,8 @@ function formatCompletionMetadata(event) {
7434
7739
  function buildMeshSystemMessage(args) {
7435
7740
  const metadata = formatCompletionMetadata(args.metadataEvent);
7436
7741
  if (args.event === "agent:generating_completed") {
7437
- if (args.metadataEvent.source === "long_generating_reconciliation") {
7438
- return `[System] ${args.nodeLabel} already has completion evidence${metadata}. The long-generating monitor reconciled the terminal handoff and marked the session complete; wait for the queued completion event/status refresh before doing any manual transcript check.`;
7742
+ if (args.metadataEvent.source === "no_progress_reconciliation") {
7743
+ return `[System] ${args.nodeLabel} already has completion evidence${metadata}. The no-progress monitor reconciled the terminal handoff and marked the session complete; wait for the queued completion event/status refresh before doing any manual transcript check.`;
7439
7744
  }
7440
7745
  const reviewNote = args.metadataEvent.reviewRecommended === true ? " Completion evidence is insufficient \u2014 verify via git status or provider_session_id before assuming the task is done. Use mesh_read_chat once if needed, but do not poll repeatedly." : " Use mesh_read_chat once to review its final progress, but do not poll repeatedly.";
7441
7746
  return `[System] ${args.nodeLabel} has completed its task and is now idle${metadata}. This completion came from the agent status event path;${reviewNote}`;
@@ -7474,7 +7779,7 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
7474
7779
  }
7475
7780
  return `[System] ${args.nodeLabel} has stopped${metadata}. Use mesh_read_chat once if you need to inspect its last output.`;
7476
7781
  }
7477
- if (args.event === "monitor:long_generating") {
7782
+ if (args.event === "monitor:no_progress") {
7478
7783
  return `[System] ${args.nodeLabel} is still reported as generating after a long interval${metadata}. Wait for pendingCoordinatorEvents or a completion/status event; if the user explicitly asks for status, make one bounded status check and then wait again.`;
7479
7784
  }
7480
7785
  if (args.event === "worktree_bootstrap_complete") {
@@ -7613,9 +7918,9 @@ function getPendingEventsPath(meshId, coordinatorDaemonId) {
7613
7918
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
7614
7919
  if (coordinatorDaemonId) {
7615
7920
  const safeDaemon = coordinatorDaemonId.replace(/[^a-zA-Z0-9_-]/g, "_");
7616
- return (0, import_path8.join)(getLedgerDir(), `${safe}-${safeDaemon}.pending-events.jsonl`);
7921
+ return (0, import_path9.join)(getLedgerDir(), `${safe}-${safeDaemon}.pending-events.jsonl`);
7617
7922
  }
7618
- return (0, import_path8.join)(getLedgerDir(), `${safe}.pending-events.jsonl`);
7923
+ return (0, import_path9.join)(getLedgerDir(), `${safe}.pending-events.jsonl`);
7619
7924
  }
7620
7925
  function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
7621
7926
  if (!meshId) return [];
@@ -7624,9 +7929,9 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
7624
7929
  const paths = primaryDaemonId ? [getPendingEventsPath(meshId, primaryDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
7625
7930
  const events = [];
7626
7931
  for (const path42 of paths) {
7627
- if (!(0, import_fs8.existsSync)(path42)) continue;
7932
+ if (!(0, import_fs9.existsSync)(path42)) continue;
7628
7933
  try {
7629
- const raw = (0, import_fs8.readFileSync)(path42, "utf-8");
7934
+ const raw = (0, import_fs9.readFileSync)(path42, "utf-8");
7630
7935
  const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
7631
7936
  try {
7632
7937
  return [JSON.parse(line)];
@@ -7701,11 +8006,11 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
7701
8006
  }
7702
8007
  function trimPendingEventsIfNeeded(path42) {
7703
8008
  try {
7704
- if (!(0, import_fs8.existsSync)(path42)) return;
7705
- if ((0, import_fs8.statSync)(path42).size <= MAX_PENDING_EVENTS_BYTES) return;
7706
- const lines = (0, import_fs8.readFileSync)(path42, "utf-8").split("\n").filter(Boolean);
8009
+ if (!(0, import_fs9.existsSync)(path42)) return;
8010
+ if ((0, import_fs9.statSync)(path42).size <= MAX_PENDING_EVENTS_BYTES) return;
8011
+ const lines = (0, import_fs9.readFileSync)(path42, "utf-8").split("\n").filter(Boolean);
7707
8012
  if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
7708
- (0, import_fs8.writeFileSync)(path42, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
8013
+ (0, import_fs9.writeFileSync)(path42, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
7709
8014
  } catch {
7710
8015
  }
7711
8016
  }
@@ -7734,7 +8039,7 @@ function queuePendingMeshCoordinatorEvent(event) {
7734
8039
  }
7735
8040
  const path42 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
7736
8041
  trimPendingEventsIfNeeded(path42);
7737
- (0, import_fs8.appendFileSync)(path42, JSON.stringify(event) + "\n", "utf-8");
8042
+ (0, import_fs9.appendFileSync)(path42, JSON.stringify(event) + "\n", "utf-8");
7738
8043
  return true;
7739
8044
  } catch (e) {
7740
8045
  LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
@@ -7744,20 +8049,20 @@ function queuePendingMeshCoordinatorEvent(event) {
7744
8049
  function atomicDrainFile(path42) {
7745
8050
  const tmpPath = `${path42}.draining`;
7746
8051
  try {
7747
- (0, import_fs8.renameSync)(path42, tmpPath);
8052
+ (0, import_fs9.renameSync)(path42, tmpPath);
7748
8053
  } catch {
7749
8054
  return null;
7750
8055
  }
7751
8056
  try {
7752
- const content = (0, import_fs8.readFileSync)(tmpPath, "utf-8");
8057
+ const content = (0, import_fs9.readFileSync)(tmpPath, "utf-8");
7753
8058
  try {
7754
- (0, import_fs8.unlinkSync)(tmpPath);
8059
+ (0, import_fs9.unlinkSync)(tmpPath);
7755
8060
  } catch {
7756
8061
  }
7757
8062
  return content;
7758
8063
  } catch {
7759
8064
  try {
7760
- (0, import_fs8.unlinkSync)(tmpPath);
8065
+ (0, import_fs9.unlinkSync)(tmpPath);
7761
8066
  } catch {
7762
8067
  }
7763
8068
  return null;
@@ -7766,16 +8071,16 @@ function atomicDrainFile(path42) {
7766
8071
  function selectiveDrainFile(path42, predicate) {
7767
8072
  const tmpPath = `${path42}.draining`;
7768
8073
  try {
7769
- (0, import_fs8.renameSync)(path42, tmpPath);
8074
+ (0, import_fs9.renameSync)(path42, tmpPath);
7770
8075
  } catch {
7771
8076
  return [];
7772
8077
  }
7773
8078
  let content;
7774
8079
  try {
7775
- content = (0, import_fs8.readFileSync)(tmpPath, "utf-8");
8080
+ content = (0, import_fs9.readFileSync)(tmpPath, "utf-8");
7776
8081
  } catch {
7777
8082
  try {
7778
- (0, import_fs8.unlinkSync)(tmpPath);
8083
+ (0, import_fs9.unlinkSync)(tmpPath);
7779
8084
  } catch {
7780
8085
  }
7781
8086
  return [];
@@ -7798,12 +8103,12 @@ function selectiveDrainFile(path42, predicate) {
7798
8103
  }
7799
8104
  try {
7800
8105
  if (keptLines.length > 0) {
7801
- (0, import_fs8.writeFileSync)(path42, keptLines.join("\n") + "\n", "utf-8");
8106
+ (0, import_fs9.writeFileSync)(path42, keptLines.join("\n") + "\n", "utf-8");
7802
8107
  }
7803
- (0, import_fs8.unlinkSync)(tmpPath);
8108
+ (0, import_fs9.unlinkSync)(tmpPath);
7804
8109
  } catch {
7805
8110
  try {
7806
- if ((0, import_fs8.existsSync)(tmpPath) && !(0, import_fs8.existsSync)(path42)) (0, import_fs8.renameSync)(tmpPath, path42);
8111
+ if ((0, import_fs9.existsSync)(tmpPath) && !(0, import_fs9.existsSync)(path42)) (0, import_fs9.renameSync)(tmpPath, path42);
7807
8112
  } catch {
7808
8113
  }
7809
8114
  return [];
@@ -7897,18 +8202,18 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
7897
8202
  }
7898
8203
  const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
7899
8204
  for (const path42 of paths) {
7900
- if ((0, import_fs8.existsSync)(path42)) try {
7901
- (0, import_fs8.unlinkSync)(path42);
8205
+ if ((0, import_fs9.existsSync)(path42)) try {
8206
+ (0, import_fs9.unlinkSync)(path42);
7902
8207
  } catch {
7903
8208
  }
7904
8209
  }
7905
8210
  }
7906
- var import_fs8, import_path8, import_crypto7, REFINE_TERMINAL_EVENTS, MAX_PENDING_EVENTS_BYTES, MAX_PENDING_EVENTS_KEEP;
8211
+ var import_fs9, import_path9, import_crypto7, REFINE_TERMINAL_EVENTS, MAX_PENDING_EVENTS_BYTES, MAX_PENDING_EVENTS_KEEP;
7907
8212
  var init_mesh_events_pending = __esm({
7908
8213
  "src/mesh/mesh-events-pending.ts"() {
7909
8214
  "use strict";
7910
- import_fs8 = require("fs");
7911
- import_path8 = require("path");
8215
+ import_fs9 = require("fs");
8216
+ import_path9 = require("path");
7912
8217
  import_crypto7 = require("crypto");
7913
8218
  init_logger();
7914
8219
  init_mesh_ledger();
@@ -8264,7 +8569,7 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
8264
8569
  });
8265
8570
  return { reconciled: true, kind, workerResult, ledgerEntryId: entry.id };
8266
8571
  }
8267
- function buildLongGeneratingCompletionReconciliation(args) {
8572
+ function buildNoProgressCompletionReconciliation(args) {
8268
8573
  const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
8269
8574
  const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
8270
8575
  const providerType = readNonEmptyString2(args.metadataEvent.providerType);
@@ -8283,8 +8588,8 @@ function buildLongGeneratingCompletionReconciliation(args) {
8283
8588
  providerType,
8284
8589
  providerSessionId,
8285
8590
  finalSummary,
8286
- source: "long_generating_reconciliation",
8287
- reconciledFromEvent: "monitor:long_generating",
8591
+ source: "no_progress_reconciliation",
8592
+ reconciledFromEvent: "monitor:no_progress",
8288
8593
  timestamp: args.metadataEvent.timestamp ?? Date.now(),
8289
8594
  completionDiagnostic: {
8290
8595
  ...completionDiagnostic || {},
@@ -8300,7 +8605,7 @@ function buildLongGeneratingCompletionReconciliation(args) {
8300
8605
  if (!terminal) return null;
8301
8606
  return {
8302
8607
  ...args.metadataEvent,
8303
- source: "long_generating_terminal_ledger_suppression",
8608
+ source: "no_progress_terminal_ledger_suppression",
8304
8609
  terminalLedgerKind: terminal.kind,
8305
8610
  terminalLedgerAt: terminal.timestamp
8306
8611
  };
@@ -8740,7 +9045,7 @@ function resolveCommandPath(command) {
8740
9045
  if (isExplicitCommandPath(trimmed)) {
8741
9046
  const expanded = expandHome(trimmed);
8742
9047
  const candidate = path11.isAbsolute(expanded) ? expanded : path11.resolve(expanded);
8743
- return (0, import_fs9.existsSync)(candidate) ? candidate : null;
9048
+ return (0, import_fs10.existsSync)(candidate) ? candidate : null;
8744
9049
  }
8745
9050
  return null;
8746
9051
  }
@@ -8750,7 +9055,7 @@ async function resolveDetectionPath(command, whichCmd) {
8750
9055
  const whichResult = await execAsync(`${whichCmd} ${shellQuote(command)}`);
8751
9056
  if (whichResult) return whichResult.split("\n")[0];
8752
9057
  const resolved = findBinary(command);
8753
- if (path11.isAbsolute(resolved) && (0, import_fs9.existsSync)(resolved)) return resolved;
9058
+ if (path11.isAbsolute(resolved) && (0, import_fs10.existsSync)(resolved)) return resolved;
8754
9059
  return null;
8755
9060
  }
8756
9061
  function execAsync(cmd, timeoutMs = 5e3) {
@@ -8845,14 +9150,14 @@ async function detectCLI(cliId, providerLoader, options) {
8845
9150
  const all = await detectCLIs(providerLoader, options);
8846
9151
  return all.find((c) => c.id === resolvedId && c.installed) || null;
8847
9152
  }
8848
- var import_child_process, os6, path11, import_fs9;
9153
+ var import_child_process, os6, path11, import_fs10;
8849
9154
  var init_cli_detector = __esm({
8850
9155
  "src/detection/cli-detector.ts"() {
8851
9156
  "use strict";
8852
9157
  import_child_process = require("child_process");
8853
9158
  os6 = __toESM(require("os"));
8854
9159
  path11 = __toESM(require("path"));
8855
- import_fs9 = require("fs");
9160
+ import_fs10 = require("fs");
8856
9161
  init_provider_cli_shared();
8857
9162
  }
8858
9163
  });
@@ -9151,7 +9456,7 @@ function hasRecentIntentionalCleanupStop(meshId, sessionId, nodeId) {
9151
9456
  return false;
9152
9457
  }
9153
9458
  function shouldSuppressIntentionalCleanupStop(args) {
9154
- if (args.event !== "agent:stopped" && args.event !== "monitor:long_generating") return false;
9459
+ if (args.event !== "agent:stopped" && args.event !== "monitor:no_progress") return false;
9155
9460
  if (isIntentionalCleanupStopMetadata(args.metadataEvent)) return true;
9156
9461
  return hasRecentIntentionalCleanupStop(args.meshId, args.sessionId, args.nodeId);
9157
9462
  }
@@ -9367,7 +9672,7 @@ function resolveAutoFastForwardPolicy(mesh) {
9367
9672
  function sessionStateLooksActive(state) {
9368
9673
  const status = readNonEmptyString2(state?.status).toLowerCase();
9369
9674
  const chatStatus = readNonEmptyString2(state?.activeChat?.status).toLowerCase();
9370
- const active = /* @__PURE__ */ new Set(["generating", "streaming", "long_generating", "working", "starting", "waiting_approval"]);
9675
+ const active = /* @__PURE__ */ new Set(["generating", "streaming", "no_progress", "long_generating", "working", "starting", "waiting_approval"]);
9371
9676
  return active.has(status) || active.has(chatStatus);
9372
9677
  }
9373
9678
  function nodeHasActiveMeshWork(components, meshId, nodeId, currentSessionId) {
@@ -9887,7 +10192,7 @@ async function maybeAutoFastForwardIdleNode(components, args) {
9887
10192
  const node = mesh?.nodes?.find((candidate) => meshNodeIdMatches(candidate, args.nodeId));
9888
10193
  const workspace = readNonEmptyString2(node?.workspace);
9889
10194
  if (!workspace) return;
9890
- if (!(0, import_fs10.existsSync)(workspace)) return;
10195
+ if (!(0, import_fs11.existsSync)(workspace)) return;
9891
10196
  const policy = resolveAutoFastForwardPolicy(mesh);
9892
10197
  if (!policy.enabled) return;
9893
10198
  if (nodeHasActiveMeshWork(components, args.meshId, args.nodeId, args.sessionId)) return;
@@ -9981,24 +10286,24 @@ function injectMeshSystemMessage(components, args) {
9981
10286
  LOG.info("MeshEvents", `Suppressed ${args.event} for intentionally cleanup-stopped session ${eventSessionId || "(unknown session)"}`);
9982
10287
  return { success: true, forwarded: 0, suppressed: true, intentionalCleanupStop: true };
9983
10288
  }
9984
- if (args.event === "monitor:long_generating") {
9985
- const reconciledCompletion = buildLongGeneratingCompletionReconciliation({
10289
+ if (args.event === "monitor:no_progress") {
10290
+ const reconciledCompletion = buildNoProgressCompletionReconciliation({
9986
10291
  meshId: args.meshId,
9987
10292
  nodeId: args.nodeId,
9988
10293
  nodeLabel: args.nodeLabel,
9989
10294
  metadataEvent: args.metadataEvent,
9990
10295
  sourceInstanceId: args.sourceInstanceId
9991
10296
  });
9992
- if (reconciledCompletion?.source === "long_generating_reconciliation") {
9993
- LOG.info("MeshEvents", `Reconciled long-generating monitor to completion for session ${eventSessionId || "(unknown session)"}`);
10297
+ if (reconciledCompletion?.source === "no_progress_reconciliation") {
10298
+ LOG.info("MeshEvents", `Reconciled no-progress monitor to completion for session ${eventSessionId || "(unknown session)"}`);
9994
10299
  return injectMeshSystemMessage(components, {
9995
10300
  ...args,
9996
10301
  event: "agent:generating_completed",
9997
10302
  metadataEvent: reconciledCompletion
9998
10303
  });
9999
10304
  }
10000
- if (reconciledCompletion?.source === "long_generating_terminal_ledger_suppression") {
10001
- LOG.info("MeshEvents", `Suppressed long-generating monitor because terminal ledger evidence already exists for session ${eventSessionId || "(unknown session)"}`);
10305
+ if (reconciledCompletion?.source === "no_progress_terminal_ledger_suppression") {
10306
+ LOG.info("MeshEvents", `Suppressed no-progress monitor because terminal ledger evidence already exists for session ${eventSessionId || "(unknown session)"}`);
10002
10307
  return {
10003
10308
  success: true,
10004
10309
  forwarded: 0,
@@ -10040,7 +10345,7 @@ function injectMeshSystemMessage(components, args) {
10040
10345
  const terminalFinalSummary = readNonEmptyString2(terminal.payload.finalSummary);
10041
10346
  const eventProviderSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId);
10042
10347
  const eventFinalSummary = readNonEmptyString2(args.metadataEvent.finalSummary);
10043
- if (terminalProviderSessionId && terminalProviderSessionId === eventProviderSessionId || terminalFinalSummary && terminalFinalSummary === eventFinalSummary || args.metadataEvent.source === "long_generating_reconciliation") {
10348
+ if (terminalProviderSessionId && terminalProviderSessionId === eventProviderSessionId || terminalFinalSummary && terminalFinalSummary === eventFinalSummary || args.metadataEvent.source === "no_progress_reconciliation") {
10044
10349
  LOG.info("MeshEvents", `Suppressed duplicate completion with existing terminal ledger evidence for mesh ${args.meshId} session ${eventSessionId}`);
10045
10350
  return { success: true, forwarded: 0, suppressed: true, duplicateCompletion: true, terminalLedgerEvidence: true };
10046
10351
  }
@@ -10479,11 +10784,11 @@ function setupMeshEventForwarding(components) {
10479
10784
  });
10480
10785
  });
10481
10786
  }
10482
- var import_fs10, REMOTE_IDLE_SESSION_TTL_MS, meshByWorkspaceCache, MESH_WORKSPACE_CACHE_TTL_MS, IDLE_AUTO_FAST_FORWARD_THROTTLE_MS, idleAutoFastForwardLastAttempt, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS, AUTO_LAUNCH_AWAIT_CLAIM_MS, lastAutoLaunchLedgerKey, AUTO_LAUNCH_LEDGER_DEDUP_MAX, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, MESH_FORCE_INJECT_EVENTS;
10787
+ var import_fs11, REMOTE_IDLE_SESSION_TTL_MS, meshByWorkspaceCache, MESH_WORKSPACE_CACHE_TTL_MS, IDLE_AUTO_FAST_FORWARD_THROTTLE_MS, idleAutoFastForwardLastAttempt, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS, AUTO_LAUNCH_AWAIT_CLAIM_MS, lastAutoLaunchLedgerKey, AUTO_LAUNCH_LEDGER_DEDUP_MAX, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, MESH_FORCE_INJECT_EVENTS;
10483
10788
  var init_mesh_events_coordinator = __esm({
10484
10789
  "src/mesh/mesh-events-coordinator.ts"() {
10485
10790
  "use strict";
10486
- import_fs10 = require("fs");
10791
+ import_fs11 = require("fs");
10487
10792
  init_config();
10488
10793
  init_mesh_config();
10489
10794
  init_cli_detector();
@@ -10519,7 +10824,7 @@ var init_mesh_events_coordinator = __esm({
10519
10824
  "agent:waiting_approval",
10520
10825
  "agent:stopped",
10521
10826
  "agent:ready",
10522
- "monitor:long_generating",
10827
+ "monitor:no_progress",
10523
10828
  "refine:accepted",
10524
10829
  "refine:completed",
10525
10830
  "refine:failed",
@@ -10530,7 +10835,7 @@ var init_mesh_events_coordinator = __esm({
10530
10835
  "agent:generating_completed": "task_completed",
10531
10836
  "agent:waiting_approval": "task_approval_needed",
10532
10837
  "agent:stopped": "task_failed",
10533
- "monitor:long_generating": "task_stalled"
10838
+ "monitor:no_progress": "task_stalled"
10534
10839
  };
10535
10840
  MESH_FORCE_INJECT_EVENTS = /* @__PURE__ */ new Set([
10536
10841
  "agent:generating_completed",
@@ -12678,7 +12983,7 @@ function resolveWin32GlobalBin(trimmed) {
12678
12983
  if (!dir) continue;
12679
12984
  for (const ext of WIN_EXEC_EXT) {
12680
12985
  const full = path18.join(dir, trimmed + ext);
12681
- if ((0, import_fs13.existsSync)(full)) return full;
12986
+ if ((0, import_fs14.existsSync)(full)) return full;
12682
12987
  }
12683
12988
  }
12684
12989
  return null;
@@ -12687,7 +12992,7 @@ function resolveWin32Executable(command) {
12687
12992
  if (process.platform !== "win32") return command;
12688
12993
  const trimmed = (command || "").trim();
12689
12994
  if (!trimmed) return command;
12690
- if (path18.isAbsolute(trimmed) && (0, import_fs13.existsSync)(trimmed)) return trimmed;
12995
+ if (path18.isAbsolute(trimmed) && (0, import_fs14.existsSync)(trimmed)) return trimmed;
12691
12996
  try {
12692
12997
  const out = (0, import_child_process4.execFileSync)("where", [trimmed], {
12693
12998
  encoding: "utf8",
@@ -12704,12 +13009,12 @@ function resolveWin32Executable(command) {
12704
13009
  if (globalBin) return globalBin;
12705
13010
  return command;
12706
13011
  }
12707
- var import_child_process4, import_fs13, path18, DIRECT_EXEC_EXT, WIN_EXEC_EXT;
13012
+ var import_child_process4, import_fs14, path18, DIRECT_EXEC_EXT, WIN_EXEC_EXT;
12708
13013
  var init_resolve_executable = __esm({
12709
13014
  "src/cli-adapters/resolve-executable.ts"() {
12710
13015
  "use strict";
12711
13016
  import_child_process4 = require("child_process");
12712
- import_fs13 = require("fs");
13017
+ import_fs14 = require("fs");
12713
13018
  path18 = __toESM(require("path"));
12714
13019
  DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
12715
13020
  WIN_EXEC_EXT = [".exe", ".com", ".cmd", ".bat"];
@@ -15677,7 +15982,7 @@ ${lastSnapshot}`;
15677
15982
  };
15678
15983
  if (parsedSessionStatus === "idle" && hasFinalAssistant(parsedStatusBeforeSend)) return null;
15679
15984
  if (this.engine.currentStatus === "generating") return "current_status_generating";
15680
- if (parsedSessionStatus === "generating" || parsedSessionStatus === "long_generating") {
15985
+ if (parsedSessionStatus === "generating" || parsedSessionStatus === "no_progress" || parsedSessionStatus === "long_generating") {
15681
15986
  const parsedModal = parsedStatusBeforeSend?.activeModal ?? parsedStatusBeforeSend?.modal ?? null;
15682
15987
  const parsedHasActionableModal = Boolean(
15683
15988
  parsedModal && Array.isArray(parsedModal.buttons) && parsedModal.buttons.some((candidate) => typeof candidate === "string" && candidate.trim())
@@ -15754,7 +16059,7 @@ ${lastSnapshot}`;
15754
16059
  }
15755
16060
  if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.engine.currentStatus})`);
15756
16061
  const parsedSessionStatus = typeof parsedStatusBeforeSend?.status === "string" ? String(parsedStatusBeforeSend.status) : "";
15757
- if (!allowInputDuringGeneration && (parsedSessionStatus === "generating" || parsedSessionStatus === "long_generating")) {
16062
+ if (!allowInputDuringGeneration && (parsedSessionStatus === "generating" || parsedSessionStatus === "no_progress" || parsedSessionStatus === "long_generating")) {
15758
16063
  const parsedModal = parsedStatusBeforeSend?.activeModal ?? parsedStatusBeforeSend?.modal ?? null;
15759
16064
  const parsedHasActionableModal = Boolean(
15760
16065
  parsedModal && Array.isArray(parsedModal.buttons) && parsedModal.buttons.some((candidate) => typeof candidate === "string" && candidate.trim())
@@ -17264,6 +17569,8 @@ __export(index_exports, {
17264
17569
  AcpProviderInstance: () => AcpProviderInstance,
17265
17570
  AgentStreamPoller: () => AgentStreamPoller,
17266
17571
  BUILTIN_CHAT_MESSAGE_KINDS: () => BUILTIN_CHAT_MESSAGE_KINDS,
17572
+ CHANGE_IMPACT_CONFIG_LOCATIONS: () => CHANGE_IMPACT_CONFIG_LOCATIONS,
17573
+ CHANGE_IMPACT_CONFIG_SCHEMA: () => CHANGE_IMPACT_CONFIG_SCHEMA,
17267
17574
  CHAT_MESSAGE_ACTIVITY_SOURCES: () => CHAT_MESSAGE_ACTIVITY_SOURCES,
17268
17575
  CHAT_MESSAGE_AUDIENCES: () => CHAT_MESSAGE_AUDIENCES,
17269
17576
  CHAT_MESSAGE_INTERNAL_SOURCES: () => CHAT_MESSAGE_INTERNAL_SOURCES,
@@ -17454,6 +17761,7 @@ __export(index_exports, {
17454
17761
  getSessionHostSurfaceKind: () => getSessionHostSurfaceKind,
17455
17762
  getSessionRecoveryContext: () => getSessionRecoveryContext,
17456
17763
  getWorkspaceState: () => getWorkspaceState,
17764
+ globToRegExp: () => globToRegExp,
17457
17765
  handleGitCommand: () => handleGitCommand,
17458
17766
  hasCdpManager: () => hasCdpManager,
17459
17767
  hasPendingDependents: () => hasPendingDependents,
@@ -17487,6 +17795,7 @@ __export(index_exports, {
17487
17795
  listMeshMissionSummaries: () => listMeshMissionSummaries,
17488
17796
  listMeshes: () => listMeshes,
17489
17797
  listWorktrees: () => listWorktrees,
17798
+ loadChangeImpactConfig: () => loadChangeImpactConfig,
17490
17799
  loadConfig: () => loadConfig,
17491
17800
  loadMeshCoordinatorRegistry: () => loadMeshCoordinatorRegistry,
17492
17801
  loadMeshRefineConfig: () => loadMeshRefineConfig,
@@ -17581,6 +17890,7 @@ __export(index_exports, {
17581
17890
  spawnDetachedDaemonUpgradeHelper: () => spawnDetachedDaemonUpgradeHelper,
17582
17891
  startDaemonDevSupport: () => startDaemonDevSupport,
17583
17892
  startLocalIpcServer: () => startLocalIpcServer,
17893
+ suggestChangeImpactConfig: () => suggestChangeImpactConfig,
17584
17894
  suggestMeshRefineConfig: () => suggestMeshRefineConfig,
17585
17895
  summarizeGitStatus: () => summarizeGitStatus,
17586
17896
  summarizeMeshAsyncRefineJobs: () => summarizeMeshAsyncRefineJobs,
@@ -17597,6 +17907,7 @@ __export(index_exports, {
17597
17907
  updateTaskStatus: () => updateTaskStatus,
17598
17908
  upsertMeshMission: () => upsertMeshMission,
17599
17909
  upsertSavedProviderSession: () => upsertSavedProviderSession,
17910
+ validateChangeImpactConfig: () => validateChangeImpactConfig,
17600
17911
  validateCliProviderManifest: () => validateCliProviderManifest,
17601
17912
  validateFsmSpec: () => validateFsmSpec,
17602
17913
  validateMeshRefineConfig: () => validateMeshRefineConfig,
@@ -17966,6 +18277,7 @@ init_repo_mesh_types();
17966
18277
  // src/git/index.ts
17967
18278
  init_git_executor();
17968
18279
  init_git_status();
18280
+ init_change_impact_config();
17969
18281
  init_git_diff();
17970
18282
 
17971
18283
  // src/git/git-summary.ts
@@ -19259,18 +19571,18 @@ init_mesh_task_stats();
19259
19571
  init_mesh_review_inbox();
19260
19572
 
19261
19573
  // src/mesh/coordinator-registry.ts
19262
- var import_path5 = require("path");
19263
- var import_fs5 = require("fs");
19574
+ var import_path6 = require("path");
19575
+ var import_fs6 = require("fs");
19264
19576
  init_config();
19265
19577
  var _registry = /* @__PURE__ */ new Map();
19266
19578
  function getRegistryPath() {
19267
- return (0, import_path5.join)(getDaemonDataDir(), "mesh-coordinators.json");
19579
+ return (0, import_path6.join)(getDaemonDataDir(), "mesh-coordinators.json");
19268
19580
  }
19269
19581
  function loadMeshCoordinatorRegistry() {
19270
19582
  const path42 = getRegistryPath();
19271
- if (!(0, import_fs5.existsSync)(path42)) return;
19583
+ if (!(0, import_fs6.existsSync)(path42)) return;
19272
19584
  try {
19273
- const raw = JSON.parse((0, import_fs5.readFileSync)(path42, "utf-8"));
19585
+ const raw = JSON.parse((0, import_fs6.readFileSync)(path42, "utf-8"));
19274
19586
  if (!Array.isArray(raw)) return;
19275
19587
  _registry.clear();
19276
19588
  for (const entry of raw) {
@@ -19283,7 +19595,7 @@ function loadMeshCoordinatorRegistry() {
19283
19595
  }
19284
19596
  function saveRegistry() {
19285
19597
  try {
19286
- (0, import_fs5.writeFileSync)(
19598
+ (0, import_fs6.writeFileSync)(
19287
19599
  getRegistryPath(),
19288
19600
  JSON.stringify([..._registry.values()], null, 2),
19289
19601
  { encoding: "utf-8", mode: 384 }
@@ -19318,9 +19630,9 @@ function listCoordinatorsForWorkspace(workspace) {
19318
19630
  }
19319
19631
 
19320
19632
  // src/mesh/refine-config.ts
19321
- var import_fs6 = require("fs");
19322
- var import_path6 = require("path");
19323
- var yaml = __toESM(require("js-yaml"));
19633
+ var import_fs7 = require("fs");
19634
+ var import_path7 = require("path");
19635
+ var yaml2 = __toESM(require("js-yaml"));
19324
19636
  var MESH_REFINE_VALIDATION_CATEGORIES = ["typecheck", "test", "lint", "build"];
19325
19637
  var MESH_REFINE_CONFIG_LOCATIONS = [
19326
19638
  ".adhdev/refine.json",
@@ -19461,7 +19773,7 @@ function normalizeMeshCommandConfig(entry, source) {
19461
19773
  }
19462
19774
  };
19463
19775
  }
19464
- var isRecord = isMeshConfigRecord;
19776
+ var isRecord2 = isMeshConfigRecord;
19465
19777
  function validateMeshRefineConfig(config, source = "inline") {
19466
19778
  const errors = [];
19467
19779
  const bootstrapCommands = [];
@@ -19469,14 +19781,14 @@ function validateMeshRefineConfig(config, source = "inline") {
19469
19781
  const rejectedCommands = [];
19470
19782
  const deprecationWarnings = [];
19471
19783
  let bootstrapMode = "inherit";
19472
- if (!isRecord(config)) return { valid: false, errors: ["config must be an object"], bootstrapCommands, commands, rejectedCommands, bootstrapMode, deprecationWarnings };
19784
+ if (!isRecord2(config)) return { valid: false, errors: ["config must be an object"], bootstrapCommands, commands, rejectedCommands, bootstrapMode, deprecationWarnings };
19473
19785
  if (config.version !== 1) errors.push("version must be 1");
19474
19786
  if (config.allowAutoPublishSubmoduleMainCommits !== void 0 && typeof config.allowAutoPublishSubmoduleMainCommits !== "boolean") {
19475
19787
  errors.push("allowAutoPublishSubmoduleMainCommits must be a boolean when provided");
19476
19788
  }
19477
19789
  const validation = config.validation;
19478
- if (validation !== void 0 && !isRecord(validation)) errors.push("validation must be an object");
19479
- const rawBootstrapMode = isRecord(validation) ? validation.bootstrap : void 0;
19790
+ if (validation !== void 0 && !isRecord2(validation)) errors.push("validation must be an object");
19791
+ const rawBootstrapMode = isRecord2(validation) ? validation.bootstrap : void 0;
19480
19792
  if (rawBootstrapMode !== void 0) {
19481
19793
  if (rawBootstrapMode === "inherit" || rawBootstrapMode === "skip") {
19482
19794
  bootstrapMode = rawBootstrapMode;
@@ -19484,8 +19796,8 @@ function validateMeshRefineConfig(config, source = "inline") {
19484
19796
  errors.push("validation.bootstrap must be 'inherit' or 'skip' when provided");
19485
19797
  }
19486
19798
  }
19487
- const rawCommands = isRecord(validation) ? validation.commands : void 0;
19488
- const rawBootstrapCommands = isRecord(validation) ? validation.bootstrapCommands : void 0;
19799
+ const rawCommands = isRecord2(validation) ? validation.commands : void 0;
19800
+ const rawBootstrapCommands = isRecord2(validation) ? validation.bootstrapCommands : void 0;
19489
19801
  if (rawCommands !== void 0 && !Array.isArray(rawCommands)) errors.push("validation.commands must be an array");
19490
19802
  if (rawBootstrapCommands !== void 0 && !Array.isArray(rawBootstrapCommands)) errors.push("validation.bootstrapCommands must be an array");
19491
19803
  if (Array.isArray(rawBootstrapCommands) && rawBootstrapCommands.length > 0) {
@@ -19508,9 +19820,9 @@ function validateMeshRefineConfig(config, source = "inline") {
19508
19820
  if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
19509
19821
  return { valid: errors.length === 0, errors, bootstrapCommands, commands, rejectedCommands, bootstrapMode, deprecationWarnings };
19510
19822
  }
19511
- function parseConfigText(path42, text) {
19823
+ function parseConfigText2(path42, text) {
19512
19824
  if (/\.json$/i.test(path42)) return JSON.parse(text);
19513
- return yaml.load(text);
19825
+ return yaml2.load(text);
19514
19826
  }
19515
19827
  function loadMeshRefineConfig(mesh, workspace) {
19516
19828
  const policy = mesh?.policy && typeof mesh.policy === "object" && !Array.isArray(mesh.policy) ? mesh.policy : {};
@@ -19521,10 +19833,10 @@ function loadMeshRefineConfig(mesh, workspace) {
19521
19833
  return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
19522
19834
  }
19523
19835
  for (const relative5 of MESH_REFINE_CONFIG_LOCATIONS) {
19524
- const configPath = (0, import_path6.join)(workspace, relative5);
19525
- if (!(0, import_fs6.existsSync)(configPath)) continue;
19836
+ const configPath = (0, import_path7.join)(workspace, relative5);
19837
+ if (!(0, import_fs7.existsSync)(configPath)) continue;
19526
19838
  try {
19527
- const parsed = parseConfigText(configPath, (0, import_fs6.readFileSync)(configPath, "utf-8"));
19839
+ const parsed = parseConfigText2(configPath, (0, import_fs7.readFileSync)(configPath, "utf-8"));
19528
19840
  const validation = validateMeshRefineConfig(parsed, relative5);
19529
19841
  if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
19530
19842
  return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
@@ -19540,20 +19852,20 @@ function loadMeshRefineConfig(mesh, workspace) {
19540
19852
  }
19541
19853
  function readPackageScripts(workspace) {
19542
19854
  try {
19543
- const parsed = JSON.parse((0, import_fs6.readFileSync)((0, import_path6.join)(workspace, "package.json"), "utf-8"));
19544
- return isRecord(parsed?.scripts) ? parsed.scripts : {};
19855
+ const parsed = JSON.parse((0, import_fs7.readFileSync)((0, import_path7.join)(workspace, "package.json"), "utf-8"));
19856
+ return isRecord2(parsed?.scripts) ? parsed.scripts : {};
19545
19857
  } catch {
19546
19858
  return {};
19547
19859
  }
19548
19860
  }
19549
19861
  function collectProjectContextSuggestions(mesh) {
19550
19862
  const commands = mesh?.projectContext?.commands;
19551
- if (!isRecord(commands)) return [];
19863
+ if (!isRecord2(commands)) return [];
19552
19864
  const suggestions = [];
19553
19865
  for (const category of MESH_REFINE_VALIDATION_CATEGORIES) {
19554
19866
  const entries = Array.isArray(commands[category]) ? commands[category] : [];
19555
19867
  for (const entry of entries) {
19556
- if (isRecord(entry) && typeof entry.command === "string") suggestions.push({ command: entry.command, category });
19868
+ if (isRecord2(entry) && typeof entry.command === "string") suggestions.push({ command: entry.command, category });
19557
19869
  }
19558
19870
  }
19559
19871
  return suggestions;
@@ -19617,12 +19929,12 @@ function resolveMeshRefineValidationPlan(mesh, workspace) {
19617
19929
  }
19618
19930
 
19619
19931
  // src/mesh/worktree-bootstrap-config.ts
19620
- var import_fs7 = require("fs");
19621
- var import_path7 = require("path");
19932
+ var import_fs8 = require("fs");
19933
+ var import_path8 = require("path");
19622
19934
  var import_node_child_process3 = require("child_process");
19623
19935
  var import_node_crypto2 = require("crypto");
19624
19936
  var import_node_util3 = require("util");
19625
- var yaml2 = __toESM(require("js-yaml"));
19937
+ var yaml3 = __toESM(require("js-yaml"));
19626
19938
  var MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS = [
19627
19939
  ".adhdev/worktree_bootstrap.json",
19628
19940
  ".adhdev/worktree_bootstrap.yaml",
@@ -19667,9 +19979,9 @@ var MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA = {
19667
19979
  var DEFAULT_TIMEOUT_MS2 = 12e4;
19668
19980
  var DEFAULT_OUTPUT_LIMIT_BYTES = 128 * 1024;
19669
19981
  var OUTPUT_SUMMARY_CHARS = 2e3;
19670
- function parseConfigText2(path42, text) {
19982
+ function parseConfigText3(path42, text) {
19671
19983
  if (/\.json$/i.test(path42)) return JSON.parse(text);
19672
- return yaml2.load(text);
19984
+ return yaml3.load(text);
19673
19985
  }
19674
19986
  function truncateOutput(value) {
19675
19987
  const text = typeof value === "string" ? value : value == null ? "" : String(value);
@@ -19709,10 +20021,10 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
19709
20021
  return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
19710
20022
  }
19711
20023
  for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
19712
- const configPath = (0, import_path7.join)(workspace, relative5);
19713
- if (!(0, import_fs7.existsSync)(configPath)) continue;
20024
+ const configPath = (0, import_path8.join)(workspace, relative5);
20025
+ if (!(0, import_fs8.existsSync)(configPath)) continue;
19714
20026
  try {
19715
- const parsed = parseConfigText2(configPath, (0, import_fs7.readFileSync)(configPath, "utf-8"));
20027
+ const parsed = parseConfigText3(configPath, (0, import_fs8.readFileSync)(configPath, "utf-8"));
19716
20028
  const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
19717
20029
  if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
19718
20030
  return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
@@ -19725,9 +20037,9 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
19725
20037
  function computeStaleInputsDigest(workspace, staleInputs) {
19726
20038
  const digest = {};
19727
20039
  for (const relative5 of staleInputs ?? []) {
19728
- const filePath = (0, import_path7.join)(workspace, relative5);
20040
+ const filePath = (0, import_path8.join)(workspace, relative5);
19729
20041
  try {
19730
- digest[relative5] = (0, import_node_crypto2.createHash)("sha256").update((0, import_fs7.readFileSync)(filePath)).digest("hex");
20042
+ digest[relative5] = (0, import_node_crypto2.createHash)("sha256").update((0, import_fs8.readFileSync)(filePath)).digest("hex");
19731
20043
  } catch {
19732
20044
  digest[relative5] = "absent";
19733
20045
  }
@@ -19797,10 +20109,10 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
19797
20109
  staleInputs: loaded.config.staleInputs
19798
20110
  };
19799
20111
  const staleInputPaths = loaded.config.staleInputs ?? [];
19800
- const initiallyAbsent = staleInputPaths.filter((p) => !(0, import_fs7.existsSync)((0, import_path7.join)(workspace, p)));
20112
+ const initiallyAbsent = staleInputPaths.filter((p) => !(0, import_fs8.existsSync)((0, import_path8.join)(workspace, p)));
19801
20113
  for (const command of validation.commands) {
19802
20114
  if (initiallyAbsent.length > 0) {
19803
- const appearedNow = initiallyAbsent.filter((p) => (0, import_fs7.existsSync)((0, import_path7.join)(workspace, p)));
20115
+ const appearedNow = initiallyAbsent.filter((p) => (0, import_fs8.existsSync)((0, import_path8.join)(workspace, p)));
19804
20116
  if (appearedNow.length > 0) {
19805
20117
  state.status = "stale";
19806
20118
  state.completedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -19808,7 +20120,7 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
19808
20120
  return state;
19809
20121
  }
19810
20122
  }
19811
- const cwd = command.cwd ? (0, import_path7.resolve)(workspace, command.cwd) : workspace;
20123
+ const cwd = command.cwd ? (0, import_path8.resolve)(workspace, command.cwd) : workspace;
19812
20124
  const startedAt = Date.now();
19813
20125
  state.lastCommand = command.displayCommand;
19814
20126
  try {
@@ -20047,8 +20359,8 @@ var P2pRelayFailureError = class extends Error {
20047
20359
  };
20048
20360
 
20049
20361
  // src/config/state-store.ts
20050
- var import_fs11 = require("fs");
20051
- var import_path9 = require("path");
20362
+ var import_fs12 = require("fs");
20363
+ var import_path10 = require("path");
20052
20364
  init_config();
20053
20365
  var DEFAULT_STATE = {
20054
20366
  recentActivity: [],
@@ -20062,7 +20374,7 @@ function isPlainObject2(value) {
20062
20374
  return !!value && typeof value === "object" && !Array.isArray(value);
20063
20375
  }
20064
20376
  function getStatePath() {
20065
- return (0, import_path9.join)(getConfigDir(), "state.json");
20377
+ return (0, import_path10.join)(getConfigDir(), "state.json");
20066
20378
  }
20067
20379
  function normalizeState(raw) {
20068
20380
  const parsed = isPlainObject2(raw) ? raw : {};
@@ -20098,11 +20410,11 @@ function normalizeState(raw) {
20098
20410
  }
20099
20411
  function loadState() {
20100
20412
  const statePath = getStatePath();
20101
- if (!(0, import_fs11.existsSync)(statePath)) {
20413
+ if (!(0, import_fs12.existsSync)(statePath)) {
20102
20414
  return { ...DEFAULT_STATE };
20103
20415
  }
20104
20416
  try {
20105
- const raw = (0, import_fs11.readFileSync)(statePath, "utf-8");
20417
+ const raw = (0, import_fs12.readFileSync)(statePath, "utf-8");
20106
20418
  return normalizeState(JSON.parse(raw));
20107
20419
  } catch {
20108
20420
  return { ...DEFAULT_STATE };
@@ -20111,7 +20423,7 @@ function loadState() {
20111
20423
  function saveState(state) {
20112
20424
  const statePath = getStatePath();
20113
20425
  const normalized = normalizeState(state);
20114
- (0, import_fs11.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
20426
+ (0, import_fs12.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
20115
20427
  }
20116
20428
  function resetState() {
20117
20429
  saveState({ ...DEFAULT_STATE });
@@ -20120,7 +20432,7 @@ function resetState() {
20120
20432
  // src/detection/ide-detector.ts
20121
20433
  var import_child_process2 = require("child_process");
20122
20434
  var import_util = require("util");
20123
- var import_fs12 = require("fs");
20435
+ var import_fs13 = require("fs");
20124
20436
  var import_os2 = require("os");
20125
20437
  var path13 = __toESM(require("path"));
20126
20438
 
@@ -20201,7 +20513,7 @@ function findCliCommand(command) {
20201
20513
  if (path13.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
20202
20514
  const candidate = trimmed.startsWith("~") ? path13.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
20203
20515
  const resolved = path13.isAbsolute(candidate) ? candidate : path13.resolve(candidate);
20204
- return (0, import_fs12.existsSync)(resolved) ? resolved : null;
20516
+ return (0, import_fs13.existsSync)(resolved) ? resolved : null;
20205
20517
  }
20206
20518
  const isWin = (0, import_os2.platform)() === "win32";
20207
20519
  const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
@@ -20211,8 +20523,8 @@ function findCliCommand(command) {
20211
20523
  for (const ext of exes) {
20212
20524
  const fullPath = path13.join(p, trimmed + ext);
20213
20525
  try {
20214
- if ((0, import_fs12.existsSync)(fullPath)) {
20215
- const stat2 = (0, import_fs12.statSync)(fullPath);
20526
+ if ((0, import_fs13.existsSync)(fullPath)) {
20527
+ const stat2 = (0, import_fs13.statSync)(fullPath);
20216
20528
  if (stat2.isFile() && (isWin || stat2.mode & 73)) {
20217
20529
  return fullPath;
20218
20530
  }
@@ -20230,9 +20542,9 @@ function checkPathExists(paths) {
20230
20542
  if (normalized.includes("*")) {
20231
20543
  const username = home.split(/[\\/]/).pop() || "";
20232
20544
  const resolved = normalized.replace("*", username);
20233
- if ((0, import_fs12.existsSync)(resolved)) return resolved;
20545
+ if ((0, import_fs13.existsSync)(resolved)) return resolved;
20234
20546
  } else {
20235
- if ((0, import_fs12.existsSync)(normalized)) return normalized;
20547
+ if ((0, import_fs13.existsSync)(normalized)) return normalized;
20236
20548
  }
20237
20549
  }
20238
20550
  return null;
@@ -20246,7 +20558,7 @@ async function detectIDEs(providerLoader) {
20246
20558
  let resolvedCli = cliPath;
20247
20559
  if (!resolvedCli && appPath && os30 === "darwin") {
20248
20560
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
20249
- if ((0, import_fs12.existsSync)(bundledCli)) resolvedCli = bundledCli;
20561
+ if ((0, import_fs13.existsSync)(bundledCli)) resolvedCli = bundledCli;
20250
20562
  }
20251
20563
  if (!resolvedCli && appPath && os30 === "win32") {
20252
20564
  const { dirname: dirname17 } = await import("path");
@@ -20259,7 +20571,7 @@ async function detectIDEs(providerLoader) {
20259
20571
  `${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
20260
20572
  ];
20261
20573
  for (const c of candidates) {
20262
- if ((0, import_fs12.existsSync)(c)) {
20574
+ if ((0, import_fs13.existsSync)(c)) {
20263
20575
  resolvedCli = c;
20264
20576
  break;
20265
20577
  }
@@ -21804,8 +22116,8 @@ init_contracts();
21804
22116
  // src/providers/status-monitor.ts
21805
22117
  var DEFAULT_MONITOR_CONFIG = {
21806
22118
  approvalAlert: true,
21807
- longGeneratingAlert: true,
21808
- longGeneratingThresholdSec: 180,
22119
+ noProgressAlert: true,
22120
+ noProgressThresholdSec: 180,
21809
22121
  // 3 minutes
21810
22122
  alertCooldownSec: 60
21811
22123
  // 1 minute cooldown
@@ -21814,7 +22126,7 @@ var StatusMonitor = class {
21814
22126
  config;
21815
22127
  lastAlertTime = /* @__PURE__ */ new Map();
21816
22128
  generatingStartTimes = /* @__PURE__ */ new Map();
21817
- longGeneratingAlerted = /* @__PURE__ */ new Map();
22129
+ noProgressAlerted = /* @__PURE__ */ new Map();
21818
22130
  lastProgressFingerprint = /* @__PURE__ */ new Map();
21819
22131
  lastProgressChangeAt = /* @__PURE__ */ new Map();
21820
22132
  constructor(config) {
@@ -21832,7 +22144,7 @@ var StatusMonitor = class {
21832
22144
  * Check status transition → return notification event array.
21833
22145
  * Called from each onTick() or detectStatusTransition().
21834
22146
  */
21835
- check(agentKey, status, now, progressFingerprint) {
22147
+ check(agentKey, status, now, progressFingerprint, approvalPending) {
21836
22148
  const events = [];
21837
22149
  if (this.config.approvalAlert && status === "waiting_approval") {
21838
22150
  if (this.shouldAlert(agentKey + ":approval", now)) {
@@ -21845,9 +22157,16 @@ var StatusMonitor = class {
21845
22157
  }
21846
22158
  }
21847
22159
  if (status === "generating" || status === "streaming") {
22160
+ if (approvalPending) {
22161
+ this.generatingStartTimes.set(agentKey, now);
22162
+ this.lastProgressFingerprint.set(agentKey, progressFingerprint ?? "");
22163
+ this.lastProgressChangeAt.set(agentKey, now);
22164
+ this.noProgressAlerted.set(agentKey, false);
22165
+ return events;
22166
+ }
21848
22167
  if (!this.generatingStartTimes.has(agentKey)) {
21849
22168
  this.generatingStartTimes.set(agentKey, now);
21850
- this.longGeneratingAlerted.set(agentKey, false);
22169
+ this.noProgressAlerted.set(agentKey, false);
21851
22170
  const initialFingerprint = progressFingerprint ?? "";
21852
22171
  this.lastProgressFingerprint.set(agentKey, initialFingerprint);
21853
22172
  this.lastProgressChangeAt.set(agentKey, now);
@@ -21857,17 +22176,17 @@ var StatusMonitor = class {
21857
22176
  if (previousFingerprint !== currentFingerprint) {
21858
22177
  this.lastProgressFingerprint.set(agentKey, currentFingerprint);
21859
22178
  this.lastProgressChangeAt.set(agentKey, now);
21860
- this.longGeneratingAlerted.set(agentKey, false);
22179
+ this.noProgressAlerted.set(agentKey, false);
21861
22180
  }
21862
- if (this.config.longGeneratingAlert) {
22181
+ if (this.config.noProgressAlert) {
21863
22182
  const progressChangedAt = this.lastProgressChangeAt.get(agentKey) || this.generatingStartTimes.get(agentKey);
21864
22183
  const elapsedSec = Math.round((now - progressChangedAt) / 1e3);
21865
- const alreadyAlerted = this.longGeneratingAlerted.get(agentKey) === true;
21866
- if (elapsedSec > this.config.longGeneratingThresholdSec && !alreadyAlerted) {
21867
- if (this.shouldAlert(agentKey + ":long_gen", now)) {
21868
- this.longGeneratingAlerted.set(agentKey, true);
22184
+ const alreadyAlerted = this.noProgressAlerted.get(agentKey) === true;
22185
+ if (elapsedSec > this.config.noProgressThresholdSec && !alreadyAlerted) {
22186
+ if (this.shouldAlert(agentKey + ":no_progress", now)) {
22187
+ this.noProgressAlerted.set(agentKey, true);
21869
22188
  events.push({
21870
- type: "monitor:long_generating",
22189
+ type: "monitor:no_progress",
21871
22190
  agentKey,
21872
22191
  elapsedSec,
21873
22192
  timestamp: now,
@@ -21878,7 +22197,7 @@ var StatusMonitor = class {
21878
22197
  }
21879
22198
  } else {
21880
22199
  this.generatingStartTimes.delete(agentKey);
21881
- this.longGeneratingAlerted.delete(agentKey);
22200
+ this.noProgressAlerted.delete(agentKey);
21882
22201
  this.lastProgressFingerprint.delete(agentKey);
21883
22202
  this.lastProgressChangeAt.delete(agentKey);
21884
22203
  }
@@ -21897,7 +22216,7 @@ var StatusMonitor = class {
21897
22216
  reset(agentKey) {
21898
22217
  if (agentKey) {
21899
22218
  this.generatingStartTimes.delete(agentKey);
21900
- this.longGeneratingAlerted.delete(agentKey);
22219
+ this.noProgressAlerted.delete(agentKey);
21901
22220
  this.lastProgressFingerprint.delete(agentKey);
21902
22221
  this.lastProgressChangeAt.delete(agentKey);
21903
22222
  for (const k of this.lastAlertTime.keys()) {
@@ -21905,7 +22224,7 @@ var StatusMonitor = class {
21905
22224
  }
21906
22225
  } else {
21907
22226
  this.generatingStartTimes.clear();
21908
- this.longGeneratingAlerted.clear();
22227
+ this.noProgressAlerted.clear();
21909
22228
  this.lastProgressFingerprint.clear();
21910
22229
  this.lastProgressChangeAt.clear();
21911
22230
  this.lastAlertTime.clear();
@@ -23728,8 +24047,8 @@ var ExtensionProviderInstance = class {
23728
24047
  this.settings = context.settings || {};
23729
24048
  this.monitor.updateConfig({
23730
24049
  approvalAlert: this.settings.approvalAlert !== false,
23731
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
23732
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
24050
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
24051
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
23733
24052
  });
23734
24053
  }
23735
24054
  async onTick() {
@@ -23820,8 +24139,8 @@ var ExtensionProviderInstance = class {
23820
24139
  this.settings = { ...this.settings, ...newSettings };
23821
24140
  this.monitor.updateConfig({
23822
24141
  approvalAlert: this.settings.approvalAlert !== false,
23823
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
23824
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
24142
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
24143
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
23825
24144
  });
23826
24145
  }
23827
24146
  /** Query UUID instanceId */
@@ -23881,7 +24200,8 @@ var ExtensionProviderInstance = class {
23881
24200
  phase: agentStatus === "idle" && (previousStatus === "generating" || previousStatus === "waiting_approval") ? "turn_completed" : "immediate"
23882
24201
  });
23883
24202
  const agentKey = `${this.type}:ext`;
23884
- const monitorEvents = this.monitor.check(agentKey, agentStatus, now, progressFingerprint);
24203
+ const approvalPending = agentStatus === "waiting_approval";
24204
+ const monitorEvents = this.monitor.check(agentKey, agentStatus, now, progressFingerprint, approvalPending);
23885
24205
  for (const me of monitorEvents) {
23886
24206
  this.pushEvent({ event: me.type, agentKey: me.agentKey, message: me.message, elapsedSec: me.elapsedSec, timestamp: me.timestamp });
23887
24207
  }
@@ -24096,7 +24416,7 @@ init_contracts();
24096
24416
  var CHAT_CONTRACT_VERSION_V1 = "1.0";
24097
24417
 
24098
24418
  // src/providers/read-chat-contract.ts
24099
- var VALID_STATUSES = ["idle", "generating", "waiting_approval", "error", "panel_hidden", "starting", "streaming", "long_generating"];
24419
+ var VALID_STATUSES = ["idle", "generating", "waiting_approval", "error", "panel_hidden", "starting", "streaming", "no_progress", "long_generating"];
24100
24420
  var VALID_ROLES = ["user", "assistant", "system", "human"];
24101
24421
  var VALID_BUBBLE_STATES = ["draft", "streaming", "final", "removed"];
24102
24422
  var VALID_TURN_STATUSES = ["open", "waiting_approval", "complete", "error"];
@@ -24363,8 +24683,8 @@ var IdeProviderInstance = class {
24363
24683
  this.settings = context.settings || {};
24364
24684
  this.monitor.updateConfig({
24365
24685
  approvalAlert: this.settings.approvalAlert !== false,
24366
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
24367
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
24686
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
24687
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
24368
24688
  });
24369
24689
  }
24370
24690
  async onTick() {
@@ -24491,8 +24811,8 @@ var IdeProviderInstance = class {
24491
24811
  this.settings = { ...this.settings, ...newSettings };
24492
24812
  this.monitor.updateConfig({
24493
24813
  approvalAlert: this.settings.approvalAlert !== false,
24494
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
24495
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
24814
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
24815
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
24496
24816
  });
24497
24817
  }
24498
24818
  // ─── Extension manage ─────────────────────────────
@@ -24623,7 +24943,7 @@ var IdeProviderInstance = class {
24623
24943
  const persistedMessages = chat.messages || messages;
24624
24944
  if (persistedMessages.length > 0) {
24625
24945
  let toSave = persistedMessages;
24626
- if (chat.status === "generating" || chat.status === "long_generating") {
24946
+ if (chat.status === "generating" || chat.status === "no_progress" || chat.status === "long_generating") {
24627
24947
  const lastIdx = toSave.length - 1;
24628
24948
  if (lastIdx >= 0 && toSave[lastIdx].role === "assistant") {
24629
24949
  toSave = toSave.slice(0, lastIdx);
@@ -24693,7 +25013,8 @@ var IdeProviderInstance = class {
24693
25013
  if (rawAgentStatus === "waiting_approval" && autoApproveActive && !this.autoApproveBusy) {
24694
25014
  this.autoApproveViaScript(chatData);
24695
25015
  }
24696
- const monitorEvents = this.monitor.check(agentKey, agentStatus, now, progressFingerprint);
25016
+ const approvalPending = rawAgentStatus === "waiting_approval";
25017
+ const monitorEvents = this.monitor.check(agentKey, agentStatus, now, progressFingerprint, approvalPending);
24697
25018
  for (const me of monitorEvents) {
24698
25019
  this.pushEvent({ event: me.type, agentKey: me.agentKey, message: me.message, elapsedSec: me.elapsedSec, timestamp: me.timestamp });
24699
25020
  }
@@ -27250,7 +27571,7 @@ function normalizeReadChatCommandStatus(status, activeModal) {
27250
27571
  }
27251
27572
  }
27252
27573
  function isGeneratingLikeStatus(status) {
27253
- return status === "generating" || status === "streaming" || status === "long_generating" || status === "starting";
27574
+ return status === "generating" || status === "streaming" || status === "no_progress" || status === "long_generating" || status === "starting";
27254
27575
  }
27255
27576
  function hasVisibleAssistantMessage(messages) {
27256
27577
  if (!Array.isArray(messages)) return false;
@@ -31283,7 +31604,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
31283
31604
  var os19 = __toESM(require("os"));
31284
31605
  var path26 = __toESM(require("path"));
31285
31606
  var crypto5 = __toESM(require("crypto"));
31286
- var import_fs14 = require("fs");
31607
+ var import_fs15 = require("fs");
31287
31608
  var import_child_process6 = require("child_process");
31288
31609
  var import_chalk = __toESM(require("chalk"));
31289
31610
  init_provider_cli_adapter();
@@ -33928,7 +34249,7 @@ function hasNonEmptyCliModalButtons(activeModal) {
33928
34249
  return Array.isArray(buttons) && buttons.some((button) => String(button || "").trim().length > 0);
33929
34250
  }
33930
34251
  function isCliGeneratingLikeStatus(status) {
33931
- return status === "generating" || status === "streaming" || status === "long_generating" || status === "starting";
34252
+ return status === "generating" || status === "streaming" || status === "no_progress" || status === "long_generating" || status === "starting";
33932
34253
  }
33933
34254
  function buildCliStructuredInputPrompt(input, options = {}) {
33934
34255
  const promptParts = [];
@@ -34130,8 +34451,8 @@ var CliProviderInstance = class _CliProviderInstance {
34130
34451
  this.adapter.updateRuntimeSettings?.(this.settings);
34131
34452
  this.monitor.updateConfig({
34132
34453
  approvalAlert: this.settings.approvalAlert !== false,
34133
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
34134
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
34454
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
34455
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
34135
34456
  });
34136
34457
  if (context.serverConn) {
34137
34458
  this.adapter.setServerConn(context.serverConn);
@@ -34278,7 +34599,7 @@ var CliProviderInstance = class _CliProviderInstance {
34278
34599
  if (parsedMessages.length > 0) {
34279
34600
  const shouldSkipReplayPersist = this.suppressIdleHistoryReplay && adapterStatus.status === "idle" && parsedStatus?.status === "idle";
34280
34601
  let messagesToSave = parsedMessages;
34281
- if (!suppressStaleParsedBusyStatus && (parsedChatStatus === "generating" || parsedChatStatus === "long_generating")) {
34602
+ if (!suppressStaleParsedBusyStatus && (parsedChatStatus === "generating" || parsedChatStatus === "no_progress" || parsedChatStatus === "long_generating")) {
34282
34603
  const lastIdx = messagesToSave.length - 1;
34283
34604
  if (lastIdx >= 0 && messagesToSave[lastIdx]?.role === "assistant") {
34284
34605
  messagesToSave = messagesToSave.slice(0, lastIdx);
@@ -34406,8 +34727,8 @@ var CliProviderInstance = class _CliProviderInstance {
34406
34727
  this.adapter.updateRuntimeSettings?.(this.settings);
34407
34728
  this.monitor.updateConfig({
34408
34729
  approvalAlert: this.settings.approvalAlert !== false,
34409
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
34410
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
34730
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
34731
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
34411
34732
  });
34412
34733
  }
34413
34734
  /**
@@ -35139,10 +35460,11 @@ var CliProviderInstance = class _CliProviderInstance {
35139
35460
  phase: newStatus === "idle" && (previousStatus === "generating" || previousStatus === "waiting_approval") ? "turn_completed" : "immediate"
35140
35461
  });
35141
35462
  const agentKey = `${this.type}:cli`;
35142
- const monitorEvents = this.monitor.check(agentKey, newStatus, now, progressFingerprint);
35463
+ const approvalPending = rawStatus === "waiting_approval";
35464
+ const monitorEvents = this.monitor.check(agentKey, newStatus, now, progressFingerprint, approvalPending);
35143
35465
  const monitorParsedStatus = parsedStatus;
35144
35466
  for (const me of monitorEvents) {
35145
- if (me.type === "monitor:long_generating" && this.completionHasFinalAssistantMessage(monitorParsedStatus?.messages) && !this.hasAdapterPendingResponse() && !hasNonEmptyCliModalButtons(monitorParsedStatus?.activeModal ?? monitorParsedStatus?.modal)) {
35467
+ if (me.type === "monitor:no_progress" && this.completionHasFinalAssistantMessage(monitorParsedStatus?.messages) && !this.hasAdapterPendingResponse() && !hasNonEmptyCliModalButtons(monitorParsedStatus?.activeModal ?? monitorParsedStatus?.modal)) {
35146
35468
  this.pushEvent({
35147
35469
  event: "agent:generating_completed",
35148
35470
  chatTitle,
@@ -35153,7 +35475,7 @@ var CliProviderInstance = class _CliProviderInstance {
35153
35475
  providerType: this.type,
35154
35476
  sessionId: this.instanceId,
35155
35477
  providerSessionId: this.providerSessionId || null,
35156
- reconciliationReason: "long_generating_monitor_final_summary",
35478
+ reconciliationReason: "no_progress_monitor_final_summary",
35157
35479
  finalAssistantPresent: true
35158
35480
  }
35159
35481
  });
@@ -35830,8 +36152,8 @@ var AcpProviderInstance = class {
35830
36152
  this.settings = context.settings || {};
35831
36153
  this.monitor.updateConfig({
35832
36154
  approvalAlert: this.settings.approvalAlert !== false,
35833
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
35834
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
36155
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
36156
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
35835
36157
  });
35836
36158
  await this.spawnAgent();
35837
36159
  }
@@ -36127,8 +36449,8 @@ var AcpProviderInstance = class {
36127
36449
  this.settings = { ...this.settings, ...newSettings };
36128
36450
  this.monitor.updateConfig({
36129
36451
  approvalAlert: this.settings.approvalAlert !== false,
36130
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
36131
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
36452
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
36453
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
36132
36454
  });
36133
36455
  this.log.info(`[${this.type}] Settings updated: ${Object.keys(newSettings).join(", ")}`);
36134
36456
  }
@@ -36835,7 +37157,8 @@ ${rawInput}` : rawInput;
36835
37157
  this.lastStatus = newStatus;
36836
37158
  }
36837
37159
  const agentKey = `${this.type}:acp`;
36838
- const monitorEvents = this.monitor.check(agentKey, newStatus, now, progressFingerprint);
37160
+ const approvalPending = newStatus === "waiting_approval";
37161
+ const monitorEvents = this.monitor.check(agentKey, newStatus, now, progressFingerprint, approvalPending);
36839
37162
  for (const me of monitorEvents) {
36840
37163
  this.pushEvent({ event: me.type, agentKey: me.agentKey, message: me.message, elapsedSec: me.elapsedSec, timestamp: me.timestamp });
36841
37164
  }
@@ -36897,7 +37220,7 @@ function commandExists(command) {
36897
37220
  const trimmed = command.trim();
36898
37221
  if (!trimmed) return false;
36899
37222
  if (isExplicitCommand(trimmed)) {
36900
- return (0, import_fs14.existsSync)(expandExecutable(trimmed));
37223
+ return (0, import_fs15.existsSync)(expandExecutable(trimmed));
36901
37224
  }
36902
37225
  try {
36903
37226
  (0, import_child_process6.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
@@ -36909,7 +37232,7 @@ function commandExists(command) {
36909
37232
  return false;
36910
37233
  }
36911
37234
  }
36912
- var BUSY_AGENT_STATUSES = /* @__PURE__ */ new Set(["generating", "running", "streaming", "starting", "busy", "waiting", "waiting_approval", "long_generating"]);
37235
+ var BUSY_AGENT_STATUSES = /* @__PURE__ */ new Set(["generating", "running", "streaming", "starting", "busy", "waiting", "waiting_approval", "no_progress", "long_generating"]);
36913
37236
  var ZERO_MESSAGE_STARTING_SEND_WAIT_MS = 2e3;
36914
37237
  function normalizeAgentStatus(value) {
36915
37238
  return typeof value === "string" ? value.trim().toLowerCase() : "";
@@ -37033,10 +37356,10 @@ function hasConfigOverride(args, key) {
37033
37356
  }
37034
37357
  function ensureEmptyDelegatedMcpConfig(workspace) {
37035
37358
  const baseDir = path26.join(os19.tmpdir(), "adhdev-delegated-agent-empty-mcp");
37036
- (0, import_fs14.mkdirSync)(baseDir, { recursive: true });
37359
+ (0, import_fs15.mkdirSync)(baseDir, { recursive: true });
37037
37360
  const workspaceHash = crypto5.createHash("sha256").update(path26.resolve(workspace || os19.tmpdir())).digest("hex").slice(0, 16);
37038
37361
  const filePath = path26.join(baseDir, `${workspaceHash}.json`);
37039
- (0, import_fs14.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
37362
+ (0, import_fs15.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
37040
37363
  return filePath;
37041
37364
  }
37042
37365
  function buildCoordinatorDelegatedCliLaunchOptions(input) {
@@ -41774,6 +42097,7 @@ function getAvailableIdeIds() {
41774
42097
  init_config();
41775
42098
  init_cli_detector();
41776
42099
  init_git_status();
42100
+ init_change_impact_config();
41777
42101
  init_dist();
41778
42102
  init_logger();
41779
42103
 
@@ -41922,7 +42246,7 @@ function getRecentCommands(count = 50) {
41922
42246
  cleanOldFiles();
41923
42247
 
41924
42248
  // src/commands/router.ts
41925
- var yaml3 = __toESM(require("js-yaml"));
42249
+ var yaml4 = __toESM(require("js-yaml"));
41926
42250
  init_logger();
41927
42251
 
41928
42252
  // src/logging/log-tail-reader.ts
@@ -42308,8 +42632,8 @@ function buildPreviewFreshness(repoRoot) {
42308
42632
  init_mesh_refine_status();
42309
42633
 
42310
42634
  // src/mesh/mesh-init.ts
42311
- var import_fs15 = require("fs");
42312
- var import_path10 = require("path");
42635
+ var import_fs16 = require("fs");
42636
+ var import_path11 = require("path");
42313
42637
  var MESH_INIT_REFINE_CONFIG_PATH = MESH_REFINE_CONFIG_LOCATIONS[0];
42314
42638
  var MESH_INIT_WORKTREE_BOOTSTRAP_CONFIG_PATH = MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS[0];
42315
42639
  var CANDIDATE_STALE_INPUTS = [
@@ -42323,22 +42647,22 @@ var CANDIDATE_STALE_INPUTS = [
42323
42647
  "requirements.txt"
42324
42648
  ];
42325
42649
  function writeConfigFile(workspace, relativePath, config) {
42326
- const target = (0, import_path10.join)(workspace, relativePath);
42327
- (0, import_fs15.mkdirSync)((0, import_path10.dirname)(target), { recursive: true });
42328
- (0, import_fs15.writeFileSync)(target, `${JSON.stringify(config, null, 2)}
42650
+ const target = (0, import_path11.join)(workspace, relativePath);
42651
+ (0, import_fs16.mkdirSync)((0, import_path11.dirname)(target), { recursive: true });
42652
+ (0, import_fs16.writeFileSync)(target, `${JSON.stringify(config, null, 2)}
42329
42653
  `, "utf-8");
42330
42654
  return target;
42331
42655
  }
42332
42656
  function suggestMeshWorktreeBootstrapConfig(workspace) {
42333
42657
  const commands = [];
42334
- const hasPackageJson = (0, import_fs15.existsSync)((0, import_path10.join)(workspace, "package.json"));
42335
- const hasNpmLock = (0, import_fs15.existsSync)((0, import_path10.join)(workspace, "package-lock.json"));
42658
+ const hasPackageJson = (0, import_fs16.existsSync)((0, import_path11.join)(workspace, "package.json"));
42659
+ const hasNpmLock = (0, import_fs16.existsSync)((0, import_path11.join)(workspace, "package-lock.json"));
42336
42660
  if (hasPackageJson) {
42337
42661
  commands.push(
42338
42662
  hasNpmLock ? { command: "npm", args: ["ci"] } : { command: "npm", args: ["install"] }
42339
42663
  );
42340
42664
  }
42341
- const staleInputs = CANDIDATE_STALE_INPUTS.filter((relative5) => (0, import_fs15.existsSync)((0, import_path10.join)(workspace, relative5)));
42665
+ const staleInputs = CANDIDATE_STALE_INPUTS.filter((relative5) => (0, import_fs16.existsSync)((0, import_path11.join)(workspace, relative5)));
42342
42666
  if (!commands.length) {
42343
42667
  return { commands, staleInputs };
42344
42668
  }
@@ -42406,7 +42730,7 @@ function runMeshInit(mesh, workspace, detected, options = {}) {
42406
42730
  }
42407
42731
  function applyConfigSuggestion(input) {
42408
42732
  const { workspace, relativePath, existing, suggestedConfig, validate, write, overwrite } = input;
42409
- const absolute = (0, import_path10.join)(workspace, relativePath);
42733
+ const absolute = (0, import_path11.join)(workspace, relativePath);
42410
42734
  if (existing !== void 0 && !overwrite) {
42411
42735
  return { path: absolute, relativePath, written: false, skippedReason: "already_exists", config: existing };
42412
42736
  }
@@ -43131,7 +43455,7 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
43131
43455
  init_mesh_work_queue();
43132
43456
  init_repo_mesh_types();
43133
43457
  var import_os3 = require("os");
43134
- var import_path11 = require("path");
43458
+ var import_path12 = require("path");
43135
43459
  var fs26 = __toESM(require("fs"));
43136
43460
  var import_node_child_process6 = require("child_process");
43137
43461
  var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
@@ -44604,14 +44928,14 @@ function collectFastForwardGitlinkPaths(repoRoot, baseHead, branchHead) {
44604
44928
  const baseCommit = readTreeObject(repoRoot, baseHead, path42);
44605
44929
  const branchCommit = readTreeObject(repoRoot, branchHead, path42);
44606
44930
  if (!baseCommit || !branchCommit) return false;
44607
- return isSubmoduleFastForward((0, import_path11.resolve)(repoRoot, path42), baseCommit, branchCommit);
44931
+ return isSubmoduleFastForward((0, import_path12.resolve)(repoRoot, path42), baseCommit, branchCommit);
44608
44932
  });
44609
44933
  }
44610
44934
  function evaluateGitlinkTrivialFastForward(repoRoot, baseHead, branchHead) {
44611
44935
  const changedGitlinks = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path42) => {
44612
44936
  const baseCommit = readTreeObject(repoRoot, baseHead, path42);
44613
44937
  const branchCommit = readTreeObject(repoRoot, branchHead, path42);
44614
- const submoduleRepoPath = (0, import_path11.resolve)(repoRoot, path42);
44938
+ const submoduleRepoPath = (0, import_path12.resolve)(repoRoot, path42);
44615
44939
  const fastForward = !!baseCommit && !!branchCommit && isSubmoduleFastForward(submoduleRepoPath, baseCommit, branchCommit);
44616
44940
  return { path: path42, baseCommit, branchCommit, fastForward };
44617
44941
  });
@@ -44666,7 +44990,7 @@ function buildTreeWithGitlinksEqualized(repoRoot, commitish, paths, placeholderC
44666
44990
  if (!tree) return void 0;
44667
44991
  const updates = paths.map((path42) => `160000 commit ${placeholderCommit} ${path42}`).join("\n");
44668
44992
  if (!updates) return tree;
44669
- const tmpIndex = (0, import_path11.join)(resolveGitDir(repoRoot), `adhdev-refine-eq-${commitish.slice(0, 12)}.index`);
44993
+ const tmpIndex = (0, import_path12.join)(resolveGitDir(repoRoot), `adhdev-refine-eq-${commitish.slice(0, 12)}.index`);
44670
44994
  const env = { ...process.env, GIT_INDEX_FILE: tmpIndex };
44671
44995
  try {
44672
44996
  (0, import_node_child_process6.execFileSync)("git", ["read-tree", tree], { cwd: repoRoot, env, stdio: "ignore" });
@@ -44741,7 +45065,7 @@ function synthesizeTrivialFastForwardMergeTree(repoRoot, baseHead, branchHead, g
44741
45065
  if (!contentTree) return void 0;
44742
45066
  const updates = branchGitlinks.map((entry) => `160000 commit ${entry.branchCommit} ${entry.path}`).join("\n");
44743
45067
  if (!updates) return contentTree;
44744
- const tmpIndex = (0, import_path11.join)(resolveGitDir(repoRoot), `adhdev-refine-ff-${baseHead.slice(0, 12)}-${branchHead.slice(0, 12)}.index`);
45068
+ const tmpIndex = (0, import_path12.join)(resolveGitDir(repoRoot), `adhdev-refine-ff-${baseHead.slice(0, 12)}-${branchHead.slice(0, 12)}.index`);
44745
45069
  const env = { ...process.env, GIT_INDEX_FILE: tmpIndex };
44746
45070
  try {
44747
45071
  (0, import_node_child_process6.execFileSync)("git", ["read-tree", contentTree], { cwd: repoRoot, env, stdio: "ignore" });
@@ -44879,7 +45203,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
44879
45203
  return match ? { commit: match[1], path: match[2] } : null;
44880
45204
  }).filter((entry) => !!entry);
44881
45205
  for (const gitlink of gitlinks) {
44882
- const submodulePath = (0, import_path11.resolve)(repoRoot, gitlink.path);
45206
+ const submodulePath = (0, import_path12.resolve)(repoRoot, gitlink.path);
44883
45207
  const entry = {
44884
45208
  path: gitlink.path,
44885
45209
  commit: gitlink.commit,
@@ -44907,7 +45231,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
44907
45231
  try {
44908
45232
  const imported = await importCommitFromWorktreeSubmodule(
44909
45233
  submodulePath,
44910
- (0, import_path11.resolve)(options.worktreeRoot, gitlink.path),
45234
+ (0, import_path12.resolve)(options.worktreeRoot, gitlink.path),
44911
45235
  gitlink.commit
44912
45236
  );
44913
45237
  if (imported) {
@@ -45119,19 +45443,19 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
45119
45443
  ...extras
45120
45444
  });
45121
45445
  const isPackageManagerValidation = (candidate) => {
45122
- const command = (0, import_path11.basename)(candidate.command).replace(/\.(?:cmd|exe)$/i, "");
45446
+ const command = (0, import_path12.basename)(candidate.command).replace(/\.(?:cmd|exe)$/i, "");
45123
45447
  return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
45124
45448
  };
45125
45449
  const dependenciesLikelyMissing = (cwd) => {
45126
- if (!fs26.existsSync((0, import_path11.join)(cwd, "package.json"))) return false;
45127
- if (fs26.existsSync((0, import_path11.join)(cwd, "node_modules"))) return false;
45128
- return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs26.existsSync((0, import_path11.join)(cwd, lock)));
45450
+ if (!fs26.existsSync((0, import_path12.join)(cwd, "package.json"))) return false;
45451
+ if (fs26.existsSync((0, import_path12.join)(cwd, "node_modules"))) return false;
45452
+ return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs26.existsSync((0, import_path12.join)(cwd, lock)));
45129
45453
  };
45130
45454
  if (runLegacyBootstrapCommands) {
45131
45455
  summary.bootstrap = { stage: "legacy" };
45132
45456
  for (const candidate of selection.bootstrapCommands) {
45133
45457
  const startedAt = Date.now();
45134
- const cwd = candidate.cwd ? (0, import_path11.resolve)(workspace, candidate.cwd) : workspace;
45458
+ const cwd = candidate.cwd ? (0, import_path12.resolve)(workspace, candidate.cwd) : workspace;
45135
45459
  const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
45136
45460
  try {
45137
45461
  const result = await execFileAsync4(candidate.command, candidate.args, {
@@ -45159,7 +45483,7 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
45159
45483
  }
45160
45484
  for (const candidate of selection.commands) {
45161
45485
  const startedAt = Date.now();
45162
- const cwd = candidate.cwd ? (0, import_path11.resolve)(workspace, candidate.cwd) : workspace;
45486
+ const cwd = candidate.cwd ? (0, import_path12.resolve)(workspace, candidate.cwd) : workspace;
45163
45487
  const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
45164
45488
  const bootstrapProvidedDependencies = summary.bootstrap?.stage === "cached" || summary.bootstrap?.stage === "ran" || summary.bootstrap?.stage === "legacy";
45165
45489
  if (!bootstrapProvidedDependencies && isPackageManagerValidation(candidate) && dependenciesLikelyMissing(cwd)) {
@@ -45205,7 +45529,7 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
45205
45529
  return summary;
45206
45530
  }
45207
45531
  function loadYamlModule() {
45208
- return yaml3;
45532
+ return yaml4;
45209
45533
  }
45210
45534
  function getMcpServersKey(format) {
45211
45535
  return format === "hermes_config_yaml" ? "mcp_servers" : "mcpServers";
@@ -45222,13 +45546,13 @@ function serializeMeshCoordinatorMcpConfig(config, format) {
45222
45546
  }
45223
45547
  function resolveHermesUserHome() {
45224
45548
  const explicitHome = process.env.HERMES_HOME?.trim();
45225
- return explicitHome || (0, import_path11.join)((0, import_os3.homedir)(), ".hermes");
45549
+ return explicitHome || (0, import_path12.join)((0, import_os3.homedir)(), ".hermes");
45226
45550
  }
45227
45551
  function loadHermesCoordinatorBaseConfig(targetConfigPath) {
45228
45552
  const sourceHome = resolveHermesUserHome();
45229
- const sourceConfigPath = (0, import_path11.join)(sourceHome, "config.yaml");
45553
+ const sourceConfigPath = (0, import_path12.join)(sourceHome, "config.yaml");
45230
45554
  if (!fs26.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
45231
- if ((0, import_path11.resolve)(sourceConfigPath) === (0, import_path11.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
45555
+ if ((0, import_path12.resolve)(sourceConfigPath) === (0, import_path12.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
45232
45556
  const parsed = parseMeshCoordinatorMcpConfig(fs26.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
45233
45557
  const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
45234
45558
  return { config: baseConfig, sourceHome, sourceConfigPath };
@@ -45262,10 +45586,10 @@ function stripHermesCoordinatorTempModelProviderOverrides(config) {
45262
45586
  return sanitized;
45263
45587
  }
45264
45588
  function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
45265
- if ((0, import_path11.resolve)(sourceHome) === (0, import_path11.resolve)(targetHome)) return;
45589
+ if ((0, import_path12.resolve)(sourceHome) === (0, import_path12.resolve)(targetHome)) return;
45266
45590
  for (const fileName of [".env", "auth.json"]) {
45267
- const sourcePath = (0, import_path11.join)(sourceHome, fileName);
45268
- const targetPath = (0, import_path11.join)(targetHome, fileName);
45591
+ const sourcePath = (0, import_path12.join)(sourceHome, fileName);
45592
+ const targetPath = (0, import_path12.join)(targetHome, fileName);
45269
45593
  if (!fs26.existsSync(sourcePath)) continue;
45270
45594
  try {
45271
45595
  fs26.copyFileSync(sourcePath, targetPath);
@@ -45767,7 +46091,7 @@ var DaemonCommandRouter = class {
45767
46091
  }
45768
46092
  const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2, removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
45769
46093
  const normalizePath = (value) => {
45770
- const resolved = (0, import_path11.resolve)(value);
46094
+ const resolved = (0, import_path12.resolve)(value);
45771
46095
  try {
45772
46096
  return fs26.realpathSync(resolved);
45773
46097
  } catch {
@@ -48947,6 +49271,42 @@ ${hintLines.join("\n")}` : "",
48947
49271
  note: "Suggestions are heuristic scaffold only; Refinery will not execute them until saved into repo mesh/refine config."
48948
49272
  };
48949
49273
  }
49274
+ case "get_mesh_change_impact_config_schema": {
49275
+ return {
49276
+ success: true,
49277
+ schema: CHANGE_IMPACT_CONFIG_SCHEMA,
49278
+ locations: CHANGE_IMPACT_CONFIG_LOCATIONS,
49279
+ sourceOfTruth: "repo change-impact config",
49280
+ heuristicRole: "suggestions_only_not_execution_path",
49281
+ note: "Declarative config only \u2014 JSON/YAML are parsed but never executed. Defines which package/file changes require a daemon rebuild/restart vs. a web-only redeploy vs. nothing."
49282
+ };
49283
+ }
49284
+ case "validate_mesh_change_impact_config": {
49285
+ const workspace = typeof args?.workspace === "string" ? args.workspace : process.cwd();
49286
+ if (args?.config !== void 0) {
49287
+ const validation = validateChangeImpactConfig(args.config, "inline");
49288
+ return { success: validation.valid, source: "inline", sourceType: "mesh_policy", ...validation };
49289
+ }
49290
+ const loaded = loadChangeImpactConfig(workspace);
49291
+ if (loaded.sourceType === "repo_file") {
49292
+ const validation = validateChangeImpactConfig(loaded.config, loaded.source);
49293
+ return { success: validation.valid, ...loaded, ...validation };
49294
+ }
49295
+ return {
49296
+ success: false,
49297
+ ...loaded,
49298
+ valid: false,
49299
+ errors: [loaded.error || "repo change-impact config unavailable"]
49300
+ };
49301
+ }
49302
+ case "suggest_mesh_change_impact_config": {
49303
+ const workspace = typeof args?.workspace === "string" ? args.workspace : process.cwd();
49304
+ return {
49305
+ success: true,
49306
+ ...suggestChangeImpactConfig(workspace),
49307
+ note: "Suggestions are heuristic scaffold only; the draft must be reviewed and saved into repo change-impact config before it takes effect. Nothing is executed."
49308
+ };
49309
+ }
48950
49310
  case "mesh_init": {
48951
49311
  const workspace = typeof args?.workspace === "string" && args.workspace.trim() ? args.workspace.trim() : process.cwd();
48952
49312
  const mesh = args?.inlineMesh || {};
@@ -49738,7 +50098,7 @@ ${ptyResult.output.slice(-2e3)}`);
49738
50098
  };
49739
50099
  }
49740
50100
  if (cliType === "codex-cli") {
49741
- const repoMcpConfigPath = (0, import_path11.join)(workspace, ".mcp.json");
50101
+ const repoMcpConfigPath = (0, import_path12.join)(workspace, ".mcp.json");
49742
50102
  if (fs26.existsSync(repoMcpConfigPath)) {
49743
50103
  try {
49744
50104
  const repoMcpConfig = parseMeshCoordinatorMcpConfig(
@@ -49863,7 +50223,7 @@ ${ptyResult.output.slice(-2e3)}`);
49863
50223
  workspace
49864
50224
  };
49865
50225
  }
49866
- const { existsSync: existsSync45, readFileSync: readFileSync36, writeFileSync: writeFileSync23, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
50226
+ const { existsSync: existsSync46, readFileSync: readFileSync37, writeFileSync: writeFileSync23, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
49867
50227
  const { dirname: dirname17 } = await import("path");
49868
50228
  const mcpConfigPath = coordinatorSetup.configPath;
49869
50229
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
@@ -49906,14 +50266,14 @@ ${ptyResult.output.slice(-2e3)}`);
49906
50266
  if (hermesManualFallback) return returnManualFallback(message);
49907
50267
  return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
49908
50268
  }
49909
- const hadExistingMcpConfig = existsSync45(mcpConfigPath);
50269
+ const hadExistingMcpConfig = existsSync46(mcpConfigPath);
49910
50270
  let existingMcpConfig = hermesBaseConfig?.config || {};
49911
50271
  if (hermesBaseConfig) {
49912
50272
  copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname17(mcpConfigPath));
49913
50273
  }
49914
50274
  if (hadExistingMcpConfig) {
49915
50275
  try {
49916
- const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync36(mcpConfigPath, "utf-8"), configFormat);
50276
+ const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync37(mcpConfigPath, "utf-8"), configFormat);
49917
50277
  const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
49918
50278
  existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
49919
50279
  copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
@@ -50412,7 +50772,7 @@ ${ptyResult.output.slice(-2e3)}`);
50412
50772
  const { deriveMeshReviewInboxItems: deriveMeshReviewInboxItems2 } = await Promise.resolve().then(() => (init_mesh_review_inbox(), mesh_review_inbox_exports));
50413
50773
  const { readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
50414
50774
  const { getGitDiffSummary: getGitDiffSummary2 } = await Promise.resolve().then(() => (init_git_diff(), git_diff_exports));
50415
- const { existsSync: existsSync45 } = await import("fs");
50775
+ const { existsSync: existsSync46 } = await import("fs");
50416
50776
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
50417
50777
  const mesh = meshRecord?.mesh;
50418
50778
  if (!mesh) return { success: false, error: "Mesh not found" };
@@ -50431,7 +50791,7 @@ ${ptyResult.output.slice(-2e3)}`);
50431
50791
  const derivation = deriveMeshReviewInboxItems2({ nodes: nodeStatuses, ledgerEntries });
50432
50792
  for (const item of derivation.items) {
50433
50793
  const workspace = item.workspace;
50434
- if (!workspace || !existsSync45(workspace)) continue;
50794
+ if (!workspace || !existsSync46(workspace)) continue;
50435
50795
  const baseRef = item.defaultBranch ? `origin/${item.defaultBranch}` : "origin/main";
50436
50796
  try {
50437
50797
  const diffResult = await getGitDiffSummary2(workspace, { baseRef, maxFiles: 100 });
@@ -50605,7 +50965,7 @@ var DaemonStatusReporter = class {
50605
50965
  case "agent:waiting_approval":
50606
50966
  case "agent:generating_completed":
50607
50967
  case "agent:stopped":
50608
- case "monitor:long_generating":
50968
+ case "monitor:no_progress":
50609
50969
  return value;
50610
50970
  default:
50611
50971
  return null;
@@ -51150,7 +51510,7 @@ var ProviderStreamAdapter = class {
51150
51510
  }
51151
51511
  const validated = validateReadChatResultPayload(data, `${this.agentType} readChat`);
51152
51512
  const validatedStatus = validated.status;
51153
- const streamStatus = validatedStatus === "generating" || validatedStatus === "long_generating" ? "streaming" : validatedStatus;
51513
+ const streamStatus = validatedStatus === "generating" || validatedStatus === "no_progress" || validatedStatus === "long_generating" ? "streaming" : validatedStatus;
51154
51514
  const state = {
51155
51515
  agentType: this.agentType,
51156
51516
  agentName: this.agentName,
@@ -59069,6 +59429,8 @@ var V1_CONTRACT_VERSION = "1.0.0";
59069
59429
  AcpProviderInstance,
59070
59430
  AgentStreamPoller,
59071
59431
  BUILTIN_CHAT_MESSAGE_KINDS,
59432
+ CHANGE_IMPACT_CONFIG_LOCATIONS,
59433
+ CHANGE_IMPACT_CONFIG_SCHEMA,
59072
59434
  CHAT_MESSAGE_ACTIVITY_SOURCES,
59073
59435
  CHAT_MESSAGE_AUDIENCES,
59074
59436
  CHAT_MESSAGE_INTERNAL_SOURCES,
@@ -59259,6 +59621,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
59259
59621
  getSessionHostSurfaceKind,
59260
59622
  getSessionRecoveryContext,
59261
59623
  getWorkspaceState,
59624
+ globToRegExp,
59262
59625
  handleGitCommand,
59263
59626
  hasCdpManager,
59264
59627
  hasPendingDependents,
@@ -59292,6 +59655,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
59292
59655
  listMeshMissionSummaries,
59293
59656
  listMeshes,
59294
59657
  listWorktrees,
59658
+ loadChangeImpactConfig,
59295
59659
  loadConfig,
59296
59660
  loadMeshCoordinatorRegistry,
59297
59661
  loadMeshRefineConfig,
@@ -59386,6 +59750,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
59386
59750
  spawnDetachedDaemonUpgradeHelper,
59387
59751
  startDaemonDevSupport,
59388
59752
  startLocalIpcServer,
59753
+ suggestChangeImpactConfig,
59389
59754
  suggestMeshRefineConfig,
59390
59755
  summarizeGitStatus,
59391
59756
  summarizeMeshAsyncRefineJobs,
@@ -59402,6 +59767,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
59402
59767
  updateTaskStatus,
59403
59768
  upsertMeshMission,
59404
59769
  upsertSavedProviderSession,
59770
+ validateChangeImpactConfig,
59405
59771
  validateCliProviderManifest,
59406
59772
  validateFsmSpec,
59407
59773
  validateMeshRefineConfig,